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 "libcli/raw/libcliraw.h"
25 #include "librpc/gen_ndr/ndr_security.h"
27 #define BASEDIR "\\testsd"
29 #define CHECK_STATUS(status, correct) do { \
30 if (!NT_STATUS_EQUAL(status, correct)) { \
31 printf("(%s) Incorrect status %s - should be %s\n", \
32 __location__, nt_errstr(status), nt_errstr(correct)); \
38 static BOOL test_sd(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
42 const char *fname = BASEDIR "\\sd.txt";
46 union smb_setfileinfo set;
47 struct security_ace ace;
48 struct security_descriptor *sd;
49 struct dom_sid *test_sid;
51 printf("TESTING SETFILEINFO EA_SET\n");
53 io.generic.level = RAW_OPEN_NTCREATEX;
54 io.ntcreatex.in.root_fid = 0;
55 io.ntcreatex.in.flags = 0;
56 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
57 io.ntcreatex.in.create_options = 0;
58 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
59 io.ntcreatex.in.share_access =
60 NTCREATEX_SHARE_ACCESS_READ |
61 NTCREATEX_SHARE_ACCESS_WRITE;
62 io.ntcreatex.in.alloc_size = 0;
63 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
64 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
65 io.ntcreatex.in.security_flags = 0;
66 io.ntcreatex.in.fname = fname;
67 status = smb_raw_open(cli->tree, mem_ctx, &io);
68 CHECK_STATUS(status, NT_STATUS_OK);
69 fnum = io.ntcreatex.out.fnum;
71 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
72 q.query_secdesc.in.fnum = fnum;
73 q.query_secdesc.in.secinfo_flags =
77 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
78 CHECK_STATUS(status, NT_STATUS_OK);
79 sd = q.query_secdesc.out.sd;
81 printf("add a new ACE to the DACL\n");
83 test_sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1234-5432");
85 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
87 ace.access_mask = SEC_STD_ALL;
88 ace.trustee = *test_sid;
90 status = security_descriptor_dacl_add(sd, &ace);
91 CHECK_STATUS(status, NT_STATUS_OK);
93 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
94 set.set_secdesc.file.fnum = fnum;
95 set.set_secdesc.in.secinfo_flags = q.query_secdesc.in.secinfo_flags;
96 set.set_secdesc.in.sd = sd;
98 status = smb_raw_setfileinfo(cli->tree, &set);
99 CHECK_STATUS(status, NT_STATUS_OK);
101 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
102 CHECK_STATUS(status, NT_STATUS_OK);
104 if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
105 printf("%s: security descriptors don't match!\n", __location__);
107 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
108 printf("expected:\n");
109 NDR_PRINT_DEBUG(security_descriptor, sd);
113 printf("remove it again\n");
115 status = security_descriptor_dacl_del(sd, test_sid);
116 CHECK_STATUS(status, NT_STATUS_OK);
118 status = smb_raw_setfileinfo(cli->tree, &set);
119 CHECK_STATUS(status, NT_STATUS_OK);
121 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
122 CHECK_STATUS(status, NT_STATUS_OK);
124 if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
125 printf("%s: security descriptors don't match!\n", __location__);
127 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
128 printf("expected:\n");
129 NDR_PRINT_DEBUG(security_descriptor, sd);
134 smbcli_close(cli->tree, fnum);
140 test using NTTRANS CREATE to create a file with an initial ACL set
142 static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
146 const char *fname = BASEDIR "\\acl2.txt";
149 union smb_fileinfo q;
150 struct security_ace ace;
151 struct security_descriptor *sd;
152 struct dom_sid *test_sid;
154 printf("TESTING NTTRANS CREATE WITH SEC_DESC\n");
156 io.generic.level = RAW_OPEN_NTTRANS_CREATE;
157 io.ntcreatex.in.root_fid = 0;
158 io.ntcreatex.in.flags = 0;
159 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
160 io.ntcreatex.in.create_options = 0;
161 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
162 io.ntcreatex.in.share_access =
163 NTCREATEX_SHARE_ACCESS_READ |
164 NTCREATEX_SHARE_ACCESS_WRITE;
165 io.ntcreatex.in.alloc_size = 0;
166 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
167 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
168 io.ntcreatex.in.security_flags = 0;
169 io.ntcreatex.in.fname = fname;
170 io.ntcreatex.in.sec_desc = NULL;
171 io.ntcreatex.in.ea_list = NULL;
173 printf("creating normal file\n");
175 status = smb_raw_open(cli->tree, mem_ctx, &io);
176 CHECK_STATUS(status, NT_STATUS_OK);
177 fnum = io.ntcreatex.out.fnum;
179 printf("querying ACL\n");
181 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
182 q.query_secdesc.in.fnum = fnum;
183 q.query_secdesc.in.secinfo_flags =
187 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
188 CHECK_STATUS(status, NT_STATUS_OK);
189 sd = q.query_secdesc.out.sd;
191 smbcli_close(cli->tree, fnum);
192 smbcli_unlink(cli->tree, fname);
194 printf("adding a new ACE\n");
195 test_sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1234-54321");
197 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
199 ace.access_mask = SEC_STD_ALL;
200 ace.trustee = *test_sid;
202 status = security_descriptor_dacl_add(sd, &ace);
203 CHECK_STATUS(status, NT_STATUS_OK);
205 printf("creating a file with an initial ACL\n");
207 io.ntcreatex.in.sec_desc = sd;
208 status = smb_raw_open(cli->tree, mem_ctx, &io);
209 CHECK_STATUS(status, NT_STATUS_OK);
210 fnum = io.ntcreatex.out.fnum;
212 q.query_secdesc.in.fnum = fnum;
213 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
214 CHECK_STATUS(status, NT_STATUS_OK);
216 if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
217 printf("%s: security descriptors don't match!\n", __location__);
219 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
220 printf("expected:\n");
221 NDR_PRINT_DEBUG(security_descriptor, sd);
226 smbcli_close(cli->tree, fnum);
230 #define CHECK_ACCESS_FLAGS(_fnum, flags) do { \
231 union smb_fileinfo _q; \
232 _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
233 _q.access_information.in.fnum = (_fnum); \
234 status = smb_raw_fileinfo(cli->tree, mem_ctx, &_q); \
235 CHECK_STATUS(status, NT_STATUS_OK); \
236 if (_q.access_information.out.access_flags != (flags)) { \
237 printf("(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
238 __location__, _q.access_information.out.access_flags, (flags)); \
246 test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
249 static BOOL test_creator_sid(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
253 const char *fname = BASEDIR "\\creator.txt";
256 union smb_fileinfo q;
257 union smb_setfileinfo set;
258 struct security_descriptor *sd, *sd_orig, *sd2;
259 const char *owner_sid;
261 printf("TESTING SID_CREATOR_OWNER\n");
263 io.generic.level = RAW_OPEN_NTCREATEX;
264 io.ntcreatex.in.root_fid = 0;
265 io.ntcreatex.in.flags = 0;
266 io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
267 io.ntcreatex.in.create_options = 0;
268 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
269 io.ntcreatex.in.share_access =
270 NTCREATEX_SHARE_ACCESS_READ |
271 NTCREATEX_SHARE_ACCESS_WRITE;
272 io.ntcreatex.in.alloc_size = 0;
273 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
274 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
275 io.ntcreatex.in.security_flags = 0;
276 io.ntcreatex.in.fname = fname;
277 status = smb_raw_open(cli->tree, mem_ctx, &io);
278 CHECK_STATUS(status, NT_STATUS_OK);
279 fnum = io.ntcreatex.out.fnum;
281 printf("get the original sd\n");
282 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
283 q.query_secdesc.in.fnum = fnum;
284 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
285 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
286 CHECK_STATUS(status, NT_STATUS_OK);
287 sd_orig = q.query_secdesc.out.sd;
289 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
291 printf("set a sec desc allowing no write by CREATOR_OWNER\n");
292 sd = security_descriptor_create(mem_ctx,
295 SEC_ACE_TYPE_ACCESS_ALLOWED,
296 SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
300 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
301 set.set_secdesc.file.fnum = fnum;
302 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
303 set.set_secdesc.in.sd = sd;
305 status = smb_raw_setfileinfo(cli->tree, &set);
306 CHECK_STATUS(status, NT_STATUS_OK);
308 printf("try open for write\n");
309 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
310 status = smb_raw_open(cli->tree, mem_ctx, &io);
311 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
313 printf("try open for read\n");
314 io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
315 status = smb_raw_open(cli->tree, mem_ctx, &io);
316 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
318 printf("try open for generic write\n");
319 io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
320 status = smb_raw_open(cli->tree, mem_ctx, &io);
321 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
323 printf("try open for generic read\n");
324 io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
325 status = smb_raw_open(cli->tree, mem_ctx, &io);
326 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
328 printf("set a sec desc allowing no write by owner\n");
329 sd = security_descriptor_create(mem_ctx,
332 SEC_ACE_TYPE_ACCESS_ALLOWED,
333 SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
337 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
338 set.set_secdesc.file.fnum = fnum;
339 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
340 set.set_secdesc.in.sd = sd;
341 status = smb_raw_setfileinfo(cli->tree, &set);
342 CHECK_STATUS(status, NT_STATUS_OK);
344 printf("check that sd has been mapped correctly\n");
345 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
346 CHECK_STATUS(status, NT_STATUS_OK);
347 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd)) {
348 printf("%s: security descriptors don't match!\n", __location__);
350 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
351 printf("expected:\n");
352 NDR_PRINT_DEBUG(security_descriptor, sd);
356 printf("try open for write\n");
357 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
358 status = smb_raw_open(cli->tree, mem_ctx, &io);
359 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
361 printf("try open for read\n");
362 io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
363 status = smb_raw_open(cli->tree, mem_ctx, &io);
364 CHECK_STATUS(status, NT_STATUS_OK);
365 CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum,
367 SEC_FILE_READ_ATTRIBUTE);
368 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
370 printf("try open for generic write\n");
371 io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
372 status = smb_raw_open(cli->tree, mem_ctx, &io);
373 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
375 printf("try open for generic read\n");
376 io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
377 status = smb_raw_open(cli->tree, mem_ctx, &io);
378 CHECK_STATUS(status, NT_STATUS_OK);
379 CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum,
380 SEC_RIGHTS_FILE_READ);
381 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
383 printf("set a sec desc allowing generic read by owner\n");
384 sd = security_descriptor_create(mem_ctx,
387 SEC_ACE_TYPE_ACCESS_ALLOWED,
388 SEC_GENERIC_READ | SEC_STD_ALL,
392 set.set_secdesc.in.sd = sd;
393 status = smb_raw_setfileinfo(cli->tree, &set);
394 CHECK_STATUS(status, NT_STATUS_OK);
396 printf("check that generic read has been mapped correctly\n");
397 sd2 = security_descriptor_create(mem_ctx,
400 SEC_ACE_TYPE_ACCESS_ALLOWED,
401 SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
405 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
406 CHECK_STATUS(status, NT_STATUS_OK);
407 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
408 printf("%s: security descriptors don't match!\n", __location__);
410 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
411 printf("expected:\n");
412 NDR_PRINT_DEBUG(security_descriptor, sd2);
417 printf("try open for write\n");
418 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
419 status = smb_raw_open(cli->tree, mem_ctx, &io);
420 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
422 printf("try open for read\n");
423 io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
424 status = smb_raw_open(cli->tree, mem_ctx, &io);
425 CHECK_STATUS(status, NT_STATUS_OK);
426 CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum,
428 SEC_FILE_READ_ATTRIBUTE);
429 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
431 printf("try open for generic write\n");
432 io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
433 status = smb_raw_open(cli->tree, mem_ctx, &io);
434 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
436 printf("try open for generic read\n");
437 io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
438 status = smb_raw_open(cli->tree, mem_ctx, &io);
439 CHECK_STATUS(status, NT_STATUS_OK);
440 CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum, SEC_RIGHTS_FILE_READ);
441 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
444 printf("put back original sd\n");
445 set.set_secdesc.in.sd = sd_orig;
446 status = smb_raw_setfileinfo(cli->tree, &set);
447 CHECK_STATUS(status, NT_STATUS_OK);
451 smbcli_close(cli->tree, fnum);
457 test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
460 static BOOL test_generic_bits(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
464 const char *fname = BASEDIR "\\generic.txt";
467 union smb_fileinfo q;
468 union smb_setfileinfo set;
469 struct security_descriptor *sd, *sd_orig, *sd2;
470 const char *owner_sid;
473 uint32_t specific_bits;
474 } file_mappings[] = {
476 { SEC_GENERIC_READ, SEC_RIGHTS_FILE_READ },
477 { SEC_GENERIC_WRITE, SEC_RIGHTS_FILE_WRITE },
478 { SEC_GENERIC_EXECUTE, SEC_RIGHTS_FILE_EXECUTE },
479 { SEC_GENERIC_ALL, SEC_RIGHTS_FILE_ALL },
480 { SEC_FILE_READ_DATA, SEC_FILE_READ_DATA },
481 { SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_ATTRIBUTE }
485 uint32_t specific_bits;
488 { SEC_GENERIC_READ, SEC_RIGHTS_DIR_READ },
489 { SEC_GENERIC_WRITE, SEC_RIGHTS_DIR_WRITE },
490 { SEC_GENERIC_EXECUTE, SEC_RIGHTS_DIR_EXECUTE },
491 { SEC_GENERIC_ALL, SEC_RIGHTS_DIR_ALL }
493 BOOL has_restore_privilege;
494 BOOL has_take_ownership_privilege;
496 printf("TESTING FILE GENERIC BITS\n");
498 io.generic.level = RAW_OPEN_NTCREATEX;
499 io.ntcreatex.in.root_fid = 0;
500 io.ntcreatex.in.flags = 0;
501 io.ntcreatex.in.access_mask =
502 SEC_STD_READ_CONTROL |
505 io.ntcreatex.in.create_options = 0;
506 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
507 io.ntcreatex.in.share_access =
508 NTCREATEX_SHARE_ACCESS_READ |
509 NTCREATEX_SHARE_ACCESS_WRITE;
510 io.ntcreatex.in.alloc_size = 0;
511 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
512 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
513 io.ntcreatex.in.security_flags = 0;
514 io.ntcreatex.in.fname = fname;
515 status = smb_raw_open(cli->tree, mem_ctx, &io);
516 CHECK_STATUS(status, NT_STATUS_OK);
517 fnum = io.ntcreatex.out.fnum;
519 printf("get the original sd\n");
520 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
521 q.query_secdesc.in.fnum = fnum;
522 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
523 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
524 CHECK_STATUS(status, NT_STATUS_OK);
525 sd_orig = q.query_secdesc.out.sd;
527 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
529 status = smblsa_sid_check_privilege(cli,
531 sec_privilege_name(SEC_PRIV_RESTORE));
532 has_restore_privilege = NT_STATUS_IS_OK(status);
533 if (!NT_STATUS_IS_OK(status)) {
534 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
536 printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
538 status = smblsa_sid_check_privilege(cli,
540 sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
541 has_take_ownership_privilege = NT_STATUS_IS_OK(status);
542 if (!NT_STATUS_IS_OK(status)) {
543 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
545 printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_restore_privilege?"Yes":"No");
547 for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
548 uint32_t expected_mask =
550 SEC_STD_READ_CONTROL |
551 SEC_FILE_READ_ATTRIBUTE |
553 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
555 if (has_restore_privilege) {
556 expected_mask_anon |= SEC_STD_DELETE;
559 printf("testing generic bits 0x%08x\n",
560 file_mappings[i].gen_bits);
561 sd = security_descriptor_create(mem_ctx,
564 SEC_ACE_TYPE_ACCESS_ALLOWED,
565 file_mappings[i].gen_bits,
569 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
570 set.set_secdesc.file.fnum = fnum;
571 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
572 set.set_secdesc.in.sd = sd;
574 status = smb_raw_setfileinfo(cli->tree, &set);
575 CHECK_STATUS(status, NT_STATUS_OK);
577 sd2 = security_descriptor_create(mem_ctx,
580 SEC_ACE_TYPE_ACCESS_ALLOWED,
581 file_mappings[i].specific_bits,
585 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
586 CHECK_STATUS(status, NT_STATUS_OK);
587 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
588 printf("%s: security descriptors don't match!\n", __location__);
590 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
591 printf("expected:\n");
592 NDR_PRINT_DEBUG(security_descriptor, sd2);
596 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
597 status = smb_raw_open(cli->tree, mem_ctx, &io);
598 CHECK_STATUS(status, NT_STATUS_OK);
599 CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum,
600 expected_mask | file_mappings[i].specific_bits);
601 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
603 if (!has_take_ownership_privilege) {
607 printf("testing generic bits 0x%08x (anonymous)\n",
608 file_mappings[i].gen_bits);
609 sd = security_descriptor_create(mem_ctx,
610 SID_NT_ANONYMOUS, NULL,
612 SEC_ACE_TYPE_ACCESS_ALLOWED,
613 file_mappings[i].gen_bits,
617 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
618 set.set_secdesc.file.fnum = fnum;
619 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
620 set.set_secdesc.in.sd = sd;
622 status = smb_raw_setfileinfo(cli->tree, &set);
623 CHECK_STATUS(status, NT_STATUS_OK);
625 sd2 = security_descriptor_create(mem_ctx,
626 SID_NT_ANONYMOUS, NULL,
628 SEC_ACE_TYPE_ACCESS_ALLOWED,
629 file_mappings[i].specific_bits,
633 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
634 CHECK_STATUS(status, NT_STATUS_OK);
635 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
636 printf("%s: security descriptors don't match!\n", __location__);
638 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
639 printf("expected:\n");
640 NDR_PRINT_DEBUG(security_descriptor, sd2);
644 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
645 status = smb_raw_open(cli->tree, mem_ctx, &io);
646 CHECK_STATUS(status, NT_STATUS_OK);
647 CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum,
648 expected_mask_anon | file_mappings[i].specific_bits);
649 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
652 printf("put back original sd\n");
653 set.set_secdesc.in.sd = sd_orig;
654 status = smb_raw_setfileinfo(cli->tree, &set);
655 CHECK_STATUS(status, NT_STATUS_OK);
657 smbcli_close(cli->tree, fnum);
658 smbcli_unlink(cli->tree, fname);
661 printf("TESTING DIR GENERIC BITS\n");
663 io.generic.level = RAW_OPEN_NTCREATEX;
664 io.ntcreatex.in.root_fid = 0;
665 io.ntcreatex.in.flags = 0;
666 io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC;
667 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
668 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
669 io.ntcreatex.in.share_access =
670 NTCREATEX_SHARE_ACCESS_READ |
671 NTCREATEX_SHARE_ACCESS_WRITE;
672 io.ntcreatex.in.alloc_size = 0;
673 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
674 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
675 io.ntcreatex.in.security_flags = 0;
676 io.ntcreatex.in.fname = fname;
677 status = smb_raw_open(cli->tree, mem_ctx, &io);
678 CHECK_STATUS(status, NT_STATUS_OK);
679 fnum = io.ntcreatex.out.fnum;
681 printf("get the original sd\n");
682 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
683 q.query_secdesc.in.fnum = fnum;
684 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
685 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
686 CHECK_STATUS(status, NT_STATUS_OK);
687 sd_orig = q.query_secdesc.out.sd;
689 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
692 for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
693 uint32_t expected_mask =
695 SEC_STD_READ_CONTROL |
696 SEC_FILE_READ_ATTRIBUTE |
699 printf("testing generic bits 0x%08x\n",
700 file_mappings[i].gen_bits);
701 sd = security_descriptor_create(mem_ctx,
704 SEC_ACE_TYPE_ACCESS_ALLOWED,
705 dir_mappings[i].gen_bits,
709 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
710 set.set_secdesc.file.fnum = fnum;
711 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
712 set.set_secdesc.in.sd = sd;
714 status = smb_raw_setfileinfo(cli->tree, &set);
715 CHECK_STATUS(status, NT_STATUS_OK);
717 sd2 = security_descriptor_create(mem_ctx,
720 SEC_ACE_TYPE_ACCESS_ALLOWED,
721 dir_mappings[i].specific_bits,
725 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
726 CHECK_STATUS(status, NT_STATUS_OK);
727 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
728 printf("%s: security descriptors don't match!\n", __location__);
730 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
731 printf("expected:\n");
732 NDR_PRINT_DEBUG(security_descriptor, sd2);
736 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
737 status = smb_raw_open(cli->tree, mem_ctx, &io);
738 CHECK_STATUS(status, NT_STATUS_OK);
739 CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum,
740 expected_mask | dir_mappings[i].specific_bits);
741 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
744 printf("put back original sd\n");
745 set.set_secdesc.in.sd = sd_orig;
746 status = smb_raw_setfileinfo(cli->tree, &set);
747 CHECK_STATUS(status, NT_STATUS_OK);
749 smbcli_close(cli->tree, fnum);
750 smbcli_unlink(cli->tree, fname);
753 smbcli_close(cli->tree, fnum);
759 see what access bits the owner of a file always gets
761 static BOOL test_owner_bits(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
765 const char *fname = BASEDIR "\\generic.txt";
768 union smb_fileinfo q;
769 union smb_setfileinfo set;
770 struct security_descriptor *sd, *sd_orig;
771 const char *owner_sid;
772 BOOL has_restore_privilege;
773 BOOL has_take_ownership_privilege;
774 uint32_t expected_bits;
776 printf("TESTING FILE OWNER BITS\n");
778 io.generic.level = RAW_OPEN_NTCREATEX;
779 io.ntcreatex.in.root_fid = 0;
780 io.ntcreatex.in.flags = 0;
781 io.ntcreatex.in.access_mask =
782 SEC_STD_READ_CONTROL |
785 io.ntcreatex.in.create_options = 0;
786 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
787 io.ntcreatex.in.share_access =
788 NTCREATEX_SHARE_ACCESS_READ |
789 NTCREATEX_SHARE_ACCESS_WRITE;
790 io.ntcreatex.in.alloc_size = 0;
791 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
792 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
793 io.ntcreatex.in.security_flags = 0;
794 io.ntcreatex.in.fname = fname;
795 status = smb_raw_open(cli->tree, mem_ctx, &io);
796 CHECK_STATUS(status, NT_STATUS_OK);
797 fnum = io.ntcreatex.out.fnum;
799 printf("get the original sd\n");
800 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
801 q.query_secdesc.in.fnum = fnum;
802 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
803 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
804 CHECK_STATUS(status, NT_STATUS_OK);
805 sd_orig = q.query_secdesc.out.sd;
807 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
809 status = smblsa_sid_check_privilege(cli,
811 sec_privilege_name(SEC_PRIV_RESTORE));
812 has_restore_privilege = NT_STATUS_IS_OK(status);
813 if (!NT_STATUS_IS_OK(status)) {
814 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
816 printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
818 status = smblsa_sid_check_privilege(cli,
820 sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
821 has_take_ownership_privilege = NT_STATUS_IS_OK(status);
822 if (!NT_STATUS_IS_OK(status)) {
823 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
825 printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_restore_privilege?"Yes":"No");
827 sd = security_descriptor_create(mem_ctx,
830 SEC_ACE_TYPE_ACCESS_ALLOWED,
835 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
836 set.set_secdesc.file.fnum = fnum;
837 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
838 set.set_secdesc.in.sd = sd;
840 status = smb_raw_setfileinfo(cli->tree, &set);
841 CHECK_STATUS(status, NT_STATUS_OK);
843 expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
847 io.ntcreatex.in.access_mask = bit;
848 status = smb_raw_open(cli->tree, mem_ctx, &io);
849 if (expected_bits & bit) {
850 if (!NT_STATUS_IS_OK(status)) {
851 printf("failed with access mask 0x%08x of expected 0x%08x\n",
854 CHECK_STATUS(status, NT_STATUS_OK);
855 CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum, bit | SEC_FILE_READ_ATTRIBUTE);
856 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
858 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
862 printf("put back original sd\n");
863 set.set_secdesc.in.sd = sd_orig;
864 status = smb_raw_setfileinfo(cli->tree, &set);
865 CHECK_STATUS(status, NT_STATUS_OK);
868 smbcli_close(cli->tree, fnum);
869 smbcli_unlink(cli->tree, fname);
876 test the inheritance of ACL flags onto new files and directories
878 static BOOL test_inheritance(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
882 const char *dname = BASEDIR "\\inheritance";
883 const char *fname1 = BASEDIR "\\inheritance\\testfile";
884 const char *fname2 = BASEDIR "\\inheritance\\testdir";
887 union smb_fileinfo q;
888 union smb_setfileinfo set;
889 struct security_descriptor *sd, *sd_orig, *sd_def;
890 const char *owner_sid;
891 const struct dom_sid *creator_owner;
893 uint32_t parent_flags;
903 SEC_ACE_FLAG_OBJECT_INHERIT,
905 SEC_ACE_FLAG_OBJECT_INHERIT |
906 SEC_ACE_FLAG_INHERIT_ONLY,
909 SEC_ACE_FLAG_CONTAINER_INHERIT,
911 SEC_ACE_FLAG_CONTAINER_INHERIT,
914 SEC_ACE_FLAG_OBJECT_INHERIT |
915 SEC_ACE_FLAG_CONTAINER_INHERIT,
917 SEC_ACE_FLAG_OBJECT_INHERIT |
918 SEC_ACE_FLAG_CONTAINER_INHERIT,
921 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
926 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
927 SEC_ACE_FLAG_OBJECT_INHERIT,
932 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
933 SEC_ACE_FLAG_CONTAINER_INHERIT,
938 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
939 SEC_ACE_FLAG_CONTAINER_INHERIT |
940 SEC_ACE_FLAG_OBJECT_INHERIT,
945 SEC_ACE_FLAG_INHERIT_ONLY,
950 SEC_ACE_FLAG_INHERIT_ONLY |
951 SEC_ACE_FLAG_OBJECT_INHERIT,
953 SEC_ACE_FLAG_OBJECT_INHERIT |
954 SEC_ACE_FLAG_INHERIT_ONLY,
957 SEC_ACE_FLAG_INHERIT_ONLY |
958 SEC_ACE_FLAG_CONTAINER_INHERIT,
960 SEC_ACE_FLAG_CONTAINER_INHERIT,
963 SEC_ACE_FLAG_INHERIT_ONLY |
964 SEC_ACE_FLAG_CONTAINER_INHERIT |
965 SEC_ACE_FLAG_OBJECT_INHERIT,
967 SEC_ACE_FLAG_CONTAINER_INHERIT |
968 SEC_ACE_FLAG_OBJECT_INHERIT,
971 SEC_ACE_FLAG_INHERIT_ONLY |
972 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
977 SEC_ACE_FLAG_INHERIT_ONLY |
978 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
979 SEC_ACE_FLAG_OBJECT_INHERIT,
984 SEC_ACE_FLAG_INHERIT_ONLY |
985 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
986 SEC_ACE_FLAG_CONTAINER_INHERIT,
991 SEC_ACE_FLAG_INHERIT_ONLY |
992 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
993 SEC_ACE_FLAG_CONTAINER_INHERIT |
994 SEC_ACE_FLAG_OBJECT_INHERIT,
1000 smbcli_rmdir(cli->tree, dname);
1002 printf("TESTING ACL INHERITANCE\n");
1004 io.generic.level = RAW_OPEN_NTCREATEX;
1005 io.ntcreatex.in.root_fid = 0;
1006 io.ntcreatex.in.flags = 0;
1007 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1008 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1009 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1010 io.ntcreatex.in.share_access = 0;
1011 io.ntcreatex.in.alloc_size = 0;
1012 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1013 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1014 io.ntcreatex.in.security_flags = 0;
1015 io.ntcreatex.in.fname = dname;
1017 status = smb_raw_open(cli->tree, mem_ctx, &io);
1018 CHECK_STATUS(status, NT_STATUS_OK);
1019 fnum = io.ntcreatex.out.fnum;
1021 printf("get the original sd\n");
1022 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1023 q.query_secdesc.in.fnum = fnum;
1024 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1025 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1026 CHECK_STATUS(status, NT_STATUS_OK);
1027 sd_orig = q.query_secdesc.out.sd;
1029 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
1031 printf("owner_sid is %s\n", owner_sid);
1033 sd_def = security_descriptor_create(mem_ctx,
1036 SEC_ACE_TYPE_ACCESS_ALLOWED,
1037 SEC_RIGHTS_FILE_ALL,
1040 SEC_ACE_TYPE_ACCESS_ALLOWED,
1041 SEC_RIGHTS_FILE_ALL,
1045 creator_owner = dom_sid_parse_talloc(mem_ctx, SID_CREATOR_OWNER);
1047 for (i=0;i<ARRAY_SIZE(test_flags);i++) {
1048 sd = security_descriptor_create(mem_ctx,
1051 SEC_ACE_TYPE_ACCESS_ALLOWED,
1052 SEC_FILE_WRITE_DATA,
1053 test_flags[i].parent_flags,
1055 SEC_ACE_TYPE_ACCESS_ALLOWED,
1056 SEC_FILE_ALL | SEC_STD_ALL,
1059 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1060 set.set_secdesc.file.fnum = fnum;
1061 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1062 set.set_secdesc.in.sd = sd;
1063 status = smb_raw_setfileinfo(cli->tree, &set);
1064 CHECK_STATUS(status, NT_STATUS_OK);
1066 io.ntcreatex.in.fname = fname1;
1067 io.ntcreatex.in.create_options = 0;
1068 status = smb_raw_open(cli->tree, mem_ctx, &io);
1069 CHECK_STATUS(status, NT_STATUS_OK);
1070 fnum2 = io.ntcreatex.out.fnum;
1072 q.query_secdesc.in.fnum = fnum2;
1073 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1074 CHECK_STATUS(status, NT_STATUS_OK);
1076 smbcli_close(cli->tree, fnum2);
1077 smbcli_unlink(cli->tree, fname1);
1079 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
1080 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1081 printf("Expected default sd at %d - got:\n", i);
1082 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1087 if (q.query_secdesc.out.sd->dacl == NULL ||
1088 q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1089 q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1090 !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1091 sd_orig->owner_sid)) {
1092 printf("Bad sd in child file at %d\n", i);
1093 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1098 if (q.query_secdesc.out.sd->dacl->aces[0].flags !=
1099 test_flags[i].file_flags) {
1100 printf("incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
1101 q.query_secdesc.out.sd->dacl->aces[0].flags,
1102 test_flags[i].file_flags,
1103 test_flags[i].parent_flags,
1109 io.ntcreatex.in.fname = fname2;
1110 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1111 status = smb_raw_open(cli->tree, mem_ctx, &io);
1112 CHECK_STATUS(status, NT_STATUS_OK);
1113 fnum2 = io.ntcreatex.out.fnum;
1115 q.query_secdesc.in.fnum = fnum2;
1116 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1117 CHECK_STATUS(status, NT_STATUS_OK);
1119 smbcli_close(cli->tree, fnum2);
1120 smbcli_rmdir(cli->tree, fname2);
1122 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1123 (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
1124 (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
1125 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1126 printf("Expected default sd for dir at %d - got:\n", i);
1127 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1132 if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1133 (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
1134 if (q.query_secdesc.out.sd->dacl == NULL ||
1135 q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1136 q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1137 !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1138 sd_orig->owner_sid) ||
1139 q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1140 printf("Bad sd in child dir at %d (parent 0x%x)\n",
1141 i, test_flags[i].parent_flags);
1142 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1146 } else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
1147 if (q.query_secdesc.out.sd->dacl == NULL ||
1148 q.query_secdesc.out.sd->dacl->num_aces != 2 ||
1149 q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1150 !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1151 sd_orig->owner_sid) ||
1152 q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
1153 !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
1155 q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
1156 q.query_secdesc.out.sd->dacl->aces[1].flags !=
1157 (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
1158 printf("Bad sd in child dir at %d (parent 0x%x)\n",
1159 i, test_flags[i].parent_flags);
1160 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1165 if (q.query_secdesc.out.sd->dacl == NULL ||
1166 q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1167 q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1168 !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1170 q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1171 printf("Bad sd in child dir at %d (parent 0x%x)\n",
1172 i, test_flags[i].parent_flags);
1173 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1180 printf("testing access checks on inherited create with %s\n", fname1);
1181 sd = security_descriptor_create(mem_ctx,
1184 SEC_ACE_TYPE_ACCESS_ALLOWED,
1185 SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1186 SEC_ACE_FLAG_OBJECT_INHERIT,
1188 SEC_ACE_TYPE_ACCESS_ALLOWED,
1189 SEC_FILE_ALL | SEC_STD_ALL,
1192 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1193 set.set_secdesc.file.fnum = fnum;
1194 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1195 set.set_secdesc.in.sd = sd;
1196 status = smb_raw_setfileinfo(cli->tree, &set);
1197 CHECK_STATUS(status, NT_STATUS_OK);
1199 io.ntcreatex.in.fname = fname1;
1200 io.ntcreatex.in.create_options = 0;
1201 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1202 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1203 status = smb_raw_open(cli->tree, mem_ctx, &io);
1204 CHECK_STATUS(status, NT_STATUS_OK);
1205 fnum2 = io.ntcreatex.out.fnum;
1206 CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1208 q.query_secdesc.in.fnum = fnum2;
1209 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1210 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1211 CHECK_STATUS(status, NT_STATUS_OK);
1212 smbcli_close(cli->tree, fnum2);
1214 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1215 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1216 status = smb_raw_open(cli->tree, mem_ctx, &io);
1217 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1219 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1220 status = smb_raw_open(cli->tree, mem_ctx, &io);
1221 CHECK_STATUS(status, NT_STATUS_OK);
1222 fnum2 = io.ntcreatex.out.fnum;
1223 CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1224 smbcli_close(cli->tree, fnum2);
1226 printf("put back original sd\n");
1227 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1228 set.set_secdesc.file.fnum = fnum;
1229 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1230 set.set_secdesc.in.sd = sd_orig;
1231 status = smb_raw_setfileinfo(cli->tree, &set);
1232 CHECK_STATUS(status, NT_STATUS_OK);
1234 smbcli_close(cli->tree, fnum);
1236 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1237 status = smb_raw_open(cli->tree, mem_ctx, &io);
1238 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1240 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1241 status = smb_raw_open(cli->tree, mem_ctx, &io);
1242 CHECK_STATUS(status, NT_STATUS_OK);
1243 fnum2 = io.ntcreatex.out.fnum;
1244 CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1245 smbcli_close(cli->tree, fnum2);
1247 smbcli_unlink(cli->tree, fname1);
1248 smbcli_rmdir(cli->tree, dname);
1251 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1252 set.set_secdesc.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);
1257 smbcli_close(cli->tree, fnum);
1263 test dynamic acl inheritance
1265 static BOOL test_inheritance_dynamic(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
1269 const char *dname = BASEDIR "\\inheritance";
1270 const char *fname1 = BASEDIR "\\inheritance\\testfile";
1273 union smb_fileinfo q;
1274 union smb_setfileinfo set;
1275 struct security_descriptor *sd, *sd_orig;
1276 const char *owner_sid;
1278 printf("TESTING DYNAMIC ACL INHERITANCE\n");
1280 if (!torture_setup_dir(cli, BASEDIR)) {
1284 io.generic.level = RAW_OPEN_NTCREATEX;
1285 io.ntcreatex.in.root_fid = 0;
1286 io.ntcreatex.in.flags = 0;
1287 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1288 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1289 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1290 io.ntcreatex.in.share_access = 0;
1291 io.ntcreatex.in.alloc_size = 0;
1292 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1293 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1294 io.ntcreatex.in.security_flags = 0;
1295 io.ntcreatex.in.fname = dname;
1297 status = smb_raw_open(cli->tree, mem_ctx, &io);
1298 CHECK_STATUS(status, NT_STATUS_OK);
1299 fnum = io.ntcreatex.out.fnum;
1301 printf("get the original sd\n");
1302 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1303 q.query_secdesc.in.fnum = fnum;
1304 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1305 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1306 CHECK_STATUS(status, NT_STATUS_OK);
1307 sd_orig = q.query_secdesc.out.sd;
1309 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
1311 printf("owner_sid is %s\n", owner_sid);
1313 sd = security_descriptor_create(mem_ctx,
1316 SEC_ACE_TYPE_ACCESS_ALLOWED,
1317 SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
1318 SEC_ACE_FLAG_OBJECT_INHERIT,
1320 sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1322 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1323 set.set_secdesc.file.fnum = fnum;
1324 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1325 set.set_secdesc.in.sd = sd;
1326 status = smb_raw_setfileinfo(cli->tree, &set);
1327 CHECK_STATUS(status, NT_STATUS_OK);
1329 printf("create a file with an inherited acl\n");
1330 io.ntcreatex.in.fname = fname1;
1331 io.ntcreatex.in.create_options = 0;
1332 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE;
1333 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1334 status = smb_raw_open(cli->tree, mem_ctx, &io);
1335 CHECK_STATUS(status, NT_STATUS_OK);
1336 fnum2 = io.ntcreatex.out.fnum;
1337 smbcli_close(cli->tree, fnum2);
1339 printf("try and access file with base rights - should be OK\n");
1340 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1341 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1342 status = smb_raw_open(cli->tree, mem_ctx, &io);
1343 CHECK_STATUS(status, NT_STATUS_OK);
1344 fnum2 = io.ntcreatex.out.fnum;
1345 smbcli_close(cli->tree, fnum2);
1347 printf("try and access file with extra rights - should be denied\n");
1348 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1349 status = smb_raw_open(cli->tree, mem_ctx, &io);
1350 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1352 printf("update parent sd\n");
1353 sd = security_descriptor_create(mem_ctx,
1356 SEC_ACE_TYPE_ACCESS_ALLOWED,
1357 SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE,
1358 SEC_ACE_FLAG_OBJECT_INHERIT,
1360 sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1362 set.set_secdesc.in.sd = sd;
1363 status = smb_raw_setfileinfo(cli->tree, &set);
1364 CHECK_STATUS(status, NT_STATUS_OK);
1366 printf("try and access file with base rights - should be OK\n");
1367 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1368 status = smb_raw_open(cli->tree, mem_ctx, &io);
1369 CHECK_STATUS(status, NT_STATUS_OK);
1370 fnum2 = io.ntcreatex.out.fnum;
1371 smbcli_close(cli->tree, fnum2);
1374 printf("try and access now - should be OK if dynamic inheritance works\n");
1375 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1376 status = smb_raw_open(cli->tree, mem_ctx, &io);
1377 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1378 printf("Server does not have dynamic inheritance\n");
1380 if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1381 printf("Server does have dynamic inheritance\n");
1383 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1385 smbcli_unlink(cli->tree, fname1);
1388 printf("put back original sd\n");
1389 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1390 set.set_secdesc.file.fnum = fnum;
1391 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1392 set.set_secdesc.in.sd = sd_orig;
1393 status = smb_raw_setfileinfo(cli->tree, &set);
1395 smbcli_close(cli->tree, fnum);
1396 smbcli_rmdir(cli->tree, dname);
1403 basic testing of security descriptor calls
1405 BOOL torture_raw_acls(void)
1407 struct smbcli_state *cli;
1409 TALLOC_CTX *mem_ctx;
1411 if (!torture_open_connection(&cli)) {
1415 mem_ctx = talloc_init("torture_raw_acls");
1417 if (!torture_setup_dir(cli, BASEDIR)) {
1421 ret &= test_sd(cli, mem_ctx);
1422 ret &= test_nttrans_create(cli, mem_ctx);
1423 ret &= test_creator_sid(cli, mem_ctx);
1424 ret &= test_generic_bits(cli, mem_ctx);
1425 ret &= test_owner_bits(cli, mem_ctx);
1426 ret &= test_inheritance(cli, mem_ctx);
1427 ret &= test_inheritance_dynamic(cli, mem_ctx);
1429 smb_raw_exit(cli->session);
1430 smbcli_deltree(cli->tree, BASEDIR);
1432 torture_close_connection(cli);
1433 talloc_destroy(mem_ctx);