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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "torture/torture.h"
25 #include "libcli/raw/libcliraw.h"
26 #include "libcli/libcli.h"
27 #include "librpc/gen_ndr/lsa.h"
28 #include "libcli/util/clilsa.h"
29 #include "libcli/security/proto.h"
30 #include "librpc/gen_ndr/ndr_security.h"
32 #define BASEDIR "\\testsd"
34 #define CHECK_STATUS(status, correct) do { \
35 if (!NT_STATUS_EQUAL(status, correct)) { \
36 printf("(%s) Incorrect status %s - should be %s\n", \
37 __location__, nt_errstr(status), nt_errstr(correct)); \
43 static BOOL test_sd(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
47 const char *fname = BASEDIR "\\sd.txt";
51 union smb_setfileinfo set;
52 struct security_ace ace;
53 struct security_descriptor *sd;
54 struct dom_sid *test_sid;
56 printf("TESTING SETFILEINFO EA_SET\n");
58 io.generic.level = RAW_OPEN_NTCREATEX;
59 io.ntcreatex.in.root_fid = 0;
60 io.ntcreatex.in.flags = 0;
61 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
62 io.ntcreatex.in.create_options = 0;
63 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
64 io.ntcreatex.in.share_access =
65 NTCREATEX_SHARE_ACCESS_READ |
66 NTCREATEX_SHARE_ACCESS_WRITE;
67 io.ntcreatex.in.alloc_size = 0;
68 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
69 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
70 io.ntcreatex.in.security_flags = 0;
71 io.ntcreatex.in.fname = fname;
72 status = smb_raw_open(cli->tree, mem_ctx, &io);
73 CHECK_STATUS(status, NT_STATUS_OK);
74 fnum = io.ntcreatex.out.file.fnum;
76 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
77 q.query_secdesc.in.file.fnum = fnum;
78 q.query_secdesc.in.secinfo_flags =
82 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
83 CHECK_STATUS(status, NT_STATUS_OK);
84 sd = q.query_secdesc.out.sd;
86 printf("add a new ACE to the DACL\n");
88 test_sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1234-5432");
90 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
92 ace.access_mask = SEC_STD_ALL;
93 ace.trustee = *test_sid;
95 status = security_descriptor_dacl_add(sd, &ace);
96 CHECK_STATUS(status, NT_STATUS_OK);
98 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
99 set.set_secdesc.in.file.fnum = fnum;
100 set.set_secdesc.in.secinfo_flags = q.query_secdesc.in.secinfo_flags;
101 set.set_secdesc.in.sd = sd;
103 status = smb_raw_setfileinfo(cli->tree, &set);
104 CHECK_STATUS(status, NT_STATUS_OK);
106 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
107 CHECK_STATUS(status, NT_STATUS_OK);
109 if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
110 printf("%s: security descriptors don't match!\n", __location__);
112 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
113 printf("expected:\n");
114 NDR_PRINT_DEBUG(security_descriptor, sd);
118 printf("remove it again\n");
120 status = security_descriptor_dacl_del(sd, test_sid);
121 CHECK_STATUS(status, NT_STATUS_OK);
123 status = smb_raw_setfileinfo(cli->tree, &set);
124 CHECK_STATUS(status, NT_STATUS_OK);
126 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
127 CHECK_STATUS(status, NT_STATUS_OK);
129 if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
130 printf("%s: security descriptors don't match!\n", __location__);
132 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
133 printf("expected:\n");
134 NDR_PRINT_DEBUG(security_descriptor, sd);
139 smbcli_close(cli->tree, fnum);
145 test using NTTRANS CREATE to create a file with an initial ACL set
147 static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
151 const char *fname = BASEDIR "\\acl2.txt";
154 union smb_fileinfo q;
155 struct security_ace ace;
156 struct security_descriptor *sd;
157 struct dom_sid *test_sid;
159 printf("TESTING NTTRANS CREATE WITH SEC_DESC\n");
161 io.generic.level = RAW_OPEN_NTTRANS_CREATE;
162 io.ntcreatex.in.root_fid = 0;
163 io.ntcreatex.in.flags = 0;
164 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
165 io.ntcreatex.in.create_options = 0;
166 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
167 io.ntcreatex.in.share_access =
168 NTCREATEX_SHARE_ACCESS_READ |
169 NTCREATEX_SHARE_ACCESS_WRITE;
170 io.ntcreatex.in.alloc_size = 0;
171 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
172 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
173 io.ntcreatex.in.security_flags = 0;
174 io.ntcreatex.in.fname = fname;
175 io.ntcreatex.in.sec_desc = NULL;
176 io.ntcreatex.in.ea_list = NULL;
178 printf("creating normal file\n");
180 status = smb_raw_open(cli->tree, mem_ctx, &io);
181 CHECK_STATUS(status, NT_STATUS_OK);
182 fnum = io.ntcreatex.out.file.fnum;
184 printf("querying ACL\n");
186 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
187 q.query_secdesc.in.file.fnum = fnum;
188 q.query_secdesc.in.secinfo_flags =
192 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
193 CHECK_STATUS(status, NT_STATUS_OK);
194 sd = q.query_secdesc.out.sd;
196 smbcli_close(cli->tree, fnum);
197 smbcli_unlink(cli->tree, fname);
199 printf("adding a new ACE\n");
200 test_sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1234-54321");
202 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
204 ace.access_mask = SEC_STD_ALL;
205 ace.trustee = *test_sid;
207 status = security_descriptor_dacl_add(sd, &ace);
208 CHECK_STATUS(status, NT_STATUS_OK);
210 printf("creating a file with an initial ACL\n");
212 io.ntcreatex.in.sec_desc = sd;
213 status = smb_raw_open(cli->tree, mem_ctx, &io);
214 CHECK_STATUS(status, NT_STATUS_OK);
215 fnum = io.ntcreatex.out.file.fnum;
217 q.query_secdesc.in.file.fnum = fnum;
218 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
219 CHECK_STATUS(status, NT_STATUS_OK);
221 if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
222 printf("%s: security descriptors don't match!\n", __location__);
224 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
225 printf("expected:\n");
226 NDR_PRINT_DEBUG(security_descriptor, sd);
231 smbcli_close(cli->tree, fnum);
235 #define CHECK_ACCESS_FLAGS(_fnum, flags) do { \
236 union smb_fileinfo _q; \
237 _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
238 _q.access_information.in.file.fnum = (_fnum); \
239 status = smb_raw_fileinfo(cli->tree, mem_ctx, &_q); \
240 CHECK_STATUS(status, NT_STATUS_OK); \
241 if (_q.access_information.out.access_flags != (flags)) { \
242 printf("(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
243 __location__, _q.access_information.out.access_flags, (flags)); \
251 test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
254 static BOOL test_creator_sid(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
258 const char *fname = BASEDIR "\\creator.txt";
261 union smb_fileinfo q;
262 union smb_setfileinfo set;
263 struct security_descriptor *sd, *sd_orig, *sd2;
264 const char *owner_sid;
266 printf("TESTING SID_CREATOR_OWNER\n");
268 io.generic.level = RAW_OPEN_NTCREATEX;
269 io.ntcreatex.in.root_fid = 0;
270 io.ntcreatex.in.flags = 0;
271 io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
272 io.ntcreatex.in.create_options = 0;
273 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
274 io.ntcreatex.in.share_access =
275 NTCREATEX_SHARE_ACCESS_READ |
276 NTCREATEX_SHARE_ACCESS_WRITE;
277 io.ntcreatex.in.alloc_size = 0;
278 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
279 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
280 io.ntcreatex.in.security_flags = 0;
281 io.ntcreatex.in.fname = fname;
282 status = smb_raw_open(cli->tree, mem_ctx, &io);
283 CHECK_STATUS(status, NT_STATUS_OK);
284 fnum = io.ntcreatex.out.file.fnum;
286 printf("get the original sd\n");
287 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
288 q.query_secdesc.in.file.fnum = fnum;
289 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
290 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
291 CHECK_STATUS(status, NT_STATUS_OK);
292 sd_orig = q.query_secdesc.out.sd;
294 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
296 printf("set a sec desc allowing no write by CREATOR_OWNER\n");
297 sd = security_descriptor_create(mem_ctx,
300 SEC_ACE_TYPE_ACCESS_ALLOWED,
301 SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
305 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
306 set.set_secdesc.in.file.fnum = fnum;
307 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
308 set.set_secdesc.in.sd = sd;
310 status = smb_raw_setfileinfo(cli->tree, &set);
311 CHECK_STATUS(status, NT_STATUS_OK);
313 printf("try open for write\n");
314 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
315 status = smb_raw_open(cli->tree, mem_ctx, &io);
316 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
318 printf("try open for read\n");
319 io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
320 status = smb_raw_open(cli->tree, mem_ctx, &io);
321 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
323 printf("try open for generic write\n");
324 io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
325 status = smb_raw_open(cli->tree, mem_ctx, &io);
326 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
328 printf("try open for generic read\n");
329 io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
330 status = smb_raw_open(cli->tree, mem_ctx, &io);
331 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
333 printf("set a sec desc allowing no write by owner\n");
334 sd = security_descriptor_create(mem_ctx,
337 SEC_ACE_TYPE_ACCESS_ALLOWED,
338 SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
342 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
343 set.set_secdesc.in.file.fnum = fnum;
344 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
345 set.set_secdesc.in.sd = sd;
346 status = smb_raw_setfileinfo(cli->tree, &set);
347 CHECK_STATUS(status, NT_STATUS_OK);
349 printf("check that sd has been mapped correctly\n");
350 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
351 CHECK_STATUS(status, NT_STATUS_OK);
352 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd)) {
353 printf("%s: security descriptors don't match!\n", __location__);
355 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
356 printf("expected:\n");
357 NDR_PRINT_DEBUG(security_descriptor, sd);
361 printf("try open for write\n");
362 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
363 status = smb_raw_open(cli->tree, mem_ctx, &io);
364 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
366 printf("try open for read\n");
367 io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
368 status = smb_raw_open(cli->tree, mem_ctx, &io);
369 CHECK_STATUS(status, NT_STATUS_OK);
370 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
372 SEC_FILE_READ_ATTRIBUTE);
373 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
375 printf("try open for generic write\n");
376 io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
377 status = smb_raw_open(cli->tree, mem_ctx, &io);
378 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
380 printf("try open for generic read\n");
381 io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
382 status = smb_raw_open(cli->tree, mem_ctx, &io);
383 CHECK_STATUS(status, NT_STATUS_OK);
384 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
385 SEC_RIGHTS_FILE_READ);
386 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
388 printf("set a sec desc allowing generic read by owner\n");
389 sd = security_descriptor_create(mem_ctx,
392 SEC_ACE_TYPE_ACCESS_ALLOWED,
393 SEC_GENERIC_READ | SEC_STD_ALL,
397 set.set_secdesc.in.sd = sd;
398 status = smb_raw_setfileinfo(cli->tree, &set);
399 CHECK_STATUS(status, NT_STATUS_OK);
401 printf("check that generic read has been mapped correctly\n");
402 sd2 = security_descriptor_create(mem_ctx,
405 SEC_ACE_TYPE_ACCESS_ALLOWED,
406 SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
410 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
411 CHECK_STATUS(status, NT_STATUS_OK);
412 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
413 printf("%s: security descriptors don't match!\n", __location__);
415 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
416 printf("expected:\n");
417 NDR_PRINT_DEBUG(security_descriptor, sd2);
422 printf("try open for write\n");
423 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
424 status = smb_raw_open(cli->tree, mem_ctx, &io);
425 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
427 printf("try open for read\n");
428 io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
429 status = smb_raw_open(cli->tree, mem_ctx, &io);
430 CHECK_STATUS(status, NT_STATUS_OK);
431 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
433 SEC_FILE_READ_ATTRIBUTE);
434 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
436 printf("try open for generic write\n");
437 io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
438 status = smb_raw_open(cli->tree, mem_ctx, &io);
439 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
441 printf("try open for generic read\n");
442 io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
443 status = smb_raw_open(cli->tree, mem_ctx, &io);
444 CHECK_STATUS(status, NT_STATUS_OK);
445 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, SEC_RIGHTS_FILE_READ);
446 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
449 printf("put back original sd\n");
450 set.set_secdesc.in.sd = sd_orig;
451 status = smb_raw_setfileinfo(cli->tree, &set);
452 CHECK_STATUS(status, NT_STATUS_OK);
456 smbcli_close(cli->tree, fnum);
462 test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
465 static BOOL test_generic_bits(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
469 const char *fname = BASEDIR "\\generic.txt";
472 union smb_fileinfo q;
473 union smb_setfileinfo set;
474 struct security_descriptor *sd, *sd_orig, *sd2;
475 const char *owner_sid;
478 uint32_t specific_bits;
479 } file_mappings[] = {
481 { SEC_GENERIC_READ, SEC_RIGHTS_FILE_READ },
482 { SEC_GENERIC_WRITE, SEC_RIGHTS_FILE_WRITE },
483 { SEC_GENERIC_EXECUTE, SEC_RIGHTS_FILE_EXECUTE },
484 { SEC_GENERIC_ALL, SEC_RIGHTS_FILE_ALL },
485 { SEC_FILE_READ_DATA, SEC_FILE_READ_DATA },
486 { SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_ATTRIBUTE }
490 uint32_t specific_bits;
493 { SEC_GENERIC_READ, SEC_RIGHTS_DIR_READ },
494 { SEC_GENERIC_WRITE, SEC_RIGHTS_DIR_WRITE },
495 { SEC_GENERIC_EXECUTE, SEC_RIGHTS_DIR_EXECUTE },
496 { SEC_GENERIC_ALL, SEC_RIGHTS_DIR_ALL }
498 BOOL has_restore_privilege;
499 BOOL has_take_ownership_privilege;
501 printf("TESTING FILE GENERIC BITS\n");
503 io.generic.level = RAW_OPEN_NTCREATEX;
504 io.ntcreatex.in.root_fid = 0;
505 io.ntcreatex.in.flags = 0;
506 io.ntcreatex.in.access_mask =
507 SEC_STD_READ_CONTROL |
510 io.ntcreatex.in.create_options = 0;
511 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
512 io.ntcreatex.in.share_access =
513 NTCREATEX_SHARE_ACCESS_READ |
514 NTCREATEX_SHARE_ACCESS_WRITE;
515 io.ntcreatex.in.alloc_size = 0;
516 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
517 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
518 io.ntcreatex.in.security_flags = 0;
519 io.ntcreatex.in.fname = fname;
520 status = smb_raw_open(cli->tree, mem_ctx, &io);
521 CHECK_STATUS(status, NT_STATUS_OK);
522 fnum = io.ntcreatex.out.file.fnum;
524 printf("get the original sd\n");
525 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
526 q.query_secdesc.in.file.fnum = fnum;
527 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
528 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
529 CHECK_STATUS(status, NT_STATUS_OK);
530 sd_orig = q.query_secdesc.out.sd;
532 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
534 status = smblsa_sid_check_privilege(cli,
536 sec_privilege_name(SEC_PRIV_RESTORE));
537 has_restore_privilege = NT_STATUS_IS_OK(status);
538 if (!NT_STATUS_IS_OK(status)) {
539 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
541 printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
543 status = smblsa_sid_check_privilege(cli,
545 sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
546 has_take_ownership_privilege = NT_STATUS_IS_OK(status);
547 if (!NT_STATUS_IS_OK(status)) {
548 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
550 printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
552 for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
553 uint32_t expected_mask =
555 SEC_STD_READ_CONTROL |
556 SEC_FILE_READ_ATTRIBUTE |
558 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
560 if (has_restore_privilege) {
561 expected_mask_anon |= SEC_STD_DELETE;
564 printf("testing generic bits 0x%08x\n",
565 file_mappings[i].gen_bits);
566 sd = security_descriptor_create(mem_ctx,
569 SEC_ACE_TYPE_ACCESS_ALLOWED,
570 file_mappings[i].gen_bits,
574 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
575 set.set_secdesc.in.file.fnum = fnum;
576 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
577 set.set_secdesc.in.sd = sd;
579 status = smb_raw_setfileinfo(cli->tree, &set);
580 CHECK_STATUS(status, NT_STATUS_OK);
582 sd2 = security_descriptor_create(mem_ctx,
585 SEC_ACE_TYPE_ACCESS_ALLOWED,
586 file_mappings[i].specific_bits,
590 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
591 CHECK_STATUS(status, NT_STATUS_OK);
592 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
593 printf("%s: security descriptors don't match!\n", __location__);
595 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
596 printf("expected:\n");
597 NDR_PRINT_DEBUG(security_descriptor, sd2);
601 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
602 status = smb_raw_open(cli->tree, mem_ctx, &io);
603 CHECK_STATUS(status, NT_STATUS_OK);
604 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
605 expected_mask | file_mappings[i].specific_bits);
606 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
608 if (!has_take_ownership_privilege) {
612 printf("testing generic bits 0x%08x (anonymous)\n",
613 file_mappings[i].gen_bits);
614 sd = security_descriptor_create(mem_ctx,
615 SID_NT_ANONYMOUS, NULL,
617 SEC_ACE_TYPE_ACCESS_ALLOWED,
618 file_mappings[i].gen_bits,
622 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
623 set.set_secdesc.in.file.fnum = fnum;
624 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
625 set.set_secdesc.in.sd = sd;
627 status = smb_raw_setfileinfo(cli->tree, &set);
628 CHECK_STATUS(status, NT_STATUS_OK);
630 sd2 = security_descriptor_create(mem_ctx,
631 SID_NT_ANONYMOUS, NULL,
633 SEC_ACE_TYPE_ACCESS_ALLOWED,
634 file_mappings[i].specific_bits,
638 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
639 CHECK_STATUS(status, NT_STATUS_OK);
640 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
641 printf("%s: security descriptors don't match!\n", __location__);
643 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
644 printf("expected:\n");
645 NDR_PRINT_DEBUG(security_descriptor, sd2);
649 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
650 status = smb_raw_open(cli->tree, mem_ctx, &io);
651 CHECK_STATUS(status, NT_STATUS_OK);
652 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
653 expected_mask_anon | file_mappings[i].specific_bits);
654 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
657 printf("put back original sd\n");
658 set.set_secdesc.in.sd = sd_orig;
659 status = smb_raw_setfileinfo(cli->tree, &set);
660 CHECK_STATUS(status, NT_STATUS_OK);
662 smbcli_close(cli->tree, fnum);
663 smbcli_unlink(cli->tree, fname);
666 printf("TESTING DIR GENERIC BITS\n");
668 io.generic.level = RAW_OPEN_NTCREATEX;
669 io.ntcreatex.in.root_fid = 0;
670 io.ntcreatex.in.flags = 0;
671 io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC;
672 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
673 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
674 io.ntcreatex.in.share_access =
675 NTCREATEX_SHARE_ACCESS_READ |
676 NTCREATEX_SHARE_ACCESS_WRITE;
677 io.ntcreatex.in.alloc_size = 0;
678 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
679 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
680 io.ntcreatex.in.security_flags = 0;
681 io.ntcreatex.in.fname = fname;
682 status = smb_raw_open(cli->tree, mem_ctx, &io);
683 CHECK_STATUS(status, NT_STATUS_OK);
684 fnum = io.ntcreatex.out.file.fnum;
686 printf("get the original sd\n");
687 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
688 q.query_secdesc.in.file.fnum = fnum;
689 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
690 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
691 CHECK_STATUS(status, NT_STATUS_OK);
692 sd_orig = q.query_secdesc.out.sd;
694 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
697 for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
698 uint32_t expected_mask =
700 SEC_STD_READ_CONTROL |
701 SEC_FILE_READ_ATTRIBUTE |
704 printf("testing generic bits 0x%08x\n",
705 file_mappings[i].gen_bits);
706 sd = security_descriptor_create(mem_ctx,
709 SEC_ACE_TYPE_ACCESS_ALLOWED,
710 dir_mappings[i].gen_bits,
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 sd2 = security_descriptor_create(mem_ctx,
725 SEC_ACE_TYPE_ACCESS_ALLOWED,
726 dir_mappings[i].specific_bits,
730 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
731 CHECK_STATUS(status, NT_STATUS_OK);
732 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
733 printf("%s: security descriptors don't match!\n", __location__);
735 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
736 printf("expected:\n");
737 NDR_PRINT_DEBUG(security_descriptor, sd2);
741 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
742 status = smb_raw_open(cli->tree, mem_ctx, &io);
743 CHECK_STATUS(status, NT_STATUS_OK);
744 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
745 expected_mask | dir_mappings[i].specific_bits);
746 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
749 printf("put back original sd\n");
750 set.set_secdesc.in.sd = sd_orig;
751 status = smb_raw_setfileinfo(cli->tree, &set);
752 CHECK_STATUS(status, NT_STATUS_OK);
754 smbcli_close(cli->tree, fnum);
755 smbcli_unlink(cli->tree, fname);
758 smbcli_close(cli->tree, fnum);
764 see what access bits the owner of a file always gets
766 static BOOL test_owner_bits(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
770 const char *fname = BASEDIR "\\generic.txt";
773 union smb_fileinfo q;
774 union smb_setfileinfo set;
775 struct security_descriptor *sd, *sd_orig;
776 const char *owner_sid;
777 BOOL has_restore_privilege;
778 BOOL has_take_ownership_privilege;
779 uint32_t expected_bits;
781 printf("TESTING FILE OWNER BITS\n");
783 io.generic.level = RAW_OPEN_NTCREATEX;
784 io.ntcreatex.in.root_fid = 0;
785 io.ntcreatex.in.flags = 0;
786 io.ntcreatex.in.access_mask =
787 SEC_STD_READ_CONTROL |
790 io.ntcreatex.in.create_options = 0;
791 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
792 io.ntcreatex.in.share_access =
793 NTCREATEX_SHARE_ACCESS_READ |
794 NTCREATEX_SHARE_ACCESS_WRITE;
795 io.ntcreatex.in.alloc_size = 0;
796 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
797 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
798 io.ntcreatex.in.security_flags = 0;
799 io.ntcreatex.in.fname = fname;
800 status = smb_raw_open(cli->tree, mem_ctx, &io);
801 CHECK_STATUS(status, NT_STATUS_OK);
802 fnum = io.ntcreatex.out.file.fnum;
804 printf("get the original sd\n");
805 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
806 q.query_secdesc.in.file.fnum = fnum;
807 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
808 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
809 CHECK_STATUS(status, NT_STATUS_OK);
810 sd_orig = q.query_secdesc.out.sd;
812 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
814 status = smblsa_sid_check_privilege(cli,
816 sec_privilege_name(SEC_PRIV_RESTORE));
817 has_restore_privilege = NT_STATUS_IS_OK(status);
818 if (!NT_STATUS_IS_OK(status)) {
819 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
821 printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
823 status = smblsa_sid_check_privilege(cli,
825 sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
826 has_take_ownership_privilege = NT_STATUS_IS_OK(status);
827 if (!NT_STATUS_IS_OK(status)) {
828 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
830 printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
832 sd = security_descriptor_create(mem_ctx,
835 SEC_ACE_TYPE_ACCESS_ALLOWED,
840 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
841 set.set_secdesc.in.file.fnum = fnum;
842 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
843 set.set_secdesc.in.sd = sd;
845 status = smb_raw_setfileinfo(cli->tree, &set);
846 CHECK_STATUS(status, NT_STATUS_OK);
848 expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
851 uint32_t bit = (1<<i);
852 io.ntcreatex.in.access_mask = bit;
853 status = smb_raw_open(cli->tree, mem_ctx, &io);
854 if (expected_bits & bit) {
855 if (!NT_STATUS_IS_OK(status)) {
856 printf("failed with access mask 0x%08x of expected 0x%08x\n",
859 CHECK_STATUS(status, NT_STATUS_OK);
860 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, bit | SEC_FILE_READ_ATTRIBUTE);
861 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
863 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
867 printf("put back original sd\n");
868 set.set_secdesc.in.sd = sd_orig;
869 status = smb_raw_setfileinfo(cli->tree, &set);
870 CHECK_STATUS(status, NT_STATUS_OK);
873 smbcli_close(cli->tree, fnum);
874 smbcli_unlink(cli->tree, fname);
881 test the inheritance of ACL flags onto new files and directories
883 static BOOL test_inheritance(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
887 const char *dname = BASEDIR "\\inheritance";
888 const char *fname1 = BASEDIR "\\inheritance\\testfile";
889 const char *fname2 = BASEDIR "\\inheritance\\testdir";
892 union smb_fileinfo q;
893 union smb_setfileinfo set;
894 struct security_descriptor *sd, *sd_orig, *sd_def;
895 const char *owner_sid;
896 const struct dom_sid *creator_owner;
898 uint32_t parent_flags;
908 SEC_ACE_FLAG_OBJECT_INHERIT,
910 SEC_ACE_FLAG_OBJECT_INHERIT |
911 SEC_ACE_FLAG_INHERIT_ONLY,
914 SEC_ACE_FLAG_CONTAINER_INHERIT,
916 SEC_ACE_FLAG_CONTAINER_INHERIT,
919 SEC_ACE_FLAG_OBJECT_INHERIT |
920 SEC_ACE_FLAG_CONTAINER_INHERIT,
922 SEC_ACE_FLAG_OBJECT_INHERIT |
923 SEC_ACE_FLAG_CONTAINER_INHERIT,
926 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
931 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
932 SEC_ACE_FLAG_OBJECT_INHERIT,
937 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
938 SEC_ACE_FLAG_CONTAINER_INHERIT,
943 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
944 SEC_ACE_FLAG_CONTAINER_INHERIT |
945 SEC_ACE_FLAG_OBJECT_INHERIT,
950 SEC_ACE_FLAG_INHERIT_ONLY,
955 SEC_ACE_FLAG_INHERIT_ONLY |
956 SEC_ACE_FLAG_OBJECT_INHERIT,
958 SEC_ACE_FLAG_OBJECT_INHERIT |
959 SEC_ACE_FLAG_INHERIT_ONLY,
962 SEC_ACE_FLAG_INHERIT_ONLY |
963 SEC_ACE_FLAG_CONTAINER_INHERIT,
965 SEC_ACE_FLAG_CONTAINER_INHERIT,
968 SEC_ACE_FLAG_INHERIT_ONLY |
969 SEC_ACE_FLAG_CONTAINER_INHERIT |
970 SEC_ACE_FLAG_OBJECT_INHERIT,
972 SEC_ACE_FLAG_CONTAINER_INHERIT |
973 SEC_ACE_FLAG_OBJECT_INHERIT,
976 SEC_ACE_FLAG_INHERIT_ONLY |
977 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
982 SEC_ACE_FLAG_INHERIT_ONLY |
983 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
984 SEC_ACE_FLAG_OBJECT_INHERIT,
989 SEC_ACE_FLAG_INHERIT_ONLY |
990 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
991 SEC_ACE_FLAG_CONTAINER_INHERIT,
996 SEC_ACE_FLAG_INHERIT_ONLY |
997 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
998 SEC_ACE_FLAG_CONTAINER_INHERIT |
999 SEC_ACE_FLAG_OBJECT_INHERIT,
1005 smbcli_rmdir(cli->tree, dname);
1007 printf("TESTING ACL INHERITANCE\n");
1009 io.generic.level = RAW_OPEN_NTCREATEX;
1010 io.ntcreatex.in.root_fid = 0;
1011 io.ntcreatex.in.flags = 0;
1012 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1013 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1014 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1015 io.ntcreatex.in.share_access = 0;
1016 io.ntcreatex.in.alloc_size = 0;
1017 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1018 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1019 io.ntcreatex.in.security_flags = 0;
1020 io.ntcreatex.in.fname = dname;
1022 status = smb_raw_open(cli->tree, mem_ctx, &io);
1023 CHECK_STATUS(status, NT_STATUS_OK);
1024 fnum = io.ntcreatex.out.file.fnum;
1026 printf("get the original sd\n");
1027 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1028 q.query_secdesc.in.file.fnum = fnum;
1029 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1030 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1031 CHECK_STATUS(status, NT_STATUS_OK);
1032 sd_orig = q.query_secdesc.out.sd;
1034 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
1036 printf("owner_sid is %s\n", owner_sid);
1038 sd_def = security_descriptor_create(mem_ctx,
1041 SEC_ACE_TYPE_ACCESS_ALLOWED,
1042 SEC_RIGHTS_FILE_ALL,
1045 SEC_ACE_TYPE_ACCESS_ALLOWED,
1046 SEC_RIGHTS_FILE_ALL,
1050 creator_owner = dom_sid_parse_talloc(mem_ctx, SID_CREATOR_OWNER);
1052 for (i=0;i<ARRAY_SIZE(test_flags);i++) {
1053 sd = security_descriptor_create(mem_ctx,
1056 SEC_ACE_TYPE_ACCESS_ALLOWED,
1057 SEC_FILE_WRITE_DATA,
1058 test_flags[i].parent_flags,
1060 SEC_ACE_TYPE_ACCESS_ALLOWED,
1061 SEC_FILE_ALL | SEC_STD_ALL,
1064 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1065 set.set_secdesc.in.file.fnum = fnum;
1066 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1067 set.set_secdesc.in.sd = sd;
1068 status = smb_raw_setfileinfo(cli->tree, &set);
1069 CHECK_STATUS(status, NT_STATUS_OK);
1071 io.ntcreatex.in.fname = fname1;
1072 io.ntcreatex.in.create_options = 0;
1073 status = smb_raw_open(cli->tree, mem_ctx, &io);
1074 CHECK_STATUS(status, NT_STATUS_OK);
1075 fnum2 = io.ntcreatex.out.file.fnum;
1077 q.query_secdesc.in.file.fnum = fnum2;
1078 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1079 CHECK_STATUS(status, NT_STATUS_OK);
1081 smbcli_close(cli->tree, fnum2);
1082 smbcli_unlink(cli->tree, fname1);
1084 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
1085 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1086 printf("Expected default sd at %d - got:\n", i);
1087 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1092 if (q.query_secdesc.out.sd->dacl == NULL ||
1093 q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1094 q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1095 !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1096 sd_orig->owner_sid)) {
1097 printf("Bad sd in child file at %d\n", i);
1098 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1103 if (q.query_secdesc.out.sd->dacl->aces[0].flags !=
1104 test_flags[i].file_flags) {
1105 printf("incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
1106 q.query_secdesc.out.sd->dacl->aces[0].flags,
1107 test_flags[i].file_flags,
1108 test_flags[i].parent_flags,
1114 io.ntcreatex.in.fname = fname2;
1115 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1116 status = smb_raw_open(cli->tree, mem_ctx, &io);
1117 CHECK_STATUS(status, NT_STATUS_OK);
1118 fnum2 = io.ntcreatex.out.file.fnum;
1120 q.query_secdesc.in.file.fnum = fnum2;
1121 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1122 CHECK_STATUS(status, NT_STATUS_OK);
1124 smbcli_close(cli->tree, fnum2);
1125 smbcli_rmdir(cli->tree, fname2);
1127 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1128 (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
1129 (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
1130 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1131 printf("Expected default sd for dir at %d - got:\n", i);
1132 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1137 if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1138 (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
1139 if (q.query_secdesc.out.sd->dacl == NULL ||
1140 q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1141 q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1142 !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1143 sd_orig->owner_sid) ||
1144 q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1145 printf("Bad sd in child dir at %d (parent 0x%x)\n",
1146 i, test_flags[i].parent_flags);
1147 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1151 } else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
1152 if (q.query_secdesc.out.sd->dacl == NULL ||
1153 q.query_secdesc.out.sd->dacl->num_aces != 2 ||
1154 q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1155 !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1156 sd_orig->owner_sid) ||
1157 q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
1158 !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
1160 q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
1161 q.query_secdesc.out.sd->dacl->aces[1].flags !=
1162 (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
1163 printf("Bad sd in child dir at %d (parent 0x%x)\n",
1164 i, test_flags[i].parent_flags);
1165 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1170 if (q.query_secdesc.out.sd->dacl == NULL ||
1171 q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1172 q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1173 !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1175 q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1176 printf("Bad sd in child dir at %d (parent 0x%x)\n",
1177 i, test_flags[i].parent_flags);
1178 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1185 printf("testing access checks on inherited create with %s\n", fname1);
1186 sd = security_descriptor_create(mem_ctx,
1189 SEC_ACE_TYPE_ACCESS_ALLOWED,
1190 SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1191 SEC_ACE_FLAG_OBJECT_INHERIT,
1193 SEC_ACE_TYPE_ACCESS_ALLOWED,
1194 SEC_FILE_ALL | SEC_STD_ALL,
1197 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1198 set.set_secdesc.in.file.fnum = fnum;
1199 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1200 set.set_secdesc.in.sd = sd;
1201 status = smb_raw_setfileinfo(cli->tree, &set);
1202 CHECK_STATUS(status, NT_STATUS_OK);
1204 io.ntcreatex.in.fname = fname1;
1205 io.ntcreatex.in.create_options = 0;
1206 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1207 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1208 status = smb_raw_open(cli->tree, mem_ctx, &io);
1209 CHECK_STATUS(status, NT_STATUS_OK);
1210 fnum2 = io.ntcreatex.out.file.fnum;
1211 CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1213 q.query_secdesc.in.file.fnum = fnum2;
1214 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1215 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1216 CHECK_STATUS(status, NT_STATUS_OK);
1217 smbcli_close(cli->tree, fnum2);
1219 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1220 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1221 status = smb_raw_open(cli->tree, mem_ctx, &io);
1222 if (NT_STATUS_IS_OK(status)) {
1223 printf("failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
1225 fnum2 = io.ntcreatex.out.file.fnum;
1226 smbcli_close(cli->tree, fnum2);
1228 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1231 printf("trying without execute\n");
1232 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1233 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
1234 status = smb_raw_open(cli->tree, mem_ctx, &io);
1235 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1237 printf("and with full permissions again\n");
1238 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1239 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1240 status = smb_raw_open(cli->tree, mem_ctx, &io);
1241 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1243 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1244 status = smb_raw_open(cli->tree, mem_ctx, &io);
1245 CHECK_STATUS(status, NT_STATUS_OK);
1246 fnum2 = io.ntcreatex.out.file.fnum;
1247 CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1248 smbcli_close(cli->tree, fnum2);
1250 printf("put back original sd\n");
1251 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1252 set.set_secdesc.in.file.fnum = fnum;
1253 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1254 set.set_secdesc.in.sd = sd_orig;
1255 status = smb_raw_setfileinfo(cli->tree, &set);
1256 CHECK_STATUS(status, NT_STATUS_OK);
1258 smbcli_close(cli->tree, fnum);
1260 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1261 status = smb_raw_open(cli->tree, mem_ctx, &io);
1262 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1264 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1265 status = smb_raw_open(cli->tree, mem_ctx, &io);
1266 CHECK_STATUS(status, NT_STATUS_OK);
1267 fnum2 = io.ntcreatex.out.file.fnum;
1268 CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1269 smbcli_close(cli->tree, fnum2);
1271 smbcli_unlink(cli->tree, fname1);
1272 smbcli_rmdir(cli->tree, dname);
1275 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1276 set.set_secdesc.in.file.fnum = fnum;
1277 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1278 set.set_secdesc.in.sd = sd_orig;
1279 status = smb_raw_setfileinfo(cli->tree, &set);
1281 smbcli_close(cli->tree, fnum);
1287 test dynamic acl inheritance
1289 static BOOL test_inheritance_dynamic(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
1293 const char *dname = BASEDIR "\\inheritance";
1294 const char *fname1 = BASEDIR "\\inheritance\\testfile";
1297 union smb_fileinfo q;
1298 union smb_setfileinfo set;
1299 struct security_descriptor *sd, *sd_orig;
1300 const char *owner_sid;
1302 printf("TESTING DYNAMIC ACL INHERITANCE\n");
1304 if (!torture_setup_dir(cli, BASEDIR)) {
1308 io.generic.level = RAW_OPEN_NTCREATEX;
1309 io.ntcreatex.in.root_fid = 0;
1310 io.ntcreatex.in.flags = 0;
1311 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1312 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1313 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1314 io.ntcreatex.in.share_access = 0;
1315 io.ntcreatex.in.alloc_size = 0;
1316 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1317 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1318 io.ntcreatex.in.security_flags = 0;
1319 io.ntcreatex.in.fname = dname;
1321 status = smb_raw_open(cli->tree, mem_ctx, &io);
1322 CHECK_STATUS(status, NT_STATUS_OK);
1323 fnum = io.ntcreatex.out.file.fnum;
1325 printf("get the original sd\n");
1326 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1327 q.query_secdesc.in.file.fnum = fnum;
1328 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1329 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1330 CHECK_STATUS(status, NT_STATUS_OK);
1331 sd_orig = q.query_secdesc.out.sd;
1333 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
1335 printf("owner_sid is %s\n", owner_sid);
1337 sd = security_descriptor_create(mem_ctx,
1340 SEC_ACE_TYPE_ACCESS_ALLOWED,
1341 SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
1342 SEC_ACE_FLAG_OBJECT_INHERIT,
1344 sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1346 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1347 set.set_secdesc.in.file.fnum = fnum;
1348 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1349 set.set_secdesc.in.sd = sd;
1350 status = smb_raw_setfileinfo(cli->tree, &set);
1351 CHECK_STATUS(status, NT_STATUS_OK);
1353 printf("create a file with an inherited acl\n");
1354 io.ntcreatex.in.fname = fname1;
1355 io.ntcreatex.in.create_options = 0;
1356 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE;
1357 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1358 status = smb_raw_open(cli->tree, mem_ctx, &io);
1359 CHECK_STATUS(status, NT_STATUS_OK);
1360 fnum2 = io.ntcreatex.out.file.fnum;
1361 smbcli_close(cli->tree, fnum2);
1363 printf("try and access file with base rights - should be OK\n");
1364 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1365 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1366 status = smb_raw_open(cli->tree, mem_ctx, &io);
1367 CHECK_STATUS(status, NT_STATUS_OK);
1368 fnum2 = io.ntcreatex.out.file.fnum;
1369 smbcli_close(cli->tree, fnum2);
1371 printf("try and access file with extra rights - should be denied\n");
1372 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1373 status = smb_raw_open(cli->tree, mem_ctx, &io);
1374 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1376 printf("update parent sd\n");
1377 sd = security_descriptor_create(mem_ctx,
1380 SEC_ACE_TYPE_ACCESS_ALLOWED,
1381 SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE,
1382 SEC_ACE_FLAG_OBJECT_INHERIT,
1384 sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1386 set.set_secdesc.in.sd = sd;
1387 status = smb_raw_setfileinfo(cli->tree, &set);
1388 CHECK_STATUS(status, NT_STATUS_OK);
1390 printf("try and access file with base rights - should be OK\n");
1391 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1392 status = smb_raw_open(cli->tree, mem_ctx, &io);
1393 CHECK_STATUS(status, NT_STATUS_OK);
1394 fnum2 = io.ntcreatex.out.file.fnum;
1395 smbcli_close(cli->tree, fnum2);
1398 printf("try and access now - should be OK if dynamic inheritance works\n");
1399 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1400 status = smb_raw_open(cli->tree, mem_ctx, &io);
1401 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1402 printf("Server does not have dynamic inheritance\n");
1404 if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1405 printf("Server does have dynamic inheritance\n");
1407 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1409 smbcli_unlink(cli->tree, fname1);
1412 printf("put back original sd\n");
1413 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1414 set.set_secdesc.in.file.fnum = fnum;
1415 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1416 set.set_secdesc.in.sd = sd_orig;
1417 status = smb_raw_setfileinfo(cli->tree, &set);
1419 smbcli_close(cli->tree, fnum);
1420 smbcli_rmdir(cli->tree, dname);
1427 basic testing of security descriptor calls
1429 BOOL torture_raw_acls(void)
1431 struct smbcli_state *cli;
1433 TALLOC_CTX *mem_ctx;
1435 if (!torture_open_connection(&cli)) {
1439 mem_ctx = talloc_init("torture_raw_acls");
1441 if (!torture_setup_dir(cli, BASEDIR)) {
1445 ret &= test_sd(cli, mem_ctx);
1446 ret &= test_nttrans_create(cli, mem_ctx);
1447 ret &= test_creator_sid(cli, mem_ctx);
1448 ret &= test_generic_bits(cli, mem_ctx);
1449 ret &= test_owner_bits(cli, mem_ctx);
1450 ret &= test_inheritance(cli, mem_ctx);
1451 ret &= test_inheritance_dynamic(cli, mem_ctx);
1453 smb_raw_exit(cli->session);
1454 smbcli_deltree(cli->tree, BASEDIR);
1456 torture_close_connection(cli);
1457 talloc_free(mem_ctx);