s4-smbtorture: Make test names lowercase and dot-separated.
[metze/samba/wip.git] / source4 / torture / raw / acls.c
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                 ret = false; \
37                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
38                        __location__, nt_errstr(status), nt_errstr(correct)); \
39                 goto done; \
40         }} while (0)
41
42 #define FAIL_UNLESS(__cond)                                     \
43         do {                                                    \
44                 if (__cond) {} else {                           \
45                         ret = false; \
46                         torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n", \
47                             __location__, #__cond); \
48                         goto done; \
49                 }                                               \
50         } while(0)
51
52 #define CHECK_SECURITY_DESCRIPTOR(_sd1, _sd2) do { \
53         if (!security_descriptor_equal(_sd1, _sd2)) { \
54                 torture_warning(tctx, "%s: security descriptors don't match!\n", __location__); \
55                 torture_warning(tctx, "got:\n"); \
56                 NDR_PRINT_DEBUG(security_descriptor, _sd1); \
57                 torture_warning(tctx, "expected:\n"); \
58                 NDR_PRINT_DEBUG(security_descriptor, _sd2); \
59                 ret = false; \
60         } \
61 } while (0)
62
63 /*
64  * Helper function to verify a security descriptor, by querying
65  * and comparing against the passed in sd.
66  * Copied to smb2_util_verify_sd() for SMB2.
67  */
68 static bool verify_sd(TALLOC_CTX *tctx, struct smbcli_state *cli,
69     int fnum, struct security_descriptor *sd)
70 {
71         NTSTATUS status;
72         bool ret = true;
73         union smb_fileinfo q = {};
74
75         if (sd) {
76                 q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
77                 q.query_secdesc.in.file.fnum = fnum;
78                 q.query_secdesc.in.secinfo_flags =
79                     SECINFO_OWNER |
80                     SECINFO_GROUP |
81                     SECINFO_DACL;
82                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
83                 CHECK_STATUS(status, NT_STATUS_OK);
84
85                 /* More work is needed if we're going to check this bit. */
86                 sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
87
88                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
89         }
90
91  done:
92         return ret;
93 }
94
95 /*
96  * Helper function to verify attributes, by querying
97  * and comparing against the passed attrib.
98  * Copied to smb2_util_verify_attrib() for SMB2.
99  */
100 static bool verify_attrib(TALLOC_CTX *tctx, struct smbcli_state *cli,
101     int fnum, uint32_t attrib)
102 {
103         NTSTATUS status;
104         bool ret = true;
105         union smb_fileinfo q2 = {};
106
107         if (attrib) {
108                 q2.standard.level = RAW_FILEINFO_STANDARD;
109                 q2.standard.in.file.fnum = fnum;
110                 status = smb_raw_fileinfo(cli->tree, tctx, &q2);
111                 CHECK_STATUS(status, NT_STATUS_OK);
112
113                 q2.standard.out.attrib &= ~FILE_ATTRIBUTE_ARCHIVE;
114
115                 if (q2.standard.out.attrib != attrib) {
116                         torture_warning(tctx, "%s: attributes don't match! "
117                             "got %x, expected %x\n", __location__,
118                             (uint32_t)q2.standard.out.attrib,
119                             (uint32_t)attrib);
120                         ret = false;
121                 }
122         }
123
124  done:
125         return ret;
126 }
127
128 /**
129  * Test setting and removing a DACL.
130  * Test copied to torture_smb2_setinfo() for SMB2.
131  */
132 static bool test_sd(struct torture_context *tctx, struct smbcli_state *cli)
133 {
134         NTSTATUS status;
135         union smb_open io;
136         const char *fname = BASEDIR "\\sd.txt";
137         bool ret = true;
138         int fnum = -1;
139         union smb_fileinfo q;
140         union smb_setfileinfo set;
141         struct security_ace ace;
142         struct security_descriptor *sd;
143         struct dom_sid *test_sid;
144
145         if (!torture_setup_dir(cli, BASEDIR))
146                 return false;
147
148         torture_comment(tctx, "TESTING SETFILEINFO EA_SET\n");
149
150         io.generic.level = RAW_OPEN_NTCREATEX;
151         io.ntcreatex.in.root_fid.fnum = 0;
152         io.ntcreatex.in.flags = 0;
153         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
154         io.ntcreatex.in.create_options = 0;
155         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
156         io.ntcreatex.in.share_access = 
157                 NTCREATEX_SHARE_ACCESS_READ | 
158                 NTCREATEX_SHARE_ACCESS_WRITE;
159         io.ntcreatex.in.alloc_size = 0;
160         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
161         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
162         io.ntcreatex.in.security_flags = 0;
163         io.ntcreatex.in.fname = fname;
164         status = smb_raw_open(cli->tree, tctx, &io);
165         CHECK_STATUS(status, NT_STATUS_OK);
166         fnum = io.ntcreatex.out.file.fnum;
167         
168         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
169         q.query_secdesc.in.file.fnum = fnum;
170         q.query_secdesc.in.secinfo_flags = 
171                 SECINFO_OWNER |
172                 SECINFO_GROUP |
173                 SECINFO_DACL;
174         status = smb_raw_fileinfo(cli->tree, tctx, &q);
175         CHECK_STATUS(status, NT_STATUS_OK);
176         sd = q.query_secdesc.out.sd;
177
178         torture_comment(tctx, "add a new ACE to the DACL\n");
179
180         test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
181
182         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
183         ace.flags = 0;
184         ace.access_mask = SEC_STD_ALL;
185         ace.trustee = *test_sid;
186
187         status = security_descriptor_dacl_add(sd, &ace);
188         CHECK_STATUS(status, NT_STATUS_OK);
189
190         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
191         set.set_secdesc.in.file.fnum = fnum;
192         set.set_secdesc.in.secinfo_flags = q.query_secdesc.in.secinfo_flags;
193         set.set_secdesc.in.sd = sd;
194
195         status = smb_raw_setfileinfo(cli->tree, &set);
196         CHECK_STATUS(status, NT_STATUS_OK);
197         FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
198
199         torture_comment(tctx, "remove it again\n");
200
201         status = security_descriptor_dacl_del(sd, test_sid);
202         CHECK_STATUS(status, NT_STATUS_OK);
203
204         status = smb_raw_setfileinfo(cli->tree, &set);
205         CHECK_STATUS(status, NT_STATUS_OK);
206         FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
207
208 done:
209         smbcli_close(cli->tree, fnum);
210         smb_raw_exit(cli->session);
211         smbcli_deltree(cli->tree, BASEDIR);
212
213         return ret;
214 }
215
216
217 /*
218   test using nttrans create to create a file with an initial acl set
219   Test copied to test_create_acl() for SMB2.
220 */
221 static bool test_nttrans_create_ext(struct torture_context *tctx,
222                                     struct smbcli_state *cli, bool test_dir)
223 {
224         NTSTATUS status;
225         union smb_open io;
226         const char *fname = BASEDIR "\\acl2.txt";
227         bool ret = true;
228         int fnum = -1;
229         union smb_fileinfo q = {};
230         struct security_ace ace;
231         struct security_descriptor *sd;
232         struct dom_sid *test_sid;
233         uint32_t attrib =
234             FILE_ATTRIBUTE_HIDDEN |
235             FILE_ATTRIBUTE_SYSTEM |
236             (test_dir ? FILE_ATTRIBUTE_DIRECTORY : 0);
237         NTSTATUS (*delete_func)(struct smbcli_tree *, const char *) =
238             test_dir ? smbcli_rmdir : smbcli_unlink;
239
240         if (!torture_setup_dir(cli, BASEDIR))
241                 return false;
242
243         io.generic.level = RAW_OPEN_NTTRANS_CREATE;
244         io.ntcreatex.in.root_fid.fnum = 0;
245         io.ntcreatex.in.flags = 0;
246         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
247         io.ntcreatex.in.create_options =
248             test_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
249         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
250         io.ntcreatex.in.share_access = 
251                 NTCREATEX_SHARE_ACCESS_READ | 
252                 NTCREATEX_SHARE_ACCESS_WRITE;
253         io.ntcreatex.in.alloc_size = 0;
254         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
255         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
256         io.ntcreatex.in.security_flags = 0;
257         io.ntcreatex.in.fname = fname;
258         io.ntcreatex.in.sec_desc = NULL;
259         io.ntcreatex.in.ea_list = NULL;
260
261         torture_comment(tctx, "basic create\n");
262
263         status = smb_raw_open(cli->tree, tctx, &io);
264         CHECK_STATUS(status, NT_STATUS_OK);
265         fnum = io.ntcreatex.out.file.fnum;
266
267         torture_comment(tctx, "querying ACL\n");
268
269         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
270         q.query_secdesc.in.file.fnum = fnum;
271         q.query_secdesc.in.secinfo_flags = 
272                 SECINFO_OWNER |
273                 SECINFO_GROUP |
274                 SECINFO_DACL;
275         status = smb_raw_fileinfo(cli->tree, tctx, &q);
276         CHECK_STATUS(status, NT_STATUS_OK);
277         sd = q.query_secdesc.out.sd;
278
279         status = smbcli_close(cli->tree, fnum);
280         CHECK_STATUS(status, NT_STATUS_OK);
281
282         status = delete_func(cli->tree, fname);
283         CHECK_STATUS(status, NT_STATUS_OK);
284
285         torture_comment(tctx, "adding a new ACE\n");
286         test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
287
288         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
289         ace.flags = 0;
290         ace.access_mask = SEC_STD_ALL;
291         ace.trustee = *test_sid;
292
293         status = security_descriptor_dacl_add(sd, &ace);
294         CHECK_STATUS(status, NT_STATUS_OK);
295         
296         torture_comment(tctx, "creating with an initial ACL\n");
297
298         io.ntcreatex.in.sec_desc = sd;
299         status = smb_raw_open(cli->tree, tctx, &io);
300         CHECK_STATUS(status, NT_STATUS_OK);
301         fnum = io.ntcreatex.out.file.fnum;
302         
303         FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
304
305         status = smbcli_close(cli->tree, fnum);
306         CHECK_STATUS(status, NT_STATUS_OK);
307         status = delete_func(cli->tree, fname);
308         CHECK_STATUS(status, NT_STATUS_OK);
309
310         torture_comment(tctx, "creating with attributes\n");
311
312         io.ntcreatex.in.sec_desc = NULL;
313         io.ntcreatex.in.file_attr = attrib;
314         status = smb_raw_open(cli->tree, tctx, &io);
315         CHECK_STATUS(status, NT_STATUS_OK);
316         fnum = io.ntcreatex.out.file.fnum;
317
318         FAIL_UNLESS(verify_attrib(tctx, cli, fnum, attrib));
319
320         status = smbcli_close(cli->tree, fnum);
321         CHECK_STATUS(status, NT_STATUS_OK);
322
323         status = delete_func(cli->tree, fname);
324         CHECK_STATUS(status, NT_STATUS_OK);
325
326         torture_comment(tctx, "creating with attributes and ACL\n");
327
328         io.ntcreatex.in.sec_desc = sd;
329         io.ntcreatex.in.file_attr = attrib;
330         status = smb_raw_open(cli->tree, tctx, &io);
331         CHECK_STATUS(status, NT_STATUS_OK);
332         fnum = io.ntcreatex.out.file.fnum;
333
334         FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
335         FAIL_UNLESS(verify_attrib(tctx, cli, fnum, attrib));
336
337         status = smbcli_close(cli->tree, fnum);
338         CHECK_STATUS(status, NT_STATUS_OK);
339         status = delete_func(cli->tree, fname);
340         CHECK_STATUS(status, NT_STATUS_OK);
341
342         torture_comment(tctx, "creating with attributes, ACL and owner\n");
343
344         sd = security_descriptor_dacl_create(tctx,
345                                         0, SID_WORLD, SID_BUILTIN_USERS,
346                                         SID_WORLD,
347                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
348                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
349                                         0,
350                                         NULL);
351
352         io.ntcreatex.in.sec_desc = sd;
353         io.ntcreatex.in.file_attr = attrib;
354         status = smb_raw_open(cli->tree, tctx, &io);
355         CHECK_STATUS(status, NT_STATUS_OK);
356         fnum = io.ntcreatex.out.file.fnum;
357
358         FAIL_UNLESS(verify_sd(tctx, cli, fnum, sd));
359         FAIL_UNLESS(verify_attrib(tctx, cli, fnum, attrib));
360
361         status = smbcli_close(cli->tree, fnum);
362         CHECK_STATUS(status, NT_STATUS_OK);
363         status = delete_func(cli->tree, fname);
364         CHECK_STATUS(status, NT_STATUS_OK);
365
366  done:
367         smbcli_close(cli->tree, fnum);
368         smb_raw_exit(cli->session);
369         smbcli_deltree(cli->tree, BASEDIR);
370         return ret;
371 }
372
373 static bool test_nttrans_create_file(struct torture_context *tctx,
374     struct smbcli_state *cli)
375 {
376         torture_comment(tctx, "Testing nttrans create with sec_desc on files\n");
377
378         return test_nttrans_create_ext(tctx, cli, false);
379 }
380
381 static bool test_nttrans_create_dir(struct torture_context *tctx,
382     struct smbcli_state *cli)
383 {
384         torture_comment(tctx, "Testing nttrans create with sec_desc on directories\n");
385
386         return test_nttrans_create_ext(tctx, cli, true);
387 }
388
389 #define CHECK_ACCESS_FLAGS(_fnum, flags) do { \
390         union smb_fileinfo _q; \
391         _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
392         _q.access_information.in.file.fnum = (_fnum); \
393         status = smb_raw_fileinfo(cli->tree, tctx, &_q); \
394         CHECK_STATUS(status, NT_STATUS_OK); \
395         if (_q.access_information.out.access_flags != (flags)) { \
396                 ret = false; \
397                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
398                        __location__, _q.access_information.out.access_flags, (flags)); \
399                 goto done; \
400         } \
401 } while (0)
402
403 /*
404   test using NTTRANS CREATE to create a file with a null ACL set
405   Test copied to test_create_null_dacl() for SMB2.
406 */
407 static bool test_nttrans_create_null_dacl(struct torture_context *tctx,
408                                           struct smbcli_state *cli)
409 {
410         NTSTATUS status;
411         union smb_open io;
412         const char *fname = BASEDIR "\\nulldacl.txt";
413         bool ret = true;
414         int fnum = -1;
415         union smb_fileinfo q;
416         union smb_setfileinfo s;
417         struct security_descriptor *sd = security_descriptor_initialise(tctx);
418         struct security_acl dacl;
419
420         if (!torture_setup_dir(cli, BASEDIR))
421                 return false;
422
423         torture_comment(tctx, "TESTING SEC_DESC WITH A NULL DACL\n");
424
425         io.generic.level = RAW_OPEN_NTTRANS_CREATE;
426         io.ntcreatex.in.root_fid.fnum = 0;
427         io.ntcreatex.in.flags = 0;
428         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC
429                 | SEC_STD_WRITE_OWNER;
430         io.ntcreatex.in.create_options = 0;
431         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
432         io.ntcreatex.in.share_access =
433                 NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
434         io.ntcreatex.in.alloc_size = 0;
435         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
436         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
437         io.ntcreatex.in.security_flags = 0;
438         io.ntcreatex.in.fname = fname;
439         io.ntcreatex.in.sec_desc = sd;
440         io.ntcreatex.in.ea_list = NULL;
441
442         torture_comment(tctx, "creating a file with a empty sd\n");
443         status = smb_raw_open(cli->tree, tctx, &io);
444         CHECK_STATUS(status, NT_STATUS_OK);
445         fnum = io.ntcreatex.out.file.fnum;
446
447         torture_comment(tctx, "get the original sd\n");
448         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
449         q.query_secdesc.in.file.fnum = fnum;
450         q.query_secdesc.in.secinfo_flags =
451                 SECINFO_OWNER |
452                 SECINFO_GROUP |
453                 SECINFO_DACL;
454         status = smb_raw_fileinfo(cli->tree, tctx, &q);
455         CHECK_STATUS(status, NT_STATUS_OK);
456
457         /*
458          * Testing the created DACL,
459          * the server should add the inherited DACL
460          * when SEC_DESC_DACL_PRESENT isn't specified
461          */
462         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
463                 ret = false;
464                 torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
465                 goto done;
466         }
467         if (q.query_secdesc.out.sd->dacl == NULL) {
468                 ret = false;
469                 torture_result(tctx, TORTURE_FAIL, "no DACL has been created on the server!\n");
470                 goto done;
471         }
472
473         torture_comment(tctx, "set NULL DACL\n");
474         sd->type |= SEC_DESC_DACL_PRESENT;
475
476         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
477         s.set_secdesc.in.file.fnum = fnum;
478         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
479         s.set_secdesc.in.sd = sd;
480         status = smb_raw_setfileinfo(cli->tree, &s);
481         CHECK_STATUS(status, NT_STATUS_OK);
482
483         torture_comment(tctx, "get the sd\n");
484         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
485         q.query_secdesc.in.file.fnum = fnum;
486         q.query_secdesc.in.secinfo_flags =
487                 SECINFO_OWNER |
488                 SECINFO_GROUP |
489                 SECINFO_DACL;
490         status = smb_raw_fileinfo(cli->tree, tctx, &q);
491         CHECK_STATUS(status, NT_STATUS_OK);
492
493         /* Testing the modified DACL */
494         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
495                 ret = false;
496                 torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
497                 goto done;
498         }
499         if (q.query_secdesc.out.sd->dacl != NULL) {
500                 ret = false;
501                 torture_result(tctx, TORTURE_FAIL, "DACL has been created on the server!\n");
502                 goto done;
503         }
504
505         torture_comment(tctx, "try open for read control\n");
506         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL;
507         status = smb_raw_open(cli->tree, tctx, &io);
508         CHECK_STATUS(status, NT_STATUS_OK);
509         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
510                 SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE);
511         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
512
513         torture_comment(tctx, "try open for write\n");
514         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
515         status = smb_raw_open(cli->tree, tctx, &io);
516         CHECK_STATUS(status, NT_STATUS_OK);
517         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
518                 SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
519         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
520
521         torture_comment(tctx, "try open for read\n");
522         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
523         status = smb_raw_open(cli->tree, tctx, &io);
524         CHECK_STATUS(status, NT_STATUS_OK);
525         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
526                 SEC_FILE_READ_DATA | SEC_FILE_READ_ATTRIBUTE);
527         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
528
529         torture_comment(tctx, "try open for generic write\n");
530         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
531         status = smb_raw_open(cli->tree, tctx, &io);
532         CHECK_STATUS(status, NT_STATUS_OK);
533         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
534                 SEC_RIGHTS_FILE_WRITE | SEC_FILE_READ_ATTRIBUTE);
535         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
536
537         torture_comment(tctx, "try open for generic read\n");
538         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
539         status = smb_raw_open(cli->tree, tctx, &io);
540         CHECK_STATUS(status, NT_STATUS_OK);
541         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
542                 SEC_RIGHTS_FILE_READ | SEC_FILE_READ_ATTRIBUTE);
543         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
544
545         torture_comment(tctx, "set DACL with 0 aces\n");
546         ZERO_STRUCT(dacl);
547         dacl.revision = SECURITY_ACL_REVISION_NT4;
548         dacl.num_aces = 0;
549         sd->dacl = &dacl;
550
551         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
552         s.set_secdesc.in.file.fnum = fnum;
553         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
554         s.set_secdesc.in.sd = sd;
555         status = smb_raw_setfileinfo(cli->tree, &s);
556         CHECK_STATUS(status, NT_STATUS_OK);
557
558         torture_comment(tctx, "get the sd\n");
559         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
560         q.query_secdesc.in.file.fnum = fnum;
561         q.query_secdesc.in.secinfo_flags =
562                 SECINFO_OWNER |
563                 SECINFO_GROUP |
564                 SECINFO_DACL;
565         status = smb_raw_fileinfo(cli->tree, tctx, &q);
566         CHECK_STATUS(status, NT_STATUS_OK);
567
568         /* Testing the modified DACL */
569         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
570                 ret = false;
571                 torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
572                 goto done;
573         }
574         if (q.query_secdesc.out.sd->dacl == NULL) {
575                 ret = false;
576                 torture_result(tctx, TORTURE_FAIL, "no DACL has been created on the server!\n");
577                 goto done;
578         }
579         if (q.query_secdesc.out.sd->dacl->num_aces != 0) {
580                 ret = false;
581                 torture_result(tctx, TORTURE_FAIL, "DACL has %u aces!\n",
582                        q.query_secdesc.out.sd->dacl->num_aces);
583                 goto done;
584         }
585
586         torture_comment(tctx, "try open for read control\n");
587         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL;
588         status = smb_raw_open(cli->tree, tctx, &io);
589         CHECK_STATUS(status, NT_STATUS_OK);
590         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
591                 SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE);
592         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
593
594         torture_comment(tctx, "try open for write => access_denied\n");
595         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
596         status = smb_raw_open(cli->tree, tctx, &io);
597         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
598
599         torture_comment(tctx, "try open for read => access_denied\n");
600         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
601         status = smb_raw_open(cli->tree, tctx, &io);
602         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
603
604         torture_comment(tctx, "try open for generic write => access_denied\n");
605         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
606         status = smb_raw_open(cli->tree, tctx, &io);
607         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
608
609         torture_comment(tctx, "try open for generic read => access_denied\n");
610         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
611         status = smb_raw_open(cli->tree, tctx, &io);
612         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
613
614         torture_comment(tctx, "set empty sd\n");
615         sd->type &= ~SEC_DESC_DACL_PRESENT;
616         sd->dacl = NULL;
617
618         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
619         s.set_secdesc.in.file.fnum = fnum;
620         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
621         s.set_secdesc.in.sd = sd;
622         status = smb_raw_setfileinfo(cli->tree, &s);
623         CHECK_STATUS(status, NT_STATUS_OK);
624
625         torture_comment(tctx, "get the sd\n");
626         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
627         q.query_secdesc.in.file.fnum = fnum;
628         q.query_secdesc.in.secinfo_flags =
629                 SECINFO_OWNER |
630                 SECINFO_GROUP |
631                 SECINFO_DACL;
632         status = smb_raw_fileinfo(cli->tree, tctx, &q);
633         CHECK_STATUS(status, NT_STATUS_OK);
634
635         /* Testing the modified DACL */
636         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
637                 ret = false;
638                 torture_result(tctx, TORTURE_FAIL, "DACL_PRESENT flag not set by the server!\n");
639                 goto done;
640         }
641         if (q.query_secdesc.out.sd->dacl != NULL) {
642                 ret = false;
643                 torture_result(tctx, TORTURE_FAIL, "DACL has been created on the server!\n");
644                 goto done;
645         }
646 done:
647         smbcli_close(cli->tree, fnum);
648         smb_raw_exit(cli->session);
649         smbcli_deltree(cli->tree, BASEDIR);
650         return ret;
651 }
652
653 /*
654   test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
655   mapping bits
656   Test copied to smb2/acls.c for SMB2.
657 */
658 static bool test_creator_sid(struct torture_context *tctx, 
659                                                          struct smbcli_state *cli)
660 {
661         NTSTATUS status;
662         union smb_open io;
663         const char *fname = BASEDIR "\\creator.txt";
664         bool ret = true;
665         int fnum = -1;
666         union smb_fileinfo q;
667         union smb_setfileinfo set;
668         struct security_descriptor *sd, *sd_orig, *sd2;
669         const char *owner_sid;
670
671         if (!torture_setup_dir(cli, BASEDIR))
672                 return false;
673
674         torture_comment(tctx, "TESTING SID_CREATOR_OWNER\n");
675
676         io.generic.level = RAW_OPEN_NTCREATEX;
677         io.ntcreatex.in.root_fid.fnum = 0;
678         io.ntcreatex.in.flags = 0;
679         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
680         io.ntcreatex.in.create_options = 0;
681         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
682         io.ntcreatex.in.share_access = 
683                 NTCREATEX_SHARE_ACCESS_READ | 
684                 NTCREATEX_SHARE_ACCESS_WRITE;
685         io.ntcreatex.in.alloc_size = 0;
686         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
687         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
688         io.ntcreatex.in.security_flags = 0;
689         io.ntcreatex.in.fname = fname;
690         status = smb_raw_open(cli->tree, tctx, &io);
691         CHECK_STATUS(status, NT_STATUS_OK);
692         fnum = io.ntcreatex.out.file.fnum;
693
694         torture_comment(tctx, "get the original sd\n");
695         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
696         q.query_secdesc.in.file.fnum = fnum;
697         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
698         status = smb_raw_fileinfo(cli->tree, tctx, &q);
699         CHECK_STATUS(status, NT_STATUS_OK);
700         sd_orig = q.query_secdesc.out.sd;
701
702         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
703
704         torture_comment(tctx, "set a sec desc allowing no write by CREATOR_OWNER\n");
705         sd = security_descriptor_dacl_create(tctx,
706                                         0, NULL, NULL,
707                                         SID_CREATOR_OWNER,
708                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
709                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
710                                         0,
711                                         NULL);
712
713         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
714         set.set_secdesc.in.file.fnum = fnum;
715         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
716         set.set_secdesc.in.sd = sd;
717
718         status = smb_raw_setfileinfo(cli->tree, &set);
719         CHECK_STATUS(status, NT_STATUS_OK);
720
721         torture_comment(tctx, "try open for write\n");
722         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
723         status = smb_raw_open(cli->tree, tctx, &io);
724         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
725
726         torture_comment(tctx, "try open for read\n");
727         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
728         status = smb_raw_open(cli->tree, tctx, &io);
729         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
730
731         torture_comment(tctx, "try open for generic write\n");
732         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
733         status = smb_raw_open(cli->tree, tctx, &io);
734         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
735
736         torture_comment(tctx, "try open for generic read\n");
737         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
738         status = smb_raw_open(cli->tree, tctx, &io);
739         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
740
741         torture_comment(tctx, "set a sec desc allowing no write by owner\n");
742         sd = security_descriptor_dacl_create(tctx,
743                                         0, owner_sid, NULL,
744                                         owner_sid,
745                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
746                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
747                                         0,
748                                         NULL);
749
750         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
751         set.set_secdesc.in.file.fnum = fnum;
752         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
753         set.set_secdesc.in.sd = sd;
754         status = smb_raw_setfileinfo(cli->tree, &set);
755         CHECK_STATUS(status, NT_STATUS_OK);
756
757         torture_comment(tctx, "check that sd has been mapped correctly\n");
758         status = smb_raw_fileinfo(cli->tree, tctx, &q);
759         CHECK_STATUS(status, NT_STATUS_OK);
760         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
761
762         torture_comment(tctx, "try open for write\n");
763         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
764         status = smb_raw_open(cli->tree, tctx, &io);
765         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
766
767         torture_comment(tctx, "try open for read\n");
768         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
769         status = smb_raw_open(cli->tree, tctx, &io);
770         CHECK_STATUS(status, NT_STATUS_OK);
771         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
772                            SEC_FILE_READ_DATA|
773                            SEC_FILE_READ_ATTRIBUTE);
774         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
775
776         torture_comment(tctx, "try open for generic write\n");
777         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
778         status = smb_raw_open(cli->tree, tctx, &io);
779         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
780
781         torture_comment(tctx, "try open for generic read\n");
782         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
783         status = smb_raw_open(cli->tree, tctx, &io);
784         CHECK_STATUS(status, NT_STATUS_OK);
785         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
786                            SEC_RIGHTS_FILE_READ);
787         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
788
789         torture_comment(tctx, "set a sec desc allowing generic read by owner\n");
790         sd = security_descriptor_dacl_create(tctx,
791                                         0, NULL, NULL,
792                                         owner_sid,
793                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
794                                         SEC_GENERIC_READ | SEC_STD_ALL,
795                                         0,
796                                         NULL);
797
798         set.set_secdesc.in.sd = sd;
799         status = smb_raw_setfileinfo(cli->tree, &set);
800         CHECK_STATUS(status, NT_STATUS_OK);
801
802         torture_comment(tctx, "check that generic read has been mapped correctly\n");
803         sd2 = security_descriptor_dacl_create(tctx,
804                                          0, owner_sid, NULL,
805                                          owner_sid,
806                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
807                                          SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
808                                          0,
809                                          NULL);
810
811         status = smb_raw_fileinfo(cli->tree, tctx, &q);
812         CHECK_STATUS(status, NT_STATUS_OK);
813         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
814
815         torture_comment(tctx, "try open for write\n");
816         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
817         status = smb_raw_open(cli->tree, tctx, &io);
818         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
819
820         torture_comment(tctx, "try open for read\n");
821         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
822         status = smb_raw_open(cli->tree, tctx, &io);
823         CHECK_STATUS(status, NT_STATUS_OK);
824         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
825                            SEC_FILE_READ_DATA | 
826                            SEC_FILE_READ_ATTRIBUTE);
827         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
828
829         torture_comment(tctx, "try open for generic write\n");
830         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
831         status = smb_raw_open(cli->tree, tctx, &io);
832         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
833
834         torture_comment(tctx, "try open for generic read\n");
835         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
836         status = smb_raw_open(cli->tree, tctx, &io);
837         CHECK_STATUS(status, NT_STATUS_OK);
838         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, SEC_RIGHTS_FILE_READ);
839         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
840
841
842         torture_comment(tctx, "put back original sd\n");
843         set.set_secdesc.in.sd = sd_orig;
844         status = smb_raw_setfileinfo(cli->tree, &set);
845         CHECK_STATUS(status, NT_STATUS_OK);
846
847
848 done:
849         smbcli_close(cli->tree, fnum);
850         smb_raw_exit(cli->session);
851         smbcli_deltree(cli->tree, BASEDIR);
852         return ret;
853 }
854
855
856 /*
857   test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
858   SEC_FILE_xx bits
859   Test copied to smb2/acls.c for SMB2.
860 */
861 static bool test_generic_bits(struct torture_context *tctx, 
862                                                           struct smbcli_state *cli)
863 {
864         NTSTATUS status;
865         union smb_open io;
866         const char *fname = BASEDIR "\\generic.txt";
867         bool ret = true;
868         int fnum = -1, i;
869         union smb_fileinfo q;
870         union smb_setfileinfo set;
871         struct security_descriptor *sd, *sd_orig, *sd2;
872         const char *owner_sid;
873         const struct {
874                 uint32_t gen_bits;
875                 uint32_t specific_bits;
876         } file_mappings[] = {
877                 { 0,                       0 },
878                 { SEC_GENERIC_READ,        SEC_RIGHTS_FILE_READ },
879                 { SEC_GENERIC_WRITE,       SEC_RIGHTS_FILE_WRITE },
880                 { SEC_GENERIC_EXECUTE,     SEC_RIGHTS_FILE_EXECUTE },
881                 { SEC_GENERIC_ALL,         SEC_RIGHTS_FILE_ALL },
882                 { SEC_FILE_READ_DATA,      SEC_FILE_READ_DATA },
883                 { SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_ATTRIBUTE }
884         };
885         const struct {
886                 uint32_t gen_bits;
887                 uint32_t specific_bits;
888         } dir_mappings[] = {
889                 { 0,                   0 },
890                 { SEC_GENERIC_READ,    SEC_RIGHTS_DIR_READ },
891                 { SEC_GENERIC_WRITE,   SEC_RIGHTS_DIR_WRITE },
892                 { SEC_GENERIC_EXECUTE, SEC_RIGHTS_DIR_EXECUTE },
893                 { SEC_GENERIC_ALL,     SEC_RIGHTS_DIR_ALL }
894         };
895         bool has_restore_privilege;
896         bool has_take_ownership_privilege;
897
898         if (!torture_setup_dir(cli, BASEDIR))
899                 return false;
900
901         torture_comment(tctx, "TESTING FILE GENERIC BITS\n");
902
903         io.generic.level = RAW_OPEN_NTCREATEX;
904         io.ntcreatex.in.root_fid.fnum = 0;
905         io.ntcreatex.in.flags = 0;
906         io.ntcreatex.in.access_mask = 
907                 SEC_STD_READ_CONTROL | 
908                 SEC_STD_WRITE_DAC | 
909                 SEC_STD_WRITE_OWNER;
910         io.ntcreatex.in.create_options = 0;
911         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
912         io.ntcreatex.in.share_access = 
913                 NTCREATEX_SHARE_ACCESS_READ | 
914                 NTCREATEX_SHARE_ACCESS_WRITE;
915         io.ntcreatex.in.alloc_size = 0;
916         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
917         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
918         io.ntcreatex.in.security_flags = 0;
919         io.ntcreatex.in.fname = fname;
920         status = smb_raw_open(cli->tree, tctx, &io);
921         CHECK_STATUS(status, NT_STATUS_OK);
922         fnum = io.ntcreatex.out.file.fnum;
923
924         torture_comment(tctx, "get the original sd\n");
925         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
926         q.query_secdesc.in.file.fnum = fnum;
927         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
928         status = smb_raw_fileinfo(cli->tree, tctx, &q);
929         CHECK_STATUS(status, NT_STATUS_OK);
930         sd_orig = q.query_secdesc.out.sd;
931
932         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
933
934         status = torture_check_privilege(cli, 
935                                             owner_sid, 
936                                             sec_privilege_name(SEC_PRIV_RESTORE));
937         has_restore_privilege = NT_STATUS_IS_OK(status);
938         if (!NT_STATUS_IS_OK(status)) {
939                 torture_warning(tctx, "torture_check_privilege - %s\n",
940                     nt_errstr(status));
941         }
942         torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
943
944         status = torture_check_privilege(cli, 
945                                             owner_sid, 
946                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
947         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
948         if (!NT_STATUS_IS_OK(status)) {
949                 torture_warning(tctx, "torture_check_privilege - %s\n",
950                     nt_errstr(status));
951         }
952         torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
953
954         for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
955                 uint32_t expected_mask = 
956                         SEC_STD_WRITE_DAC | 
957                         SEC_STD_READ_CONTROL | 
958                         SEC_FILE_READ_ATTRIBUTE |
959                         SEC_STD_DELETE;
960                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
961
962                 if (has_restore_privilege) {
963                         expected_mask_anon |= SEC_STD_DELETE;
964                 }
965
966                 torture_comment(tctx, "Testing generic bits 0x%08x\n",
967                        file_mappings[i].gen_bits);
968                 sd = security_descriptor_dacl_create(tctx,
969                                                 0, owner_sid, NULL,
970                                                 owner_sid,
971                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
972                                                 file_mappings[i].gen_bits,
973                                                 0,
974                                                 NULL);
975
976                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
977                 set.set_secdesc.in.file.fnum = fnum;
978                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
979                 set.set_secdesc.in.sd = sd;
980
981                 status = smb_raw_setfileinfo(cli->tree, &set);
982                 CHECK_STATUS(status, NT_STATUS_OK);
983
984                 sd2 = security_descriptor_dacl_create(tctx,
985                                                  0, owner_sid, NULL,
986                                                  owner_sid,
987                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
988                                                  file_mappings[i].specific_bits,
989                                                  0,
990                                                  NULL);
991
992                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
993                 CHECK_STATUS(status, NT_STATUS_OK);
994                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
995
996                 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
997                 status = smb_raw_open(cli->tree, tctx, &io);
998                 CHECK_STATUS(status, NT_STATUS_OK);
999                 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
1000                                    expected_mask | file_mappings[i].specific_bits);
1001                 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1002
1003                 if (!has_take_ownership_privilege) {
1004                         continue;
1005                 }
1006
1007                 torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
1008                        file_mappings[i].gen_bits);
1009                 sd = security_descriptor_dacl_create(tctx,
1010                                                 0, SID_NT_ANONYMOUS, NULL,
1011                                                 owner_sid,
1012                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1013                                                 file_mappings[i].gen_bits,
1014                                                 0,
1015                                                 NULL);
1016
1017                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1018                 set.set_secdesc.in.file.fnum = fnum;
1019                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1020                 set.set_secdesc.in.sd = sd;
1021
1022                 status = smb_raw_setfileinfo(cli->tree, &set);
1023                 CHECK_STATUS(status, NT_STATUS_OK);
1024
1025                 sd2 = security_descriptor_dacl_create(tctx,
1026                                                  0, SID_NT_ANONYMOUS, NULL,
1027                                                  owner_sid,
1028                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
1029                                                  file_mappings[i].specific_bits,
1030                                                  0,
1031                                                  NULL);
1032
1033                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1034                 CHECK_STATUS(status, NT_STATUS_OK);
1035                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1036
1037                 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1038                 status = smb_raw_open(cli->tree, tctx, &io);
1039                 CHECK_STATUS(status, NT_STATUS_OK);
1040                 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
1041                                    expected_mask_anon | file_mappings[i].specific_bits);
1042                 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1043         }
1044
1045         torture_comment(tctx, "put back original sd\n");
1046         set.set_secdesc.in.sd = sd_orig;
1047         status = smb_raw_setfileinfo(cli->tree, &set);
1048         CHECK_STATUS(status, NT_STATUS_OK);
1049
1050         smbcli_close(cli->tree, fnum);
1051         smbcli_unlink(cli->tree, fname);
1052
1053
1054         torture_comment(tctx, "TESTING DIR GENERIC BITS\n");
1055
1056         io.generic.level = RAW_OPEN_NTCREATEX;
1057         io.ntcreatex.in.root_fid.fnum = 0;
1058         io.ntcreatex.in.flags = 0;
1059         io.ntcreatex.in.access_mask = 
1060                 SEC_STD_READ_CONTROL | 
1061                 SEC_STD_WRITE_DAC | 
1062                 SEC_STD_WRITE_OWNER;
1063         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1064         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1065         io.ntcreatex.in.share_access = 
1066                 NTCREATEX_SHARE_ACCESS_READ | 
1067                 NTCREATEX_SHARE_ACCESS_WRITE;
1068         io.ntcreatex.in.alloc_size = 0;
1069         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1070         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1071         io.ntcreatex.in.security_flags = 0;
1072         io.ntcreatex.in.fname = fname;
1073         status = smb_raw_open(cli->tree, tctx, &io);
1074         CHECK_STATUS(status, NT_STATUS_OK);
1075         fnum = io.ntcreatex.out.file.fnum;
1076
1077         torture_comment(tctx, "get the original sd\n");
1078         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1079         q.query_secdesc.in.file.fnum = fnum;
1080         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1081         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1082         CHECK_STATUS(status, NT_STATUS_OK);
1083         sd_orig = q.query_secdesc.out.sd;
1084
1085         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1086
1087         status = torture_check_privilege(cli, 
1088                                             owner_sid, 
1089                                             sec_privilege_name(SEC_PRIV_RESTORE));
1090         has_restore_privilege = NT_STATUS_IS_OK(status);
1091         if (!NT_STATUS_IS_OK(status)) {
1092                 torture_warning(tctx, "torture_check_privilege - %s\n",
1093                     nt_errstr(status));
1094         }
1095         torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
1096
1097         status = torture_check_privilege(cli, 
1098                                             owner_sid, 
1099                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
1100         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
1101         if (!NT_STATUS_IS_OK(status)) {
1102                 torture_warning(tctx, "torture_check_privilege - %s\n",
1103                     nt_errstr(status));
1104         }
1105         torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
1106
1107         for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
1108                 uint32_t expected_mask = 
1109                         SEC_STD_WRITE_DAC | 
1110                         SEC_STD_READ_CONTROL | 
1111                         SEC_FILE_READ_ATTRIBUTE |
1112                         SEC_STD_DELETE;
1113                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
1114
1115                 if (has_restore_privilege) {
1116                         expected_mask_anon |= SEC_STD_DELETE;
1117                 }
1118
1119                 torture_comment(tctx, "Testing generic bits 0x%08x\n",
1120                        file_mappings[i].gen_bits);
1121                 sd = security_descriptor_dacl_create(tctx,
1122                                                 0, owner_sid, NULL,
1123                                                 owner_sid,
1124                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1125                                                 dir_mappings[i].gen_bits,
1126                                                 0,
1127                                                 NULL);
1128
1129                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1130                 set.set_secdesc.in.file.fnum = fnum;
1131                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1132                 set.set_secdesc.in.sd = sd;
1133
1134                 status = smb_raw_setfileinfo(cli->tree, &set);
1135                 CHECK_STATUS(status, NT_STATUS_OK);
1136
1137                 sd2 = security_descriptor_dacl_create(tctx,
1138                                                  0, owner_sid, NULL,
1139                                                  owner_sid,
1140                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
1141                                                  dir_mappings[i].specific_bits,
1142                                                  0,
1143                                                  NULL);
1144
1145                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1146                 CHECK_STATUS(status, NT_STATUS_OK);
1147                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1148
1149                 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1150                 status = smb_raw_open(cli->tree, tctx, &io);
1151                 CHECK_STATUS(status, NT_STATUS_OK);
1152                 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
1153                                    expected_mask | dir_mappings[i].specific_bits);
1154                 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1155
1156                 if (!has_take_ownership_privilege) {
1157                         continue;
1158                 }
1159
1160                 torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
1161                        file_mappings[i].gen_bits);
1162                 sd = security_descriptor_dacl_create(tctx,
1163                                                 0, SID_NT_ANONYMOUS, NULL,
1164                                                 owner_sid,
1165                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1166                                                 file_mappings[i].gen_bits,
1167                                                 0,
1168                                                 NULL);
1169
1170                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1171                 set.set_secdesc.in.file.fnum = fnum;
1172                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1173                 set.set_secdesc.in.sd = sd;
1174
1175                 status = smb_raw_setfileinfo(cli->tree, &set);
1176                 CHECK_STATUS(status, NT_STATUS_OK);
1177
1178                 sd2 = security_descriptor_dacl_create(tctx,
1179                                                  0, SID_NT_ANONYMOUS, NULL,
1180                                                  owner_sid,
1181                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
1182                                                  file_mappings[i].specific_bits,
1183                                                  0,
1184                                                  NULL);
1185
1186                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1187                 CHECK_STATUS(status, NT_STATUS_OK);
1188                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1189
1190                 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1191                 status = smb_raw_open(cli->tree, tctx, &io);
1192                 CHECK_STATUS(status, NT_STATUS_OK);
1193                 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
1194                                    expected_mask_anon | dir_mappings[i].specific_bits);
1195                 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1196         }
1197
1198         torture_comment(tctx, "put back original sd\n");
1199         set.set_secdesc.in.sd = sd_orig;
1200         status = smb_raw_setfileinfo(cli->tree, &set);
1201         CHECK_STATUS(status, NT_STATUS_OK);
1202
1203         smbcli_close(cli->tree, fnum);
1204         smbcli_unlink(cli->tree, fname);
1205
1206 done:
1207         smbcli_close(cli->tree, fnum);
1208         smb_raw_exit(cli->session);
1209         smbcli_deltree(cli->tree, BASEDIR);
1210         return ret;
1211 }
1212
1213
1214 /*
1215   see what access bits the owner of a file always gets
1216   Test copied to smb2/acls.c for SMB2.
1217 */
1218 static bool test_owner_bits(struct torture_context *tctx, 
1219                                                         struct smbcli_state *cli)
1220 {
1221         NTSTATUS status;
1222         union smb_open io;
1223         const char *fname = BASEDIR "\\test_owner_bits.txt";
1224         bool ret = true;
1225         int fnum = -1, i;
1226         union smb_fileinfo q;
1227         union smb_setfileinfo set;
1228         struct security_descriptor *sd, *sd_orig;
1229         const char *owner_sid;
1230         bool has_restore_privilege;
1231         bool has_take_ownership_privilege;
1232         uint32_t expected_bits;
1233
1234         if (!torture_setup_dir(cli, BASEDIR))
1235                 return false;
1236
1237         torture_comment(tctx, "TESTING FILE OWNER BITS\n");
1238
1239         io.generic.level = RAW_OPEN_NTCREATEX;
1240         io.ntcreatex.in.root_fid.fnum = 0;
1241         io.ntcreatex.in.flags = 0;
1242         io.ntcreatex.in.access_mask = 
1243                 SEC_STD_READ_CONTROL | 
1244                 SEC_STD_WRITE_DAC | 
1245                 SEC_STD_WRITE_OWNER;
1246         io.ntcreatex.in.create_options = 0;
1247         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1248         io.ntcreatex.in.share_access = 
1249                 NTCREATEX_SHARE_ACCESS_READ | 
1250                 NTCREATEX_SHARE_ACCESS_WRITE;
1251         io.ntcreatex.in.alloc_size = 0;
1252         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1253         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1254         io.ntcreatex.in.security_flags = 0;
1255         io.ntcreatex.in.fname = fname;
1256         status = smb_raw_open(cli->tree, tctx, &io);
1257         CHECK_STATUS(status, NT_STATUS_OK);
1258         fnum = io.ntcreatex.out.file.fnum;
1259
1260         torture_comment(tctx, "get the original sd\n");
1261         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1262         q.query_secdesc.in.file.fnum = fnum;
1263         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1264         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1265         CHECK_STATUS(status, NT_STATUS_OK);
1266         sd_orig = q.query_secdesc.out.sd;
1267
1268         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1269
1270         status = torture_check_privilege(cli, 
1271                                             owner_sid, 
1272                                             sec_privilege_name(SEC_PRIV_RESTORE));
1273         has_restore_privilege = NT_STATUS_IS_OK(status);
1274         if (!NT_STATUS_IS_OK(status)) {
1275                 torture_warning(tctx, "torture_check_privilege - %s\n", nt_errstr(status));
1276         }
1277         torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
1278
1279         status = torture_check_privilege(cli, 
1280                                             owner_sid, 
1281                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
1282         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
1283         if (!NT_STATUS_IS_OK(status)) {
1284                 torture_warning(tctx, "torture_check_privilege - %s\n", nt_errstr(status));
1285         }
1286         torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
1287
1288         sd = security_descriptor_dacl_create(tctx,
1289                                         0, NULL, NULL,
1290                                         owner_sid,
1291                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1292                                         SEC_FILE_WRITE_DATA,
1293                                         0,
1294                                         NULL);
1295
1296         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1297         set.set_secdesc.in.file.fnum = fnum;
1298         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1299         set.set_secdesc.in.sd = sd;
1300
1301         status = smb_raw_setfileinfo(cli->tree, &set);
1302         CHECK_STATUS(status, NT_STATUS_OK);
1303
1304         expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
1305
1306         for (i=0;i<16;i++) {
1307                 uint32_t bit = (1<<i);
1308                 io.ntcreatex.in.access_mask = bit;
1309                 status = smb_raw_open(cli->tree, tctx, &io);
1310                 if (expected_bits & bit) {
1311                         if (!NT_STATUS_IS_OK(status)) {
1312                                 torture_warning(tctx, "failed with access mask 0x%08x of expected 0x%08x\n",
1313                                        bit, expected_bits);
1314                         }
1315                         CHECK_STATUS(status, NT_STATUS_OK);
1316                         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, bit | SEC_FILE_READ_ATTRIBUTE);
1317                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1318                 } else {
1319                         if (NT_STATUS_IS_OK(status)) {
1320                                 torture_warning(tctx, "open succeeded with access mask 0x%08x of "
1321                                         "expected 0x%08x - should fail\n",
1322                                        bit, expected_bits);
1323                         }
1324                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1325                 }
1326         }
1327
1328         torture_comment(tctx, "put back original sd\n");
1329         set.set_secdesc.in.sd = sd_orig;
1330         status = smb_raw_setfileinfo(cli->tree, &set);
1331         CHECK_STATUS(status, NT_STATUS_OK);
1332
1333 done:
1334         smbcli_close(cli->tree, fnum);
1335         smbcli_unlink(cli->tree, fname);
1336         smb_raw_exit(cli->session);
1337         smbcli_deltree(cli->tree, BASEDIR);
1338         return ret;
1339 }
1340
1341
1342
1343 /*
1344   test the inheritance of ACL flags onto new files and directories
1345   Test copied to smb2/acls.c for SMB2.
1346 */
1347 static bool test_inheritance(struct torture_context *tctx, 
1348                                                          struct smbcli_state *cli)
1349 {
1350         NTSTATUS status;
1351         union smb_open io;
1352         const char *dname = BASEDIR "\\inheritance";
1353         const char *fname1 = BASEDIR "\\inheritance\\testfile";
1354         const char *fname2 = BASEDIR "\\inheritance\\testdir";
1355         bool ret = true;
1356         int fnum=0, fnum2, i;
1357         union smb_fileinfo q;
1358         union smb_setfileinfo set;
1359         struct security_descriptor *sd, *sd2, *sd_orig=NULL, *sd_def1, *sd_def2;
1360         const char *owner_sid, *group_sid;
1361         const struct dom_sid *creator_owner;
1362         const struct {
1363                 uint32_t parent_flags;
1364                 uint32_t file_flags;
1365                 uint32_t dir_flags;
1366         } test_flags[] = {
1367                 {
1368                         0, 
1369                         0,
1370                         0
1371                 },
1372                 {
1373                         SEC_ACE_FLAG_OBJECT_INHERIT,
1374                         0,
1375                         SEC_ACE_FLAG_OBJECT_INHERIT | 
1376                         SEC_ACE_FLAG_INHERIT_ONLY,
1377                 },
1378                 {
1379                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1380                         0,
1381                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1382                 },
1383                 {
1384                         SEC_ACE_FLAG_OBJECT_INHERIT | 
1385                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1386                         0,
1387                         SEC_ACE_FLAG_OBJECT_INHERIT | 
1388                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1389                 },
1390                 {
1391                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
1392                         0,
1393                         0,
1394                 },
1395                 {
1396                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1397                         SEC_ACE_FLAG_OBJECT_INHERIT,
1398                         0,
1399                         0,
1400                 },
1401                 {
1402                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1403                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1404                         0,
1405                         0,
1406                 },
1407                 {
1408                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1409                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
1410                         SEC_ACE_FLAG_OBJECT_INHERIT,
1411                         0,
1412                         0,
1413                 },
1414                 {
1415                         SEC_ACE_FLAG_INHERIT_ONLY,
1416                         0,
1417                         0,
1418                 },
1419                 {
1420                         SEC_ACE_FLAG_INHERIT_ONLY | 
1421                         SEC_ACE_FLAG_OBJECT_INHERIT,
1422                         0,
1423                         SEC_ACE_FLAG_OBJECT_INHERIT | 
1424                         SEC_ACE_FLAG_INHERIT_ONLY,
1425                 },
1426                 {
1427                         SEC_ACE_FLAG_INHERIT_ONLY | 
1428                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1429                         0,
1430                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1431                 },
1432                 {
1433                         SEC_ACE_FLAG_INHERIT_ONLY | 
1434                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
1435                         SEC_ACE_FLAG_OBJECT_INHERIT,
1436                         0,
1437                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
1438                         SEC_ACE_FLAG_OBJECT_INHERIT,
1439                 },
1440                 {
1441                         SEC_ACE_FLAG_INHERIT_ONLY | 
1442                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
1443                         0,
1444                         0,
1445                 },
1446                 {
1447                         SEC_ACE_FLAG_INHERIT_ONLY | 
1448                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1449                         SEC_ACE_FLAG_OBJECT_INHERIT,
1450                         0,
1451                         0,
1452                 },
1453                 {
1454                         SEC_ACE_FLAG_INHERIT_ONLY | 
1455                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1456                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1457                         0,
1458                         0,
1459                 },
1460                 {
1461                         SEC_ACE_FLAG_INHERIT_ONLY | 
1462                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1463                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
1464                         SEC_ACE_FLAG_OBJECT_INHERIT,
1465                         0,
1466                         0,
1467                 }
1468         };
1469
1470         if (!torture_setup_dir(cli, BASEDIR))
1471                 return false;
1472
1473         torture_comment(tctx, "TESTING ACL INHERITANCE\n");
1474
1475         io.generic.level = RAW_OPEN_NTCREATEX;
1476         io.ntcreatex.in.root_fid.fnum = 0;
1477         io.ntcreatex.in.flags = 0;
1478         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1479         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1480         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1481         io.ntcreatex.in.share_access = 0;
1482         io.ntcreatex.in.alloc_size = 0;
1483         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1484         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1485         io.ntcreatex.in.security_flags = 0;
1486         io.ntcreatex.in.fname = dname;
1487
1488         status = smb_raw_open(cli->tree, tctx, &io);
1489         CHECK_STATUS(status, NT_STATUS_OK);
1490         fnum = io.ntcreatex.out.file.fnum;
1491
1492         torture_comment(tctx, "get the original sd\n");
1493         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1494         q.query_secdesc.in.file.fnum = fnum;
1495         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
1496         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1497         CHECK_STATUS(status, NT_STATUS_OK);
1498         sd_orig = q.query_secdesc.out.sd;
1499
1500         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1501         group_sid = dom_sid_string(tctx, sd_orig->group_sid);
1502
1503         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
1504         torture_comment(tctx, "group_sid is %s\n", group_sid);
1505
1506         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1507
1508         if (torture_setting_bool(tctx, "samba4", false)) {
1509                 /* the default ACL in Samba4 includes the group and
1510                    other permissions */
1511                 sd_def1 = security_descriptor_dacl_create(tctx,
1512                                                          0, owner_sid, NULL,
1513                                                          owner_sid,
1514                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1515                                                          SEC_RIGHTS_FILE_ALL,
1516                                                          0,
1517                                                          group_sid,
1518                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1519                                                          SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE,
1520                                                          0,
1521                                                          SID_WORLD,
1522                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1523                                                          SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE,
1524                                                          0,
1525                                                          SID_NT_SYSTEM,
1526                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1527                                                          SEC_RIGHTS_FILE_ALL,
1528                                                          0,
1529                                                          NULL);
1530         } else {
1531                 /*
1532                  * The Windows Default ACL for a new file, when there is no ACL to be
1533                  * inherited: FullControl for the owner and SYSTEM.
1534                  */
1535                 sd_def1 = security_descriptor_dacl_create(tctx,
1536                                                          0, owner_sid, NULL,
1537                                                          owner_sid,
1538                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1539                                                          SEC_RIGHTS_FILE_ALL,
1540                                                          0,
1541                                                          SID_NT_SYSTEM,
1542                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1543                                                          SEC_RIGHTS_FILE_ALL,
1544                                                          0,
1545                                                          NULL);
1546         }
1547
1548         /*
1549          * Use this in the case the system being tested does not add an ACE for
1550          * the SYSTEM SID.
1551          */
1552         sd_def2 = security_descriptor_dacl_create(tctx,
1553                                             0, owner_sid, NULL,
1554                                             owner_sid,
1555                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
1556                                             SEC_RIGHTS_FILE_ALL,
1557                                             0,
1558                                             NULL);
1559
1560         creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER);
1561
1562         for (i=0;i<ARRAY_SIZE(test_flags);i++) {
1563                 sd = security_descriptor_dacl_create(tctx,
1564                                                 0, NULL, NULL,
1565                                                 SID_CREATOR_OWNER,
1566                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1567                                                 SEC_FILE_WRITE_DATA,
1568                                                 test_flags[i].parent_flags,
1569                                                 SID_WORLD,
1570                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1571                                                 SEC_FILE_ALL | SEC_STD_ALL,
1572                                                 0,
1573                                                 NULL);
1574                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1575                 set.set_secdesc.in.file.fnum = fnum;
1576                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1577                 set.set_secdesc.in.sd = sd;
1578                 status = smb_raw_setfileinfo(cli->tree, &set);
1579                 CHECK_STATUS(status, NT_STATUS_OK);
1580
1581                 io.ntcreatex.in.fname = fname1;
1582                 io.ntcreatex.in.create_options = 0;
1583                 status = smb_raw_open(cli->tree, tctx, &io);
1584                 CHECK_STATUS(status, NT_STATUS_OK);
1585                 fnum2 = io.ntcreatex.out.file.fnum;
1586
1587                 q.query_secdesc.in.file.fnum = fnum2;
1588                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1589                 CHECK_STATUS(status, NT_STATUS_OK);
1590
1591                 smbcli_close(cli->tree, fnum2);
1592                 smbcli_unlink(cli->tree, fname1);
1593
1594                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
1595                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
1596                             !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
1597                                 torture_warning(tctx, "Expected default sd "
1598                                     "for i=%d:\n", i);
1599                                 NDR_PRINT_DEBUG(security_descriptor, sd_def1);
1600                                 torture_warning(tctx, "at %d - got:\n", i);
1601                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1602                         }
1603                         goto check_dir;
1604                 }
1605
1606                 if (q.query_secdesc.out.sd->dacl == NULL ||
1607                     q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1608                     q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1609                     !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1610                                    sd_orig->owner_sid)) {
1611                         ret = false;
1612                         torture_warning(tctx, "Bad sd in child file at %d\n", i);
1613                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1614                         goto check_dir;
1615                 }
1616
1617                 if (q.query_secdesc.out.sd->dacl->aces[0].flags != 
1618                     test_flags[i].file_flags) {
1619                         torture_warning(tctx, "incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
1620                                q.query_secdesc.out.sd->dacl->aces[0].flags,
1621                                test_flags[i].file_flags,
1622                                test_flags[i].parent_flags,
1623                                i);
1624                         ret = false;
1625                 }
1626
1627         check_dir:
1628                 io.ntcreatex.in.fname = fname2;
1629                 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1630                 status = smb_raw_open(cli->tree, tctx, &io);
1631                 CHECK_STATUS(status, NT_STATUS_OK);
1632                 fnum2 = io.ntcreatex.out.file.fnum;
1633
1634                 q.query_secdesc.in.file.fnum = fnum2;
1635                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1636                 CHECK_STATUS(status, NT_STATUS_OK);
1637
1638                 smbcli_close(cli->tree, fnum2);
1639                 smbcli_rmdir(cli->tree, fname2);
1640
1641                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1642                     (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
1643                      (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
1644                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
1645                             !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
1646                                 torture_warning(tctx, "Expected default sd for dir at %d:\n", i);
1647                                 NDR_PRINT_DEBUG(security_descriptor, sd_def1);
1648                                 torture_warning(tctx, "got:\n");
1649                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1650                         }
1651                         continue;
1652                 }
1653
1654                 if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) && 
1655                     (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
1656                         if (q.query_secdesc.out.sd->dacl == NULL ||
1657                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1658                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1659                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1660                                            sd_orig->owner_sid) ||
1661                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1662                                 torture_warning(tctx, "(CI & NP) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1663                                        test_flags[i].dir_flags,
1664                                        test_flags[i].parent_flags, i);
1665                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1666                                 torture_comment(tctx, "FYI, here is the parent sd:\n");
1667                                 NDR_PRINT_DEBUG(security_descriptor, sd);
1668                                 ret = false;
1669                                 continue;
1670                         }
1671                 } else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
1672                         if (q.query_secdesc.out.sd->dacl == NULL ||
1673                             q.query_secdesc.out.sd->dacl->num_aces != 2 ||
1674                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1675                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1676                                            sd_orig->owner_sid) ||
1677                             q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
1678                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
1679                                            creator_owner) ||
1680                             q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
1681                             q.query_secdesc.out.sd->dacl->aces[1].flags != 
1682                             (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
1683                                 torture_warning(tctx, "(CI) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1684                                        test_flags[i].dir_flags,
1685                                        test_flags[i].parent_flags, i);
1686                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1687                                 torture_comment(tctx, "FYI, here is the parent sd:\n");
1688                                 NDR_PRINT_DEBUG(security_descriptor, sd);
1689                                 ret = false;
1690                                 continue;
1691                         }
1692                 } else {
1693                         if (q.query_secdesc.out.sd->dacl == NULL ||
1694                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1695                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1696                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1697                                            creator_owner) ||
1698                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1699                                 torture_warning(tctx, "(0) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1700                                        test_flags[i].dir_flags,
1701                                        test_flags[i].parent_flags, i);
1702                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1703                                 torture_comment(tctx, "FYI, here is the parent sd:\n");
1704                                 NDR_PRINT_DEBUG(security_descriptor, sd);
1705                                 ret = false;
1706                                 continue;
1707                         }
1708                 }
1709         }
1710
1711         torture_comment(tctx, "Testing access checks on inherited create with %s\n", fname1);
1712         sd = security_descriptor_dacl_create(tctx,
1713                                         0, NULL, NULL,
1714                                         owner_sid,
1715                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1716                                         SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1717                                         SEC_ACE_FLAG_OBJECT_INHERIT,
1718                                         SID_WORLD,
1719                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1720                                         SEC_FILE_ALL | SEC_STD_ALL,
1721                                         0,
1722                                         NULL);
1723         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1724         set.set_secdesc.in.file.fnum = fnum;
1725         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1726         set.set_secdesc.in.sd = sd;
1727         status = smb_raw_setfileinfo(cli->tree, &set);
1728         CHECK_STATUS(status, NT_STATUS_OK);
1729
1730         /* Check DACL we just set. */
1731         torture_comment(tctx, "checking new sd\n");
1732         q.query_secdesc.in.file.fnum = fnum;
1733         q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
1734         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1735         CHECK_STATUS(status, NT_STATUS_OK);
1736         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
1737
1738         io.ntcreatex.in.fname = fname1;
1739         io.ntcreatex.in.create_options = 0;
1740         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1741         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1742         status = smb_raw_open(cli->tree, tctx, &io);
1743         CHECK_STATUS(status, NT_STATUS_OK);
1744         fnum2 = io.ntcreatex.out.file.fnum;
1745         CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1746
1747         q.query_secdesc.in.file.fnum = fnum2;
1748         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1749         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1750         CHECK_STATUS(status, NT_STATUS_OK);
1751         smbcli_close(cli->tree, fnum2);
1752
1753         sd2 = security_descriptor_dacl_create(tctx,
1754                                          0, owner_sid, NULL,
1755                                          owner_sid,
1756                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1757                                          SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1758                                          0,
1759                                          NULL);
1760         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1761
1762         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1763         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1764         status = smb_raw_open(cli->tree, tctx, &io);
1765         if (NT_STATUS_IS_OK(status)) {
1766                 torture_warning(tctx, "failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
1767                 ret = false;
1768                 fnum2 = io.ntcreatex.out.file.fnum;
1769                 CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1770                 smbcli_close(cli->tree, fnum2);
1771         } else {
1772                 if (TARGET_IS_WIN7(tctx)) {
1773                         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1774                 } else {
1775                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1776                 }
1777         }
1778
1779         torture_comment(tctx, "trying without execute\n");
1780         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1781         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
1782         status = smb_raw_open(cli->tree, tctx, &io);
1783         if (TARGET_IS_WIN7(tctx)) {
1784                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1785         } else {
1786                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1787         }
1788
1789         torture_comment(tctx, "and with full permissions again\n");
1790         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1791         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1792         status = smb_raw_open(cli->tree, tctx, &io);
1793         if (TARGET_IS_WIN7(tctx)) {
1794                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1795         } else {
1796                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1797         }
1798
1799         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1800         status = smb_raw_open(cli->tree, tctx, &io);
1801         CHECK_STATUS(status, NT_STATUS_OK);
1802         fnum2 = io.ntcreatex.out.file.fnum;
1803         CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1804         smbcli_close(cli->tree, fnum2);
1805
1806         torture_comment(tctx, "put back original sd\n");
1807         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1808         set.set_secdesc.in.file.fnum = fnum;
1809         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1810         set.set_secdesc.in.sd = sd_orig;
1811         status = smb_raw_setfileinfo(cli->tree, &set);
1812         CHECK_STATUS(status, NT_STATUS_OK);
1813
1814         smbcli_close(cli->tree, fnum);
1815
1816         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1817         status = smb_raw_open(cli->tree, tctx, &io);
1818         if (TARGET_IS_WIN7(tctx)) {
1819                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1820         } else {
1821                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1822         }
1823
1824         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1825         status = smb_raw_open(cli->tree, tctx, &io);
1826         CHECK_STATUS(status, NT_STATUS_OK);
1827         fnum2 = io.ntcreatex.out.file.fnum;
1828         CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1829         smbcli_close(cli->tree, fnum2);
1830
1831 done:
1832         if (sd_orig != NULL) {
1833                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1834                 set.set_secdesc.in.file.fnum = fnum;
1835                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1836                 set.set_secdesc.in.sd = sd_orig;
1837                 status = smb_raw_setfileinfo(cli->tree, &set);
1838         }
1839
1840         smbcli_close(cli->tree, fnum);
1841         smbcli_unlink(cli->tree, fname1);
1842         smbcli_rmdir(cli->tree, dname);
1843         smb_raw_exit(cli->session);
1844         smbcli_deltree(cli->tree, BASEDIR);
1845         return ret;
1846 }
1847
1848 static bool test_inheritance_flags(struct torture_context *tctx,
1849     struct smbcli_state *cli)
1850 {
1851         NTSTATUS status;
1852         union smb_open io;
1853         const char *dname = BASEDIR "\\inheritance";
1854         const char *fname1 = BASEDIR "\\inheritance\\testfile";
1855         bool ret = true;
1856         int fnum=0, fnum2, i, j;
1857         union smb_fileinfo q;
1858         union smb_setfileinfo set;
1859         struct security_descriptor *sd, *sd2, *sd_orig=NULL;
1860         const char *owner_sid;
1861         struct {
1862                 uint32_t parent_set_sd_type; /* 3 options */
1863                 uint32_t parent_set_ace_inherit; /* 1 option */
1864                 uint32_t parent_get_sd_type;
1865                 uint32_t parent_get_ace_inherit;
1866                 uint32_t child_get_sd_type;
1867                 uint32_t child_get_ace_inherit;
1868         } tflags[16]; /* 2^4 */
1869
1870         for (i = 0; i < 15; i++) {
1871                 torture_comment(tctx, "i=%d:", i);
1872
1873                 ZERO_STRUCT(tflags[i]);
1874
1875                 if (i & 1) {
1876                         tflags[i].parent_set_sd_type |=
1877                             SEC_DESC_DACL_AUTO_INHERITED;
1878                         torture_comment(tctx, "AUTO_INHERITED, ");
1879                 }
1880                 if (i & 2) {
1881                         tflags[i].parent_set_sd_type |=
1882                             SEC_DESC_DACL_AUTO_INHERIT_REQ;
1883                         torture_comment(tctx, "AUTO_INHERIT_REQ, ");
1884                 }
1885                 if (i & 4) {
1886                         tflags[i].parent_set_sd_type |=
1887                             SEC_DESC_DACL_PROTECTED;
1888                         tflags[i].parent_get_sd_type |=
1889                             SEC_DESC_DACL_PROTECTED;
1890                         torture_comment(tctx, "PROTECTED, ");
1891                 }
1892                 if (i & 8) {
1893                         tflags[i].parent_set_ace_inherit |=
1894                             SEC_ACE_FLAG_INHERITED_ACE;
1895                         tflags[i].parent_get_ace_inherit |=
1896                             SEC_ACE_FLAG_INHERITED_ACE;
1897                         torture_comment(tctx, "INHERITED, ");
1898                 }
1899
1900                 if ((tflags[i].parent_set_sd_type &
1901                     (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) ==
1902                     (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) {
1903                         tflags[i].parent_get_sd_type |=
1904                             SEC_DESC_DACL_AUTO_INHERITED;
1905                         tflags[i].child_get_sd_type |=
1906                             SEC_DESC_DACL_AUTO_INHERITED;
1907                         tflags[i].child_get_ace_inherit |=
1908                             SEC_ACE_FLAG_INHERITED_ACE;
1909                         torture_comment(tctx, "  ... parent is AUTO INHERITED");
1910                 }
1911
1912                 if (tflags[i].parent_set_ace_inherit &
1913                     SEC_ACE_FLAG_INHERITED_ACE) {
1914                         tflags[i].parent_get_ace_inherit =
1915                             SEC_ACE_FLAG_INHERITED_ACE;
1916                         torture_comment(tctx, "  ... parent ACE is INHERITED");
1917                 }
1918
1919                 torture_comment(tctx, "\n");
1920         }
1921
1922         if (!torture_setup_dir(cli, BASEDIR))
1923                 return false;
1924
1925         torture_comment(tctx, "TESTING ACL INHERITANCE FLAGS\n");
1926
1927         io.generic.level = RAW_OPEN_NTCREATEX;
1928         io.ntcreatex.in.root_fid.fnum = 0;
1929         io.ntcreatex.in.flags = 0;
1930         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1931         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1932         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1933         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
1934         io.ntcreatex.in.alloc_size = 0;
1935         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1936         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1937         io.ntcreatex.in.security_flags = 0;
1938         io.ntcreatex.in.fname = dname;
1939
1940         torture_comment(tctx, "creating initial directory %s\n", dname);
1941         status = smb_raw_open(cli->tree, tctx, &io);
1942         CHECK_STATUS(status, NT_STATUS_OK);
1943         fnum = io.ntcreatex.out.file.fnum;
1944
1945         torture_comment(tctx, "getting original sd\n");
1946         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1947         q.query_secdesc.in.file.fnum = fnum;
1948         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1949         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1950         CHECK_STATUS(status, NT_STATUS_OK);
1951         sd_orig = q.query_secdesc.out.sd;
1952
1953         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1954         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
1955
1956         for (i=0; i < ARRAY_SIZE(tflags); i++) {
1957                 torture_comment(tctx, "setting a new sd on directory, pass #%d\n", i);
1958
1959                 sd = security_descriptor_dacl_create(tctx,
1960                                                 tflags[i].parent_set_sd_type,
1961                                                 NULL, NULL,
1962                                                 owner_sid,
1963                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1964                                                 SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1965                                                 SEC_ACE_FLAG_OBJECT_INHERIT |
1966                                                 SEC_ACE_FLAG_CONTAINER_INHERIT |
1967                                                 tflags[i].parent_set_ace_inherit,
1968                                                 SID_WORLD,
1969                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1970                                                 SEC_FILE_ALL | SEC_STD_ALL,
1971                                                 0,
1972                                                 NULL);
1973                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1974                 set.set_secdesc.in.file.fnum = fnum;
1975                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1976                 set.set_secdesc.in.sd = sd;
1977                 status = smb_raw_setfileinfo(cli->tree, &set);
1978                 CHECK_STATUS(status, NT_STATUS_OK);
1979
1980                 /*
1981                  * Check DACL we just set, except change the bits to what they
1982                  * should be.
1983                  */
1984                 torture_comment(tctx, "  checking new sd\n");
1985
1986                 /* REQ bit should always be false. */
1987                 sd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
1988
1989                 if ((tflags[i].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
1990                         sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
1991
1992                 q.query_secdesc.in.file.fnum = fnum;
1993                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
1994                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1995                 CHECK_STATUS(status, NT_STATUS_OK);
1996                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
1997
1998                 /* Create file. */
1999                 torture_comment(tctx, "  creating file %s\n", fname1);
2000                 io.ntcreatex.in.fname = fname1;
2001                 io.ntcreatex.in.create_options = 0;
2002                 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2003                 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2004                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2005                 status = smb_raw_open(cli->tree, tctx, &io);
2006                 CHECK_STATUS(status, NT_STATUS_OK);
2007                 fnum2 = io.ntcreatex.out.file.fnum;
2008                 CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
2009
2010                 q.query_secdesc.in.file.fnum = fnum2;
2011                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2012                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
2013                 CHECK_STATUS(status, NT_STATUS_OK);
2014
2015                 torture_comment(tctx, "  checking sd on file %s\n", fname1);
2016                 sd2 = security_descriptor_dacl_create(tctx,
2017                                                  tflags[i].child_get_sd_type,
2018                                                  owner_sid, NULL,
2019                                                  owner_sid,
2020                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
2021                                                  SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
2022                                                  tflags[i].child_get_ace_inherit,
2023                                                  NULL);
2024                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
2025
2026                 /*
2027                  * Set new sd on file ... prove that the bits have nothing to
2028                  * do with the parents bits when manually setting an ACL. The
2029                  * _AUTO_INHERITED bit comes directly from the ACL set.
2030                  */
2031                 for (j = 0; j < ARRAY_SIZE(tflags); j++) {
2032                         torture_comment(tctx, "  setting new file sd, pass #%d\n", j);
2033
2034                         /* Change sd type. */
2035                         sd2->type &= ~(SEC_DESC_DACL_AUTO_INHERITED |
2036                             SEC_DESC_DACL_AUTO_INHERIT_REQ |
2037                             SEC_DESC_DACL_PROTECTED);
2038                         sd2->type |= tflags[j].parent_set_sd_type;
2039
2040                         sd2->dacl->aces[0].flags &=
2041                             ~SEC_ACE_FLAG_INHERITED_ACE;
2042                         sd2->dacl->aces[0].flags |=
2043                             tflags[j].parent_set_ace_inherit;
2044
2045                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2046                         set.set_secdesc.in.file.fnum = fnum2;
2047                         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2048                         set.set_secdesc.in.sd = sd2;
2049                         status = smb_raw_setfileinfo(cli->tree, &set);
2050                         CHECK_STATUS(status, NT_STATUS_OK);
2051
2052                         /* Check DACL we just set. */
2053                         sd2->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
2054                         if ((tflags[j].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
2055                                 sd2->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
2056
2057                         q.query_secdesc.in.file.fnum = fnum2;
2058                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2059                         status = smb_raw_fileinfo(cli->tree, tctx, &q);
2060                         CHECK_STATUS(status, NT_STATUS_OK);
2061
2062                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
2063                 }
2064
2065                 smbcli_close(cli->tree, fnum2);
2066                 smbcli_unlink(cli->tree, fname1);
2067         }
2068
2069 done:
2070         smbcli_close(cli->tree, fnum);
2071         smb_raw_exit(cli->session);
2072         smbcli_deltree(cli->tree, BASEDIR);
2073         return ret;
2074 }
2075
2076 /*
2077   test dynamic acl inheritance
2078   Test copied to smb2/acls.c for SMB2.
2079 */
2080 static bool test_inheritance_dynamic(struct torture_context *tctx, 
2081                                                                          struct smbcli_state *cli)
2082 {
2083         NTSTATUS status;
2084         union smb_open io;
2085         const char *dname = BASEDIR "\\inheritance2";
2086         const char *fname1 = BASEDIR "\\inheritance2\\testfile";
2087         bool ret = true;
2088         int fnum=0, fnum2;
2089         union smb_fileinfo q;
2090         union smb_setfileinfo set;
2091         struct security_descriptor *sd, *sd_orig=NULL;
2092         const char *owner_sid;
2093         
2094         torture_comment(tctx, "TESTING DYNAMIC ACL INHERITANCE\n");
2095
2096         if (!torture_setup_dir(cli, BASEDIR))
2097                 return false;
2098
2099         io.generic.level = RAW_OPEN_NTCREATEX;
2100         io.ntcreatex.in.root_fid.fnum = 0;
2101         io.ntcreatex.in.flags = 0;
2102         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2103         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2104         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
2105         io.ntcreatex.in.share_access = 0;
2106         io.ntcreatex.in.alloc_size = 0;
2107         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2108         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2109         io.ntcreatex.in.security_flags = 0;
2110         io.ntcreatex.in.fname = dname;
2111
2112         status = smb_raw_open(cli->tree, tctx, &io);
2113         CHECK_STATUS(status, NT_STATUS_OK);
2114         fnum = io.ntcreatex.out.file.fnum;
2115
2116         torture_comment(tctx, "get the original sd\n");
2117         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
2118         q.query_secdesc.in.file.fnum = fnum;
2119         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2120         status = smb_raw_fileinfo(cli->tree, tctx, &q);
2121         CHECK_STATUS(status, NT_STATUS_OK);
2122         sd_orig = q.query_secdesc.out.sd;
2123
2124         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
2125
2126         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
2127
2128         sd = security_descriptor_dacl_create(tctx,
2129                                         0, NULL, NULL,
2130                                         owner_sid,
2131                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
2132                                         SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
2133                                         SEC_ACE_FLAG_OBJECT_INHERIT,
2134                                         NULL);
2135         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
2136
2137         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2138         set.set_secdesc.in.file.fnum = fnum;
2139         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2140         set.set_secdesc.in.sd = sd;
2141         status = smb_raw_setfileinfo(cli->tree, &set);
2142         CHECK_STATUS(status, NT_STATUS_OK);
2143
2144         torture_comment(tctx, "create a file with an inherited acl\n");
2145         io.ntcreatex.in.fname = fname1;
2146         io.ntcreatex.in.create_options = 0;
2147         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE;
2148         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2149         status = smb_raw_open(cli->tree, tctx, &io);
2150         CHECK_STATUS(status, NT_STATUS_OK);
2151         fnum2 = io.ntcreatex.out.file.fnum;
2152         smbcli_close(cli->tree, fnum2);
2153
2154         torture_comment(tctx, "try and access file with base rights - should be OK\n");
2155         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
2156         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2157         status = smb_raw_open(cli->tree, tctx, &io);
2158         CHECK_STATUS(status, NT_STATUS_OK);
2159         fnum2 = io.ntcreatex.out.file.fnum;
2160         smbcli_close(cli->tree, fnum2);
2161
2162         torture_comment(tctx, "try and access file with extra rights - should be denied\n");
2163         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
2164         status = smb_raw_open(cli->tree, tctx, &io);
2165         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
2166
2167         torture_comment(tctx, "update parent sd\n");
2168         sd = security_descriptor_dacl_create(tctx,
2169                                         0, NULL, NULL,
2170                                         owner_sid,
2171                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
2172                                         SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE,
2173                                         SEC_ACE_FLAG_OBJECT_INHERIT,
2174                                         NULL);
2175         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
2176
2177         set.set_secdesc.in.sd = sd;
2178         status = smb_raw_setfileinfo(cli->tree, &set);
2179         CHECK_STATUS(status, NT_STATUS_OK);
2180
2181         torture_comment(tctx, "try and access file with base rights - should be OK\n");
2182         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
2183         status = smb_raw_open(cli->tree, tctx, &io);
2184         CHECK_STATUS(status, NT_STATUS_OK);
2185         fnum2 = io.ntcreatex.out.file.fnum;
2186         smbcli_close(cli->tree, fnum2);
2187
2188
2189         torture_comment(tctx, "try and access now - should be OK if dynamic inheritance works\n");
2190         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
2191         status = smb_raw_open(cli->tree, tctx, &io);
2192         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2193                 torture_comment(tctx, "Server does not have dynamic inheritance\n");
2194         }
2195         if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
2196                 torture_comment(tctx, "Server does have dynamic inheritance\n");
2197         }
2198         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
2199
2200         smbcli_unlink(cli->tree, fname1);
2201
2202 done:
2203         torture_comment(tctx, "put back original sd\n");
2204         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2205         set.set_secdesc.in.file.fnum = fnum;
2206         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2207         set.set_secdesc.in.sd = sd_orig;
2208         status = smb_raw_setfileinfo(cli->tree, &set);
2209
2210         smbcli_close(cli->tree, fnum);
2211         smbcli_rmdir(cli->tree, dname);
2212         smb_raw_exit(cli->session);
2213         smbcli_deltree(cli->tree, BASEDIR);
2214
2215         return ret;
2216 }
2217
2218 #define CHECK_STATUS_FOR_BIT_ACTION(status, bits, action) do { \
2219         if (!(bits & desired_64)) {\
2220                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); \
2221                 action; \
2222         } else { \
2223                 CHECK_STATUS(status, NT_STATUS_OK); \
2224         } \
2225 } while (0)
2226
2227 #define CHECK_STATUS_FOR_BIT(status, bits, access) do { \
2228         if (NT_STATUS_IS_OK(status)) { \
2229                 if (!(granted & access)) {\
2230                         ret = false; \
2231                         torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are not granted! granted[0x%08X] desired[0x%08X]\n", \
2232                                __location__, nt_errstr(status), access, granted, desired); \
2233                         goto done; \
2234                 } \
2235         } else { \
2236                 if (granted & access) {\
2237                         ret = false; \
2238                         torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are granted! granted[0x%08X] desired[0x%08X]\n", \
2239                                __location__, nt_errstr(status), access, granted, desired); \
2240                         goto done; \
2241                 } \
2242         } \
2243         CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \
2244 } while (0)
2245
2246 /* test what access mask is needed for getting and setting security_descriptors
2247   Test copied to smb2/acls.c for SMB2. */
2248 static bool test_sd_get_set(struct torture_context *tctx, 
2249                                                         struct smbcli_state *cli)
2250 {
2251         NTSTATUS status;
2252         bool ret = true;
2253         union smb_open io;
2254         union smb_fileinfo fi;
2255         union smb_setfileinfo si;
2256         struct security_descriptor *sd;
2257         struct security_descriptor *sd_owner = NULL;
2258         struct security_descriptor *sd_group = NULL;
2259         struct security_descriptor *sd_dacl = NULL;
2260         struct security_descriptor *sd_sacl = NULL;
2261         int fnum=0;
2262         const char *fname = BASEDIR "\\sd_get_set.txt";
2263         uint64_t desired_64;
2264         uint32_t desired = 0, granted;
2265         int i = 0;
2266 #define NO_BITS_HACK (((uint64_t)1)<<32)
2267         uint64_t open_bits =
2268                 SEC_MASK_GENERIC |
2269                 SEC_FLAG_SYSTEM_SECURITY |
2270                 SEC_FLAG_MAXIMUM_ALLOWED |
2271                 SEC_STD_ALL |
2272                 SEC_FILE_ALL | 
2273                 NO_BITS_HACK;
2274         uint64_t get_owner_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
2275         uint64_t set_owner_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
2276         uint64_t get_group_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
2277         uint64_t set_group_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
2278         uint64_t get_dacl_bits  = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
2279         uint64_t set_dacl_bits  = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_DAC;
2280         uint64_t get_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
2281         uint64_t set_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
2282
2283         if (!torture_setup_dir(cli, BASEDIR))
2284                 return false;
2285
2286         torture_comment(tctx, "TESTING ACCESS MASKS FOR SD GET/SET\n");
2287
2288         /* first create a file with full access for everyone */
2289         sd = security_descriptor_dacl_create(tctx,
2290                                         0, SID_NT_ANONYMOUS, SID_BUILTIN_USERS,
2291                                         SID_WORLD,
2292                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
2293                                         SEC_GENERIC_ALL,
2294                                         0,
2295                                         NULL);
2296         sd->type |= SEC_DESC_SACL_PRESENT;
2297         sd->sacl = NULL;
2298         io.ntcreatex.level = RAW_OPEN_NTTRANS_CREATE;
2299         io.ntcreatex.in.root_fid.fnum = 0;
2300         io.ntcreatex.in.flags = 0;
2301         io.ntcreatex.in.access_mask = SEC_GENERIC_ALL;
2302         io.ntcreatex.in.create_options = 0;
2303         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2304         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2305         io.ntcreatex.in.alloc_size = 0;
2306         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2307         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2308         io.ntcreatex.in.security_flags = 0;
2309         io.ntcreatex.in.fname = fname;
2310         io.ntcreatex.in.sec_desc = sd;
2311         io.ntcreatex.in.ea_list = NULL;
2312         status = smb_raw_open(cli->tree, tctx, &io);
2313         CHECK_STATUS(status, NT_STATUS_OK);
2314         fnum = io.ntcreatex.out.file.fnum;
2315
2316         status = smbcli_close(cli->tree, fnum);
2317         CHECK_STATUS(status, NT_STATUS_OK);
2318
2319         /* 
2320          * now try each access_mask bit and no bit at all in a loop
2321          * and see what's allowed
2322          * NOTE: if i == 32 it means access_mask = 0 (see NO_BITS_HACK above)
2323          */
2324         for (i=0; i <= 32; i++) {
2325                 desired_64 = ((uint64_t)1) << i;
2326                 desired = (uint32_t)desired_64;
2327
2328                 /* first open the file with the desired access */
2329                 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2330                 io.ntcreatex.in.access_mask = desired;
2331                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2332                 status = smb_raw_open(cli->tree, tctx, &io);
2333                 CHECK_STATUS_FOR_BIT_ACTION(status, open_bits, goto next);
2334                 fnum = io.ntcreatex.out.file.fnum;
2335
2336                 /* then check what access was granted */
2337                 fi.access_information.level             = RAW_FILEINFO_ACCESS_INFORMATION;
2338                 fi.access_information.in.file.fnum      = fnum;
2339                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2340                 CHECK_STATUS(status, NT_STATUS_OK);
2341                 granted = fi.access_information.out.access_flags;
2342
2343                 /* test the owner */
2344                 ZERO_STRUCT(fi);
2345                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
2346                 fi.query_secdesc.in.file.fnum           = fnum;
2347                 fi.query_secdesc.in.secinfo_flags       = SECINFO_OWNER;
2348                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2349                 CHECK_STATUS_FOR_BIT(status, get_owner_bits, SEC_STD_READ_CONTROL);
2350                 if (fi.query_secdesc.out.sd) {
2351                         sd_owner = fi.query_secdesc.out.sd;
2352                 } else if (!sd_owner) {
2353                         sd_owner = sd;
2354                 }
2355                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
2356                 si.set_secdesc.in.file.fnum             = fnum;
2357                 si.set_secdesc.in.secinfo_flags         = SECINFO_OWNER;
2358                 si.set_secdesc.in.sd                    = sd_owner;
2359                 status = smb_raw_setfileinfo(cli->tree, &si);
2360                 CHECK_STATUS_FOR_BIT(status, set_owner_bits, SEC_STD_WRITE_OWNER);
2361
2362                 /* test the group */
2363                 ZERO_STRUCT(fi);
2364                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
2365                 fi.query_secdesc.in.file.fnum           = fnum;
2366                 fi.query_secdesc.in.secinfo_flags       = SECINFO_GROUP;
2367                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2368                 CHECK_STATUS_FOR_BIT(status, get_group_bits, SEC_STD_READ_CONTROL);
2369                 if (fi.query_secdesc.out.sd) {
2370                         sd_group = fi.query_secdesc.out.sd;
2371                 } else if (!sd_group) {
2372                         sd_group = sd;
2373                 }
2374                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
2375                 si.set_secdesc.in.file.fnum             = fnum;
2376                 si.set_secdesc.in.secinfo_flags         = SECINFO_GROUP;
2377                 si.set_secdesc.in.sd                    = sd_group;
2378                 status = smb_raw_setfileinfo(cli->tree, &si);
2379                 CHECK_STATUS_FOR_BIT(status, set_group_bits, SEC_STD_WRITE_OWNER);
2380
2381                 /* test the DACL */
2382                 ZERO_STRUCT(fi);
2383                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
2384                 fi.query_secdesc.in.file.fnum           = fnum;
2385                 fi.query_secdesc.in.secinfo_flags       = SECINFO_DACL;
2386                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2387                 CHECK_STATUS_FOR_BIT(status, get_dacl_bits, SEC_STD_READ_CONTROL);
2388                 if (fi.query_secdesc.out.sd) {
2389                         sd_dacl = fi.query_secdesc.out.sd;
2390                 } else if (!sd_dacl) {
2391                         sd_dacl = sd;
2392                 }
2393                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
2394                 si.set_secdesc.in.file.fnum             = fnum;
2395                 si.set_secdesc.in.secinfo_flags         = SECINFO_DACL;
2396                 si.set_secdesc.in.sd                    = sd_dacl;
2397                 status = smb_raw_setfileinfo(cli->tree, &si);
2398                 CHECK_STATUS_FOR_BIT(status, set_dacl_bits, SEC_STD_WRITE_DAC);
2399
2400                 /* test the SACL */
2401                 ZERO_STRUCT(fi);
2402                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
2403                 fi.query_secdesc.in.file.fnum           = fnum;
2404                 fi.query_secdesc.in.secinfo_flags       = SECINFO_SACL;
2405                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
2406                 CHECK_STATUS_FOR_BIT(status, get_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
2407                 if (fi.query_secdesc.out.sd) {
2408                         sd_sacl = fi.query_secdesc.out.sd;
2409                 } else if (!sd_sacl) {
2410                         sd_sacl = sd;
2411                 }
2412                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
2413                 si.set_secdesc.in.file.fnum             = fnum;
2414                 si.set_secdesc.in.secinfo_flags         = SECINFO_SACL;
2415                 si.set_secdesc.in.sd                    = sd_sacl;
2416                 status = smb_raw_setfileinfo(cli->tree, &si);
2417                 CHECK_STATUS_FOR_BIT(status, set_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
2418
2419                 /* close the handle */
2420                 status = smbcli_close(cli->tree, fnum);
2421                 CHECK_STATUS(status, NT_STATUS_OK);
2422 next:
2423                 continue;
2424         }
2425
2426 done:
2427         smbcli_close(cli->tree, fnum);
2428         smbcli_unlink(cli->tree, fname);
2429         smb_raw_exit(cli->session);
2430         smbcli_deltree(cli->tree, BASEDIR);
2431
2432         return ret;
2433 }
2434
2435
2436 /* 
2437    basic testing of security descriptor calls
2438 */
2439 struct torture_suite *torture_raw_acls(TALLOC_CTX *mem_ctx)
2440 {
2441         struct torture_suite *suite = torture_suite_create(mem_ctx, "acls");
2442
2443         torture_suite_add_1smb_test(suite, "sd", test_sd);
2444         torture_suite_add_1smb_test(suite, "create_file", test_nttrans_create_file);
2445         torture_suite_add_1smb_test(suite, "create_dir", test_nttrans_create_dir);
2446         torture_suite_add_1smb_test(suite, "nulldacl", test_nttrans_create_null_dacl);
2447         torture_suite_add_1smb_test(suite, "creator", test_creator_sid);
2448         torture_suite_add_1smb_test(suite, "generic", test_generic_bits);
2449         torture_suite_add_1smb_test(suite, "owner", test_owner_bits);
2450         torture_suite_add_1smb_test(suite, "inheritance", test_inheritance);
2451
2452         /* torture_suite_add_1smb_test(suite, "INHERITFLAGS", test_inheritance_flags); */
2453         torture_suite_add_1smb_test(suite, "dynamic", test_inheritance_dynamic);
2454         /* XXX This test does not work against XP or Vista.
2455         torture_suite_add_1smb_test(suite, "GETSET", test_sd_get_set);
2456         */
2457
2458         return suite;
2459 }