s4-smbtorture: add RPC-SAMR-USERS-PRIVILEGES test.
[Samba/gbeck.git] / source4 / torture / rpc / samr.c
blob080f8e403090ee22621dd6d48b95cb7542b393d5
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7 Copyright (C) Guenther Deschner 2008,2009
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
29 #include "librpc/gen_ndr/ndr_samr_c.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "../lib/crypto/crypto.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "libcli/security/security.h"
34 #include "torture/rpc/rpc.h"
35 #include "param/param.h"
37 #include <unistd.h>
39 #define TEST_ACCOUNT_NAME "samrtorturetest"
40 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
41 #define TEST_ALIASNAME "samrtorturetestalias"
42 #define TEST_GROUPNAME "samrtorturetestgroup"
43 #define TEST_MACHINENAME "samrtestmach$"
44 #define TEST_DOMAINNAME "samrtestdom$"
46 enum torture_samr_choice {
47 TORTURE_SAMR_PASSWORDS,
48 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
49 TORTURE_SAMR_USER_ATTRIBUTES,
50 TORTURE_SAMR_USER_PRIVILEGES,
51 TORTURE_SAMR_OTHER
54 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
55 struct torture_context *tctx,
56 struct policy_handle *handle);
58 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
59 struct torture_context *tctx,
60 struct policy_handle *handle);
62 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
63 struct torture_context *tctx,
64 struct policy_handle *handle);
66 static bool test_ChangePassword(struct dcerpc_pipe *p,
67 struct torture_context *tctx,
68 const char *acct_name,
69 struct policy_handle *domain_handle, char **password);
71 static void init_lsa_String(struct lsa_String *string, const char *s)
73 string->string = s;
76 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
78 string->string = s;
81 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
83 string->length = length;
84 string->size = length;
85 string->array = (uint16_t *)discard_const(s);
88 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
89 struct policy_handle *handle)
91 NTSTATUS status;
92 struct samr_Close r;
94 r.in.handle = handle;
95 r.out.handle = handle;
97 status = dcerpc_samr_Close(p, tctx, &r);
98 torture_assert_ntstatus_ok(tctx, status, "Close");
100 return true;
103 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
104 struct policy_handle *handle)
106 NTSTATUS status;
107 struct samr_Shutdown r;
109 if (!torture_setting_bool(tctx, "dangerous", false)) {
110 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
111 return true;
114 r.in.connect_handle = handle;
116 torture_comment(tctx, "testing samr_Shutdown\n");
118 status = dcerpc_samr_Shutdown(p, tctx, &r);
119 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
121 return true;
124 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
125 struct policy_handle *handle)
127 NTSTATUS status;
128 struct samr_SetDsrmPassword r;
129 struct lsa_String string;
130 struct samr_Password hash;
132 if (!torture_setting_bool(tctx, "dangerous", false)) {
133 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
136 E_md4hash("TeSTDSRM123", hash.hash);
138 init_lsa_String(&string, "Administrator");
140 r.in.name = &string;
141 r.in.unknown = 0;
142 r.in.hash = &hash;
144 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
146 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
147 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
149 return true;
153 static bool test_QuerySecurity(struct dcerpc_pipe *p,
154 struct torture_context *tctx,
155 struct policy_handle *handle)
157 NTSTATUS status;
158 struct samr_QuerySecurity r;
159 struct samr_SetSecurity s;
160 struct sec_desc_buf *sdbuf = NULL;
162 r.in.handle = handle;
163 r.in.sec_info = 7;
164 r.out.sdbuf = &sdbuf;
166 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
167 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
169 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
171 s.in.handle = handle;
172 s.in.sec_info = 7;
173 s.in.sdbuf = sdbuf;
175 if (torture_setting_bool(tctx, "samba4", false)) {
176 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
179 status = dcerpc_samr_SetSecurity(p, tctx, &s);
180 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
182 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
183 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
185 return true;
189 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
190 struct policy_handle *handle, uint32_t base_acct_flags,
191 const char *base_account_name)
193 NTSTATUS status;
194 struct samr_SetUserInfo s;
195 struct samr_SetUserInfo2 s2;
196 struct samr_QueryUserInfo q;
197 struct samr_QueryUserInfo q0;
198 union samr_UserInfo u;
199 union samr_UserInfo *info;
200 bool ret = true;
201 const char *test_account_name;
203 uint32_t user_extra_flags = 0;
205 if (!torture_setting_bool(tctx, "samba3", false)) {
206 if (base_acct_flags == ACB_NORMAL) {
207 /* When created, accounts are expired by default */
208 user_extra_flags = ACB_PW_EXPIRED;
212 s.in.user_handle = handle;
213 s.in.info = &u;
215 s2.in.user_handle = handle;
216 s2.in.info = &u;
218 q.in.user_handle = handle;
219 q.out.info = &info;
220 q0 = q;
222 #define TESTCALL(call, r) \
223 status = dcerpc_samr_ ##call(p, tctx, &r); \
224 if (!NT_STATUS_IS_OK(status)) { \
225 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
226 r.in.level, nt_errstr(status), __location__); \
227 ret = false; \
228 break; \
231 #define STRING_EQUAL(s1, s2, field) \
232 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
233 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
234 #field, s2, __location__); \
235 ret = false; \
236 break; \
239 #define MEM_EQUAL(s1, s2, length, field) \
240 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
241 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
242 #field, (const char *)s2, __location__); \
243 ret = false; \
244 break; \
247 #define INT_EQUAL(i1, i2, field) \
248 if (i1 != i2) { \
249 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
250 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
251 ret = false; \
252 break; \
255 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
256 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
257 q.in.level = lvl1; \
258 TESTCALL(QueryUserInfo, q) \
259 s.in.level = lvl1; \
260 s2.in.level = lvl1; \
261 u = *info; \
262 if (lvl1 == 21) { \
263 ZERO_STRUCT(u.info21); \
264 u.info21.fields_present = fpval; \
266 init_lsa_String(&u.info ## lvl1.field1, value); \
267 TESTCALL(SetUserInfo, s) \
268 TESTCALL(SetUserInfo2, s2) \
269 init_lsa_String(&u.info ## lvl1.field1, ""); \
270 TESTCALL(QueryUserInfo, q); \
271 u = *info; \
272 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
273 q.in.level = lvl2; \
274 TESTCALL(QueryUserInfo, q) \
275 u = *info; \
276 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
277 } while (0)
279 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
280 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
281 q.in.level = lvl1; \
282 TESTCALL(QueryUserInfo, q) \
283 s.in.level = lvl1; \
284 s2.in.level = lvl1; \
285 u = *info; \
286 if (lvl1 == 21) { \
287 ZERO_STRUCT(u.info21); \
288 u.info21.fields_present = fpval; \
290 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
291 TESTCALL(SetUserInfo, s) \
292 TESTCALL(SetUserInfo2, s2) \
293 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
294 TESTCALL(QueryUserInfo, q); \
295 u = *info; \
296 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
297 q.in.level = lvl2; \
298 TESTCALL(QueryUserInfo, q) \
299 u = *info; \
300 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
301 } while (0)
303 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
304 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
305 q.in.level = lvl1; \
306 TESTCALL(QueryUserInfo, q) \
307 s.in.level = lvl1; \
308 s2.in.level = lvl1; \
309 u = *info; \
310 if (lvl1 == 21) { \
311 uint8_t *bits = u.info21.logon_hours.bits; \
312 ZERO_STRUCT(u.info21); \
313 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
314 u.info21.logon_hours.units_per_week = 168; \
315 u.info21.logon_hours.bits = bits; \
317 u.info21.fields_present = fpval; \
319 u.info ## lvl1.field1 = value; \
320 TESTCALL(SetUserInfo, s) \
321 TESTCALL(SetUserInfo2, s2) \
322 u.info ## lvl1.field1 = 0; \
323 TESTCALL(QueryUserInfo, q); \
324 u = *info; \
325 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
326 q.in.level = lvl2; \
327 TESTCALL(QueryUserInfo, q) \
328 u = *info; \
329 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
330 } while (0)
332 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
333 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
334 } while (0)
336 q0.in.level = 12;
337 do { TESTCALL(QueryUserInfo, q0) } while (0);
339 /* Samba 3 cannot store comment fields atm. - gd */
340 if (!torture_setting_bool(tctx, "samba3", false)) {
341 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
342 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
343 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
344 SAMR_FIELD_COMMENT);
347 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
348 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
349 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
350 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
351 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
352 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
353 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
354 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
355 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
356 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
357 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
358 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
359 test_account_name = base_account_name;
360 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
361 SAMR_FIELD_ACCOUNT_NAME);
363 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
364 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
365 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
366 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
367 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
368 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
369 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
370 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
371 SAMR_FIELD_FULL_NAME);
373 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
374 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
375 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
376 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
377 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
378 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
379 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
380 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
381 SAMR_FIELD_FULL_NAME);
383 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
384 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
385 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
386 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
387 SAMR_FIELD_LOGON_SCRIPT);
389 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
390 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
391 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
392 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
393 SAMR_FIELD_PROFILE_PATH);
395 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
396 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
397 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
398 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
399 SAMR_FIELD_HOME_DIRECTORY);
400 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
401 SAMR_FIELD_HOME_DIRECTORY);
403 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
404 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
405 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
406 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
407 SAMR_FIELD_HOME_DRIVE);
408 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
409 SAMR_FIELD_HOME_DRIVE);
411 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
412 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
413 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
414 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
415 SAMR_FIELD_DESCRIPTION);
417 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
418 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
419 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
420 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
421 SAMR_FIELD_WORKSTATIONS);
422 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
423 SAMR_FIELD_WORKSTATIONS);
424 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
425 SAMR_FIELD_WORKSTATIONS);
426 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
427 SAMR_FIELD_WORKSTATIONS);
429 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
430 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
431 SAMR_FIELD_PARAMETERS);
432 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
433 SAMR_FIELD_PARAMETERS);
434 /* also empty user parameters are allowed */
435 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
436 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
437 SAMR_FIELD_PARAMETERS);
438 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
439 SAMR_FIELD_PARAMETERS);
441 /* Samba 3 cannot store country_code and copy_page atm. - gd */
442 if (!torture_setting_bool(tctx, "samba3", false)) {
443 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
444 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
445 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
446 SAMR_FIELD_COUNTRY_CODE);
447 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
448 SAMR_FIELD_COUNTRY_CODE);
450 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
451 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
452 SAMR_FIELD_CODE_PAGE);
453 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
454 SAMR_FIELD_CODE_PAGE);
457 if (!torture_setting_bool(tctx, "samba3", false)) {
458 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
459 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
460 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
461 SAMR_FIELD_ACCT_EXPIRY);
462 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
463 SAMR_FIELD_ACCT_EXPIRY);
464 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
465 SAMR_FIELD_ACCT_EXPIRY);
466 } else {
467 /* Samba 3 can only store seconds / time_t in passdb - gd */
468 NTTIME nt;
469 unix_to_nt_time(&nt, time(NULL) + __LINE__);
470 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
471 unix_to_nt_time(&nt, time(NULL) + __LINE__);
472 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
473 unix_to_nt_time(&nt, time(NULL) + __LINE__);
474 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
475 unix_to_nt_time(&nt, time(NULL) + __LINE__);
476 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
477 unix_to_nt_time(&nt, time(NULL) + __LINE__);
478 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
481 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
482 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
483 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
484 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
485 SAMR_FIELD_LOGON_HOURS);
487 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
488 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
489 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
491 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
492 (base_acct_flags | ACB_DISABLED),
493 (base_acct_flags | ACB_DISABLED | user_extra_flags),
496 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
497 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
498 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
499 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
501 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
502 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
503 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
507 /* The 'autolock' flag doesn't stick - check this */
508 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
509 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
510 (base_acct_flags | ACB_DISABLED | user_extra_flags),
512 #if 0
513 /* Removing the 'disabled' flag doesn't stick - check this */
514 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
515 (base_acct_flags),
516 (base_acct_flags | ACB_DISABLED | user_extra_flags),
518 #endif
520 /* Samba3 cannot store these atm */
521 if (!torture_setting_bool(tctx, "samba3", false)) {
522 /* The 'store plaintext' flag does stick */
523 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
524 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
525 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
527 /* The 'use DES' flag does stick */
528 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
529 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
530 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
532 /* The 'don't require kerberos pre-authentication flag does stick */
533 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
534 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
535 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
537 /* The 'no kerberos PAC required' flag sticks */
538 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
539 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
540 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
543 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
544 (base_acct_flags | ACB_DISABLED),
545 (base_acct_flags | ACB_DISABLED | user_extra_flags),
546 SAMR_FIELD_ACCT_FLAGS);
548 #if 0
549 /* these fail with win2003 - it appears you can't set the primary gid?
550 the set succeeds, but the gid isn't changed. Very weird! */
551 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
552 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
553 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
554 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
555 #endif
557 return ret;
561 generate a random password for password change tests
563 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
565 size_t len = MAX(8, min_len) + (random() % 6);
566 char *s = generate_random_str(mem_ctx, len);
567 return s;
570 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
572 char *s = samr_rand_pass_silent(mem_ctx, min_len);
573 printf("Generated password '%s'\n", s);
574 return s;
579 generate a random password for password change tests
581 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
583 int i;
584 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
585 generate_random_buffer(password.data, password.length);
587 for (i=0; i < len; i++) {
588 if (((uint16_t *)password.data)[i] == 0) {
589 ((uint16_t *)password.data)[i] = 1;
593 return password;
597 generate a random password for password change tests (fixed length)
599 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
601 char *s = generate_random_str(mem_ctx, len);
602 printf("Generated password '%s'\n", s);
603 return s;
606 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
607 struct policy_handle *handle, char **password)
609 NTSTATUS status;
610 struct samr_SetUserInfo s;
611 union samr_UserInfo u;
612 bool ret = true;
613 DATA_BLOB session_key;
614 char *newpass;
615 struct samr_GetUserPwInfo pwp;
616 struct samr_PwInfo info;
617 int policy_min_pw_len = 0;
618 pwp.in.user_handle = handle;
619 pwp.out.info = &info;
621 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
622 if (NT_STATUS_IS_OK(status)) {
623 policy_min_pw_len = pwp.out.info->min_password_length;
625 newpass = samr_rand_pass(tctx, policy_min_pw_len);
627 s.in.user_handle = handle;
628 s.in.info = &u;
629 s.in.level = 24;
631 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
632 u.info24.password_expired = 0;
634 status = dcerpc_fetch_session_key(p, &session_key);
635 if (!NT_STATUS_IS_OK(status)) {
636 printf("SetUserInfo level %u - no session key - %s\n",
637 s.in.level, nt_errstr(status));
638 return false;
641 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
643 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
645 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
646 if (!NT_STATUS_IS_OK(status)) {
647 printf("SetUserInfo level %u failed - %s\n",
648 s.in.level, nt_errstr(status));
649 ret = false;
650 } else {
651 *password = newpass;
654 return ret;
658 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
659 struct policy_handle *handle, uint32_t fields_present,
660 char **password)
662 NTSTATUS status;
663 struct samr_SetUserInfo s;
664 union samr_UserInfo u;
665 bool ret = true;
666 DATA_BLOB session_key;
667 char *newpass;
668 struct samr_GetUserPwInfo pwp;
669 struct samr_PwInfo info;
670 int policy_min_pw_len = 0;
671 pwp.in.user_handle = handle;
672 pwp.out.info = &info;
674 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
675 if (NT_STATUS_IS_OK(status)) {
676 policy_min_pw_len = pwp.out.info->min_password_length;
678 newpass = samr_rand_pass(tctx, policy_min_pw_len);
680 s.in.user_handle = handle;
681 s.in.info = &u;
682 s.in.level = 23;
684 ZERO_STRUCT(u);
686 u.info23.info.fields_present = fields_present;
688 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
690 status = dcerpc_fetch_session_key(p, &session_key);
691 if (!NT_STATUS_IS_OK(status)) {
692 printf("SetUserInfo level %u - no session key - %s\n",
693 s.in.level, nt_errstr(status));
694 return false;
697 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
699 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
701 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
702 if (!NT_STATUS_IS_OK(status)) {
703 printf("SetUserInfo level %u failed - %s\n",
704 s.in.level, nt_errstr(status));
705 ret = false;
706 } else {
707 *password = newpass;
710 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
712 status = dcerpc_fetch_session_key(p, &session_key);
713 if (!NT_STATUS_IS_OK(status)) {
714 printf("SetUserInfo level %u - no session key - %s\n",
715 s.in.level, nt_errstr(status));
716 return false;
719 /* This should break the key nicely */
720 session_key.length--;
721 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
723 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
725 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
726 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
727 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
728 s.in.level, nt_errstr(status));
729 ret = false;
732 return ret;
736 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
737 struct policy_handle *handle, bool makeshort,
738 char **password)
740 NTSTATUS status;
741 struct samr_SetUserInfo s;
742 union samr_UserInfo u;
743 bool ret = true;
744 DATA_BLOB session_key;
745 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
746 uint8_t confounder[16];
747 char *newpass;
748 struct MD5Context ctx;
749 struct samr_GetUserPwInfo pwp;
750 struct samr_PwInfo info;
751 int policy_min_pw_len = 0;
752 pwp.in.user_handle = handle;
753 pwp.out.info = &info;
755 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
756 if (NT_STATUS_IS_OK(status)) {
757 policy_min_pw_len = pwp.out.info->min_password_length;
759 if (makeshort && policy_min_pw_len) {
760 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
761 } else {
762 newpass = samr_rand_pass(tctx, policy_min_pw_len);
765 s.in.user_handle = handle;
766 s.in.info = &u;
767 s.in.level = 26;
769 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
770 u.info26.password_expired = 0;
772 status = dcerpc_fetch_session_key(p, &session_key);
773 if (!NT_STATUS_IS_OK(status)) {
774 printf("SetUserInfo level %u - no session key - %s\n",
775 s.in.level, nt_errstr(status));
776 return false;
779 generate_random_buffer((uint8_t *)confounder, 16);
781 MD5Init(&ctx);
782 MD5Update(&ctx, confounder, 16);
783 MD5Update(&ctx, session_key.data, session_key.length);
784 MD5Final(confounded_session_key.data, &ctx);
786 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
787 memcpy(&u.info26.password.data[516], confounder, 16);
789 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
791 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
792 if (!NT_STATUS_IS_OK(status)) {
793 printf("SetUserInfo level %u failed - %s\n",
794 s.in.level, nt_errstr(status));
795 ret = false;
796 } else {
797 *password = newpass;
800 /* This should break the key nicely */
801 confounded_session_key.data[0]++;
803 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
804 memcpy(&u.info26.password.data[516], confounder, 16);
806 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
808 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
809 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
810 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
811 s.in.level, nt_errstr(status));
812 ret = false;
813 } else {
814 *password = newpass;
817 return ret;
820 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
821 struct policy_handle *handle, uint32_t fields_present,
822 char **password)
824 NTSTATUS status;
825 struct samr_SetUserInfo s;
826 union samr_UserInfo u;
827 bool ret = true;
828 DATA_BLOB session_key;
829 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
830 struct MD5Context ctx;
831 uint8_t confounder[16];
832 char *newpass;
833 struct samr_GetUserPwInfo pwp;
834 struct samr_PwInfo info;
835 int policy_min_pw_len = 0;
836 pwp.in.user_handle = handle;
837 pwp.out.info = &info;
839 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
840 if (NT_STATUS_IS_OK(status)) {
841 policy_min_pw_len = pwp.out.info->min_password_length;
843 newpass = samr_rand_pass(tctx, policy_min_pw_len);
845 s.in.user_handle = handle;
846 s.in.info = &u;
847 s.in.level = 25;
849 ZERO_STRUCT(u);
851 u.info25.info.fields_present = fields_present;
853 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
855 status = dcerpc_fetch_session_key(p, &session_key);
856 if (!NT_STATUS_IS_OK(status)) {
857 printf("SetUserInfo level %u - no session key - %s\n",
858 s.in.level, nt_errstr(status));
859 return false;
862 generate_random_buffer((uint8_t *)confounder, 16);
864 MD5Init(&ctx);
865 MD5Update(&ctx, confounder, 16);
866 MD5Update(&ctx, session_key.data, session_key.length);
867 MD5Final(confounded_session_key.data, &ctx);
869 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
870 memcpy(&u.info25.password.data[516], confounder, 16);
872 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
874 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
875 if (!NT_STATUS_IS_OK(status)) {
876 printf("SetUserInfo level %u failed - %s\n",
877 s.in.level, nt_errstr(status));
878 ret = false;
879 } else {
880 *password = newpass;
883 /* This should break the key nicely */
884 confounded_session_key.data[0]++;
886 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
887 memcpy(&u.info25.password.data[516], confounder, 16);
889 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
891 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
892 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
893 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
894 s.in.level, nt_errstr(status));
895 ret = false;
898 return ret;
901 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
902 struct policy_handle *handle, char **password)
904 NTSTATUS status;
905 struct samr_SetUserInfo s;
906 union samr_UserInfo u;
907 bool ret = true;
908 DATA_BLOB session_key;
909 char *newpass;
910 struct samr_GetUserPwInfo pwp;
911 struct samr_PwInfo info;
912 int policy_min_pw_len = 0;
913 uint8_t lm_hash[16], nt_hash[16];
915 pwp.in.user_handle = handle;
916 pwp.out.info = &info;
918 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
919 if (NT_STATUS_IS_OK(status)) {
920 policy_min_pw_len = pwp.out.info->min_password_length;
922 newpass = samr_rand_pass(tctx, policy_min_pw_len);
924 s.in.user_handle = handle;
925 s.in.info = &u;
926 s.in.level = 18;
928 ZERO_STRUCT(u);
930 u.info18.nt_pwd_active = true;
931 u.info18.lm_pwd_active = true;
933 E_md4hash(newpass, nt_hash);
934 E_deshash(newpass, lm_hash);
936 status = dcerpc_fetch_session_key(p, &session_key);
937 if (!NT_STATUS_IS_OK(status)) {
938 printf("SetUserInfo level %u - no session key - %s\n",
939 s.in.level, nt_errstr(status));
940 return false;
944 DATA_BLOB in,out;
945 in = data_blob_const(nt_hash, 16);
946 out = data_blob_talloc_zero(tctx, 16);
947 sess_crypt_blob(&out, &in, &session_key, true);
948 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
951 DATA_BLOB in,out;
952 in = data_blob_const(lm_hash, 16);
953 out = data_blob_talloc_zero(tctx, 16);
954 sess_crypt_blob(&out, &in, &session_key, true);
955 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
958 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
960 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
961 if (!NT_STATUS_IS_OK(status)) {
962 printf("SetUserInfo level %u failed - %s\n",
963 s.in.level, nt_errstr(status));
964 ret = false;
965 } else {
966 *password = newpass;
969 return ret;
972 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
973 struct policy_handle *handle, uint32_t fields_present,
974 char **password)
976 NTSTATUS status;
977 struct samr_SetUserInfo s;
978 union samr_UserInfo u;
979 bool ret = true;
980 DATA_BLOB session_key;
981 char *newpass;
982 struct samr_GetUserPwInfo pwp;
983 struct samr_PwInfo info;
984 int policy_min_pw_len = 0;
985 uint8_t lm_hash[16], nt_hash[16];
987 pwp.in.user_handle = handle;
988 pwp.out.info = &info;
990 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
991 if (NT_STATUS_IS_OK(status)) {
992 policy_min_pw_len = pwp.out.info->min_password_length;
994 newpass = samr_rand_pass(tctx, policy_min_pw_len);
996 s.in.user_handle = handle;
997 s.in.info = &u;
998 s.in.level = 21;
1000 E_md4hash(newpass, nt_hash);
1001 E_deshash(newpass, lm_hash);
1003 ZERO_STRUCT(u);
1005 u.info21.fields_present = fields_present;
1007 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1008 u.info21.lm_owf_password.length = 16;
1009 u.info21.lm_owf_password.size = 16;
1010 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1011 u.info21.lm_password_set = true;
1014 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1015 u.info21.nt_owf_password.length = 16;
1016 u.info21.nt_owf_password.size = 16;
1017 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1018 u.info21.nt_password_set = true;
1021 status = dcerpc_fetch_session_key(p, &session_key);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 printf("SetUserInfo level %u - no session key - %s\n",
1024 s.in.level, nt_errstr(status));
1025 return false;
1028 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1029 DATA_BLOB in,out;
1030 in = data_blob_const(u.info21.lm_owf_password.array,
1031 u.info21.lm_owf_password.length);
1032 out = data_blob_talloc_zero(tctx, 16);
1033 sess_crypt_blob(&out, &in, &session_key, true);
1034 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1037 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1038 DATA_BLOB in,out;
1039 in = data_blob_const(u.info21.nt_owf_password.array,
1040 u.info21.nt_owf_password.length);
1041 out = data_blob_talloc_zero(tctx, 16);
1042 sess_crypt_blob(&out, &in, &session_key, true);
1043 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1046 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1048 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1049 if (!NT_STATUS_IS_OK(status)) {
1050 printf("SetUserInfo level %u failed - %s\n",
1051 s.in.level, nt_errstr(status));
1052 ret = false;
1053 } else {
1054 *password = newpass;
1057 /* try invalid length */
1058 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1060 u.info21.nt_owf_password.length++;
1062 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1064 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1065 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1066 s.in.level, nt_errstr(status));
1067 ret = false;
1071 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1073 u.info21.lm_owf_password.length++;
1075 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1077 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1078 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1079 s.in.level, nt_errstr(status));
1080 ret = false;
1084 return ret;
1087 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1088 struct torture_context *tctx,
1089 struct policy_handle *handle,
1090 uint16_t level,
1091 uint32_t fields_present,
1092 char **password, uint8_t password_expired,
1093 bool use_setinfo2,
1094 bool *matched_expected_error)
1096 NTSTATUS status;
1097 NTSTATUS expected_error = NT_STATUS_OK;
1098 struct samr_SetUserInfo s;
1099 struct samr_SetUserInfo2 s2;
1100 union samr_UserInfo u;
1101 bool ret = true;
1102 DATA_BLOB session_key;
1103 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1104 struct MD5Context ctx;
1105 uint8_t confounder[16];
1106 char *newpass;
1107 struct samr_GetUserPwInfo pwp;
1108 struct samr_PwInfo info;
1109 int policy_min_pw_len = 0;
1110 const char *comment = NULL;
1111 uint8_t lm_hash[16], nt_hash[16];
1113 pwp.in.user_handle = handle;
1114 pwp.out.info = &info;
1116 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1117 if (NT_STATUS_IS_OK(status)) {
1118 policy_min_pw_len = pwp.out.info->min_password_length;
1120 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1122 if (use_setinfo2) {
1123 s2.in.user_handle = handle;
1124 s2.in.info = &u;
1125 s2.in.level = level;
1126 } else {
1127 s.in.user_handle = handle;
1128 s.in.info = &u;
1129 s.in.level = level;
1132 if (fields_present & SAMR_FIELD_COMMENT) {
1133 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1136 ZERO_STRUCT(u);
1138 switch (level) {
1139 case 18:
1140 E_md4hash(newpass, nt_hash);
1141 E_deshash(newpass, lm_hash);
1143 u.info18.nt_pwd_active = true;
1144 u.info18.lm_pwd_active = true;
1145 u.info18.password_expired = password_expired;
1147 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1148 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1150 break;
1151 case 21:
1152 E_md4hash(newpass, nt_hash);
1153 E_deshash(newpass, lm_hash);
1155 u.info21.fields_present = fields_present;
1156 u.info21.password_expired = password_expired;
1157 u.info21.comment.string = comment;
1159 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1160 u.info21.lm_owf_password.length = 16;
1161 u.info21.lm_owf_password.size = 16;
1162 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1163 u.info21.lm_password_set = true;
1166 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1167 u.info21.nt_owf_password.length = 16;
1168 u.info21.nt_owf_password.size = 16;
1169 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1170 u.info21.nt_password_set = true;
1173 break;
1174 case 23:
1175 u.info23.info.fields_present = fields_present;
1176 u.info23.info.password_expired = password_expired;
1177 u.info23.info.comment.string = comment;
1179 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1181 break;
1182 case 24:
1183 u.info24.password_expired = password_expired;
1185 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1187 break;
1188 case 25:
1189 u.info25.info.fields_present = fields_present;
1190 u.info25.info.password_expired = password_expired;
1191 u.info25.info.comment.string = comment;
1193 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1195 break;
1196 case 26:
1197 u.info26.password_expired = password_expired;
1199 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1201 break;
1204 status = dcerpc_fetch_session_key(p, &session_key);
1205 if (!NT_STATUS_IS_OK(status)) {
1206 printf("SetUserInfo level %u - no session key - %s\n",
1207 s.in.level, nt_errstr(status));
1208 return false;
1211 generate_random_buffer((uint8_t *)confounder, 16);
1213 MD5Init(&ctx);
1214 MD5Update(&ctx, confounder, 16);
1215 MD5Update(&ctx, session_key.data, session_key.length);
1216 MD5Final(confounded_session_key.data, &ctx);
1218 switch (level) {
1219 case 18:
1221 DATA_BLOB in,out;
1222 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1223 out = data_blob_talloc_zero(tctx, 16);
1224 sess_crypt_blob(&out, &in, &session_key, true);
1225 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1228 DATA_BLOB in,out;
1229 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1230 out = data_blob_talloc_zero(tctx, 16);
1231 sess_crypt_blob(&out, &in, &session_key, true);
1232 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1235 break;
1236 case 21:
1237 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1238 DATA_BLOB in,out;
1239 in = data_blob_const(u.info21.lm_owf_password.array,
1240 u.info21.lm_owf_password.length);
1241 out = data_blob_talloc_zero(tctx, 16);
1242 sess_crypt_blob(&out, &in, &session_key, true);
1243 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1245 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1246 DATA_BLOB in,out;
1247 in = data_blob_const(u.info21.nt_owf_password.array,
1248 u.info21.nt_owf_password.length);
1249 out = data_blob_talloc_zero(tctx, 16);
1250 sess_crypt_blob(&out, &in, &session_key, true);
1251 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1253 break;
1254 case 23:
1255 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1256 break;
1257 case 24:
1258 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1259 break;
1260 case 25:
1261 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1262 memcpy(&u.info25.password.data[516], confounder, 16);
1263 break;
1264 case 26:
1265 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1266 memcpy(&u.info26.password.data[516], confounder, 16);
1267 break;
1270 if (use_setinfo2) {
1271 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1272 } else {
1273 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1276 if (!NT_STATUS_IS_OK(status)) {
1277 if (fields_present == 0) {
1278 expected_error = NT_STATUS_INVALID_PARAMETER;
1280 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1281 expected_error = NT_STATUS_ACCESS_DENIED;
1285 if (!NT_STATUS_IS_OK(expected_error)) {
1286 if (use_setinfo2) {
1287 torture_assert_ntstatus_equal(tctx,
1288 s2.out.result,
1289 expected_error, "SetUserInfo2 failed");
1290 } else {
1291 torture_assert_ntstatus_equal(tctx,
1292 s.out.result,
1293 expected_error, "SetUserInfo failed");
1295 *matched_expected_error = true;
1296 return true;
1299 if (!NT_STATUS_IS_OK(status)) {
1300 printf("SetUserInfo%s level %u failed - %s\n",
1301 use_setinfo2 ? "2":"", level, nt_errstr(status));
1302 ret = false;
1303 } else {
1304 *password = newpass;
1307 return ret;
1310 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1311 struct policy_handle *handle)
1313 NTSTATUS status;
1314 struct samr_SetAliasInfo r;
1315 struct samr_QueryAliasInfo q;
1316 union samr_AliasInfo *info;
1317 uint16_t levels[] = {2, 3};
1318 int i;
1319 bool ret = true;
1321 /* Ignoring switch level 1, as that includes the number of members for the alias
1322 * and setting this to a wrong value might have negative consequences
1325 for (i=0;i<ARRAY_SIZE(levels);i++) {
1326 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1328 r.in.alias_handle = handle;
1329 r.in.level = levels[i];
1330 r.in.info = talloc(tctx, union samr_AliasInfo);
1331 switch (r.in.level) {
1332 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1333 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1334 "Test Description, should test I18N as well"); break;
1335 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1338 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1339 if (!NT_STATUS_IS_OK(status)) {
1340 printf("SetAliasInfo level %u failed - %s\n",
1341 levels[i], nt_errstr(status));
1342 ret = false;
1345 q.in.alias_handle = handle;
1346 q.in.level = levels[i];
1347 q.out.info = &info;
1349 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1350 if (!NT_STATUS_IS_OK(status)) {
1351 printf("QueryAliasInfo level %u failed - %s\n",
1352 levels[i], nt_errstr(status));
1353 ret = false;
1357 return ret;
1360 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1361 struct policy_handle *user_handle)
1363 struct samr_GetGroupsForUser r;
1364 struct samr_RidWithAttributeArray *rids = NULL;
1365 NTSTATUS status;
1367 torture_comment(tctx, "testing GetGroupsForUser\n");
1369 r.in.user_handle = user_handle;
1370 r.out.rids = &rids;
1372 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1373 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1375 return true;
1379 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1380 struct lsa_String *domain_name)
1382 NTSTATUS status;
1383 struct samr_GetDomPwInfo r;
1384 struct samr_PwInfo info;
1386 r.in.domain_name = domain_name;
1387 r.out.info = &info;
1389 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1391 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1392 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1394 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1395 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1397 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1398 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1400 r.in.domain_name->string = "\\\\__NONAME__";
1401 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1403 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1404 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1406 r.in.domain_name->string = "\\\\Builtin";
1407 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1409 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1410 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1412 return true;
1415 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1416 struct policy_handle *handle)
1418 NTSTATUS status;
1419 struct samr_GetUserPwInfo r;
1420 struct samr_PwInfo info;
1422 torture_comment(tctx, "Testing GetUserPwInfo\n");
1424 r.in.user_handle = handle;
1425 r.out.info = &info;
1427 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1428 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1430 return true;
1433 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1434 struct policy_handle *domain_handle, const char *name,
1435 uint32_t *rid)
1437 NTSTATUS status;
1438 struct samr_LookupNames n;
1439 struct lsa_String sname[2];
1440 struct samr_Ids rids, types;
1442 init_lsa_String(&sname[0], name);
1444 n.in.domain_handle = domain_handle;
1445 n.in.num_names = 1;
1446 n.in.names = sname;
1447 n.out.rids = &rids;
1448 n.out.types = &types;
1449 status = dcerpc_samr_LookupNames(p, tctx, &n);
1450 if (NT_STATUS_IS_OK(status)) {
1451 *rid = n.out.rids->ids[0];
1452 } else {
1453 return status;
1456 init_lsa_String(&sname[1], "xxNONAMExx");
1457 n.in.num_names = 2;
1458 status = dcerpc_samr_LookupNames(p, tctx, &n);
1459 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1460 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1461 if (NT_STATUS_IS_OK(status)) {
1462 return NT_STATUS_UNSUCCESSFUL;
1464 return status;
1467 n.in.num_names = 0;
1468 status = dcerpc_samr_LookupNames(p, tctx, &n);
1469 if (!NT_STATUS_IS_OK(status)) {
1470 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1471 return status;
1474 init_lsa_String(&sname[0], "xxNONAMExx");
1475 n.in.num_names = 1;
1476 status = dcerpc_samr_LookupNames(p, tctx, &n);
1477 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1478 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1479 if (NT_STATUS_IS_OK(status)) {
1480 return NT_STATUS_UNSUCCESSFUL;
1482 return status;
1485 init_lsa_String(&sname[0], "xxNONAMExx");
1486 init_lsa_String(&sname[1], "xxNONAME2xx");
1487 n.in.num_names = 2;
1488 status = dcerpc_samr_LookupNames(p, tctx, &n);
1489 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1490 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1491 if (NT_STATUS_IS_OK(status)) {
1492 return NT_STATUS_UNSUCCESSFUL;
1494 return status;
1497 return NT_STATUS_OK;
1500 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1501 struct torture_context *tctx,
1502 struct policy_handle *domain_handle,
1503 const char *name, struct policy_handle *user_handle)
1505 NTSTATUS status;
1506 struct samr_OpenUser r;
1507 uint32_t rid;
1509 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1510 if (!NT_STATUS_IS_OK(status)) {
1511 return status;
1514 r.in.domain_handle = domain_handle;
1515 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1516 r.in.rid = rid;
1517 r.out.user_handle = user_handle;
1518 status = dcerpc_samr_OpenUser(p, tctx, &r);
1519 if (!NT_STATUS_IS_OK(status)) {
1520 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1523 return status;
1526 #if 0
1527 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1528 struct torture_context *tctx,
1529 struct policy_handle *handle)
1531 NTSTATUS status;
1532 struct samr_ChangePasswordUser r;
1533 bool ret = true;
1534 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1535 struct policy_handle user_handle;
1536 char *oldpass = "test";
1537 char *newpass = "test2";
1538 uint8_t old_nt_hash[16], new_nt_hash[16];
1539 uint8_t old_lm_hash[16], new_lm_hash[16];
1541 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1542 if (!NT_STATUS_IS_OK(status)) {
1543 return false;
1546 printf("Testing ChangePasswordUser for user 'testuser'\n");
1548 printf("old password: %s\n", oldpass);
1549 printf("new password: %s\n", newpass);
1551 E_md4hash(oldpass, old_nt_hash);
1552 E_md4hash(newpass, new_nt_hash);
1553 E_deshash(oldpass, old_lm_hash);
1554 E_deshash(newpass, new_lm_hash);
1556 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1557 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1558 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1559 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1560 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1561 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1563 r.in.handle = &user_handle;
1564 r.in.lm_present = 1;
1565 r.in.old_lm_crypted = &hash1;
1566 r.in.new_lm_crypted = &hash2;
1567 r.in.nt_present = 1;
1568 r.in.old_nt_crypted = &hash3;
1569 r.in.new_nt_crypted = &hash4;
1570 r.in.cross1_present = 1;
1571 r.in.nt_cross = &hash5;
1572 r.in.cross2_present = 1;
1573 r.in.lm_cross = &hash6;
1575 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1576 if (!NT_STATUS_IS_OK(status)) {
1577 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1578 ret = false;
1581 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1582 ret = false;
1585 return ret;
1587 #endif
1589 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1590 const char *acct_name,
1591 struct policy_handle *handle, char **password)
1593 NTSTATUS status;
1594 struct samr_ChangePasswordUser r;
1595 bool ret = true;
1596 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1597 struct policy_handle user_handle;
1598 char *oldpass;
1599 uint8_t old_nt_hash[16], new_nt_hash[16];
1600 uint8_t old_lm_hash[16], new_lm_hash[16];
1601 bool changed = true;
1603 char *newpass;
1604 struct samr_GetUserPwInfo pwp;
1605 struct samr_PwInfo info;
1606 int policy_min_pw_len = 0;
1608 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1609 if (!NT_STATUS_IS_OK(status)) {
1610 return false;
1612 pwp.in.user_handle = &user_handle;
1613 pwp.out.info = &info;
1615 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1616 if (NT_STATUS_IS_OK(status)) {
1617 policy_min_pw_len = pwp.out.info->min_password_length;
1619 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1621 torture_comment(tctx, "Testing ChangePasswordUser\n");
1623 torture_assert(tctx, *password != NULL,
1624 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1626 oldpass = *password;
1628 E_md4hash(oldpass, old_nt_hash);
1629 E_md4hash(newpass, new_nt_hash);
1630 E_deshash(oldpass, old_lm_hash);
1631 E_deshash(newpass, new_lm_hash);
1633 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1634 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1635 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1636 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1637 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1638 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1640 r.in.user_handle = &user_handle;
1641 r.in.lm_present = 1;
1642 /* Break the LM hash */
1643 hash1.hash[0]++;
1644 r.in.old_lm_crypted = &hash1;
1645 r.in.new_lm_crypted = &hash2;
1646 r.in.nt_present = 1;
1647 r.in.old_nt_crypted = &hash3;
1648 r.in.new_nt_crypted = &hash4;
1649 r.in.cross1_present = 1;
1650 r.in.nt_cross = &hash5;
1651 r.in.cross2_present = 1;
1652 r.in.lm_cross = &hash6;
1654 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1655 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1656 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1658 /* Unbreak the LM hash */
1659 hash1.hash[0]--;
1661 r.in.user_handle = &user_handle;
1662 r.in.lm_present = 1;
1663 r.in.old_lm_crypted = &hash1;
1664 r.in.new_lm_crypted = &hash2;
1665 /* Break the NT hash */
1666 hash3.hash[0]--;
1667 r.in.nt_present = 1;
1668 r.in.old_nt_crypted = &hash3;
1669 r.in.new_nt_crypted = &hash4;
1670 r.in.cross1_present = 1;
1671 r.in.nt_cross = &hash5;
1672 r.in.cross2_present = 1;
1673 r.in.lm_cross = &hash6;
1675 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1676 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1677 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1679 /* Unbreak the NT hash */
1680 hash3.hash[0]--;
1682 r.in.user_handle = &user_handle;
1683 r.in.lm_present = 1;
1684 r.in.old_lm_crypted = &hash1;
1685 r.in.new_lm_crypted = &hash2;
1686 r.in.nt_present = 1;
1687 r.in.old_nt_crypted = &hash3;
1688 r.in.new_nt_crypted = &hash4;
1689 r.in.cross1_present = 1;
1690 r.in.nt_cross = &hash5;
1691 r.in.cross2_present = 1;
1692 /* Break the LM cross */
1693 hash6.hash[0]++;
1694 r.in.lm_cross = &hash6;
1696 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1697 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1698 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1699 ret = false;
1702 /* Unbreak the LM cross */
1703 hash6.hash[0]--;
1705 r.in.user_handle = &user_handle;
1706 r.in.lm_present = 1;
1707 r.in.old_lm_crypted = &hash1;
1708 r.in.new_lm_crypted = &hash2;
1709 r.in.nt_present = 1;
1710 r.in.old_nt_crypted = &hash3;
1711 r.in.new_nt_crypted = &hash4;
1712 r.in.cross1_present = 1;
1713 /* Break the NT cross */
1714 hash5.hash[0]++;
1715 r.in.nt_cross = &hash5;
1716 r.in.cross2_present = 1;
1717 r.in.lm_cross = &hash6;
1719 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1720 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1721 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1722 ret = false;
1725 /* Unbreak the NT cross */
1726 hash5.hash[0]--;
1729 /* Reset the hashes to not broken values */
1730 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1731 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1732 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1733 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1734 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1735 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1737 r.in.user_handle = &user_handle;
1738 r.in.lm_present = 1;
1739 r.in.old_lm_crypted = &hash1;
1740 r.in.new_lm_crypted = &hash2;
1741 r.in.nt_present = 1;
1742 r.in.old_nt_crypted = &hash3;
1743 r.in.new_nt_crypted = &hash4;
1744 r.in.cross1_present = 1;
1745 r.in.nt_cross = &hash5;
1746 r.in.cross2_present = 0;
1747 r.in.lm_cross = NULL;
1749 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1750 if (NT_STATUS_IS_OK(status)) {
1751 changed = true;
1752 *password = newpass;
1753 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1754 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1755 ret = false;
1758 oldpass = newpass;
1759 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1761 E_md4hash(oldpass, old_nt_hash);
1762 E_md4hash(newpass, new_nt_hash);
1763 E_deshash(oldpass, old_lm_hash);
1764 E_deshash(newpass, new_lm_hash);
1767 /* Reset the hashes to not broken values */
1768 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1769 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1770 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1771 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1772 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1773 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1775 r.in.user_handle = &user_handle;
1776 r.in.lm_present = 1;
1777 r.in.old_lm_crypted = &hash1;
1778 r.in.new_lm_crypted = &hash2;
1779 r.in.nt_present = 1;
1780 r.in.old_nt_crypted = &hash3;
1781 r.in.new_nt_crypted = &hash4;
1782 r.in.cross1_present = 0;
1783 r.in.nt_cross = NULL;
1784 r.in.cross2_present = 1;
1785 r.in.lm_cross = &hash6;
1787 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1788 if (NT_STATUS_IS_OK(status)) {
1789 changed = true;
1790 *password = newpass;
1791 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1792 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1793 ret = false;
1796 oldpass = newpass;
1797 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1799 E_md4hash(oldpass, old_nt_hash);
1800 E_md4hash(newpass, new_nt_hash);
1801 E_deshash(oldpass, old_lm_hash);
1802 E_deshash(newpass, new_lm_hash);
1805 /* Reset the hashes to not broken values */
1806 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1807 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1808 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1809 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1810 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1811 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1813 r.in.user_handle = &user_handle;
1814 r.in.lm_present = 1;
1815 r.in.old_lm_crypted = &hash1;
1816 r.in.new_lm_crypted = &hash2;
1817 r.in.nt_present = 1;
1818 r.in.old_nt_crypted = &hash3;
1819 r.in.new_nt_crypted = &hash4;
1820 r.in.cross1_present = 1;
1821 r.in.nt_cross = &hash5;
1822 r.in.cross2_present = 1;
1823 r.in.lm_cross = &hash6;
1825 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1826 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1827 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1828 } else if (!NT_STATUS_IS_OK(status)) {
1829 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1830 ret = false;
1831 } else {
1832 changed = true;
1833 *password = newpass;
1836 r.in.user_handle = &user_handle;
1837 r.in.lm_present = 1;
1838 r.in.old_lm_crypted = &hash1;
1839 r.in.new_lm_crypted = &hash2;
1840 r.in.nt_present = 1;
1841 r.in.old_nt_crypted = &hash3;
1842 r.in.new_nt_crypted = &hash4;
1843 r.in.cross1_present = 1;
1844 r.in.nt_cross = &hash5;
1845 r.in.cross2_present = 1;
1846 r.in.lm_cross = &hash6;
1848 if (changed) {
1849 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1850 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1851 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1852 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1853 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1854 ret = false;
1859 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1860 ret = false;
1863 return ret;
1867 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1868 const char *acct_name,
1869 struct policy_handle *handle, char **password)
1871 NTSTATUS status;
1872 struct samr_OemChangePasswordUser2 r;
1873 bool ret = true;
1874 struct samr_Password lm_verifier;
1875 struct samr_CryptPassword lm_pass;
1876 struct lsa_AsciiString server, account, account_bad;
1877 char *oldpass;
1878 char *newpass;
1879 uint8_t old_lm_hash[16], new_lm_hash[16];
1881 struct samr_GetDomPwInfo dom_pw_info;
1882 struct samr_PwInfo info;
1883 int policy_min_pw_len = 0;
1885 struct lsa_String domain_name;
1887 domain_name.string = "";
1888 dom_pw_info.in.domain_name = &domain_name;
1889 dom_pw_info.out.info = &info;
1891 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1893 torture_assert(tctx, *password != NULL,
1894 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1896 oldpass = *password;
1898 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1899 if (NT_STATUS_IS_OK(status)) {
1900 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1903 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1905 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1906 account.string = acct_name;
1908 E_deshash(oldpass, old_lm_hash);
1909 E_deshash(newpass, new_lm_hash);
1911 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1912 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1913 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1915 r.in.server = &server;
1916 r.in.account = &account;
1917 r.in.password = &lm_pass;
1918 r.in.hash = &lm_verifier;
1920 /* Break the verification */
1921 lm_verifier.hash[0]++;
1923 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1925 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1926 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1927 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1928 nt_errstr(status));
1929 ret = false;
1932 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1933 /* Break the old password */
1934 old_lm_hash[0]++;
1935 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1936 /* unbreak it for the next operation */
1937 old_lm_hash[0]--;
1938 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1940 r.in.server = &server;
1941 r.in.account = &account;
1942 r.in.password = &lm_pass;
1943 r.in.hash = &lm_verifier;
1945 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1947 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1948 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1949 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1950 nt_errstr(status));
1951 ret = false;
1954 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1955 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1957 r.in.server = &server;
1958 r.in.account = &account;
1959 r.in.password = &lm_pass;
1960 r.in.hash = NULL;
1962 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1964 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1965 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1966 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1967 nt_errstr(status));
1968 ret = false;
1971 /* This shouldn't be a valid name */
1972 account_bad.string = TEST_ACCOUNT_NAME "XX";
1973 r.in.account = &account_bad;
1975 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1977 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1978 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1979 nt_errstr(status));
1980 ret = false;
1983 /* This shouldn't be a valid name */
1984 account_bad.string = TEST_ACCOUNT_NAME "XX";
1985 r.in.account = &account_bad;
1986 r.in.password = &lm_pass;
1987 r.in.hash = &lm_verifier;
1989 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1991 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1992 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1993 nt_errstr(status));
1994 ret = false;
1997 /* This shouldn't be a valid name */
1998 account_bad.string = TEST_ACCOUNT_NAME "XX";
1999 r.in.account = &account_bad;
2000 r.in.password = NULL;
2001 r.in.hash = &lm_verifier;
2003 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2005 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2006 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2007 nt_errstr(status));
2008 ret = false;
2011 E_deshash(oldpass, old_lm_hash);
2012 E_deshash(newpass, new_lm_hash);
2014 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2015 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2016 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2018 r.in.server = &server;
2019 r.in.account = &account;
2020 r.in.password = &lm_pass;
2021 r.in.hash = &lm_verifier;
2023 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2024 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2025 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2026 } else if (!NT_STATUS_IS_OK(status)) {
2027 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2028 ret = false;
2029 } else {
2030 *password = newpass;
2033 return ret;
2037 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2038 const char *acct_name,
2039 char **password,
2040 char *newpass, bool allow_password_restriction)
2042 NTSTATUS status;
2043 struct samr_ChangePasswordUser2 r;
2044 bool ret = true;
2045 struct lsa_String server, account;
2046 struct samr_CryptPassword nt_pass, lm_pass;
2047 struct samr_Password nt_verifier, lm_verifier;
2048 char *oldpass;
2049 uint8_t old_nt_hash[16], new_nt_hash[16];
2050 uint8_t old_lm_hash[16], new_lm_hash[16];
2052 struct samr_GetDomPwInfo dom_pw_info;
2053 struct samr_PwInfo info;
2055 struct lsa_String domain_name;
2057 domain_name.string = "";
2058 dom_pw_info.in.domain_name = &domain_name;
2059 dom_pw_info.out.info = &info;
2061 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2063 torture_assert(tctx, *password != NULL,
2064 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2065 oldpass = *password;
2067 if (!newpass) {
2068 int policy_min_pw_len = 0;
2069 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2070 if (NT_STATUS_IS_OK(status)) {
2071 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2074 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2077 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2078 init_lsa_String(&account, acct_name);
2080 E_md4hash(oldpass, old_nt_hash);
2081 E_md4hash(newpass, new_nt_hash);
2083 E_deshash(oldpass, old_lm_hash);
2084 E_deshash(newpass, new_lm_hash);
2086 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2087 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2088 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2090 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2091 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2092 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2094 r.in.server = &server;
2095 r.in.account = &account;
2096 r.in.nt_password = &nt_pass;
2097 r.in.nt_verifier = &nt_verifier;
2098 r.in.lm_change = 1;
2099 r.in.lm_password = &lm_pass;
2100 r.in.lm_verifier = &lm_verifier;
2102 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2103 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2104 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2105 } else if (!NT_STATUS_IS_OK(status)) {
2106 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2107 ret = false;
2108 } else {
2109 *password = newpass;
2112 return ret;
2116 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2117 const char *account_string,
2118 int policy_min_pw_len,
2119 char **password,
2120 const char *newpass,
2121 NTTIME last_password_change,
2122 bool handle_reject_reason)
2124 NTSTATUS status;
2125 struct samr_ChangePasswordUser3 r;
2126 bool ret = true;
2127 struct lsa_String server, account, account_bad;
2128 struct samr_CryptPassword nt_pass, lm_pass;
2129 struct samr_Password nt_verifier, lm_verifier;
2130 char *oldpass;
2131 uint8_t old_nt_hash[16], new_nt_hash[16];
2132 uint8_t old_lm_hash[16], new_lm_hash[16];
2133 NTTIME t;
2134 struct samr_DomInfo1 *dominfo = NULL;
2135 struct samr_ChangeReject *reject = NULL;
2137 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2139 if (newpass == NULL) {
2140 do {
2141 if (policy_min_pw_len == 0) {
2142 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2143 } else {
2144 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2146 } while (check_password_quality(newpass) == false);
2147 } else {
2148 torture_comment(tctx, "Using password '%s'\n", newpass);
2151 torture_assert(tctx, *password != NULL,
2152 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2154 oldpass = *password;
2155 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2156 init_lsa_String(&account, account_string);
2158 E_md4hash(oldpass, old_nt_hash);
2159 E_md4hash(newpass, new_nt_hash);
2161 E_deshash(oldpass, old_lm_hash);
2162 E_deshash(newpass, new_lm_hash);
2164 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2165 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2166 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2168 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2169 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2170 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2172 /* Break the verification */
2173 nt_verifier.hash[0]++;
2175 r.in.server = &server;
2176 r.in.account = &account;
2177 r.in.nt_password = &nt_pass;
2178 r.in.nt_verifier = &nt_verifier;
2179 r.in.lm_change = 1;
2180 r.in.lm_password = &lm_pass;
2181 r.in.lm_verifier = &lm_verifier;
2182 r.in.password3 = NULL;
2183 r.out.dominfo = &dominfo;
2184 r.out.reject = &reject;
2186 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2187 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2188 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2189 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2190 nt_errstr(status));
2191 ret = false;
2194 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2195 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2196 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2198 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2199 /* Break the NT hash */
2200 old_nt_hash[0]++;
2201 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2202 /* Unbreak it again */
2203 old_nt_hash[0]--;
2204 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2206 r.in.server = &server;
2207 r.in.account = &account;
2208 r.in.nt_password = &nt_pass;
2209 r.in.nt_verifier = &nt_verifier;
2210 r.in.lm_change = 1;
2211 r.in.lm_password = &lm_pass;
2212 r.in.lm_verifier = &lm_verifier;
2213 r.in.password3 = NULL;
2214 r.out.dominfo = &dominfo;
2215 r.out.reject = &reject;
2217 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2218 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2219 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2220 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2221 nt_errstr(status));
2222 ret = false;
2225 /* This shouldn't be a valid name */
2226 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2228 r.in.account = &account_bad;
2229 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2230 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2231 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2232 nt_errstr(status));
2233 ret = false;
2236 E_md4hash(oldpass, old_nt_hash);
2237 E_md4hash(newpass, new_nt_hash);
2239 E_deshash(oldpass, old_lm_hash);
2240 E_deshash(newpass, new_lm_hash);
2242 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2243 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2244 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2246 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2247 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2248 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2250 r.in.server = &server;
2251 r.in.account = &account;
2252 r.in.nt_password = &nt_pass;
2253 r.in.nt_verifier = &nt_verifier;
2254 r.in.lm_change = 1;
2255 r.in.lm_password = &lm_pass;
2256 r.in.lm_verifier = &lm_verifier;
2257 r.in.password3 = NULL;
2258 r.out.dominfo = &dominfo;
2259 r.out.reject = &reject;
2261 unix_to_nt_time(&t, time(NULL));
2263 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2265 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2266 && dominfo
2267 && reject
2268 && handle_reject_reason
2269 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2270 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2272 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2273 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2274 SAMR_REJECT_OTHER, reject->reason);
2275 return false;
2279 /* We tested the order of precendence which is as follows:
2281 * pwd min_age
2282 * pwd length
2283 * pwd complexity
2284 * pwd history
2286 Guenther */
2288 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2289 (last_password_change + dominfo->min_password_age > t)) {
2291 if (reject->reason != SAMR_REJECT_OTHER) {
2292 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2293 SAMR_REJECT_OTHER, reject->reason);
2294 return false;
2297 } else if ((dominfo->min_password_length > 0) &&
2298 (strlen(newpass) < dominfo->min_password_length)) {
2300 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2301 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2302 SAMR_REJECT_TOO_SHORT, reject->reason);
2303 return false;
2306 } else if ((dominfo->password_history_length > 0) &&
2307 strequal(oldpass, newpass)) {
2309 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2310 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2311 SAMR_REJECT_IN_HISTORY, reject->reason);
2312 return false;
2314 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2316 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2317 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2318 SAMR_REJECT_COMPLEXITY, reject->reason);
2319 return false;
2324 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2325 /* retry with adjusted size */
2326 return test_ChangePasswordUser3(p, tctx, account_string,
2327 dominfo->min_password_length,
2328 password, NULL, 0, false);
2332 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2333 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2334 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2335 SAMR_REJECT_OTHER, reject->reason);
2336 return false;
2338 /* Perhaps the server has a 'min password age' set? */
2340 } else {
2341 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2342 *password = talloc_strdup(tctx, newpass);
2345 return ret;
2348 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2349 const char *account_string,
2350 struct policy_handle *handle,
2351 char **password)
2353 NTSTATUS status;
2354 struct samr_ChangePasswordUser3 r;
2355 struct samr_SetUserInfo s;
2356 union samr_UserInfo u;
2357 DATA_BLOB session_key;
2358 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2359 uint8_t confounder[16];
2360 struct MD5Context ctx;
2362 bool ret = true;
2363 struct lsa_String server, account;
2364 struct samr_CryptPassword nt_pass;
2365 struct samr_Password nt_verifier;
2366 DATA_BLOB new_random_pass;
2367 char *newpass;
2368 char *oldpass;
2369 uint8_t old_nt_hash[16], new_nt_hash[16];
2370 NTTIME t;
2371 struct samr_DomInfo1 *dominfo = NULL;
2372 struct samr_ChangeReject *reject = NULL;
2374 new_random_pass = samr_very_rand_pass(tctx, 128);
2376 torture_assert(tctx, *password != NULL,
2377 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2379 oldpass = *password;
2380 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2381 init_lsa_String(&account, account_string);
2383 s.in.user_handle = handle;
2384 s.in.info = &u;
2385 s.in.level = 25;
2387 ZERO_STRUCT(u);
2389 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2391 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2393 status = dcerpc_fetch_session_key(p, &session_key);
2394 if (!NT_STATUS_IS_OK(status)) {
2395 printf("SetUserInfo level %u - no session key - %s\n",
2396 s.in.level, nt_errstr(status));
2397 return false;
2400 generate_random_buffer((uint8_t *)confounder, 16);
2402 MD5Init(&ctx);
2403 MD5Update(&ctx, confounder, 16);
2404 MD5Update(&ctx, session_key.data, session_key.length);
2405 MD5Final(confounded_session_key.data, &ctx);
2407 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2408 memcpy(&u.info25.password.data[516], confounder, 16);
2410 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2412 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2413 if (!NT_STATUS_IS_OK(status)) {
2414 printf("SetUserInfo level %u failed - %s\n",
2415 s.in.level, nt_errstr(status));
2416 ret = false;
2419 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2421 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2423 new_random_pass = samr_very_rand_pass(tctx, 128);
2425 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2427 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2428 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2429 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2431 r.in.server = &server;
2432 r.in.account = &account;
2433 r.in.nt_password = &nt_pass;
2434 r.in.nt_verifier = &nt_verifier;
2435 r.in.lm_change = 0;
2436 r.in.lm_password = NULL;
2437 r.in.lm_verifier = NULL;
2438 r.in.password3 = NULL;
2439 r.out.dominfo = &dominfo;
2440 r.out.reject = &reject;
2442 unix_to_nt_time(&t, time(NULL));
2444 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2446 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2447 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2448 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2449 SAMR_REJECT_OTHER, reject->reason);
2450 return false;
2452 /* Perhaps the server has a 'min password age' set? */
2454 } else if (!NT_STATUS_IS_OK(status)) {
2455 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2456 ret = false;
2459 newpass = samr_rand_pass(tctx, 128);
2461 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2463 E_md4hash(newpass, new_nt_hash);
2465 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2466 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2467 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2469 r.in.server = &server;
2470 r.in.account = &account;
2471 r.in.nt_password = &nt_pass;
2472 r.in.nt_verifier = &nt_verifier;
2473 r.in.lm_change = 0;
2474 r.in.lm_password = NULL;
2475 r.in.lm_verifier = NULL;
2476 r.in.password3 = NULL;
2477 r.out.dominfo = &dominfo;
2478 r.out.reject = &reject;
2480 unix_to_nt_time(&t, time(NULL));
2482 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2484 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2485 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2486 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2487 SAMR_REJECT_OTHER, reject->reason);
2488 return false;
2490 /* Perhaps the server has a 'min password age' set? */
2492 } else {
2493 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2494 *password = talloc_strdup(tctx, newpass);
2497 return ret;
2501 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2502 struct policy_handle *alias_handle)
2504 struct samr_GetMembersInAlias r;
2505 struct lsa_SidArray sids;
2506 NTSTATUS status;
2508 torture_comment(tctx, "Testing GetMembersInAlias\n");
2510 r.in.alias_handle = alias_handle;
2511 r.out.sids = &sids;
2513 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2514 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2516 return true;
2519 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2520 struct policy_handle *alias_handle,
2521 const struct dom_sid *domain_sid)
2523 struct samr_AddAliasMember r;
2524 struct samr_DeleteAliasMember d;
2525 NTSTATUS status;
2526 struct dom_sid *sid;
2528 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2530 torture_comment(tctx, "testing AddAliasMember\n");
2531 r.in.alias_handle = alias_handle;
2532 r.in.sid = sid;
2534 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2535 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2537 d.in.alias_handle = alias_handle;
2538 d.in.sid = sid;
2540 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2541 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2543 return true;
2546 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2547 struct policy_handle *alias_handle)
2549 struct samr_AddMultipleMembersToAlias a;
2550 struct samr_RemoveMultipleMembersFromAlias r;
2551 NTSTATUS status;
2552 struct lsa_SidArray sids;
2554 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2555 a.in.alias_handle = alias_handle;
2556 a.in.sids = &sids;
2558 sids.num_sids = 3;
2559 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2561 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2562 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2563 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2565 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2566 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2569 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2570 r.in.alias_handle = alias_handle;
2571 r.in.sids = &sids;
2573 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2574 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2576 /* strange! removing twice doesn't give any error */
2577 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2578 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2580 /* but removing an alias that isn't there does */
2581 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2583 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2584 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2586 return true;
2589 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2590 struct policy_handle *user_handle)
2592 struct samr_TestPrivateFunctionsUser r;
2593 NTSTATUS status;
2595 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2597 r.in.user_handle = user_handle;
2599 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2600 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2602 return true;
2605 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2606 struct torture_context *tctx,
2607 struct policy_handle *handle,
2608 bool use_info2,
2609 NTTIME *pwdlastset)
2611 NTSTATUS status;
2612 uint16_t levels[] = { /* 3, */ 5, 21 };
2613 int i;
2614 NTTIME pwdlastset3 = 0;
2615 NTTIME pwdlastset5 = 0;
2616 NTTIME pwdlastset21 = 0;
2618 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2619 use_info2 ? "2":"");
2621 for (i=0; i<ARRAY_SIZE(levels); i++) {
2623 struct samr_QueryUserInfo r;
2624 struct samr_QueryUserInfo2 r2;
2625 union samr_UserInfo *info;
2627 if (use_info2) {
2628 r2.in.user_handle = handle;
2629 r2.in.level = levels[i];
2630 r2.out.info = &info;
2631 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2633 } else {
2634 r.in.user_handle = handle;
2635 r.in.level = levels[i];
2636 r.out.info = &info;
2637 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2640 if (!NT_STATUS_IS_OK(status) &&
2641 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2642 printf("QueryUserInfo%s level %u failed - %s\n",
2643 use_info2 ? "2":"", levels[i], nt_errstr(status));
2644 return false;
2647 switch (levels[i]) {
2648 case 3:
2649 pwdlastset3 = info->info3.last_password_change;
2650 break;
2651 case 5:
2652 pwdlastset5 = info->info5.last_password_change;
2653 break;
2654 case 21:
2655 pwdlastset21 = info->info21.last_password_change;
2656 break;
2657 default:
2658 return false;
2661 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2662 "pwdlastset mixup"); */
2663 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2664 "pwdlastset mixup");
2666 *pwdlastset = pwdlastset21;
2668 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2670 return true;
2673 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2674 struct cli_credentials *machine_credentials,
2675 struct cli_credentials *test_credentials,
2676 struct creds_CredentialState *creds,
2677 NTSTATUS expected_result)
2679 NTSTATUS status;
2680 struct netr_LogonSamLogon r;
2681 struct netr_Authenticator auth, auth2;
2682 union netr_LogonLevel logon;
2683 union netr_Validation validation;
2684 uint8_t authoritative;
2685 struct netr_NetworkInfo ninfo;
2686 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2687 int flags = CLI_CRED_NTLM_AUTH;
2689 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2690 flags |= CLI_CRED_LANMAN_AUTH;
2693 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2694 flags |= CLI_CRED_NTLMv2_AUTH;
2697 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2698 &ninfo.identity_info.account_name.string,
2699 &ninfo.identity_info.domain_name.string);
2701 generate_random_buffer(ninfo.challenge,
2702 sizeof(ninfo.challenge));
2703 chal = data_blob_const(ninfo.challenge,
2704 sizeof(ninfo.challenge));
2706 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2707 cli_credentials_get_domain(machine_credentials));
2709 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2710 &flags,
2711 chal,
2712 names_blob,
2713 &lm_resp, &nt_resp,
2714 NULL, NULL);
2715 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2717 ninfo.lm.data = lm_resp.data;
2718 ninfo.lm.length = lm_resp.length;
2720 ninfo.nt.data = nt_resp.data;
2721 ninfo.nt.length = nt_resp.length;
2723 ninfo.identity_info.parameter_control =
2724 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2725 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2726 ninfo.identity_info.logon_id_low = 0;
2727 ninfo.identity_info.logon_id_high = 0;
2728 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2730 logon.network = &ninfo;
2732 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2733 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2734 r.in.credential = &auth;
2735 r.in.return_authenticator = &auth2;
2736 r.in.logon_level = 2;
2737 r.in.logon = &logon;
2738 r.out.validation = &validation;
2739 r.out.authoritative = &authoritative;
2741 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2743 ZERO_STRUCT(auth2);
2744 creds_client_authenticator(creds, &auth);
2746 r.in.validation_level = 2;
2748 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2749 if (!NT_STATUS_IS_OK(status)) {
2750 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2751 return true;
2752 } else {
2753 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2756 torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred),
2757 "Credential chaining failed");
2759 return true;
2762 static bool test_SamLogon(struct torture_context *tctx,
2763 struct dcerpc_pipe *p,
2764 struct cli_credentials *machine_credentials,
2765 struct cli_credentials *test_credentials,
2766 NTSTATUS expected_result)
2768 struct creds_CredentialState *creds;
2770 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2771 return false;
2774 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2775 creds, expected_result);
2778 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2779 struct dcerpc_pipe *p,
2780 struct cli_credentials *machine_creds,
2781 const char *acct_name,
2782 char *password,
2783 NTSTATUS expected_samlogon_result)
2785 bool ret = true;
2786 struct cli_credentials *test_credentials;
2788 test_credentials = cli_credentials_init(tctx);
2790 cli_credentials_set_workstation(test_credentials,
2791 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2792 cli_credentials_set_domain(test_credentials,
2793 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2794 cli_credentials_set_username(test_credentials,
2795 acct_name, CRED_SPECIFIED);
2796 cli_credentials_set_password(test_credentials,
2797 password, CRED_SPECIFIED);
2798 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2800 printf("testing samlogon as %s@%s password: %s\n",
2801 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2803 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2804 expected_samlogon_result)) {
2805 torture_warning(tctx, "new password did not work\n");
2806 ret = false;
2809 return ret;
2812 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2813 struct dcerpc_pipe *np,
2814 struct torture_context *tctx,
2815 struct policy_handle *handle,
2816 uint16_t level,
2817 uint32_t fields_present,
2818 uint8_t password_expired,
2819 bool *matched_expected_error,
2820 bool use_setinfo2,
2821 const char *acct_name,
2822 char **password,
2823 struct cli_credentials *machine_creds,
2824 bool use_queryinfo2,
2825 NTTIME *pwdlastset,
2826 NTSTATUS expected_samlogon_result)
2828 const char *fields = NULL;
2829 bool ret = true;
2831 switch (level) {
2832 case 21:
2833 case 23:
2834 case 25:
2835 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2836 fields_present);
2837 break;
2838 default:
2839 break;
2842 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2843 "(password_expired: %d) %s\n",
2844 use_setinfo2 ? "2":"", level, password_expired,
2845 fields ? fields : "");
2847 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2848 fields_present,
2849 password,
2850 password_expired,
2851 use_setinfo2,
2852 matched_expected_error)) {
2853 ret = false;
2856 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2857 use_queryinfo2,
2858 pwdlastset)) {
2859 ret = false;
2862 if (*matched_expected_error == true) {
2863 return ret;
2866 if (!test_SamLogon_with_creds(tctx, np,
2867 machine_creds,
2868 acct_name,
2869 *password,
2870 expected_samlogon_result)) {
2871 ret = false;
2874 return ret;
2877 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2878 struct torture_context *tctx,
2879 uint32_t acct_flags,
2880 const char *acct_name,
2881 struct policy_handle *handle,
2882 char **password,
2883 struct cli_credentials *machine_credentials)
2885 int s = 0, q = 0, f = 0, l = 0, z = 0;
2886 bool ret = true;
2887 int delay = 500000;
2888 bool set_levels[] = { false, true };
2889 bool query_levels[] = { false, true };
2890 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2891 uint32_t nonzeros[] = { 1, 24 };
2892 uint32_t fields_present[] = {
2894 SAMR_FIELD_EXPIRED_FLAG,
2895 SAMR_FIELD_LAST_PWD_CHANGE,
2896 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2897 SAMR_FIELD_COMMENT,
2898 SAMR_FIELD_NT_PASSWORD_PRESENT,
2899 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2900 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2901 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2902 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2903 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2904 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2906 NTSTATUS status;
2907 struct dcerpc_pipe *np = NULL;
2909 if (torture_setting_bool(tctx, "samba3", false)) {
2910 delay = 1000000;
2911 printf("Samba3 has second granularity, setting delay to: %d\n",
2912 delay);
2915 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2916 if (!NT_STATUS_IS_OK(status)) {
2917 return false;
2920 /* set to 1 to enable testing for all possible opcode
2921 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2922 combinations */
2923 #if 0
2924 #define TEST_SET_LEVELS 1
2925 #define TEST_QUERY_LEVELS 1
2926 #endif
2927 for (l=0; l<ARRAY_SIZE(levels); l++) {
2928 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2929 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2930 #ifdef TEST_SET_LEVELS
2931 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2932 #endif
2933 #ifdef TEST_QUERY_LEVELS
2934 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2935 #endif
2936 NTTIME pwdlastset_old = 0;
2937 NTTIME pwdlastset_new = 0;
2938 bool matched_expected_error = false;
2939 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2941 torture_comment(tctx, "------------------------------\n"
2942 "Testing pwdLastSet attribute for flags: 0x%08x "
2943 "(s: %d (l: %d), q: %d)\n",
2944 acct_flags, s, levels[l], q);
2946 switch (levels[l]) {
2947 case 21:
2948 case 23:
2949 case 25:
2950 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2951 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2952 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2954 break;
2958 /* set #1 */
2960 /* set a password and force password change (pwdlastset 0) by
2961 * setting the password expired flag to a non-0 value */
2963 if (!test_SetPassword_level(p, np, tctx, handle,
2964 levels[l],
2965 fields_present[f],
2966 nonzeros[z],
2967 &matched_expected_error,
2968 set_levels[s],
2969 acct_name,
2970 password,
2971 machine_credentials,
2972 query_levels[q],
2973 &pwdlastset_old,
2974 expected_samlogon_result)) {
2975 ret = false;
2978 if (matched_expected_error == true) {
2979 /* skipping on expected failure */
2980 continue;
2983 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2984 * set without the SAMR_FIELD_EXPIRED_FLAG */
2986 switch (levels[l]) {
2987 case 21:
2988 case 23:
2989 case 25:
2990 if ((pwdlastset_new != 0) &&
2991 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2992 torture_comment(tctx, "not considering a non-0 "
2993 "pwdLastSet as a an error as the "
2994 "SAMR_FIELD_EXPIRED_FLAG has not "
2995 "been set\n");
2996 break;
2998 default:
2999 if (pwdlastset_new != 0) {
3000 torture_warning(tctx, "pwdLastSet test failed: "
3001 "expected pwdLastSet 0 but got %lld\n",
3002 pwdlastset_old);
3003 ret = false;
3005 break;
3008 switch (levels[l]) {
3009 case 21:
3010 case 23:
3011 case 25:
3012 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3013 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3014 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3015 (pwdlastset_old >= pwdlastset_new)) {
3016 torture_warning(tctx, "pwdlastset not increasing\n");
3017 ret = false;
3019 break;
3020 default:
3021 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3022 (pwdlastset_old >= pwdlastset_new)) {
3023 torture_warning(tctx, "pwdlastset not increasing\n");
3024 ret = false;
3026 break;
3029 usleep(delay);
3031 /* set #2 */
3033 /* set a password, pwdlastset needs to get updated (increased
3034 * value), password_expired value used here is 0 */
3036 if (!test_SetPassword_level(p, np, tctx, handle,
3037 levels[l],
3038 fields_present[f],
3040 &matched_expected_error,
3041 set_levels[s],
3042 acct_name,
3043 password,
3044 machine_credentials,
3045 query_levels[q],
3046 &pwdlastset_new,
3047 expected_samlogon_result)) {
3048 ret = false;
3051 /* when a password has been changed, pwdlastset must not be 0 afterwards
3052 * and must be larger then the old value */
3054 switch (levels[l]) {
3055 case 21:
3056 case 23:
3057 case 25:
3059 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3060 * password has been changed, old and new pwdlastset
3061 * need to be the same value */
3063 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3064 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3065 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3067 torture_assert_int_equal(tctx, pwdlastset_old,
3068 pwdlastset_new, "pwdlastset must be equal");
3069 break;
3071 default:
3072 if (pwdlastset_old >= pwdlastset_new) {
3073 torture_warning(tctx, "pwdLastSet test failed: "
3074 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3075 pwdlastset_old, pwdlastset_new);
3076 ret = false;
3078 if (pwdlastset_new == 0) {
3079 torture_warning(tctx, "pwdLastSet test failed: "
3080 "expected non-0 pwdlastset, got: %lld\n",
3081 pwdlastset_new);
3082 ret = false;
3086 switch (levels[l]) {
3087 case 21:
3088 case 23:
3089 case 25:
3090 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3091 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3092 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3093 (pwdlastset_old >= pwdlastset_new)) {
3094 torture_warning(tctx, "pwdlastset not increasing\n");
3095 ret = false;
3097 break;
3098 default:
3099 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3100 (pwdlastset_old >= pwdlastset_new)) {
3101 torture_warning(tctx, "pwdlastset not increasing\n");
3102 ret = false;
3104 break;
3107 pwdlastset_old = pwdlastset_new;
3109 usleep(delay);
3111 /* set #2b */
3113 /* set a password, pwdlastset needs to get updated (increased
3114 * value), password_expired value used here is 0 */
3116 if (!test_SetPassword_level(p, np, tctx, handle,
3117 levels[l],
3118 fields_present[f],
3120 &matched_expected_error,
3121 set_levels[s],
3122 acct_name,
3123 password,
3124 machine_credentials,
3125 query_levels[q],
3126 &pwdlastset_new,
3127 expected_samlogon_result)) {
3128 ret = false;
3131 /* when a password has been changed, pwdlastset must not be 0 afterwards
3132 * and must be larger then the old value */
3134 switch (levels[l]) {
3135 case 21:
3136 case 23:
3137 case 25:
3139 /* if no password has been changed, old and new pwdlastset
3140 * need to be the same value */
3142 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3143 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3145 torture_assert_int_equal(tctx, pwdlastset_old,
3146 pwdlastset_new, "pwdlastset must be equal");
3147 break;
3149 default:
3150 if (pwdlastset_old >= pwdlastset_new) {
3151 torture_warning(tctx, "pwdLastSet test failed: "
3152 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3153 pwdlastset_old, pwdlastset_new);
3154 ret = false;
3156 if (pwdlastset_new == 0) {
3157 torture_warning(tctx, "pwdLastSet test failed: "
3158 "expected non-0 pwdlastset, got: %lld\n",
3159 pwdlastset_new);
3160 ret = false;
3164 /* set #3 */
3166 /* set a password and force password change (pwdlastset 0) by
3167 * setting the password expired flag to a non-0 value */
3169 if (!test_SetPassword_level(p, np, tctx, handle,
3170 levels[l],
3171 fields_present[f],
3172 nonzeros[z],
3173 &matched_expected_error,
3174 set_levels[s],
3175 acct_name,
3176 password,
3177 machine_credentials,
3178 query_levels[q],
3179 &pwdlastset_new,
3180 expected_samlogon_result)) {
3181 ret = false;
3184 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3185 * set without the SAMR_FIELD_EXPIRED_FLAG */
3187 switch (levels[l]) {
3188 case 21:
3189 case 23:
3190 case 25:
3191 if ((pwdlastset_new != 0) &&
3192 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3193 torture_comment(tctx, "not considering a non-0 "
3194 "pwdLastSet as a an error as the "
3195 "SAMR_FIELD_EXPIRED_FLAG has not "
3196 "been set\n");
3197 break;
3200 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3201 * password has been changed, old and new pwdlastset
3202 * need to be the same value */
3204 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3205 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3206 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3208 torture_assert_int_equal(tctx, pwdlastset_old,
3209 pwdlastset_new, "pwdlastset must be equal");
3210 break;
3212 default:
3214 if (pwdlastset_old == pwdlastset_new) {
3215 torture_warning(tctx, "pwdLastSet test failed: "
3216 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3217 pwdlastset_old, pwdlastset_new);
3218 ret = false;
3221 if (pwdlastset_new != 0) {
3222 torture_warning(tctx, "pwdLastSet test failed: "
3223 "expected pwdLastSet 0, got %lld\n",
3224 pwdlastset_old);
3225 ret = false;
3227 break;
3230 switch (levels[l]) {
3231 case 21:
3232 case 23:
3233 case 25:
3234 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3235 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3236 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3237 (pwdlastset_old >= pwdlastset_new)) {
3238 torture_warning(tctx, "pwdlastset not increasing\n");
3239 ret = false;
3241 break;
3242 default:
3243 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3244 (pwdlastset_old >= pwdlastset_new)) {
3245 torture_warning(tctx, "pwdlastset not increasing\n");
3246 ret = false;
3248 break;
3251 /* if the level we are testing does not have a fields_present
3252 * field, skip all fields present tests by setting f to to
3253 * arraysize */
3254 switch (levels[l]) {
3255 case 18:
3256 case 24:
3257 case 26:
3258 f = ARRAY_SIZE(fields_present);
3259 break;
3262 #ifdef TEST_QUERY_LEVELS
3264 #endif
3265 #ifdef TEST_SET_LEVELS
3267 #endif
3268 } /* fields present */
3269 } /* nonzeros */
3270 } /* levels */
3272 #undef TEST_SET_LEVELS
3273 #undef TEST_QUERY_LEVELS
3275 return ret;
3278 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3279 struct dcerpc_pipe *lp,
3280 struct torture_context *tctx,
3281 struct policy_handle *domain_handle,
3282 struct policy_handle *lsa_handle,
3283 struct policy_handle *user_handle,
3284 const struct dom_sid *domain_sid,
3285 uint32_t rid,
3286 struct cli_credentials *machine_credentials)
3288 NTSTATUS status;
3289 bool ret = true;
3291 struct policy_handle lsa_acct_handle;
3292 struct dom_sid *user_sid;
3294 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3297 struct lsa_EnumAccountRights r;
3298 struct lsa_RightSet rights;
3300 printf("Testing LSA EnumAccountRights\n");
3302 r.in.handle = lsa_handle;
3303 r.in.sid = user_sid;
3304 r.out.rights = &rights;
3306 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3307 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3308 "Expected enum rights for account to fail");
3312 struct lsa_RightSet rights;
3313 struct lsa_StringLarge names[2];
3314 struct lsa_AddAccountRights r;
3316 printf("Testing LSA AddAccountRights\n");
3318 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3319 init_lsa_StringLarge(&names[1], NULL);
3321 rights.count = 1;
3322 rights.names = names;
3324 r.in.handle = lsa_handle;
3325 r.in.sid = user_sid;
3326 r.in.rights = &rights;
3328 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3329 torture_assert_ntstatus_ok(tctx, status,
3330 "Failed to add privileges");
3334 struct lsa_EnumAccounts r;
3335 uint32_t resume_handle = 0;
3336 struct lsa_SidArray lsa_sid_array;
3337 int i;
3338 bool found_sid = false;
3340 printf("Testing LSA EnumAccounts\n");
3342 r.in.handle = lsa_handle;
3343 r.in.num_entries = 0x1000;
3344 r.in.resume_handle = &resume_handle;
3345 r.out.sids = &lsa_sid_array;
3346 r.out.resume_handle = &resume_handle;
3348 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3349 torture_assert_ntstatus_ok(tctx, status,
3350 "Failed to enum accounts");
3352 for (i=0; i < lsa_sid_array.num_sids; i++) {
3353 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3354 found_sid = true;
3358 torture_assert(tctx, found_sid,
3359 "failed to list privileged account");
3363 struct lsa_EnumAccountRights r;
3364 struct lsa_RightSet user_rights;
3366 printf("Testing LSA EnumAccountRights\n");
3368 r.in.handle = lsa_handle;
3369 r.in.sid = user_sid;
3370 r.out.rights = &user_rights;
3372 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3373 torture_assert_ntstatus_ok(tctx, status,
3374 "Failed to enum rights for account");
3376 if (user_rights.count < 1) {
3377 torture_warning(tctx, "failed to find newly added rights");
3378 return false;
3383 struct lsa_OpenAccount r;
3385 printf("Testing LSA OpenAccount\n");
3387 r.in.handle = lsa_handle;
3388 r.in.sid = user_sid;
3389 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3390 r.out.acct_handle = &lsa_acct_handle;
3392 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3393 torture_assert_ntstatus_ok(tctx, status,
3394 "Failed to open lsa account");
3398 struct lsa_GetSystemAccessAccount r;
3399 uint32_t access_mask;
3401 printf("Testing LSA GetSystemAccessAccount\n");
3403 r.in.handle = &lsa_acct_handle;
3404 r.out.access_mask = &access_mask;
3406 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3407 torture_assert_ntstatus_ok(tctx, status,
3408 "Failed to get lsa system access account");
3412 struct lsa_Close r;
3414 printf("Testing LSA Close\n");
3416 r.in.handle = &lsa_acct_handle;
3417 r.out.handle = &lsa_acct_handle;
3419 status = dcerpc_lsa_Close(lp, tctx, &r);
3420 torture_assert_ntstatus_ok(tctx, status,
3421 "Failed to close lsa");
3425 struct samr_DeleteUser r;
3427 printf("Testing SAMR DeleteUser\n");
3429 r.in.user_handle = user_handle;
3430 r.out.user_handle = user_handle;
3432 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3433 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3437 struct lsa_EnumAccounts r;
3438 uint32_t resume_handle = 0;
3439 struct lsa_SidArray lsa_sid_array;
3440 int i;
3441 bool found_sid = false;
3443 printf("Testing LSA EnumAccounts\n");
3445 r.in.handle = lsa_handle;
3446 r.in.num_entries = 0x1000;
3447 r.in.resume_handle = &resume_handle;
3448 r.out.sids = &lsa_sid_array;
3449 r.out.resume_handle = &resume_handle;
3451 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3452 torture_assert_ntstatus_ok(tctx, status,
3453 "Failed to enum accounts");
3455 for (i=0; i < lsa_sid_array.num_sids; i++) {
3456 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3457 found_sid = true;
3461 torture_assert(tctx, found_sid,
3462 "failed to list privileged account");
3466 struct lsa_EnumAccountRights r;
3467 struct lsa_RightSet user_rights;
3469 printf("Testing LSA EnumAccountRights\n");
3471 r.in.handle = lsa_handle;
3472 r.in.sid = user_sid;
3473 r.out.rights = &user_rights;
3475 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3476 torture_assert_ntstatus_ok(tctx, status,
3477 "Failed to enum rights for account");
3479 if (user_rights.count < 1) {
3480 torture_warning(tctx, "failed to find newly added rights");
3481 return false;
3486 struct lsa_OpenAccount r;
3488 printf("Testing LSA OpenAccount\n");
3490 r.in.handle = lsa_handle;
3491 r.in.sid = user_sid;
3492 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3493 r.out.acct_handle = &lsa_acct_handle;
3495 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3496 torture_assert_ntstatus_ok(tctx, status,
3497 "Failed to open lsa account");
3501 struct lsa_GetSystemAccessAccount r;
3502 uint32_t access_mask;
3504 printf("Testing LSA GetSystemAccessAccount\n");
3506 r.in.handle = &lsa_acct_handle;
3507 r.out.access_mask = &access_mask;
3509 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3510 torture_assert_ntstatus_ok(tctx, status,
3511 "Failed to get lsa system access account");
3515 struct lsa_DeleteObject r;
3517 printf("Testing LSA DeleteObject\n");
3519 r.in.handle = &lsa_acct_handle;
3520 r.out.handle = &lsa_acct_handle;
3522 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3523 torture_assert_ntstatus_ok(tctx, status,
3524 "Failed to delete object");
3528 struct lsa_EnumAccounts r;
3529 uint32_t resume_handle = 0;
3530 struct lsa_SidArray lsa_sid_array;
3531 int i;
3532 bool found_sid = false;
3534 printf("Testing LSA EnumAccounts\n");
3536 r.in.handle = lsa_handle;
3537 r.in.num_entries = 0x1000;
3538 r.in.resume_handle = &resume_handle;
3539 r.out.sids = &lsa_sid_array;
3540 r.out.resume_handle = &resume_handle;
3542 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3543 torture_assert_ntstatus_ok(tctx, status,
3544 "Failed to enum accounts");
3546 for (i=0; i < lsa_sid_array.num_sids; i++) {
3547 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3548 found_sid = true;
3552 torture_assert(tctx, !found_sid,
3553 "should not have listed privileged account");
3557 struct lsa_EnumAccountRights r;
3558 struct lsa_RightSet user_rights;
3560 printf("Testing LSA EnumAccountRights\n");
3562 r.in.handle = lsa_handle;
3563 r.in.sid = user_sid;
3564 r.out.rights = &user_rights;
3566 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3567 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3568 "Failed to enum rights for account");
3571 return ret;
3574 static bool test_user_ops(struct dcerpc_pipe *p,
3575 struct torture_context *tctx,
3576 struct policy_handle *user_handle,
3577 struct policy_handle *domain_handle,
3578 const struct dom_sid *domain_sid,
3579 uint32_t base_acct_flags,
3580 const char *base_acct_name, enum torture_samr_choice which_ops,
3581 struct cli_credentials *machine_credentials)
3583 char *password = NULL;
3584 struct samr_QueryUserInfo q;
3585 union samr_UserInfo *info;
3586 NTSTATUS status;
3588 bool ret = true;
3589 int i;
3590 uint32_t rid;
3591 const uint32_t password_fields[] = {
3592 SAMR_FIELD_NT_PASSWORD_PRESENT,
3593 SAMR_FIELD_LM_PASSWORD_PRESENT,
3594 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3598 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3599 if (!NT_STATUS_IS_OK(status)) {
3600 ret = false;
3603 switch (which_ops) {
3604 case TORTURE_SAMR_USER_ATTRIBUTES:
3605 if (!test_QuerySecurity(p, tctx, user_handle)) {
3606 ret = false;
3609 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3610 ret = false;
3613 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3614 ret = false;
3617 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3618 base_acct_name)) {
3619 ret = false;
3622 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3623 ret = false;
3626 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3627 ret = false;
3630 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3631 ret = false;
3633 break;
3634 case TORTURE_SAMR_PASSWORDS:
3635 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3636 char simple_pass[9];
3637 char *v = generate_random_str(tctx, 1);
3639 ZERO_STRUCT(simple_pass);
3640 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3642 printf("Testing machine account password policy rules\n");
3644 /* Workstation trust accounts don't seem to need to honour password quality policy */
3645 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3646 ret = false;
3649 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3650 ret = false;
3653 /* reset again, to allow another 'user' password change */
3654 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3655 ret = false;
3658 /* Try a 'short' password */
3659 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3660 ret = false;
3663 /* Try a compleatly random password */
3664 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3665 ret = false;
3669 for (i = 0; password_fields[i]; i++) {
3670 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3671 ret = false;
3674 /* check it was set right */
3675 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3676 ret = false;
3680 for (i = 0; password_fields[i]; i++) {
3681 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3682 ret = false;
3685 /* check it was set right */
3686 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3687 ret = false;
3691 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3692 ret = false;
3695 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3696 ret = false;
3699 if (torture_setting_bool(tctx, "samba4", false)) {
3700 printf("skipping Set Password level 18 and 21 against Samba4\n");
3701 } else {
3703 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3704 ret = false;
3707 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3708 ret = false;
3711 for (i = 0; password_fields[i]; i++) {
3713 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3714 /* we need to skip as that would break
3715 * the ChangePasswordUser3 verify */
3716 continue;
3719 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3720 ret = false;
3723 /* check it was set right */
3724 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3725 ret = false;
3730 q.in.user_handle = user_handle;
3731 q.in.level = 5;
3732 q.out.info = &info;
3734 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3735 if (!NT_STATUS_IS_OK(status)) {
3736 printf("QueryUserInfo level %u failed - %s\n",
3737 q.in.level, nt_errstr(status));
3738 ret = false;
3739 } else {
3740 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3741 if ((info->info5.acct_flags) != expected_flags) {
3742 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3743 info->info5.acct_flags,
3744 expected_flags);
3745 /* FIXME: GD */
3746 if (!torture_setting_bool(tctx, "samba3", false)) {
3747 ret = false;
3750 if (info->info5.rid != rid) {
3751 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3752 info->info5.rid, rid);
3757 break;
3759 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3761 /* test last password change timestamp behaviour */
3762 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3763 base_acct_name,
3764 user_handle, &password,
3765 machine_credentials)) {
3766 ret = false;
3769 if (ret == true) {
3770 torture_comment(tctx, "pwdLastSet test succeeded\n");
3771 } else {
3772 torture_warning(tctx, "pwdLastSet test failed\n");
3775 break;
3777 case TORTURE_SAMR_USER_PRIVILEGES: {
3779 struct dcerpc_pipe *lp;
3780 struct policy_handle *lsa_handle;
3782 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3783 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3785 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3786 ret = false;
3789 if (!test_DeleteUser_with_privs(p, lp, tctx,
3790 domain_handle, lsa_handle, user_handle,
3791 domain_sid, rid,
3792 machine_credentials)) {
3793 ret = false;
3796 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3797 ret = false;
3800 if (!ret) {
3801 torture_warning(tctx, "privileged user delete test failed\n");
3804 break;
3806 case TORTURE_SAMR_OTHER:
3807 /* We just need the account to exist */
3808 break;
3810 return ret;
3813 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3814 struct policy_handle *alias_handle,
3815 const struct dom_sid *domain_sid)
3817 bool ret = true;
3819 if (!torture_setting_bool(tctx, "samba3", false)) {
3820 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3821 ret = false;
3825 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3826 ret = false;
3829 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3830 ret = false;
3833 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3834 ret = false;
3837 if (torture_setting_bool(tctx, "samba4", false)) {
3838 printf("skipping MultipleMembers Alias tests against Samba4\n");
3839 return ret;
3842 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3843 ret = false;
3846 return ret;
3850 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3851 struct policy_handle *user_handle)
3853 struct samr_DeleteUser d;
3854 NTSTATUS status;
3855 torture_comment(tctx, "Testing DeleteUser\n");
3857 d.in.user_handle = user_handle;
3858 d.out.user_handle = user_handle;
3860 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3861 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3863 return true;
3866 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3867 struct torture_context *tctx,
3868 struct policy_handle *handle, const char *name)
3870 NTSTATUS status;
3871 struct samr_DeleteUser d;
3872 struct policy_handle user_handle;
3873 uint32_t rid;
3875 status = test_LookupName(p, tctx, handle, name, &rid);
3876 if (!NT_STATUS_IS_OK(status)) {
3877 goto failed;
3880 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3881 if (!NT_STATUS_IS_OK(status)) {
3882 goto failed;
3885 d.in.user_handle = &user_handle;
3886 d.out.user_handle = &user_handle;
3887 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3888 if (!NT_STATUS_IS_OK(status)) {
3889 goto failed;
3892 return true;
3894 failed:
3895 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3896 return false;
3900 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3901 struct torture_context *tctx,
3902 struct policy_handle *handle, const char *name)
3904 NTSTATUS status;
3905 struct samr_OpenGroup r;
3906 struct samr_DeleteDomainGroup d;
3907 struct policy_handle group_handle;
3908 uint32_t rid;
3910 status = test_LookupName(p, tctx, handle, name, &rid);
3911 if (!NT_STATUS_IS_OK(status)) {
3912 goto failed;
3915 r.in.domain_handle = handle;
3916 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3917 r.in.rid = rid;
3918 r.out.group_handle = &group_handle;
3919 status = dcerpc_samr_OpenGroup(p, tctx, &r);
3920 if (!NT_STATUS_IS_OK(status)) {
3921 goto failed;
3924 d.in.group_handle = &group_handle;
3925 d.out.group_handle = &group_handle;
3926 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3927 if (!NT_STATUS_IS_OK(status)) {
3928 goto failed;
3931 return true;
3933 failed:
3934 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3935 return false;
3939 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3940 struct torture_context *tctx,
3941 struct policy_handle *domain_handle,
3942 const char *name)
3944 NTSTATUS status;
3945 struct samr_OpenAlias r;
3946 struct samr_DeleteDomAlias d;
3947 struct policy_handle alias_handle;
3948 uint32_t rid;
3950 printf("testing DeleteAlias_byname\n");
3952 status = test_LookupName(p, tctx, domain_handle, name, &rid);
3953 if (!NT_STATUS_IS_OK(status)) {
3954 goto failed;
3957 r.in.domain_handle = domain_handle;
3958 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3959 r.in.rid = rid;
3960 r.out.alias_handle = &alias_handle;
3961 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3962 if (!NT_STATUS_IS_OK(status)) {
3963 goto failed;
3966 d.in.alias_handle = &alias_handle;
3967 d.out.alias_handle = &alias_handle;
3968 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3969 if (!NT_STATUS_IS_OK(status)) {
3970 goto failed;
3973 return true;
3975 failed:
3976 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3977 return false;
3980 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3981 struct torture_context *tctx,
3982 struct policy_handle *alias_handle)
3984 struct samr_DeleteDomAlias d;
3985 NTSTATUS status;
3986 bool ret = true;
3987 printf("Testing DeleteAlias\n");
3989 d.in.alias_handle = alias_handle;
3990 d.out.alias_handle = alias_handle;
3992 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3993 if (!NT_STATUS_IS_OK(status)) {
3994 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3995 ret = false;
3998 return ret;
4001 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4002 struct policy_handle *domain_handle,
4003 struct policy_handle *alias_handle,
4004 const struct dom_sid *domain_sid)
4006 NTSTATUS status;
4007 struct samr_CreateDomAlias r;
4008 struct lsa_String name;
4009 uint32_t rid;
4010 bool ret = true;
4012 init_lsa_String(&name, TEST_ALIASNAME);
4013 r.in.domain_handle = domain_handle;
4014 r.in.alias_name = &name;
4015 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4016 r.out.alias_handle = alias_handle;
4017 r.out.rid = &rid;
4019 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
4021 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4023 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4024 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4025 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
4026 return true;
4027 } else {
4028 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4029 nt_errstr(status));
4030 return false;
4034 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4035 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4036 return false;
4038 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4041 if (!NT_STATUS_IS_OK(status)) {
4042 printf("CreateAlias failed - %s\n", nt_errstr(status));
4043 return false;
4046 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4047 ret = false;
4050 return ret;
4053 static bool test_ChangePassword(struct dcerpc_pipe *p,
4054 struct torture_context *tctx,
4055 const char *acct_name,
4056 struct policy_handle *domain_handle, char **password)
4058 bool ret = true;
4060 if (!*password) {
4061 return false;
4064 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4065 ret = false;
4068 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4069 ret = false;
4072 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4073 ret = false;
4076 /* test what happens when setting the old password again */
4077 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4078 ret = false;
4082 char simple_pass[9];
4083 char *v = generate_random_str(tctx, 1);
4085 ZERO_STRUCT(simple_pass);
4086 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4088 /* test what happens when picking a simple password */
4089 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4090 ret = false;
4094 /* set samr_SetDomainInfo level 1 with min_length 5 */
4096 struct samr_QueryDomainInfo r;
4097 union samr_DomainInfo *info = NULL;
4098 struct samr_SetDomainInfo s;
4099 uint16_t len_old, len;
4100 uint32_t pwd_prop_old;
4101 int64_t min_pwd_age_old;
4102 NTSTATUS status;
4104 len = 5;
4106 r.in.domain_handle = domain_handle;
4107 r.in.level = 1;
4108 r.out.info = &info;
4110 printf("testing samr_QueryDomainInfo level 1\n");
4111 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4112 if (!NT_STATUS_IS_OK(status)) {
4113 return false;
4116 s.in.domain_handle = domain_handle;
4117 s.in.level = 1;
4118 s.in.info = info;
4120 /* remember the old min length, so we can reset it */
4121 len_old = s.in.info->info1.min_password_length;
4122 s.in.info->info1.min_password_length = len;
4123 pwd_prop_old = s.in.info->info1.password_properties;
4124 /* turn off password complexity checks for this test */
4125 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4127 min_pwd_age_old = s.in.info->info1.min_password_age;
4128 s.in.info->info1.min_password_age = 0;
4130 printf("testing samr_SetDomainInfo level 1\n");
4131 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4132 if (!NT_STATUS_IS_OK(status)) {
4133 return false;
4136 printf("calling test_ChangePasswordUser3 with too short password\n");
4138 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4139 ret = false;
4142 s.in.info->info1.min_password_length = len_old;
4143 s.in.info->info1.password_properties = pwd_prop_old;
4144 s.in.info->info1.min_password_age = min_pwd_age_old;
4146 printf("testing samr_SetDomainInfo level 1\n");
4147 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4148 if (!NT_STATUS_IS_OK(status)) {
4149 return false;
4155 NTSTATUS status;
4156 struct samr_OpenUser r;
4157 struct samr_QueryUserInfo q;
4158 union samr_UserInfo *info;
4159 struct samr_LookupNames n;
4160 struct policy_handle user_handle;
4161 struct samr_Ids rids, types;
4163 n.in.domain_handle = domain_handle;
4164 n.in.num_names = 1;
4165 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4166 n.in.names[0].string = acct_name;
4167 n.out.rids = &rids;
4168 n.out.types = &types;
4170 status = dcerpc_samr_LookupNames(p, tctx, &n);
4171 if (!NT_STATUS_IS_OK(status)) {
4172 printf("LookupNames failed - %s\n", nt_errstr(status));
4173 return false;
4176 r.in.domain_handle = domain_handle;
4177 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4178 r.in.rid = n.out.rids->ids[0];
4179 r.out.user_handle = &user_handle;
4181 status = dcerpc_samr_OpenUser(p, tctx, &r);
4182 if (!NT_STATUS_IS_OK(status)) {
4183 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4184 return false;
4187 q.in.user_handle = &user_handle;
4188 q.in.level = 5;
4189 q.out.info = &info;
4191 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4192 if (!NT_STATUS_IS_OK(status)) {
4193 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
4194 return false;
4197 printf("calling test_ChangePasswordUser3 with too early password change\n");
4199 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4200 info->info5.last_password_change, true)) {
4201 ret = false;
4205 /* we change passwords twice - this has the effect of verifying
4206 they were changed correctly for the final call */
4207 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4208 ret = false;
4211 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4212 ret = false;
4215 return ret;
4218 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4219 struct policy_handle *domain_handle,
4220 struct policy_handle *user_handle_out,
4221 struct dom_sid *domain_sid,
4222 enum torture_samr_choice which_ops,
4223 struct cli_credentials *machine_credentials)
4226 TALLOC_CTX *user_ctx;
4228 NTSTATUS status;
4229 struct samr_CreateUser r;
4230 struct samr_QueryUserInfo q;
4231 union samr_UserInfo *info;
4232 struct samr_DeleteUser d;
4233 uint32_t rid;
4235 /* This call creates a 'normal' account - check that it really does */
4236 const uint32_t acct_flags = ACB_NORMAL;
4237 struct lsa_String name;
4238 bool ret = true;
4240 struct policy_handle user_handle;
4241 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4242 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4244 r.in.domain_handle = domain_handle;
4245 r.in.account_name = &name;
4246 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4247 r.out.user_handle = &user_handle;
4248 r.out.rid = &rid;
4250 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
4252 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4254 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4255 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4256 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4257 return true;
4258 } else {
4259 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4260 nt_errstr(status));
4261 return false;
4265 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4266 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4267 talloc_free(user_ctx);
4268 return false;
4270 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4272 if (!NT_STATUS_IS_OK(status)) {
4273 talloc_free(user_ctx);
4274 printf("CreateUser failed - %s\n", nt_errstr(status));
4275 return false;
4276 } else {
4277 q.in.user_handle = &user_handle;
4278 q.in.level = 16;
4279 q.out.info = &info;
4281 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4282 if (!NT_STATUS_IS_OK(status)) {
4283 printf("QueryUserInfo level %u failed - %s\n",
4284 q.in.level, nt_errstr(status));
4285 ret = false;
4286 } else {
4287 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4288 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4289 info->info16.acct_flags,
4290 acct_flags);
4291 ret = false;
4295 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4296 domain_sid, acct_flags, name.string, which_ops,
4297 machine_credentials)) {
4298 ret = false;
4301 if (user_handle_out) {
4302 *user_handle_out = user_handle;
4303 } else {
4304 printf("Testing DeleteUser (createuser test)\n");
4306 d.in.user_handle = &user_handle;
4307 d.out.user_handle = &user_handle;
4309 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4310 if (!NT_STATUS_IS_OK(status)) {
4311 printf("DeleteUser failed - %s\n", nt_errstr(status));
4312 ret = false;
4318 talloc_free(user_ctx);
4320 return ret;
4324 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4325 struct policy_handle *domain_handle,
4326 struct dom_sid *domain_sid,
4327 enum torture_samr_choice which_ops,
4328 struct cli_credentials *machine_credentials)
4330 NTSTATUS status;
4331 struct samr_CreateUser2 r;
4332 struct samr_QueryUserInfo q;
4333 union samr_UserInfo *info;
4334 struct samr_DeleteUser d;
4335 struct policy_handle user_handle;
4336 uint32_t rid;
4337 struct lsa_String name;
4338 bool ret = true;
4339 int i;
4341 struct {
4342 uint32_t acct_flags;
4343 const char *account_name;
4344 NTSTATUS nt_status;
4345 } account_types[] = {
4346 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4347 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4348 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4349 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4350 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4351 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4352 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4353 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4354 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4355 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
4356 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4357 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4358 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4359 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4360 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4363 for (i = 0; account_types[i].account_name; i++) {
4364 TALLOC_CTX *user_ctx;
4365 uint32_t acct_flags = account_types[i].acct_flags;
4366 uint32_t access_granted;
4367 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4368 init_lsa_String(&name, account_types[i].account_name);
4370 r.in.domain_handle = domain_handle;
4371 r.in.account_name = &name;
4372 r.in.acct_flags = acct_flags;
4373 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4374 r.out.user_handle = &user_handle;
4375 r.out.access_granted = &access_granted;
4376 r.out.rid = &rid;
4378 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4380 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4382 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4383 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4384 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4385 continue;
4386 } else {
4387 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4388 nt_errstr(status));
4389 ret = false;
4390 continue;
4394 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4395 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4396 talloc_free(user_ctx);
4397 ret = false;
4398 continue;
4400 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4403 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4404 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4405 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4406 ret = false;
4409 if (NT_STATUS_IS_OK(status)) {
4410 q.in.user_handle = &user_handle;
4411 q.in.level = 5;
4412 q.out.info = &info;
4414 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4415 if (!NT_STATUS_IS_OK(status)) {
4416 printf("QueryUserInfo level %u failed - %s\n",
4417 q.in.level, nt_errstr(status));
4418 ret = false;
4419 } else {
4420 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4421 if (acct_flags == ACB_NORMAL) {
4422 expected_flags |= ACB_PW_EXPIRED;
4424 if ((info->info5.acct_flags) != expected_flags) {
4425 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4426 info->info5.acct_flags,
4427 expected_flags);
4428 ret = false;
4430 switch (acct_flags) {
4431 case ACB_SVRTRUST:
4432 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4433 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4434 DOMAIN_RID_DCS, info->info5.primary_gid);
4435 ret = false;
4437 break;
4438 case ACB_WSTRUST:
4439 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4440 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4441 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4442 ret = false;
4444 break;
4445 case ACB_NORMAL:
4446 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4447 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4448 DOMAIN_RID_USERS, info->info5.primary_gid);
4449 ret = false;
4451 break;
4455 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4456 domain_sid, acct_flags, name.string, which_ops,
4457 machine_credentials)) {
4458 ret = false;
4461 if (!policy_handle_empty(&user_handle)) {
4462 printf("Testing DeleteUser (createuser2 test)\n");
4464 d.in.user_handle = &user_handle;
4465 d.out.user_handle = &user_handle;
4467 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4468 if (!NT_STATUS_IS_OK(status)) {
4469 printf("DeleteUser failed - %s\n", nt_errstr(status));
4470 ret = false;
4474 talloc_free(user_ctx);
4477 return ret;
4480 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4481 struct torture_context *tctx,
4482 struct policy_handle *handle)
4484 NTSTATUS status;
4485 struct samr_QueryAliasInfo r;
4486 union samr_AliasInfo *info;
4487 uint16_t levels[] = {1, 2, 3};
4488 int i;
4489 bool ret = true;
4491 for (i=0;i<ARRAY_SIZE(levels);i++) {
4492 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4494 r.in.alias_handle = handle;
4495 r.in.level = levels[i];
4496 r.out.info = &info;
4498 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4499 if (!NT_STATUS_IS_OK(status)) {
4500 printf("QueryAliasInfo level %u failed - %s\n",
4501 levels[i], nt_errstr(status));
4502 ret = false;
4506 return ret;
4509 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4510 struct torture_context *tctx,
4511 struct policy_handle *handle)
4513 NTSTATUS status;
4514 struct samr_QueryGroupInfo r;
4515 union samr_GroupInfo *info;
4516 uint16_t levels[] = {1, 2, 3, 4, 5};
4517 int i;
4518 bool ret = true;
4520 for (i=0;i<ARRAY_SIZE(levels);i++) {
4521 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4523 r.in.group_handle = handle;
4524 r.in.level = levels[i];
4525 r.out.info = &info;
4527 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4528 if (!NT_STATUS_IS_OK(status)) {
4529 printf("QueryGroupInfo level %u failed - %s\n",
4530 levels[i], nt_errstr(status));
4531 ret = false;
4535 return ret;
4538 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4539 struct torture_context *tctx,
4540 struct policy_handle *handle)
4542 NTSTATUS status;
4543 struct samr_QueryGroupMember r;
4544 struct samr_RidTypeArray *rids = NULL;
4545 bool ret = true;
4547 printf("Testing QueryGroupMember\n");
4549 r.in.group_handle = handle;
4550 r.out.rids = &rids;
4552 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4553 if (!NT_STATUS_IS_OK(status)) {
4554 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4555 ret = false;
4558 return ret;
4562 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4563 struct torture_context *tctx,
4564 struct policy_handle *handle)
4566 NTSTATUS status;
4567 struct samr_QueryGroupInfo r;
4568 union samr_GroupInfo *info;
4569 struct samr_SetGroupInfo s;
4570 uint16_t levels[] = {1, 2, 3, 4};
4571 uint16_t set_ok[] = {0, 1, 1, 1};
4572 int i;
4573 bool ret = true;
4575 for (i=0;i<ARRAY_SIZE(levels);i++) {
4576 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4578 r.in.group_handle = handle;
4579 r.in.level = levels[i];
4580 r.out.info = &info;
4582 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4583 if (!NT_STATUS_IS_OK(status)) {
4584 printf("QueryGroupInfo level %u failed - %s\n",
4585 levels[i], nt_errstr(status));
4586 ret = false;
4589 printf("Testing SetGroupInfo level %u\n", levels[i]);
4591 s.in.group_handle = handle;
4592 s.in.level = levels[i];
4593 s.in.info = *r.out.info;
4595 #if 0
4596 /* disabled this, as it changes the name only from the point of view of samr,
4597 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4598 the name is still reserved, so creating the old name fails, but deleting by the old name
4599 also fails */
4600 if (s.in.level == 2) {
4601 init_lsa_String(&s.in.info->string, "NewName");
4603 #endif
4605 if (s.in.level == 4) {
4606 init_lsa_String(&s.in.info->description, "test description");
4609 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4610 if (set_ok[i]) {
4611 if (!NT_STATUS_IS_OK(status)) {
4612 printf("SetGroupInfo level %u failed - %s\n",
4613 r.in.level, nt_errstr(status));
4614 ret = false;
4615 continue;
4617 } else {
4618 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4619 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4620 r.in.level, nt_errstr(status));
4621 ret = false;
4622 continue;
4627 return ret;
4630 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4631 struct torture_context *tctx,
4632 struct policy_handle *handle)
4634 NTSTATUS status;
4635 struct samr_QueryUserInfo r;
4636 union samr_UserInfo *info;
4637 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4638 11, 12, 13, 14, 16, 17, 20, 21};
4639 int i;
4640 bool ret = true;
4642 for (i=0;i<ARRAY_SIZE(levels);i++) {
4643 printf("Testing QueryUserInfo level %u\n", levels[i]);
4645 r.in.user_handle = handle;
4646 r.in.level = levels[i];
4647 r.out.info = &info;
4649 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4650 if (!NT_STATUS_IS_OK(status)) {
4651 printf("QueryUserInfo level %u failed - %s\n",
4652 levels[i], nt_errstr(status));
4653 ret = false;
4657 return ret;
4660 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4661 struct torture_context *tctx,
4662 struct policy_handle *handle)
4664 NTSTATUS status;
4665 struct samr_QueryUserInfo2 r;
4666 union samr_UserInfo *info;
4667 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4668 11, 12, 13, 14, 16, 17, 20, 21};
4669 int i;
4670 bool ret = true;
4672 for (i=0;i<ARRAY_SIZE(levels);i++) {
4673 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4675 r.in.user_handle = handle;
4676 r.in.level = levels[i];
4677 r.out.info = &info;
4679 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4680 if (!NT_STATUS_IS_OK(status)) {
4681 printf("QueryUserInfo2 level %u failed - %s\n",
4682 levels[i], nt_errstr(status));
4683 ret = false;
4687 return ret;
4690 static bool test_OpenUser(struct dcerpc_pipe *p,
4691 struct torture_context *tctx,
4692 struct policy_handle *handle, uint32_t rid)
4694 NTSTATUS status;
4695 struct samr_OpenUser r;
4696 struct policy_handle user_handle;
4697 bool ret = true;
4699 printf("Testing OpenUser(%u)\n", rid);
4701 r.in.domain_handle = handle;
4702 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4703 r.in.rid = rid;
4704 r.out.user_handle = &user_handle;
4706 status = dcerpc_samr_OpenUser(p, tctx, &r);
4707 if (!NT_STATUS_IS_OK(status)) {
4708 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4709 return false;
4712 if (!test_QuerySecurity(p, tctx, &user_handle)) {
4713 ret = false;
4716 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4717 ret = false;
4720 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4721 ret = false;
4724 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4725 ret = false;
4728 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4729 ret = false;
4732 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4733 ret = false;
4736 return ret;
4739 static bool test_OpenGroup(struct dcerpc_pipe *p,
4740 struct torture_context *tctx,
4741 struct policy_handle *handle, uint32_t rid)
4743 NTSTATUS status;
4744 struct samr_OpenGroup r;
4745 struct policy_handle group_handle;
4746 bool ret = true;
4748 printf("Testing OpenGroup(%u)\n", rid);
4750 r.in.domain_handle = handle;
4751 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4752 r.in.rid = rid;
4753 r.out.group_handle = &group_handle;
4755 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4756 if (!NT_STATUS_IS_OK(status)) {
4757 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4758 return false;
4761 if (!torture_setting_bool(tctx, "samba3", false)) {
4762 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4763 ret = false;
4767 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4768 ret = false;
4771 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4772 ret = false;
4775 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4776 ret = false;
4779 return ret;
4782 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4783 struct policy_handle *handle, uint32_t rid)
4785 NTSTATUS status;
4786 struct samr_OpenAlias r;
4787 struct policy_handle alias_handle;
4788 bool ret = true;
4790 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4792 r.in.domain_handle = handle;
4793 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4794 r.in.rid = rid;
4795 r.out.alias_handle = &alias_handle;
4797 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4798 if (!NT_STATUS_IS_OK(status)) {
4799 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4800 return false;
4803 if (!torture_setting_bool(tctx, "samba3", false)) {
4804 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4805 ret = false;
4809 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4810 ret = false;
4813 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4814 ret = false;
4817 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4818 ret = false;
4821 return ret;
4824 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4825 struct policy_handle *handle, uint32_t rid,
4826 uint32_t acct_flag_mask)
4828 NTSTATUS status;
4829 struct samr_OpenUser r;
4830 struct samr_QueryUserInfo q;
4831 union samr_UserInfo *info;
4832 struct policy_handle user_handle;
4833 bool ret = true;
4835 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4837 r.in.domain_handle = handle;
4838 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4839 r.in.rid = rid;
4840 r.out.user_handle = &user_handle;
4842 status = dcerpc_samr_OpenUser(p, tctx, &r);
4843 if (!NT_STATUS_IS_OK(status)) {
4844 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4845 return false;
4848 q.in.user_handle = &user_handle;
4849 q.in.level = 16;
4850 q.out.info = &info;
4852 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4853 if (!NT_STATUS_IS_OK(status)) {
4854 printf("QueryUserInfo level 16 failed - %s\n",
4855 nt_errstr(status));
4856 ret = false;
4857 } else {
4858 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4859 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4860 acct_flag_mask, info->info16.acct_flags, rid);
4861 ret = false;
4865 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4866 ret = false;
4869 return ret;
4872 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4873 struct policy_handle *handle)
4875 NTSTATUS status = STATUS_MORE_ENTRIES;
4876 struct samr_EnumDomainUsers r;
4877 uint32_t mask, resume_handle=0;
4878 int i, mask_idx;
4879 bool ret = true;
4880 struct samr_LookupNames n;
4881 struct samr_LookupRids lr ;
4882 struct lsa_Strings names;
4883 struct samr_Ids rids, types;
4884 struct samr_SamArray *sam = NULL;
4885 uint32_t num_entries = 0;
4887 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4888 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4889 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4890 ACB_PWNOEXP, 0};
4892 printf("Testing EnumDomainUsers\n");
4894 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4895 r.in.domain_handle = handle;
4896 r.in.resume_handle = &resume_handle;
4897 r.in.acct_flags = mask = masks[mask_idx];
4898 r.in.max_size = (uint32_t)-1;
4899 r.out.resume_handle = &resume_handle;
4900 r.out.num_entries = &num_entries;
4901 r.out.sam = &sam;
4903 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4904 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4905 !NT_STATUS_IS_OK(status)) {
4906 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4907 return false;
4910 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4912 if (sam->count == 0) {
4913 continue;
4916 for (i=0;i<sam->count;i++) {
4917 if (mask) {
4918 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4919 ret = false;
4921 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4922 ret = false;
4927 printf("Testing LookupNames\n");
4928 n.in.domain_handle = handle;
4929 n.in.num_names = sam->count;
4930 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4931 n.out.rids = &rids;
4932 n.out.types = &types;
4933 for (i=0;i<sam->count;i++) {
4934 n.in.names[i].string = sam->entries[i].name.string;
4936 status = dcerpc_samr_LookupNames(p, tctx, &n);
4937 if (!NT_STATUS_IS_OK(status)) {
4938 printf("LookupNames failed - %s\n", nt_errstr(status));
4939 ret = false;
4943 printf("Testing LookupRids\n");
4944 lr.in.domain_handle = handle;
4945 lr.in.num_rids = sam->count;
4946 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4947 lr.out.names = &names;
4948 lr.out.types = &types;
4949 for (i=0;i<sam->count;i++) {
4950 lr.in.rids[i] = sam->entries[i].idx;
4952 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4953 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4955 return ret;
4959 try blasting the server with a bunch of sync requests
4961 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4962 struct policy_handle *handle)
4964 NTSTATUS status;
4965 struct samr_EnumDomainUsers r;
4966 uint32_t resume_handle=0;
4967 int i;
4968 #define ASYNC_COUNT 100
4969 struct rpc_request *req[ASYNC_COUNT];
4971 if (!torture_setting_bool(tctx, "dangerous", false)) {
4972 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4975 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4977 r.in.domain_handle = handle;
4978 r.in.resume_handle = &resume_handle;
4979 r.in.acct_flags = 0;
4980 r.in.max_size = (uint32_t)-1;
4981 r.out.resume_handle = &resume_handle;
4983 for (i=0;i<ASYNC_COUNT;i++) {
4984 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4987 for (i=0;i<ASYNC_COUNT;i++) {
4988 status = dcerpc_ndr_request_recv(req[i]);
4989 if (!NT_STATUS_IS_OK(status)) {
4990 printf("EnumDomainUsers[%d] failed - %s\n",
4991 i, nt_errstr(status));
4992 return false;
4996 torture_comment(tctx, "%d async requests OK\n", i);
4998 return true;
5001 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
5002 struct torture_context *tctx,
5003 struct policy_handle *handle)
5005 NTSTATUS status;
5006 struct samr_EnumDomainGroups r;
5007 uint32_t resume_handle=0;
5008 struct samr_SamArray *sam = NULL;
5009 uint32_t num_entries = 0;
5010 int i;
5011 bool ret = true;
5013 printf("Testing EnumDomainGroups\n");
5015 r.in.domain_handle = handle;
5016 r.in.resume_handle = &resume_handle;
5017 r.in.max_size = (uint32_t)-1;
5018 r.out.resume_handle = &resume_handle;
5019 r.out.num_entries = &num_entries;
5020 r.out.sam = &sam;
5022 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5023 if (!NT_STATUS_IS_OK(status)) {
5024 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
5025 return false;
5028 if (!sam) {
5029 return false;
5032 for (i=0;i<sam->count;i++) {
5033 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5034 ret = false;
5038 return ret;
5041 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
5042 struct torture_context *tctx,
5043 struct policy_handle *handle)
5045 NTSTATUS status;
5046 struct samr_EnumDomainAliases r;
5047 uint32_t resume_handle=0;
5048 struct samr_SamArray *sam = NULL;
5049 uint32_t num_entries = 0;
5050 int i;
5051 bool ret = true;
5053 printf("Testing EnumDomainAliases\n");
5055 r.in.domain_handle = handle;
5056 r.in.resume_handle = &resume_handle;
5057 r.in.max_size = (uint32_t)-1;
5058 r.out.sam = &sam;
5059 r.out.num_entries = &num_entries;
5060 r.out.resume_handle = &resume_handle;
5062 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5063 if (!NT_STATUS_IS_OK(status)) {
5064 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
5065 return false;
5068 if (!sam) {
5069 return false;
5072 for (i=0;i<sam->count;i++) {
5073 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5074 ret = false;
5078 return ret;
5081 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5082 struct torture_context *tctx,
5083 struct policy_handle *handle)
5085 NTSTATUS status;
5086 struct samr_GetDisplayEnumerationIndex r;
5087 bool ret = true;
5088 uint16_t levels[] = {1, 2, 3, 4, 5};
5089 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5090 struct lsa_String name;
5091 uint32_t idx = 0;
5092 int i;
5094 for (i=0;i<ARRAY_SIZE(levels);i++) {
5095 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5097 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5099 r.in.domain_handle = handle;
5100 r.in.level = levels[i];
5101 r.in.name = &name;
5102 r.out.idx = &idx;
5104 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5106 if (ok_lvl[i] &&
5107 !NT_STATUS_IS_OK(status) &&
5108 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5109 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5110 levels[i], nt_errstr(status));
5111 ret = false;
5114 init_lsa_String(&name, "zzzzzzzz");
5116 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5118 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5119 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5120 levels[i], nt_errstr(status));
5121 ret = false;
5125 return ret;
5128 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5129 struct torture_context *tctx,
5130 struct policy_handle *handle)
5132 NTSTATUS status;
5133 struct samr_GetDisplayEnumerationIndex2 r;
5134 bool ret = true;
5135 uint16_t levels[] = {1, 2, 3, 4, 5};
5136 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5137 struct lsa_String name;
5138 uint32_t idx = 0;
5139 int i;
5141 for (i=0;i<ARRAY_SIZE(levels);i++) {
5142 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5144 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5146 r.in.domain_handle = handle;
5147 r.in.level = levels[i];
5148 r.in.name = &name;
5149 r.out.idx = &idx;
5151 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5152 if (ok_lvl[i] &&
5153 !NT_STATUS_IS_OK(status) &&
5154 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5155 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5156 levels[i], nt_errstr(status));
5157 ret = false;
5160 init_lsa_String(&name, "zzzzzzzz");
5162 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5163 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5164 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5165 levels[i], nt_errstr(status));
5166 ret = false;
5170 return ret;
5173 #define STRING_EQUAL_QUERY(s1, s2, user) \
5174 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5175 /* odd, but valid */ \
5176 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5177 printf("%s mismatch for %s: %s != %s (%s)\n", \
5178 #s1, user.string, s1.string, s2.string, __location__); \
5179 ret = false; \
5181 #define INT_EQUAL_QUERY(s1, s2, user) \
5182 if (s1 != s2) { \
5183 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5184 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5185 ret = false; \
5188 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5189 struct torture_context *tctx,
5190 struct samr_QueryDisplayInfo *querydisplayinfo,
5191 bool *seen_testuser)
5193 struct samr_OpenUser r;
5194 struct samr_QueryUserInfo q;
5195 union samr_UserInfo *info;
5196 struct policy_handle user_handle;
5197 int i, ret = true;
5198 NTSTATUS status;
5199 r.in.domain_handle = querydisplayinfo->in.domain_handle;
5200 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5201 for (i = 0; ; i++) {
5202 switch (querydisplayinfo->in.level) {
5203 case 1:
5204 if (i >= querydisplayinfo->out.info->info1.count) {
5205 return ret;
5207 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5208 break;
5209 case 2:
5210 if (i >= querydisplayinfo->out.info->info2.count) {
5211 return ret;
5213 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5214 break;
5215 case 3:
5216 /* Groups */
5217 case 4:
5218 case 5:
5219 /* Not interested in validating just the account name */
5220 return true;
5223 r.out.user_handle = &user_handle;
5225 switch (querydisplayinfo->in.level) {
5226 case 1:
5227 case 2:
5228 status = dcerpc_samr_OpenUser(p, tctx, &r);
5229 if (!NT_STATUS_IS_OK(status)) {
5230 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5231 return false;
5235 q.in.user_handle = &user_handle;
5236 q.in.level = 21;
5237 q.out.info = &info;
5238 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5239 if (!NT_STATUS_IS_OK(status)) {
5240 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5241 return false;
5244 switch (querydisplayinfo->in.level) {
5245 case 1:
5246 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5247 *seen_testuser = true;
5249 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5250 info->info21.full_name, info->info21.account_name);
5251 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5252 info->info21.account_name, info->info21.account_name);
5253 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5254 info->info21.description, info->info21.account_name);
5255 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5256 info->info21.rid, info->info21.account_name);
5257 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5258 info->info21.acct_flags, info->info21.account_name);
5260 break;
5261 case 2:
5262 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5263 info->info21.account_name, info->info21.account_name);
5264 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5265 info->info21.description, info->info21.account_name);
5266 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5267 info->info21.rid, info->info21.account_name);
5268 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5269 info->info21.acct_flags, info->info21.account_name);
5271 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5272 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5273 info->info21.account_name.string);
5276 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5277 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5278 info->info21.account_name.string,
5279 querydisplayinfo->out.info->info2.entries[i].acct_flags,
5280 info->info21.acct_flags);
5281 return false;
5284 break;
5287 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5288 return false;
5291 return ret;
5294 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5295 struct torture_context *tctx,
5296 struct policy_handle *handle)
5298 NTSTATUS status;
5299 struct samr_QueryDisplayInfo r;
5300 struct samr_QueryDomainInfo dom_info;
5301 union samr_DomainInfo *info = NULL;
5302 bool ret = true;
5303 uint16_t levels[] = {1, 2, 3, 4, 5};
5304 int i;
5305 bool seen_testuser = false;
5306 uint32_t total_size;
5307 uint32_t returned_size;
5308 union samr_DispInfo disp_info;
5311 for (i=0;i<ARRAY_SIZE(levels);i++) {
5312 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
5314 r.in.start_idx = 0;
5315 status = STATUS_MORE_ENTRIES;
5316 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5317 r.in.domain_handle = handle;
5318 r.in.level = levels[i];
5319 r.in.max_entries = 2;
5320 r.in.buf_size = (uint32_t)-1;
5321 r.out.total_size = &total_size;
5322 r.out.returned_size = &returned_size;
5323 r.out.info = &disp_info;
5325 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5326 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5327 printf("QueryDisplayInfo level %u failed - %s\n",
5328 levels[i], nt_errstr(status));
5329 ret = false;
5331 switch (r.in.level) {
5332 case 1:
5333 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5334 ret = false;
5336 r.in.start_idx += r.out.info->info1.count;
5337 break;
5338 case 2:
5339 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5340 ret = false;
5342 r.in.start_idx += r.out.info->info2.count;
5343 break;
5344 case 3:
5345 r.in.start_idx += r.out.info->info3.count;
5346 break;
5347 case 4:
5348 r.in.start_idx += r.out.info->info4.count;
5349 break;
5350 case 5:
5351 r.in.start_idx += r.out.info->info5.count;
5352 break;
5355 dom_info.in.domain_handle = handle;
5356 dom_info.in.level = 2;
5357 dom_info.out.info = &info;
5359 /* Check number of users returned is correct */
5360 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5361 if (!NT_STATUS_IS_OK(status)) {
5362 printf("QueryDomainInfo level %u failed - %s\n",
5363 r.in.level, nt_errstr(status));
5364 ret = false;
5365 break;
5367 switch (r.in.level) {
5368 case 1:
5369 case 4:
5370 if (info->general.num_users < r.in.start_idx) {
5371 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5372 r.in.start_idx, info->general.num_groups,
5373 info->general.domain_name.string);
5374 ret = false;
5376 if (!seen_testuser) {
5377 struct policy_handle user_handle;
5378 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5379 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5380 info->general.domain_name.string);
5381 ret = false;
5382 test_samr_handle_Close(p, tctx, &user_handle);
5385 break;
5386 case 3:
5387 case 5:
5388 if (info->general.num_groups != r.in.start_idx) {
5389 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5390 r.in.start_idx, info->general.num_groups,
5391 info->general.domain_name.string);
5392 ret = false;
5395 break;
5400 return ret;
5403 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5404 struct torture_context *tctx,
5405 struct policy_handle *handle)
5407 NTSTATUS status;
5408 struct samr_QueryDisplayInfo2 r;
5409 bool ret = true;
5410 uint16_t levels[] = {1, 2, 3, 4, 5};
5411 int i;
5412 uint32_t total_size;
5413 uint32_t returned_size;
5414 union samr_DispInfo info;
5416 for (i=0;i<ARRAY_SIZE(levels);i++) {
5417 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5419 r.in.domain_handle = handle;
5420 r.in.level = levels[i];
5421 r.in.start_idx = 0;
5422 r.in.max_entries = 1000;
5423 r.in.buf_size = (uint32_t)-1;
5424 r.out.total_size = &total_size;
5425 r.out.returned_size = &returned_size;
5426 r.out.info = &info;
5428 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5429 if (!NT_STATUS_IS_OK(status)) {
5430 printf("QueryDisplayInfo2 level %u failed - %s\n",
5431 levels[i], nt_errstr(status));
5432 ret = false;
5436 return ret;
5439 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5440 struct policy_handle *handle)
5442 NTSTATUS status;
5443 struct samr_QueryDisplayInfo3 r;
5444 bool ret = true;
5445 uint16_t levels[] = {1, 2, 3, 4, 5};
5446 int i;
5447 uint32_t total_size;
5448 uint32_t returned_size;
5449 union samr_DispInfo info;
5451 for (i=0;i<ARRAY_SIZE(levels);i++) {
5452 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5454 r.in.domain_handle = handle;
5455 r.in.level = levels[i];
5456 r.in.start_idx = 0;
5457 r.in.max_entries = 1000;
5458 r.in.buf_size = (uint32_t)-1;
5459 r.out.total_size = &total_size;
5460 r.out.returned_size = &returned_size;
5461 r.out.info = &info;
5463 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5464 if (!NT_STATUS_IS_OK(status)) {
5465 printf("QueryDisplayInfo3 level %u failed - %s\n",
5466 levels[i], nt_errstr(status));
5467 ret = false;
5471 return ret;
5475 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5476 struct torture_context *tctx,
5477 struct policy_handle *handle)
5479 NTSTATUS status;
5480 struct samr_QueryDisplayInfo r;
5481 bool ret = true;
5482 uint32_t total_size;
5483 uint32_t returned_size;
5484 union samr_DispInfo info;
5486 printf("Testing QueryDisplayInfo continuation\n");
5488 r.in.domain_handle = handle;
5489 r.in.level = 1;
5490 r.in.start_idx = 0;
5491 r.in.max_entries = 1;
5492 r.in.buf_size = (uint32_t)-1;
5493 r.out.total_size = &total_size;
5494 r.out.returned_size = &returned_size;
5495 r.out.info = &info;
5497 do {
5498 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5499 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5500 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5501 printf("expected idx %d but got %d\n",
5502 r.in.start_idx + 1,
5503 r.out.info->info1.entries[0].idx);
5504 break;
5507 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5508 !NT_STATUS_IS_OK(status)) {
5509 printf("QueryDisplayInfo level %u failed - %s\n",
5510 r.in.level, nt_errstr(status));
5511 ret = false;
5512 break;
5514 r.in.start_idx++;
5515 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5516 NT_STATUS_IS_OK(status)) &&
5517 *r.out.returned_size != 0);
5519 return ret;
5522 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5523 struct policy_handle *handle)
5525 NTSTATUS status;
5526 struct samr_QueryDomainInfo r;
5527 union samr_DomainInfo *info = NULL;
5528 struct samr_SetDomainInfo s;
5529 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5530 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5531 int i;
5532 bool ret = true;
5533 const char *domain_comment = talloc_asprintf(tctx,
5534 "Tortured by Samba4 RPC-SAMR: %s",
5535 timestring(tctx, time(NULL)));
5537 s.in.domain_handle = handle;
5538 s.in.level = 4;
5539 s.in.info = talloc(tctx, union samr_DomainInfo);
5541 s.in.info->oem.oem_information.string = domain_comment;
5542 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5543 if (!NT_STATUS_IS_OK(status)) {
5544 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5545 s.in.level, nt_errstr(status));
5546 return false;
5549 for (i=0;i<ARRAY_SIZE(levels);i++) {
5550 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5552 r.in.domain_handle = handle;
5553 r.in.level = levels[i];
5554 r.out.info = &info;
5556 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5557 if (!NT_STATUS_IS_OK(status)) {
5558 printf("QueryDomainInfo level %u failed - %s\n",
5559 r.in.level, nt_errstr(status));
5560 ret = false;
5561 continue;
5564 switch (levels[i]) {
5565 case 2:
5566 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5567 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5568 levels[i], info->general.oem_information.string, domain_comment);
5569 ret = false;
5571 if (!info->general.primary.string) {
5572 printf("QueryDomainInfo level %u returned no PDC name\n",
5573 levels[i]);
5574 ret = false;
5575 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5576 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5577 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5578 levels[i], info->general.primary.string, dcerpc_server_name(p));
5581 break;
5582 case 4:
5583 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5584 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5585 levels[i], info->oem.oem_information.string, domain_comment);
5586 ret = false;
5588 break;
5589 case 6:
5590 if (!info->info6.primary.string) {
5591 printf("QueryDomainInfo level %u returned no PDC name\n",
5592 levels[i]);
5593 ret = false;
5595 break;
5596 case 11:
5597 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5598 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5599 levels[i], info->general2.general.oem_information.string, domain_comment);
5600 ret = false;
5602 break;
5605 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5607 s.in.domain_handle = handle;
5608 s.in.level = levels[i];
5609 s.in.info = info;
5611 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5612 if (set_ok[i]) {
5613 if (!NT_STATUS_IS_OK(status)) {
5614 printf("SetDomainInfo level %u failed - %s\n",
5615 r.in.level, nt_errstr(status));
5616 ret = false;
5617 continue;
5619 } else {
5620 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5621 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5622 r.in.level, nt_errstr(status));
5623 ret = false;
5624 continue;
5628 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5629 if (!NT_STATUS_IS_OK(status)) {
5630 printf("QueryDomainInfo level %u failed - %s\n",
5631 r.in.level, nt_errstr(status));
5632 ret = false;
5633 continue;
5637 return ret;
5641 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5642 struct policy_handle *handle)
5644 NTSTATUS status;
5645 struct samr_QueryDomainInfo2 r;
5646 union samr_DomainInfo *info = NULL;
5647 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5648 int i;
5649 bool ret = true;
5651 for (i=0;i<ARRAY_SIZE(levels);i++) {
5652 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5654 r.in.domain_handle = handle;
5655 r.in.level = levels[i];
5656 r.out.info = &info;
5658 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5659 if (!NT_STATUS_IS_OK(status)) {
5660 printf("QueryDomainInfo2 level %u failed - %s\n",
5661 r.in.level, nt_errstr(status));
5662 ret = false;
5663 continue;
5667 return true;
5670 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5671 set of group names. */
5672 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5673 struct policy_handle *handle)
5675 struct samr_EnumDomainGroups q1;
5676 struct samr_QueryDisplayInfo q2;
5677 NTSTATUS status;
5678 uint32_t resume_handle=0;
5679 struct samr_SamArray *sam = NULL;
5680 uint32_t num_entries = 0;
5681 int i;
5682 bool ret = true;
5683 uint32_t total_size;
5684 uint32_t returned_size;
5685 union samr_DispInfo info;
5687 int num_names = 0;
5688 const char **names = NULL;
5690 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5692 q1.in.domain_handle = handle;
5693 q1.in.resume_handle = &resume_handle;
5694 q1.in.max_size = 5;
5695 q1.out.resume_handle = &resume_handle;
5696 q1.out.num_entries = &num_entries;
5697 q1.out.sam = &sam;
5699 status = STATUS_MORE_ENTRIES;
5700 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5701 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5703 if (!NT_STATUS_IS_OK(status) &&
5704 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5705 break;
5707 for (i=0; i<*q1.out.num_entries; i++) {
5708 add_string_to_array(tctx,
5709 sam->entries[i].name.string,
5710 &names, &num_names);
5714 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5716 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5718 q2.in.domain_handle = handle;
5719 q2.in.level = 5;
5720 q2.in.start_idx = 0;
5721 q2.in.max_entries = 5;
5722 q2.in.buf_size = (uint32_t)-1;
5723 q2.out.total_size = &total_size;
5724 q2.out.returned_size = &returned_size;
5725 q2.out.info = &info;
5727 status = STATUS_MORE_ENTRIES;
5728 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5729 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5731 if (!NT_STATUS_IS_OK(status) &&
5732 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5733 break;
5735 for (i=0; i<q2.out.info->info5.count; i++) {
5736 int j;
5737 const char *name = q2.out.info->info5.entries[i].account_name.string;
5738 bool found = false;
5739 for (j=0; j<num_names; j++) {
5740 if (names[j] == NULL)
5741 continue;
5742 if (strequal(names[j], name)) {
5743 names[j] = NULL;
5744 found = true;
5745 break;
5749 if (!found) {
5750 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5751 name);
5752 ret = false;
5755 q2.in.start_idx += q2.out.info->info5.count;
5758 if (!NT_STATUS_IS_OK(status)) {
5759 printf("QueryDisplayInfo level 5 failed - %s\n",
5760 nt_errstr(status));
5761 ret = false;
5764 for (i=0; i<num_names; i++) {
5765 if (names[i] != NULL) {
5766 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5767 names[i]);
5768 ret = false;
5772 return ret;
5775 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5776 struct policy_handle *group_handle)
5778 struct samr_DeleteDomainGroup d;
5779 NTSTATUS status;
5781 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5783 d.in.group_handle = group_handle;
5784 d.out.group_handle = group_handle;
5786 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5787 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5789 return true;
5792 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5793 struct policy_handle *domain_handle)
5795 struct samr_TestPrivateFunctionsDomain r;
5796 NTSTATUS status;
5797 bool ret = true;
5799 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5801 r.in.domain_handle = domain_handle;
5803 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5804 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5806 return ret;
5809 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5810 struct dom_sid *domain_sid,
5811 struct policy_handle *domain_handle)
5813 struct samr_RidToSid r;
5814 NTSTATUS status;
5815 bool ret = true;
5816 struct dom_sid *calc_sid, *out_sid;
5817 int rids[] = { 0, 42, 512, 10200 };
5818 int i;
5820 for (i=0;i<ARRAY_SIZE(rids);i++) {
5821 torture_comment(tctx, "Testing RidToSid\n");
5823 calc_sid = dom_sid_dup(tctx, domain_sid);
5824 r.in.domain_handle = domain_handle;
5825 r.in.rid = rids[i];
5826 r.out.sid = &out_sid;
5828 status = dcerpc_samr_RidToSid(p, tctx, &r);
5829 if (!NT_STATUS_IS_OK(status)) {
5830 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5831 ret = false;
5832 } else {
5833 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5835 if (!dom_sid_equal(calc_sid, out_sid)) {
5836 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5837 dom_sid_string(tctx, out_sid),
5838 dom_sid_string(tctx, calc_sid));
5839 ret = false;
5844 return ret;
5847 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5848 struct policy_handle *domain_handle)
5850 struct samr_GetBootKeyInformation r;
5851 NTSTATUS status;
5852 bool ret = true;
5853 uint32_t unknown = 0;
5855 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5857 r.in.domain_handle = domain_handle;
5858 r.out.unknown = &unknown;
5860 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5861 if (!NT_STATUS_IS_OK(status)) {
5862 /* w2k3 seems to fail this sometimes and pass it sometimes */
5863 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5866 return ret;
5869 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5870 struct policy_handle *domain_handle,
5871 struct policy_handle *group_handle)
5873 NTSTATUS status;
5874 struct samr_AddGroupMember r;
5875 struct samr_DeleteGroupMember d;
5876 struct samr_QueryGroupMember q;
5877 struct samr_RidTypeArray *rids = NULL;
5878 struct samr_SetMemberAttributesOfGroup s;
5879 uint32_t rid;
5881 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5882 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5884 r.in.group_handle = group_handle;
5885 r.in.rid = rid;
5886 r.in.flags = 0; /* ??? */
5888 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5890 d.in.group_handle = group_handle;
5891 d.in.rid = rid;
5893 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5894 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5896 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5897 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5899 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5900 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5902 if (torture_setting_bool(tctx, "samba4", false) ||
5903 torture_setting_bool(tctx, "samba3", false)) {
5904 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5905 } else {
5906 /* this one is quite strange. I am using random inputs in the
5907 hope of triggering an error that might give us a clue */
5909 s.in.group_handle = group_handle;
5910 s.in.unknown1 = random();
5911 s.in.unknown2 = random();
5913 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5914 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5917 q.in.group_handle = group_handle;
5918 q.out.rids = &rids;
5920 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5921 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5923 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5924 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5926 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5927 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5929 return true;
5933 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5934 struct torture_context *tctx,
5935 struct policy_handle *domain_handle,
5936 struct policy_handle *group_handle,
5937 struct dom_sid *domain_sid)
5939 NTSTATUS status;
5940 struct samr_CreateDomainGroup r;
5941 uint32_t rid;
5942 struct lsa_String name;
5943 bool ret = true;
5945 init_lsa_String(&name, TEST_GROUPNAME);
5947 r.in.domain_handle = domain_handle;
5948 r.in.name = &name;
5949 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5950 r.out.group_handle = group_handle;
5951 r.out.rid = &rid;
5953 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5955 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5957 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5958 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5959 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5960 return true;
5961 } else {
5962 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5963 nt_errstr(status));
5964 return false;
5968 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5969 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5970 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5971 nt_errstr(status));
5972 return false;
5974 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5976 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5977 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5979 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5980 nt_errstr(status));
5981 return false;
5983 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5985 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5987 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5988 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5989 ret = false;
5992 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5993 ret = false;
5996 return ret;
6001 its not totally clear what this does. It seems to accept any sid you like.
6003 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6004 struct torture_context *tctx,
6005 struct policy_handle *domain_handle)
6007 NTSTATUS status;
6008 struct samr_RemoveMemberFromForeignDomain r;
6010 r.in.domain_handle = domain_handle;
6011 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6013 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6014 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6016 return true;
6021 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6022 struct policy_handle *handle);
6024 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6025 struct policy_handle *handle, struct dom_sid *sid,
6026 enum torture_samr_choice which_ops,
6027 struct cli_credentials *machine_credentials)
6029 NTSTATUS status;
6030 struct samr_OpenDomain r;
6031 struct policy_handle domain_handle;
6032 struct policy_handle alias_handle;
6033 struct policy_handle user_handle;
6034 struct policy_handle group_handle;
6035 bool ret = true;
6037 ZERO_STRUCT(alias_handle);
6038 ZERO_STRUCT(user_handle);
6039 ZERO_STRUCT(group_handle);
6040 ZERO_STRUCT(domain_handle);
6042 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6044 r.in.connect_handle = handle;
6045 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6046 r.in.sid = sid;
6047 r.out.domain_handle = &domain_handle;
6049 status = dcerpc_samr_OpenDomain(p, tctx, &r);
6050 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6052 /* run the domain tests with the main handle closed - this tests
6053 the servers reference counting */
6054 ret &= test_samr_handle_Close(p, tctx, handle);
6056 switch (which_ops) {
6057 case TORTURE_SAMR_USER_ATTRIBUTES:
6058 case TORTURE_SAMR_USER_PRIVILEGES:
6059 case TORTURE_SAMR_PASSWORDS:
6060 if (!torture_setting_bool(tctx, "samba3", false)) {
6061 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6063 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
6064 /* This test needs 'complex' users to validate */
6065 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6066 if (!ret) {
6067 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6069 break;
6070 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6071 if (!torture_setting_bool(tctx, "samba3", false)) {
6072 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6074 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials);
6075 if (!ret) {
6076 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6078 break;
6079 case TORTURE_SAMR_OTHER:
6080 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
6081 if (!ret) {
6082 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6084 if (!torture_setting_bool(tctx, "samba3", false)) {
6085 ret &= test_QuerySecurity(p, tctx, &domain_handle);
6087 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6088 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
6089 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
6090 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6091 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6092 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
6093 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6094 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
6095 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
6096 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6097 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6098 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6100 if (torture_setting_bool(tctx, "samba4", false)) {
6101 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6102 } else {
6103 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6104 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6106 ret &= test_GroupList(p, tctx, &domain_handle);
6107 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6108 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6109 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6110 if (!ret) {
6111 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6113 break;
6116 if (!policy_handle_empty(&user_handle) &&
6117 !test_DeleteUser(p, tctx, &user_handle)) {
6118 ret = false;
6121 if (!policy_handle_empty(&alias_handle) &&
6122 !test_DeleteAlias(p, tctx, &alias_handle)) {
6123 ret = false;
6126 if (!policy_handle_empty(&group_handle) &&
6127 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6128 ret = false;
6131 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
6133 /* reconnect the main handle */
6134 ret &= test_Connect(p, tctx, handle);
6136 if (!ret) {
6137 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6140 return ret;
6143 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6144 struct policy_handle *handle, const char *domain,
6145 enum torture_samr_choice which_ops,
6146 struct cli_credentials *machine_credentials)
6148 NTSTATUS status;
6149 struct samr_LookupDomain r;
6150 struct dom_sid2 *sid = NULL;
6151 struct lsa_String n1;
6152 struct lsa_String n2;
6153 bool ret = true;
6155 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6157 /* check for correct error codes */
6158 r.in.connect_handle = handle;
6159 r.in.domain_name = &n2;
6160 r.out.sid = &sid;
6161 n2.string = NULL;
6163 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6164 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6166 init_lsa_String(&n2, "xxNODOMAINxx");
6168 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6169 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6171 r.in.connect_handle = handle;
6173 init_lsa_String(&n1, domain);
6174 r.in.domain_name = &n1;
6176 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6177 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6179 if (!test_GetDomPwInfo(p, tctx, &n1)) {
6180 ret = false;
6183 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6184 machine_credentials)) {
6185 ret = false;
6188 return ret;
6192 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6193 struct policy_handle *handle, enum torture_samr_choice which_ops,
6194 struct cli_credentials *machine_credentials)
6196 NTSTATUS status;
6197 struct samr_EnumDomains r;
6198 uint32_t resume_handle = 0;
6199 uint32_t num_entries = 0;
6200 struct samr_SamArray *sam = NULL;
6201 int i;
6202 bool ret = true;
6204 r.in.connect_handle = handle;
6205 r.in.resume_handle = &resume_handle;
6206 r.in.buf_size = (uint32_t)-1;
6207 r.out.resume_handle = &resume_handle;
6208 r.out.num_entries = &num_entries;
6209 r.out.sam = &sam;
6211 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6212 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6214 if (!*r.out.sam) {
6215 return false;
6218 for (i=0;i<sam->count;i++) {
6219 if (!test_LookupDomain(p, tctx, handle,
6220 sam->entries[i].name.string, which_ops,
6221 machine_credentials)) {
6222 ret = false;
6226 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6227 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6229 return ret;
6233 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6234 struct policy_handle *handle)
6236 NTSTATUS status;
6237 struct samr_Connect r;
6238 struct samr_Connect2 r2;
6239 struct samr_Connect3 r3;
6240 struct samr_Connect4 r4;
6241 struct samr_Connect5 r5;
6242 union samr_ConnectInfo info;
6243 struct policy_handle h;
6244 uint32_t level_out = 0;
6245 bool ret = true, got_handle = false;
6247 torture_comment(tctx, "testing samr_Connect\n");
6249 r.in.system_name = 0;
6250 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6251 r.out.connect_handle = &h;
6253 status = dcerpc_samr_Connect(p, tctx, &r);
6254 if (!NT_STATUS_IS_OK(status)) {
6255 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6256 ret = false;
6257 } else {
6258 got_handle = true;
6259 *handle = h;
6262 torture_comment(tctx, "testing samr_Connect2\n");
6264 r2.in.system_name = NULL;
6265 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6266 r2.out.connect_handle = &h;
6268 status = dcerpc_samr_Connect2(p, tctx, &r2);
6269 if (!NT_STATUS_IS_OK(status)) {
6270 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6271 ret = false;
6272 } else {
6273 if (got_handle) {
6274 test_samr_handle_Close(p, tctx, handle);
6276 got_handle = true;
6277 *handle = h;
6280 torture_comment(tctx, "testing samr_Connect3\n");
6282 r3.in.system_name = NULL;
6283 r3.in.unknown = 0;
6284 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6285 r3.out.connect_handle = &h;
6287 status = dcerpc_samr_Connect3(p, tctx, &r3);
6288 if (!NT_STATUS_IS_OK(status)) {
6289 printf("Connect3 failed - %s\n", nt_errstr(status));
6290 ret = false;
6291 } else {
6292 if (got_handle) {
6293 test_samr_handle_Close(p, tctx, handle);
6295 got_handle = true;
6296 *handle = h;
6299 torture_comment(tctx, "testing samr_Connect4\n");
6301 r4.in.system_name = "";
6302 r4.in.client_version = 0;
6303 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6304 r4.out.connect_handle = &h;
6306 status = dcerpc_samr_Connect4(p, tctx, &r4);
6307 if (!NT_STATUS_IS_OK(status)) {
6308 printf("Connect4 failed - %s\n", nt_errstr(status));
6309 ret = false;
6310 } else {
6311 if (got_handle) {
6312 test_samr_handle_Close(p, tctx, handle);
6314 got_handle = true;
6315 *handle = h;
6318 torture_comment(tctx, "testing samr_Connect5\n");
6320 info.info1.client_version = 0;
6321 info.info1.unknown2 = 0;
6323 r5.in.system_name = "";
6324 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6325 r5.in.level_in = 1;
6326 r5.out.level_out = &level_out;
6327 r5.in.info_in = &info;
6328 r5.out.info_out = &info;
6329 r5.out.connect_handle = &h;
6331 status = dcerpc_samr_Connect5(p, tctx, &r5);
6332 if (!NT_STATUS_IS_OK(status)) {
6333 printf("Connect5 failed - %s\n", nt_errstr(status));
6334 ret = false;
6335 } else {
6336 if (got_handle) {
6337 test_samr_handle_Close(p, tctx, handle);
6339 got_handle = true;
6340 *handle = h;
6343 return ret;
6347 bool torture_rpc_samr(struct torture_context *torture)
6349 NTSTATUS status;
6350 struct dcerpc_pipe *p;
6351 bool ret = true;
6352 struct policy_handle handle;
6354 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6355 if (!NT_STATUS_IS_OK(status)) {
6356 return false;
6359 ret &= test_Connect(p, torture, &handle);
6361 if (!torture_setting_bool(torture, "samba3", false)) {
6362 ret &= test_QuerySecurity(p, torture, &handle);
6365 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6367 ret &= test_SetDsrmPassword(p, torture, &handle);
6369 ret &= test_Shutdown(p, torture, &handle);
6371 ret &= test_samr_handle_Close(p, torture, &handle);
6373 return ret;
6377 bool torture_rpc_samr_users(struct torture_context *torture)
6379 NTSTATUS status;
6380 struct dcerpc_pipe *p;
6381 bool ret = true;
6382 struct policy_handle handle;
6384 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6385 if (!NT_STATUS_IS_OK(status)) {
6386 return false;
6389 ret &= test_Connect(p, torture, &handle);
6391 if (!torture_setting_bool(torture, "samba3", false)) {
6392 ret &= test_QuerySecurity(p, torture, &handle);
6395 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6397 ret &= test_SetDsrmPassword(p, torture, &handle);
6399 ret &= test_Shutdown(p, torture, &handle);
6401 ret &= test_samr_handle_Close(p, torture, &handle);
6403 return ret;
6407 bool torture_rpc_samr_passwords(struct torture_context *torture)
6409 NTSTATUS status;
6410 struct dcerpc_pipe *p;
6411 bool ret = true;
6412 struct policy_handle handle;
6414 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6415 if (!NT_STATUS_IS_OK(status)) {
6416 return false;
6419 ret &= test_Connect(p, torture, &handle);
6421 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6423 ret &= test_samr_handle_Close(p, torture, &handle);
6425 return ret;
6428 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6429 struct dcerpc_pipe *p2,
6430 struct cli_credentials *machine_credentials)
6432 NTSTATUS status;
6433 struct dcerpc_pipe *p;
6434 bool ret = true;
6435 struct policy_handle handle;
6437 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6438 if (!NT_STATUS_IS_OK(status)) {
6439 return false;
6442 ret &= test_Connect(p, torture, &handle);
6444 ret &= test_EnumDomains(p, torture, &handle,
6445 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6446 machine_credentials);
6448 ret &= test_samr_handle_Close(p, torture, &handle);
6450 return ret;
6453 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(struct torture_context *tctx)
6455 struct torture_suite *suite = torture_suite_create(tctx, "SAMR-PASSWORDS-PWDLASTSET");
6456 struct torture_rpc_tcase *tcase;
6458 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6459 &ndr_table_samr,
6460 TEST_ACCOUNT_NAME_PWD);
6462 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6463 torture_rpc_samr_pwdlastset);
6465 return suite;
6468 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6469 struct dcerpc_pipe *p2,
6470 struct cli_credentials *machine_credentials)
6472 NTSTATUS status;
6473 struct dcerpc_pipe *p;
6474 bool ret = true;
6475 struct policy_handle handle;
6477 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6478 if (!NT_STATUS_IS_OK(status)) {
6479 return false;
6482 ret &= test_Connect(p, torture, &handle);
6484 ret &= test_EnumDomains(p, torture, &handle,
6485 TORTURE_SAMR_USER_PRIVILEGES,
6486 machine_credentials);
6488 ret &= test_samr_handle_Close(p, torture, &handle);
6490 return ret;
6493 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6495 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6496 struct torture_rpc_tcase *tcase;
6498 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6499 &ndr_table_samr,
6500 TEST_ACCOUNT_NAME_PWD);
6502 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6503 torture_rpc_samr_users_privileges_delete_user);
6505 return suite;