2
Unix SMB/CIFS implementation.
4
test security descriptor operations
6
Copyright (C) Andrew Tridgell 2004
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program. If not, see <http://www.gnu.org/licenses/>.
23
#include "torture/torture.h"
24
#include "libcli/raw/libcliraw.h"
25
#include "libcli/libcli.h"
26
#include "librpc/gen_ndr/lsa.h"
27
#include "libcli/util/clilsa.h"
28
#include "libcli/security/security.h"
29
#include "torture/util.h"
30
#include "librpc/gen_ndr/ndr_security.h"
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 torture_context *tctx,
44
struct smbcli_state *cli)
48
const char *fname = BASEDIR "\\sd.txt";
52
union smb_setfileinfo set;
53
struct security_ace ace;
54
struct security_descriptor *sd;
55
struct dom_sid *test_sid;
57
printf("TESTING SETFILEINFO EA_SET\n");
59
io.generic.level = RAW_OPEN_NTCREATEX;
60
io.ntcreatex.in.root_fid = 0;
61
io.ntcreatex.in.flags = 0;
62
io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
63
io.ntcreatex.in.create_options = 0;
64
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
65
io.ntcreatex.in.share_access =
66
NTCREATEX_SHARE_ACCESS_READ |
67
NTCREATEX_SHARE_ACCESS_WRITE;
68
io.ntcreatex.in.alloc_size = 0;
69
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
70
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
71
io.ntcreatex.in.security_flags = 0;
72
io.ntcreatex.in.fname = fname;
73
status = smb_raw_open(cli->tree, tctx, &io);
74
CHECK_STATUS(status, NT_STATUS_OK);
75
fnum = io.ntcreatex.out.file.fnum;
77
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
78
q.query_secdesc.in.file.fnum = fnum;
79
q.query_secdesc.in.secinfo_flags =
83
status = smb_raw_fileinfo(cli->tree, tctx, &q);
84
CHECK_STATUS(status, NT_STATUS_OK);
85
sd = q.query_secdesc.out.sd;
87
printf("add a new ACE to the DACL\n");
89
test_sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1234-5432");
91
ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
93
ace.access_mask = SEC_STD_ALL;
94
ace.trustee = *test_sid;
96
status = security_descriptor_dacl_add(sd, &ace);
97
CHECK_STATUS(status, NT_STATUS_OK);
99
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
100
set.set_secdesc.in.file.fnum = fnum;
101
set.set_secdesc.in.secinfo_flags = q.query_secdesc.in.secinfo_flags;
102
set.set_secdesc.in.sd = sd;
104
status = smb_raw_setfileinfo(cli->tree, &set);
105
CHECK_STATUS(status, NT_STATUS_OK);
107
status = smb_raw_fileinfo(cli->tree, tctx, &q);
108
CHECK_STATUS(status, NT_STATUS_OK);
110
if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
111
printf("%s: security descriptors don't match!\n", __location__);
113
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
114
printf("expected:\n");
115
NDR_PRINT_DEBUG(security_descriptor, sd);
119
printf("remove it again\n");
121
status = security_descriptor_dacl_del(sd, test_sid);
122
CHECK_STATUS(status, NT_STATUS_OK);
124
status = smb_raw_setfileinfo(cli->tree, &set);
125
CHECK_STATUS(status, NT_STATUS_OK);
127
status = smb_raw_fileinfo(cli->tree, tctx, &q);
128
CHECK_STATUS(status, NT_STATUS_OK);
130
if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
131
printf("%s: security descriptors don't match!\n", __location__);
133
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
134
printf("expected:\n");
135
NDR_PRINT_DEBUG(security_descriptor, sd);
140
smbcli_close(cli->tree, fnum);
146
test using nttrans create to create a file with an initial acl set
148
static bool test_nttrans_create(struct torture_context *tctx,
149
struct smbcli_state *cli)
153
const char *fname = BASEDIR "\\acl2.txt";
156
union smb_fileinfo q;
157
struct security_ace ace;
158
struct security_descriptor *sd;
159
struct dom_sid *test_sid;
161
printf("testing nttrans create with sec_desc\n");
163
io.generic.level = RAW_OPEN_NTTRANS_CREATE;
164
io.ntcreatex.in.root_fid = 0;
165
io.ntcreatex.in.flags = 0;
166
io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
167
io.ntcreatex.in.create_options = 0;
168
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
169
io.ntcreatex.in.share_access =
170
NTCREATEX_SHARE_ACCESS_READ |
171
NTCREATEX_SHARE_ACCESS_WRITE;
172
io.ntcreatex.in.alloc_size = 0;
173
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
174
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
175
io.ntcreatex.in.security_flags = 0;
176
io.ntcreatex.in.fname = fname;
177
io.ntcreatex.in.sec_desc = NULL;
178
io.ntcreatex.in.ea_list = NULL;
180
printf("creating normal file\n");
182
status = smb_raw_open(cli->tree, tctx, &io);
183
CHECK_STATUS(status, NT_STATUS_OK);
184
fnum = io.ntcreatex.out.file.fnum;
186
printf("querying ACL\n");
188
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
189
q.query_secdesc.in.file.fnum = fnum;
190
q.query_secdesc.in.secinfo_flags =
194
status = smb_raw_fileinfo(cli->tree, tctx, &q);
195
CHECK_STATUS(status, NT_STATUS_OK);
196
sd = q.query_secdesc.out.sd;
198
smbcli_close(cli->tree, fnum);
199
smbcli_unlink(cli->tree, fname);
201
printf("adding a new ACE\n");
202
test_sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1234-54321");
204
ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
206
ace.access_mask = SEC_STD_ALL;
207
ace.trustee = *test_sid;
209
status = security_descriptor_dacl_add(sd, &ace);
210
CHECK_STATUS(status, NT_STATUS_OK);
212
printf("creating a file with an initial ACL\n");
214
io.ntcreatex.in.sec_desc = sd;
215
status = smb_raw_open(cli->tree, tctx, &io);
216
CHECK_STATUS(status, NT_STATUS_OK);
217
fnum = io.ntcreatex.out.file.fnum;
219
q.query_secdesc.in.file.fnum = fnum;
220
status = smb_raw_fileinfo(cli->tree, tctx, &q);
221
CHECK_STATUS(status, NT_STATUS_OK);
223
if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
224
printf("%s: security descriptors don't match!\n", __location__);
226
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
227
printf("expected:\n");
228
NDR_PRINT_DEBUG(security_descriptor, sd);
233
smbcli_close(cli->tree, fnum);
237
#define CHECK_ACCESS_FLAGS(_fnum, flags) do { \
238
union smb_fileinfo _q; \
239
_q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
240
_q.access_information.in.file.fnum = (_fnum); \
241
status = smb_raw_fileinfo(cli->tree, tctx, &_q); \
242
CHECK_STATUS(status, NT_STATUS_OK); \
243
if (_q.access_information.out.access_flags != (flags)) { \
244
printf("(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
245
__location__, _q.access_information.out.access_flags, (flags)); \
252
test using NTTRANS CREATE to create a file with a null ACL set
254
static bool test_nttrans_create_null_dacl(struct torture_context *tctx,
255
struct smbcli_state *cli)
259
const char *fname = BASEDIR "\\acl3.txt";
262
union smb_fileinfo q;
263
union smb_setfileinfo s;
264
struct security_descriptor *sd = security_descriptor_initialise(tctx);
265
struct security_acl dacl;
267
printf("TESTING SEC_DESC WITH A NULL DACL\n");
269
io.generic.level = RAW_OPEN_NTTRANS_CREATE;
270
io.ntcreatex.in.root_fid = 0;
271
io.ntcreatex.in.flags = 0;
272
io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC
273
| SEC_STD_WRITE_OWNER;
274
io.ntcreatex.in.create_options = 0;
275
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
276
io.ntcreatex.in.share_access =
277
NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
278
io.ntcreatex.in.alloc_size = 0;
279
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
280
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
281
io.ntcreatex.in.security_flags = 0;
282
io.ntcreatex.in.fname = fname;
283
io.ntcreatex.in.sec_desc = sd;
284
io.ntcreatex.in.ea_list = NULL;
286
printf("creating a file with a empty sd\n");
287
status = smb_raw_open(cli->tree, tctx, &io);
288
CHECK_STATUS(status, NT_STATUS_OK);
289
fnum = io.ntcreatex.out.file.fnum;
291
printf("get the original sd\n");
292
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
293
q.query_secdesc.in.file.fnum = fnum;
294
q.query_secdesc.in.secinfo_flags =
298
status = smb_raw_fileinfo(cli->tree, tctx, &q);
299
CHECK_STATUS(status, NT_STATUS_OK);
302
* Testing the created DACL,
303
* the server should add the inherited DACL
304
* when SEC_DESC_DACL_PRESENT isn't specified
306
if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
307
printf("DACL_PRESENT flag not set by the server!\n");
311
if (q.query_secdesc.out.sd->dacl == NULL) {
312
printf("no DACL has been created on the server!\n");
317
printf("set NULL DACL\n");
318
sd->type |= SEC_DESC_DACL_PRESENT;
320
s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
321
s.set_secdesc.in.file.fnum = fnum;
322
s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
323
s.set_secdesc.in.sd = sd;
324
status = smb_raw_setfileinfo(cli->tree, &s);
325
CHECK_STATUS(status, NT_STATUS_OK);
327
printf("get the sd\n");
328
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
329
q.query_secdesc.in.file.fnum = fnum;
330
q.query_secdesc.in.secinfo_flags =
334
status = smb_raw_fileinfo(cli->tree, tctx, &q);
335
CHECK_STATUS(status, NT_STATUS_OK);
337
/* Testing the modified DACL */
338
if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
339
printf("DACL_PRESENT flag not set by the server!\n");
343
if (q.query_secdesc.out.sd->dacl != NULL) {
344
printf("DACL has been created on the server!\n");
349
printf("try open for read control\n");
350
io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL;
351
status = smb_raw_open(cli->tree, tctx, &io);
352
CHECK_STATUS(status, NT_STATUS_OK);
353
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
354
SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE);
355
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
357
printf("try open for write\n");
358
io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
359
status = smb_raw_open(cli->tree, tctx, &io);
360
CHECK_STATUS(status, NT_STATUS_OK);
361
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
362
SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
363
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
365
printf("try open for read\n");
366
io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
367
status = smb_raw_open(cli->tree, tctx, &io);
368
CHECK_STATUS(status, NT_STATUS_OK);
369
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
370
SEC_FILE_READ_DATA | SEC_FILE_READ_ATTRIBUTE);
371
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
373
printf("try open for generic write\n");
374
io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
375
status = smb_raw_open(cli->tree, tctx, &io);
376
CHECK_STATUS(status, NT_STATUS_OK);
377
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
378
SEC_RIGHTS_FILE_WRITE | SEC_FILE_READ_ATTRIBUTE);
379
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
381
printf("try open for generic read\n");
382
io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
383
status = smb_raw_open(cli->tree, tctx, &io);
384
CHECK_STATUS(status, NT_STATUS_OK);
385
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
386
SEC_RIGHTS_FILE_READ | SEC_FILE_READ_ATTRIBUTE);
387
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
389
printf("set DACL with 0 aces\n");
391
dacl.revision = SECURITY_ACL_REVISION_NT4;
395
s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
396
s.set_secdesc.in.file.fnum = fnum;
397
s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
398
s.set_secdesc.in.sd = sd;
399
status = smb_raw_setfileinfo(cli->tree, &s);
400
CHECK_STATUS(status, NT_STATUS_OK);
402
printf("get the sd\n");
403
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
404
q.query_secdesc.in.file.fnum = fnum;
405
q.query_secdesc.in.secinfo_flags =
409
status = smb_raw_fileinfo(cli->tree, tctx, &q);
410
CHECK_STATUS(status, NT_STATUS_OK);
412
/* Testing the modified DACL */
413
if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
414
printf("DACL_PRESENT flag not set by the server!\n");
418
if (q.query_secdesc.out.sd->dacl == NULL) {
419
printf("no DACL has been created on the server!\n");
423
if (q.query_secdesc.out.sd->dacl->num_aces != 0) {
424
printf("DACL has %u aces!\n",
425
q.query_secdesc.out.sd->dacl->num_aces);
430
printf("try open for read control\n");
431
io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL;
432
status = smb_raw_open(cli->tree, tctx, &io);
433
CHECK_STATUS(status, NT_STATUS_OK);
434
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
435
SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE);
436
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
438
printf("try open for write => access_denied\n");
439
io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
440
status = smb_raw_open(cli->tree, tctx, &io);
441
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
443
printf("try open for read => access_denied\n");
444
io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
445
status = smb_raw_open(cli->tree, tctx, &io);
446
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
448
printf("try open for generic write => access_denied\n");
449
io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
450
status = smb_raw_open(cli->tree, tctx, &io);
451
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
453
printf("try open for generic read => access_denied\n");
454
io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
455
status = smb_raw_open(cli->tree, tctx, &io);
456
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
458
printf("set empty sd\n");
459
sd->type &= ~SEC_DESC_DACL_PRESENT;
462
s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
463
s.set_secdesc.in.file.fnum = fnum;
464
s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
465
s.set_secdesc.in.sd = sd;
466
status = smb_raw_setfileinfo(cli->tree, &s);
467
CHECK_STATUS(status, NT_STATUS_OK);
469
printf("get the sd\n");
470
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
471
q.query_secdesc.in.file.fnum = fnum;
472
q.query_secdesc.in.secinfo_flags =
476
status = smb_raw_fileinfo(cli->tree, tctx, &q);
477
CHECK_STATUS(status, NT_STATUS_OK);
479
/* Testing the modified DACL */
480
if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
481
printf("DACL_PRESENT flag not set by the server!\n");
485
if (q.query_secdesc.out.sd->dacl != NULL) {
486
printf("DACL has been created on the server!\n");
491
smbcli_close(cli->tree, fnum);
496
test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
499
static bool test_creator_sid(struct torture_context *tctx,
500
struct smbcli_state *cli)
504
const char *fname = BASEDIR "\\creator.txt";
507
union smb_fileinfo q;
508
union smb_setfileinfo set;
509
struct security_descriptor *sd, *sd_orig, *sd2;
510
const char *owner_sid;
512
printf("TESTING SID_CREATOR_OWNER\n");
514
io.generic.level = RAW_OPEN_NTCREATEX;
515
io.ntcreatex.in.root_fid = 0;
516
io.ntcreatex.in.flags = 0;
517
io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
518
io.ntcreatex.in.create_options = 0;
519
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
520
io.ntcreatex.in.share_access =
521
NTCREATEX_SHARE_ACCESS_READ |
522
NTCREATEX_SHARE_ACCESS_WRITE;
523
io.ntcreatex.in.alloc_size = 0;
524
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
525
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
526
io.ntcreatex.in.security_flags = 0;
527
io.ntcreatex.in.fname = fname;
528
status = smb_raw_open(cli->tree, tctx, &io);
529
CHECK_STATUS(status, NT_STATUS_OK);
530
fnum = io.ntcreatex.out.file.fnum;
532
printf("get the original sd\n");
533
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
534
q.query_secdesc.in.file.fnum = fnum;
535
q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
536
status = smb_raw_fileinfo(cli->tree, tctx, &q);
537
CHECK_STATUS(status, NT_STATUS_OK);
538
sd_orig = q.query_secdesc.out.sd;
540
owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
542
printf("set a sec desc allowing no write by CREATOR_OWNER\n");
543
sd = security_descriptor_dacl_create(tctx,
546
SEC_ACE_TYPE_ACCESS_ALLOWED,
547
SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
551
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
552
set.set_secdesc.in.file.fnum = fnum;
553
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
554
set.set_secdesc.in.sd = sd;
556
status = smb_raw_setfileinfo(cli->tree, &set);
557
CHECK_STATUS(status, NT_STATUS_OK);
559
printf("try open for write\n");
560
io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
561
status = smb_raw_open(cli->tree, tctx, &io);
562
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
564
printf("try open for read\n");
565
io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
566
status = smb_raw_open(cli->tree, tctx, &io);
567
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
569
printf("try open for generic write\n");
570
io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
571
status = smb_raw_open(cli->tree, tctx, &io);
572
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
574
printf("try open for generic read\n");
575
io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
576
status = smb_raw_open(cli->tree, tctx, &io);
577
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
579
printf("set a sec desc allowing no write by owner\n");
580
sd = security_descriptor_dacl_create(tctx,
583
SEC_ACE_TYPE_ACCESS_ALLOWED,
584
SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
588
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
589
set.set_secdesc.in.file.fnum = fnum;
590
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
591
set.set_secdesc.in.sd = sd;
592
status = smb_raw_setfileinfo(cli->tree, &set);
593
CHECK_STATUS(status, NT_STATUS_OK);
595
printf("check that sd has been mapped correctly\n");
596
status = smb_raw_fileinfo(cli->tree, tctx, &q);
597
CHECK_STATUS(status, NT_STATUS_OK);
598
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd)) {
599
printf("%s: security descriptors don't match!\n", __location__);
601
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
602
printf("expected:\n");
603
NDR_PRINT_DEBUG(security_descriptor, sd);
607
printf("try open for write\n");
608
io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
609
status = smb_raw_open(cli->tree, tctx, &io);
610
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
612
printf("try open for read\n");
613
io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
614
status = smb_raw_open(cli->tree, tctx, &io);
615
CHECK_STATUS(status, NT_STATUS_OK);
616
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
618
SEC_FILE_READ_ATTRIBUTE);
619
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
621
printf("try open for generic write\n");
622
io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
623
status = smb_raw_open(cli->tree, tctx, &io);
624
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
626
printf("try open for generic read\n");
627
io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
628
status = smb_raw_open(cli->tree, tctx, &io);
629
CHECK_STATUS(status, NT_STATUS_OK);
630
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
631
SEC_RIGHTS_FILE_READ);
632
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
634
printf("set a sec desc allowing generic read by owner\n");
635
sd = security_descriptor_dacl_create(tctx,
638
SEC_ACE_TYPE_ACCESS_ALLOWED,
639
SEC_GENERIC_READ | SEC_STD_ALL,
643
set.set_secdesc.in.sd = sd;
644
status = smb_raw_setfileinfo(cli->tree, &set);
645
CHECK_STATUS(status, NT_STATUS_OK);
647
printf("check that generic read has been mapped correctly\n");
648
sd2 = security_descriptor_dacl_create(tctx,
651
SEC_ACE_TYPE_ACCESS_ALLOWED,
652
SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
656
status = smb_raw_fileinfo(cli->tree, tctx, &q);
657
CHECK_STATUS(status, NT_STATUS_OK);
658
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
659
printf("%s: security descriptors don't match!\n", __location__);
661
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
662
printf("expected:\n");
663
NDR_PRINT_DEBUG(security_descriptor, sd2);
668
printf("try open for write\n");
669
io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
670
status = smb_raw_open(cli->tree, tctx, &io);
671
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
673
printf("try open for read\n");
674
io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
675
status = smb_raw_open(cli->tree, tctx, &io);
676
CHECK_STATUS(status, NT_STATUS_OK);
677
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
679
SEC_FILE_READ_ATTRIBUTE);
680
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
682
printf("try open for generic write\n");
683
io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
684
status = smb_raw_open(cli->tree, tctx, &io);
685
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
687
printf("try open for generic read\n");
688
io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
689
status = smb_raw_open(cli->tree, tctx, &io);
690
CHECK_STATUS(status, NT_STATUS_OK);
691
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, SEC_RIGHTS_FILE_READ);
692
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
695
printf("put back original sd\n");
696
set.set_secdesc.in.sd = sd_orig;
697
status = smb_raw_setfileinfo(cli->tree, &set);
698
CHECK_STATUS(status, NT_STATUS_OK);
702
smbcli_close(cli->tree, fnum);
708
test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
711
static bool test_generic_bits(struct torture_context *tctx,
712
struct smbcli_state *cli)
716
const char *fname = BASEDIR "\\generic.txt";
719
union smb_fileinfo q;
720
union smb_setfileinfo set;
721
struct security_descriptor *sd, *sd_orig, *sd2;
722
const char *owner_sid;
725
uint32_t specific_bits;
726
} file_mappings[] = {
728
{ SEC_GENERIC_READ, SEC_RIGHTS_FILE_READ },
729
{ SEC_GENERIC_WRITE, SEC_RIGHTS_FILE_WRITE },
730
{ SEC_GENERIC_EXECUTE, SEC_RIGHTS_FILE_EXECUTE },
731
{ SEC_GENERIC_ALL, SEC_RIGHTS_FILE_ALL },
732
{ SEC_FILE_READ_DATA, SEC_FILE_READ_DATA },
733
{ SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_ATTRIBUTE }
737
uint32_t specific_bits;
740
{ SEC_GENERIC_READ, SEC_RIGHTS_DIR_READ },
741
{ SEC_GENERIC_WRITE, SEC_RIGHTS_DIR_WRITE },
742
{ SEC_GENERIC_EXECUTE, SEC_RIGHTS_DIR_EXECUTE },
743
{ SEC_GENERIC_ALL, SEC_RIGHTS_DIR_ALL }
745
bool has_restore_privilege;
746
bool has_take_ownership_privilege;
748
printf("TESTING FILE GENERIC BITS\n");
750
io.generic.level = RAW_OPEN_NTCREATEX;
751
io.ntcreatex.in.root_fid = 0;
752
io.ntcreatex.in.flags = 0;
753
io.ntcreatex.in.access_mask =
754
SEC_STD_READ_CONTROL |
757
io.ntcreatex.in.create_options = 0;
758
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
759
io.ntcreatex.in.share_access =
760
NTCREATEX_SHARE_ACCESS_READ |
761
NTCREATEX_SHARE_ACCESS_WRITE;
762
io.ntcreatex.in.alloc_size = 0;
763
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
764
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
765
io.ntcreatex.in.security_flags = 0;
766
io.ntcreatex.in.fname = fname;
767
status = smb_raw_open(cli->tree, tctx, &io);
768
CHECK_STATUS(status, NT_STATUS_OK);
769
fnum = io.ntcreatex.out.file.fnum;
771
printf("get the original sd\n");
772
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
773
q.query_secdesc.in.file.fnum = fnum;
774
q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
775
status = smb_raw_fileinfo(cli->tree, tctx, &q);
776
CHECK_STATUS(status, NT_STATUS_OK);
777
sd_orig = q.query_secdesc.out.sd;
779
owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
781
status = smblsa_sid_check_privilege(cli,
783
sec_privilege_name(SEC_PRIV_RESTORE));
784
has_restore_privilege = NT_STATUS_IS_OK(status);
785
if (!NT_STATUS_IS_OK(status)) {
786
printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
788
printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
790
status = smblsa_sid_check_privilege(cli,
792
sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
793
has_take_ownership_privilege = NT_STATUS_IS_OK(status);
794
if (!NT_STATUS_IS_OK(status)) {
795
printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
797
printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
799
for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
800
uint32_t expected_mask =
802
SEC_STD_READ_CONTROL |
803
SEC_FILE_READ_ATTRIBUTE |
805
uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
807
if (has_restore_privilege) {
808
expected_mask_anon |= SEC_STD_DELETE;
811
printf("testing generic bits 0x%08x\n",
812
file_mappings[i].gen_bits);
813
sd = security_descriptor_dacl_create(tctx,
816
SEC_ACE_TYPE_ACCESS_ALLOWED,
817
file_mappings[i].gen_bits,
821
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
822
set.set_secdesc.in.file.fnum = fnum;
823
set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
824
set.set_secdesc.in.sd = sd;
826
status = smb_raw_setfileinfo(cli->tree, &set);
827
CHECK_STATUS(status, NT_STATUS_OK);
829
sd2 = security_descriptor_dacl_create(tctx,
832
SEC_ACE_TYPE_ACCESS_ALLOWED,
833
file_mappings[i].specific_bits,
837
status = smb_raw_fileinfo(cli->tree, tctx, &q);
838
CHECK_STATUS(status, NT_STATUS_OK);
839
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
840
printf("%s: security descriptors don't match!\n", __location__);
842
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
843
printf("expected:\n");
844
NDR_PRINT_DEBUG(security_descriptor, sd2);
848
io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
849
status = smb_raw_open(cli->tree, tctx, &io);
850
CHECK_STATUS(status, NT_STATUS_OK);
851
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
852
expected_mask | file_mappings[i].specific_bits);
853
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
855
if (!has_take_ownership_privilege) {
859
printf("testing generic bits 0x%08x (anonymous)\n",
860
file_mappings[i].gen_bits);
861
sd = security_descriptor_dacl_create(tctx,
862
0, SID_NT_ANONYMOUS, NULL,
864
SEC_ACE_TYPE_ACCESS_ALLOWED,
865
file_mappings[i].gen_bits,
869
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
870
set.set_secdesc.in.file.fnum = fnum;
871
set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
872
set.set_secdesc.in.sd = sd;
874
status = smb_raw_setfileinfo(cli->tree, &set);
875
CHECK_STATUS(status, NT_STATUS_OK);
877
sd2 = security_descriptor_dacl_create(tctx,
878
0, SID_NT_ANONYMOUS, NULL,
880
SEC_ACE_TYPE_ACCESS_ALLOWED,
881
file_mappings[i].specific_bits,
885
status = smb_raw_fileinfo(cli->tree, tctx, &q);
886
CHECK_STATUS(status, NT_STATUS_OK);
887
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
888
printf("%s: security descriptors don't match!\n", __location__);
890
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
891
printf("expected:\n");
892
NDR_PRINT_DEBUG(security_descriptor, sd2);
896
io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
897
status = smb_raw_open(cli->tree, tctx, &io);
898
CHECK_STATUS(status, NT_STATUS_OK);
899
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
900
expected_mask_anon | file_mappings[i].specific_bits);
901
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
904
printf("put back original sd\n");
905
set.set_secdesc.in.sd = sd_orig;
906
status = smb_raw_setfileinfo(cli->tree, &set);
907
CHECK_STATUS(status, NT_STATUS_OK);
909
smbcli_close(cli->tree, fnum);
910
smbcli_unlink(cli->tree, fname);
913
printf("TESTING DIR GENERIC BITS\n");
915
io.generic.level = RAW_OPEN_NTCREATEX;
916
io.ntcreatex.in.root_fid = 0;
917
io.ntcreatex.in.flags = 0;
918
io.ntcreatex.in.access_mask =
919
SEC_STD_READ_CONTROL |
922
io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
923
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
924
io.ntcreatex.in.share_access =
925
NTCREATEX_SHARE_ACCESS_READ |
926
NTCREATEX_SHARE_ACCESS_WRITE;
927
io.ntcreatex.in.alloc_size = 0;
928
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
929
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
930
io.ntcreatex.in.security_flags = 0;
931
io.ntcreatex.in.fname = fname;
932
status = smb_raw_open(cli->tree, tctx, &io);
933
CHECK_STATUS(status, NT_STATUS_OK);
934
fnum = io.ntcreatex.out.file.fnum;
936
printf("get the original sd\n");
937
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
938
q.query_secdesc.in.file.fnum = fnum;
939
q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
940
status = smb_raw_fileinfo(cli->tree, tctx, &q);
941
CHECK_STATUS(status, NT_STATUS_OK);
942
sd_orig = q.query_secdesc.out.sd;
944
owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
946
status = smblsa_sid_check_privilege(cli,
948
sec_privilege_name(SEC_PRIV_RESTORE));
949
has_restore_privilege = NT_STATUS_IS_OK(status);
950
if (!NT_STATUS_IS_OK(status)) {
951
printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
953
printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
955
status = smblsa_sid_check_privilege(cli,
957
sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
958
has_take_ownership_privilege = NT_STATUS_IS_OK(status);
959
if (!NT_STATUS_IS_OK(status)) {
960
printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
962
printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
964
for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
965
uint32_t expected_mask =
967
SEC_STD_READ_CONTROL |
968
SEC_FILE_READ_ATTRIBUTE |
970
uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
972
if (has_restore_privilege) {
973
expected_mask_anon |= SEC_STD_DELETE;
976
printf("testing generic bits 0x%08x\n",
977
file_mappings[i].gen_bits);
978
sd = security_descriptor_dacl_create(tctx,
981
SEC_ACE_TYPE_ACCESS_ALLOWED,
982
dir_mappings[i].gen_bits,
986
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
987
set.set_secdesc.in.file.fnum = fnum;
988
set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
989
set.set_secdesc.in.sd = sd;
991
status = smb_raw_setfileinfo(cli->tree, &set);
992
CHECK_STATUS(status, NT_STATUS_OK);
994
sd2 = security_descriptor_dacl_create(tctx,
997
SEC_ACE_TYPE_ACCESS_ALLOWED,
998
dir_mappings[i].specific_bits,
1002
status = smb_raw_fileinfo(cli->tree, tctx, &q);
1003
CHECK_STATUS(status, NT_STATUS_OK);
1004
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
1005
printf("%s: security descriptors don't match!\n", __location__);
1007
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1008
printf("expected:\n");
1009
NDR_PRINT_DEBUG(security_descriptor, sd2);
1013
io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1014
status = smb_raw_open(cli->tree, tctx, &io);
1015
CHECK_STATUS(status, NT_STATUS_OK);
1016
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
1017
expected_mask | dir_mappings[i].specific_bits);
1018
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1020
if (!has_take_ownership_privilege) {
1024
printf("testing generic bits 0x%08x (anonymous)\n",
1025
file_mappings[i].gen_bits);
1026
sd = security_descriptor_dacl_create(tctx,
1027
0, SID_NT_ANONYMOUS, NULL,
1029
SEC_ACE_TYPE_ACCESS_ALLOWED,
1030
file_mappings[i].gen_bits,
1034
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1035
set.set_secdesc.in.file.fnum = fnum;
1036
set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1037
set.set_secdesc.in.sd = sd;
1039
status = smb_raw_setfileinfo(cli->tree, &set);
1040
CHECK_STATUS(status, NT_STATUS_OK);
1042
sd2 = security_descriptor_dacl_create(tctx,
1043
0, SID_NT_ANONYMOUS, NULL,
1045
SEC_ACE_TYPE_ACCESS_ALLOWED,
1046
file_mappings[i].specific_bits,
1050
status = smb_raw_fileinfo(cli->tree, tctx, &q);
1051
CHECK_STATUS(status, NT_STATUS_OK);
1052
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
1053
printf("%s: security descriptors don't match!\n", __location__);
1055
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1056
printf("expected:\n");
1057
NDR_PRINT_DEBUG(security_descriptor, sd2);
1061
io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1062
status = smb_raw_open(cli->tree, tctx, &io);
1063
CHECK_STATUS(status, NT_STATUS_OK);
1064
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
1065
expected_mask_anon | dir_mappings[i].specific_bits);
1066
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1069
printf("put back original sd\n");
1070
set.set_secdesc.in.sd = sd_orig;
1071
status = smb_raw_setfileinfo(cli->tree, &set);
1072
CHECK_STATUS(status, NT_STATUS_OK);
1074
smbcli_close(cli->tree, fnum);
1075
smbcli_unlink(cli->tree, fname);
1078
smbcli_close(cli->tree, fnum);
1084
see what access bits the owner of a file always gets
1086
static bool test_owner_bits(struct torture_context *tctx,
1087
struct smbcli_state *cli)
1091
const char *fname = BASEDIR "\\test_owner_bits.txt";
1094
union smb_fileinfo q;
1095
union smb_setfileinfo set;
1096
struct security_descriptor *sd, *sd_orig;
1097
const char *owner_sid;
1098
bool has_restore_privilege;
1099
bool has_take_ownership_privilege;
1100
uint32_t expected_bits;
1102
printf("TESTING FILE OWNER BITS\n");
1104
io.generic.level = RAW_OPEN_NTCREATEX;
1105
io.ntcreatex.in.root_fid = 0;
1106
io.ntcreatex.in.flags = 0;
1107
io.ntcreatex.in.access_mask =
1108
SEC_STD_READ_CONTROL |
1110
SEC_STD_WRITE_OWNER;
1111
io.ntcreatex.in.create_options = 0;
1112
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1113
io.ntcreatex.in.share_access =
1114
NTCREATEX_SHARE_ACCESS_READ |
1115
NTCREATEX_SHARE_ACCESS_WRITE;
1116
io.ntcreatex.in.alloc_size = 0;
1117
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1118
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1119
io.ntcreatex.in.security_flags = 0;
1120
io.ntcreatex.in.fname = fname;
1121
status = smb_raw_open(cli->tree, tctx, &io);
1122
CHECK_STATUS(status, NT_STATUS_OK);
1123
fnum = io.ntcreatex.out.file.fnum;
1125
printf("get the original sd\n");
1126
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1127
q.query_secdesc.in.file.fnum = fnum;
1128
q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1129
status = smb_raw_fileinfo(cli->tree, tctx, &q);
1130
CHECK_STATUS(status, NT_STATUS_OK);
1131
sd_orig = q.query_secdesc.out.sd;
1133
owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1135
status = smblsa_sid_check_privilege(cli,
1137
sec_privilege_name(SEC_PRIV_RESTORE));
1138
has_restore_privilege = NT_STATUS_IS_OK(status);
1139
if (!NT_STATUS_IS_OK(status)) {
1140
printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
1142
printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
1144
status = smblsa_sid_check_privilege(cli,
1146
sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
1147
has_take_ownership_privilege = NT_STATUS_IS_OK(status);
1148
if (!NT_STATUS_IS_OK(status)) {
1149
printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
1151
printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
1153
sd = security_descriptor_dacl_create(tctx,
1156
SEC_ACE_TYPE_ACCESS_ALLOWED,
1157
SEC_FILE_WRITE_DATA,
1161
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1162
set.set_secdesc.in.file.fnum = fnum;
1163
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1164
set.set_secdesc.in.sd = sd;
1166
status = smb_raw_setfileinfo(cli->tree, &set);
1167
CHECK_STATUS(status, NT_STATUS_OK);
1169
expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
1171
for (i=0;i<16;i++) {
1172
uint32_t bit = (1<<i);
1173
io.ntcreatex.in.access_mask = bit;
1174
status = smb_raw_open(cli->tree, tctx, &io);
1175
if (expected_bits & bit) {
1176
if (!NT_STATUS_IS_OK(status)) {
1177
printf("failed with access mask 0x%08x of expected 0x%08x\n",
1178
bit, expected_bits);
1180
CHECK_STATUS(status, NT_STATUS_OK);
1181
CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, bit | SEC_FILE_READ_ATTRIBUTE);
1182
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1184
if (NT_STATUS_IS_OK(status)) {
1185
printf("open succeeded with access mask 0x%08x of "
1186
"expected 0x%08x - should fail\n",
1187
bit, expected_bits);
1189
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1193
printf("put back original sd\n");
1194
set.set_secdesc.in.sd = sd_orig;
1195
status = smb_raw_setfileinfo(cli->tree, &set);
1196
CHECK_STATUS(status, NT_STATUS_OK);
1199
smbcli_close(cli->tree, fnum);
1200
smbcli_unlink(cli->tree, fname);
1207
test the inheritance of ACL flags onto new files and directories
1209
static bool test_inheritance(struct torture_context *tctx,
1210
struct smbcli_state *cli)
1214
const char *dname = BASEDIR "\\inheritance";
1215
const char *fname1 = BASEDIR "\\inheritance\\testfile";
1216
const char *fname2 = BASEDIR "\\inheritance\\testdir";
1218
int fnum=0, fnum2, i;
1219
union smb_fileinfo q;
1220
union smb_setfileinfo set;
1221
struct security_descriptor *sd, *sd2, *sd_orig=NULL, *sd_def;
1222
const char *owner_sid;
1223
const struct dom_sid *creator_owner;
1225
uint32_t parent_flags;
1226
uint32_t file_flags;
1235
SEC_ACE_FLAG_OBJECT_INHERIT,
1237
SEC_ACE_FLAG_OBJECT_INHERIT |
1238
SEC_ACE_FLAG_INHERIT_ONLY,
1241
SEC_ACE_FLAG_CONTAINER_INHERIT,
1243
SEC_ACE_FLAG_CONTAINER_INHERIT,
1246
SEC_ACE_FLAG_OBJECT_INHERIT |
1247
SEC_ACE_FLAG_CONTAINER_INHERIT,
1249
SEC_ACE_FLAG_OBJECT_INHERIT |
1250
SEC_ACE_FLAG_CONTAINER_INHERIT,
1253
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
1258
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1259
SEC_ACE_FLAG_OBJECT_INHERIT,
1264
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1265
SEC_ACE_FLAG_CONTAINER_INHERIT,
1270
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1271
SEC_ACE_FLAG_CONTAINER_INHERIT |
1272
SEC_ACE_FLAG_OBJECT_INHERIT,
1277
SEC_ACE_FLAG_INHERIT_ONLY,
1282
SEC_ACE_FLAG_INHERIT_ONLY |
1283
SEC_ACE_FLAG_OBJECT_INHERIT,
1285
SEC_ACE_FLAG_OBJECT_INHERIT |
1286
SEC_ACE_FLAG_INHERIT_ONLY,
1289
SEC_ACE_FLAG_INHERIT_ONLY |
1290
SEC_ACE_FLAG_CONTAINER_INHERIT,
1292
SEC_ACE_FLAG_CONTAINER_INHERIT,
1295
SEC_ACE_FLAG_INHERIT_ONLY |
1296
SEC_ACE_FLAG_CONTAINER_INHERIT |
1297
SEC_ACE_FLAG_OBJECT_INHERIT,
1299
SEC_ACE_FLAG_CONTAINER_INHERIT |
1300
SEC_ACE_FLAG_OBJECT_INHERIT,
1303
SEC_ACE_FLAG_INHERIT_ONLY |
1304
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
1309
SEC_ACE_FLAG_INHERIT_ONLY |
1310
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1311
SEC_ACE_FLAG_OBJECT_INHERIT,
1316
SEC_ACE_FLAG_INHERIT_ONLY |
1317
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1318
SEC_ACE_FLAG_CONTAINER_INHERIT,
1323
SEC_ACE_FLAG_INHERIT_ONLY |
1324
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
1325
SEC_ACE_FLAG_CONTAINER_INHERIT |
1326
SEC_ACE_FLAG_OBJECT_INHERIT,
1332
smbcli_rmdir(cli->tree, dname);
1334
printf("TESTING ACL INHERITANCE\n");
1336
io.generic.level = RAW_OPEN_NTCREATEX;
1337
io.ntcreatex.in.root_fid = 0;
1338
io.ntcreatex.in.flags = 0;
1339
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1340
io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1341
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1342
io.ntcreatex.in.share_access = 0;
1343
io.ntcreatex.in.alloc_size = 0;
1344
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1345
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1346
io.ntcreatex.in.security_flags = 0;
1347
io.ntcreatex.in.fname = dname;
1349
status = smb_raw_open(cli->tree, tctx, &io);
1350
CHECK_STATUS(status, NT_STATUS_OK);
1351
fnum = io.ntcreatex.out.file.fnum;
1353
printf("get the original sd\n");
1354
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1355
q.query_secdesc.in.file.fnum = fnum;
1356
q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1357
status = smb_raw_fileinfo(cli->tree, tctx, &q);
1358
CHECK_STATUS(status, NT_STATUS_OK);
1359
sd_orig = q.query_secdesc.out.sd;
1361
owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1363
printf("owner_sid is %s\n", owner_sid);
1365
sd_def = security_descriptor_dacl_create(tctx,
1368
SEC_ACE_TYPE_ACCESS_ALLOWED,
1369
SEC_RIGHTS_FILE_ALL,
1372
SEC_ACE_TYPE_ACCESS_ALLOWED,
1373
SEC_RIGHTS_FILE_ALL,
1377
creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER);
1379
for (i=0;i<ARRAY_SIZE(test_flags);i++) {
1380
sd = security_descriptor_dacl_create(tctx,
1383
SEC_ACE_TYPE_ACCESS_ALLOWED,
1384
SEC_FILE_WRITE_DATA,
1385
test_flags[i].parent_flags,
1387
SEC_ACE_TYPE_ACCESS_ALLOWED,
1388
SEC_FILE_ALL | SEC_STD_ALL,
1391
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1392
set.set_secdesc.in.file.fnum = fnum;
1393
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1394
set.set_secdesc.in.sd = sd;
1395
status = smb_raw_setfileinfo(cli->tree, &set);
1396
CHECK_STATUS(status, NT_STATUS_OK);
1398
io.ntcreatex.in.fname = fname1;
1399
io.ntcreatex.in.create_options = 0;
1400
status = smb_raw_open(cli->tree, tctx, &io);
1401
CHECK_STATUS(status, NT_STATUS_OK);
1402
fnum2 = io.ntcreatex.out.file.fnum;
1404
q.query_secdesc.in.file.fnum = fnum2;
1405
status = smb_raw_fileinfo(cli->tree, tctx, &q);
1406
CHECK_STATUS(status, NT_STATUS_OK);
1408
smbcli_close(cli->tree, fnum2);
1409
smbcli_unlink(cli->tree, fname1);
1411
if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
1412
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1413
printf("Expected default sd:\n");
1414
NDR_PRINT_DEBUG(security_descriptor, sd_def);
1415
printf("at %d - got:\n", i);
1416
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1421
if (q.query_secdesc.out.sd->dacl == NULL ||
1422
q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1423
q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1424
!dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1425
sd_orig->owner_sid)) {
1426
printf("Bad sd in child file at %d\n", i);
1427
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1432
if (q.query_secdesc.out.sd->dacl->aces[0].flags !=
1433
test_flags[i].file_flags) {
1434
printf("incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
1435
q.query_secdesc.out.sd->dacl->aces[0].flags,
1436
test_flags[i].file_flags,
1437
test_flags[i].parent_flags,
1443
io.ntcreatex.in.fname = fname2;
1444
io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1445
status = smb_raw_open(cli->tree, tctx, &io);
1446
CHECK_STATUS(status, NT_STATUS_OK);
1447
fnum2 = io.ntcreatex.out.file.fnum;
1449
q.query_secdesc.in.file.fnum = fnum2;
1450
status = smb_raw_fileinfo(cli->tree, tctx, &q);
1451
CHECK_STATUS(status, NT_STATUS_OK);
1453
smbcli_close(cli->tree, fnum2);
1454
smbcli_rmdir(cli->tree, fname2);
1456
if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1457
(!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
1458
(test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
1459
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1460
printf("Expected default sd for dir at %d:\n", i);
1461
NDR_PRINT_DEBUG(security_descriptor, sd_def);
1463
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1468
if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1469
(test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
1470
if (q.query_secdesc.out.sd->dacl == NULL ||
1471
q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1472
q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1473
!dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1474
sd_orig->owner_sid) ||
1475
q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1476
printf("(CI & NP) Bad sd in child dir at %d (parent 0x%x)\n",
1477
i, test_flags[i].parent_flags);
1478
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1482
} else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
1483
if (q.query_secdesc.out.sd->dacl == NULL ||
1484
q.query_secdesc.out.sd->dacl->num_aces != 2 ||
1485
q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1486
!dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1487
sd_orig->owner_sid) ||
1488
q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
1489
!dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
1491
q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
1492
q.query_secdesc.out.sd->dacl->aces[1].flags !=
1493
(test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
1494
printf("(CI) Bad sd in child dir at %d (parent 0x%x)\n",
1495
i, test_flags[i].parent_flags);
1496
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1501
if (q.query_secdesc.out.sd->dacl == NULL ||
1502
q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1503
q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1504
!dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1506
q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1507
printf("(0) Bad sd in child dir at %d (parent 0x%x)\n",
1508
i, test_flags[i].parent_flags);
1509
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1516
printf("testing access checks on inherited create with %s\n", fname1);
1517
sd = security_descriptor_dacl_create(tctx,
1520
SEC_ACE_TYPE_ACCESS_ALLOWED,
1521
SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1522
SEC_ACE_FLAG_OBJECT_INHERIT,
1524
SEC_ACE_TYPE_ACCESS_ALLOWED,
1525
SEC_FILE_ALL | SEC_STD_ALL,
1528
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1529
set.set_secdesc.in.file.fnum = fnum;
1530
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1531
set.set_secdesc.in.sd = sd;
1532
status = smb_raw_setfileinfo(cli->tree, &set);
1533
CHECK_STATUS(status, NT_STATUS_OK);
1535
io.ntcreatex.in.fname = fname1;
1536
io.ntcreatex.in.create_options = 0;
1537
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1538
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1539
status = smb_raw_open(cli->tree, tctx, &io);
1540
CHECK_STATUS(status, NT_STATUS_OK);
1541
fnum2 = io.ntcreatex.out.file.fnum;
1542
CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1544
q.query_secdesc.in.file.fnum = fnum2;
1545
q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1546
status = smb_raw_fileinfo(cli->tree, tctx, &q);
1547
CHECK_STATUS(status, NT_STATUS_OK);
1548
smbcli_close(cli->tree, fnum2);
1550
sd2 = security_descriptor_dacl_create(tctx,
1553
SEC_ACE_TYPE_ACCESS_ALLOWED,
1554
SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1557
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
1558
printf("%s: security descriptors don't match!\n", __location__);
1560
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1561
printf("expected:\n");
1562
NDR_PRINT_DEBUG(security_descriptor, sd2);
1566
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1567
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1568
status = smb_raw_open(cli->tree, tctx, &io);
1569
if (NT_STATUS_IS_OK(status)) {
1570
printf("failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
1572
fnum2 = io.ntcreatex.out.file.fnum;
1573
CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1574
smbcli_close(cli->tree, fnum2);
1576
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1579
printf("trying without execute\n");
1580
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1581
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
1582
status = smb_raw_open(cli->tree, tctx, &io);
1583
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1585
printf("and with full permissions again\n");
1586
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1587
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1588
status = smb_raw_open(cli->tree, tctx, &io);
1589
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1591
io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1592
status = smb_raw_open(cli->tree, tctx, &io);
1593
CHECK_STATUS(status, NT_STATUS_OK);
1594
fnum2 = io.ntcreatex.out.file.fnum;
1595
CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1596
smbcli_close(cli->tree, fnum2);
1598
printf("put back original sd\n");
1599
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1600
set.set_secdesc.in.file.fnum = fnum;
1601
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1602
set.set_secdesc.in.sd = sd_orig;
1603
status = smb_raw_setfileinfo(cli->tree, &set);
1604
CHECK_STATUS(status, NT_STATUS_OK);
1606
smbcli_close(cli->tree, fnum);
1608
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1609
status = smb_raw_open(cli->tree, tctx, &io);
1610
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1612
io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1613
status = smb_raw_open(cli->tree, tctx, &io);
1614
CHECK_STATUS(status, NT_STATUS_OK);
1615
fnum2 = io.ntcreatex.out.file.fnum;
1616
CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1617
smbcli_close(cli->tree, fnum2);
1619
smbcli_unlink(cli->tree, fname1);
1620
smbcli_rmdir(cli->tree, dname);
1623
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1624
set.set_secdesc.in.file.fnum = fnum;
1625
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1626
set.set_secdesc.in.sd = sd_orig;
1627
status = smb_raw_setfileinfo(cli->tree, &set);
1629
smbcli_close(cli->tree, fnum);
1635
test dynamic acl inheritance
1637
static bool test_inheritance_dynamic(struct torture_context *tctx,
1638
struct smbcli_state *cli)
1642
const char *dname = BASEDIR "\\inheritance";
1643
const char *fname1 = BASEDIR "\\inheritance\\testfile";
1646
union smb_fileinfo q;
1647
union smb_setfileinfo set;
1648
struct security_descriptor *sd, *sd_orig=NULL;
1649
const char *owner_sid;
1651
printf("TESTING DYNAMIC ACL INHERITANCE\n");
1653
if (!torture_setup_dir(cli, BASEDIR)) {
1657
io.generic.level = RAW_OPEN_NTCREATEX;
1658
io.ntcreatex.in.root_fid = 0;
1659
io.ntcreatex.in.flags = 0;
1660
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1661
io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1662
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1663
io.ntcreatex.in.share_access = 0;
1664
io.ntcreatex.in.alloc_size = 0;
1665
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1666
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1667
io.ntcreatex.in.security_flags = 0;
1668
io.ntcreatex.in.fname = dname;
1670
status = smb_raw_open(cli->tree, tctx, &io);
1671
CHECK_STATUS(status, NT_STATUS_OK);
1672
fnum = io.ntcreatex.out.file.fnum;
1674
printf("get the original sd\n");
1675
q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1676
q.query_secdesc.in.file.fnum = fnum;
1677
q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1678
status = smb_raw_fileinfo(cli->tree, tctx, &q);
1679
CHECK_STATUS(status, NT_STATUS_OK);
1680
sd_orig = q.query_secdesc.out.sd;
1682
owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1684
printf("owner_sid is %s\n", owner_sid);
1686
sd = security_descriptor_dacl_create(tctx,
1689
SEC_ACE_TYPE_ACCESS_ALLOWED,
1690
SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
1691
SEC_ACE_FLAG_OBJECT_INHERIT,
1693
sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1695
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1696
set.set_secdesc.in.file.fnum = fnum;
1697
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1698
set.set_secdesc.in.sd = sd;
1699
status = smb_raw_setfileinfo(cli->tree, &set);
1700
CHECK_STATUS(status, NT_STATUS_OK);
1702
printf("create a file with an inherited acl\n");
1703
io.ntcreatex.in.fname = fname1;
1704
io.ntcreatex.in.create_options = 0;
1705
io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE;
1706
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1707
status = smb_raw_open(cli->tree, tctx, &io);
1708
CHECK_STATUS(status, NT_STATUS_OK);
1709
fnum2 = io.ntcreatex.out.file.fnum;
1710
smbcli_close(cli->tree, fnum2);
1712
printf("try and access file with base rights - should be OK\n");
1713
io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1714
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1715
status = smb_raw_open(cli->tree, tctx, &io);
1716
CHECK_STATUS(status, NT_STATUS_OK);
1717
fnum2 = io.ntcreatex.out.file.fnum;
1718
smbcli_close(cli->tree, fnum2);
1720
printf("try and access file with extra rights - should be denied\n");
1721
io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1722
status = smb_raw_open(cli->tree, tctx, &io);
1723
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1725
printf("update parent sd\n");
1726
sd = security_descriptor_dacl_create(tctx,
1729
SEC_ACE_TYPE_ACCESS_ALLOWED,
1730
SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE,
1731
SEC_ACE_FLAG_OBJECT_INHERIT,
1733
sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1735
set.set_secdesc.in.sd = sd;
1736
status = smb_raw_setfileinfo(cli->tree, &set);
1737
CHECK_STATUS(status, NT_STATUS_OK);
1739
printf("try and access file with base rights - should be OK\n");
1740
io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1741
status = smb_raw_open(cli->tree, tctx, &io);
1742
CHECK_STATUS(status, NT_STATUS_OK);
1743
fnum2 = io.ntcreatex.out.file.fnum;
1744
smbcli_close(cli->tree, fnum2);
1747
printf("try and access now - should be OK if dynamic inheritance works\n");
1748
io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1749
status = smb_raw_open(cli->tree, tctx, &io);
1750
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1751
printf("Server does not have dynamic inheritance\n");
1753
if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1754
printf("Server does have dynamic inheritance\n");
1756
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1758
smbcli_unlink(cli->tree, fname1);
1761
printf("put back original sd\n");
1762
set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1763
set.set_secdesc.in.file.fnum = fnum;
1764
set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1765
set.set_secdesc.in.sd = sd_orig;
1766
status = smb_raw_setfileinfo(cli->tree, &set);
1768
smbcli_close(cli->tree, fnum);
1769
smbcli_rmdir(cli->tree, dname);
1774
#define CHECK_STATUS_FOR_BIT_ACTION(status, bits, action) do { \
1775
if (!(bits & desired_64)) {\
1776
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); \
1779
CHECK_STATUS(status, NT_STATUS_OK); \
1783
#define CHECK_STATUS_FOR_BIT(status, bits, access) do { \
1784
if (NT_STATUS_IS_OK(status)) { \
1785
if (!(granted & access)) {\
1786
printf("(%s) %s but flags 0x%08X are not granted! granted[0x%08X] desired[0x%08X]\n", \
1787
__location__, nt_errstr(status), access, granted, desired); \
1792
if (granted & access) {\
1793
printf("(%s) %s but flags 0x%08X are granted! granted[0x%08X] desired[0x%08X]\n", \
1794
__location__, nt_errstr(status), access, granted, desired); \
1799
CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \
1802
/* test what access mask is needed for getting and setting security_descriptors */
1803
static bool test_sd_get_set(struct torture_context *tctx,
1804
struct smbcli_state *cli)
1809
union smb_fileinfo fi;
1810
union smb_setfileinfo si;
1811
struct security_descriptor *sd;
1812
struct security_descriptor *sd_owner = NULL;
1813
struct security_descriptor *sd_group = NULL;
1814
struct security_descriptor *sd_dacl = NULL;
1815
struct security_descriptor *sd_sacl = NULL;
1817
const char *fname = BASEDIR "\\sd_get_set.txt";
1818
uint64_t desired_64;
1819
uint32_t desired = 0, granted;
1821
#define NO_BITS_HACK (((uint64_t)1)<<32)
1822
uint64_t open_bits =
1824
SEC_FLAG_SYSTEM_SECURITY |
1825
SEC_FLAG_MAXIMUM_ALLOWED |
1829
uint64_t get_owner_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1830
uint64_t set_owner_bits = SEC_GENERIC_ALL | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
1831
uint64_t get_group_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1832
uint64_t set_group_bits = SEC_GENERIC_ALL | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
1833
uint64_t get_dacl_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1834
uint64_t set_dacl_bits = SEC_GENERIC_ALL | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_DAC;
1835
uint64_t get_sacl_bits = SEC_FLAG_SYSTEM_SECURITY;
1836
uint64_t set_sacl_bits = SEC_FLAG_SYSTEM_SECURITY;
1838
printf("TESTING ACCESS MASKS FOR SD GET/SET\n");
1840
/* first create a file with full access for everyone */
1841
sd = security_descriptor_dacl_create(tctx,
1842
0, SID_NT_ANONYMOUS, SID_BUILTIN_USERS,
1844
SEC_ACE_TYPE_ACCESS_ALLOWED,
1848
sd->type |= SEC_DESC_SACL_PRESENT;
1850
io.ntcreatex.level = RAW_OPEN_NTTRANS_CREATE;
1851
io.ntcreatex.in.root_fid = 0;
1852
io.ntcreatex.in.flags = 0;
1853
io.ntcreatex.in.access_mask = SEC_GENERIC_ALL;
1854
io.ntcreatex.in.create_options = 0;
1855
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1856
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1857
io.ntcreatex.in.alloc_size = 0;
1858
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1859
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1860
io.ntcreatex.in.security_flags = 0;
1861
io.ntcreatex.in.fname = fname;
1862
io.ntcreatex.in.sec_desc = sd;
1863
io.ntcreatex.in.ea_list = NULL;
1864
status = smb_raw_open(cli->tree, tctx, &io);
1865
CHECK_STATUS(status, NT_STATUS_OK);
1866
fnum = io.ntcreatex.out.file.fnum;
1868
status = smbcli_close(cli->tree, fnum);
1869
CHECK_STATUS(status, NT_STATUS_OK);
1872
* now try each access_mask bit and no bit at all in a loop
1873
* and see what's allowed
1874
* NOTE: if i == 32 it means access_mask = 0 (see NO_BITS_HACK above)
1876
for (i=0; i <= 32; i++) {
1877
desired_64 = ((uint64_t)1) << i;
1878
desired = (uint32_t)desired_64;
1880
/* first open the file with the desired access */
1881
io.ntcreatex.level = RAW_OPEN_NTCREATEX;
1882
io.ntcreatex.in.access_mask = desired;
1883
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1884
status = smb_raw_open(cli->tree, tctx, &io);
1885
CHECK_STATUS_FOR_BIT_ACTION(status, open_bits, goto next);
1886
fnum = io.ntcreatex.out.file.fnum;
1888
/* then check what access was granted */
1889
fi.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
1890
fi.access_information.in.file.fnum = fnum;
1891
status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1892
CHECK_STATUS(status, NT_STATUS_OK);
1893
granted = fi.access_information.out.access_flags;
1895
/* test the owner */
1897
fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1898
fi.query_secdesc.in.file.fnum = fnum;
1899
fi.query_secdesc.in.secinfo_flags = SECINFO_OWNER;
1900
status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1901
CHECK_STATUS_FOR_BIT(status, get_owner_bits, SEC_STD_READ_CONTROL);
1902
if (fi.query_secdesc.out.sd) {
1903
sd_owner = fi.query_secdesc.out.sd;
1904
} else if (!sd_owner) {
1907
si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1908
si.set_secdesc.in.file.fnum = fnum;
1909
si.set_secdesc.in.secinfo_flags = SECINFO_OWNER;
1910
si.set_secdesc.in.sd = sd_owner;
1911
status = smb_raw_setfileinfo(cli->tree, &si);
1912
CHECK_STATUS_FOR_BIT(status, set_owner_bits, SEC_STD_WRITE_OWNER);
1914
/* test the group */
1916
fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1917
fi.query_secdesc.in.file.fnum = fnum;
1918
fi.query_secdesc.in.secinfo_flags = SECINFO_GROUP;
1919
status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1920
CHECK_STATUS_FOR_BIT(status, get_group_bits, SEC_STD_READ_CONTROL);
1921
if (fi.query_secdesc.out.sd) {
1922
sd_group = fi.query_secdesc.out.sd;
1923
} else if (!sd_group) {
1926
si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1927
si.set_secdesc.in.file.fnum = fnum;
1928
si.set_secdesc.in.secinfo_flags = SECINFO_GROUP;
1929
si.set_secdesc.in.sd = sd_group;
1930
status = smb_raw_setfileinfo(cli->tree, &si);
1931
CHECK_STATUS_FOR_BIT(status, set_group_bits, SEC_STD_WRITE_OWNER);
1935
fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1936
fi.query_secdesc.in.file.fnum = fnum;
1937
fi.query_secdesc.in.secinfo_flags = SECINFO_DACL;
1938
status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1939
CHECK_STATUS_FOR_BIT(status, get_dacl_bits, SEC_STD_READ_CONTROL);
1940
if (fi.query_secdesc.out.sd) {
1941
sd_dacl = fi.query_secdesc.out.sd;
1942
} else if (!sd_dacl) {
1945
si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1946
si.set_secdesc.in.file.fnum = fnum;
1947
si.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1948
si.set_secdesc.in.sd = sd_dacl;
1949
status = smb_raw_setfileinfo(cli->tree, &si);
1950
CHECK_STATUS_FOR_BIT(status, set_dacl_bits, SEC_STD_WRITE_DAC);
1954
fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1955
fi.query_secdesc.in.file.fnum = fnum;
1956
fi.query_secdesc.in.secinfo_flags = SECINFO_SACL;
1957
status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1958
CHECK_STATUS_FOR_BIT(status, get_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
1959
if (fi.query_secdesc.out.sd) {
1960
sd_sacl = fi.query_secdesc.out.sd;
1961
} else if (!sd_sacl) {
1964
si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1965
si.set_secdesc.in.file.fnum = fnum;
1966
si.set_secdesc.in.secinfo_flags = SECINFO_SACL;
1967
si.set_secdesc.in.sd = sd_sacl;
1968
status = smb_raw_setfileinfo(cli->tree, &si);
1969
CHECK_STATUS_FOR_BIT(status, set_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
1971
/* close the handle */
1972
status = smbcli_close(cli->tree, fnum);
1973
CHECK_STATUS(status, NT_STATUS_OK);
1979
smbcli_close(cli->tree, fnum);
1980
smbcli_unlink(cli->tree, fname);
1987
basic testing of security descriptor calls
1989
bool torture_raw_acls(struct torture_context *tctx, struct smbcli_state *cli)
1993
if (!torture_setup_dir(cli, BASEDIR)) {
1997
ret &= test_sd(tctx, cli);
1998
ret &= test_nttrans_create(tctx, cli);
1999
ret &= test_nttrans_create_null_dacl(tctx, cli);
2000
ret &= test_creator_sid(tctx, cli);
2001
ret &= test_generic_bits(tctx, cli);
2002
ret &= test_owner_bits(tctx, cli);
2003
ret &= test_inheritance(tctx, cli);
2004
ret &= test_inheritance_dynamic(tctx, cli);
2005
ret &= test_sd_get_set(tctx, cli);
2007
smb_raw_exit(cli->session);
2008
smbcli_deltree(cli->tree, BASEDIR);