r4612: make the output for the w2k3 acl bug a bit clearer
[Samba/gebeck_regimport.git] / source4 / torture / raw / acls.c
blobcc99b40050acc21a05f6cb58681a01d05e0af6ac
1 /*
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.
23 #include "includes.h"
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)); \
33 ret = False; \
34 goto done; \
35 }} while (0)
38 static BOOL test_sd(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
40 NTSTATUS status;
41 union smb_open io;
42 const char *fname = BASEDIR "\\sd.txt";
43 BOOL ret = True;
44 int fnum = -1;
45 union smb_fileinfo q;
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 =
74 SECINFO_OWNER |
75 SECINFO_GROUP |
76 SECINFO_DACL;
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;
86 ace.flags = 0;
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__);
106 printf("got:\n");
107 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
108 printf("expected:\n");
109 NDR_PRINT_DEBUG(security_descriptor, sd);
110 ret = False;
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__);
126 printf("got:\n");
127 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
128 printf("expected:\n");
129 NDR_PRINT_DEBUG(security_descriptor, sd);
130 ret = False;
133 done:
134 smbcli_close(cli->tree, fnum);
135 return ret;
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)
144 NTSTATUS status;
145 union smb_open io;
146 const char *fname = BASEDIR "\\acl2.txt";
147 BOOL ret = True;
148 int fnum = -1;
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 =
184 SECINFO_OWNER |
185 SECINFO_GROUP |
186 SECINFO_DACL;
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;
198 ace.flags = 0;
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__);
218 printf("got:\n");
219 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
220 printf("expected:\n");
221 NDR_PRINT_DEBUG(security_descriptor, sd);
222 ret = False;
225 done:
226 smbcli_close(cli->tree, fnum);
227 return ret;
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)); \
239 ret = False; \
240 goto done; \
242 } while (0)
246 test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
247 mapping bits
249 static BOOL test_creator_sid(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
251 NTSTATUS status;
252 union smb_open io;
253 const char *fname = BASEDIR "\\creator.txt";
254 BOOL ret = True;
255 int fnum = -1;
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,
293 NULL, NULL,
294 SID_CREATOR_OWNER,
295 SEC_ACE_TYPE_ACCESS_ALLOWED,
296 SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
298 NULL);
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,
330 owner_sid, NULL,
331 owner_sid,
332 SEC_ACE_TYPE_ACCESS_ALLOWED,
333 SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
335 NULL);
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__);
349 printf("got:\n");
350 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
351 printf("expected:\n");
352 NDR_PRINT_DEBUG(security_descriptor, sd);
353 ret = False;
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,
366 SEC_FILE_READ_DATA|
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,
385 NULL, NULL,
386 owner_sid,
387 SEC_ACE_TYPE_ACCESS_ALLOWED,
388 SEC_GENERIC_READ | SEC_STD_ALL,
390 NULL);
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,
398 owner_sid, NULL,
399 owner_sid,
400 SEC_ACE_TYPE_ACCESS_ALLOWED,
401 SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
403 NULL);
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__);
409 printf("got:\n");
410 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
411 printf("expected:\n");
412 NDR_PRINT_DEBUG(security_descriptor, sd2);
413 ret = False;
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,
427 SEC_FILE_READ_DATA |
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);
450 done:
451 smbcli_close(cli->tree, fnum);
452 return ret;
457 test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
458 SEC_FILE_xx bits
460 static BOOL test_generic_bits(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
462 NTSTATUS status;
463 union smb_open io;
464 const char *fname = BASEDIR "\\generic.txt";
465 BOOL ret = True;
466 int fnum = -1, i;
467 union smb_fileinfo q;
468 union smb_setfileinfo set;
469 struct security_descriptor *sd, *sd_orig, *sd2;
470 const char *owner_sid;
471 const struct {
472 uint32_t gen_bits;
473 uint32_t specific_bits;
474 } file_mappings[] = {
475 { 0, 0 },
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 }
483 const struct {
484 uint32_t gen_bits;
485 uint32_t specific_bits;
486 } dir_mappings[] = {
487 { 0, 0 },
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 |
503 SEC_STD_WRITE_DAC |
504 SEC_STD_WRITE_OWNER;
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,
530 owner_sid,
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,
539 owner_sid,
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 =
549 SEC_STD_WRITE_DAC |
550 SEC_STD_READ_CONTROL |
551 SEC_FILE_READ_ATTRIBUTE |
552 SEC_STD_DELETE;
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,
562 owner_sid, NULL,
563 owner_sid,
564 SEC_ACE_TYPE_ACCESS_ALLOWED,
565 file_mappings[i].gen_bits,
567 NULL);
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,
578 owner_sid, NULL,
579 owner_sid,
580 SEC_ACE_TYPE_ACCESS_ALLOWED,
581 file_mappings[i].specific_bits,
583 NULL);
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__);
589 printf("got:\n");
590 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
591 printf("expected:\n");
592 NDR_PRINT_DEBUG(security_descriptor, sd2);
593 ret = False;
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) {
604 continue;
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,
611 owner_sid,
612 SEC_ACE_TYPE_ACCESS_ALLOWED,
613 file_mappings[i].gen_bits,
615 NULL);
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,
627 owner_sid,
628 SEC_ACE_TYPE_ACCESS_ALLOWED,
629 file_mappings[i].specific_bits,
631 NULL);
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__);
637 printf("got:\n");
638 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
639 printf("expected:\n");
640 NDR_PRINT_DEBUG(security_descriptor, sd2);
641 ret = False;
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 =
694 SEC_STD_WRITE_DAC |
695 SEC_STD_READ_CONTROL |
696 SEC_FILE_READ_ATTRIBUTE |
697 SEC_STD_DELETE;
699 printf("testing generic bits 0x%08x\n",
700 file_mappings[i].gen_bits);
701 sd = security_descriptor_create(mem_ctx,
702 NULL, NULL,
703 owner_sid,
704 SEC_ACE_TYPE_ACCESS_ALLOWED,
705 dir_mappings[i].gen_bits,
707 NULL);
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,
718 owner_sid, NULL,
719 owner_sid,
720 SEC_ACE_TYPE_ACCESS_ALLOWED,
721 dir_mappings[i].specific_bits,
723 NULL);
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__);
729 printf("got:\n");
730 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
731 printf("expected:\n");
732 NDR_PRINT_DEBUG(security_descriptor, sd2);
733 ret = False;
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);
752 done:
753 smbcli_close(cli->tree, fnum);
754 return ret;
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)
763 NTSTATUS status;
764 union smb_open io;
765 const char *fname = BASEDIR "\\generic.txt";
766 BOOL ret = True;
767 int fnum = -1, i;
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 |
783 SEC_STD_WRITE_DAC |
784 SEC_STD_WRITE_OWNER;
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,
810 owner_sid,
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,
819 owner_sid,
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,
828 NULL, NULL,
829 owner_sid,
830 SEC_ACE_TYPE_ACCESS_ALLOWED,
831 SEC_FILE_WRITE_DATA,
833 NULL);
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;
845 for (i=0;i<16;i++) {
846 uint32 bit = (1<<i);
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",
852 bit, expected_bits);
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);
857 } else {
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);
867 done:
868 smbcli_close(cli->tree, fnum);
869 smbcli_unlink(cli->tree, fname);
870 return ret;
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)
880 NTSTATUS status;
881 union smb_open io;
882 const char *dname = BASEDIR "\\inheritance";
883 const char *fname1 = BASEDIR "\\inheritance\\testfile";
884 const char *fname2 = BASEDIR "\\inheritance\\testdir";
885 BOOL ret = True;
886 int fnum, fnum2, i;
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;
892 const struct {
893 uint32_t parent_flags;
894 uint32_t file_flags;
895 uint32_t dir_flags;
896 } test_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,
1034 owner_sid, NULL,
1035 owner_sid,
1036 SEC_ACE_TYPE_ACCESS_ALLOWED,
1037 SEC_RIGHTS_FILE_ALL,
1039 SID_NT_SYSTEM,
1040 SEC_ACE_TYPE_ACCESS_ALLOWED,
1041 SEC_RIGHTS_FILE_ALL,
1043 NULL);
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,
1049 NULL, NULL,
1050 SID_CREATOR_OWNER,
1051 SEC_ACE_TYPE_ACCESS_ALLOWED,
1052 SEC_FILE_WRITE_DATA,
1053 test_flags[i].parent_flags,
1054 SID_WORLD,
1055 SEC_ACE_TYPE_ACCESS_ALLOWED,
1056 SEC_FILE_ALL | SEC_STD_ALL,
1058 NULL);
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);
1084 goto check_dir;
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);
1094 ret = False;
1095 goto check_dir;
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,
1105 ret = False;
1108 check_dir:
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);
1129 continue;
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);
1143 ret = False;
1144 continue;
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,
1154 creator_owner) ||
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);
1161 ret = False;
1162 continue;
1164 } else {
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,
1169 creator_owner) ||
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);
1174 ret = False;
1175 continue;
1180 printf("testing access checks on inherited create with %s\n", fname1);
1181 sd = security_descriptor_create(mem_ctx,
1182 NULL, NULL,
1183 owner_sid,
1184 SEC_ACE_TYPE_ACCESS_ALLOWED,
1185 SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1186 SEC_ACE_FLAG_OBJECT_INHERIT,
1187 SID_WORLD,
1188 SEC_ACE_TYPE_ACCESS_ALLOWED,
1189 SEC_FILE_ALL | SEC_STD_ALL,
1191 NULL);
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 if (NT_STATUS_IS_OK(status)) {
1218 printf("failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
1219 ret = False;
1220 fnum2 = io.ntcreatex.out.fnum;
1221 smbcli_close(cli->tree, fnum2);
1222 } else {
1223 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1226 printf("trying without execute\n");
1227 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1228 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
1229 status = smb_raw_open(cli->tree, mem_ctx, &io);
1230 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1232 printf("and with full permissions again\n");
1233 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1234 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1235 status = smb_raw_open(cli->tree, mem_ctx, &io);
1236 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1238 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1239 status = smb_raw_open(cli->tree, mem_ctx, &io);
1240 CHECK_STATUS(status, NT_STATUS_OK);
1241 fnum2 = io.ntcreatex.out.fnum;
1242 CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1243 smbcli_close(cli->tree, fnum2);
1245 printf("put back original sd\n");
1246 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1247 set.set_secdesc.file.fnum = fnum;
1248 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1249 set.set_secdesc.in.sd = sd_orig;
1250 status = smb_raw_setfileinfo(cli->tree, &set);
1251 CHECK_STATUS(status, NT_STATUS_OK);
1253 smbcli_close(cli->tree, fnum);
1255 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1256 status = smb_raw_open(cli->tree, mem_ctx, &io);
1257 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1259 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1260 status = smb_raw_open(cli->tree, mem_ctx, &io);
1261 CHECK_STATUS(status, NT_STATUS_OK);
1262 fnum2 = io.ntcreatex.out.fnum;
1263 CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1264 smbcli_close(cli->tree, fnum2);
1266 smbcli_unlink(cli->tree, fname1);
1267 smbcli_rmdir(cli->tree, dname);
1269 done:
1270 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1271 set.set_secdesc.file.fnum = fnum;
1272 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1273 set.set_secdesc.in.sd = sd_orig;
1274 status = smb_raw_setfileinfo(cli->tree, &set);
1276 smbcli_close(cli->tree, fnum);
1277 return ret;
1282 test dynamic acl inheritance
1284 static BOOL test_inheritance_dynamic(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
1286 NTSTATUS status;
1287 union smb_open io;
1288 const char *dname = BASEDIR "\\inheritance";
1289 const char *fname1 = BASEDIR "\\inheritance\\testfile";
1290 BOOL ret = True;
1291 int fnum, fnum2;
1292 union smb_fileinfo q;
1293 union smb_setfileinfo set;
1294 struct security_descriptor *sd, *sd_orig;
1295 const char *owner_sid;
1297 printf("TESTING DYNAMIC ACL INHERITANCE\n");
1299 if (!torture_setup_dir(cli, BASEDIR)) {
1300 return False;
1303 io.generic.level = RAW_OPEN_NTCREATEX;
1304 io.ntcreatex.in.root_fid = 0;
1305 io.ntcreatex.in.flags = 0;
1306 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1307 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1308 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1309 io.ntcreatex.in.share_access = 0;
1310 io.ntcreatex.in.alloc_size = 0;
1311 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1312 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1313 io.ntcreatex.in.security_flags = 0;
1314 io.ntcreatex.in.fname = dname;
1316 status = smb_raw_open(cli->tree, mem_ctx, &io);
1317 CHECK_STATUS(status, NT_STATUS_OK);
1318 fnum = io.ntcreatex.out.fnum;
1320 printf("get the original sd\n");
1321 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1322 q.query_secdesc.in.fnum = fnum;
1323 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1324 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1325 CHECK_STATUS(status, NT_STATUS_OK);
1326 sd_orig = q.query_secdesc.out.sd;
1328 owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
1330 printf("owner_sid is %s\n", owner_sid);
1332 sd = security_descriptor_create(mem_ctx,
1333 NULL, NULL,
1334 owner_sid,
1335 SEC_ACE_TYPE_ACCESS_ALLOWED,
1336 SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
1337 SEC_ACE_FLAG_OBJECT_INHERIT,
1338 NULL);
1339 sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1341 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1342 set.set_secdesc.file.fnum = fnum;
1343 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1344 set.set_secdesc.in.sd = sd;
1345 status = smb_raw_setfileinfo(cli->tree, &set);
1346 CHECK_STATUS(status, NT_STATUS_OK);
1348 printf("create a file with an inherited acl\n");
1349 io.ntcreatex.in.fname = fname1;
1350 io.ntcreatex.in.create_options = 0;
1351 io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE;
1352 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1353 status = smb_raw_open(cli->tree, mem_ctx, &io);
1354 CHECK_STATUS(status, NT_STATUS_OK);
1355 fnum2 = io.ntcreatex.out.fnum;
1356 smbcli_close(cli->tree, fnum2);
1358 printf("try and access file with base rights - should be OK\n");
1359 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1360 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1361 status = smb_raw_open(cli->tree, mem_ctx, &io);
1362 CHECK_STATUS(status, NT_STATUS_OK);
1363 fnum2 = io.ntcreatex.out.fnum;
1364 smbcli_close(cli->tree, fnum2);
1366 printf("try and access file with extra rights - should be denied\n");
1367 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1368 status = smb_raw_open(cli->tree, mem_ctx, &io);
1369 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1371 printf("update parent sd\n");
1372 sd = security_descriptor_create(mem_ctx,
1373 NULL, NULL,
1374 owner_sid,
1375 SEC_ACE_TYPE_ACCESS_ALLOWED,
1376 SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE,
1377 SEC_ACE_FLAG_OBJECT_INHERIT,
1378 NULL);
1379 sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1381 set.set_secdesc.in.sd = sd;
1382 status = smb_raw_setfileinfo(cli->tree, &set);
1383 CHECK_STATUS(status, NT_STATUS_OK);
1385 printf("try and access file with base rights - should be OK\n");
1386 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1387 status = smb_raw_open(cli->tree, mem_ctx, &io);
1388 CHECK_STATUS(status, NT_STATUS_OK);
1389 fnum2 = io.ntcreatex.out.fnum;
1390 smbcli_close(cli->tree, fnum2);
1393 printf("try and access now - should be OK if dynamic inheritance works\n");
1394 io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1395 status = smb_raw_open(cli->tree, mem_ctx, &io);
1396 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1397 printf("Server does not have dynamic inheritance\n");
1399 if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1400 printf("Server does have dynamic inheritance\n");
1402 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1404 smbcli_unlink(cli->tree, fname1);
1406 done:
1407 printf("put back original sd\n");
1408 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1409 set.set_secdesc.file.fnum = fnum;
1410 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1411 set.set_secdesc.in.sd = sd_orig;
1412 status = smb_raw_setfileinfo(cli->tree, &set);
1414 smbcli_close(cli->tree, fnum);
1415 smbcli_rmdir(cli->tree, dname);
1417 return ret;
1422 basic testing of security descriptor calls
1424 BOOL torture_raw_acls(void)
1426 struct smbcli_state *cli;
1427 BOOL ret = True;
1428 TALLOC_CTX *mem_ctx;
1430 if (!torture_open_connection(&cli)) {
1431 return False;
1434 mem_ctx = talloc_init("torture_raw_acls");
1436 if (!torture_setup_dir(cli, BASEDIR)) {
1437 return False;
1440 ret &= test_sd(cli, mem_ctx);
1441 ret &= test_nttrans_create(cli, mem_ctx);
1442 ret &= test_creator_sid(cli, mem_ctx);
1443 ret &= test_generic_bits(cli, mem_ctx);
1444 ret &= test_owner_bits(cli, mem_ctx);
1445 ret &= test_inheritance(cli, mem_ctx);
1446 ret &= test_inheritance_dynamic(cli, mem_ctx);
1448 smb_raw_exit(cli->session);
1449 smbcli_deltree(cli->tree, BASEDIR);
1451 torture_close_connection(cli);
1452 talloc_destroy(mem_ctx);
1453 return ret;