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