~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/torture/raw/acls.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/CIFS implementation.
 
3
 
 
4
   test security descriptor operations
 
5
 
 
6
   Copyright (C) Andrew Tridgell 2004
 
7
   
 
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.
 
12
   
 
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.
 
17
   
 
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/>.
 
20
*/
 
21
 
 
22
#include "includes.h"
 
23
#include "torture/torture.h"
 
24
#include "libcli/raw/libcliraw.h"
 
25
#include "libcli/libcli.h"
 
26
#include "librpc/gen_ndr/lsa.h"
 
27
#include "libcli/util/clilsa.h"
 
28
#include "libcli/security/security.h"
 
29
#include "torture/util.h"
 
30
#include "librpc/gen_ndr/ndr_security.h"
 
31
 
 
32
#define BASEDIR "\\testsd"
 
33
 
 
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)); \
 
38
                ret = false; \
 
39
                goto done; \
 
40
        }} while (0)
 
41
 
 
42
 
 
43
static bool test_sd(struct torture_context *tctx, 
 
44
                                        struct smbcli_state *cli)
 
45
{
 
46
        NTSTATUS status;
 
47
        union smb_open io;
 
48
        const char *fname = BASEDIR "\\sd.txt";
 
49
        bool ret = true;
 
50
        int fnum = -1;
 
51
        union smb_fileinfo q;
 
52
        union smb_setfileinfo set;
 
53
        struct security_ace ace;
 
54
        struct security_descriptor *sd;
 
55
        struct dom_sid *test_sid;
 
56
 
 
57
        printf("TESTING SETFILEINFO EA_SET\n");
 
58
 
 
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;
 
76
        
 
77
        q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
 
78
        q.query_secdesc.in.file.fnum = fnum;
 
79
        q.query_secdesc.in.secinfo_flags = 
 
80
                SECINFO_OWNER |
 
81
                SECINFO_GROUP |
 
82
                SECINFO_DACL;
 
83
        status = smb_raw_fileinfo(cli->tree, tctx, &q);
 
84
        CHECK_STATUS(status, NT_STATUS_OK);
 
85
        sd = q.query_secdesc.out.sd;
 
86
 
 
87
        printf("add a new ACE to the DACL\n");
 
88
 
 
89
        test_sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1234-5432");
 
90
 
 
91
        ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
 
92
        ace.flags = 0;
 
93
        ace.access_mask = SEC_STD_ALL;
 
94
        ace.trustee = *test_sid;
 
95
 
 
96
        status = security_descriptor_dacl_add(sd, &ace);
 
97
        CHECK_STATUS(status, NT_STATUS_OK);
 
98
 
 
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;
 
103
 
 
104
        status = smb_raw_setfileinfo(cli->tree, &set);
 
105
        CHECK_STATUS(status, NT_STATUS_OK);
 
106
 
 
107
        status = smb_raw_fileinfo(cli->tree, tctx, &q);
 
108
        CHECK_STATUS(status, NT_STATUS_OK);
 
109
 
 
110
        if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
 
111
                printf("%s: security descriptors don't match!\n", __location__);
 
112
                printf("got:\n");
 
113
                NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
 
114
                printf("expected:\n");
 
115
                NDR_PRINT_DEBUG(security_descriptor, sd);
 
116
                ret = false;
 
117
        }
 
118
 
 
119
        printf("remove it again\n");
 
120
 
 
121
        status = security_descriptor_dacl_del(sd, test_sid);
 
122
        CHECK_STATUS(status, NT_STATUS_OK);
 
123
 
 
124
        status = smb_raw_setfileinfo(cli->tree, &set);
 
125
        CHECK_STATUS(status, NT_STATUS_OK);
 
126
 
 
127
        status = smb_raw_fileinfo(cli->tree, tctx, &q);
 
128
        CHECK_STATUS(status, NT_STATUS_OK);
 
129
 
 
130
        if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
 
131
                printf("%s: security descriptors don't match!\n", __location__);
 
132
                printf("got:\n");
 
133
                NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
 
134
                printf("expected:\n");
 
135
                NDR_PRINT_DEBUG(security_descriptor, sd);
 
136
                ret = false;
 
137
        }
 
138
 
 
139
done:
 
140
        smbcli_close(cli->tree, fnum);
 
141
        return ret;
 
142
}
 
143
 
 
144
 
 
145
/*
 
146
  test using nttrans create to create a file with an initial acl set
 
147
*/
 
148
static bool test_nttrans_create(struct torture_context *tctx, 
 
149
                                                                struct smbcli_state *cli)
 
150
{
 
151
        NTSTATUS status;
 
152
        union smb_open io;
 
153
        const char *fname = BASEDIR "\\acl2.txt";
 
154
        bool ret = true;
 
155
        int fnum = -1;
 
156
        union smb_fileinfo q;
 
157
        struct security_ace ace;
 
158
        struct security_descriptor *sd;
 
159
        struct dom_sid *test_sid;
 
160
 
 
161
        printf("testing nttrans create with sec_desc\n");
 
162
 
 
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;
 
179
 
 
180
        printf("creating normal file\n");
 
181
 
 
182
        status = smb_raw_open(cli->tree, tctx, &io);
 
183
        CHECK_STATUS(status, NT_STATUS_OK);
 
184
        fnum = io.ntcreatex.out.file.fnum;
 
185
 
 
186
        printf("querying ACL\n");
 
187
 
 
188
        q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
 
189
        q.query_secdesc.in.file.fnum = fnum;
 
190
        q.query_secdesc.in.secinfo_flags = 
 
191
                SECINFO_OWNER |
 
192
                SECINFO_GROUP |
 
193
                SECINFO_DACL;
 
194
        status = smb_raw_fileinfo(cli->tree, tctx, &q);
 
195
        CHECK_STATUS(status, NT_STATUS_OK);
 
196
        sd = q.query_secdesc.out.sd;
 
197
 
 
198
        smbcli_close(cli->tree, fnum);
 
199
        smbcli_unlink(cli->tree, fname);
 
200
 
 
201
        printf("adding a new ACE\n");
 
202
        test_sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1234-54321");
 
203
 
 
204
        ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
 
205
        ace.flags = 0;
 
206
        ace.access_mask = SEC_STD_ALL;
 
207
        ace.trustee = *test_sid;
 
208
 
 
209
        status = security_descriptor_dacl_add(sd, &ace);
 
210
        CHECK_STATUS(status, NT_STATUS_OK);
 
211
        
 
212
        printf("creating a file with an initial ACL\n");
 
213
 
 
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;
 
218
        
 
219
        q.query_secdesc.in.file.fnum = fnum;
 
220
        status = smb_raw_fileinfo(cli->tree, tctx, &q);
 
221
        CHECK_STATUS(status, NT_STATUS_OK);
 
222
 
 
223
        if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
 
224
                printf("%s: security descriptors don't match!\n", __location__);
 
225
                printf("got:\n");
 
226
                NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
 
227
                printf("expected:\n");
 
228
                NDR_PRINT_DEBUG(security_descriptor, sd);
 
229
                ret = false;
 
230
        }
 
231
 
 
232
done:
 
233
        smbcli_close(cli->tree, fnum);
 
234
        return ret;
 
235
}
 
236
 
 
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)); \
 
246
                ret = false; \
 
247
                goto done; \
 
248
        } \
 
249
} while (0)
 
250
 
 
251
/*
 
252
  test using NTTRANS CREATE to create a file with a null ACL set
 
253
*/
 
254
static bool test_nttrans_create_null_dacl(struct torture_context *tctx,
 
255
                                          struct smbcli_state *cli)
 
256
{
 
257
        NTSTATUS status;
 
258
        union smb_open io;
 
259
        const char *fname = BASEDIR "\\acl3.txt";
 
260
        bool ret = true;
 
261
        int fnum = -1;
 
262
        union smb_fileinfo q;
 
263
        union smb_setfileinfo s;
 
264
        struct security_descriptor *sd = security_descriptor_initialise(tctx);
 
265
        struct security_acl dacl;
 
266
 
 
267
        printf("TESTING SEC_DESC WITH A NULL DACL\n");
 
268
 
 
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;
 
285
 
 
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;
 
290
 
 
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 =
 
295
                SECINFO_OWNER |
 
296
                SECINFO_GROUP |
 
297
                SECINFO_DACL;
 
298
        status = smb_raw_fileinfo(cli->tree, tctx, &q);
 
299
        CHECK_STATUS(status, NT_STATUS_OK);
 
300
 
 
301
        /*
 
302
         * Testing the created DACL,
 
303
         * the server should add the inherited DACL
 
304
         * when SEC_DESC_DACL_PRESENT isn't specified
 
305
         */
 
306
        if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
 
307
                printf("DACL_PRESENT flag not set by the server!\n");
 
308
                ret = false;
 
309
                goto done;
 
310
        }
 
311
        if (q.query_secdesc.out.sd->dacl == NULL) {
 
312
                printf("no DACL has been created on the server!\n");
 
313
                ret = false;
 
314
                goto done;
 
315
        }
 
316
 
 
317
        printf("set NULL DACL\n");
 
318
        sd->type |= SEC_DESC_DACL_PRESENT;
 
319
 
 
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);
 
326
 
 
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 =
 
331
                SECINFO_OWNER |
 
332
                SECINFO_GROUP |
 
333
                SECINFO_DACL;
 
334
        status = smb_raw_fileinfo(cli->tree, tctx, &q);
 
335
        CHECK_STATUS(status, NT_STATUS_OK);
 
336
 
 
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");
 
340
                ret = false;
 
341
                goto done;
 
342
        }
 
343
        if (q.query_secdesc.out.sd->dacl != NULL) {
 
344
                printf("DACL has been created on the server!\n");
 
345
                ret = false;
 
346
                goto done;
 
347
        }
 
348
 
 
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);
 
356
 
 
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);
 
364
 
 
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);
 
372
 
 
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);
 
380
 
 
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);
 
388
 
 
389
        printf("set DACL with 0 aces\n");
 
390
        ZERO_STRUCT(dacl);
 
391
        dacl.revision = SECURITY_ACL_REVISION_NT4;
 
392
        dacl.num_aces = 0;
 
393
        sd->dacl = &dacl;
 
394
 
 
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);
 
401
 
 
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 =
 
406
                SECINFO_OWNER |
 
407
                SECINFO_GROUP |
 
408
                SECINFO_DACL;
 
409
        status = smb_raw_fileinfo(cli->tree, tctx, &q);
 
410
        CHECK_STATUS(status, NT_STATUS_OK);
 
411
 
 
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");
 
415
                ret = false;
 
416
                goto done;
 
417
        }
 
418
        if (q.query_secdesc.out.sd->dacl == NULL) {
 
419
                printf("no DACL has been created on the server!\n");
 
420
                ret = false;
 
421
                goto done;
 
422
        }
 
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);
 
426
                ret = false;
 
427
                goto done;
 
428
        }
 
429
 
 
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);
 
437
 
 
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);
 
442
 
 
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);
 
447
 
 
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);
 
452
 
 
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);
 
457
 
 
458
        printf("set empty sd\n");
 
459
        sd->type &= ~SEC_DESC_DACL_PRESENT;
 
460
        sd->dacl = NULL;
 
461
 
 
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);
 
468
 
 
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 =
 
473
                SECINFO_OWNER |
 
474
                SECINFO_GROUP |
 
475
                SECINFO_DACL;
 
476
        status = smb_raw_fileinfo(cli->tree, tctx, &q);
 
477
        CHECK_STATUS(status, NT_STATUS_OK);
 
478
 
 
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");
 
482
                ret = false;
 
483
                goto done;
 
484
        }
 
485
        if (q.query_secdesc.out.sd->dacl != NULL) {
 
486
                printf("DACL has been created on the server!\n");
 
487
                ret = false;
 
488
                goto done;
 
489
        }
 
490
done:
 
491
        smbcli_close(cli->tree, fnum);
 
492
        return ret;
 
493
}
 
494
 
 
495
/*
 
496
  test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
 
497
  mapping bits
 
498
*/
 
499
static bool test_creator_sid(struct torture_context *tctx, 
 
500
                                                         struct smbcli_state *cli)
 
501
{
 
502
        NTSTATUS status;
 
503
        union smb_open io;
 
504
        const char *fname = BASEDIR "\\creator.txt";
 
505
        bool ret = true;
 
506
        int fnum = -1;
 
507
        union smb_fileinfo q;
 
508
        union smb_setfileinfo set;
 
509
        struct security_descriptor *sd, *sd_orig, *sd2;
 
510
        const char *owner_sid;
 
511
 
 
512
        printf("TESTING SID_CREATOR_OWNER\n");
 
513
 
 
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;
 
531
 
 
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;
 
539
 
 
540
        owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
 
541
 
 
542
        printf("set a sec desc allowing no write by CREATOR_OWNER\n");
 
543
        sd = security_descriptor_dacl_create(tctx,
 
544
                                        0, NULL, NULL,
 
545
                                        SID_CREATOR_OWNER,
 
546
                                        SEC_ACE_TYPE_ACCESS_ALLOWED,
 
547
                                        SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
 
548
                                        0,
 
549
                                        NULL);
 
550
 
 
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;
 
555
 
 
556
        status = smb_raw_setfileinfo(cli->tree, &set);
 
557
        CHECK_STATUS(status, NT_STATUS_OK);
 
558
 
 
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);
 
563
 
 
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);
 
568
 
 
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);
 
573
 
 
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);
 
578
 
 
579
        printf("set a sec desc allowing no write by owner\n");
 
580
        sd = security_descriptor_dacl_create(tctx,
 
581
                                        0, owner_sid, NULL,
 
582
                                        owner_sid,
 
583
                                        SEC_ACE_TYPE_ACCESS_ALLOWED,
 
584
                                        SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
 
585
                                        0,
 
586
                                        NULL);
 
587
 
 
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);
 
594
 
 
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__);
 
600
                printf("got:\n");
 
601
                NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
 
602
                printf("expected:\n");
 
603
                NDR_PRINT_DEBUG(security_descriptor, sd);
 
604
                ret = false;
 
605
        }
 
606
 
 
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);
 
611
 
 
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, 
 
617
                           SEC_FILE_READ_DATA|
 
618
                           SEC_FILE_READ_ATTRIBUTE);
 
619
        smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
 
620
 
 
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);
 
625
 
 
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);
 
633
 
 
634
        printf("set a sec desc allowing generic read by owner\n");
 
635
        sd = security_descriptor_dacl_create(tctx,
 
636
                                        0, NULL, NULL,
 
637
                                        owner_sid,
 
638
                                        SEC_ACE_TYPE_ACCESS_ALLOWED,
 
639
                                        SEC_GENERIC_READ | SEC_STD_ALL,
 
640
                                        0,
 
641
                                        NULL);
 
642
 
 
643
        set.set_secdesc.in.sd = sd;
 
644
        status = smb_raw_setfileinfo(cli->tree, &set);
 
645
        CHECK_STATUS(status, NT_STATUS_OK);
 
646
 
 
647
        printf("check that generic read has been mapped correctly\n");
 
648
        sd2 = security_descriptor_dacl_create(tctx,
 
649
                                         0, owner_sid, NULL,
 
650
                                         owner_sid,
 
651
                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
 
652
                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
 
653
                                         0,
 
654
                                         NULL);
 
655
 
 
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__);
 
660
                printf("got:\n");
 
661
                NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
 
662
                printf("expected:\n");
 
663
                NDR_PRINT_DEBUG(security_descriptor, sd2);
 
664
                ret = false;
 
665
        }
 
666
        
 
667
 
 
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);
 
672
 
 
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, 
 
678
                           SEC_FILE_READ_DATA | 
 
679
                           SEC_FILE_READ_ATTRIBUTE);
 
680
        smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
 
681
 
 
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);
 
686
 
 
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);
 
693
 
 
694
 
 
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);
 
699
 
 
700
 
 
701
done:
 
702
        smbcli_close(cli->tree, fnum);
 
703
        return ret;
 
704
}
 
705
 
 
706
 
 
707
/*
 
708
  test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
 
709
  SEC_FILE_xx bits
 
710
*/
 
711
static bool test_generic_bits(struct torture_context *tctx, 
 
712
                                                          struct smbcli_state *cli)
 
713
{
 
714
        NTSTATUS status;
 
715
        union smb_open io;
 
716
        const char *fname = BASEDIR "\\generic.txt";
 
717
        bool ret = true;
 
718
        int fnum = -1, i;
 
719
        union smb_fileinfo q;
 
720
        union smb_setfileinfo set;
 
721
        struct security_descriptor *sd, *sd_orig, *sd2;
 
722
        const char *owner_sid;
 
723
        const struct {
 
724
                uint32_t gen_bits;
 
725
                uint32_t specific_bits;
 
726
        } file_mappings[] = {
 
727
                { 0,                       0 },
 
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 }
 
734
        };
 
735
        const struct {
 
736
                uint32_t gen_bits;
 
737
                uint32_t specific_bits;
 
738
        } dir_mappings[] = {
 
739
                { 0,                   0 },
 
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 }
 
744
        };
 
745
        bool has_restore_privilege;
 
746
        bool has_take_ownership_privilege;
 
747
 
 
748
        printf("TESTING FILE GENERIC BITS\n");
 
749
 
 
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 | 
 
755
                SEC_STD_WRITE_DAC | 
 
756
                SEC_STD_WRITE_OWNER;
 
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;
 
770
 
 
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;
 
778
 
 
779
        owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
 
780
 
 
781
        status = smblsa_sid_check_privilege(cli, 
 
782
                                            owner_sid, 
 
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));
 
787
        }
 
788
        printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
 
789
 
 
790
        status = smblsa_sid_check_privilege(cli, 
 
791
                                            owner_sid, 
 
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));
 
796
        }
 
797
        printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
 
798
 
 
799
        for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
 
800
                uint32_t expected_mask = 
 
801
                        SEC_STD_WRITE_DAC | 
 
802
                        SEC_STD_READ_CONTROL | 
 
803
                        SEC_FILE_READ_ATTRIBUTE |
 
804
                        SEC_STD_DELETE;
 
805
                uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
 
806
 
 
807
                if (has_restore_privilege) {
 
808
                        expected_mask_anon |= SEC_STD_DELETE;
 
809
                }
 
810
 
 
811
                printf("testing generic bits 0x%08x\n", 
 
812
                       file_mappings[i].gen_bits);
 
813
                sd = security_descriptor_dacl_create(tctx,
 
814
                                                0, owner_sid, NULL,
 
815
                                                owner_sid,
 
816
                                                SEC_ACE_TYPE_ACCESS_ALLOWED,
 
817
                                                file_mappings[i].gen_bits,
 
818
                                                0,
 
819
                                                NULL);
 
820
 
 
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;
 
825
 
 
826
                status = smb_raw_setfileinfo(cli->tree, &set);
 
827
                CHECK_STATUS(status, NT_STATUS_OK);
 
828
 
 
829
                sd2 = security_descriptor_dacl_create(tctx,
 
830
                                                 0, owner_sid, NULL,
 
831
                                                 owner_sid,
 
832
                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
 
833
                                                 file_mappings[i].specific_bits,
 
834
                                                 0,
 
835
                                                 NULL);
 
836
 
 
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__);
 
841
                        printf("got:\n");
 
842
                        NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
 
843
                        printf("expected:\n");
 
844
                        NDR_PRINT_DEBUG(security_descriptor, sd2);
 
845
                        ret = false;
 
846
                }
 
847
 
 
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);
 
854
 
 
855
                if (!has_take_ownership_privilege) {
 
856
                        continue;
 
857
                }
 
858
 
 
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,
 
863
                                                owner_sid,
 
864
                                                SEC_ACE_TYPE_ACCESS_ALLOWED,
 
865
                                                file_mappings[i].gen_bits,
 
866
                                                0,
 
867
                                                NULL);
 
868
 
 
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;
 
873
 
 
874
                status = smb_raw_setfileinfo(cli->tree, &set);
 
875
                CHECK_STATUS(status, NT_STATUS_OK);
 
876
 
 
877
                sd2 = security_descriptor_dacl_create(tctx,
 
878
                                                 0, SID_NT_ANONYMOUS, NULL,
 
879
                                                 owner_sid,
 
880
                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
 
881
                                                 file_mappings[i].specific_bits,
 
882
                                                 0,
 
883
                                                 NULL);
 
884
 
 
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__);
 
889
                        printf("got:\n");
 
890
                        NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
 
891
                        printf("expected:\n");
 
892
                        NDR_PRINT_DEBUG(security_descriptor, sd2);
 
893
                        ret = false;
 
894
                }
 
895
 
 
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);
 
902
        }
 
903
 
 
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);
 
908
 
 
909
        smbcli_close(cli->tree, fnum);
 
910
        smbcli_unlink(cli->tree, fname);
 
911
 
 
912
 
 
913
        printf("TESTING DIR GENERIC BITS\n");
 
914
 
 
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 | 
 
920
                SEC_STD_WRITE_DAC | 
 
921
                SEC_STD_WRITE_OWNER;
 
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;
 
935
 
 
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;
 
943
 
 
944
        owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
 
945
 
 
946
        status = smblsa_sid_check_privilege(cli, 
 
947
                                            owner_sid, 
 
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));
 
952
        }
 
953
        printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
 
954
 
 
955
        status = smblsa_sid_check_privilege(cli, 
 
956
                                            owner_sid, 
 
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));
 
961
        }
 
962
        printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
 
963
 
 
964
        for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
 
965
                uint32_t expected_mask = 
 
966
                        SEC_STD_WRITE_DAC | 
 
967
                        SEC_STD_READ_CONTROL | 
 
968
                        SEC_FILE_READ_ATTRIBUTE |
 
969
                        SEC_STD_DELETE;
 
970
                uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
 
971
 
 
972
                if (has_restore_privilege) {
 
973
                        expected_mask_anon |= SEC_STD_DELETE;
 
974
                }
 
975
 
 
976
                printf("testing generic bits 0x%08x\n", 
 
977
                       file_mappings[i].gen_bits);
 
978
                sd = security_descriptor_dacl_create(tctx,
 
979
                                                0, owner_sid, NULL,
 
980
                                                owner_sid,
 
981
                                                SEC_ACE_TYPE_ACCESS_ALLOWED,
 
982
                                                dir_mappings[i].gen_bits,
 
983
                                                0,
 
984
                                                NULL);
 
985
 
 
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;
 
990
 
 
991
                status = smb_raw_setfileinfo(cli->tree, &set);
 
992
                CHECK_STATUS(status, NT_STATUS_OK);
 
993
 
 
994
                sd2 = security_descriptor_dacl_create(tctx,
 
995
                                                 0, owner_sid, NULL,
 
996
                                                 owner_sid,
 
997
                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
 
998
                                                 dir_mappings[i].specific_bits,
 
999
                                                 0,
 
1000
                                                 NULL);
 
1001
 
 
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__);
 
1006
                        printf("got:\n");
 
1007
                        NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
 
1008
                        printf("expected:\n");
 
1009
                        NDR_PRINT_DEBUG(security_descriptor, sd2);
 
1010
                        ret = false;
 
1011
                }
 
1012
 
 
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);
 
1019
 
 
1020
                if (!has_take_ownership_privilege) {
 
1021
                        continue;
 
1022
                }
 
1023
 
 
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,
 
1028
                                                owner_sid,
 
1029
                                                SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1030
                                                file_mappings[i].gen_bits,
 
1031
                                                0,
 
1032
                                                NULL);
 
1033
 
 
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;
 
1038
 
 
1039
                status = smb_raw_setfileinfo(cli->tree, &set);
 
1040
                CHECK_STATUS(status, NT_STATUS_OK);
 
1041
 
 
1042
                sd2 = security_descriptor_dacl_create(tctx,
 
1043
                                                 0, SID_NT_ANONYMOUS, NULL,
 
1044
                                                 owner_sid,
 
1045
                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1046
                                                 file_mappings[i].specific_bits,
 
1047
                                                 0,
 
1048
                                                 NULL);
 
1049
 
 
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__);
 
1054
                        printf("got:\n");
 
1055
                        NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
 
1056
                        printf("expected:\n");
 
1057
                        NDR_PRINT_DEBUG(security_descriptor, sd2);
 
1058
                        ret = false;
 
1059
                }
 
1060
 
 
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);
 
1067
        }
 
1068
 
 
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);
 
1073
 
 
1074
        smbcli_close(cli->tree, fnum);
 
1075
        smbcli_unlink(cli->tree, fname);
 
1076
 
 
1077
done:
 
1078
        smbcli_close(cli->tree, fnum);
 
1079
        return ret;
 
1080
}
 
1081
 
 
1082
 
 
1083
/*
 
1084
  see what access bits the owner of a file always gets
 
1085
*/
 
1086
static bool test_owner_bits(struct torture_context *tctx, 
 
1087
                                                        struct smbcli_state *cli)
 
1088
{
 
1089
        NTSTATUS status;
 
1090
        union smb_open io;
 
1091
        const char *fname = BASEDIR "\\test_owner_bits.txt";
 
1092
        bool ret = true;
 
1093
        int fnum = -1, i;
 
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;
 
1101
 
 
1102
        printf("TESTING FILE OWNER BITS\n");
 
1103
 
 
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 | 
 
1109
                SEC_STD_WRITE_DAC | 
 
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;
 
1124
 
 
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;
 
1132
 
 
1133
        owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
 
1134
 
 
1135
        status = smblsa_sid_check_privilege(cli, 
 
1136
                                            owner_sid, 
 
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));
 
1141
        }
 
1142
        printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
 
1143
 
 
1144
        status = smblsa_sid_check_privilege(cli, 
 
1145
                                            owner_sid, 
 
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));
 
1150
        }
 
1151
        printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
 
1152
 
 
1153
        sd = security_descriptor_dacl_create(tctx,
 
1154
                                        0, NULL, NULL,
 
1155
                                        owner_sid,
 
1156
                                        SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1157
                                        SEC_FILE_WRITE_DATA,
 
1158
                                        0,
 
1159
                                        NULL);
 
1160
 
 
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;
 
1165
 
 
1166
        status = smb_raw_setfileinfo(cli->tree, &set);
 
1167
        CHECK_STATUS(status, NT_STATUS_OK);
 
1168
 
 
1169
        expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
 
1170
 
 
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);
 
1179
                        }
 
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);
 
1183
                } else {
 
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);
 
1188
                        }
 
1189
                        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
 
1190
                }
 
1191
        }
 
1192
 
 
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);
 
1197
 
 
1198
done:
 
1199
        smbcli_close(cli->tree, fnum);
 
1200
        smbcli_unlink(cli->tree, fname);
 
1201
        return ret;
 
1202
}
 
1203
 
 
1204
 
 
1205
 
 
1206
/*
 
1207
  test the inheritance of ACL flags onto new files and directories
 
1208
*/
 
1209
static bool test_inheritance(struct torture_context *tctx, 
 
1210
                                                         struct smbcli_state *cli)
 
1211
{
 
1212
        NTSTATUS status;
 
1213
        union smb_open io;
 
1214
        const char *dname = BASEDIR "\\inheritance";
 
1215
        const char *fname1 = BASEDIR "\\inheritance\\testfile";
 
1216
        const char *fname2 = BASEDIR "\\inheritance\\testdir";
 
1217
        bool ret = true;
 
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;
 
1224
        const struct {
 
1225
                uint32_t parent_flags;
 
1226
                uint32_t file_flags;
 
1227
                uint32_t dir_flags;
 
1228
        } test_flags[] = {
 
1229
                {
 
1230
                        0, 
 
1231
                        0,
 
1232
                        0
 
1233
                },
 
1234
                {
 
1235
                        SEC_ACE_FLAG_OBJECT_INHERIT,
 
1236
                        0,
 
1237
                        SEC_ACE_FLAG_OBJECT_INHERIT | 
 
1238
                        SEC_ACE_FLAG_INHERIT_ONLY,
 
1239
                },
 
1240
                {
 
1241
                        SEC_ACE_FLAG_CONTAINER_INHERIT,
 
1242
                        0,
 
1243
                        SEC_ACE_FLAG_CONTAINER_INHERIT,
 
1244
                },
 
1245
                {
 
1246
                        SEC_ACE_FLAG_OBJECT_INHERIT | 
 
1247
                        SEC_ACE_FLAG_CONTAINER_INHERIT,
 
1248
                        0,
 
1249
                        SEC_ACE_FLAG_OBJECT_INHERIT | 
 
1250
                        SEC_ACE_FLAG_CONTAINER_INHERIT,
 
1251
                },
 
1252
                {
 
1253
                        SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
 
1254
                        0,
 
1255
                        0,
 
1256
                },
 
1257
                {
 
1258
                        SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
 
1259
                        SEC_ACE_FLAG_OBJECT_INHERIT,
 
1260
                        0,
 
1261
                        0,
 
1262
                },
 
1263
                {
 
1264
                        SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
 
1265
                        SEC_ACE_FLAG_CONTAINER_INHERIT,
 
1266
                        0,
 
1267
                        0,
 
1268
                },
 
1269
                {
 
1270
                        SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
 
1271
                        SEC_ACE_FLAG_CONTAINER_INHERIT | 
 
1272
                        SEC_ACE_FLAG_OBJECT_INHERIT,
 
1273
                        0,
 
1274
                        0,
 
1275
                },
 
1276
                {
 
1277
                        SEC_ACE_FLAG_INHERIT_ONLY,
 
1278
                        0,
 
1279
                        0,
 
1280
                },
 
1281
                {
 
1282
                        SEC_ACE_FLAG_INHERIT_ONLY | 
 
1283
                        SEC_ACE_FLAG_OBJECT_INHERIT,
 
1284
                        0,
 
1285
                        SEC_ACE_FLAG_OBJECT_INHERIT | 
 
1286
                        SEC_ACE_FLAG_INHERIT_ONLY,
 
1287
                },
 
1288
                {
 
1289
                        SEC_ACE_FLAG_INHERIT_ONLY | 
 
1290
                        SEC_ACE_FLAG_CONTAINER_INHERIT,
 
1291
                        0,
 
1292
                        SEC_ACE_FLAG_CONTAINER_INHERIT,
 
1293
                },
 
1294
                {
 
1295
                        SEC_ACE_FLAG_INHERIT_ONLY | 
 
1296
                        SEC_ACE_FLAG_CONTAINER_INHERIT | 
 
1297
                        SEC_ACE_FLAG_OBJECT_INHERIT,
 
1298
                        0,
 
1299
                        SEC_ACE_FLAG_CONTAINER_INHERIT | 
 
1300
                        SEC_ACE_FLAG_OBJECT_INHERIT,
 
1301
                },
 
1302
                {
 
1303
                        SEC_ACE_FLAG_INHERIT_ONLY | 
 
1304
                        SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
 
1305
                        0,
 
1306
                        0,
 
1307
                },
 
1308
                {
 
1309
                        SEC_ACE_FLAG_INHERIT_ONLY | 
 
1310
                        SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
 
1311
                        SEC_ACE_FLAG_OBJECT_INHERIT,
 
1312
                        0,
 
1313
                        0,
 
1314
                },
 
1315
                {
 
1316
                        SEC_ACE_FLAG_INHERIT_ONLY | 
 
1317
                        SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
 
1318
                        SEC_ACE_FLAG_CONTAINER_INHERIT,
 
1319
                        0,
 
1320
                        0,
 
1321
                },
 
1322
                {
 
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,
 
1327
                        0,
 
1328
                        0,
 
1329
                }
 
1330
        };
 
1331
 
 
1332
        smbcli_rmdir(cli->tree, dname);
 
1333
 
 
1334
        printf("TESTING ACL INHERITANCE\n");
 
1335
 
 
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;
 
1348
 
 
1349
        status = smb_raw_open(cli->tree, tctx, &io);
 
1350
        CHECK_STATUS(status, NT_STATUS_OK);
 
1351
        fnum = io.ntcreatex.out.file.fnum;
 
1352
 
 
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;
 
1360
 
 
1361
        owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
 
1362
 
 
1363
        printf("owner_sid is %s\n", owner_sid);
 
1364
 
 
1365
        sd_def = security_descriptor_dacl_create(tctx,
 
1366
                                            0, owner_sid, NULL,
 
1367
                                            owner_sid,
 
1368
                                            SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1369
                                            SEC_RIGHTS_FILE_ALL,
 
1370
                                            0,
 
1371
                                            SID_NT_SYSTEM,
 
1372
                                            SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1373
                                            SEC_RIGHTS_FILE_ALL,
 
1374
                                            0,
 
1375
                                            NULL);
 
1376
 
 
1377
        creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER);
 
1378
 
 
1379
        for (i=0;i<ARRAY_SIZE(test_flags);i++) {
 
1380
                sd = security_descriptor_dacl_create(tctx,
 
1381
                                                0, NULL, NULL,
 
1382
                                                SID_CREATOR_OWNER,
 
1383
                                                SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1384
                                                SEC_FILE_WRITE_DATA,
 
1385
                                                test_flags[i].parent_flags,
 
1386
                                                SID_WORLD,
 
1387
                                                SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1388
                                                SEC_FILE_ALL | SEC_STD_ALL,
 
1389
                                                0,
 
1390
                                                NULL);
 
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);
 
1397
 
 
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;
 
1403
 
 
1404
                q.query_secdesc.in.file.fnum = fnum2;
 
1405
                status = smb_raw_fileinfo(cli->tree, tctx, &q);
 
1406
                CHECK_STATUS(status, NT_STATUS_OK);
 
1407
 
 
1408
                smbcli_close(cli->tree, fnum2);
 
1409
                smbcli_unlink(cli->tree, fname1);
 
1410
 
 
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);
 
1417
                        }
 
1418
                        goto check_dir;
 
1419
                }
 
1420
 
 
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);
 
1428
                        ret = false;
 
1429
                        goto check_dir;
 
1430
                }
 
1431
 
 
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,
 
1438
                               i);
 
1439
                        ret = false;
 
1440
                }
 
1441
 
 
1442
        check_dir:
 
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;
 
1448
 
 
1449
                q.query_secdesc.in.file.fnum = fnum2;
 
1450
                status = smb_raw_fileinfo(cli->tree, tctx, &q);
 
1451
                CHECK_STATUS(status, NT_STATUS_OK);
 
1452
 
 
1453
                smbcli_close(cli->tree, fnum2);
 
1454
                smbcli_rmdir(cli->tree, fname2);
 
1455
 
 
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);
 
1462
                                printf("got:\n");
 
1463
                                NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
 
1464
                        }
 
1465
                        continue;
 
1466
                }
 
1467
 
 
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);
 
1479
                                ret = false;
 
1480
                                continue;
 
1481
                        }
 
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,
 
1490
                                           creator_owner) ||
 
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);
 
1497
                                ret = false;
 
1498
                                continue;
 
1499
                        }
 
1500
                } else {
 
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,
 
1505
                                           creator_owner) ||
 
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);
 
1510
                                ret = false;
 
1511
                                continue;
 
1512
                        }
 
1513
                }
 
1514
        }
 
1515
 
 
1516
        printf("testing access checks on inherited create with %s\n", fname1);
 
1517
        sd = security_descriptor_dacl_create(tctx,
 
1518
                                        0, NULL, NULL,
 
1519
                                        owner_sid,
 
1520
                                        SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1521
                                        SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
 
1522
                                        SEC_ACE_FLAG_OBJECT_INHERIT,
 
1523
                                        SID_WORLD,
 
1524
                                        SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1525
                                        SEC_FILE_ALL | SEC_STD_ALL,
 
1526
                                        0,
 
1527
                                        NULL);
 
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);
 
1534
 
 
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);
 
1543
 
 
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);
 
1549
 
 
1550
        sd2 = security_descriptor_dacl_create(tctx,
 
1551
                                         0, owner_sid, NULL,
 
1552
                                         owner_sid,
 
1553
                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1554
                                         SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
 
1555
                                         0,
 
1556
                                         NULL);
 
1557
        if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
 
1558
                printf("%s: security descriptors don't match!\n", __location__);
 
1559
                printf("got:\n");
 
1560
                NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
 
1561
                printf("expected:\n");
 
1562
                NDR_PRINT_DEBUG(security_descriptor, sd2);
 
1563
                ret = false;
 
1564
        }
 
1565
 
 
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");
 
1571
                ret = false;
 
1572
                fnum2 = io.ntcreatex.out.file.fnum;
 
1573
                CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
 
1574
                smbcli_close(cli->tree, fnum2);
 
1575
        } else {
 
1576
                CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
 
1577
        }
 
1578
 
 
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);
 
1584
 
 
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);
 
1590
 
 
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);
 
1597
 
 
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);
 
1605
 
 
1606
        smbcli_close(cli->tree, fnum);
 
1607
 
 
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);
 
1611
 
 
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);
 
1618
 
 
1619
        smbcli_unlink(cli->tree, fname1);
 
1620
        smbcli_rmdir(cli->tree, dname);
 
1621
 
 
1622
done:
 
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);
 
1628
 
 
1629
        smbcli_close(cli->tree, fnum);
 
1630
        return ret;
 
1631
}
 
1632
 
 
1633
 
 
1634
/*
 
1635
  test dynamic acl inheritance
 
1636
*/
 
1637
static bool test_inheritance_dynamic(struct torture_context *tctx, 
 
1638
                                                                         struct smbcli_state *cli)
 
1639
{
 
1640
        NTSTATUS status;
 
1641
        union smb_open io;
 
1642
        const char *dname = BASEDIR "\\inheritance";
 
1643
        const char *fname1 = BASEDIR "\\inheritance\\testfile";
 
1644
        bool ret = true;
 
1645
        int fnum=0, fnum2;
 
1646
        union smb_fileinfo q;
 
1647
        union smb_setfileinfo set;
 
1648
        struct security_descriptor *sd, *sd_orig=NULL;
 
1649
        const char *owner_sid;
 
1650
        
 
1651
        printf("TESTING DYNAMIC ACL INHERITANCE\n");
 
1652
 
 
1653
        if (!torture_setup_dir(cli, BASEDIR)) {
 
1654
                return false;
 
1655
        }
 
1656
 
 
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;
 
1669
 
 
1670
        status = smb_raw_open(cli->tree, tctx, &io);
 
1671
        CHECK_STATUS(status, NT_STATUS_OK);
 
1672
        fnum = io.ntcreatex.out.file.fnum;
 
1673
 
 
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;
 
1681
 
 
1682
        owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
 
1683
 
 
1684
        printf("owner_sid is %s\n", owner_sid);
 
1685
 
 
1686
        sd = security_descriptor_dacl_create(tctx,
 
1687
                                        0, NULL, NULL,
 
1688
                                        owner_sid,
 
1689
                                        SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1690
                                        SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
 
1691
                                        SEC_ACE_FLAG_OBJECT_INHERIT,
 
1692
                                        NULL);
 
1693
        sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
 
1694
 
 
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);
 
1701
 
 
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);
 
1711
 
 
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);
 
1719
 
 
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);
 
1724
 
 
1725
        printf("update parent sd\n");
 
1726
        sd = security_descriptor_dacl_create(tctx,
 
1727
                                        0, NULL, NULL,
 
1728
                                        owner_sid,
 
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,
 
1732
                                        NULL);
 
1733
        sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
 
1734
 
 
1735
        set.set_secdesc.in.sd = sd;
 
1736
        status = smb_raw_setfileinfo(cli->tree, &set);
 
1737
        CHECK_STATUS(status, NT_STATUS_OK);
 
1738
 
 
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);
 
1745
 
 
1746
 
 
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");
 
1752
        }
 
1753
        if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
 
1754
                printf("Server does have dynamic inheritance\n");
 
1755
        }
 
1756
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
 
1757
 
 
1758
        smbcli_unlink(cli->tree, fname1);
 
1759
 
 
1760
done:
 
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);
 
1767
 
 
1768
        smbcli_close(cli->tree, fnum);
 
1769
        smbcli_rmdir(cli->tree, dname);
 
1770
 
 
1771
        return ret;
 
1772
}
 
1773
 
 
1774
#define CHECK_STATUS_FOR_BIT_ACTION(status, bits, action) do { \
 
1775
        if (!(bits & desired_64)) {\
 
1776
                CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); \
 
1777
                action; \
 
1778
        } else { \
 
1779
                CHECK_STATUS(status, NT_STATUS_OK); \
 
1780
        } \
 
1781
} while (0)
 
1782
 
 
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); \
 
1788
                        ret = false; \
 
1789
                        goto done; \
 
1790
                } \
 
1791
        } else { \
 
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); \
 
1795
                        ret = false; \
 
1796
                        goto done; \
 
1797
                } \
 
1798
        } \
 
1799
        CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \
 
1800
} while (0)
 
1801
 
 
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)
 
1805
{
 
1806
        NTSTATUS status;
 
1807
        bool ret = true;
 
1808
        union smb_open io;
 
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;
 
1816
        int fnum=0;
 
1817
        const char *fname = BASEDIR "\\sd_get_set.txt";
 
1818
        uint64_t desired_64;
 
1819
        uint32_t desired = 0, granted;
 
1820
        int i = 0;
 
1821
#define NO_BITS_HACK (((uint64_t)1)<<32)
 
1822
        uint64_t open_bits =
 
1823
                SEC_MASK_GENERIC |
 
1824
                SEC_FLAG_SYSTEM_SECURITY |
 
1825
                SEC_FLAG_MAXIMUM_ALLOWED |
 
1826
                SEC_STD_ALL |
 
1827
                SEC_FILE_ALL | 
 
1828
                NO_BITS_HACK;
 
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;
 
1837
 
 
1838
        printf("TESTING ACCESS MASKS FOR SD GET/SET\n");
 
1839
 
 
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,
 
1843
                                        SID_WORLD,
 
1844
                                        SEC_ACE_TYPE_ACCESS_ALLOWED,
 
1845
                                        SEC_GENERIC_ALL,
 
1846
                                        0,
 
1847
                                        NULL);
 
1848
        sd->type |= SEC_DESC_SACL_PRESENT;
 
1849
        sd->sacl = NULL;
 
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;
 
1867
 
 
1868
        status = smbcli_close(cli->tree, fnum);
 
1869
        CHECK_STATUS(status, NT_STATUS_OK);
 
1870
 
 
1871
        /* 
 
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)
 
1875
         */
 
1876
        for (i=0; i <= 32; i++) {
 
1877
                desired_64 = ((uint64_t)1) << i;
 
1878
                desired = (uint32_t)desired_64;
 
1879
 
 
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;
 
1887
 
 
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;
 
1894
 
 
1895
                /* test the owner */
 
1896
                ZERO_STRUCT(fi);
 
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) {
 
1905
                        sd_owner = sd;
 
1906
                }
 
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);
 
1913
 
 
1914
                /* test the group */
 
1915
                ZERO_STRUCT(fi);
 
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) {
 
1924
                        sd_group = sd;
 
1925
                }
 
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);
 
1932
 
 
1933
                /* test the DACL */
 
1934
                ZERO_STRUCT(fi);
 
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) {
 
1943
                        sd_dacl = sd;
 
1944
                }
 
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);
 
1951
 
 
1952
                /* test the SACL */
 
1953
                ZERO_STRUCT(fi);
 
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) {
 
1962
                        sd_sacl = sd;
 
1963
                }
 
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);
 
1970
 
 
1971
                /* close the handle */
 
1972
                status = smbcli_close(cli->tree, fnum);
 
1973
                CHECK_STATUS(status, NT_STATUS_OK);
 
1974
next:
 
1975
                continue;
 
1976
        }
 
1977
 
 
1978
done:
 
1979
        smbcli_close(cli->tree, fnum);
 
1980
        smbcli_unlink(cli->tree, fname);
 
1981
 
 
1982
        return ret;
 
1983
}
 
1984
 
 
1985
 
 
1986
/* 
 
1987
   basic testing of security descriptor calls
 
1988
*/
 
1989
bool torture_raw_acls(struct torture_context *tctx, struct smbcli_state *cli)
 
1990
{
 
1991
        bool ret = true;
 
1992
 
 
1993
        if (!torture_setup_dir(cli, BASEDIR)) {
 
1994
                return false;
 
1995
        }
 
1996
 
 
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);
 
2006
 
 
2007
        smb_raw_exit(cli->session);
 
2008
        smbcli_deltree(cli->tree, BASEDIR);
 
2009
 
 
2010
        return ret;
 
2011
}