2 Unix SMB/CIFS implementation.
4 test security descriptor operations
6 Copyright (C) Andrew Tridgell 2004
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.
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.
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/>.
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/util/clilsa.h"
28 #include "libcli/security/security.h"
29 #include "torture/util.h"
30 #include "librpc/gen_ndr/ndr_security.h"
31 #include "torture/raw/proto.h"
33 #define BASEDIR "\\testsd"
35 #define CHECK_STATUS(status, correct) do { \
36 if (!NT_STATUS_EQUAL(status, correct)) { \
38 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
39 __location__, nt_errstr(status), nt_errstr(correct)); \
43 #define FAIL_UNLESS(__cond) \
45 if (__cond) {} else { \
47 torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n", \
48 __location__, #__cond); \
53 #define CHECK_SECURITY_DESCRIPTOR(_sd1, _sd2) do { \
54 if (!security_descriptor_equal(_sd1, _sd2)) { \
55 torture_warning(tctx, "%s: security descriptors don't match!\n", __location__); \
56 torture_warning(tctx, "got:\n"); \
57 NDR_PRINT_DEBUG(security_descriptor, _sd1); \
58 torture_warning(tctx, "expected:\n"); \
59 NDR_PRINT_DEBUG(security_descriptor, _sd2); \
65 * Helper function to verify a security descriptor, by querying
66 * and comparing against the passed in sd.
67 * Copied to smb2_util_verify_sd() for SMB2.
69 static bool verify_sd(TALLOC_CTX
*tctx
, struct smbcli_state
*cli
,
70 int fnum
, struct security_descriptor
*sd
)
74 union smb_fileinfo q
= {};
77 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
78 q
.query_secdesc
.in
.file
.fnum
= fnum
;
79 q
.query_secdesc
.in
.secinfo_flags
=
83 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
84 CHECK_STATUS(status
, NT_STATUS_OK
);
86 /* More work is needed if we're going to check this bit. */
87 sd
->type
&= ~SEC_DESC_DACL_AUTO_INHERITED
;
89 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd
);
97 * Helper function to verify attributes, by querying
98 * and comparing against the passed attrib.
99 * Copied to smb2_util_verify_attrib() for SMB2.
101 static bool verify_attrib(TALLOC_CTX
*tctx
, struct smbcli_state
*cli
,
102 int fnum
, uint32_t attrib
)
106 union smb_fileinfo q2
= {};
109 q2
.standard
.level
= RAW_FILEINFO_STANDARD
;
110 q2
.standard
.in
.file
.fnum
= fnum
;
111 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q2
);
112 CHECK_STATUS(status
, NT_STATUS_OK
);
114 q2
.standard
.out
.attrib
&= ~FILE_ATTRIBUTE_ARCHIVE
;
116 if (q2
.standard
.out
.attrib
!= attrib
) {
117 torture_warning(tctx
, "%s: attributes don't match! "
118 "got %x, expected %x\n", __location__
,
119 (uint32_t)q2
.standard
.out
.attrib
,
130 * Test setting and removing a DACL.
131 * Test copied to torture_smb2_setinfo() for SMB2.
133 static bool test_sd(struct torture_context
*tctx
, struct smbcli_state
*cli
)
137 const char *fname
= BASEDIR
"\\sd.txt";
140 union smb_fileinfo q
;
141 union smb_setfileinfo set
;
142 struct security_ace ace
;
143 struct security_descriptor
*sd
;
144 struct dom_sid
*test_sid
;
146 if (!torture_setup_dir(cli
, BASEDIR
))
149 torture_comment(tctx
, "TESTING SETFILEINFO EA_SET\n");
151 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
152 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
153 io
.ntcreatex
.in
.flags
= 0;
154 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
155 io
.ntcreatex
.in
.create_options
= 0;
156 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
157 io
.ntcreatex
.in
.share_access
=
158 NTCREATEX_SHARE_ACCESS_READ
|
159 NTCREATEX_SHARE_ACCESS_WRITE
;
160 io
.ntcreatex
.in
.alloc_size
= 0;
161 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
162 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
163 io
.ntcreatex
.in
.security_flags
= 0;
164 io
.ntcreatex
.in
.fname
= fname
;
165 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
166 CHECK_STATUS(status
, NT_STATUS_OK
);
167 fnum
= io
.ntcreatex
.out
.file
.fnum
;
169 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
170 q
.query_secdesc
.in
.file
.fnum
= fnum
;
171 q
.query_secdesc
.in
.secinfo_flags
=
175 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
176 CHECK_STATUS(status
, NT_STATUS_OK
);
177 sd
= q
.query_secdesc
.out
.sd
;
179 torture_comment(tctx
, "add a new ACE to the DACL\n");
181 test_sid
= dom_sid_parse_talloc(tctx
, SID_NT_AUTHENTICATED_USERS
);
183 ace
.type
= SEC_ACE_TYPE_ACCESS_ALLOWED
;
185 ace
.access_mask
= SEC_STD_ALL
;
186 ace
.trustee
= *test_sid
;
188 status
= security_descriptor_dacl_add(sd
, &ace
);
189 CHECK_STATUS(status
, NT_STATUS_OK
);
191 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
192 set
.set_secdesc
.in
.file
.fnum
= fnum
;
193 set
.set_secdesc
.in
.secinfo_flags
= q
.query_secdesc
.in
.secinfo_flags
;
194 set
.set_secdesc
.in
.sd
= sd
;
196 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
197 CHECK_STATUS(status
, NT_STATUS_OK
);
198 FAIL_UNLESS(verify_sd(tctx
, cli
, fnum
, sd
));
200 torture_comment(tctx
, "remove it again\n");
202 status
= security_descriptor_dacl_del(sd
, test_sid
);
203 CHECK_STATUS(status
, NT_STATUS_OK
);
205 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
206 CHECK_STATUS(status
, NT_STATUS_OK
);
207 FAIL_UNLESS(verify_sd(tctx
, cli
, fnum
, sd
));
210 smbcli_close(cli
->tree
, fnum
);
211 smb_raw_exit(cli
->session
);
212 smbcli_deltree(cli
->tree
, BASEDIR
);
219 test using nttrans create to create a file with an initial acl set
220 Test copied to test_create_acl() for SMB2.
222 static bool test_nttrans_create_ext(struct torture_context
*tctx
,
223 struct smbcli_state
*cli
, bool test_dir
)
227 const char *fname
= BASEDIR
"\\acl2.txt";
230 union smb_fileinfo q
= {};
231 struct security_ace ace
;
232 struct security_descriptor
*sd
;
233 struct dom_sid
*test_sid
;
235 FILE_ATTRIBUTE_HIDDEN
|
236 FILE_ATTRIBUTE_SYSTEM
|
237 (test_dir
? FILE_ATTRIBUTE_DIRECTORY
: 0);
238 NTSTATUS (*delete_func
)(struct smbcli_tree
*, const char *) =
239 test_dir
? smbcli_rmdir
: smbcli_unlink
;
241 if (!torture_setup_dir(cli
, BASEDIR
))
244 io
.generic
.level
= RAW_OPEN_NTTRANS_CREATE
;
245 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
246 io
.ntcreatex
.in
.flags
= 0;
247 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
248 io
.ntcreatex
.in
.create_options
=
249 test_dir
? NTCREATEX_OPTIONS_DIRECTORY
: 0;
250 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
251 io
.ntcreatex
.in
.share_access
=
252 NTCREATEX_SHARE_ACCESS_READ
|
253 NTCREATEX_SHARE_ACCESS_WRITE
;
254 io
.ntcreatex
.in
.alloc_size
= 0;
255 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
256 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
257 io
.ntcreatex
.in
.security_flags
= 0;
258 io
.ntcreatex
.in
.fname
= fname
;
259 io
.ntcreatex
.in
.sec_desc
= NULL
;
260 io
.ntcreatex
.in
.ea_list
= NULL
;
262 torture_comment(tctx
, "basic create\n");
264 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
265 CHECK_STATUS(status
, NT_STATUS_OK
);
266 fnum
= io
.ntcreatex
.out
.file
.fnum
;
268 torture_comment(tctx
, "querying ACL\n");
270 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
271 q
.query_secdesc
.in
.file
.fnum
= fnum
;
272 q
.query_secdesc
.in
.secinfo_flags
=
276 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
277 CHECK_STATUS(status
, NT_STATUS_OK
);
278 sd
= q
.query_secdesc
.out
.sd
;
280 status
= smbcli_close(cli
->tree
, fnum
);
281 CHECK_STATUS(status
, NT_STATUS_OK
);
283 status
= delete_func(cli
->tree
, fname
);
284 CHECK_STATUS(status
, NT_STATUS_OK
);
286 torture_comment(tctx
, "adding a new ACE\n");
287 test_sid
= dom_sid_parse_talloc(tctx
, SID_NT_AUTHENTICATED_USERS
);
289 ace
.type
= SEC_ACE_TYPE_ACCESS_ALLOWED
;
291 ace
.access_mask
= SEC_STD_ALL
;
292 ace
.trustee
= *test_sid
;
294 status
= security_descriptor_dacl_add(sd
, &ace
);
295 CHECK_STATUS(status
, NT_STATUS_OK
);
297 torture_comment(tctx
, "creating with an initial ACL\n");
299 io
.ntcreatex
.in
.sec_desc
= sd
;
300 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
301 CHECK_STATUS(status
, NT_STATUS_OK
);
302 fnum
= io
.ntcreatex
.out
.file
.fnum
;
304 FAIL_UNLESS(verify_sd(tctx
, cli
, fnum
, sd
));
306 status
= smbcli_close(cli
->tree
, fnum
);
307 CHECK_STATUS(status
, NT_STATUS_OK
);
308 status
= delete_func(cli
->tree
, fname
);
309 CHECK_STATUS(status
, NT_STATUS_OK
);
311 torture_comment(tctx
, "creating with attributes\n");
313 io
.ntcreatex
.in
.sec_desc
= NULL
;
314 io
.ntcreatex
.in
.file_attr
= attrib
;
315 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
316 CHECK_STATUS(status
, NT_STATUS_OK
);
317 fnum
= io
.ntcreatex
.out
.file
.fnum
;
319 FAIL_UNLESS(verify_attrib(tctx
, cli
, fnum
, attrib
));
321 status
= smbcli_close(cli
->tree
, fnum
);
322 CHECK_STATUS(status
, NT_STATUS_OK
);
324 status
= delete_func(cli
->tree
, fname
);
325 CHECK_STATUS(status
, NT_STATUS_OK
);
327 torture_comment(tctx
, "creating with attributes and ACL\n");
329 io
.ntcreatex
.in
.sec_desc
= sd
;
330 io
.ntcreatex
.in
.file_attr
= attrib
;
331 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
332 CHECK_STATUS(status
, NT_STATUS_OK
);
333 fnum
= io
.ntcreatex
.out
.file
.fnum
;
335 FAIL_UNLESS(verify_sd(tctx
, cli
, fnum
, sd
));
336 FAIL_UNLESS(verify_attrib(tctx
, cli
, fnum
, attrib
));
338 status
= smbcli_close(cli
->tree
, fnum
);
339 CHECK_STATUS(status
, NT_STATUS_OK
);
340 status
= delete_func(cli
->tree
, fname
);
341 CHECK_STATUS(status
, NT_STATUS_OK
);
343 torture_comment(tctx
, "creating with attributes, ACL and owner\n");
345 sd
= security_descriptor_dacl_create(tctx
,
346 0, SID_WORLD
, SID_BUILTIN_USERS
,
348 SEC_ACE_TYPE_ACCESS_ALLOWED
,
349 SEC_RIGHTS_FILE_READ
| SEC_STD_ALL
,
353 io
.ntcreatex
.in
.sec_desc
= sd
;
354 io
.ntcreatex
.in
.file_attr
= attrib
;
355 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
356 CHECK_STATUS(status
, NT_STATUS_OK
);
357 fnum
= io
.ntcreatex
.out
.file
.fnum
;
359 FAIL_UNLESS(verify_sd(tctx
, cli
, fnum
, sd
));
360 FAIL_UNLESS(verify_attrib(tctx
, cli
, fnum
, attrib
));
362 status
= smbcli_close(cli
->tree
, fnum
);
363 CHECK_STATUS(status
, NT_STATUS_OK
);
364 status
= delete_func(cli
->tree
, fname
);
365 CHECK_STATUS(status
, NT_STATUS_OK
);
368 smbcli_close(cli
->tree
, fnum
);
369 smb_raw_exit(cli
->session
);
370 smbcli_deltree(cli
->tree
, BASEDIR
);
374 static bool test_nttrans_create_file(struct torture_context
*tctx
,
375 struct smbcli_state
*cli
)
377 torture_comment(tctx
, "Testing nttrans create with sec_desc on files\n");
379 return test_nttrans_create_ext(tctx
, cli
, false);
382 static bool test_nttrans_create_dir(struct torture_context
*tctx
,
383 struct smbcli_state
*cli
)
385 torture_comment(tctx
, "Testing nttrans create with sec_desc on directories\n");
387 return test_nttrans_create_ext(tctx
, cli
, true);
390 #define CHECK_ACCESS_FLAGS(_fnum, flags) do { \
391 union smb_fileinfo _q; \
392 _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
393 _q.access_information.in.file.fnum = (_fnum); \
394 status = smb_raw_fileinfo(cli->tree, tctx, &_q); \
395 CHECK_STATUS(status, NT_STATUS_OK); \
396 if (_q.access_information.out.access_flags != (flags)) { \
398 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
399 __location__, _q.access_information.out.access_flags, (flags)); \
405 test using NTTRANS CREATE to create a file with a null ACL set
406 Test copied to test_create_null_dacl() for SMB2.
408 static bool test_nttrans_create_null_dacl(struct torture_context
*tctx
,
409 struct smbcli_state
*cli
)
413 const char *fname
= BASEDIR
"\\nulldacl.txt";
416 union smb_fileinfo q
;
417 union smb_setfileinfo s
;
418 struct security_descriptor
*sd
= security_descriptor_initialise(tctx
);
419 struct security_acl dacl
;
421 if (!torture_setup_dir(cli
, BASEDIR
))
424 torture_comment(tctx
, "TESTING SEC_DESC WITH A NULL DACL\n");
426 io
.generic
.level
= RAW_OPEN_NTTRANS_CREATE
;
427 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
428 io
.ntcreatex
.in
.flags
= 0;
429 io
.ntcreatex
.in
.access_mask
= SEC_STD_READ_CONTROL
| SEC_STD_WRITE_DAC
430 | SEC_STD_WRITE_OWNER
;
431 io
.ntcreatex
.in
.create_options
= 0;
432 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
433 io
.ntcreatex
.in
.share_access
=
434 NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
435 io
.ntcreatex
.in
.alloc_size
= 0;
436 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
437 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
438 io
.ntcreatex
.in
.security_flags
= 0;
439 io
.ntcreatex
.in
.fname
= fname
;
440 io
.ntcreatex
.in
.sec_desc
= sd
;
441 io
.ntcreatex
.in
.ea_list
= NULL
;
443 torture_comment(tctx
, "creating a file with a empty sd\n");
444 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
445 CHECK_STATUS(status
, NT_STATUS_OK
);
446 fnum
= io
.ntcreatex
.out
.file
.fnum
;
448 torture_comment(tctx
, "get the original sd\n");
449 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
450 q
.query_secdesc
.in
.file
.fnum
= fnum
;
451 q
.query_secdesc
.in
.secinfo_flags
=
455 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
456 CHECK_STATUS(status
, NT_STATUS_OK
);
459 * Testing the created DACL,
460 * the server should add the inherited DACL
461 * when SEC_DESC_DACL_PRESENT isn't specified
463 if (!(q
.query_secdesc
.out
.sd
->type
& SEC_DESC_DACL_PRESENT
)) {
465 torture_result(tctx
, TORTURE_FAIL
, "DACL_PRESENT flag not set by the server!\n");
468 if (q
.query_secdesc
.out
.sd
->dacl
== NULL
) {
470 torture_result(tctx
, TORTURE_FAIL
, "no DACL has been created on the server!\n");
474 torture_comment(tctx
, "set NULL DACL\n");
475 sd
->type
|= SEC_DESC_DACL_PRESENT
;
477 s
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
478 s
.set_secdesc
.in
.file
.fnum
= fnum
;
479 s
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
480 s
.set_secdesc
.in
.sd
= sd
;
481 status
= smb_raw_setfileinfo(cli
->tree
, &s
);
482 CHECK_STATUS(status
, NT_STATUS_OK
);
484 torture_comment(tctx
, "get the sd\n");
485 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
486 q
.query_secdesc
.in
.file
.fnum
= fnum
;
487 q
.query_secdesc
.in
.secinfo_flags
=
491 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
492 CHECK_STATUS(status
, NT_STATUS_OK
);
494 /* Testing the modified DACL */
495 if (!(q
.query_secdesc
.out
.sd
->type
& SEC_DESC_DACL_PRESENT
)) {
497 torture_result(tctx
, TORTURE_FAIL
, "DACL_PRESENT flag not set by the server!\n");
500 if (q
.query_secdesc
.out
.sd
->dacl
!= NULL
) {
502 torture_result(tctx
, TORTURE_FAIL
, "DACL has been created on the server!\n");
506 torture_comment(tctx
, "try open for read control\n");
507 io
.ntcreatex
.in
.access_mask
= SEC_STD_READ_CONTROL
;
508 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
509 CHECK_STATUS(status
, NT_STATUS_OK
);
510 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
511 SEC_STD_READ_CONTROL
| SEC_FILE_READ_ATTRIBUTE
);
512 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
514 torture_comment(tctx
, "try open for write\n");
515 io
.ntcreatex
.in
.access_mask
= SEC_FILE_WRITE_DATA
;
516 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
517 CHECK_STATUS(status
, NT_STATUS_OK
);
518 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
519 SEC_FILE_WRITE_DATA
| SEC_FILE_READ_ATTRIBUTE
);
520 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
522 torture_comment(tctx
, "try open for read\n");
523 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_DATA
;
524 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
525 CHECK_STATUS(status
, NT_STATUS_OK
);
526 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
527 SEC_FILE_READ_DATA
| SEC_FILE_READ_ATTRIBUTE
);
528 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
530 torture_comment(tctx
, "try open for generic write\n");
531 io
.ntcreatex
.in
.access_mask
= SEC_GENERIC_WRITE
;
532 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
533 CHECK_STATUS(status
, NT_STATUS_OK
);
534 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
535 SEC_RIGHTS_FILE_WRITE
| SEC_FILE_READ_ATTRIBUTE
);
536 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
538 torture_comment(tctx
, "try open for generic read\n");
539 io
.ntcreatex
.in
.access_mask
= SEC_GENERIC_READ
;
540 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
541 CHECK_STATUS(status
, NT_STATUS_OK
);
542 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
543 SEC_RIGHTS_FILE_READ
| SEC_FILE_READ_ATTRIBUTE
);
544 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
546 torture_comment(tctx
, "set DACL with 0 aces\n");
548 dacl
.revision
= SECURITY_ACL_REVISION_NT4
;
552 s
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
553 s
.set_secdesc
.in
.file
.fnum
= fnum
;
554 s
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
555 s
.set_secdesc
.in
.sd
= sd
;
556 status
= smb_raw_setfileinfo(cli
->tree
, &s
);
557 CHECK_STATUS(status
, NT_STATUS_OK
);
559 torture_comment(tctx
, "get the sd\n");
560 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
561 q
.query_secdesc
.in
.file
.fnum
= fnum
;
562 q
.query_secdesc
.in
.secinfo_flags
=
566 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
567 CHECK_STATUS(status
, NT_STATUS_OK
);
569 /* Testing the modified DACL */
570 if (!(q
.query_secdesc
.out
.sd
->type
& SEC_DESC_DACL_PRESENT
)) {
572 torture_result(tctx
, TORTURE_FAIL
, "DACL_PRESENT flag not set by the server!\n");
575 if (q
.query_secdesc
.out
.sd
->dacl
== NULL
) {
577 torture_result(tctx
, TORTURE_FAIL
, "no DACL has been created on the server!\n");
580 if (q
.query_secdesc
.out
.sd
->dacl
->num_aces
!= 0) {
582 torture_result(tctx
, TORTURE_FAIL
, "DACL has %u aces!\n",
583 q
.query_secdesc
.out
.sd
->dacl
->num_aces
);
587 torture_comment(tctx
, "try open for read control\n");
588 io
.ntcreatex
.in
.access_mask
= SEC_STD_READ_CONTROL
;
589 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
590 CHECK_STATUS(status
, NT_STATUS_OK
);
591 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
592 SEC_STD_READ_CONTROL
| SEC_FILE_READ_ATTRIBUTE
);
593 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
595 torture_comment(tctx
, "try open for write => access_denied\n");
596 io
.ntcreatex
.in
.access_mask
= SEC_FILE_WRITE_DATA
;
597 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
598 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
600 torture_comment(tctx
, "try open for read => access_denied\n");
601 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_DATA
;
602 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
603 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
605 torture_comment(tctx
, "try open for generic write => access_denied\n");
606 io
.ntcreatex
.in
.access_mask
= SEC_GENERIC_WRITE
;
607 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
608 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
610 torture_comment(tctx
, "try open for generic read => access_denied\n");
611 io
.ntcreatex
.in
.access_mask
= SEC_GENERIC_READ
;
612 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
613 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
615 torture_comment(tctx
, "set empty sd\n");
616 sd
->type
&= ~SEC_DESC_DACL_PRESENT
;
619 s
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
620 s
.set_secdesc
.in
.file
.fnum
= fnum
;
621 s
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
622 s
.set_secdesc
.in
.sd
= sd
;
623 status
= smb_raw_setfileinfo(cli
->tree
, &s
);
624 CHECK_STATUS(status
, NT_STATUS_OK
);
626 torture_comment(tctx
, "get the sd\n");
627 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
628 q
.query_secdesc
.in
.file
.fnum
= fnum
;
629 q
.query_secdesc
.in
.secinfo_flags
=
633 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
634 CHECK_STATUS(status
, NT_STATUS_OK
);
636 /* Testing the modified DACL */
637 if (!(q
.query_secdesc
.out
.sd
->type
& SEC_DESC_DACL_PRESENT
)) {
639 torture_result(tctx
, TORTURE_FAIL
, "DACL_PRESENT flag not set by the server!\n");
642 if (q
.query_secdesc
.out
.sd
->dacl
!= NULL
) {
644 torture_result(tctx
, TORTURE_FAIL
, "DACL has been created on the server!\n");
648 smbcli_close(cli
->tree
, fnum
);
649 smb_raw_exit(cli
->session
);
650 smbcli_deltree(cli
->tree
, BASEDIR
);
655 test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
657 Test copied to smb2/acls.c for SMB2.
659 static bool test_creator_sid(struct torture_context
*tctx
,
660 struct smbcli_state
*cli
)
664 const char *fname
= BASEDIR
"\\creator.txt";
667 union smb_fileinfo q
;
668 union smb_setfileinfo set
;
669 struct security_descriptor
*sd
, *sd_orig
, *sd2
;
670 const char *owner_sid
;
672 if (!torture_setup_dir(cli
, BASEDIR
))
675 torture_comment(tctx
, "TESTING SID_CREATOR_OWNER\n");
677 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
678 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
679 io
.ntcreatex
.in
.flags
= 0;
680 io
.ntcreatex
.in
.access_mask
= SEC_STD_READ_CONTROL
| SEC_STD_WRITE_DAC
| SEC_STD_WRITE_OWNER
;
681 io
.ntcreatex
.in
.create_options
= 0;
682 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
683 io
.ntcreatex
.in
.share_access
=
684 NTCREATEX_SHARE_ACCESS_READ
|
685 NTCREATEX_SHARE_ACCESS_WRITE
;
686 io
.ntcreatex
.in
.alloc_size
= 0;
687 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
688 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
689 io
.ntcreatex
.in
.security_flags
= 0;
690 io
.ntcreatex
.in
.fname
= fname
;
691 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
692 CHECK_STATUS(status
, NT_STATUS_OK
);
693 fnum
= io
.ntcreatex
.out
.file
.fnum
;
695 torture_comment(tctx
, "get the original sd\n");
696 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
697 q
.query_secdesc
.in
.file
.fnum
= fnum
;
698 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
699 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
700 CHECK_STATUS(status
, NT_STATUS_OK
);
701 sd_orig
= q
.query_secdesc
.out
.sd
;
703 owner_sid
= dom_sid_string(tctx
, sd_orig
->owner_sid
);
705 torture_comment(tctx
, "set a sec desc allowing no write by CREATOR_OWNER\n");
706 sd
= security_descriptor_dacl_create(tctx
,
709 SEC_ACE_TYPE_ACCESS_ALLOWED
,
710 SEC_RIGHTS_FILE_READ
| SEC_STD_ALL
,
714 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
715 set
.set_secdesc
.in
.file
.fnum
= fnum
;
716 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
717 set
.set_secdesc
.in
.sd
= sd
;
719 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
720 CHECK_STATUS(status
, NT_STATUS_OK
);
722 torture_comment(tctx
, "try open for write\n");
723 io
.ntcreatex
.in
.access_mask
= SEC_FILE_WRITE_DATA
;
724 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
725 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
727 torture_comment(tctx
, "try open for read\n");
728 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_DATA
;
729 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
730 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
732 torture_comment(tctx
, "try open for generic write\n");
733 io
.ntcreatex
.in
.access_mask
= SEC_GENERIC_WRITE
;
734 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
735 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
737 torture_comment(tctx
, "try open for generic read\n");
738 io
.ntcreatex
.in
.access_mask
= SEC_GENERIC_READ
;
739 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
740 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
742 torture_comment(tctx
, "set a sec desc allowing no write by owner\n");
743 sd
= security_descriptor_dacl_create(tctx
,
746 SEC_ACE_TYPE_ACCESS_ALLOWED
,
747 SEC_RIGHTS_FILE_READ
| SEC_STD_ALL
,
751 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
752 set
.set_secdesc
.in
.file
.fnum
= fnum
;
753 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
754 set
.set_secdesc
.in
.sd
= sd
;
755 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
756 CHECK_STATUS(status
, NT_STATUS_OK
);
758 torture_comment(tctx
, "check that sd has been mapped correctly\n");
759 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
760 CHECK_STATUS(status
, NT_STATUS_OK
);
761 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd
);
763 torture_comment(tctx
, "try open for write\n");
764 io
.ntcreatex
.in
.access_mask
= SEC_FILE_WRITE_DATA
;
765 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
766 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
768 torture_comment(tctx
, "try open for read\n");
769 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_DATA
;
770 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
771 CHECK_STATUS(status
, NT_STATUS_OK
);
772 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
774 SEC_FILE_READ_ATTRIBUTE
);
775 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
777 torture_comment(tctx
, "try open for generic write\n");
778 io
.ntcreatex
.in
.access_mask
= SEC_GENERIC_WRITE
;
779 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
780 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
782 torture_comment(tctx
, "try open for generic read\n");
783 io
.ntcreatex
.in
.access_mask
= SEC_GENERIC_READ
;
784 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
785 CHECK_STATUS(status
, NT_STATUS_OK
);
786 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
787 SEC_RIGHTS_FILE_READ
);
788 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
790 torture_comment(tctx
, "set a sec desc allowing generic read by owner\n");
791 sd
= security_descriptor_dacl_create(tctx
,
794 SEC_ACE_TYPE_ACCESS_ALLOWED
,
795 SEC_GENERIC_READ
| SEC_STD_ALL
,
799 set
.set_secdesc
.in
.sd
= sd
;
800 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
801 CHECK_STATUS(status
, NT_STATUS_OK
);
803 torture_comment(tctx
, "check that generic read has been mapped correctly\n");
804 sd2
= security_descriptor_dacl_create(tctx
,
807 SEC_ACE_TYPE_ACCESS_ALLOWED
,
808 SEC_RIGHTS_FILE_READ
| SEC_STD_ALL
,
812 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
813 CHECK_STATUS(status
, NT_STATUS_OK
);
814 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd2
);
816 torture_comment(tctx
, "try open for write\n");
817 io
.ntcreatex
.in
.access_mask
= SEC_FILE_WRITE_DATA
;
818 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
819 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
821 torture_comment(tctx
, "try open for read\n");
822 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_DATA
;
823 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
824 CHECK_STATUS(status
, NT_STATUS_OK
);
825 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
827 SEC_FILE_READ_ATTRIBUTE
);
828 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
830 torture_comment(tctx
, "try open for generic write\n");
831 io
.ntcreatex
.in
.access_mask
= SEC_GENERIC_WRITE
;
832 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
833 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
835 torture_comment(tctx
, "try open for generic read\n");
836 io
.ntcreatex
.in
.access_mask
= SEC_GENERIC_READ
;
837 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
838 CHECK_STATUS(status
, NT_STATUS_OK
);
839 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
, SEC_RIGHTS_FILE_READ
);
840 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
843 torture_comment(tctx
, "put back original sd\n");
844 set
.set_secdesc
.in
.sd
= sd_orig
;
845 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
846 CHECK_STATUS(status
, NT_STATUS_OK
);
850 smbcli_close(cli
->tree
, fnum
);
851 smb_raw_exit(cli
->session
);
852 smbcli_deltree(cli
->tree
, BASEDIR
);
858 test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
860 Test copied to smb2/acls.c for SMB2.
862 static bool test_generic_bits(struct torture_context
*tctx
,
863 struct smbcli_state
*cli
)
867 const char *fname
= BASEDIR
"\\generic.txt";
870 union smb_fileinfo q
;
871 union smb_setfileinfo set
;
872 struct security_descriptor
*sd
, *sd_orig
, *sd2
;
873 const char *owner_sid
;
876 uint32_t specific_bits
;
877 } file_mappings
[] = {
879 { SEC_GENERIC_READ
, SEC_RIGHTS_FILE_READ
},
880 { SEC_GENERIC_WRITE
, SEC_RIGHTS_FILE_WRITE
},
881 { SEC_GENERIC_EXECUTE
, SEC_RIGHTS_FILE_EXECUTE
},
882 { SEC_GENERIC_ALL
, SEC_RIGHTS_FILE_ALL
},
883 { SEC_FILE_READ_DATA
, SEC_FILE_READ_DATA
},
884 { SEC_FILE_READ_ATTRIBUTE
, SEC_FILE_READ_ATTRIBUTE
}
888 uint32_t specific_bits
;
891 { SEC_GENERIC_READ
, SEC_RIGHTS_DIR_READ
},
892 { SEC_GENERIC_WRITE
, SEC_RIGHTS_DIR_WRITE
},
893 { SEC_GENERIC_EXECUTE
, SEC_RIGHTS_DIR_EXECUTE
},
894 { SEC_GENERIC_ALL
, SEC_RIGHTS_DIR_ALL
}
896 bool has_restore_privilege
;
897 bool has_take_ownership_privilege
;
899 if (!torture_setup_dir(cli
, BASEDIR
))
902 torture_comment(tctx
, "TESTING FILE GENERIC BITS\n");
904 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
905 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
906 io
.ntcreatex
.in
.flags
= 0;
907 io
.ntcreatex
.in
.access_mask
=
908 SEC_STD_READ_CONTROL
|
911 io
.ntcreatex
.in
.create_options
= 0;
912 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
913 io
.ntcreatex
.in
.share_access
=
914 NTCREATEX_SHARE_ACCESS_READ
|
915 NTCREATEX_SHARE_ACCESS_WRITE
;
916 io
.ntcreatex
.in
.alloc_size
= 0;
917 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
918 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
919 io
.ntcreatex
.in
.security_flags
= 0;
920 io
.ntcreatex
.in
.fname
= fname
;
921 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
922 CHECK_STATUS(status
, NT_STATUS_OK
);
923 fnum
= io
.ntcreatex
.out
.file
.fnum
;
925 torture_comment(tctx
, "get the original sd\n");
926 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
927 q
.query_secdesc
.in
.file
.fnum
= fnum
;
928 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
929 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
930 CHECK_STATUS(status
, NT_STATUS_OK
);
931 sd_orig
= q
.query_secdesc
.out
.sd
;
933 owner_sid
= dom_sid_string(tctx
, sd_orig
->owner_sid
);
935 status
= torture_check_privilege(cli
,
937 sec_privilege_name(SEC_PRIV_RESTORE
));
938 has_restore_privilege
= NT_STATUS_IS_OK(status
);
939 if (!NT_STATUS_IS_OK(status
)) {
940 torture_warning(tctx
, "torture_check_privilege - %s\n",
943 torture_comment(tctx
, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege
?"Yes":"No");
945 status
= torture_check_privilege(cli
,
947 sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP
));
948 has_take_ownership_privilege
= NT_STATUS_IS_OK(status
);
949 if (!NT_STATUS_IS_OK(status
)) {
950 torture_warning(tctx
, "torture_check_privilege - %s\n",
953 torture_comment(tctx
, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege
?"Yes":"No");
955 for (i
=0;i
<ARRAY_SIZE(file_mappings
);i
++) {
956 uint32_t expected_mask
=
958 SEC_STD_READ_CONTROL
|
959 SEC_FILE_READ_ATTRIBUTE
|
961 uint32_t expected_mask_anon
= SEC_FILE_READ_ATTRIBUTE
;
963 if (has_restore_privilege
) {
964 expected_mask_anon
|= SEC_STD_DELETE
;
967 torture_comment(tctx
, "Testing generic bits 0x%08x\n",
968 file_mappings
[i
].gen_bits
);
969 sd
= security_descriptor_dacl_create(tctx
,
972 SEC_ACE_TYPE_ACCESS_ALLOWED
,
973 file_mappings
[i
].gen_bits
,
977 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
978 set
.set_secdesc
.in
.file
.fnum
= fnum
;
979 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
980 set
.set_secdesc
.in
.sd
= sd
;
982 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
983 CHECK_STATUS(status
, NT_STATUS_OK
);
985 sd2
= security_descriptor_dacl_create(tctx
,
988 SEC_ACE_TYPE_ACCESS_ALLOWED
,
989 file_mappings
[i
].specific_bits
,
993 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
994 CHECK_STATUS(status
, NT_STATUS_OK
);
995 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd2
);
997 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
998 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
999 CHECK_STATUS(status
, NT_STATUS_OK
);
1000 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
1001 expected_mask
| file_mappings
[i
].specific_bits
);
1002 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
1004 if (!has_take_ownership_privilege
) {
1008 torture_comment(tctx
, "Testing generic bits 0x%08x (anonymous)\n",
1009 file_mappings
[i
].gen_bits
);
1010 sd
= security_descriptor_dacl_create(tctx
,
1011 0, SID_NT_ANONYMOUS
, NULL
,
1013 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1014 file_mappings
[i
].gen_bits
,
1018 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
1019 set
.set_secdesc
.in
.file
.fnum
= fnum
;
1020 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
1021 set
.set_secdesc
.in
.sd
= sd
;
1023 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1024 CHECK_STATUS(status
, NT_STATUS_OK
);
1026 sd2
= security_descriptor_dacl_create(tctx
,
1027 0, SID_NT_ANONYMOUS
, NULL
,
1029 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1030 file_mappings
[i
].specific_bits
,
1034 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1035 CHECK_STATUS(status
, NT_STATUS_OK
);
1036 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd2
);
1038 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1039 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1040 CHECK_STATUS(status
, NT_STATUS_OK
);
1041 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
1042 expected_mask_anon
| file_mappings
[i
].specific_bits
);
1043 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
1046 torture_comment(tctx
, "put back original sd\n");
1047 set
.set_secdesc
.in
.sd
= sd_orig
;
1048 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1049 CHECK_STATUS(status
, NT_STATUS_OK
);
1051 smbcli_close(cli
->tree
, fnum
);
1052 smbcli_unlink(cli
->tree
, fname
);
1055 torture_comment(tctx
, "TESTING DIR GENERIC BITS\n");
1057 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1058 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1059 io
.ntcreatex
.in
.flags
= 0;
1060 io
.ntcreatex
.in
.access_mask
=
1061 SEC_STD_READ_CONTROL
|
1063 SEC_STD_WRITE_OWNER
;
1064 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
1065 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_DIRECTORY
;
1066 io
.ntcreatex
.in
.share_access
=
1067 NTCREATEX_SHARE_ACCESS_READ
|
1068 NTCREATEX_SHARE_ACCESS_WRITE
;
1069 io
.ntcreatex
.in
.alloc_size
= 0;
1070 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1071 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1072 io
.ntcreatex
.in
.security_flags
= 0;
1073 io
.ntcreatex
.in
.fname
= fname
;
1074 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1075 CHECK_STATUS(status
, NT_STATUS_OK
);
1076 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1078 torture_comment(tctx
, "get the original sd\n");
1079 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
1080 q
.query_secdesc
.in
.file
.fnum
= fnum
;
1081 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
1082 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1083 CHECK_STATUS(status
, NT_STATUS_OK
);
1084 sd_orig
= q
.query_secdesc
.out
.sd
;
1086 owner_sid
= dom_sid_string(tctx
, sd_orig
->owner_sid
);
1088 status
= torture_check_privilege(cli
,
1090 sec_privilege_name(SEC_PRIV_RESTORE
));
1091 has_restore_privilege
= NT_STATUS_IS_OK(status
);
1092 if (!NT_STATUS_IS_OK(status
)) {
1093 torture_warning(tctx
, "torture_check_privilege - %s\n",
1096 torture_comment(tctx
, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege
?"Yes":"No");
1098 status
= torture_check_privilege(cli
,
1100 sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP
));
1101 has_take_ownership_privilege
= NT_STATUS_IS_OK(status
);
1102 if (!NT_STATUS_IS_OK(status
)) {
1103 torture_warning(tctx
, "torture_check_privilege - %s\n",
1106 torture_comment(tctx
, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege
?"Yes":"No");
1108 for (i
=0;i
<ARRAY_SIZE(dir_mappings
);i
++) {
1109 uint32_t expected_mask
=
1111 SEC_STD_READ_CONTROL
|
1112 SEC_FILE_READ_ATTRIBUTE
|
1114 uint32_t expected_mask_anon
= SEC_FILE_READ_ATTRIBUTE
;
1116 if (has_restore_privilege
) {
1117 expected_mask_anon
|= SEC_STD_DELETE
;
1120 torture_comment(tctx
, "Testing generic bits 0x%08x\n",
1121 file_mappings
[i
].gen_bits
);
1122 sd
= security_descriptor_dacl_create(tctx
,
1125 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1126 dir_mappings
[i
].gen_bits
,
1130 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
1131 set
.set_secdesc
.in
.file
.fnum
= fnum
;
1132 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
1133 set
.set_secdesc
.in
.sd
= sd
;
1135 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1136 CHECK_STATUS(status
, NT_STATUS_OK
);
1138 sd2
= security_descriptor_dacl_create(tctx
,
1141 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1142 dir_mappings
[i
].specific_bits
,
1146 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1147 CHECK_STATUS(status
, NT_STATUS_OK
);
1148 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd2
);
1150 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1151 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1152 CHECK_STATUS(status
, NT_STATUS_OK
);
1153 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
1154 expected_mask
| dir_mappings
[i
].specific_bits
);
1155 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
1157 if (!has_take_ownership_privilege
) {
1161 torture_comment(tctx
, "Testing generic bits 0x%08x (anonymous)\n",
1162 file_mappings
[i
].gen_bits
);
1163 sd
= security_descriptor_dacl_create(tctx
,
1164 0, SID_NT_ANONYMOUS
, NULL
,
1166 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1167 file_mappings
[i
].gen_bits
,
1171 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
1172 set
.set_secdesc
.in
.file
.fnum
= fnum
;
1173 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
1174 set
.set_secdesc
.in
.sd
= sd
;
1176 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1177 CHECK_STATUS(status
, NT_STATUS_OK
);
1179 sd2
= security_descriptor_dacl_create(tctx
,
1180 0, SID_NT_ANONYMOUS
, NULL
,
1182 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1183 file_mappings
[i
].specific_bits
,
1187 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1188 CHECK_STATUS(status
, NT_STATUS_OK
);
1189 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd2
);
1191 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1192 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1193 CHECK_STATUS(status
, NT_STATUS_OK
);
1194 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
,
1195 expected_mask_anon
| dir_mappings
[i
].specific_bits
);
1196 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
1199 torture_comment(tctx
, "put back original sd\n");
1200 set
.set_secdesc
.in
.sd
= sd_orig
;
1201 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1202 CHECK_STATUS(status
, NT_STATUS_OK
);
1204 smbcli_close(cli
->tree
, fnum
);
1205 smbcli_unlink(cli
->tree
, fname
);
1208 smbcli_close(cli
->tree
, fnum
);
1209 smb_raw_exit(cli
->session
);
1210 smbcli_deltree(cli
->tree
, BASEDIR
);
1216 see what access bits the owner of a file always gets
1217 Test copied to smb2/acls.c for SMB2.
1219 static bool test_owner_bits(struct torture_context
*tctx
,
1220 struct smbcli_state
*cli
)
1224 const char *fname
= BASEDIR
"\\test_owner_bits.txt";
1227 union smb_fileinfo q
;
1228 union smb_setfileinfo set
;
1229 struct security_descriptor
*sd
, *sd_orig
;
1230 const char *owner_sid
;
1231 bool has_restore_privilege
;
1232 bool has_take_ownership_privilege
;
1233 uint32_t expected_bits
;
1235 if (!torture_setup_dir(cli
, BASEDIR
))
1238 torture_comment(tctx
, "TESTING FILE OWNER BITS\n");
1240 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1241 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1242 io
.ntcreatex
.in
.flags
= 0;
1243 io
.ntcreatex
.in
.access_mask
=
1244 SEC_STD_READ_CONTROL
|
1246 SEC_STD_WRITE_OWNER
;
1247 io
.ntcreatex
.in
.create_options
= 0;
1248 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
1249 io
.ntcreatex
.in
.share_access
=
1250 NTCREATEX_SHARE_ACCESS_READ
|
1251 NTCREATEX_SHARE_ACCESS_WRITE
;
1252 io
.ntcreatex
.in
.alloc_size
= 0;
1253 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN_IF
;
1254 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1255 io
.ntcreatex
.in
.security_flags
= 0;
1256 io
.ntcreatex
.in
.fname
= fname
;
1257 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1258 CHECK_STATUS(status
, NT_STATUS_OK
);
1259 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1261 torture_comment(tctx
, "get the original sd\n");
1262 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
1263 q
.query_secdesc
.in
.file
.fnum
= fnum
;
1264 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
1265 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1266 CHECK_STATUS(status
, NT_STATUS_OK
);
1267 sd_orig
= q
.query_secdesc
.out
.sd
;
1269 owner_sid
= dom_sid_string(tctx
, sd_orig
->owner_sid
);
1271 status
= torture_check_privilege(cli
,
1273 sec_privilege_name(SEC_PRIV_RESTORE
));
1274 has_restore_privilege
= NT_STATUS_IS_OK(status
);
1275 if (!NT_STATUS_IS_OK(status
)) {
1276 torture_warning(tctx
, "torture_check_privilege - %s\n", nt_errstr(status
));
1278 torture_comment(tctx
, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege
?"Yes":"No");
1280 status
= torture_check_privilege(cli
,
1282 sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP
));
1283 has_take_ownership_privilege
= NT_STATUS_IS_OK(status
);
1284 if (!NT_STATUS_IS_OK(status
)) {
1285 torture_warning(tctx
, "torture_check_privilege - %s\n", nt_errstr(status
));
1287 torture_comment(tctx
, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege
?"Yes":"No");
1289 sd
= security_descriptor_dacl_create(tctx
,
1292 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1293 SEC_FILE_WRITE_DATA
,
1297 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
1298 set
.set_secdesc
.in
.file
.fnum
= fnum
;
1299 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
1300 set
.set_secdesc
.in
.sd
= sd
;
1302 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1303 CHECK_STATUS(status
, NT_STATUS_OK
);
1305 expected_bits
= SEC_FILE_WRITE_DATA
| SEC_FILE_READ_ATTRIBUTE
;
1307 for (i
=0;i
<16;i
++) {
1308 uint32_t bit
= (1<<i
);
1309 io
.ntcreatex
.in
.access_mask
= bit
;
1310 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1311 if (expected_bits
& bit
) {
1312 if (!NT_STATUS_IS_OK(status
)) {
1313 torture_warning(tctx
, "failed with access mask 0x%08x of expected 0x%08x\n",
1314 bit
, expected_bits
);
1316 CHECK_STATUS(status
, NT_STATUS_OK
);
1317 CHECK_ACCESS_FLAGS(io
.ntcreatex
.out
.file
.fnum
, bit
| SEC_FILE_READ_ATTRIBUTE
);
1318 smbcli_close(cli
->tree
, io
.ntcreatex
.out
.file
.fnum
);
1320 if (NT_STATUS_IS_OK(status
)) {
1321 torture_warning(tctx
, "open succeeded with access mask 0x%08x of "
1322 "expected 0x%08x - should fail\n",
1323 bit
, expected_bits
);
1325 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
1329 torture_comment(tctx
, "put back original sd\n");
1330 set
.set_secdesc
.in
.sd
= sd_orig
;
1331 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1332 CHECK_STATUS(status
, NT_STATUS_OK
);
1335 smbcli_close(cli
->tree
, fnum
);
1336 smbcli_unlink(cli
->tree
, fname
);
1337 smb_raw_exit(cli
->session
);
1338 smbcli_deltree(cli
->tree
, BASEDIR
);
1345 test the inheritance of ACL flags onto new files and directories
1346 Test copied to smb2/acls.c for SMB2.
1348 static bool test_inheritance(struct torture_context
*tctx
,
1349 struct smbcli_state
*cli
)
1353 const char *dname
= BASEDIR
"\\inheritance";
1354 const char *fname1
= BASEDIR
"\\inheritance\\testfile";
1355 const char *fname2
= BASEDIR
"\\inheritance\\testdir";
1357 int fnum
=0, fnum2
, i
;
1358 union smb_fileinfo q
;
1359 union smb_setfileinfo set
;
1360 struct security_descriptor
*sd
, *sd2
, *sd_orig
=NULL
, *sd_def1
, *sd_def2
;
1361 const char *owner_sid
, *group_sid
;
1362 const struct dom_sid
*creator_owner
;
1364 uint32_t parent_flags
;
1365 uint32_t file_flags
;
1374 SEC_ACE_FLAG_OBJECT_INHERIT
,
1376 SEC_ACE_FLAG_OBJECT_INHERIT
|
1377 SEC_ACE_FLAG_INHERIT_ONLY
,
1380 SEC_ACE_FLAG_CONTAINER_INHERIT
,
1382 SEC_ACE_FLAG_CONTAINER_INHERIT
,
1385 SEC_ACE_FLAG_OBJECT_INHERIT
|
1386 SEC_ACE_FLAG_CONTAINER_INHERIT
,
1388 SEC_ACE_FLAG_OBJECT_INHERIT
|
1389 SEC_ACE_FLAG_CONTAINER_INHERIT
,
1392 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
,
1397 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
|
1398 SEC_ACE_FLAG_OBJECT_INHERIT
,
1403 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
|
1404 SEC_ACE_FLAG_CONTAINER_INHERIT
,
1409 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
|
1410 SEC_ACE_FLAG_CONTAINER_INHERIT
|
1411 SEC_ACE_FLAG_OBJECT_INHERIT
,
1416 SEC_ACE_FLAG_INHERIT_ONLY
,
1421 SEC_ACE_FLAG_INHERIT_ONLY
|
1422 SEC_ACE_FLAG_OBJECT_INHERIT
,
1424 SEC_ACE_FLAG_OBJECT_INHERIT
|
1425 SEC_ACE_FLAG_INHERIT_ONLY
,
1428 SEC_ACE_FLAG_INHERIT_ONLY
|
1429 SEC_ACE_FLAG_CONTAINER_INHERIT
,
1431 SEC_ACE_FLAG_CONTAINER_INHERIT
,
1434 SEC_ACE_FLAG_INHERIT_ONLY
|
1435 SEC_ACE_FLAG_CONTAINER_INHERIT
|
1436 SEC_ACE_FLAG_OBJECT_INHERIT
,
1438 SEC_ACE_FLAG_CONTAINER_INHERIT
|
1439 SEC_ACE_FLAG_OBJECT_INHERIT
,
1442 SEC_ACE_FLAG_INHERIT_ONLY
|
1443 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
,
1448 SEC_ACE_FLAG_INHERIT_ONLY
|
1449 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
|
1450 SEC_ACE_FLAG_OBJECT_INHERIT
,
1455 SEC_ACE_FLAG_INHERIT_ONLY
|
1456 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
|
1457 SEC_ACE_FLAG_CONTAINER_INHERIT
,
1462 SEC_ACE_FLAG_INHERIT_ONLY
|
1463 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
|
1464 SEC_ACE_FLAG_CONTAINER_INHERIT
|
1465 SEC_ACE_FLAG_OBJECT_INHERIT
,
1471 if (!torture_setup_dir(cli
, BASEDIR
))
1474 torture_comment(tctx
, "TESTING ACL INHERITANCE\n");
1476 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1477 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1478 io
.ntcreatex
.in
.flags
= 0;
1479 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1480 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
1481 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_DIRECTORY
;
1482 io
.ntcreatex
.in
.share_access
= 0;
1483 io
.ntcreatex
.in
.alloc_size
= 0;
1484 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1485 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1486 io
.ntcreatex
.in
.security_flags
= 0;
1487 io
.ntcreatex
.in
.fname
= dname
;
1489 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1490 CHECK_STATUS(status
, NT_STATUS_OK
);
1491 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1493 torture_comment(tctx
, "get the original sd\n");
1494 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
1495 q
.query_secdesc
.in
.file
.fnum
= fnum
;
1496 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
| SECINFO_GROUP
;
1497 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1498 CHECK_STATUS(status
, NT_STATUS_OK
);
1499 sd_orig
= q
.query_secdesc
.out
.sd
;
1501 owner_sid
= dom_sid_string(tctx
, sd_orig
->owner_sid
);
1502 group_sid
= dom_sid_string(tctx
, sd_orig
->group_sid
);
1504 torture_comment(tctx
, "owner_sid is %s\n", owner_sid
);
1505 torture_comment(tctx
, "group_sid is %s\n", group_sid
);
1507 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
1509 if (torture_setting_bool(tctx
, "samba4", false)) {
1510 /* the default ACL in Samba4 includes the group and
1511 other permissions */
1512 sd_def1
= security_descriptor_dacl_create(tctx
,
1515 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1516 SEC_RIGHTS_FILE_ALL
,
1519 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1520 SEC_RIGHTS_FILE_READ
| SEC_FILE_EXECUTE
,
1523 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1524 SEC_RIGHTS_FILE_READ
| SEC_FILE_EXECUTE
,
1527 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1528 SEC_RIGHTS_FILE_ALL
,
1533 * The Windows Default ACL for a new file, when there is no ACL to be
1534 * inherited: FullControl for the owner and SYSTEM.
1536 sd_def1
= security_descriptor_dacl_create(tctx
,
1539 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1540 SEC_RIGHTS_FILE_ALL
,
1543 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1544 SEC_RIGHTS_FILE_ALL
,
1550 * Use this in the case the system being tested does not add an ACE for
1553 sd_def2
= security_descriptor_dacl_create(tctx
,
1556 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1557 SEC_RIGHTS_FILE_ALL
,
1561 creator_owner
= dom_sid_parse_talloc(tctx
, SID_CREATOR_OWNER
);
1563 for (i
=0;i
<ARRAY_SIZE(test_flags
);i
++) {
1564 sd
= security_descriptor_dacl_create(tctx
,
1567 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1568 SEC_FILE_WRITE_DATA
,
1569 test_flags
[i
].parent_flags
,
1571 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1572 SEC_FILE_ALL
| SEC_STD_ALL
,
1575 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
1576 set
.set_secdesc
.in
.file
.fnum
= fnum
;
1577 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
1578 set
.set_secdesc
.in
.sd
= sd
;
1579 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1580 CHECK_STATUS(status
, NT_STATUS_OK
);
1582 io
.ntcreatex
.in
.fname
= fname1
;
1583 io
.ntcreatex
.in
.create_options
= 0;
1584 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1585 CHECK_STATUS(status
, NT_STATUS_OK
);
1586 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1588 q
.query_secdesc
.in
.file
.fnum
= fnum2
;
1589 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1590 CHECK_STATUS(status
, NT_STATUS_OK
);
1592 smbcli_close(cli
->tree
, fnum2
);
1593 smbcli_unlink(cli
->tree
, fname1
);
1595 if (!(test_flags
[i
].parent_flags
& SEC_ACE_FLAG_OBJECT_INHERIT
)) {
1596 if (!security_descriptor_equal(q
.query_secdesc
.out
.sd
, sd_def1
) &&
1597 !security_descriptor_equal(q
.query_secdesc
.out
.sd
, sd_def2
)) {
1598 torture_warning(tctx
, "Expected default sd "
1600 NDR_PRINT_DEBUG(security_descriptor
, sd_def1
);
1601 torture_warning(tctx
, "at %d - got:\n", i
);
1602 NDR_PRINT_DEBUG(security_descriptor
, q
.query_secdesc
.out
.sd
);
1607 if (q
.query_secdesc
.out
.sd
->dacl
== NULL
||
1608 q
.query_secdesc
.out
.sd
->dacl
->num_aces
!= 1 ||
1609 q
.query_secdesc
.out
.sd
->dacl
->aces
[0].access_mask
!= SEC_FILE_WRITE_DATA
||
1610 !dom_sid_equal(&q
.query_secdesc
.out
.sd
->dacl
->aces
[0].trustee
,
1611 sd_orig
->owner_sid
)) {
1613 torture_warning(tctx
, "Bad sd in child file at %d\n", i
);
1614 NDR_PRINT_DEBUG(security_descriptor
, q
.query_secdesc
.out
.sd
);
1618 if (q
.query_secdesc
.out
.sd
->dacl
->aces
[0].flags
!=
1619 test_flags
[i
].file_flags
) {
1620 torture_warning(tctx
, "incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
1621 q
.query_secdesc
.out
.sd
->dacl
->aces
[0].flags
,
1622 test_flags
[i
].file_flags
,
1623 test_flags
[i
].parent_flags
,
1629 io
.ntcreatex
.in
.fname
= fname2
;
1630 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
1631 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1632 CHECK_STATUS(status
, NT_STATUS_OK
);
1633 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1635 q
.query_secdesc
.in
.file
.fnum
= fnum2
;
1636 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1637 CHECK_STATUS(status
, NT_STATUS_OK
);
1639 smbcli_close(cli
->tree
, fnum2
);
1640 smbcli_rmdir(cli
->tree
, fname2
);
1642 if (!(test_flags
[i
].parent_flags
& SEC_ACE_FLAG_CONTAINER_INHERIT
) &&
1643 (!(test_flags
[i
].parent_flags
& SEC_ACE_FLAG_OBJECT_INHERIT
) ||
1644 (test_flags
[i
].parent_flags
& SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
))) {
1645 if (!security_descriptor_equal(q
.query_secdesc
.out
.sd
, sd_def1
) &&
1646 !security_descriptor_equal(q
.query_secdesc
.out
.sd
, sd_def2
)) {
1647 torture_warning(tctx
, "Expected default sd for dir at %d:\n", i
);
1648 NDR_PRINT_DEBUG(security_descriptor
, sd_def1
);
1649 torture_warning(tctx
, "got:\n");
1650 NDR_PRINT_DEBUG(security_descriptor
, q
.query_secdesc
.out
.sd
);
1655 if ((test_flags
[i
].parent_flags
& SEC_ACE_FLAG_CONTAINER_INHERIT
) &&
1656 (test_flags
[i
].parent_flags
& SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
)) {
1657 if (q
.query_secdesc
.out
.sd
->dacl
== NULL
||
1658 q
.query_secdesc
.out
.sd
->dacl
->num_aces
!= 1 ||
1659 q
.query_secdesc
.out
.sd
->dacl
->aces
[0].access_mask
!= SEC_FILE_WRITE_DATA
||
1660 !dom_sid_equal(&q
.query_secdesc
.out
.sd
->dacl
->aces
[0].trustee
,
1661 sd_orig
->owner_sid
) ||
1662 q
.query_secdesc
.out
.sd
->dacl
->aces
[0].flags
!= test_flags
[i
].dir_flags
) {
1663 torture_warning(tctx
, "(CI & NP) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1664 test_flags
[i
].dir_flags
,
1665 test_flags
[i
].parent_flags
, i
);
1666 NDR_PRINT_DEBUG(security_descriptor
, q
.query_secdesc
.out
.sd
);
1667 torture_comment(tctx
, "FYI, here is the parent sd:\n");
1668 NDR_PRINT_DEBUG(security_descriptor
, sd
);
1672 } else if (test_flags
[i
].parent_flags
& SEC_ACE_FLAG_CONTAINER_INHERIT
) {
1673 if (q
.query_secdesc
.out
.sd
->dacl
== NULL
||
1674 q
.query_secdesc
.out
.sd
->dacl
->num_aces
!= 2 ||
1675 q
.query_secdesc
.out
.sd
->dacl
->aces
[0].access_mask
!= SEC_FILE_WRITE_DATA
||
1676 !dom_sid_equal(&q
.query_secdesc
.out
.sd
->dacl
->aces
[0].trustee
,
1677 sd_orig
->owner_sid
) ||
1678 q
.query_secdesc
.out
.sd
->dacl
->aces
[1].access_mask
!= SEC_FILE_WRITE_DATA
||
1679 !dom_sid_equal(&q
.query_secdesc
.out
.sd
->dacl
->aces
[1].trustee
,
1681 q
.query_secdesc
.out
.sd
->dacl
->aces
[0].flags
!= 0 ||
1682 q
.query_secdesc
.out
.sd
->dacl
->aces
[1].flags
!=
1683 (test_flags
[i
].dir_flags
| SEC_ACE_FLAG_INHERIT_ONLY
)) {
1684 torture_warning(tctx
, "(CI) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1685 test_flags
[i
].dir_flags
,
1686 test_flags
[i
].parent_flags
, i
);
1687 NDR_PRINT_DEBUG(security_descriptor
, q
.query_secdesc
.out
.sd
);
1688 torture_comment(tctx
, "FYI, here is the parent sd:\n");
1689 NDR_PRINT_DEBUG(security_descriptor
, sd
);
1694 if (q
.query_secdesc
.out
.sd
->dacl
== NULL
||
1695 q
.query_secdesc
.out
.sd
->dacl
->num_aces
!= 1 ||
1696 q
.query_secdesc
.out
.sd
->dacl
->aces
[0].access_mask
!= SEC_FILE_WRITE_DATA
||
1697 !dom_sid_equal(&q
.query_secdesc
.out
.sd
->dacl
->aces
[0].trustee
,
1699 q
.query_secdesc
.out
.sd
->dacl
->aces
[0].flags
!= test_flags
[i
].dir_flags
) {
1700 torture_warning(tctx
, "(0) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1701 test_flags
[i
].dir_flags
,
1702 test_flags
[i
].parent_flags
, i
);
1703 NDR_PRINT_DEBUG(security_descriptor
, q
.query_secdesc
.out
.sd
);
1704 torture_comment(tctx
, "FYI, here is the parent sd:\n");
1705 NDR_PRINT_DEBUG(security_descriptor
, sd
);
1712 torture_comment(tctx
, "Testing access checks on inherited create with %s\n", fname1
);
1713 sd
= security_descriptor_dacl_create(tctx
,
1716 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1717 SEC_FILE_WRITE_DATA
| SEC_STD_WRITE_DAC
,
1718 SEC_ACE_FLAG_OBJECT_INHERIT
,
1720 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1721 SEC_FILE_ALL
| SEC_STD_ALL
,
1724 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
1725 set
.set_secdesc
.in
.file
.fnum
= fnum
;
1726 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
1727 set
.set_secdesc
.in
.sd
= sd
;
1728 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1729 CHECK_STATUS(status
, NT_STATUS_OK
);
1731 /* Check DACL we just set. */
1732 torture_comment(tctx
, "checking new sd\n");
1733 q
.query_secdesc
.in
.file
.fnum
= fnum
;
1734 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
1735 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1736 CHECK_STATUS(status
, NT_STATUS_OK
);
1737 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd
);
1739 io
.ntcreatex
.in
.fname
= fname1
;
1740 io
.ntcreatex
.in
.create_options
= 0;
1741 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1742 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1743 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1744 CHECK_STATUS(status
, NT_STATUS_OK
);
1745 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1746 CHECK_ACCESS_FLAGS(fnum2
, SEC_RIGHTS_FILE_ALL
);
1748 q
.query_secdesc
.in
.file
.fnum
= fnum2
;
1749 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
1750 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1751 CHECK_STATUS(status
, NT_STATUS_OK
);
1752 smbcli_close(cli
->tree
, fnum2
);
1754 sd2
= security_descriptor_dacl_create(tctx
,
1757 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1758 SEC_FILE_WRITE_DATA
| SEC_STD_WRITE_DAC
,
1761 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd2
);
1763 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
1764 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1765 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1766 if (NT_STATUS_IS_OK(status
)) {
1767 torture_warning(tctx
, "failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
1769 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1770 CHECK_ACCESS_FLAGS(fnum2
, SEC_RIGHTS_FILE_ALL
);
1771 smbcli_close(cli
->tree
, fnum2
);
1773 if (TARGET_IS_WIN7(tctx
)) {
1774 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1776 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
1780 torture_comment(tctx
, "trying without execute\n");
1781 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
1782 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
& ~SEC_FILE_EXECUTE
;
1783 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1784 if (TARGET_IS_WIN7(tctx
)) {
1785 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1787 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
1790 torture_comment(tctx
, "and with full permissions again\n");
1791 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
1792 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1793 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1794 if (TARGET_IS_WIN7(tctx
)) {
1795 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1797 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
1800 io
.ntcreatex
.in
.access_mask
= SEC_FILE_WRITE_DATA
;
1801 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1802 CHECK_STATUS(status
, NT_STATUS_OK
);
1803 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1804 CHECK_ACCESS_FLAGS(fnum2
, SEC_FILE_WRITE_DATA
| SEC_FILE_READ_ATTRIBUTE
);
1805 smbcli_close(cli
->tree
, fnum2
);
1807 torture_comment(tctx
, "put back original sd\n");
1808 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
1809 set
.set_secdesc
.in
.file
.fnum
= fnum
;
1810 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
1811 set
.set_secdesc
.in
.sd
= sd_orig
;
1812 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1813 CHECK_STATUS(status
, NT_STATUS_OK
);
1815 smbcli_close(cli
->tree
, fnum
);
1817 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1818 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1819 if (TARGET_IS_WIN7(tctx
)) {
1820 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1822 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
1825 io
.ntcreatex
.in
.access_mask
= SEC_FILE_WRITE_DATA
;
1826 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1827 CHECK_STATUS(status
, NT_STATUS_OK
);
1828 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
1829 CHECK_ACCESS_FLAGS(fnum2
, SEC_FILE_WRITE_DATA
| SEC_FILE_READ_ATTRIBUTE
);
1830 smbcli_close(cli
->tree
, fnum2
);
1833 if (sd_orig
!= NULL
) {
1834 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
1835 set
.set_secdesc
.in
.file
.fnum
= fnum
;
1836 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
1837 set
.set_secdesc
.in
.sd
= sd_orig
;
1838 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1841 smbcli_close(cli
->tree
, fnum
);
1842 smbcli_unlink(cli
->tree
, fname1
);
1843 smbcli_rmdir(cli
->tree
, dname
);
1844 smb_raw_exit(cli
->session
);
1845 smbcli_deltree(cli
->tree
, BASEDIR
);
1850 static bool test_inheritance_flags(struct torture_context
*tctx
,
1851 struct smbcli_state
*cli
)
1855 const char *dname
= BASEDIR
"\\inheritance";
1856 const char *fname1
= BASEDIR
"\\inheritance\\testfile";
1858 int fnum
=0, fnum2
, i
, j
;
1859 union smb_fileinfo q
;
1860 union smb_setfileinfo set
;
1861 struct security_descriptor
*sd
, *sd2
, *sd_orig
=NULL
;
1862 const char *owner_sid
;
1864 uint32_t parent_set_sd_type
; /* 3 options */
1865 uint32_t parent_set_ace_inherit
; /* 1 option */
1866 uint32_t parent_get_sd_type
;
1867 uint32_t parent_get_ace_inherit
;
1868 uint32_t child_get_sd_type
;
1869 uint32_t child_get_ace_inherit
;
1870 } tflags
[16]; /* 2^4 */
1872 for (i
= 0; i
< 15; i
++) {
1873 torture_comment(tctx
, "i=%d:", i
);
1875 ZERO_STRUCT(tflags
[i
]);
1878 tflags
[i
].parent_set_sd_type
|=
1879 SEC_DESC_DACL_AUTO_INHERITED
;
1880 torture_comment(tctx
, "AUTO_INHERITED, ");
1883 tflags
[i
].parent_set_sd_type
|=
1884 SEC_DESC_DACL_AUTO_INHERIT_REQ
;
1885 torture_comment(tctx
, "AUTO_INHERIT_REQ, ");
1888 tflags
[i
].parent_set_sd_type
|=
1889 SEC_DESC_DACL_PROTECTED
;
1890 tflags
[i
].parent_get_sd_type
|=
1891 SEC_DESC_DACL_PROTECTED
;
1892 torture_comment(tctx
, "PROTECTED, ");
1895 tflags
[i
].parent_set_ace_inherit
|=
1896 SEC_ACE_FLAG_INHERITED_ACE
;
1897 tflags
[i
].parent_get_ace_inherit
|=
1898 SEC_ACE_FLAG_INHERITED_ACE
;
1899 torture_comment(tctx
, "INHERITED, ");
1902 if ((tflags
[i
].parent_set_sd_type
&
1903 (SEC_DESC_DACL_AUTO_INHERITED
| SEC_DESC_DACL_AUTO_INHERIT_REQ
)) ==
1904 (SEC_DESC_DACL_AUTO_INHERITED
| SEC_DESC_DACL_AUTO_INHERIT_REQ
)) {
1905 tflags
[i
].parent_get_sd_type
|=
1906 SEC_DESC_DACL_AUTO_INHERITED
;
1907 tflags
[i
].child_get_sd_type
|=
1908 SEC_DESC_DACL_AUTO_INHERITED
;
1909 tflags
[i
].child_get_ace_inherit
|=
1910 SEC_ACE_FLAG_INHERITED_ACE
;
1911 torture_comment(tctx
, " ... parent is AUTO INHERITED");
1914 if (tflags
[i
].parent_set_ace_inherit
&
1915 SEC_ACE_FLAG_INHERITED_ACE
) {
1916 tflags
[i
].parent_get_ace_inherit
=
1917 SEC_ACE_FLAG_INHERITED_ACE
;
1918 torture_comment(tctx
, " ... parent ACE is INHERITED");
1921 torture_comment(tctx
, "\n");
1924 if (!torture_setup_dir(cli
, BASEDIR
))
1927 torture_comment(tctx
, "TESTING ACL INHERITANCE FLAGS\n");
1929 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1930 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1931 io
.ntcreatex
.in
.flags
= 0;
1932 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1933 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
1934 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_DIRECTORY
;
1935 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_MASK
;
1936 io
.ntcreatex
.in
.alloc_size
= 0;
1937 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1938 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1939 io
.ntcreatex
.in
.security_flags
= 0;
1940 io
.ntcreatex
.in
.fname
= dname
;
1942 torture_comment(tctx
, "creating initial directory %s\n", dname
);
1943 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
1944 CHECK_STATUS(status
, NT_STATUS_OK
);
1945 fnum
= io
.ntcreatex
.out
.file
.fnum
;
1947 torture_comment(tctx
, "getting original sd\n");
1948 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
1949 q
.query_secdesc
.in
.file
.fnum
= fnum
;
1950 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
1951 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1952 CHECK_STATUS(status
, NT_STATUS_OK
);
1953 sd_orig
= q
.query_secdesc
.out
.sd
;
1955 owner_sid
= dom_sid_string(tctx
, sd_orig
->owner_sid
);
1956 torture_comment(tctx
, "owner_sid is %s\n", owner_sid
);
1958 for (i
=0; i
< ARRAY_SIZE(tflags
); i
++) {
1959 torture_comment(tctx
, "setting a new sd on directory, pass #%d\n", i
);
1961 sd
= security_descriptor_dacl_create(tctx
,
1962 tflags
[i
].parent_set_sd_type
,
1965 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1966 SEC_FILE_WRITE_DATA
| SEC_STD_WRITE_DAC
,
1967 SEC_ACE_FLAG_OBJECT_INHERIT
|
1968 SEC_ACE_FLAG_CONTAINER_INHERIT
|
1969 tflags
[i
].parent_set_ace_inherit
,
1971 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1972 SEC_FILE_ALL
| SEC_STD_ALL
,
1975 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
1976 set
.set_secdesc
.in
.file
.fnum
= fnum
;
1977 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
1978 set
.set_secdesc
.in
.sd
= sd
;
1979 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
1980 CHECK_STATUS(status
, NT_STATUS_OK
);
1983 * Check DACL we just set, except change the bits to what they
1986 torture_comment(tctx
, " checking new sd\n");
1988 /* REQ bit should always be false. */
1989 sd
->type
&= ~SEC_DESC_DACL_AUTO_INHERIT_REQ
;
1991 if ((tflags
[i
].parent_get_sd_type
& SEC_DESC_DACL_AUTO_INHERITED
) == 0)
1992 sd
->type
&= ~SEC_DESC_DACL_AUTO_INHERITED
;
1994 q
.query_secdesc
.in
.file
.fnum
= fnum
;
1995 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
1996 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
1997 CHECK_STATUS(status
, NT_STATUS_OK
);
1998 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd
);
2001 torture_comment(tctx
, " creating file %s\n", fname1
);
2002 io
.ntcreatex
.in
.fname
= fname1
;
2003 io
.ntcreatex
.in
.create_options
= 0;
2004 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2005 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2006 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
2007 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
2008 CHECK_STATUS(status
, NT_STATUS_OK
);
2009 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
2010 CHECK_ACCESS_FLAGS(fnum2
, SEC_RIGHTS_FILE_ALL
);
2012 q
.query_secdesc
.in
.file
.fnum
= fnum2
;
2013 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
2014 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
2015 CHECK_STATUS(status
, NT_STATUS_OK
);
2017 torture_comment(tctx
, " checking sd on file %s\n", fname1
);
2018 sd2
= security_descriptor_dacl_create(tctx
,
2019 tflags
[i
].child_get_sd_type
,
2022 SEC_ACE_TYPE_ACCESS_ALLOWED
,
2023 SEC_FILE_WRITE_DATA
| SEC_STD_WRITE_DAC
,
2024 tflags
[i
].child_get_ace_inherit
,
2026 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd2
);
2029 * Set new sd on file ... prove that the bits have nothing to
2030 * do with the parents bits when manually setting an ACL. The
2031 * _AUTO_INHERITED bit comes directly from the ACL set.
2033 for (j
= 0; j
< ARRAY_SIZE(tflags
); j
++) {
2034 torture_comment(tctx
, " setting new file sd, pass #%d\n", j
);
2036 /* Change sd type. */
2037 sd2
->type
&= ~(SEC_DESC_DACL_AUTO_INHERITED
|
2038 SEC_DESC_DACL_AUTO_INHERIT_REQ
|
2039 SEC_DESC_DACL_PROTECTED
);
2040 sd2
->type
|= tflags
[j
].parent_set_sd_type
;
2042 sd2
->dacl
->aces
[0].flags
&=
2043 ~SEC_ACE_FLAG_INHERITED_ACE
;
2044 sd2
->dacl
->aces
[0].flags
|=
2045 tflags
[j
].parent_set_ace_inherit
;
2047 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
2048 set
.set_secdesc
.in
.file
.fnum
= fnum2
;
2049 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
2050 set
.set_secdesc
.in
.sd
= sd2
;
2051 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
2052 CHECK_STATUS(status
, NT_STATUS_OK
);
2054 /* Check DACL we just set. */
2055 sd2
->type
&= ~SEC_DESC_DACL_AUTO_INHERIT_REQ
;
2056 if ((tflags
[j
].parent_get_sd_type
& SEC_DESC_DACL_AUTO_INHERITED
) == 0)
2057 sd2
->type
&= ~SEC_DESC_DACL_AUTO_INHERITED
;
2059 q
.query_secdesc
.in
.file
.fnum
= fnum2
;
2060 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
2061 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
2062 CHECK_STATUS(status
, NT_STATUS_OK
);
2064 CHECK_SECURITY_DESCRIPTOR(q
.query_secdesc
.out
.sd
, sd2
);
2067 smbcli_close(cli
->tree
, fnum2
);
2068 smbcli_unlink(cli
->tree
, fname1
);
2072 smbcli_close(cli
->tree
, fnum
);
2073 smb_raw_exit(cli
->session
);
2074 smbcli_deltree(cli
->tree
, BASEDIR
);
2080 test dynamic acl inheritance
2081 Test copied to smb2/acls.c for SMB2.
2083 static bool test_inheritance_dynamic(struct torture_context
*tctx
,
2084 struct smbcli_state
*cli
)
2088 const char *dname
= BASEDIR
"\\inheritance2";
2089 const char *fname1
= BASEDIR
"\\inheritance2\\testfile";
2092 union smb_fileinfo q
;
2093 union smb_setfileinfo set
;
2094 struct security_descriptor
*sd
, *sd_orig
=NULL
;
2095 const char *owner_sid
;
2097 torture_comment(tctx
, "TESTING DYNAMIC ACL INHERITANCE\n");
2099 if (!torture_setup_dir(cli
, BASEDIR
))
2102 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
2103 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2104 io
.ntcreatex
.in
.flags
= 0;
2105 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
2106 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
2107 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_DIRECTORY
;
2108 io
.ntcreatex
.in
.share_access
= 0;
2109 io
.ntcreatex
.in
.alloc_size
= 0;
2110 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
2111 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2112 io
.ntcreatex
.in
.security_flags
= 0;
2113 io
.ntcreatex
.in
.fname
= dname
;
2115 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
2116 CHECK_STATUS(status
, NT_STATUS_OK
);
2117 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2119 torture_comment(tctx
, "get the original sd\n");
2120 q
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
2121 q
.query_secdesc
.in
.file
.fnum
= fnum
;
2122 q
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
| SECINFO_OWNER
;
2123 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &q
);
2124 CHECK_STATUS(status
, NT_STATUS_OK
);
2125 sd_orig
= q
.query_secdesc
.out
.sd
;
2127 owner_sid
= dom_sid_string(tctx
, sd_orig
->owner_sid
);
2129 torture_comment(tctx
, "owner_sid is %s\n", owner_sid
);
2131 sd
= security_descriptor_dacl_create(tctx
,
2134 SEC_ACE_TYPE_ACCESS_ALLOWED
,
2135 SEC_FILE_WRITE_DATA
| SEC_STD_DELETE
| SEC_FILE_READ_ATTRIBUTE
,
2136 SEC_ACE_FLAG_OBJECT_INHERIT
,
2138 sd
->type
|= SEC_DESC_DACL_AUTO_INHERITED
| SEC_DESC_DACL_AUTO_INHERIT_REQ
;
2140 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
2141 set
.set_secdesc
.in
.file
.fnum
= fnum
;
2142 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
2143 set
.set_secdesc
.in
.sd
= sd
;
2144 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
2145 CHECK_STATUS(status
, NT_STATUS_OK
);
2147 torture_comment(tctx
, "create a file with an inherited acl\n");
2148 io
.ntcreatex
.in
.fname
= fname1
;
2149 io
.ntcreatex
.in
.create_options
= 0;
2150 io
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_ATTRIBUTE
;
2151 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
2152 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
2153 CHECK_STATUS(status
, NT_STATUS_OK
);
2154 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
2155 smbcli_close(cli
->tree
, fnum2
);
2157 torture_comment(tctx
, "try and access file with base rights - should be OK\n");
2158 io
.ntcreatex
.in
.access_mask
= SEC_FILE_WRITE_DATA
;
2159 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
2160 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
2161 CHECK_STATUS(status
, NT_STATUS_OK
);
2162 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
2163 smbcli_close(cli
->tree
, fnum2
);
2165 torture_comment(tctx
, "try and access file with extra rights - should be denied\n");
2166 io
.ntcreatex
.in
.access_mask
= SEC_FILE_WRITE_DATA
| SEC_FILE_EXECUTE
;
2167 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
2168 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
2170 torture_comment(tctx
, "update parent sd\n");
2171 sd
= security_descriptor_dacl_create(tctx
,
2174 SEC_ACE_TYPE_ACCESS_ALLOWED
,
2175 SEC_FILE_WRITE_DATA
| SEC_STD_DELETE
| SEC_FILE_READ_ATTRIBUTE
| SEC_FILE_EXECUTE
,
2176 SEC_ACE_FLAG_OBJECT_INHERIT
,
2178 sd
->type
|= SEC_DESC_DACL_AUTO_INHERITED
| SEC_DESC_DACL_AUTO_INHERIT_REQ
;
2180 set
.set_secdesc
.in
.sd
= sd
;
2181 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
2182 CHECK_STATUS(status
, NT_STATUS_OK
);
2184 torture_comment(tctx
, "try and access file with base rights - should be OK\n");
2185 io
.ntcreatex
.in
.access_mask
= SEC_FILE_WRITE_DATA
;
2186 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
2187 CHECK_STATUS(status
, NT_STATUS_OK
);
2188 fnum2
= io
.ntcreatex
.out
.file
.fnum
;
2189 smbcli_close(cli
->tree
, fnum2
);
2192 torture_comment(tctx
, "try and access now - should be OK if dynamic inheritance works\n");
2193 io
.ntcreatex
.in
.access_mask
= SEC_FILE_WRITE_DATA
| SEC_FILE_EXECUTE
;
2194 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
2195 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
2196 torture_comment(tctx
, "Server does not have dynamic inheritance\n");
2198 if (NT_STATUS_EQUAL(status
, NT_STATUS_OK
)) {
2199 torture_comment(tctx
, "Server does have dynamic inheritance\n");
2201 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
2203 smbcli_unlink(cli
->tree
, fname1
);
2206 if (sd_orig
!= NULL
) {
2207 torture_comment(tctx
, "put back original sd\n");
2208 set
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
2209 set
.set_secdesc
.in
.file
.fnum
= fnum
;
2210 set
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
2211 set
.set_secdesc
.in
.sd
= sd_orig
;
2212 status
= smb_raw_setfileinfo(cli
->tree
, &set
);
2214 smbcli_close(cli
->tree
, fnum
);
2215 smbcli_rmdir(cli
->tree
, dname
);
2216 smb_raw_exit(cli
->session
);
2217 smbcli_deltree(cli
->tree
, BASEDIR
);
2222 #define CHECK_STATUS_FOR_BIT_ACTION(status, bits, action) do { \
2223 if (!(bits & desired_64)) {\
2224 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); \
2227 CHECK_STATUS(status, NT_STATUS_OK); \
2231 #define CHECK_STATUS_FOR_BIT(status, bits, access) do { \
2232 if (NT_STATUS_IS_OK(status)) { \
2233 if (!(granted & access)) {\
2235 torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are not granted! granted[0x%08X] desired[0x%08X]\n", \
2236 __location__, nt_errstr(status), access, granted, desired); \
2240 if (granted & access) {\
2242 torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are granted! granted[0x%08X] desired[0x%08X]\n", \
2243 __location__, nt_errstr(status), access, granted, desired); \
2247 CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \
2252 /* test what access mask is needed for getting and setting security_descriptors
2253 Test copied to smb2/acls.c for SMB2. */
2254 static bool test_sd_get_set(struct torture_context
*tctx
,
2255 struct smbcli_state
*cli
)
2260 union smb_fileinfo fi
;
2261 union smb_setfileinfo si
;
2262 struct security_descriptor
*sd
;
2263 struct security_descriptor
*sd_owner
= NULL
;
2264 struct security_descriptor
*sd_group
= NULL
;
2265 struct security_descriptor
*sd_dacl
= NULL
;
2266 struct security_descriptor
*sd_sacl
= NULL
;
2268 const char *fname
= BASEDIR
"\\sd_get_set.txt";
2269 uint64_t desired_64
;
2270 uint32_t desired
= 0, granted
;
2272 #define NO_BITS_HACK (((uint64_t)1)<<32)
2273 uint64_t open_bits
=
2275 SEC_FLAG_SYSTEM_SECURITY
|
2276 SEC_FLAG_MAXIMUM_ALLOWED
|
2280 uint64_t get_owner_bits
= SEC_MASK_GENERIC
| SEC_FLAG_MAXIMUM_ALLOWED
| SEC_STD_READ_CONTROL
;
2281 uint64_t set_owner_bits
= SEC_GENERIC_ALL
| SEC_FLAG_MAXIMUM_ALLOWED
| SEC_STD_WRITE_OWNER
;
2282 uint64_t get_group_bits
= SEC_MASK_GENERIC
| SEC_FLAG_MAXIMUM_ALLOWED
| SEC_STD_READ_CONTROL
;
2283 uint64_t set_group_bits
= SEC_GENERIC_ALL
| SEC_FLAG_MAXIMUM_ALLOWED
| SEC_STD_WRITE_OWNER
;
2284 uint64_t get_dacl_bits
= SEC_MASK_GENERIC
| SEC_FLAG_MAXIMUM_ALLOWED
| SEC_STD_READ_CONTROL
;
2285 uint64_t set_dacl_bits
= SEC_GENERIC_ALL
| SEC_FLAG_MAXIMUM_ALLOWED
| SEC_STD_WRITE_DAC
;
2286 uint64_t get_sacl_bits
= SEC_FLAG_SYSTEM_SECURITY
;
2287 uint64_t set_sacl_bits
= SEC_FLAG_SYSTEM_SECURITY
;
2289 if (!torture_setup_dir(cli
, BASEDIR
))
2292 torture_comment(tctx
, "TESTING ACCESS MASKS FOR SD GET/SET\n");
2294 /* first create a file with full access for everyone */
2295 sd
= security_descriptor_dacl_create(tctx
,
2296 0, SID_NT_ANONYMOUS
, SID_BUILTIN_USERS
,
2298 SEC_ACE_TYPE_ACCESS_ALLOWED
,
2302 sd
->type
|= SEC_DESC_SACL_PRESENT
;
2304 io
.ntcreatex
.level
= RAW_OPEN_NTTRANS_CREATE
;
2305 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
2306 io
.ntcreatex
.in
.flags
= 0;
2307 io
.ntcreatex
.in
.access_mask
= SEC_GENERIC_ALL
;
2308 io
.ntcreatex
.in
.create_options
= 0;
2309 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
2310 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
2311 io
.ntcreatex
.in
.alloc_size
= 0;
2312 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OVERWRITE_IF
;
2313 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
2314 io
.ntcreatex
.in
.security_flags
= 0;
2315 io
.ntcreatex
.in
.fname
= fname
;
2316 io
.ntcreatex
.in
.sec_desc
= sd
;
2317 io
.ntcreatex
.in
.ea_list
= NULL
;
2318 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
2319 CHECK_STATUS(status
, NT_STATUS_OK
);
2320 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2322 status
= smbcli_close(cli
->tree
, fnum
);
2323 CHECK_STATUS(status
, NT_STATUS_OK
);
2326 * now try each access_mask bit and no bit at all in a loop
2327 * and see what's allowed
2328 * NOTE: if i == 32 it means access_mask = 0 (see NO_BITS_HACK above)
2330 for (i
=0; i
<= 32; i
++) {
2331 desired_64
= ((uint64_t)1) << i
;
2332 desired
= (uint32_t)desired_64
;
2334 /* first open the file with the desired access */
2335 io
.ntcreatex
.level
= RAW_OPEN_NTCREATEX
;
2336 io
.ntcreatex
.in
.access_mask
= desired
;
2337 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
2338 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
2339 CHECK_STATUS_FOR_BIT_ACTION(status
, open_bits
, goto next
);
2340 fnum
= io
.ntcreatex
.out
.file
.fnum
;
2342 /* then check what access was granted */
2343 fi
.access_information
.level
= RAW_FILEINFO_ACCESS_INFORMATION
;
2344 fi
.access_information
.in
.file
.fnum
= fnum
;
2345 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &fi
);
2346 CHECK_STATUS(status
, NT_STATUS_OK
);
2347 granted
= fi
.access_information
.out
.access_flags
;
2349 /* test the owner */
2351 fi
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
2352 fi
.query_secdesc
.in
.file
.fnum
= fnum
;
2353 fi
.query_secdesc
.in
.secinfo_flags
= SECINFO_OWNER
;
2354 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &fi
);
2355 CHECK_STATUS_FOR_BIT(status
, get_owner_bits
, SEC_STD_READ_CONTROL
);
2356 if (fi
.query_secdesc
.out
.sd
) {
2357 sd_owner
= fi
.query_secdesc
.out
.sd
;
2358 } else if (!sd_owner
) {
2361 si
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
2362 si
.set_secdesc
.in
.file
.fnum
= fnum
;
2363 si
.set_secdesc
.in
.secinfo_flags
= SECINFO_OWNER
;
2364 si
.set_secdesc
.in
.sd
= sd_owner
;
2365 status
= smb_raw_setfileinfo(cli
->tree
, &si
);
2366 CHECK_STATUS_FOR_BIT(status
, set_owner_bits
, SEC_STD_WRITE_OWNER
);
2368 /* test the group */
2370 fi
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
2371 fi
.query_secdesc
.in
.file
.fnum
= fnum
;
2372 fi
.query_secdesc
.in
.secinfo_flags
= SECINFO_GROUP
;
2373 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &fi
);
2374 CHECK_STATUS_FOR_BIT(status
, get_group_bits
, SEC_STD_READ_CONTROL
);
2375 if (fi
.query_secdesc
.out
.sd
) {
2376 sd_group
= fi
.query_secdesc
.out
.sd
;
2377 } else if (!sd_group
) {
2380 si
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
2381 si
.set_secdesc
.in
.file
.fnum
= fnum
;
2382 si
.set_secdesc
.in
.secinfo_flags
= SECINFO_GROUP
;
2383 si
.set_secdesc
.in
.sd
= sd_group
;
2384 status
= smb_raw_setfileinfo(cli
->tree
, &si
);
2385 CHECK_STATUS_FOR_BIT(status
, set_group_bits
, SEC_STD_WRITE_OWNER
);
2389 fi
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
2390 fi
.query_secdesc
.in
.file
.fnum
= fnum
;
2391 fi
.query_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
2392 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &fi
);
2393 CHECK_STATUS_FOR_BIT(status
, get_dacl_bits
, SEC_STD_READ_CONTROL
);
2394 if (fi
.query_secdesc
.out
.sd
) {
2395 sd_dacl
= fi
.query_secdesc
.out
.sd
;
2396 } else if (!sd_dacl
) {
2399 si
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
2400 si
.set_secdesc
.in
.file
.fnum
= fnum
;
2401 si
.set_secdesc
.in
.secinfo_flags
= SECINFO_DACL
;
2402 si
.set_secdesc
.in
.sd
= sd_dacl
;
2403 status
= smb_raw_setfileinfo(cli
->tree
, &si
);
2404 CHECK_STATUS_FOR_BIT(status
, set_dacl_bits
, SEC_STD_WRITE_DAC
);
2408 fi
.query_secdesc
.level
= RAW_FILEINFO_SEC_DESC
;
2409 fi
.query_secdesc
.in
.file
.fnum
= fnum
;
2410 fi
.query_secdesc
.in
.secinfo_flags
= SECINFO_SACL
;
2411 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &fi
);
2412 CHECK_STATUS_FOR_BIT(status
, get_sacl_bits
, SEC_FLAG_SYSTEM_SECURITY
);
2413 if (fi
.query_secdesc
.out
.sd
) {
2414 sd_sacl
= fi
.query_secdesc
.out
.sd
;
2415 } else if (!sd_sacl
) {
2418 si
.set_secdesc
.level
= RAW_SFILEINFO_SEC_DESC
;
2419 si
.set_secdesc
.in
.file
.fnum
= fnum
;
2420 si
.set_secdesc
.in
.secinfo_flags
= SECINFO_SACL
;
2421 si
.set_secdesc
.in
.sd
= sd_sacl
;
2422 status
= smb_raw_setfileinfo(cli
->tree
, &si
);
2423 CHECK_STATUS_FOR_BIT(status
, set_sacl_bits
, SEC_FLAG_SYSTEM_SECURITY
);
2425 /* close the handle */
2426 status
= smbcli_close(cli
->tree
, fnum
);
2427 CHECK_STATUS(status
, NT_STATUS_OK
);
2433 smbcli_close(cli
->tree
, fnum
);
2434 smbcli_unlink(cli
->tree
, fname
);
2435 smb_raw_exit(cli
->session
);
2436 smbcli_deltree(cli
->tree
, BASEDIR
);
2444 basic testing of security descriptor calls
2446 struct torture_suite
*torture_raw_acls(TALLOC_CTX
*mem_ctx
)
2448 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "acls");
2450 torture_suite_add_1smb_test(suite
, "sd", test_sd
);
2451 torture_suite_add_1smb_test(suite
, "create_file", test_nttrans_create_file
);
2452 torture_suite_add_1smb_test(suite
, "create_dir", test_nttrans_create_dir
);
2453 torture_suite_add_1smb_test(suite
, "nulldacl", test_nttrans_create_null_dacl
);
2454 torture_suite_add_1smb_test(suite
, "creator", test_creator_sid
);
2455 torture_suite_add_1smb_test(suite
, "generic", test_generic_bits
);
2456 torture_suite_add_1smb_test(suite
, "owner", test_owner_bits
);
2457 torture_suite_add_1smb_test(suite
, "inheritance", test_inheritance
);
2460 torture_suite_add_1smb_test(suite
, "INHERITFLAGS", test_inheritance_flags
);
2462 torture_suite_add_1smb_test(suite
, "dynamic", test_inheritance_dynamic
);
2464 /* XXX This test does not work against XP or Vista. */
2465 torture_suite_add_1smb_test(suite
, "GETSET", test_sd_get_set
);