Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : test security descriptor operations
5 :
6 : Copyright (C) Andrew Tridgell 2004
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "torture/torture.h"
24 : #include "libcli/raw/libcliraw.h"
25 : #include "libcli/libcli.h"
26 : #include "librpc/gen_ndr/lsa.h"
27 : #include "libcli/smb2/smb2.h"
28 : #include "libcli/util/clilsa.h"
29 : #include "libcli/security/security.h"
30 : #include "torture/util.h"
31 : #include "librpc/gen_ndr/ndr_security.h"
32 : #include "torture/raw/proto.h"
33 :
34 : #define BASEDIR "\\testsd"
35 :
36 : #define CHECK_STATUS(status, correct) do { \
37 : if (!NT_STATUS_EQUAL(status, correct)) { \
38 : ret = false; \
39 : torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
40 : __location__, nt_errstr(status), nt_errstr(correct)); \
41 : goto done; \
42 : }} while (0)
43 :
44 : #define FAIL_UNLESS(__cond) \
45 : do { \
46 : if (__cond) {} else { \
47 : ret = false; \
48 : torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n", \
49 : __location__, #__cond); \
50 : goto done; \
51 : } \
52 : } while(0)
53 :
54 : #define CHECK_SECURITY_DESCRIPTOR(_sd1, _sd2) do { \
55 : if (!security_descriptor_equal(_sd1, _sd2)) { \
56 : torture_warning(tctx, "%s: security descriptors don't match!\n", __location__); \
57 : torture_warning(tctx, "got:\n"); \
58 : NDR_PRINT_DEBUG(security_descriptor, _sd1); \
59 : torture_warning(tctx, "expected:\n"); \
60 : NDR_PRINT_DEBUG(security_descriptor, _sd2); \
61 : ret = false; \
62 : } \
63 : } while (0)
64 :
65 : /*
66 : * Helper function to verify a security descriptor, by querying
67 : * and comparing against the passed in sd.
68 : * Copied to smb2_util_verify_sd() for SMB2.
69 : */
70 151 : static bool verify_sd(TALLOC_CTX *tctx, struct smbcli_state *cli,
71 : int fnum, struct security_descriptor *sd)
72 : {
73 0 : NTSTATUS status;
74 151 : bool ret = true;
75 151 : union smb_fileinfo q = {};
76 :
77 151 : if (sd) {
78 151 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
79 151 : q.query_secdesc.in.file.fnum = fnum;
80 151 : q.query_secdesc.in.secinfo_flags =
81 : SECINFO_OWNER |
82 : SECINFO_GROUP |
83 : SECINFO_DACL;
84 151 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
85 151 : CHECK_STATUS(status, NT_STATUS_OK);
86 :
87 : /* More work is needed if we're going to check this bit. */
88 151 : sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
89 :
90 151 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
91 : }
92 :
93 121 : done:
94 151 : return ret;
95 : }
96 :
97 : /*
98 : * Helper function to verify attributes, by querying
99 : * and comparing against the passed attrib.
100 : * Copied to smb2_util_verify_attrib() for SMB2.
101 : */
102 83 : static bool verify_attrib(TALLOC_CTX *tctx, struct smbcli_state *cli,
103 : int fnum, uint32_t attrib)
104 : {
105 0 : NTSTATUS status;
106 83 : bool ret = true;
107 83 : union smb_fileinfo q2 = {};
108 :
109 83 : if (attrib) {
110 83 : q2.standard.level = RAW_FILEINFO_STANDARD;
111 83 : q2.standard.in.file.fnum = fnum;
112 83 : status = smb_raw_fileinfo(cli->tree, tctx, &q2);
113 83 : CHECK_STATUS(status, NT_STATUS_OK);
114 :
115 83 : q2.standard.out.attrib &= ~FILE_ATTRIBUTE_ARCHIVE;
116 :
117 83 : if (q2.standard.out.attrib != attrib) {
118 1 : torture_warning(tctx, "%s: attributes don't match! "
119 : "got %x, expected %x\n", __location__,
120 1 : (uint32_t)q2.standard.out.attrib,
121 : (uint32_t)attrib);
122 1 : ret = false;
123 : }
124 : }
125 :
126 82 : done:
127 83 : return ret;
128 : }
129 :
130 : /**
131 : * Test setting and removing a DACL.
132 : * Test copied to torture_smb2_setinfo() for SMB2.
133 : */
134 19 : static bool test_sd(struct torture_context *tctx, struct smbcli_state *cli)
135 : {
136 0 : NTSTATUS status;
137 0 : union smb_open io;
138 19 : const char *fname = BASEDIR "\\sd.txt";
139 19 : bool ret = true;
140 19 : int fnum = -1;
141 0 : union smb_fileinfo q;
142 0 : union smb_setfileinfo set;
143 19 : struct security_ace ace = {};
144 0 : struct security_descriptor *sd;
145 0 : const struct dom_sid *test_sid;
146 :
147 19 : if (!torture_setup_dir(cli, BASEDIR))
148 0 : return false;
149 :
150 19 : torture_comment(tctx, "TESTING SETFILEINFO EA_SET\n");
151 :
152 19 : io.generic.level = RAW_OPEN_NTCREATEX;
153 19 : io.ntcreatex.in.root_fid.fnum = 0;
154 19 : io.ntcreatex.in.flags = 0;
155 19 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
156 19 : io.ntcreatex.in.create_options = 0;
157 19 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
158 19 : io.ntcreatex.in.share_access =
159 : NTCREATEX_SHARE_ACCESS_READ |
160 : NTCREATEX_SHARE_ACCESS_WRITE;
161 19 : io.ntcreatex.in.alloc_size = 0;
162 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
163 19 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
164 19 : io.ntcreatex.in.security_flags = 0;
165 19 : io.ntcreatex.in.fname = fname;
166 19 : status = smb_raw_open(cli->tree, tctx, &io);
167 19 : CHECK_STATUS(status, NT_STATUS_OK);
168 19 : fnum = io.ntcreatex.out.file.fnum;
169 :
170 19 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
171 19 : q.query_secdesc.in.file.fnum = fnum;
172 19 : q.query_secdesc.in.secinfo_flags =
173 : SECINFO_OWNER |
174 : SECINFO_GROUP |
175 : SECINFO_DACL;
176 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
177 19 : CHECK_STATUS(status, NT_STATUS_OK);
178 19 : sd = q.query_secdesc.out.sd;
179 :
180 19 : torture_comment(tctx, "add a new ACE to the DACL\n");
181 :
182 19 : test_sid = &global_sid_Authenticated_Users;
183 :
184 19 : ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
185 19 : ace.flags = 0;
186 19 : ace.access_mask = SEC_STD_ALL;
187 19 : ace.trustee = *test_sid;
188 :
189 19 : status = security_descriptor_dacl_add(sd, &ace);
190 19 : CHECK_STATUS(status, NT_STATUS_OK);
191 :
192 19 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
193 19 : set.set_secdesc.in.file.fnum = fnum;
194 19 : set.set_secdesc.in.secinfo_flags = q.query_secdesc.in.secinfo_flags;
195 19 : set.set_secdesc.in.sd = sd;
196 :
197 19 : status = smb_raw_setfileinfo(cli->tree, &set);
198 19 : CHECK_STATUS(status, NT_STATUS_OK);
199 19 : FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
200 :
201 19 : torture_comment(tctx, "remove it again\n");
202 :
203 19 : status = security_descriptor_dacl_del(sd, test_sid);
204 19 : CHECK_STATUS(status, NT_STATUS_OK);
205 :
206 19 : status = smb_raw_setfileinfo(cli->tree, &set);
207 19 : CHECK_STATUS(status, NT_STATUS_OK);
208 19 : FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
209 :
210 19 : done:
211 19 : smbcli_close(cli->tree, fnum);
212 19 : smb_raw_exit(cli->session);
213 19 : smbcli_deltree(cli->tree, BASEDIR);
214 :
215 19 : return ret;
216 : }
217 :
218 :
219 : /*
220 : test using nttrans create to create a file with an initial acl set
221 : Test copied to test_create_acl() for SMB2.
222 : */
223 38 : static bool test_nttrans_create_ext(struct torture_context *tctx,
224 : struct smbcli_state *cli, bool test_dir)
225 : {
226 0 : NTSTATUS status;
227 0 : union smb_open io;
228 38 : const char *fname = BASEDIR "\\acl2.txt";
229 38 : bool ret = true;
230 38 : int fnum = -1;
231 38 : union smb_fileinfo q = {};
232 0 : struct security_ace ace;
233 0 : struct security_descriptor *sd;
234 0 : const struct dom_sid *test_sid;
235 38 : uint32_t attrib =
236 : FILE_ATTRIBUTE_HIDDEN |
237 : FILE_ATTRIBUTE_SYSTEM |
238 : (test_dir ? FILE_ATTRIBUTE_DIRECTORY : 0);
239 38 : NTSTATUS (*delete_func)(struct smbcli_tree *, const char *) =
240 38 : test_dir ? smbcli_rmdir : smbcli_unlink;
241 :
242 38 : ZERO_STRUCT(ace);
243 :
244 38 : if (!torture_setup_dir(cli, BASEDIR))
245 0 : return false;
246 :
247 38 : io.generic.level = RAW_OPEN_NTTRANS_CREATE;
248 38 : io.ntcreatex.in.root_fid.fnum = 0;
249 38 : io.ntcreatex.in.flags = 0;
250 38 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
251 38 : io.ntcreatex.in.create_options =
252 38 : test_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
253 38 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
254 38 : io.ntcreatex.in.share_access =
255 : NTCREATEX_SHARE_ACCESS_READ |
256 : NTCREATEX_SHARE_ACCESS_WRITE;
257 38 : io.ntcreatex.in.alloc_size = 0;
258 38 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
259 38 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
260 38 : io.ntcreatex.in.security_flags = 0;
261 38 : io.ntcreatex.in.fname = fname;
262 38 : io.ntcreatex.in.sec_desc = NULL;
263 38 : io.ntcreatex.in.ea_list = NULL;
264 :
265 38 : torture_comment(tctx, "basic create\n");
266 :
267 38 : status = smb_raw_open(cli->tree, tctx, &io);
268 38 : CHECK_STATUS(status, NT_STATUS_OK);
269 38 : fnum = io.ntcreatex.out.file.fnum;
270 :
271 38 : torture_comment(tctx, "querying ACL\n");
272 :
273 38 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
274 38 : q.query_secdesc.in.file.fnum = fnum;
275 38 : q.query_secdesc.in.secinfo_flags =
276 : SECINFO_OWNER |
277 : SECINFO_GROUP |
278 : SECINFO_DACL;
279 38 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
280 38 : CHECK_STATUS(status, NT_STATUS_OK);
281 38 : sd = q.query_secdesc.out.sd;
282 :
283 38 : status = smbcli_close(cli->tree, fnum);
284 38 : CHECK_STATUS(status, NT_STATUS_OK);
285 :
286 38 : status = delete_func(cli->tree, fname);
287 38 : CHECK_STATUS(status, NT_STATUS_OK);
288 :
289 38 : torture_comment(tctx, "adding a new ACE\n");
290 38 : test_sid = &global_sid_Authenticated_Users;
291 :
292 38 : ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
293 38 : ace.flags = 0;
294 38 : ace.access_mask = SEC_STD_ALL;
295 38 : ace.trustee = *test_sid;
296 :
297 38 : status = security_descriptor_dacl_add(sd, &ace);
298 38 : CHECK_STATUS(status, NT_STATUS_OK);
299 :
300 38 : torture_comment(tctx, "creating with an initial ACL\n");
301 :
302 38 : io.ntcreatex.in.sec_desc = sd;
303 38 : status = smb_raw_open(cli->tree, tctx, &io);
304 38 : CHECK_STATUS(status, NT_STATUS_OK);
305 38 : fnum = io.ntcreatex.out.file.fnum;
306 :
307 38 : FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
308 :
309 38 : status = smbcli_close(cli->tree, fnum);
310 38 : CHECK_STATUS(status, NT_STATUS_OK);
311 38 : status = delete_func(cli->tree, fname);
312 38 : CHECK_STATUS(status, NT_STATUS_OK);
313 :
314 38 : torture_comment(tctx, "creating with attributes\n");
315 :
316 38 : io.ntcreatex.in.sec_desc = NULL;
317 38 : io.ntcreatex.in.file_attr = attrib;
318 38 : status = smb_raw_open(cli->tree, tctx, &io);
319 38 : CHECK_STATUS(status, NT_STATUS_OK);
320 38 : fnum = io.ntcreatex.out.file.fnum;
321 :
322 38 : FAIL_UNLESS(verify_attrib(tctx, cli, fnum, attrib));
323 :
324 37 : status = smbcli_close(cli->tree, fnum);
325 37 : CHECK_STATUS(status, NT_STATUS_OK);
326 :
327 37 : status = delete_func(cli->tree, fname);
328 37 : CHECK_STATUS(status, NT_STATUS_OK);
329 :
330 37 : torture_comment(tctx, "creating with attributes and ACL\n");
331 :
332 37 : io.ntcreatex.in.sec_desc = sd;
333 37 : io.ntcreatex.in.file_attr = attrib;
334 37 : status = smb_raw_open(cli->tree, tctx, &io);
335 37 : CHECK_STATUS(status, NT_STATUS_OK);
336 37 : fnum = io.ntcreatex.out.file.fnum;
337 :
338 37 : FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
339 37 : FAIL_UNLESS(verify_attrib(tctx, cli, fnum, attrib));
340 :
341 37 : status = smbcli_close(cli->tree, fnum);
342 37 : CHECK_STATUS(status, NT_STATUS_OK);
343 37 : status = delete_func(cli->tree, fname);
344 37 : CHECK_STATUS(status, NT_STATUS_OK);
345 :
346 38 : done:
347 38 : smbcli_close(cli->tree, fnum);
348 38 : smb_raw_exit(cli->session);
349 38 : smbcli_deltree(cli->tree, BASEDIR);
350 38 : return ret;
351 : }
352 :
353 : /*
354 : test using nttrans create to create a file and directory with an initial acl
355 : and owner.
356 : */
357 38 : static bool test_nttrans_create_ext_owner(
358 : struct torture_context *tctx,
359 : struct smbcli_state *cli, bool test_dir)
360 : {
361 0 : NTSTATUS status;
362 0 : union smb_open io;
363 38 : const char *fname = BASEDIR "\\foo.txt";
364 38 : bool ret = true;
365 38 : int fnum = -1;
366 0 : struct security_ace ace;
367 0 : struct security_descriptor *sd;
368 38 : uint32_t attrib =
369 : FILE_ATTRIBUTE_HIDDEN |
370 : FILE_ATTRIBUTE_SYSTEM |
371 : (test_dir ? FILE_ATTRIBUTE_DIRECTORY : 0);
372 38 : NTSTATUS (*delete_func)(struct smbcli_tree *, const char *) =
373 38 : test_dir ? smbcli_rmdir : smbcli_unlink;
374 :
375 38 : ZERO_STRUCT(ace);
376 :
377 38 : smbcli_deltree(cli->tree, BASEDIR);
378 :
379 38 : if (!torture_setup_dir(cli, BASEDIR))
380 0 : return false;
381 :
382 38 : io.generic.level = RAW_OPEN_NTTRANS_CREATE;
383 38 : io.ntcreatex.in.root_fid.fnum = 0;
384 38 : io.ntcreatex.in.flags = 0;
385 38 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
386 38 : io.ntcreatex.in.create_options =
387 38 : test_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
388 38 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
389 38 : io.ntcreatex.in.share_access =
390 : NTCREATEX_SHARE_ACCESS_READ |
391 : NTCREATEX_SHARE_ACCESS_WRITE;
392 38 : io.ntcreatex.in.alloc_size = 0;
393 38 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
394 38 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
395 38 : io.ntcreatex.in.security_flags = 0;
396 38 : io.ntcreatex.in.fname = fname;
397 38 : io.ntcreatex.in.sec_desc = NULL;
398 38 : io.ntcreatex.in.ea_list = NULL;
399 :
400 38 : torture_comment(tctx, "creating with attributes, ACL and owner\n");
401 :
402 38 : sd = security_descriptor_dacl_create(tctx,
403 : 0, SID_WORLD, SID_BUILTIN_USERS,
404 : SID_WORLD,
405 : SEC_ACE_TYPE_ACCESS_ALLOWED,
406 : SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
407 : 0,
408 : NULL);
409 :
410 38 : io.ntcreatex.in.sec_desc = sd;
411 38 : io.ntcreatex.in.file_attr = attrib;
412 38 : status = smb_raw_open(cli->tree, tctx, &io);
413 38 : CHECK_STATUS(status, NT_STATUS_OK);
414 38 : fnum = io.ntcreatex.out.file.fnum;
415 :
416 38 : FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
417 8 : FAIL_UNLESS(verify_attrib(tctx, cli, fnum, attrib));
418 :
419 8 : status = smbcli_close(cli->tree, fnum);
420 8 : CHECK_STATUS(status, NT_STATUS_OK);
421 8 : status = delete_func(cli->tree, fname);
422 8 : CHECK_STATUS(status, NT_STATUS_OK);
423 :
424 38 : done:
425 38 : smbcli_close(cli->tree, fnum);
426 38 : smb_raw_exit(cli->session);
427 38 : smbcli_deltree(cli->tree, BASEDIR);
428 38 : return ret;
429 : }
430 :
431 19 : static bool test_nttrans_create_file(struct torture_context *tctx,
432 : struct smbcli_state *cli)
433 : {
434 19 : torture_comment(tctx, "Testing nttrans create with sec_desc on files\n");
435 :
436 19 : return test_nttrans_create_ext(tctx, cli, false);
437 : }
438 :
439 19 : static bool test_nttrans_create_dir(struct torture_context *tctx,
440 : struct smbcli_state *cli)
441 : {
442 19 : torture_comment(tctx, "Testing nttrans create with sec_desc on directories\n");
443 :
444 19 : return test_nttrans_create_ext(tctx, cli, true);
445 : }
446 :
447 19 : static bool test_nttrans_create_owner_file(struct torture_context *tctx,
448 : struct smbcli_state *cli)
449 : {
450 19 : torture_comment(tctx, "Testing nttrans create with sec_desc with owner on file\n");
451 :
452 19 : return test_nttrans_create_ext_owner(tctx, cli, false);
453 : }
454 :
455 19 : static bool test_nttrans_create_owner_dir(struct torture_context *tctx,
456 : struct smbcli_state *cli)
457 : {
458 19 : torture_comment(tctx, "Testing nttrans create with sec_desc with owner on directory\n");
459 :
460 19 : return test_nttrans_create_ext_owner(tctx, cli, true);
461 : }
462 :
463 : #define CHECK_ACCESS_FLAGS(_fnum, flags) do { \
464 : union smb_fileinfo _q; \
465 : _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
466 : _q.access_information.in.file.fnum = (_fnum); \
467 : status = smb_raw_fileinfo(cli->tree, tctx, &_q); \
468 : CHECK_STATUS(status, NT_STATUS_OK); \
469 : if (_q.access_information.out.access_flags != (flags)) { \
470 : ret = false; \
471 : torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
472 : __location__, _q.access_information.out.access_flags, (flags)); \
473 : goto done; \
474 : } \
475 : } while (0)
476 :
477 : /*
478 : test using NTTRANS CREATE to create a file with a null ACL set
479 : Test copied to test_create_null_dacl() for SMB2.
480 : */
481 19 : static bool test_nttrans_create_null_dacl(struct torture_context *tctx,
482 : struct smbcli_state *cli)
483 : {
484 0 : NTSTATUS status;
485 0 : union smb_open io;
486 19 : const char *fname = BASEDIR "\\nulldacl.txt";
487 19 : bool ret = true;
488 19 : int fnum = -1;
489 0 : union smb_fileinfo q;
490 0 : union smb_setfileinfo s;
491 19 : struct security_descriptor *sd = security_descriptor_initialise(tctx);
492 0 : struct security_acl dacl;
493 :
494 19 : if (!torture_setup_dir(cli, BASEDIR))
495 0 : return false;
496 :
497 19 : torture_comment(tctx, "TESTING SEC_DESC WITH A NULL DACL\n");
498 :
499 19 : io.generic.level = RAW_OPEN_NTTRANS_CREATE;
500 19 : io.ntcreatex.in.root_fid.fnum = 0;
501 19 : io.ntcreatex.in.flags = 0;
502 19 : io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC
503 : | SEC_STD_WRITE_OWNER;
504 19 : io.ntcreatex.in.create_options = 0;
505 19 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
506 19 : io.ntcreatex.in.share_access =
507 : NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
508 19 : io.ntcreatex.in.alloc_size = 0;
509 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
510 19 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
511 19 : io.ntcreatex.in.security_flags = 0;
512 19 : io.ntcreatex.in.fname = fname;
513 19 : io.ntcreatex.in.sec_desc = sd;
514 19 : io.ntcreatex.in.ea_list = NULL;
515 :
516 19 : torture_comment(tctx, "creating a file with a empty sd\n");
517 19 : status = smb_raw_open(cli->tree, tctx, &io);
518 19 : CHECK_STATUS(status, NT_STATUS_OK);
519 19 : fnum = io.ntcreatex.out.file.fnum;
520 :
521 19 : torture_comment(tctx, "get the original sd\n");
522 19 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
523 19 : q.query_secdesc.in.file.fnum = fnum;
524 19 : q.query_secdesc.in.secinfo_flags =
525 : SECINFO_OWNER |
526 : SECINFO_GROUP |
527 : SECINFO_DACL;
528 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
529 19 : CHECK_STATUS(status, NT_STATUS_OK);
530 :
531 : /*
532 : * Testing the created DACL,
533 : * the server should add the inherited DACL
534 : * when SEC_DESC_DACL_PRESENT isn't specified
535 : */
536 19 : if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
537 0 : ret = false;
538 0 : torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
539 0 : goto done;
540 : }
541 19 : if (q.query_secdesc.out.sd->dacl == NULL) {
542 0 : ret = false;
543 0 : torture_result(tctx, TORTURE_FAIL, "no DACL has been created on the server!\n");
544 0 : goto done;
545 : }
546 :
547 19 : torture_comment(tctx, "set NULL DACL\n");
548 19 : sd->type |= SEC_DESC_DACL_PRESENT;
549 :
550 19 : s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
551 19 : s.set_secdesc.in.file.fnum = fnum;
552 19 : s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
553 19 : s.set_secdesc.in.sd = sd;
554 19 : status = smb_raw_setfileinfo(cli->tree, &s);
555 19 : CHECK_STATUS(status, NT_STATUS_OK);
556 :
557 19 : torture_comment(tctx, "get the sd\n");
558 19 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
559 19 : q.query_secdesc.in.file.fnum = fnum;
560 19 : q.query_secdesc.in.secinfo_flags =
561 : SECINFO_OWNER |
562 : SECINFO_GROUP |
563 : SECINFO_DACL;
564 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
565 19 : CHECK_STATUS(status, NT_STATUS_OK);
566 :
567 : /* Testing the modified DACL */
568 19 : if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
569 0 : ret = false;
570 0 : torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
571 0 : goto done;
572 : }
573 19 : if (q.query_secdesc.out.sd->dacl != NULL) {
574 14 : ret = false;
575 14 : torture_result(tctx, TORTURE_FAIL, "DACL has been created on the server!\n");
576 14 : goto done;
577 : }
578 :
579 5 : torture_comment(tctx, "try open for read control\n");
580 5 : io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL;
581 5 : status = smb_raw_open(cli->tree, tctx, &io);
582 5 : CHECK_STATUS(status, NT_STATUS_OK);
583 5 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
584 : SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE);
585 5 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
586 :
587 5 : torture_comment(tctx, "try open for write\n");
588 5 : io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
589 5 : status = smb_raw_open(cli->tree, tctx, &io);
590 5 : CHECK_STATUS(status, NT_STATUS_OK);
591 5 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
592 : SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
593 5 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
594 :
595 5 : torture_comment(tctx, "try open for read\n");
596 5 : io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
597 5 : status = smb_raw_open(cli->tree, tctx, &io);
598 5 : CHECK_STATUS(status, NT_STATUS_OK);
599 5 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
600 : SEC_FILE_READ_DATA | SEC_FILE_READ_ATTRIBUTE);
601 5 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
602 :
603 5 : torture_comment(tctx, "try open for generic write\n");
604 5 : io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
605 5 : status = smb_raw_open(cli->tree, tctx, &io);
606 5 : CHECK_STATUS(status, NT_STATUS_OK);
607 5 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
608 : SEC_RIGHTS_FILE_WRITE | SEC_FILE_READ_ATTRIBUTE);
609 5 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
610 :
611 5 : torture_comment(tctx, "try open for generic read\n");
612 5 : io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
613 5 : status = smb_raw_open(cli->tree, tctx, &io);
614 5 : CHECK_STATUS(status, NT_STATUS_OK);
615 5 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
616 : SEC_RIGHTS_FILE_READ | SEC_FILE_READ_ATTRIBUTE);
617 5 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
618 :
619 5 : torture_comment(tctx, "set DACL with 0 aces\n");
620 5 : ZERO_STRUCT(dacl);
621 5 : dacl.revision = SECURITY_ACL_REVISION_NT4;
622 5 : dacl.num_aces = 0;
623 5 : sd->dacl = &dacl;
624 :
625 5 : s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
626 5 : s.set_secdesc.in.file.fnum = fnum;
627 5 : s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
628 5 : s.set_secdesc.in.sd = sd;
629 5 : status = smb_raw_setfileinfo(cli->tree, &s);
630 5 : CHECK_STATUS(status, NT_STATUS_OK);
631 :
632 5 : torture_comment(tctx, "get the sd\n");
633 5 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
634 5 : q.query_secdesc.in.file.fnum = fnum;
635 5 : q.query_secdesc.in.secinfo_flags =
636 : SECINFO_OWNER |
637 : SECINFO_GROUP |
638 : SECINFO_DACL;
639 5 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
640 5 : CHECK_STATUS(status, NT_STATUS_OK);
641 :
642 : /* Testing the modified DACL */
643 5 : if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
644 0 : ret = false;
645 0 : torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
646 0 : goto done;
647 : }
648 5 : if (q.query_secdesc.out.sd->dacl == NULL) {
649 0 : ret = false;
650 0 : torture_result(tctx, TORTURE_FAIL, "no DACL has been created on the server!\n");
651 0 : goto done;
652 : }
653 5 : if (q.query_secdesc.out.sd->dacl->num_aces != 0) {
654 0 : ret = false;
655 0 : torture_result(tctx, TORTURE_FAIL, "DACL has %u aces!\n",
656 0 : q.query_secdesc.out.sd->dacl->num_aces);
657 0 : goto done;
658 : }
659 :
660 5 : torture_comment(tctx, "try open for read control\n");
661 5 : io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL;
662 5 : status = smb_raw_open(cli->tree, tctx, &io);
663 5 : CHECK_STATUS(status, NT_STATUS_OK);
664 5 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
665 : SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE);
666 5 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
667 :
668 5 : torture_comment(tctx, "try open for write => access_denied\n");
669 5 : io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
670 5 : status = smb_raw_open(cli->tree, tctx, &io);
671 5 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
672 :
673 5 : torture_comment(tctx, "try open for read => access_denied\n");
674 5 : io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
675 5 : status = smb_raw_open(cli->tree, tctx, &io);
676 5 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
677 :
678 5 : torture_comment(tctx, "try open for generic write => access_denied\n");
679 5 : io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
680 5 : status = smb_raw_open(cli->tree, tctx, &io);
681 5 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
682 :
683 5 : torture_comment(tctx, "try open for generic read => access_denied\n");
684 5 : io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
685 5 : status = smb_raw_open(cli->tree, tctx, &io);
686 5 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
687 :
688 5 : torture_comment(tctx, "set empty sd\n");
689 5 : sd->type &= ~SEC_DESC_DACL_PRESENT;
690 5 : sd->dacl = NULL;
691 :
692 5 : s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
693 5 : s.set_secdesc.in.file.fnum = fnum;
694 5 : s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
695 5 : s.set_secdesc.in.sd = sd;
696 5 : status = smb_raw_setfileinfo(cli->tree, &s);
697 5 : CHECK_STATUS(status, NT_STATUS_OK);
698 :
699 5 : torture_comment(tctx, "get the sd\n");
700 5 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
701 5 : q.query_secdesc.in.file.fnum = fnum;
702 5 : q.query_secdesc.in.secinfo_flags =
703 : SECINFO_OWNER |
704 : SECINFO_GROUP |
705 : SECINFO_DACL;
706 5 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
707 5 : CHECK_STATUS(status, NT_STATUS_OK);
708 :
709 : /* Testing the modified DACL */
710 5 : if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
711 0 : ret = false;
712 0 : torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
713 0 : goto done;
714 : }
715 5 : if (q.query_secdesc.out.sd->dacl != NULL) {
716 0 : ret = false;
717 0 : torture_result(tctx, TORTURE_FAIL, "DACL has been created on the server!\n");
718 0 : goto done;
719 : }
720 5 : done:
721 19 : smbcli_close(cli->tree, fnum);
722 19 : smb_raw_exit(cli->session);
723 19 : smbcli_deltree(cli->tree, BASEDIR);
724 19 : return ret;
725 : }
726 :
727 : /*
728 : test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
729 : mapping bits
730 : Test copied to smb2/acls.c for SMB2.
731 : */
732 19 : static bool test_creator_sid(struct torture_context *tctx,
733 : struct smbcli_state *cli)
734 : {
735 0 : NTSTATUS status;
736 0 : union smb_open io;
737 19 : const char *fname = BASEDIR "\\creator.txt";
738 19 : bool ret = true;
739 19 : int fnum = -1;
740 0 : union smb_fileinfo q;
741 0 : union smb_setfileinfo set;
742 0 : struct security_descriptor *sd, *sd_orig, *sd2;
743 0 : const char *owner_sid;
744 :
745 19 : if (!torture_setup_dir(cli, BASEDIR))
746 0 : return false;
747 :
748 19 : torture_comment(tctx, "TESTING SID_CREATOR_OWNER\n");
749 :
750 19 : io.generic.level = RAW_OPEN_NTCREATEX;
751 19 : io.ntcreatex.in.root_fid.fnum = 0;
752 19 : io.ntcreatex.in.flags = 0;
753 19 : io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
754 19 : io.ntcreatex.in.create_options = 0;
755 19 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
756 19 : io.ntcreatex.in.share_access =
757 : NTCREATEX_SHARE_ACCESS_READ |
758 : NTCREATEX_SHARE_ACCESS_WRITE;
759 19 : io.ntcreatex.in.alloc_size = 0;
760 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
761 19 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
762 19 : io.ntcreatex.in.security_flags = 0;
763 19 : io.ntcreatex.in.fname = fname;
764 19 : status = smb_raw_open(cli->tree, tctx, &io);
765 19 : CHECK_STATUS(status, NT_STATUS_OK);
766 19 : fnum = io.ntcreatex.out.file.fnum;
767 :
768 19 : torture_comment(tctx, "get the original sd\n");
769 19 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
770 19 : q.query_secdesc.in.file.fnum = fnum;
771 19 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
772 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
773 19 : CHECK_STATUS(status, NT_STATUS_OK);
774 19 : sd_orig = q.query_secdesc.out.sd;
775 :
776 19 : owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
777 :
778 19 : torture_comment(tctx, "set a sec desc allowing no write by CREATOR_OWNER\n");
779 19 : sd = security_descriptor_dacl_create(tctx,
780 : 0, NULL, NULL,
781 : SID_CREATOR_OWNER,
782 : SEC_ACE_TYPE_ACCESS_ALLOWED,
783 : SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
784 : 0,
785 : NULL);
786 :
787 19 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
788 19 : set.set_secdesc.in.file.fnum = fnum;
789 19 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
790 19 : set.set_secdesc.in.sd = sd;
791 :
792 19 : status = smb_raw_setfileinfo(cli->tree, &set);
793 19 : CHECK_STATUS(status, NT_STATUS_OK);
794 :
795 19 : torture_comment(tctx, "try open for write\n");
796 19 : io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
797 19 : status = smb_raw_open(cli->tree, tctx, &io);
798 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
799 :
800 19 : torture_comment(tctx, "try open for read\n");
801 19 : io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
802 19 : status = smb_raw_open(cli->tree, tctx, &io);
803 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
804 :
805 19 : torture_comment(tctx, "try open for generic write\n");
806 19 : io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
807 19 : status = smb_raw_open(cli->tree, tctx, &io);
808 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
809 :
810 19 : torture_comment(tctx, "try open for generic read\n");
811 19 : io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
812 19 : status = smb_raw_open(cli->tree, tctx, &io);
813 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
814 :
815 19 : torture_comment(tctx, "set a sec desc allowing no write by owner\n");
816 19 : sd = security_descriptor_dacl_create(tctx,
817 : 0, owner_sid, NULL,
818 : owner_sid,
819 : SEC_ACE_TYPE_ACCESS_ALLOWED,
820 : SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
821 : 0,
822 : NULL);
823 :
824 19 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
825 19 : set.set_secdesc.in.file.fnum = fnum;
826 19 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
827 19 : set.set_secdesc.in.sd = sd;
828 19 : status = smb_raw_setfileinfo(cli->tree, &set);
829 19 : CHECK_STATUS(status, NT_STATUS_OK);
830 :
831 19 : torture_comment(tctx, "check that sd has been mapped correctly\n");
832 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
833 19 : CHECK_STATUS(status, NT_STATUS_OK);
834 19 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
835 :
836 19 : torture_comment(tctx, "try open for write\n");
837 19 : io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
838 19 : status = smb_raw_open(cli->tree, tctx, &io);
839 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
840 :
841 19 : torture_comment(tctx, "try open for read\n");
842 19 : io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
843 19 : status = smb_raw_open(cli->tree, tctx, &io);
844 19 : CHECK_STATUS(status, NT_STATUS_OK);
845 19 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
846 : SEC_FILE_READ_DATA|
847 : SEC_FILE_READ_ATTRIBUTE);
848 19 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
849 :
850 19 : torture_comment(tctx, "try open for generic write\n");
851 19 : io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
852 19 : status = smb_raw_open(cli->tree, tctx, &io);
853 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
854 :
855 19 : torture_comment(tctx, "try open for generic read\n");
856 19 : io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
857 19 : status = smb_raw_open(cli->tree, tctx, &io);
858 19 : CHECK_STATUS(status, NT_STATUS_OK);
859 19 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
860 : SEC_RIGHTS_FILE_READ);
861 19 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
862 :
863 19 : torture_comment(tctx, "set a sec desc allowing generic read by owner\n");
864 19 : sd = security_descriptor_dacl_create(tctx,
865 : 0, NULL, NULL,
866 : owner_sid,
867 : SEC_ACE_TYPE_ACCESS_ALLOWED,
868 : SEC_GENERIC_READ | SEC_STD_ALL,
869 : 0,
870 : NULL);
871 :
872 19 : set.set_secdesc.in.sd = sd;
873 19 : status = smb_raw_setfileinfo(cli->tree, &set);
874 19 : CHECK_STATUS(status, NT_STATUS_OK);
875 :
876 19 : torture_comment(tctx, "check that generic read has been mapped correctly\n");
877 19 : sd2 = security_descriptor_dacl_create(tctx,
878 : 0, owner_sid, NULL,
879 : owner_sid,
880 : SEC_ACE_TYPE_ACCESS_ALLOWED,
881 : SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
882 : 0,
883 : NULL);
884 :
885 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
886 19 : CHECK_STATUS(status, NT_STATUS_OK);
887 19 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
888 :
889 19 : torture_comment(tctx, "try open for write\n");
890 19 : io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
891 19 : status = smb_raw_open(cli->tree, tctx, &io);
892 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
893 :
894 19 : torture_comment(tctx, "try open for read\n");
895 19 : io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
896 19 : status = smb_raw_open(cli->tree, tctx, &io);
897 19 : CHECK_STATUS(status, NT_STATUS_OK);
898 19 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
899 : SEC_FILE_READ_DATA |
900 : SEC_FILE_READ_ATTRIBUTE);
901 19 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
902 :
903 19 : torture_comment(tctx, "try open for generic write\n");
904 19 : io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
905 19 : status = smb_raw_open(cli->tree, tctx, &io);
906 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
907 :
908 19 : torture_comment(tctx, "try open for generic read\n");
909 19 : io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
910 19 : status = smb_raw_open(cli->tree, tctx, &io);
911 19 : CHECK_STATUS(status, NT_STATUS_OK);
912 19 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, SEC_RIGHTS_FILE_READ);
913 19 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
914 :
915 :
916 19 : torture_comment(tctx, "put back original sd\n");
917 19 : set.set_secdesc.in.sd = sd_orig;
918 19 : status = smb_raw_setfileinfo(cli->tree, &set);
919 19 : CHECK_STATUS(status, NT_STATUS_OK);
920 :
921 :
922 19 : done:
923 19 : smbcli_close(cli->tree, fnum);
924 19 : smb_raw_exit(cli->session);
925 19 : smbcli_deltree(cli->tree, BASEDIR);
926 19 : return ret;
927 : }
928 :
929 :
930 : /*
931 : test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
932 : SEC_FILE_xx bits
933 : Test copied to smb2/acls.c for SMB2.
934 : */
935 19 : static bool test_generic_bits(struct torture_context *tctx,
936 : struct smbcli_state *cli)
937 : {
938 0 : NTSTATUS status;
939 0 : union smb_open io;
940 19 : const char *fname = BASEDIR "\\generic.txt";
941 19 : bool ret = true;
942 19 : int fnum = -1, i;
943 0 : union smb_fileinfo q;
944 0 : union smb_setfileinfo set;
945 0 : struct security_descriptor *sd, *sd_orig, *sd2;
946 0 : const char *owner_sid;
947 0 : const struct {
948 : uint32_t gen_bits;
949 : uint32_t specific_bits;
950 19 : } file_mappings[] = {
951 : { 0, 0 },
952 : { SEC_GENERIC_READ, SEC_RIGHTS_FILE_READ },
953 : { SEC_GENERIC_WRITE, SEC_RIGHTS_FILE_WRITE },
954 : { SEC_GENERIC_EXECUTE, SEC_RIGHTS_FILE_EXECUTE },
955 : { SEC_GENERIC_ALL, SEC_RIGHTS_FILE_ALL },
956 : { SEC_FILE_READ_DATA, SEC_FILE_READ_DATA },
957 : { SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_ATTRIBUTE }
958 : };
959 0 : const struct {
960 : uint32_t gen_bits;
961 : uint32_t specific_bits;
962 19 : } dir_mappings[] = {
963 : { 0, 0 },
964 : { SEC_GENERIC_READ, SEC_RIGHTS_DIR_READ },
965 : { SEC_GENERIC_WRITE, SEC_RIGHTS_DIR_WRITE },
966 : { SEC_GENERIC_EXECUTE, SEC_RIGHTS_DIR_EXECUTE },
967 : { SEC_GENERIC_ALL, SEC_RIGHTS_DIR_ALL }
968 : };
969 0 : bool has_restore_privilege;
970 0 : bool has_take_ownership_privilege;
971 :
972 19 : if (!torture_setup_dir(cli, BASEDIR))
973 0 : return false;
974 :
975 19 : torture_comment(tctx, "TESTING FILE GENERIC BITS\n");
976 :
977 19 : io.generic.level = RAW_OPEN_NTCREATEX;
978 19 : io.ntcreatex.in.root_fid.fnum = 0;
979 19 : io.ntcreatex.in.flags = 0;
980 19 : io.ntcreatex.in.access_mask =
981 : SEC_STD_READ_CONTROL |
982 : SEC_STD_WRITE_DAC |
983 : SEC_STD_WRITE_OWNER;
984 19 : io.ntcreatex.in.create_options = 0;
985 19 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
986 19 : io.ntcreatex.in.share_access =
987 : NTCREATEX_SHARE_ACCESS_READ |
988 : NTCREATEX_SHARE_ACCESS_WRITE;
989 19 : io.ntcreatex.in.alloc_size = 0;
990 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
991 19 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
992 19 : io.ntcreatex.in.security_flags = 0;
993 19 : io.ntcreatex.in.fname = fname;
994 19 : status = smb_raw_open(cli->tree, tctx, &io);
995 19 : CHECK_STATUS(status, NT_STATUS_OK);
996 19 : fnum = io.ntcreatex.out.file.fnum;
997 :
998 19 : torture_comment(tctx, "get the original sd\n");
999 19 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1000 19 : q.query_secdesc.in.file.fnum = fnum;
1001 19 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1002 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1003 19 : CHECK_STATUS(status, NT_STATUS_OK);
1004 19 : sd_orig = q.query_secdesc.out.sd;
1005 :
1006 19 : owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1007 :
1008 19 : status = torture_check_privilege(cli,
1009 : owner_sid,
1010 : sec_privilege_name(SEC_PRIV_RESTORE));
1011 19 : has_restore_privilege = NT_STATUS_IS_OK(status);
1012 19 : if (!NT_STATUS_IS_OK(status)) {
1013 16 : torture_warning(tctx, "torture_check_privilege - %s\n",
1014 : nt_errstr(status));
1015 : }
1016 19 : torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
1017 :
1018 19 : status = torture_check_privilege(cli,
1019 : owner_sid,
1020 : sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
1021 19 : has_take_ownership_privilege = NT_STATUS_IS_OK(status);
1022 19 : if (!NT_STATUS_IS_OK(status)) {
1023 16 : torture_warning(tctx, "torture_check_privilege - %s\n",
1024 : nt_errstr(status));
1025 : }
1026 19 : torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
1027 :
1028 152 : for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
1029 133 : uint32_t expected_mask =
1030 : SEC_STD_WRITE_DAC |
1031 : SEC_STD_READ_CONTROL |
1032 : SEC_FILE_READ_ATTRIBUTE |
1033 : SEC_STD_DELETE;
1034 133 : uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
1035 :
1036 133 : if (has_restore_privilege) {
1037 21 : expected_mask_anon |= SEC_STD_DELETE;
1038 : }
1039 :
1040 133 : torture_comment(tctx, "Testing generic bits 0x%08x\n",
1041 133 : file_mappings[i].gen_bits);
1042 133 : sd = security_descriptor_dacl_create(tctx,
1043 : 0, owner_sid, NULL,
1044 : owner_sid,
1045 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1046 133 : file_mappings[i].gen_bits,
1047 : 0,
1048 : NULL);
1049 :
1050 133 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1051 133 : set.set_secdesc.in.file.fnum = fnum;
1052 133 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1053 133 : set.set_secdesc.in.sd = sd;
1054 :
1055 133 : status = smb_raw_setfileinfo(cli->tree, &set);
1056 133 : CHECK_STATUS(status, NT_STATUS_OK);
1057 :
1058 133 : sd2 = security_descriptor_dacl_create(tctx,
1059 : 0, owner_sid, NULL,
1060 : owner_sid,
1061 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1062 133 : file_mappings[i].specific_bits,
1063 : 0,
1064 : NULL);
1065 :
1066 133 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1067 133 : CHECK_STATUS(status, NT_STATUS_OK);
1068 133 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1069 :
1070 133 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1071 133 : status = smb_raw_open(cli->tree, tctx, &io);
1072 133 : CHECK_STATUS(status, NT_STATUS_OK);
1073 133 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
1074 : expected_mask | file_mappings[i].specific_bits);
1075 133 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1076 :
1077 133 : if (!has_take_ownership_privilege) {
1078 112 : continue;
1079 : }
1080 :
1081 21 : torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
1082 21 : file_mappings[i].gen_bits);
1083 21 : sd = security_descriptor_dacl_create(tctx,
1084 : 0, SID_NT_ANONYMOUS, NULL,
1085 : owner_sid,
1086 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1087 21 : file_mappings[i].gen_bits,
1088 : 0,
1089 : NULL);
1090 :
1091 21 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1092 21 : set.set_secdesc.in.file.fnum = fnum;
1093 21 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1094 21 : set.set_secdesc.in.sd = sd;
1095 :
1096 21 : status = smb_raw_setfileinfo(cli->tree, &set);
1097 21 : CHECK_STATUS(status, NT_STATUS_OK);
1098 :
1099 21 : sd2 = security_descriptor_dacl_create(tctx,
1100 : 0, SID_NT_ANONYMOUS, NULL,
1101 : owner_sid,
1102 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1103 21 : file_mappings[i].specific_bits,
1104 : 0,
1105 : NULL);
1106 :
1107 21 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1108 21 : CHECK_STATUS(status, NT_STATUS_OK);
1109 21 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1110 :
1111 21 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1112 21 : status = smb_raw_open(cli->tree, tctx, &io);
1113 21 : CHECK_STATUS(status, NT_STATUS_OK);
1114 21 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
1115 : expected_mask_anon | file_mappings[i].specific_bits);
1116 21 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1117 : }
1118 :
1119 19 : torture_comment(tctx, "put back original sd\n");
1120 19 : set.set_secdesc.in.sd = sd_orig;
1121 19 : status = smb_raw_setfileinfo(cli->tree, &set);
1122 19 : CHECK_STATUS(status, NT_STATUS_OK);
1123 :
1124 19 : smbcli_close(cli->tree, fnum);
1125 19 : smbcli_unlink(cli->tree, fname);
1126 :
1127 :
1128 19 : torture_comment(tctx, "TESTING DIR GENERIC BITS\n");
1129 :
1130 19 : io.generic.level = RAW_OPEN_NTCREATEX;
1131 19 : io.ntcreatex.in.root_fid.fnum = 0;
1132 19 : io.ntcreatex.in.flags = 0;
1133 19 : io.ntcreatex.in.access_mask =
1134 : SEC_STD_READ_CONTROL |
1135 : SEC_STD_WRITE_DAC |
1136 : SEC_STD_WRITE_OWNER;
1137 19 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1138 19 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1139 19 : io.ntcreatex.in.share_access =
1140 : NTCREATEX_SHARE_ACCESS_READ |
1141 : NTCREATEX_SHARE_ACCESS_WRITE;
1142 19 : io.ntcreatex.in.alloc_size = 0;
1143 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1144 19 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1145 19 : io.ntcreatex.in.security_flags = 0;
1146 19 : io.ntcreatex.in.fname = fname;
1147 19 : status = smb_raw_open(cli->tree, tctx, &io);
1148 19 : CHECK_STATUS(status, NT_STATUS_OK);
1149 19 : fnum = io.ntcreatex.out.file.fnum;
1150 :
1151 19 : torture_comment(tctx, "get the original sd\n");
1152 19 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1153 19 : q.query_secdesc.in.file.fnum = fnum;
1154 19 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1155 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1156 19 : CHECK_STATUS(status, NT_STATUS_OK);
1157 19 : sd_orig = q.query_secdesc.out.sd;
1158 :
1159 19 : owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1160 :
1161 19 : status = torture_check_privilege(cli,
1162 : owner_sid,
1163 : sec_privilege_name(SEC_PRIV_RESTORE));
1164 19 : has_restore_privilege = NT_STATUS_IS_OK(status);
1165 19 : if (!NT_STATUS_IS_OK(status)) {
1166 16 : torture_warning(tctx, "torture_check_privilege - %s\n",
1167 : nt_errstr(status));
1168 : }
1169 19 : torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
1170 :
1171 19 : status = torture_check_privilege(cli,
1172 : owner_sid,
1173 : sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
1174 19 : has_take_ownership_privilege = NT_STATUS_IS_OK(status);
1175 19 : if (!NT_STATUS_IS_OK(status)) {
1176 16 : torture_warning(tctx, "torture_check_privilege - %s\n",
1177 : nt_errstr(status));
1178 : }
1179 19 : torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
1180 :
1181 114 : for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
1182 95 : uint32_t expected_mask =
1183 : SEC_STD_WRITE_DAC |
1184 : SEC_STD_READ_CONTROL |
1185 : SEC_FILE_READ_ATTRIBUTE |
1186 : SEC_STD_DELETE;
1187 95 : uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
1188 :
1189 95 : if (has_restore_privilege) {
1190 15 : expected_mask_anon |= SEC_STD_DELETE;
1191 : }
1192 :
1193 95 : torture_comment(tctx, "Testing generic bits 0x%08x\n",
1194 95 : file_mappings[i].gen_bits);
1195 95 : sd = security_descriptor_dacl_create(tctx,
1196 : 0, owner_sid, NULL,
1197 : owner_sid,
1198 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1199 95 : dir_mappings[i].gen_bits,
1200 : 0,
1201 : NULL);
1202 :
1203 95 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1204 95 : set.set_secdesc.in.file.fnum = fnum;
1205 95 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1206 95 : set.set_secdesc.in.sd = sd;
1207 :
1208 95 : status = smb_raw_setfileinfo(cli->tree, &set);
1209 95 : CHECK_STATUS(status, NT_STATUS_OK);
1210 :
1211 95 : sd2 = security_descriptor_dacl_create(tctx,
1212 : 0, owner_sid, NULL,
1213 : owner_sid,
1214 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1215 95 : dir_mappings[i].specific_bits,
1216 : 0,
1217 : NULL);
1218 :
1219 95 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1220 95 : CHECK_STATUS(status, NT_STATUS_OK);
1221 95 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1222 :
1223 95 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1224 95 : status = smb_raw_open(cli->tree, tctx, &io);
1225 95 : CHECK_STATUS(status, NT_STATUS_OK);
1226 95 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
1227 : expected_mask | dir_mappings[i].specific_bits);
1228 95 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1229 :
1230 95 : if (!has_take_ownership_privilege) {
1231 80 : continue;
1232 : }
1233 :
1234 15 : torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
1235 15 : file_mappings[i].gen_bits);
1236 15 : sd = security_descriptor_dacl_create(tctx,
1237 : 0, SID_NT_ANONYMOUS, NULL,
1238 : owner_sid,
1239 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1240 15 : file_mappings[i].gen_bits,
1241 : 0,
1242 : NULL);
1243 :
1244 15 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1245 15 : set.set_secdesc.in.file.fnum = fnum;
1246 15 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1247 15 : set.set_secdesc.in.sd = sd;
1248 :
1249 15 : status = smb_raw_setfileinfo(cli->tree, &set);
1250 15 : CHECK_STATUS(status, NT_STATUS_OK);
1251 :
1252 15 : sd2 = security_descriptor_dacl_create(tctx,
1253 : 0, SID_NT_ANONYMOUS, NULL,
1254 : owner_sid,
1255 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1256 15 : file_mappings[i].specific_bits,
1257 : 0,
1258 : NULL);
1259 :
1260 15 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1261 15 : CHECK_STATUS(status, NT_STATUS_OK);
1262 15 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1263 :
1264 15 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1265 15 : status = smb_raw_open(cli->tree, tctx, &io);
1266 15 : CHECK_STATUS(status, NT_STATUS_OK);
1267 15 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
1268 : expected_mask_anon | dir_mappings[i].specific_bits);
1269 15 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1270 : }
1271 :
1272 19 : torture_comment(tctx, "put back original sd\n");
1273 19 : set.set_secdesc.in.sd = sd_orig;
1274 19 : status = smb_raw_setfileinfo(cli->tree, &set);
1275 19 : CHECK_STATUS(status, NT_STATUS_OK);
1276 :
1277 19 : smbcli_close(cli->tree, fnum);
1278 19 : smbcli_unlink(cli->tree, fname);
1279 :
1280 19 : done:
1281 19 : smbcli_close(cli->tree, fnum);
1282 19 : smb_raw_exit(cli->session);
1283 19 : smbcli_deltree(cli->tree, BASEDIR);
1284 19 : return ret;
1285 : }
1286 :
1287 :
1288 : /*
1289 : see what access bits the owner of a file always gets
1290 : Test copied to smb2/acls.c for SMB2.
1291 : */
1292 19 : static bool test_owner_bits(struct torture_context *tctx,
1293 : struct smbcli_state *cli)
1294 : {
1295 0 : NTSTATUS status;
1296 0 : union smb_open io;
1297 19 : const char *fname = BASEDIR "\\test_owner_bits.txt";
1298 19 : bool ret = true;
1299 19 : int fnum = -1, i;
1300 0 : union smb_fileinfo q;
1301 0 : union smb_setfileinfo set;
1302 0 : struct security_descriptor *sd, *sd_orig;
1303 0 : const char *owner_sid;
1304 0 : bool has_restore_privilege;
1305 0 : bool has_take_ownership_privilege;
1306 0 : uint32_t expected_bits;
1307 :
1308 19 : if (!torture_setup_dir(cli, BASEDIR))
1309 0 : return false;
1310 :
1311 19 : torture_comment(tctx, "TESTING FILE OWNER BITS\n");
1312 :
1313 19 : io.generic.level = RAW_OPEN_NTCREATEX;
1314 19 : io.ntcreatex.in.root_fid.fnum = 0;
1315 19 : io.ntcreatex.in.flags = 0;
1316 19 : io.ntcreatex.in.access_mask =
1317 : SEC_STD_READ_CONTROL |
1318 : SEC_STD_WRITE_DAC |
1319 : SEC_STD_WRITE_OWNER;
1320 19 : io.ntcreatex.in.create_options = 0;
1321 19 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1322 19 : io.ntcreatex.in.share_access =
1323 : NTCREATEX_SHARE_ACCESS_READ |
1324 : NTCREATEX_SHARE_ACCESS_WRITE;
1325 19 : io.ntcreatex.in.alloc_size = 0;
1326 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1327 19 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1328 19 : io.ntcreatex.in.security_flags = 0;
1329 19 : io.ntcreatex.in.fname = fname;
1330 19 : status = smb_raw_open(cli->tree, tctx, &io);
1331 19 : CHECK_STATUS(status, NT_STATUS_OK);
1332 19 : fnum = io.ntcreatex.out.file.fnum;
1333 :
1334 19 : torture_comment(tctx, "get the original sd\n");
1335 19 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1336 19 : q.query_secdesc.in.file.fnum = fnum;
1337 19 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1338 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1339 19 : CHECK_STATUS(status, NT_STATUS_OK);
1340 19 : sd_orig = q.query_secdesc.out.sd;
1341 :
1342 19 : owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1343 :
1344 19 : status = torture_check_privilege(cli,
1345 : owner_sid,
1346 : sec_privilege_name(SEC_PRIV_RESTORE));
1347 19 : has_restore_privilege = NT_STATUS_IS_OK(status);
1348 19 : if (!NT_STATUS_IS_OK(status)) {
1349 16 : torture_warning(tctx, "torture_check_privilege - %s\n", nt_errstr(status));
1350 : }
1351 19 : torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
1352 :
1353 19 : status = torture_check_privilege(cli,
1354 : owner_sid,
1355 : sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
1356 19 : has_take_ownership_privilege = NT_STATUS_IS_OK(status);
1357 19 : if (!NT_STATUS_IS_OK(status)) {
1358 16 : torture_warning(tctx, "torture_check_privilege - %s\n", nt_errstr(status));
1359 : }
1360 19 : torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
1361 :
1362 19 : sd = security_descriptor_dacl_create(tctx,
1363 : 0, NULL, NULL,
1364 : owner_sid,
1365 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1366 : SEC_FILE_WRITE_DATA,
1367 : 0,
1368 : NULL);
1369 :
1370 19 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1371 19 : set.set_secdesc.in.file.fnum = fnum;
1372 19 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1373 19 : set.set_secdesc.in.sd = sd;
1374 :
1375 19 : status = smb_raw_setfileinfo(cli->tree, &set);
1376 19 : CHECK_STATUS(status, NT_STATUS_OK);
1377 :
1378 19 : expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
1379 :
1380 323 : for (i=0;i<16;i++) {
1381 304 : uint32_t bit = (1<<i);
1382 304 : io.ntcreatex.in.access_mask = bit;
1383 304 : status = smb_raw_open(cli->tree, tctx, &io);
1384 304 : if (expected_bits & bit) {
1385 38 : if (!NT_STATUS_IS_OK(status)) {
1386 0 : torture_warning(tctx, "failed with access mask 0x%08x of expected 0x%08x\n",
1387 : bit, expected_bits);
1388 : }
1389 38 : CHECK_STATUS(status, NT_STATUS_OK);
1390 38 : CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, bit | SEC_FILE_READ_ATTRIBUTE);
1391 38 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1392 : } else {
1393 266 : if (NT_STATUS_IS_OK(status)) {
1394 0 : torture_warning(tctx, "open succeeded with access mask 0x%08x of "
1395 : "expected 0x%08x - should fail\n",
1396 : bit, expected_bits);
1397 : }
1398 266 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1399 : }
1400 : }
1401 :
1402 19 : torture_comment(tctx, "put back original sd\n");
1403 19 : set.set_secdesc.in.sd = sd_orig;
1404 19 : status = smb_raw_setfileinfo(cli->tree, &set);
1405 19 : CHECK_STATUS(status, NT_STATUS_OK);
1406 :
1407 19 : done:
1408 19 : smbcli_close(cli->tree, fnum);
1409 19 : smbcli_unlink(cli->tree, fname);
1410 19 : smb_raw_exit(cli->session);
1411 19 : smbcli_deltree(cli->tree, BASEDIR);
1412 19 : return ret;
1413 : }
1414 :
1415 :
1416 :
1417 : /*
1418 : test the inheritance of ACL flags onto new files and directories
1419 : Test copied to smb2/acls.c for SMB2.
1420 : */
1421 19 : static bool test_inheritance(struct torture_context *tctx,
1422 : struct smbcli_state *cli)
1423 : {
1424 0 : NTSTATUS status;
1425 0 : union smb_open io;
1426 19 : const char *dname = BASEDIR "\\inheritance";
1427 19 : const char *fname1 = BASEDIR "\\inheritance\\testfile";
1428 19 : const char *fname2 = BASEDIR "\\inheritance\\testdir";
1429 19 : bool ret = true;
1430 19 : int fnum=0, fnum2, i;
1431 0 : union smb_fileinfo q;
1432 0 : union smb_setfileinfo set;
1433 19 : struct security_descriptor *sd, *sd2, *sd_orig=NULL, *sd_def1, *sd_def2;
1434 0 : const char *owner_sid, *group_sid;
1435 0 : const struct dom_sid *creator_owner;
1436 0 : const struct {
1437 : uint32_t parent_flags;
1438 : uint32_t file_flags;
1439 : uint32_t dir_flags;
1440 19 : } test_flags[] = {
1441 : {
1442 : 0,
1443 : 0,
1444 : 0
1445 : },
1446 : {
1447 : SEC_ACE_FLAG_OBJECT_INHERIT,
1448 : 0,
1449 : SEC_ACE_FLAG_OBJECT_INHERIT |
1450 : SEC_ACE_FLAG_INHERIT_ONLY,
1451 : },
1452 : {
1453 : SEC_ACE_FLAG_CONTAINER_INHERIT,
1454 : 0,
1455 : SEC_ACE_FLAG_CONTAINER_INHERIT,
1456 : },
1457 : {
1458 : SEC_ACE_FLAG_OBJECT_INHERIT |
1459 : SEC_ACE_FLAG_CONTAINER_INHERIT,
1460 : 0,
1461 : SEC_ACE_FLAG_OBJECT_INHERIT |
1462 : SEC_ACE_FLAG_CONTAINER_INHERIT,
1463 : },
1464 : {
1465 : SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
1466 : 0,
1467 : 0,
1468 : },
1469 : {
1470 : SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1471 : SEC_ACE_FLAG_OBJECT_INHERIT,
1472 : 0,
1473 : 0,
1474 : },
1475 : {
1476 : SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1477 : SEC_ACE_FLAG_CONTAINER_INHERIT,
1478 : 0,
1479 : 0,
1480 : },
1481 : {
1482 : SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1483 : SEC_ACE_FLAG_CONTAINER_INHERIT |
1484 : SEC_ACE_FLAG_OBJECT_INHERIT,
1485 : 0,
1486 : 0,
1487 : },
1488 : {
1489 : SEC_ACE_FLAG_INHERIT_ONLY,
1490 : 0,
1491 : 0,
1492 : },
1493 : {
1494 : SEC_ACE_FLAG_INHERIT_ONLY |
1495 : SEC_ACE_FLAG_OBJECT_INHERIT,
1496 : 0,
1497 : SEC_ACE_FLAG_OBJECT_INHERIT |
1498 : SEC_ACE_FLAG_INHERIT_ONLY,
1499 : },
1500 : {
1501 : SEC_ACE_FLAG_INHERIT_ONLY |
1502 : SEC_ACE_FLAG_CONTAINER_INHERIT,
1503 : 0,
1504 : SEC_ACE_FLAG_CONTAINER_INHERIT,
1505 : },
1506 : {
1507 : SEC_ACE_FLAG_INHERIT_ONLY |
1508 : SEC_ACE_FLAG_CONTAINER_INHERIT |
1509 : SEC_ACE_FLAG_OBJECT_INHERIT,
1510 : 0,
1511 : SEC_ACE_FLAG_CONTAINER_INHERIT |
1512 : SEC_ACE_FLAG_OBJECT_INHERIT,
1513 : },
1514 : {
1515 : SEC_ACE_FLAG_INHERIT_ONLY |
1516 : SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
1517 : 0,
1518 : 0,
1519 : },
1520 : {
1521 : SEC_ACE_FLAG_INHERIT_ONLY |
1522 : SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1523 : SEC_ACE_FLAG_OBJECT_INHERIT,
1524 : 0,
1525 : 0,
1526 : },
1527 : {
1528 : SEC_ACE_FLAG_INHERIT_ONLY |
1529 : SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1530 : SEC_ACE_FLAG_CONTAINER_INHERIT,
1531 : 0,
1532 : 0,
1533 : },
1534 : {
1535 : SEC_ACE_FLAG_INHERIT_ONLY |
1536 : SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1537 : SEC_ACE_FLAG_CONTAINER_INHERIT |
1538 : SEC_ACE_FLAG_OBJECT_INHERIT,
1539 : 0,
1540 : 0,
1541 : }
1542 : };
1543 :
1544 19 : if (!torture_setup_dir(cli, BASEDIR))
1545 0 : return false;
1546 :
1547 19 : torture_comment(tctx, "TESTING ACL INHERITANCE\n");
1548 :
1549 19 : io.generic.level = RAW_OPEN_NTCREATEX;
1550 19 : io.ntcreatex.in.root_fid.fnum = 0;
1551 19 : io.ntcreatex.in.flags = 0;
1552 19 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1553 19 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1554 19 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1555 19 : io.ntcreatex.in.share_access = 0;
1556 19 : io.ntcreatex.in.alloc_size = 0;
1557 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1558 19 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1559 19 : io.ntcreatex.in.security_flags = 0;
1560 19 : io.ntcreatex.in.fname = dname;
1561 :
1562 19 : status = smb_raw_open(cli->tree, tctx, &io);
1563 19 : CHECK_STATUS(status, NT_STATUS_OK);
1564 19 : fnum = io.ntcreatex.out.file.fnum;
1565 :
1566 19 : torture_comment(tctx, "get the original sd\n");
1567 19 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1568 19 : q.query_secdesc.in.file.fnum = fnum;
1569 19 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
1570 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1571 19 : CHECK_STATUS(status, NT_STATUS_OK);
1572 19 : sd_orig = q.query_secdesc.out.sd;
1573 :
1574 19 : owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1575 19 : group_sid = dom_sid_string(tctx, sd_orig->group_sid);
1576 :
1577 19 : torture_comment(tctx, "owner_sid is %s\n", owner_sid);
1578 19 : torture_comment(tctx, "group_sid is %s\n", group_sid);
1579 :
1580 19 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1581 :
1582 19 : if (torture_setting_bool(tctx, "samba4", false)) {
1583 : /* the default ACL in Samba4 includes the group and
1584 : other permissions */
1585 1 : sd_def1 = security_descriptor_dacl_create(tctx,
1586 : 0, owner_sid, NULL,
1587 : owner_sid,
1588 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1589 : SEC_RIGHTS_FILE_ALL,
1590 : 0,
1591 : group_sid,
1592 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1593 : SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE,
1594 : 0,
1595 : SID_WORLD,
1596 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1597 : SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE,
1598 : 0,
1599 : SID_NT_SYSTEM,
1600 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1601 : SEC_RIGHTS_FILE_ALL,
1602 : 0,
1603 : NULL);
1604 : } else {
1605 : /*
1606 : * The Windows Default ACL for a new file, when there is no ACL to be
1607 : * inherited: FullControl for the owner and SYSTEM.
1608 : */
1609 18 : sd_def1 = security_descriptor_dacl_create(tctx,
1610 : 0, owner_sid, NULL,
1611 : owner_sid,
1612 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1613 : SEC_RIGHTS_FILE_ALL,
1614 : 0,
1615 : SID_NT_SYSTEM,
1616 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1617 : SEC_RIGHTS_FILE_ALL,
1618 : 0,
1619 : NULL);
1620 : }
1621 :
1622 : /*
1623 : * Use this in the case the system being tested does not add an ACE for
1624 : * the SYSTEM SID.
1625 : */
1626 19 : sd_def2 = security_descriptor_dacl_create(tctx,
1627 : 0, owner_sid, NULL,
1628 : owner_sid,
1629 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1630 : SEC_RIGHTS_FILE_ALL,
1631 : 0,
1632 : NULL);
1633 :
1634 19 : creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER);
1635 :
1636 323 : for (i=0;i<ARRAY_SIZE(test_flags);i++) {
1637 304 : sd = security_descriptor_dacl_create(tctx,
1638 : 0, NULL, NULL,
1639 : SID_CREATOR_OWNER,
1640 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1641 : SEC_FILE_WRITE_DATA,
1642 304 : test_flags[i].parent_flags,
1643 : SID_WORLD,
1644 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1645 : SEC_FILE_ALL | SEC_STD_ALL,
1646 : 0,
1647 : NULL);
1648 304 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1649 304 : set.set_secdesc.in.file.fnum = fnum;
1650 304 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1651 304 : set.set_secdesc.in.sd = sd;
1652 304 : status = smb_raw_setfileinfo(cli->tree, &set);
1653 304 : CHECK_STATUS(status, NT_STATUS_OK);
1654 :
1655 304 : io.ntcreatex.in.fname = fname1;
1656 304 : io.ntcreatex.in.create_options = 0;
1657 304 : status = smb_raw_open(cli->tree, tctx, &io);
1658 304 : CHECK_STATUS(status, NT_STATUS_OK);
1659 304 : fnum2 = io.ntcreatex.out.file.fnum;
1660 :
1661 304 : q.query_secdesc.in.file.fnum = fnum2;
1662 304 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1663 304 : CHECK_STATUS(status, NT_STATUS_OK);
1664 :
1665 304 : smbcli_close(cli->tree, fnum2);
1666 304 : smbcli_unlink(cli->tree, fname1);
1667 :
1668 304 : if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
1669 152 : if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
1670 144 : !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
1671 144 : torture_warning(tctx, "Expected default sd "
1672 : "for i=%d:\n", i);
1673 144 : NDR_PRINT_DEBUG(security_descriptor, sd_def1);
1674 144 : torture_warning(tctx, "at %d - got:\n", i);
1675 144 : NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1676 : }
1677 152 : goto check_dir;
1678 : }
1679 :
1680 152 : if (q.query_secdesc.out.sd->dacl == NULL ||
1681 152 : q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1682 152 : q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1683 152 : !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1684 152 : sd_orig->owner_sid)) {
1685 0 : ret = false;
1686 0 : torture_warning(tctx, "Bad sd in child file at %d\n", i);
1687 0 : NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1688 0 : goto check_dir;
1689 : }
1690 :
1691 152 : if (q.query_secdesc.out.sd->dacl->aces[0].flags !=
1692 152 : test_flags[i].file_flags) {
1693 0 : torture_warning(tctx, "incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
1694 0 : q.query_secdesc.out.sd->dacl->aces[0].flags,
1695 0 : test_flags[i].file_flags,
1696 0 : test_flags[i].parent_flags,
1697 : i);
1698 0 : ret = false;
1699 : }
1700 :
1701 152 : check_dir:
1702 304 : io.ntcreatex.in.fname = fname2;
1703 304 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1704 304 : status = smb_raw_open(cli->tree, tctx, &io);
1705 304 : CHECK_STATUS(status, NT_STATUS_OK);
1706 304 : fnum2 = io.ntcreatex.out.file.fnum;
1707 :
1708 304 : q.query_secdesc.in.file.fnum = fnum2;
1709 304 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1710 304 : CHECK_STATUS(status, NT_STATUS_OK);
1711 :
1712 304 : smbcli_close(cli->tree, fnum2);
1713 304 : smbcli_rmdir(cli->tree, fname2);
1714 :
1715 304 : if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1716 152 : (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
1717 76 : (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
1718 114 : if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
1719 108 : !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
1720 108 : torture_warning(tctx, "Expected default sd for dir at %d:\n", i);
1721 108 : NDR_PRINT_DEBUG(security_descriptor, sd_def1);
1722 108 : torture_warning(tctx, "got:\n");
1723 108 : NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1724 : }
1725 114 : continue;
1726 : }
1727 :
1728 190 : if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1729 152 : (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
1730 76 : if (q.query_secdesc.out.sd->dacl == NULL ||
1731 76 : q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1732 76 : q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1733 76 : !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1734 76 : sd_orig->owner_sid) ||
1735 76 : q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1736 0 : torture_warning(tctx, "(CI & NP) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1737 0 : test_flags[i].dir_flags,
1738 0 : test_flags[i].parent_flags, i);
1739 0 : NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1740 0 : torture_comment(tctx, "FYI, here is the parent sd:\n");
1741 0 : NDR_PRINT_DEBUG(security_descriptor, sd);
1742 0 : ret = false;
1743 0 : continue;
1744 : }
1745 114 : } else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
1746 76 : if (q.query_secdesc.out.sd->dacl == NULL ||
1747 76 : q.query_secdesc.out.sd->dacl->num_aces != 2 ||
1748 76 : q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1749 76 : !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1750 76 : sd_orig->owner_sid) ||
1751 76 : q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
1752 76 : !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
1753 76 : creator_owner) ||
1754 76 : q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
1755 76 : q.query_secdesc.out.sd->dacl->aces[1].flags !=
1756 76 : (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
1757 0 : torture_warning(tctx, "(CI) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1758 0 : test_flags[i].dir_flags,
1759 0 : test_flags[i].parent_flags, i);
1760 0 : NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1761 0 : torture_comment(tctx, "FYI, here is the parent sd:\n");
1762 0 : NDR_PRINT_DEBUG(security_descriptor, sd);
1763 0 : ret = false;
1764 0 : continue;
1765 : }
1766 : } else {
1767 38 : if (q.query_secdesc.out.sd->dacl == NULL ||
1768 38 : q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1769 38 : q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1770 38 : !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1771 38 : creator_owner) ||
1772 38 : q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1773 0 : torture_warning(tctx, "(0) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1774 0 : test_flags[i].dir_flags,
1775 0 : test_flags[i].parent_flags, i);
1776 0 : NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1777 0 : torture_comment(tctx, "FYI, here is the parent sd:\n");
1778 0 : NDR_PRINT_DEBUG(security_descriptor, sd);
1779 0 : ret = false;
1780 0 : continue;
1781 : }
1782 : }
1783 : }
1784 :
1785 19 : torture_comment(tctx, "Testing access checks on inherited create with %s\n", fname1);
1786 19 : sd = security_descriptor_dacl_create(tctx,
1787 : 0, NULL, NULL,
1788 : owner_sid,
1789 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1790 : SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1791 : SEC_ACE_FLAG_OBJECT_INHERIT,
1792 : SID_WORLD,
1793 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1794 : SEC_FILE_ALL | SEC_STD_ALL,
1795 : 0,
1796 : NULL);
1797 19 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1798 19 : set.set_secdesc.in.file.fnum = fnum;
1799 19 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1800 19 : set.set_secdesc.in.sd = sd;
1801 19 : status = smb_raw_setfileinfo(cli->tree, &set);
1802 19 : CHECK_STATUS(status, NT_STATUS_OK);
1803 :
1804 : /* Check DACL we just set. */
1805 19 : torture_comment(tctx, "checking new sd\n");
1806 19 : q.query_secdesc.in.file.fnum = fnum;
1807 19 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
1808 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1809 19 : CHECK_STATUS(status, NT_STATUS_OK);
1810 19 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
1811 :
1812 19 : io.ntcreatex.in.fname = fname1;
1813 19 : io.ntcreatex.in.create_options = 0;
1814 19 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1815 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1816 19 : status = smb_raw_open(cli->tree, tctx, &io);
1817 19 : CHECK_STATUS(status, NT_STATUS_OK);
1818 19 : fnum2 = io.ntcreatex.out.file.fnum;
1819 19 : CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1820 :
1821 19 : q.query_secdesc.in.file.fnum = fnum2;
1822 19 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1823 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
1824 19 : CHECK_STATUS(status, NT_STATUS_OK);
1825 19 : smbcli_close(cli->tree, fnum2);
1826 :
1827 19 : sd2 = security_descriptor_dacl_create(tctx,
1828 : 0, owner_sid, NULL,
1829 : owner_sid,
1830 : SEC_ACE_TYPE_ACCESS_ALLOWED,
1831 : SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1832 : 0,
1833 : NULL);
1834 19 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1835 :
1836 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1837 19 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1838 19 : status = smb_raw_open(cli->tree, tctx, &io);
1839 19 : if (NT_STATUS_IS_OK(status)) {
1840 0 : torture_warning(tctx, "failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
1841 0 : ret = false;
1842 0 : fnum2 = io.ntcreatex.out.file.fnum;
1843 0 : CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1844 0 : smbcli_close(cli->tree, fnum2);
1845 : } else {
1846 19 : if (TARGET_IS_WIN7(tctx)) {
1847 0 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1848 : } else {
1849 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1850 : }
1851 : }
1852 :
1853 19 : torture_comment(tctx, "trying without execute\n");
1854 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1855 19 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
1856 19 : status = smb_raw_open(cli->tree, tctx, &io);
1857 19 : if (TARGET_IS_WIN7(tctx)) {
1858 0 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1859 : } else {
1860 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1861 : }
1862 :
1863 19 : torture_comment(tctx, "and with full permissions again\n");
1864 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1865 19 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1866 19 : status = smb_raw_open(cli->tree, tctx, &io);
1867 19 : if (TARGET_IS_WIN7(tctx)) {
1868 0 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1869 : } else {
1870 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1871 : }
1872 :
1873 19 : io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1874 19 : status = smb_raw_open(cli->tree, tctx, &io);
1875 19 : CHECK_STATUS(status, NT_STATUS_OK);
1876 19 : fnum2 = io.ntcreatex.out.file.fnum;
1877 19 : CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1878 19 : smbcli_close(cli->tree, fnum2);
1879 :
1880 19 : torture_comment(tctx, "put back original sd\n");
1881 19 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1882 19 : set.set_secdesc.in.file.fnum = fnum;
1883 19 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1884 19 : set.set_secdesc.in.sd = sd_orig;
1885 19 : status = smb_raw_setfileinfo(cli->tree, &set);
1886 19 : CHECK_STATUS(status, NT_STATUS_OK);
1887 :
1888 19 : smbcli_close(cli->tree, fnum);
1889 :
1890 19 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1891 19 : status = smb_raw_open(cli->tree, tctx, &io);
1892 19 : if (TARGET_IS_WIN7(tctx)) {
1893 0 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1894 : } else {
1895 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1896 : }
1897 :
1898 19 : io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1899 19 : status = smb_raw_open(cli->tree, tctx, &io);
1900 19 : CHECK_STATUS(status, NT_STATUS_OK);
1901 19 : fnum2 = io.ntcreatex.out.file.fnum;
1902 19 : CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1903 19 : smbcli_close(cli->tree, fnum2);
1904 :
1905 19 : done:
1906 19 : if (sd_orig != NULL) {
1907 19 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1908 19 : set.set_secdesc.in.file.fnum = fnum;
1909 19 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1910 19 : set.set_secdesc.in.sd = sd_orig;
1911 19 : status = smb_raw_setfileinfo(cli->tree, &set);
1912 : }
1913 :
1914 19 : smbcli_close(cli->tree, fnum);
1915 19 : smbcli_unlink(cli->tree, fname1);
1916 19 : smbcli_rmdir(cli->tree, dname);
1917 19 : smb_raw_exit(cli->session);
1918 19 : smbcli_deltree(cli->tree, BASEDIR);
1919 :
1920 19 : if (!ret) {
1921 0 : torture_result(tctx,
1922 : TORTURE_FAIL, "(%s) test_inheritance\n",
1923 : __location__);
1924 : }
1925 :
1926 19 : return ret;
1927 : }
1928 :
1929 19 : static bool test_inheritance_flags(struct torture_context *tctx,
1930 : struct smbcli_state *cli)
1931 : {
1932 0 : NTSTATUS status;
1933 0 : union smb_open io;
1934 19 : const char *dname = BASEDIR "\\inheritance";
1935 19 : const char *fname1 = BASEDIR "\\inheritance\\testfile";
1936 19 : bool ret = true;
1937 19 : int fnum=0, fnum2, i, j;
1938 0 : union smb_fileinfo q;
1939 0 : union smb_setfileinfo set;
1940 19 : struct security_descriptor *sd, *sd2, *sd_orig=NULL;
1941 0 : const char *owner_sid;
1942 0 : struct {
1943 : uint32_t parent_set_sd_type; /* 3 options */
1944 : uint32_t parent_set_ace_inherit; /* 1 option */
1945 : uint32_t parent_get_sd_type;
1946 : uint32_t parent_get_ace_inherit;
1947 : uint32_t child_get_sd_type;
1948 : uint32_t child_get_ace_inherit;
1949 19 : } tflags[16] = {{0}}; /* 2^4 */
1950 :
1951 304 : for (i = 0; i < 15; i++) {
1952 285 : torture_comment(tctx, "i=%d:", i);
1953 :
1954 285 : ZERO_STRUCT(tflags[i]);
1955 :
1956 285 : if (i & 1) {
1957 133 : tflags[i].parent_set_sd_type |=
1958 : SEC_DESC_DACL_AUTO_INHERITED;
1959 133 : torture_comment(tctx, "AUTO_INHERITED, ");
1960 : }
1961 285 : if (i & 2) {
1962 133 : tflags[i].parent_set_sd_type |=
1963 : SEC_DESC_DACL_AUTO_INHERIT_REQ;
1964 133 : torture_comment(tctx, "AUTO_INHERIT_REQ, ");
1965 : }
1966 285 : if (i & 4) {
1967 133 : tflags[i].parent_set_sd_type |=
1968 : SEC_DESC_DACL_PROTECTED;
1969 133 : tflags[i].parent_get_sd_type |=
1970 : SEC_DESC_DACL_PROTECTED;
1971 133 : torture_comment(tctx, "PROTECTED, ");
1972 : }
1973 285 : if (i & 8) {
1974 133 : tflags[i].parent_set_ace_inherit |=
1975 : SEC_ACE_FLAG_INHERITED_ACE;
1976 133 : tflags[i].parent_get_ace_inherit |=
1977 : SEC_ACE_FLAG_INHERITED_ACE;
1978 133 : torture_comment(tctx, "INHERITED, ");
1979 : }
1980 :
1981 285 : if ((tflags[i].parent_set_sd_type &
1982 : (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) ==
1983 : (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) {
1984 57 : tflags[i].parent_get_sd_type |=
1985 : SEC_DESC_DACL_AUTO_INHERITED;
1986 57 : tflags[i].child_get_sd_type |=
1987 : SEC_DESC_DACL_AUTO_INHERITED;
1988 57 : tflags[i].child_get_ace_inherit |=
1989 : SEC_ACE_FLAG_INHERITED_ACE;
1990 57 : torture_comment(tctx, " ... parent is AUTO INHERITED");
1991 : }
1992 :
1993 285 : if (tflags[i].parent_set_ace_inherit &
1994 : SEC_ACE_FLAG_INHERITED_ACE) {
1995 133 : tflags[i].parent_get_ace_inherit =
1996 : SEC_ACE_FLAG_INHERITED_ACE;
1997 133 : torture_comment(tctx, " ... parent ACE is INHERITED");
1998 : }
1999 :
2000 285 : torture_comment(tctx, "\n");
2001 : }
2002 :
2003 19 : if (!torture_setup_dir(cli, BASEDIR))
2004 0 : return false;
2005 :
2006 19 : torture_comment(tctx, "TESTING ACL INHERITANCE FLAGS\n");
2007 :
2008 19 : ZERO_STRUCT(io);
2009 :
2010 19 : io.generic.level = RAW_OPEN_NTCREATEX;
2011 19 : io.ntcreatex.in.root_fid.fnum = 0;
2012 19 : io.ntcreatex.in.flags = 0;
2013 19 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2014 19 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2015 19 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
2016 19 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
2017 19 : io.ntcreatex.in.alloc_size = 0;
2018 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2019 19 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2020 19 : io.ntcreatex.in.security_flags = 0;
2021 19 : io.ntcreatex.in.fname = dname;
2022 :
2023 19 : torture_comment(tctx, "creating initial directory %s\n", dname);
2024 19 : status = smb_raw_open(cli->tree, tctx, &io);
2025 19 : CHECK_STATUS(status, NT_STATUS_OK);
2026 19 : fnum = io.ntcreatex.out.file.fnum;
2027 :
2028 19 : torture_comment(tctx, "getting original sd\n");
2029 19 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
2030 19 : q.query_secdesc.in.file.fnum = fnum;
2031 19 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2032 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
2033 19 : CHECK_STATUS(status, NT_STATUS_OK);
2034 19 : sd_orig = q.query_secdesc.out.sd;
2035 :
2036 19 : owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
2037 19 : torture_comment(tctx, "owner_sid is %s\n", owner_sid);
2038 :
2039 323 : for (i=0; i < ARRAY_SIZE(tflags); i++) {
2040 304 : torture_comment(tctx, "setting a new sd on directory, pass #%d\n", i);
2041 :
2042 304 : sd = security_descriptor_dacl_create(tctx,
2043 304 : tflags[i].parent_set_sd_type,
2044 : NULL, NULL,
2045 : owner_sid,
2046 : SEC_ACE_TYPE_ACCESS_ALLOWED,
2047 : SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
2048 : SEC_ACE_FLAG_OBJECT_INHERIT |
2049 : SEC_ACE_FLAG_CONTAINER_INHERIT |
2050 304 : tflags[i].parent_set_ace_inherit,
2051 : SID_WORLD,
2052 : SEC_ACE_TYPE_ACCESS_ALLOWED,
2053 : SEC_FILE_ALL | SEC_STD_ALL,
2054 : 0,
2055 : NULL);
2056 304 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2057 304 : set.set_secdesc.in.file.fnum = fnum;
2058 304 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2059 304 : set.set_secdesc.in.sd = sd;
2060 304 : status = smb_raw_setfileinfo(cli->tree, &set);
2061 304 : CHECK_STATUS(status, NT_STATUS_OK);
2062 :
2063 : /*
2064 : * Check DACL we just set, except change the bits to what they
2065 : * should be.
2066 : */
2067 304 : torture_comment(tctx, " checking new sd\n");
2068 :
2069 : /* REQ bit should always be false. */
2070 304 : sd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
2071 :
2072 304 : if ((tflags[i].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
2073 247 : sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
2074 :
2075 304 : q.query_secdesc.in.file.fnum = fnum;
2076 304 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
2077 304 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
2078 304 : CHECK_STATUS(status, NT_STATUS_OK);
2079 304 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
2080 :
2081 : /* Create file. */
2082 304 : torture_comment(tctx, " creating file %s\n", fname1);
2083 304 : io.ntcreatex.in.fname = fname1;
2084 304 : io.ntcreatex.in.create_options = 0;
2085 304 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2086 304 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2087 304 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2088 304 : status = smb_raw_open(cli->tree, tctx, &io);
2089 304 : CHECK_STATUS(status, NT_STATUS_OK);
2090 304 : fnum2 = io.ntcreatex.out.file.fnum;
2091 304 : CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
2092 :
2093 304 : q.query_secdesc.in.file.fnum = fnum2;
2094 304 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2095 304 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
2096 304 : CHECK_STATUS(status, NT_STATUS_OK);
2097 :
2098 304 : torture_comment(tctx, " checking sd on file %s\n", fname1);
2099 304 : sd2 = security_descriptor_dacl_create(tctx,
2100 304 : tflags[i].child_get_sd_type,
2101 : owner_sid, NULL,
2102 : owner_sid,
2103 : SEC_ACE_TYPE_ACCESS_ALLOWED,
2104 : SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
2105 : tflags[i].child_get_ace_inherit,
2106 : NULL);
2107 304 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
2108 :
2109 : /*
2110 : * Set new sd on file ... prove that the bits have nothing to
2111 : * do with the parents bits when manually setting an ACL. The
2112 : * _AUTO_INHERITED bit comes directly from the ACL set.
2113 : */
2114 5168 : for (j = 0; j < ARRAY_SIZE(tflags); j++) {
2115 4864 : torture_comment(tctx, " setting new file sd, pass #%d\n", j);
2116 :
2117 : /* Change sd type. */
2118 4864 : sd2->type &= ~(SEC_DESC_DACL_AUTO_INHERITED |
2119 : SEC_DESC_DACL_AUTO_INHERIT_REQ |
2120 : SEC_DESC_DACL_PROTECTED);
2121 4864 : sd2->type |= tflags[j].parent_set_sd_type;
2122 :
2123 4864 : sd2->dacl->aces[0].flags &=
2124 : ~SEC_ACE_FLAG_INHERITED_ACE;
2125 4864 : sd2->dacl->aces[0].flags |=
2126 4864 : tflags[j].parent_set_ace_inherit;
2127 :
2128 4864 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2129 4864 : set.set_secdesc.in.file.fnum = fnum2;
2130 4864 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2131 4864 : set.set_secdesc.in.sd = sd2;
2132 4864 : status = smb_raw_setfileinfo(cli->tree, &set);
2133 4864 : CHECK_STATUS(status, NT_STATUS_OK);
2134 :
2135 : /* Check DACL we just set. */
2136 4864 : sd2->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
2137 4864 : if ((tflags[j].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
2138 3952 : sd2->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
2139 :
2140 4864 : q.query_secdesc.in.file.fnum = fnum2;
2141 4864 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2142 4864 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
2143 4864 : CHECK_STATUS(status, NT_STATUS_OK);
2144 :
2145 4864 : CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
2146 : }
2147 :
2148 304 : smbcli_close(cli->tree, fnum2);
2149 304 : smbcli_unlink(cli->tree, fname1);
2150 : }
2151 :
2152 19 : done:
2153 19 : smbcli_close(cli->tree, fnum);
2154 19 : smb_raw_exit(cli->session);
2155 19 : smbcli_deltree(cli->tree, BASEDIR);
2156 :
2157 19 : if (!ret) {
2158 9 : torture_result(tctx,
2159 : TORTURE_FAIL, "(%s) test_inheritance_flags\n",
2160 : __location__);
2161 : }
2162 :
2163 19 : return ret;
2164 : }
2165 :
2166 : /*
2167 : test dynamic acl inheritance
2168 : Test copied to smb2/acls.c for SMB2.
2169 : */
2170 19 : static bool test_inheritance_dynamic(struct torture_context *tctx,
2171 : struct smbcli_state *cli)
2172 : {
2173 0 : NTSTATUS status;
2174 0 : union smb_open io;
2175 19 : const char *dname = BASEDIR "\\inheritance2";
2176 19 : const char *fname1 = BASEDIR "\\inheritance2\\testfile";
2177 19 : bool ret = true;
2178 19 : int fnum=0, fnum2;
2179 0 : union smb_fileinfo q;
2180 0 : union smb_setfileinfo set;
2181 19 : struct security_descriptor *sd, *sd_orig=NULL;
2182 0 : const char *owner_sid;
2183 :
2184 19 : torture_comment(tctx, "TESTING DYNAMIC ACL INHERITANCE\n");
2185 :
2186 19 : if (!torture_setup_dir(cli, BASEDIR))
2187 0 : return false;
2188 :
2189 19 : io.generic.level = RAW_OPEN_NTCREATEX;
2190 19 : io.ntcreatex.in.root_fid.fnum = 0;
2191 19 : io.ntcreatex.in.flags = 0;
2192 19 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2193 19 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2194 19 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
2195 19 : io.ntcreatex.in.share_access = 0;
2196 19 : io.ntcreatex.in.alloc_size = 0;
2197 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2198 19 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2199 19 : io.ntcreatex.in.security_flags = 0;
2200 19 : io.ntcreatex.in.fname = dname;
2201 :
2202 19 : status = smb_raw_open(cli->tree, tctx, &io);
2203 19 : CHECK_STATUS(status, NT_STATUS_OK);
2204 19 : fnum = io.ntcreatex.out.file.fnum;
2205 :
2206 19 : torture_comment(tctx, "get the original sd\n");
2207 19 : q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
2208 19 : q.query_secdesc.in.file.fnum = fnum;
2209 19 : q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2210 19 : status = smb_raw_fileinfo(cli->tree, tctx, &q);
2211 19 : CHECK_STATUS(status, NT_STATUS_OK);
2212 19 : sd_orig = q.query_secdesc.out.sd;
2213 :
2214 19 : owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
2215 :
2216 19 : torture_comment(tctx, "owner_sid is %s\n", owner_sid);
2217 :
2218 19 : sd = security_descriptor_dacl_create(tctx,
2219 : 0, NULL, NULL,
2220 : owner_sid,
2221 : SEC_ACE_TYPE_ACCESS_ALLOWED,
2222 : SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
2223 : SEC_ACE_FLAG_OBJECT_INHERIT,
2224 : NULL);
2225 19 : sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
2226 :
2227 19 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2228 19 : set.set_secdesc.in.file.fnum = fnum;
2229 19 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2230 19 : set.set_secdesc.in.sd = sd;
2231 19 : status = smb_raw_setfileinfo(cli->tree, &set);
2232 19 : CHECK_STATUS(status, NT_STATUS_OK);
2233 :
2234 19 : torture_comment(tctx, "create a file with an inherited acl\n");
2235 19 : io.ntcreatex.in.fname = fname1;
2236 19 : io.ntcreatex.in.create_options = 0;
2237 19 : io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE;
2238 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2239 19 : status = smb_raw_open(cli->tree, tctx, &io);
2240 19 : CHECK_STATUS(status, NT_STATUS_OK);
2241 19 : fnum2 = io.ntcreatex.out.file.fnum;
2242 19 : smbcli_close(cli->tree, fnum2);
2243 :
2244 19 : torture_comment(tctx, "try and access file with base rights - should be OK\n");
2245 19 : io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
2246 19 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2247 19 : status = smb_raw_open(cli->tree, tctx, &io);
2248 19 : CHECK_STATUS(status, NT_STATUS_OK);
2249 19 : fnum2 = io.ntcreatex.out.file.fnum;
2250 19 : smbcli_close(cli->tree, fnum2);
2251 :
2252 19 : torture_comment(tctx, "try and access file with extra rights - should be denied\n");
2253 19 : io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
2254 19 : status = smb_raw_open(cli->tree, tctx, &io);
2255 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
2256 :
2257 19 : torture_comment(tctx, "update parent sd\n");
2258 19 : sd = security_descriptor_dacl_create(tctx,
2259 : 0, NULL, NULL,
2260 : owner_sid,
2261 : SEC_ACE_TYPE_ACCESS_ALLOWED,
2262 : SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE,
2263 : SEC_ACE_FLAG_OBJECT_INHERIT,
2264 : NULL);
2265 19 : sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
2266 :
2267 19 : set.set_secdesc.in.sd = sd;
2268 19 : status = smb_raw_setfileinfo(cli->tree, &set);
2269 19 : CHECK_STATUS(status, NT_STATUS_OK);
2270 :
2271 19 : torture_comment(tctx, "try and access file with base rights - should be OK\n");
2272 19 : io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
2273 19 : status = smb_raw_open(cli->tree, tctx, &io);
2274 19 : CHECK_STATUS(status, NT_STATUS_OK);
2275 19 : fnum2 = io.ntcreatex.out.file.fnum;
2276 19 : smbcli_close(cli->tree, fnum2);
2277 :
2278 :
2279 19 : torture_comment(tctx, "try and access now - should be OK if dynamic inheritance works\n");
2280 19 : io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
2281 19 : status = smb_raw_open(cli->tree, tctx, &io);
2282 19 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2283 19 : torture_comment(tctx, "Server does not have dynamic inheritance\n");
2284 : }
2285 19 : if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
2286 0 : torture_comment(tctx, "Server does have dynamic inheritance\n");
2287 : }
2288 19 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
2289 :
2290 19 : smbcli_unlink(cli->tree, fname1);
2291 :
2292 19 : done:
2293 19 : if (sd_orig != NULL) {
2294 19 : torture_comment(tctx, "put back original sd\n");
2295 19 : set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2296 19 : set.set_secdesc.in.file.fnum = fnum;
2297 19 : set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2298 19 : set.set_secdesc.in.sd = sd_orig;
2299 19 : status = smb_raw_setfileinfo(cli->tree, &set);
2300 : }
2301 19 : smbcli_close(cli->tree, fnum);
2302 19 : smbcli_rmdir(cli->tree, dname);
2303 19 : smb_raw_exit(cli->session);
2304 19 : smbcli_deltree(cli->tree, BASEDIR);
2305 :
2306 19 : return ret;
2307 : }
2308 :
2309 : #define CHECK_STATUS_FOR_BIT_ACTION(status, bits, action) do { \
2310 : if (!(bits & desired_64)) {\
2311 : CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); \
2312 : action; \
2313 : } else { \
2314 : CHECK_STATUS(status, NT_STATUS_OK); \
2315 : } \
2316 : } while (0)
2317 :
2318 : #define CHECK_STATUS_FOR_BIT(status, bits, access) do { \
2319 : if (NT_STATUS_IS_OK(status)) { \
2320 : if (!(granted & access)) {\
2321 : ret = false; \
2322 : torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are not granted! granted[0x%08X] desired[0x%08X]\n", \
2323 : __location__, nt_errstr(status), access, granted, desired); \
2324 : goto done; \
2325 : } \
2326 : } else { \
2327 : if (granted & access) {\
2328 : ret = false; \
2329 : torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are granted! granted[0x%08X] desired[0x%08X]\n", \
2330 : __location__, nt_errstr(status), access, granted, desired); \
2331 : goto done; \
2332 : } \
2333 : } \
2334 : CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \
2335 : } while (0)
2336 :
2337 : #if 0
2338 :
2339 : /* test what access mask is needed for getting and setting security_descriptors
2340 : Test copied to smb2/acls.c for SMB2. */
2341 : static bool test_sd_get_set(struct torture_context *tctx,
2342 : struct smbcli_state *cli)
2343 : {
2344 : NTSTATUS status;
2345 : bool ret = true;
2346 : union smb_open io;
2347 : union smb_fileinfo fi;
2348 : union smb_setfileinfo si;
2349 : struct security_descriptor *sd;
2350 : struct security_descriptor *sd_owner = NULL;
2351 : struct security_descriptor *sd_group = NULL;
2352 : struct security_descriptor *sd_dacl = NULL;
2353 : struct security_descriptor *sd_sacl = NULL;
2354 : int fnum=0;
2355 : const char *fname = BASEDIR "\\sd_get_set.txt";
2356 : uint64_t desired_64;
2357 : uint32_t desired = 0, granted;
2358 : int i = 0;
2359 : #define NO_BITS_HACK (((uint64_t)1)<<32)
2360 : uint64_t open_bits =
2361 : SEC_MASK_GENERIC |
2362 : SEC_FLAG_SYSTEM_SECURITY |
2363 : SEC_FLAG_MAXIMUM_ALLOWED |
2364 : SEC_STD_ALL |
2365 : SEC_FILE_ALL |
2366 : NO_BITS_HACK;
2367 : uint64_t get_owner_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
2368 : uint64_t set_owner_bits = SEC_GENERIC_ALL | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
2369 : uint64_t get_group_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
2370 : uint64_t set_group_bits = SEC_GENERIC_ALL | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
2371 : uint64_t get_dacl_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
2372 : uint64_t set_dacl_bits = SEC_GENERIC_ALL | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_DAC;
2373 : uint64_t get_sacl_bits = SEC_FLAG_SYSTEM_SECURITY;
2374 : uint64_t set_sacl_bits = SEC_FLAG_SYSTEM_SECURITY;
2375 :
2376 : if (!torture_setup_dir(cli, BASEDIR))
2377 : return false;
2378 :
2379 : torture_comment(tctx, "TESTING ACCESS MASKS FOR SD GET/SET\n");
2380 :
2381 : /* first create a file with full access for everyone */
2382 : sd = security_descriptor_dacl_create(tctx,
2383 : 0, SID_NT_ANONYMOUS, SID_BUILTIN_USERS,
2384 : SID_WORLD,
2385 : SEC_ACE_TYPE_ACCESS_ALLOWED,
2386 : SEC_GENERIC_ALL,
2387 : 0,
2388 : NULL);
2389 : sd->type |= SEC_DESC_SACL_PRESENT;
2390 : sd->sacl = NULL;
2391 : io.ntcreatex.level = RAW_OPEN_NTTRANS_CREATE;
2392 : io.ntcreatex.in.root_fid.fnum = 0;
2393 : io.ntcreatex.in.flags = 0;
2394 : io.ntcreatex.in.access_mask = SEC_GENERIC_ALL;
2395 : io.ntcreatex.in.create_options = 0;
2396 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2397 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2398 : io.ntcreatex.in.alloc_size = 0;
2399 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2400 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2401 : io.ntcreatex.in.security_flags = 0;
2402 : io.ntcreatex.in.fname = fname;
2403 : io.ntcreatex.in.sec_desc = sd;
2404 : io.ntcreatex.in.ea_list = NULL;
2405 : status = smb_raw_open(cli->tree, tctx, &io);
2406 : CHECK_STATUS(status, NT_STATUS_OK);
2407 : fnum = io.ntcreatex.out.file.fnum;
2408 :
2409 : status = smbcli_close(cli->tree, fnum);
2410 : CHECK_STATUS(status, NT_STATUS_OK);
2411 :
2412 : /*
2413 : * now try each access_mask bit and no bit at all in a loop
2414 : * and see what's allowed
2415 : * NOTE: if i == 32 it means access_mask = 0 (see NO_BITS_HACK above)
2416 : */
2417 : for (i=0; i <= 32; i++) {
2418 : desired_64 = ((uint64_t)1) << i;
2419 : desired = (uint32_t)desired_64;
2420 :
2421 : /* first open the file with the desired access */
2422 : io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2423 : io.ntcreatex.in.access_mask = desired;
2424 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2425 : status = smb_raw_open(cli->tree, tctx, &io);
2426 : CHECK_STATUS_FOR_BIT_ACTION(status, open_bits, goto next);
2427 : fnum = io.ntcreatex.out.file.fnum;
2428 :
2429 : /* then check what access was granted */
2430 : fi.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
2431 : fi.access_information.in.file.fnum = fnum;
2432 : status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2433 : CHECK_STATUS(status, NT_STATUS_OK);
2434 : granted = fi.access_information.out.access_flags;
2435 :
2436 : /* test the owner */
2437 : ZERO_STRUCT(fi);
2438 : fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
2439 : fi.query_secdesc.in.file.fnum = fnum;
2440 : fi.query_secdesc.in.secinfo_flags = SECINFO_OWNER;
2441 : status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2442 : CHECK_STATUS_FOR_BIT(status, get_owner_bits, SEC_STD_READ_CONTROL);
2443 : if (fi.query_secdesc.out.sd) {
2444 : sd_owner = fi.query_secdesc.out.sd;
2445 : } else if (!sd_owner) {
2446 : sd_owner = sd;
2447 : }
2448 : si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2449 : si.set_secdesc.in.file.fnum = fnum;
2450 : si.set_secdesc.in.secinfo_flags = SECINFO_OWNER;
2451 : si.set_secdesc.in.sd = sd_owner;
2452 : status = smb_raw_setfileinfo(cli->tree, &si);
2453 : CHECK_STATUS_FOR_BIT(status, set_owner_bits, SEC_STD_WRITE_OWNER);
2454 :
2455 : /* test the group */
2456 : ZERO_STRUCT(fi);
2457 : fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
2458 : fi.query_secdesc.in.file.fnum = fnum;
2459 : fi.query_secdesc.in.secinfo_flags = SECINFO_GROUP;
2460 : status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2461 : CHECK_STATUS_FOR_BIT(status, get_group_bits, SEC_STD_READ_CONTROL);
2462 : if (fi.query_secdesc.out.sd) {
2463 : sd_group = fi.query_secdesc.out.sd;
2464 : } else if (!sd_group) {
2465 : sd_group = sd;
2466 : }
2467 : si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2468 : si.set_secdesc.in.file.fnum = fnum;
2469 : si.set_secdesc.in.secinfo_flags = SECINFO_GROUP;
2470 : si.set_secdesc.in.sd = sd_group;
2471 : status = smb_raw_setfileinfo(cli->tree, &si);
2472 : CHECK_STATUS_FOR_BIT(status, set_group_bits, SEC_STD_WRITE_OWNER);
2473 :
2474 : /* test the DACL */
2475 : ZERO_STRUCT(fi);
2476 : fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
2477 : fi.query_secdesc.in.file.fnum = fnum;
2478 : fi.query_secdesc.in.secinfo_flags = SECINFO_DACL;
2479 : status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2480 : CHECK_STATUS_FOR_BIT(status, get_dacl_bits, SEC_STD_READ_CONTROL);
2481 : if (fi.query_secdesc.out.sd) {
2482 : sd_dacl = fi.query_secdesc.out.sd;
2483 : } else if (!sd_dacl) {
2484 : sd_dacl = sd;
2485 : }
2486 : si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2487 : si.set_secdesc.in.file.fnum = fnum;
2488 : si.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2489 : si.set_secdesc.in.sd = sd_dacl;
2490 : status = smb_raw_setfileinfo(cli->tree, &si);
2491 : CHECK_STATUS_FOR_BIT(status, set_dacl_bits, SEC_STD_WRITE_DAC);
2492 :
2493 : /* test the SACL */
2494 : ZERO_STRUCT(fi);
2495 : fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
2496 : fi.query_secdesc.in.file.fnum = fnum;
2497 : fi.query_secdesc.in.secinfo_flags = SECINFO_SACL;
2498 : status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2499 : CHECK_STATUS_FOR_BIT(status, get_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
2500 : if (fi.query_secdesc.out.sd) {
2501 : sd_sacl = fi.query_secdesc.out.sd;
2502 : } else if (!sd_sacl) {
2503 : sd_sacl = sd;
2504 : }
2505 : si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2506 : si.set_secdesc.in.file.fnum = fnum;
2507 : si.set_secdesc.in.secinfo_flags = SECINFO_SACL;
2508 : si.set_secdesc.in.sd = sd_sacl;
2509 : status = smb_raw_setfileinfo(cli->tree, &si);
2510 : CHECK_STATUS_FOR_BIT(status, set_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
2511 :
2512 : /* close the handle */
2513 : status = smbcli_close(cli->tree, fnum);
2514 : CHECK_STATUS(status, NT_STATUS_OK);
2515 : next:
2516 : continue;
2517 : }
2518 :
2519 : done:
2520 : smbcli_close(cli->tree, fnum);
2521 : smbcli_unlink(cli->tree, fname);
2522 : smb_raw_exit(cli->session);
2523 : smbcli_deltree(cli->tree, BASEDIR);
2524 :
2525 : return ret;
2526 : }
2527 :
2528 : #endif
2529 :
2530 : /*
2531 : basic testing of security descriptor calls
2532 : */
2533 2354 : struct torture_suite *torture_raw_acls(TALLOC_CTX *mem_ctx)
2534 : {
2535 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "acls");
2536 :
2537 2354 : torture_suite_add_1smb_test(suite, "sd", test_sd);
2538 2354 : torture_suite_add_1smb_test(suite, "create_file", test_nttrans_create_file);
2539 2354 : torture_suite_add_1smb_test(suite, "create_dir", test_nttrans_create_dir);
2540 2354 : torture_suite_add_1smb_test(suite, "create_owner_file", test_nttrans_create_owner_file);
2541 2354 : torture_suite_add_1smb_test(suite, "create_owner_dir", test_nttrans_create_owner_dir);
2542 2354 : torture_suite_add_1smb_test(suite, "nulldacl", test_nttrans_create_null_dacl);
2543 2354 : torture_suite_add_1smb_test(suite, "creator", test_creator_sid);
2544 2354 : torture_suite_add_1smb_test(suite, "generic", test_generic_bits);
2545 2354 : torture_suite_add_1smb_test(suite, "owner", test_owner_bits);
2546 2354 : torture_suite_add_1smb_test(suite, "inheritance", test_inheritance);
2547 :
2548 2354 : torture_suite_add_1smb_test(suite, "INHERITFLAGS", test_inheritance_flags);
2549 2354 : torture_suite_add_1smb_test(suite, "dynamic", test_inheritance_dynamic);
2550 : #if 0
2551 : /* XXX This test does not work against XP or Vista. */
2552 : torture_suite_add_1smb_test(suite, "GETSET", test_sd_get_set);
2553 : #endif
2554 :
2555 2354 : return suite;
2556 : }
|