Merge branch 'master' of ssh://git.samba.org/data/git/samba
[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                 printf("(%s) Incorrect status %s - should be %s\n", \
37                        __location__, nt_errstr(status), nt_errstr(correct)); \
38                 ret = false; \
39                 goto done; \
40         }} while (0)
41
42
43 static bool test_sd(struct torture_context *tctx, 
44                                         struct smbcli_state *cli)
45 {
46         NTSTATUS status;
47         union smb_open io;
48         const char *fname = BASEDIR "\\sd.txt";
49         bool ret = true;
50         int fnum = -1;
51         union smb_fileinfo q;
52         union smb_setfileinfo set;
53         struct security_ace ace;
54         struct security_descriptor *sd;
55         struct dom_sid *test_sid;
56
57         printf("TESTING SETFILEINFO EA_SET\n");
58
59         io.generic.level = RAW_OPEN_NTCREATEX;
60         io.ntcreatex.in.root_fid = 0;
61         io.ntcreatex.in.flags = 0;
62         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
63         io.ntcreatex.in.create_options = 0;
64         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
65         io.ntcreatex.in.share_access = 
66                 NTCREATEX_SHARE_ACCESS_READ | 
67                 NTCREATEX_SHARE_ACCESS_WRITE;
68         io.ntcreatex.in.alloc_size = 0;
69         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
70         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
71         io.ntcreatex.in.security_flags = 0;
72         io.ntcreatex.in.fname = fname;
73         status = smb_raw_open(cli->tree, tctx, &io);
74         CHECK_STATUS(status, NT_STATUS_OK);
75         fnum = io.ntcreatex.out.file.fnum;
76         
77         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
78         q.query_secdesc.in.file.fnum = fnum;
79         q.query_secdesc.in.secinfo_flags = 
80                 SECINFO_OWNER |
81                 SECINFO_GROUP |
82                 SECINFO_DACL;
83         status = smb_raw_fileinfo(cli->tree, tctx, &q);
84         CHECK_STATUS(status, NT_STATUS_OK);
85         sd = q.query_secdesc.out.sd;
86
87         printf("add a new ACE to the DACL\n");
88
89         test_sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1234-5432");
90
91         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
92         ace.flags = 0;
93         ace.access_mask = SEC_STD_ALL;
94         ace.trustee = *test_sid;
95
96         status = security_descriptor_dacl_add(sd, &ace);
97         CHECK_STATUS(status, NT_STATUS_OK);
98
99         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
100         set.set_secdesc.in.file.fnum = fnum;
101         set.set_secdesc.in.secinfo_flags = q.query_secdesc.in.secinfo_flags;
102         set.set_secdesc.in.sd = sd;
103
104         status = smb_raw_setfileinfo(cli->tree, &set);
105         CHECK_STATUS(status, NT_STATUS_OK);
106
107         status = smb_raw_fileinfo(cli->tree, tctx, &q);
108         CHECK_STATUS(status, NT_STATUS_OK);
109
110         if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
111                 printf("%s: security descriptors don't match!\n", __location__);
112                 printf("got:\n");
113                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
114                 printf("expected:\n");
115                 NDR_PRINT_DEBUG(security_descriptor, sd);
116                 ret = false;
117         }
118
119         printf("remove it again\n");
120
121         status = security_descriptor_dacl_del(sd, test_sid);
122         CHECK_STATUS(status, NT_STATUS_OK);
123
124         status = smb_raw_setfileinfo(cli->tree, &set);
125         CHECK_STATUS(status, NT_STATUS_OK);
126
127         status = smb_raw_fileinfo(cli->tree, tctx, &q);
128         CHECK_STATUS(status, NT_STATUS_OK);
129
130         if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
131                 printf("%s: security descriptors don't match!\n", __location__);
132                 printf("got:\n");
133                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
134                 printf("expected:\n");
135                 NDR_PRINT_DEBUG(security_descriptor, sd);
136                 ret = false;
137         }
138
139 done:
140         smbcli_close(cli->tree, fnum);
141         return ret;
142 }
143
144
145 /*
146   test using nttrans create to create a file with an initial acl set
147 */
148 static bool test_nttrans_create(struct torture_context *tctx, 
149                                                                 struct smbcli_state *cli)
150 {
151         NTSTATUS status;
152         union smb_open io;
153         const char *fname = BASEDIR "\\acl2.txt";
154         bool ret = true;
155         int fnum = -1;
156         union smb_fileinfo q;
157         struct security_ace ace;
158         struct security_descriptor *sd;
159         struct dom_sid *test_sid;
160
161         printf("testing nttrans create with sec_desc\n");
162
163         io.generic.level = RAW_OPEN_NTTRANS_CREATE;
164         io.ntcreatex.in.root_fid = 0;
165         io.ntcreatex.in.flags = 0;
166         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
167         io.ntcreatex.in.create_options = 0;
168         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
169         io.ntcreatex.in.share_access = 
170                 NTCREATEX_SHARE_ACCESS_READ | 
171                 NTCREATEX_SHARE_ACCESS_WRITE;
172         io.ntcreatex.in.alloc_size = 0;
173         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
174         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
175         io.ntcreatex.in.security_flags = 0;
176         io.ntcreatex.in.fname = fname;
177         io.ntcreatex.in.sec_desc = NULL;
178         io.ntcreatex.in.ea_list = NULL;
179
180         printf("creating normal file\n");
181
182         status = smb_raw_open(cli->tree, tctx, &io);
183         CHECK_STATUS(status, NT_STATUS_OK);
184         fnum = io.ntcreatex.out.file.fnum;
185
186         printf("querying ACL\n");
187
188         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
189         q.query_secdesc.in.file.fnum = fnum;
190         q.query_secdesc.in.secinfo_flags = 
191                 SECINFO_OWNER |
192                 SECINFO_GROUP |
193                 SECINFO_DACL;
194         status = smb_raw_fileinfo(cli->tree, tctx, &q);
195         CHECK_STATUS(status, NT_STATUS_OK);
196         sd = q.query_secdesc.out.sd;
197
198         smbcli_close(cli->tree, fnum);
199         smbcli_unlink(cli->tree, fname);
200
201         printf("adding a new ACE\n");
202         test_sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1234-54321");
203
204         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
205         ace.flags = 0;
206         ace.access_mask = SEC_STD_ALL;
207         ace.trustee = *test_sid;
208
209         status = security_descriptor_dacl_add(sd, &ace);
210         CHECK_STATUS(status, NT_STATUS_OK);
211         
212         printf("creating a file with an initial ACL\n");
213
214         io.ntcreatex.in.sec_desc = sd;
215         status = smb_raw_open(cli->tree, tctx, &io);
216         CHECK_STATUS(status, NT_STATUS_OK);
217         fnum = io.ntcreatex.out.file.fnum;
218         
219         q.query_secdesc.in.file.fnum = fnum;
220         status = smb_raw_fileinfo(cli->tree, tctx, &q);
221         CHECK_STATUS(status, NT_STATUS_OK);
222
223         if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
224                 printf("%s: security descriptors don't match!\n", __location__);
225                 printf("got:\n");
226                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
227                 printf("expected:\n");
228                 NDR_PRINT_DEBUG(security_descriptor, sd);
229                 ret = false;
230         }
231
232 done:
233         smbcli_close(cli->tree, fnum);
234         return ret;
235 }
236
237 #define CHECK_ACCESS_FLAGS(_fnum, flags) do { \
238         union smb_fileinfo _q; \
239         _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
240         _q.access_information.in.file.fnum = (_fnum); \
241         status = smb_raw_fileinfo(cli->tree, tctx, &_q); \
242         CHECK_STATUS(status, NT_STATUS_OK); \
243         if (_q.access_information.out.access_flags != (flags)) { \
244                 printf("(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
245                        __location__, _q.access_information.out.access_flags, (flags)); \
246                 ret = false; \
247                 goto done; \
248         } \
249 } while (0)
250
251 /*
252   test using NTTRANS CREATE to create a file with a null ACL set
253 */
254 static bool test_nttrans_create_null_dacl(struct torture_context *tctx,
255                                           struct smbcli_state *cli)
256 {
257         NTSTATUS status;
258         union smb_open io;
259         const char *fname = BASEDIR "\\acl3.txt";
260         bool ret = true;
261         int fnum = -1;
262         union smb_fileinfo q;
263         union smb_setfileinfo s;
264         struct security_descriptor *sd = security_descriptor_initialise(tctx);
265         struct security_acl dacl;
266
267         printf("TESTING SEC_DESC WITH A NULL DACL\n");
268
269         io.generic.level = RAW_OPEN_NTTRANS_CREATE;
270         io.ntcreatex.in.root_fid = 0;
271         io.ntcreatex.in.flags = 0;
272         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC
273                 | SEC_STD_WRITE_OWNER;
274         io.ntcreatex.in.create_options = 0;
275         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
276         io.ntcreatex.in.share_access =
277                 NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
278         io.ntcreatex.in.alloc_size = 0;
279         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
280         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
281         io.ntcreatex.in.security_flags = 0;
282         io.ntcreatex.in.fname = fname;
283         io.ntcreatex.in.sec_desc = sd;
284         io.ntcreatex.in.ea_list = NULL;
285
286         printf("creating a file with a empty sd\n");
287         status = smb_raw_open(cli->tree, tctx, &io);
288         CHECK_STATUS(status, NT_STATUS_OK);
289         fnum = io.ntcreatex.out.file.fnum;
290
291         printf("get the original sd\n");
292         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
293         q.query_secdesc.in.file.fnum = fnum;
294         q.query_secdesc.in.secinfo_flags =
295                 SECINFO_OWNER |
296                 SECINFO_GROUP |
297                 SECINFO_DACL;
298         status = smb_raw_fileinfo(cli->tree, tctx, &q);
299         CHECK_STATUS(status, NT_STATUS_OK);
300
301         /*
302          * Testing the created DACL,
303          * the server should add the inherited DACL
304          * when SEC_DESC_DACL_PRESENT isn't specified
305          */
306         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
307                 printf("DACL_PRESENT flag not set by the server!\n");
308                 ret = false;
309                 goto done;
310         }
311         if (q.query_secdesc.out.sd->dacl == NULL) {
312                 printf("no DACL has been created on the server!\n");
313                 ret = false;
314                 goto done;
315         }
316
317         printf("set NULL DACL\n");
318         sd->type |= SEC_DESC_DACL_PRESENT;
319
320         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
321         s.set_secdesc.in.file.fnum = fnum;
322         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
323         s.set_secdesc.in.sd = sd;
324         status = smb_raw_setfileinfo(cli->tree, &s);
325         CHECK_STATUS(status, NT_STATUS_OK);
326
327         printf("get the sd\n");
328         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
329         q.query_secdesc.in.file.fnum = fnum;
330         q.query_secdesc.in.secinfo_flags =
331                 SECINFO_OWNER |
332                 SECINFO_GROUP |
333                 SECINFO_DACL;
334         status = smb_raw_fileinfo(cli->tree, tctx, &q);
335         CHECK_STATUS(status, NT_STATUS_OK);
336
337         /* Testing the modified DACL */
338         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
339                 printf("DACL_PRESENT flag not set by the server!\n");
340                 ret = false;
341                 goto done;
342         }
343         if (q.query_secdesc.out.sd->dacl != NULL) {
344                 printf("DACL has been created on the server!\n");
345                 ret = false;
346                 goto done;
347         }
348
349         printf("try open for read control\n");
350         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL;
351         status = smb_raw_open(cli->tree, tctx, &io);
352         CHECK_STATUS(status, NT_STATUS_OK);
353         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
354                 SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE);
355         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
356
357         printf("try open for write\n");
358         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
359         status = smb_raw_open(cli->tree, tctx, &io);
360         CHECK_STATUS(status, NT_STATUS_OK);
361         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
362                 SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
363         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
364
365         printf("try open for read\n");
366         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
367         status = smb_raw_open(cli->tree, tctx, &io);
368         CHECK_STATUS(status, NT_STATUS_OK);
369         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
370                 SEC_FILE_READ_DATA | SEC_FILE_READ_ATTRIBUTE);
371         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
372
373         printf("try open for generic write\n");
374         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
375         status = smb_raw_open(cli->tree, tctx, &io);
376         CHECK_STATUS(status, NT_STATUS_OK);
377         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
378                 SEC_RIGHTS_FILE_WRITE | SEC_FILE_READ_ATTRIBUTE);
379         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
380
381         printf("try open for generic read\n");
382         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
383         status = smb_raw_open(cli->tree, tctx, &io);
384         CHECK_STATUS(status, NT_STATUS_OK);
385         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
386                 SEC_RIGHTS_FILE_READ | SEC_FILE_READ_ATTRIBUTE);
387         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
388
389         printf("set DACL with 0 aces\n");
390         ZERO_STRUCT(dacl);
391         dacl.revision = SECURITY_ACL_REVISION_NT4;
392         dacl.num_aces = 0;
393         sd->dacl = &dacl;
394
395         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
396         s.set_secdesc.in.file.fnum = fnum;
397         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
398         s.set_secdesc.in.sd = sd;
399         status = smb_raw_setfileinfo(cli->tree, &s);
400         CHECK_STATUS(status, NT_STATUS_OK);
401
402         printf("get the sd\n");
403         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
404         q.query_secdesc.in.file.fnum = fnum;
405         q.query_secdesc.in.secinfo_flags =
406                 SECINFO_OWNER |
407                 SECINFO_GROUP |
408                 SECINFO_DACL;
409         status = smb_raw_fileinfo(cli->tree, tctx, &q);
410         CHECK_STATUS(status, NT_STATUS_OK);
411
412         /* Testing the modified DACL */
413         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
414                 printf("DACL_PRESENT flag not set by the server!\n");
415                 ret = false;
416                 goto done;
417         }
418         if (q.query_secdesc.out.sd->dacl == NULL) {
419                 printf("no DACL has been created on the server!\n");
420                 ret = false;
421                 goto done;
422         }
423         if (q.query_secdesc.out.sd->dacl->num_aces != 0) {
424                 printf("DACL has %u aces!\n",
425                        q.query_secdesc.out.sd->dacl->num_aces);
426                 ret = false;
427                 goto done;
428         }
429
430         printf("try open for read control\n");
431         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL;
432         status = smb_raw_open(cli->tree, tctx, &io);
433         CHECK_STATUS(status, NT_STATUS_OK);
434         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum,
435                 SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE);
436         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
437
438         printf("try open for write => access_denied\n");
439         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
440         status = smb_raw_open(cli->tree, tctx, &io);
441         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
442
443         printf("try open for read => access_denied\n");
444         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
445         status = smb_raw_open(cli->tree, tctx, &io);
446         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
447
448         printf("try open for generic write => access_denied\n");
449         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
450         status = smb_raw_open(cli->tree, tctx, &io);
451         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
452
453         printf("try open for generic read => access_denied\n");
454         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
455         status = smb_raw_open(cli->tree, tctx, &io);
456         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
457
458         printf("set empty sd\n");
459         sd->type &= ~SEC_DESC_DACL_PRESENT;
460         sd->dacl = NULL;
461
462         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
463         s.set_secdesc.in.file.fnum = fnum;
464         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
465         s.set_secdesc.in.sd = sd;
466         status = smb_raw_setfileinfo(cli->tree, &s);
467         CHECK_STATUS(status, NT_STATUS_OK);
468
469         printf("get the sd\n");
470         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
471         q.query_secdesc.in.file.fnum = fnum;
472         q.query_secdesc.in.secinfo_flags =
473                 SECINFO_OWNER |
474                 SECINFO_GROUP |
475                 SECINFO_DACL;
476         status = smb_raw_fileinfo(cli->tree, tctx, &q);
477         CHECK_STATUS(status, NT_STATUS_OK);
478
479         /* Testing the modified DACL */
480         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
481                 printf("DACL_PRESENT flag not set by the server!\n");
482                 ret = false;
483                 goto done;
484         }
485         if (q.query_secdesc.out.sd->dacl != NULL) {
486                 printf("DACL has been created on the server!\n");
487                 ret = false;
488                 goto done;
489         }
490 done:
491         smbcli_close(cli->tree, fnum);
492         return ret;
493 }
494
495 /*
496   test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
497   mapping bits
498 */
499 static bool test_creator_sid(struct torture_context *tctx, 
500                                                          struct smbcli_state *cli)
501 {
502         NTSTATUS status;
503         union smb_open io;
504         const char *fname = BASEDIR "\\creator.txt";
505         bool ret = true;
506         int fnum = -1;
507         union smb_fileinfo q;
508         union smb_setfileinfo set;
509         struct security_descriptor *sd, *sd_orig, *sd2;
510         const char *owner_sid;
511
512         printf("TESTING SID_CREATOR_OWNER\n");
513
514         io.generic.level = RAW_OPEN_NTCREATEX;
515         io.ntcreatex.in.root_fid = 0;
516         io.ntcreatex.in.flags = 0;
517         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
518         io.ntcreatex.in.create_options = 0;
519         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
520         io.ntcreatex.in.share_access = 
521                 NTCREATEX_SHARE_ACCESS_READ | 
522                 NTCREATEX_SHARE_ACCESS_WRITE;
523         io.ntcreatex.in.alloc_size = 0;
524         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
525         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
526         io.ntcreatex.in.security_flags = 0;
527         io.ntcreatex.in.fname = fname;
528         status = smb_raw_open(cli->tree, tctx, &io);
529         CHECK_STATUS(status, NT_STATUS_OK);
530         fnum = io.ntcreatex.out.file.fnum;
531
532         printf("get the original sd\n");
533         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
534         q.query_secdesc.in.file.fnum = fnum;
535         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
536         status = smb_raw_fileinfo(cli->tree, tctx, &q);
537         CHECK_STATUS(status, NT_STATUS_OK);
538         sd_orig = q.query_secdesc.out.sd;
539
540         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
541
542         printf("set a sec desc allowing no write by CREATOR_OWNER\n");
543         sd = security_descriptor_dacl_create(tctx,
544                                         0, NULL, NULL,
545                                         SID_CREATOR_OWNER,
546                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
547                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
548                                         0,
549                                         NULL);
550
551         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
552         set.set_secdesc.in.file.fnum = fnum;
553         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
554         set.set_secdesc.in.sd = sd;
555
556         status = smb_raw_setfileinfo(cli->tree, &set);
557         CHECK_STATUS(status, NT_STATUS_OK);
558
559         printf("try open for write\n");
560         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
561         status = smb_raw_open(cli->tree, tctx, &io);
562         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
563
564         printf("try open for read\n");
565         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
566         status = smb_raw_open(cli->tree, tctx, &io);
567         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
568
569         printf("try open for generic write\n");
570         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
571         status = smb_raw_open(cli->tree, tctx, &io);
572         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
573
574         printf("try open for generic read\n");
575         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
576         status = smb_raw_open(cli->tree, tctx, &io);
577         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
578
579         printf("set a sec desc allowing no write by owner\n");
580         sd = security_descriptor_dacl_create(tctx,
581                                         0, owner_sid, NULL,
582                                         owner_sid,
583                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
584                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
585                                         0,
586                                         NULL);
587
588         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
589         set.set_secdesc.in.file.fnum = fnum;
590         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
591         set.set_secdesc.in.sd = sd;
592         status = smb_raw_setfileinfo(cli->tree, &set);
593         CHECK_STATUS(status, NT_STATUS_OK);
594
595         printf("check that sd has been mapped correctly\n");
596         status = smb_raw_fileinfo(cli->tree, tctx, &q);
597         CHECK_STATUS(status, NT_STATUS_OK);
598         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd)) {
599                 printf("%s: security descriptors don't match!\n", __location__);
600                 printf("got:\n");
601                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
602                 printf("expected:\n");
603                 NDR_PRINT_DEBUG(security_descriptor, sd);
604                 ret = false;
605         }
606
607         printf("try open for write\n");
608         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
609         status = smb_raw_open(cli->tree, tctx, &io);
610         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
611
612         printf("try open for read\n");
613         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
614         status = smb_raw_open(cli->tree, tctx, &io);
615         CHECK_STATUS(status, NT_STATUS_OK);
616         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
617                            SEC_FILE_READ_DATA|
618                            SEC_FILE_READ_ATTRIBUTE);
619         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
620
621         printf("try open for generic write\n");
622         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
623         status = smb_raw_open(cli->tree, tctx, &io);
624         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
625
626         printf("try open for generic read\n");
627         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
628         status = smb_raw_open(cli->tree, tctx, &io);
629         CHECK_STATUS(status, NT_STATUS_OK);
630         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
631                            SEC_RIGHTS_FILE_READ);
632         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
633
634         printf("set a sec desc allowing generic read by owner\n");
635         sd = security_descriptor_dacl_create(tctx,
636                                         0, NULL, NULL,
637                                         owner_sid,
638                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
639                                         SEC_GENERIC_READ | SEC_STD_ALL,
640                                         0,
641                                         NULL);
642
643         set.set_secdesc.in.sd = sd;
644         status = smb_raw_setfileinfo(cli->tree, &set);
645         CHECK_STATUS(status, NT_STATUS_OK);
646
647         printf("check that generic read has been mapped correctly\n");
648         sd2 = security_descriptor_dacl_create(tctx,
649                                          0, owner_sid, NULL,
650                                          owner_sid,
651                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
652                                          SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
653                                          0,
654                                          NULL);
655
656         status = smb_raw_fileinfo(cli->tree, tctx, &q);
657         CHECK_STATUS(status, NT_STATUS_OK);
658         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
659                 printf("%s: security descriptors don't match!\n", __location__);
660                 printf("got:\n");
661                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
662                 printf("expected:\n");
663                 NDR_PRINT_DEBUG(security_descriptor, sd2);
664                 ret = false;
665         }
666         
667
668         printf("try open for write\n");
669         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
670         status = smb_raw_open(cli->tree, tctx, &io);
671         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
672
673         printf("try open for read\n");
674         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
675         status = smb_raw_open(cli->tree, tctx, &io);
676         CHECK_STATUS(status, NT_STATUS_OK);
677         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
678                            SEC_FILE_READ_DATA | 
679                            SEC_FILE_READ_ATTRIBUTE);
680         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
681
682         printf("try open for generic write\n");
683         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
684         status = smb_raw_open(cli->tree, tctx, &io);
685         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
686
687         printf("try open for generic read\n");
688         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
689         status = smb_raw_open(cli->tree, tctx, &io);
690         CHECK_STATUS(status, NT_STATUS_OK);
691         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, SEC_RIGHTS_FILE_READ);
692         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
693
694
695         printf("put back original sd\n");
696         set.set_secdesc.in.sd = sd_orig;
697         status = smb_raw_setfileinfo(cli->tree, &set);
698         CHECK_STATUS(status, NT_STATUS_OK);
699
700
701 done:
702         smbcli_close(cli->tree, fnum);
703         return ret;
704 }
705
706
707 /*
708   test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
709   SEC_FILE_xx bits
710 */
711 static bool test_generic_bits(struct torture_context *tctx, 
712                                                           struct smbcli_state *cli)
713 {
714         NTSTATUS status;
715         union smb_open io;
716         const char *fname = BASEDIR "\\generic.txt";
717         bool ret = true;
718         int fnum = -1, i;
719         union smb_fileinfo q;
720         union smb_setfileinfo set;
721         struct security_descriptor *sd, *sd_orig, *sd2;
722         const char *owner_sid;
723         const struct {
724                 uint32_t gen_bits;
725                 uint32_t specific_bits;
726         } file_mappings[] = {
727                 { 0,                       0 },
728                 { SEC_GENERIC_READ,        SEC_RIGHTS_FILE_READ },
729                 { SEC_GENERIC_WRITE,       SEC_RIGHTS_FILE_WRITE },
730                 { SEC_GENERIC_EXECUTE,     SEC_RIGHTS_FILE_EXECUTE },
731                 { SEC_GENERIC_ALL,         SEC_RIGHTS_FILE_ALL },
732                 { SEC_FILE_READ_DATA,      SEC_FILE_READ_DATA },
733                 { SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_ATTRIBUTE }
734         };
735         const struct {
736                 uint32_t gen_bits;
737                 uint32_t specific_bits;
738         } dir_mappings[] = {
739                 { 0,                   0 },
740                 { SEC_GENERIC_READ,    SEC_RIGHTS_DIR_READ },
741                 { SEC_GENERIC_WRITE,   SEC_RIGHTS_DIR_WRITE },
742                 { SEC_GENERIC_EXECUTE, SEC_RIGHTS_DIR_EXECUTE },
743                 { SEC_GENERIC_ALL,     SEC_RIGHTS_DIR_ALL }
744         };
745         bool has_restore_privilege;
746         bool has_take_ownership_privilege;
747
748         printf("TESTING FILE GENERIC BITS\n");
749
750         io.generic.level = RAW_OPEN_NTCREATEX;
751         io.ntcreatex.in.root_fid = 0;
752         io.ntcreatex.in.flags = 0;
753         io.ntcreatex.in.access_mask = 
754                 SEC_STD_READ_CONTROL | 
755                 SEC_STD_WRITE_DAC | 
756                 SEC_STD_WRITE_OWNER;
757         io.ntcreatex.in.create_options = 0;
758         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
759         io.ntcreatex.in.share_access = 
760                 NTCREATEX_SHARE_ACCESS_READ | 
761                 NTCREATEX_SHARE_ACCESS_WRITE;
762         io.ntcreatex.in.alloc_size = 0;
763         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
764         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
765         io.ntcreatex.in.security_flags = 0;
766         io.ntcreatex.in.fname = fname;
767         status = smb_raw_open(cli->tree, tctx, &io);
768         CHECK_STATUS(status, NT_STATUS_OK);
769         fnum = io.ntcreatex.out.file.fnum;
770
771         printf("get the original sd\n");
772         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
773         q.query_secdesc.in.file.fnum = fnum;
774         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
775         status = smb_raw_fileinfo(cli->tree, tctx, &q);
776         CHECK_STATUS(status, NT_STATUS_OK);
777         sd_orig = q.query_secdesc.out.sd;
778
779         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
780
781         status = smblsa_sid_check_privilege(cli, 
782                                             owner_sid, 
783                                             sec_privilege_name(SEC_PRIV_RESTORE));
784         has_restore_privilege = NT_STATUS_IS_OK(status);
785         if (!NT_STATUS_IS_OK(status)) {
786                 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
787         }
788         printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
789
790         status = smblsa_sid_check_privilege(cli, 
791                                             owner_sid, 
792                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
793         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
794         if (!NT_STATUS_IS_OK(status)) {
795                 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
796         }
797         printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
798
799         for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
800                 uint32_t expected_mask = 
801                         SEC_STD_WRITE_DAC | 
802                         SEC_STD_READ_CONTROL | 
803                         SEC_FILE_READ_ATTRIBUTE |
804                         SEC_STD_DELETE;
805                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
806
807                 if (has_restore_privilege) {
808                         expected_mask_anon |= SEC_STD_DELETE;
809                 }
810
811                 printf("testing generic bits 0x%08x\n", 
812                        file_mappings[i].gen_bits);
813                 sd = security_descriptor_dacl_create(tctx,
814                                                 0, owner_sid, NULL,
815                                                 owner_sid,
816                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
817                                                 file_mappings[i].gen_bits,
818                                                 0,
819                                                 NULL);
820
821                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
822                 set.set_secdesc.in.file.fnum = fnum;
823                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
824                 set.set_secdesc.in.sd = sd;
825
826                 status = smb_raw_setfileinfo(cli->tree, &set);
827                 CHECK_STATUS(status, NT_STATUS_OK);
828
829                 sd2 = security_descriptor_dacl_create(tctx,
830                                                  0, owner_sid, NULL,
831                                                  owner_sid,
832                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
833                                                  file_mappings[i].specific_bits,
834                                                  0,
835                                                  NULL);
836
837                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
838                 CHECK_STATUS(status, NT_STATUS_OK);
839                 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
840                         printf("%s: security descriptors don't match!\n", __location__);
841                         printf("got:\n");
842                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
843                         printf("expected:\n");
844                         NDR_PRINT_DEBUG(security_descriptor, sd2);
845                         ret = false;
846                 }
847
848                 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
849                 status = smb_raw_open(cli->tree, tctx, &io);
850                 CHECK_STATUS(status, NT_STATUS_OK);
851                 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
852                                    expected_mask | file_mappings[i].specific_bits);
853                 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
854
855                 if (!has_take_ownership_privilege) {
856                         continue;
857                 }
858
859                 printf("testing generic bits 0x%08x (anonymous)\n", 
860                        file_mappings[i].gen_bits);
861                 sd = security_descriptor_dacl_create(tctx,
862                                                 0, SID_NT_ANONYMOUS, NULL,
863                                                 owner_sid,
864                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
865                                                 file_mappings[i].gen_bits,
866                                                 0,
867                                                 NULL);
868
869                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
870                 set.set_secdesc.in.file.fnum = fnum;
871                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
872                 set.set_secdesc.in.sd = sd;
873
874                 status = smb_raw_setfileinfo(cli->tree, &set);
875                 CHECK_STATUS(status, NT_STATUS_OK);
876
877                 sd2 = security_descriptor_dacl_create(tctx,
878                                                  0, SID_NT_ANONYMOUS, NULL,
879                                                  owner_sid,
880                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
881                                                  file_mappings[i].specific_bits,
882                                                  0,
883                                                  NULL);
884
885                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
886                 CHECK_STATUS(status, NT_STATUS_OK);
887                 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
888                         printf("%s: security descriptors don't match!\n", __location__);
889                         printf("got:\n");
890                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
891                         printf("expected:\n");
892                         NDR_PRINT_DEBUG(security_descriptor, sd2);
893                         ret = false;
894                 }
895
896                 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
897                 status = smb_raw_open(cli->tree, tctx, &io);
898                 CHECK_STATUS(status, NT_STATUS_OK);
899                 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
900                                    expected_mask_anon | file_mappings[i].specific_bits);
901                 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
902         }
903
904         printf("put back original sd\n");
905         set.set_secdesc.in.sd = sd_orig;
906         status = smb_raw_setfileinfo(cli->tree, &set);
907         CHECK_STATUS(status, NT_STATUS_OK);
908
909         smbcli_close(cli->tree, fnum);
910         smbcli_unlink(cli->tree, fname);
911
912
913         printf("TESTING DIR GENERIC BITS\n");
914
915         io.generic.level = RAW_OPEN_NTCREATEX;
916         io.ntcreatex.in.root_fid = 0;
917         io.ntcreatex.in.flags = 0;
918         io.ntcreatex.in.access_mask = 
919                 SEC_STD_READ_CONTROL | 
920                 SEC_STD_WRITE_DAC | 
921                 SEC_STD_WRITE_OWNER;
922         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
923         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
924         io.ntcreatex.in.share_access = 
925                 NTCREATEX_SHARE_ACCESS_READ | 
926                 NTCREATEX_SHARE_ACCESS_WRITE;
927         io.ntcreatex.in.alloc_size = 0;
928         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
929         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
930         io.ntcreatex.in.security_flags = 0;
931         io.ntcreatex.in.fname = fname;
932         status = smb_raw_open(cli->tree, tctx, &io);
933         CHECK_STATUS(status, NT_STATUS_OK);
934         fnum = io.ntcreatex.out.file.fnum;
935
936         printf("get the original sd\n");
937         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
938         q.query_secdesc.in.file.fnum = fnum;
939         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
940         status = smb_raw_fileinfo(cli->tree, tctx, &q);
941         CHECK_STATUS(status, NT_STATUS_OK);
942         sd_orig = q.query_secdesc.out.sd;
943
944         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
945
946         status = smblsa_sid_check_privilege(cli, 
947                                             owner_sid, 
948                                             sec_privilege_name(SEC_PRIV_RESTORE));
949         has_restore_privilege = NT_STATUS_IS_OK(status);
950         if (!NT_STATUS_IS_OK(status)) {
951                 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
952         }
953         printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
954
955         status = smblsa_sid_check_privilege(cli, 
956                                             owner_sid, 
957                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
958         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
959         if (!NT_STATUS_IS_OK(status)) {
960                 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
961         }
962         printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
963
964         for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
965                 uint32_t expected_mask = 
966                         SEC_STD_WRITE_DAC | 
967                         SEC_STD_READ_CONTROL | 
968                         SEC_FILE_READ_ATTRIBUTE |
969                         SEC_STD_DELETE;
970                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
971
972                 if (has_restore_privilege) {
973                         expected_mask_anon |= SEC_STD_DELETE;
974                 }
975
976                 printf("testing generic bits 0x%08x\n", 
977                        file_mappings[i].gen_bits);
978                 sd = security_descriptor_dacl_create(tctx,
979                                                 0, owner_sid, NULL,
980                                                 owner_sid,
981                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
982                                                 dir_mappings[i].gen_bits,
983                                                 0,
984                                                 NULL);
985
986                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
987                 set.set_secdesc.in.file.fnum = fnum;
988                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
989                 set.set_secdesc.in.sd = sd;
990
991                 status = smb_raw_setfileinfo(cli->tree, &set);
992                 CHECK_STATUS(status, NT_STATUS_OK);
993
994                 sd2 = security_descriptor_dacl_create(tctx,
995                                                  0, owner_sid, NULL,
996                                                  owner_sid,
997                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
998                                                  dir_mappings[i].specific_bits,
999                                                  0,
1000                                                  NULL);
1001
1002                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1003                 CHECK_STATUS(status, NT_STATUS_OK);
1004                 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
1005                         printf("%s: security descriptors don't match!\n", __location__);
1006                         printf("got:\n");
1007                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1008                         printf("expected:\n");
1009                         NDR_PRINT_DEBUG(security_descriptor, sd2);
1010                         ret = false;
1011                 }
1012
1013                 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1014                 status = smb_raw_open(cli->tree, tctx, &io);
1015                 CHECK_STATUS(status, NT_STATUS_OK);
1016                 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
1017                                    expected_mask | dir_mappings[i].specific_bits);
1018                 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1019
1020                 if (!has_take_ownership_privilege) {
1021                         continue;
1022                 }
1023
1024                 printf("testing generic bits 0x%08x (anonymous)\n", 
1025                        file_mappings[i].gen_bits);
1026                 sd = security_descriptor_dacl_create(tctx,
1027                                                 0, SID_NT_ANONYMOUS, NULL,
1028                                                 owner_sid,
1029                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1030                                                 file_mappings[i].gen_bits,
1031                                                 0,
1032                                                 NULL);
1033
1034                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1035                 set.set_secdesc.in.file.fnum = fnum;
1036                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1037                 set.set_secdesc.in.sd = sd;
1038
1039                 status = smb_raw_setfileinfo(cli->tree, &set);
1040                 CHECK_STATUS(status, NT_STATUS_OK);
1041
1042                 sd2 = security_descriptor_dacl_create(tctx,
1043                                                  0, SID_NT_ANONYMOUS, NULL,
1044                                                  owner_sid,
1045                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
1046                                                  file_mappings[i].specific_bits,
1047                                                  0,
1048                                                  NULL);
1049
1050                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1051                 CHECK_STATUS(status, NT_STATUS_OK);
1052                 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
1053                         printf("%s: security descriptors don't match!\n", __location__);
1054                         printf("got:\n");
1055                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1056                         printf("expected:\n");
1057                         NDR_PRINT_DEBUG(security_descriptor, sd2);
1058                         ret = false;
1059                 }
1060
1061                 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1062                 status = smb_raw_open(cli->tree, tctx, &io);
1063                 CHECK_STATUS(status, NT_STATUS_OK);
1064                 CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, 
1065                                    expected_mask_anon | dir_mappings[i].specific_bits);
1066                 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1067         }
1068
1069         printf("put back original sd\n");
1070         set.set_secdesc.in.sd = sd_orig;
1071         status = smb_raw_setfileinfo(cli->tree, &set);
1072         CHECK_STATUS(status, NT_STATUS_OK);
1073
1074         smbcli_close(cli->tree, fnum);
1075         smbcli_unlink(cli->tree, fname);
1076
1077 done:
1078         smbcli_close(cli->tree, fnum);
1079         return ret;
1080 }
1081
1082
1083 /*
1084   see what access bits the owner of a file always gets
1085 */
1086 static bool test_owner_bits(struct torture_context *tctx, 
1087                                                         struct smbcli_state *cli)
1088 {
1089         NTSTATUS status;
1090         union smb_open io;
1091         const char *fname = BASEDIR "\\test_owner_bits.txt";
1092         bool ret = true;
1093         int fnum = -1, i;
1094         union smb_fileinfo q;
1095         union smb_setfileinfo set;
1096         struct security_descriptor *sd, *sd_orig;
1097         const char *owner_sid;
1098         bool has_restore_privilege;
1099         bool has_take_ownership_privilege;
1100         uint32_t expected_bits;
1101
1102         printf("TESTING FILE OWNER BITS\n");
1103
1104         io.generic.level = RAW_OPEN_NTCREATEX;
1105         io.ntcreatex.in.root_fid = 0;
1106         io.ntcreatex.in.flags = 0;
1107         io.ntcreatex.in.access_mask = 
1108                 SEC_STD_READ_CONTROL | 
1109                 SEC_STD_WRITE_DAC | 
1110                 SEC_STD_WRITE_OWNER;
1111         io.ntcreatex.in.create_options = 0;
1112         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1113         io.ntcreatex.in.share_access = 
1114                 NTCREATEX_SHARE_ACCESS_READ | 
1115                 NTCREATEX_SHARE_ACCESS_WRITE;
1116         io.ntcreatex.in.alloc_size = 0;
1117         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1118         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1119         io.ntcreatex.in.security_flags = 0;
1120         io.ntcreatex.in.fname = fname;
1121         status = smb_raw_open(cli->tree, tctx, &io);
1122         CHECK_STATUS(status, NT_STATUS_OK);
1123         fnum = io.ntcreatex.out.file.fnum;
1124
1125         printf("get the original sd\n");
1126         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1127         q.query_secdesc.in.file.fnum = fnum;
1128         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1129         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1130         CHECK_STATUS(status, NT_STATUS_OK);
1131         sd_orig = q.query_secdesc.out.sd;
1132
1133         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1134
1135         status = smblsa_sid_check_privilege(cli, 
1136                                             owner_sid, 
1137                                             sec_privilege_name(SEC_PRIV_RESTORE));
1138         has_restore_privilege = NT_STATUS_IS_OK(status);
1139         if (!NT_STATUS_IS_OK(status)) {
1140                 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
1141         }
1142         printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
1143
1144         status = smblsa_sid_check_privilege(cli, 
1145                                             owner_sid, 
1146                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
1147         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
1148         if (!NT_STATUS_IS_OK(status)) {
1149                 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
1150         }
1151         printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
1152
1153         sd = security_descriptor_dacl_create(tctx,
1154                                         0, NULL, NULL,
1155                                         owner_sid,
1156                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1157                                         SEC_FILE_WRITE_DATA,
1158                                         0,
1159                                         NULL);
1160
1161         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1162         set.set_secdesc.in.file.fnum = fnum;
1163         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1164         set.set_secdesc.in.sd = sd;
1165
1166         status = smb_raw_setfileinfo(cli->tree, &set);
1167         CHECK_STATUS(status, NT_STATUS_OK);
1168
1169         expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
1170
1171         for (i=0;i<16;i++) {
1172                 uint32_t bit = (1<<i);
1173                 io.ntcreatex.in.access_mask = bit;
1174                 status = smb_raw_open(cli->tree, tctx, &io);
1175                 if (expected_bits & bit) {
1176                         if (!NT_STATUS_IS_OK(status)) {
1177                                 printf("failed with access mask 0x%08x of expected 0x%08x\n",
1178                                        bit, expected_bits);
1179                         }
1180                         CHECK_STATUS(status, NT_STATUS_OK);
1181                         CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, bit | SEC_FILE_READ_ATTRIBUTE);
1182                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1183                 } else {
1184                         if (NT_STATUS_IS_OK(status)) {
1185                                 printf("open succeeded with access mask 0x%08x of "
1186                                         "expected 0x%08x - should fail\n",
1187                                        bit, expected_bits);
1188                         }
1189                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1190                 }
1191         }
1192
1193         printf("put back original sd\n");
1194         set.set_secdesc.in.sd = sd_orig;
1195         status = smb_raw_setfileinfo(cli->tree, &set);
1196         CHECK_STATUS(status, NT_STATUS_OK);
1197
1198 done:
1199         smbcli_close(cli->tree, fnum);
1200         smbcli_unlink(cli->tree, fname);
1201         return ret;
1202 }
1203
1204
1205
1206 /*
1207   test the inheritance of ACL flags onto new files and directories
1208 */
1209 static bool test_inheritance(struct torture_context *tctx, 
1210                                                          struct smbcli_state *cli)
1211 {
1212         NTSTATUS status;
1213         union smb_open io;
1214         const char *dname = BASEDIR "\\inheritance";
1215         const char *fname1 = BASEDIR "\\inheritance\\testfile";
1216         const char *fname2 = BASEDIR "\\inheritance\\testdir";
1217         bool ret = true;
1218         int fnum=0, fnum2, i;
1219         union smb_fileinfo q;
1220         union smb_setfileinfo set;
1221         struct security_descriptor *sd, *sd2, *sd_orig=NULL, *sd_def;
1222         const char *owner_sid;
1223         const struct dom_sid *creator_owner;
1224         const struct {
1225                 uint32_t parent_flags;
1226                 uint32_t file_flags;
1227                 uint32_t dir_flags;
1228         } test_flags[] = {
1229                 {
1230                         0, 
1231                         0,
1232                         0
1233                 },
1234                 {
1235                         SEC_ACE_FLAG_OBJECT_INHERIT,
1236                         0,
1237                         SEC_ACE_FLAG_OBJECT_INHERIT | 
1238                         SEC_ACE_FLAG_INHERIT_ONLY,
1239                 },
1240                 {
1241                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1242                         0,
1243                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1244                 },
1245                 {
1246                         SEC_ACE_FLAG_OBJECT_INHERIT | 
1247                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1248                         0,
1249                         SEC_ACE_FLAG_OBJECT_INHERIT | 
1250                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1251                 },
1252                 {
1253                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
1254                         0,
1255                         0,
1256                 },
1257                 {
1258                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1259                         SEC_ACE_FLAG_OBJECT_INHERIT,
1260                         0,
1261                         0,
1262                 },
1263                 {
1264                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1265                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1266                         0,
1267                         0,
1268                 },
1269                 {
1270                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1271                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
1272                         SEC_ACE_FLAG_OBJECT_INHERIT,
1273                         0,
1274                         0,
1275                 },
1276                 {
1277                         SEC_ACE_FLAG_INHERIT_ONLY,
1278                         0,
1279                         0,
1280                 },
1281                 {
1282                         SEC_ACE_FLAG_INHERIT_ONLY | 
1283                         SEC_ACE_FLAG_OBJECT_INHERIT,
1284                         0,
1285                         SEC_ACE_FLAG_OBJECT_INHERIT | 
1286                         SEC_ACE_FLAG_INHERIT_ONLY,
1287                 },
1288                 {
1289                         SEC_ACE_FLAG_INHERIT_ONLY | 
1290                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1291                         0,
1292                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1293                 },
1294                 {
1295                         SEC_ACE_FLAG_INHERIT_ONLY | 
1296                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
1297                         SEC_ACE_FLAG_OBJECT_INHERIT,
1298                         0,
1299                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
1300                         SEC_ACE_FLAG_OBJECT_INHERIT,
1301                 },
1302                 {
1303                         SEC_ACE_FLAG_INHERIT_ONLY | 
1304                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
1305                         0,
1306                         0,
1307                 },
1308                 {
1309                         SEC_ACE_FLAG_INHERIT_ONLY | 
1310                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1311                         SEC_ACE_FLAG_OBJECT_INHERIT,
1312                         0,
1313                         0,
1314                 },
1315                 {
1316                         SEC_ACE_FLAG_INHERIT_ONLY | 
1317                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1318                         SEC_ACE_FLAG_CONTAINER_INHERIT,
1319                         0,
1320                         0,
1321                 },
1322                 {
1323                         SEC_ACE_FLAG_INHERIT_ONLY | 
1324                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
1325                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
1326                         SEC_ACE_FLAG_OBJECT_INHERIT,
1327                         0,
1328                         0,
1329                 }
1330         };
1331
1332         smbcli_rmdir(cli->tree, dname);
1333
1334         printf("TESTING ACL INHERITANCE\n");
1335
1336         io.generic.level = RAW_OPEN_NTCREATEX;
1337         io.ntcreatex.in.root_fid = 0;
1338         io.ntcreatex.in.flags = 0;
1339         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1340         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1341         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1342         io.ntcreatex.in.share_access = 0;
1343         io.ntcreatex.in.alloc_size = 0;
1344         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1345         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1346         io.ntcreatex.in.security_flags = 0;
1347         io.ntcreatex.in.fname = dname;
1348
1349         status = smb_raw_open(cli->tree, tctx, &io);
1350         CHECK_STATUS(status, NT_STATUS_OK);
1351         fnum = io.ntcreatex.out.file.fnum;
1352
1353         printf("get the original sd\n");
1354         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1355         q.query_secdesc.in.file.fnum = fnum;
1356         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1357         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1358         CHECK_STATUS(status, NT_STATUS_OK);
1359         sd_orig = q.query_secdesc.out.sd;
1360
1361         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1362
1363         printf("owner_sid is %s\n", owner_sid);
1364
1365         sd_def = security_descriptor_dacl_create(tctx,
1366                                             0, owner_sid, NULL,
1367                                             owner_sid,
1368                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
1369                                             SEC_RIGHTS_FILE_ALL,
1370                                             0,
1371                                             SID_NT_SYSTEM,
1372                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
1373                                             SEC_RIGHTS_FILE_ALL,
1374                                             0,
1375                                             NULL);
1376
1377         creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER);
1378
1379         for (i=0;i<ARRAY_SIZE(test_flags);i++) {
1380                 sd = security_descriptor_dacl_create(tctx,
1381                                                 0, NULL, NULL,
1382                                                 SID_CREATOR_OWNER,
1383                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1384                                                 SEC_FILE_WRITE_DATA,
1385                                                 test_flags[i].parent_flags,
1386                                                 SID_WORLD,
1387                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1388                                                 SEC_FILE_ALL | SEC_STD_ALL,
1389                                                 0,
1390                                                 NULL);
1391                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1392                 set.set_secdesc.in.file.fnum = fnum;
1393                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1394                 set.set_secdesc.in.sd = sd;
1395                 status = smb_raw_setfileinfo(cli->tree, &set);
1396                 CHECK_STATUS(status, NT_STATUS_OK);
1397
1398                 io.ntcreatex.in.fname = fname1;
1399                 io.ntcreatex.in.create_options = 0;
1400                 status = smb_raw_open(cli->tree, tctx, &io);
1401                 CHECK_STATUS(status, NT_STATUS_OK);
1402                 fnum2 = io.ntcreatex.out.file.fnum;
1403
1404                 q.query_secdesc.in.file.fnum = fnum2;
1405                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1406                 CHECK_STATUS(status, NT_STATUS_OK);
1407
1408                 smbcli_close(cli->tree, fnum2);
1409                 smbcli_unlink(cli->tree, fname1);
1410
1411                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
1412                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1413                                 printf("Expected default sd:\n");
1414                                 NDR_PRINT_DEBUG(security_descriptor, sd_def);
1415                                 printf("at %d - got:\n", i);
1416                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1417                         }
1418                         goto check_dir;
1419                 }
1420
1421                 if (q.query_secdesc.out.sd->dacl == NULL ||
1422                     q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1423                     q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1424                     !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1425                                    sd_orig->owner_sid)) {
1426                         printf("Bad sd in child file at %d\n", i);
1427                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1428                         ret = false;
1429                         goto check_dir;
1430                 }
1431
1432                 if (q.query_secdesc.out.sd->dacl->aces[0].flags != 
1433                     test_flags[i].file_flags) {
1434                         printf("incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
1435                                q.query_secdesc.out.sd->dacl->aces[0].flags,
1436                                test_flags[i].file_flags,
1437                                test_flags[i].parent_flags,
1438                                i);
1439                         ret = false;
1440                 }
1441
1442         check_dir:
1443                 io.ntcreatex.in.fname = fname2;
1444                 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1445                 status = smb_raw_open(cli->tree, tctx, &io);
1446                 CHECK_STATUS(status, NT_STATUS_OK);
1447                 fnum2 = io.ntcreatex.out.file.fnum;
1448
1449                 q.query_secdesc.in.file.fnum = fnum2;
1450                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1451                 CHECK_STATUS(status, NT_STATUS_OK);
1452
1453                 smbcli_close(cli->tree, fnum2);
1454                 smbcli_rmdir(cli->tree, fname2);
1455
1456                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1457                     (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
1458                      (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
1459                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1460                                 printf("Expected default sd for dir at %d:\n", i);
1461                                 NDR_PRINT_DEBUG(security_descriptor, sd_def);
1462                                 printf("got:\n");
1463                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1464                         }
1465                         continue;
1466                 }
1467
1468                 if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) && 
1469                     (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
1470                         if (q.query_secdesc.out.sd->dacl == NULL ||
1471                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1472                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1473                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1474                                            sd_orig->owner_sid) ||
1475                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1476                                 printf("(CI & NP) Bad sd in child dir at %d (parent 0x%x)\n", 
1477                                        i, test_flags[i].parent_flags);
1478                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1479                                 ret = false;
1480                                 continue;
1481                         }
1482                 } else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
1483                         if (q.query_secdesc.out.sd->dacl == NULL ||
1484                             q.query_secdesc.out.sd->dacl->num_aces != 2 ||
1485                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1486                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1487                                            sd_orig->owner_sid) ||
1488                             q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
1489                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
1490                                            creator_owner) ||
1491                             q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
1492                             q.query_secdesc.out.sd->dacl->aces[1].flags != 
1493                             (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
1494                                 printf("(CI) Bad sd in child dir at %d (parent 0x%x)\n", 
1495                                        i, test_flags[i].parent_flags);
1496                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1497                                 ret = false;
1498                                 continue;
1499                         }
1500                 } else {
1501                         if (q.query_secdesc.out.sd->dacl == NULL ||
1502                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1503                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1504                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1505                                            creator_owner) ||
1506                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1507                                 printf("(0) Bad sd in child dir at %d (parent 0x%x)\n", 
1508                                         i, test_flags[i].parent_flags);
1509                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1510                                 ret = false;
1511                                 continue;
1512                         }
1513                 }
1514         }
1515
1516         printf("testing access checks on inherited create with %s\n", fname1);
1517         sd = security_descriptor_dacl_create(tctx,
1518                                         0, NULL, NULL,
1519                                         owner_sid,
1520                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1521                                         SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1522                                         SEC_ACE_FLAG_OBJECT_INHERIT,
1523                                         SID_WORLD,
1524                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1525                                         SEC_FILE_ALL | SEC_STD_ALL,
1526                                         0,
1527                                         NULL);
1528         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1529         set.set_secdesc.in.file.fnum = fnum;
1530         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1531         set.set_secdesc.in.sd = sd;
1532         status = smb_raw_setfileinfo(cli->tree, &set);
1533         CHECK_STATUS(status, NT_STATUS_OK);
1534
1535         io.ntcreatex.in.fname = fname1;
1536         io.ntcreatex.in.create_options = 0;
1537         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1538         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1539         status = smb_raw_open(cli->tree, tctx, &io);
1540         CHECK_STATUS(status, NT_STATUS_OK);
1541         fnum2 = io.ntcreatex.out.file.fnum;
1542         CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1543
1544         q.query_secdesc.in.file.fnum = fnum2;
1545         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1546         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1547         CHECK_STATUS(status, NT_STATUS_OK);
1548         smbcli_close(cli->tree, fnum2);
1549
1550         sd2 = security_descriptor_dacl_create(tctx,
1551                                          0, owner_sid, NULL,
1552                                          owner_sid,
1553                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1554                                          SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1555                                          0,
1556                                          NULL);
1557         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
1558                 printf("%s: security descriptors don't match!\n", __location__);
1559                 printf("got:\n");
1560                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1561                 printf("expected:\n");
1562                 NDR_PRINT_DEBUG(security_descriptor, sd2);
1563                 ret = false;
1564         }
1565
1566         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1567         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1568         status = smb_raw_open(cli->tree, tctx, &io);
1569         if (NT_STATUS_IS_OK(status)) {
1570                 printf("failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
1571                 ret = false;
1572                 fnum2 = io.ntcreatex.out.file.fnum;
1573                 CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1574                 smbcli_close(cli->tree, fnum2);
1575         } else {
1576                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1577         }
1578
1579         printf("trying without execute\n");
1580         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1581         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
1582         status = smb_raw_open(cli->tree, tctx, &io);
1583         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1584
1585         printf("and with full permissions again\n");
1586         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1587         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1588         status = smb_raw_open(cli->tree, tctx, &io);
1589         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1590
1591         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1592         status = smb_raw_open(cli->tree, tctx, &io);
1593         CHECK_STATUS(status, NT_STATUS_OK);
1594         fnum2 = io.ntcreatex.out.file.fnum;
1595         CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1596         smbcli_close(cli->tree, fnum2);
1597
1598         printf("put back original sd\n");
1599         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1600         set.set_secdesc.in.file.fnum = fnum;
1601         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1602         set.set_secdesc.in.sd = sd_orig;
1603         status = smb_raw_setfileinfo(cli->tree, &set);
1604         CHECK_STATUS(status, NT_STATUS_OK);
1605
1606         smbcli_close(cli->tree, fnum);
1607
1608         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1609         status = smb_raw_open(cli->tree, tctx, &io);
1610         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1611
1612         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1613         status = smb_raw_open(cli->tree, tctx, &io);
1614         CHECK_STATUS(status, NT_STATUS_OK);
1615         fnum2 = io.ntcreatex.out.file.fnum;
1616         CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1617         smbcli_close(cli->tree, fnum2);
1618
1619         smbcli_unlink(cli->tree, fname1);
1620         smbcli_rmdir(cli->tree, dname);
1621
1622 done:
1623         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1624         set.set_secdesc.in.file.fnum = fnum;
1625         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1626         set.set_secdesc.in.sd = sd_orig;
1627         status = smb_raw_setfileinfo(cli->tree, &set);
1628
1629         smbcli_close(cli->tree, fnum);
1630         return ret;
1631 }
1632
1633
1634 /*
1635   test dynamic acl inheritance
1636 */
1637 static bool test_inheritance_dynamic(struct torture_context *tctx, 
1638                                                                          struct smbcli_state *cli)
1639 {
1640         NTSTATUS status;
1641         union smb_open io;
1642         const char *dname = BASEDIR "\\inheritance";
1643         const char *fname1 = BASEDIR "\\inheritance\\testfile";
1644         bool ret = true;
1645         int fnum=0, fnum2;
1646         union smb_fileinfo q;
1647         union smb_setfileinfo set;
1648         struct security_descriptor *sd, *sd_orig=NULL;
1649         const char *owner_sid;
1650         
1651         printf("TESTING DYNAMIC ACL INHERITANCE\n");
1652
1653         if (!torture_setup_dir(cli, BASEDIR)) {
1654                 return false;
1655         }
1656
1657         io.generic.level = RAW_OPEN_NTCREATEX;
1658         io.ntcreatex.in.root_fid = 0;
1659         io.ntcreatex.in.flags = 0;
1660         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1661         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1662         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1663         io.ntcreatex.in.share_access = 0;
1664         io.ntcreatex.in.alloc_size = 0;
1665         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1666         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1667         io.ntcreatex.in.security_flags = 0;
1668         io.ntcreatex.in.fname = dname;
1669
1670         status = smb_raw_open(cli->tree, tctx, &io);
1671         CHECK_STATUS(status, NT_STATUS_OK);
1672         fnum = io.ntcreatex.out.file.fnum;
1673
1674         printf("get the original sd\n");
1675         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1676         q.query_secdesc.in.file.fnum = fnum;
1677         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1678         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1679         CHECK_STATUS(status, NT_STATUS_OK);
1680         sd_orig = q.query_secdesc.out.sd;
1681
1682         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1683
1684         printf("owner_sid is %s\n", owner_sid);
1685
1686         sd = security_descriptor_dacl_create(tctx,
1687                                         0, NULL, NULL,
1688                                         owner_sid,
1689                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1690                                         SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
1691                                         SEC_ACE_FLAG_OBJECT_INHERIT,
1692                                         NULL);
1693         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1694
1695         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1696         set.set_secdesc.in.file.fnum = fnum;
1697         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1698         set.set_secdesc.in.sd = sd;
1699         status = smb_raw_setfileinfo(cli->tree, &set);
1700         CHECK_STATUS(status, NT_STATUS_OK);
1701
1702         printf("create a file with an inherited acl\n");
1703         io.ntcreatex.in.fname = fname1;
1704         io.ntcreatex.in.create_options = 0;
1705         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE;
1706         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1707         status = smb_raw_open(cli->tree, tctx, &io);
1708         CHECK_STATUS(status, NT_STATUS_OK);
1709         fnum2 = io.ntcreatex.out.file.fnum;
1710         smbcli_close(cli->tree, fnum2);
1711
1712         printf("try and access file with base rights - should be OK\n");
1713         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1714         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1715         status = smb_raw_open(cli->tree, tctx, &io);
1716         CHECK_STATUS(status, NT_STATUS_OK);
1717         fnum2 = io.ntcreatex.out.file.fnum;
1718         smbcli_close(cli->tree, fnum2);
1719
1720         printf("try and access file with extra rights - should be denied\n");
1721         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1722         status = smb_raw_open(cli->tree, tctx, &io);
1723         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1724
1725         printf("update parent sd\n");
1726         sd = security_descriptor_dacl_create(tctx,
1727                                         0, NULL, NULL,
1728                                         owner_sid,
1729                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1730                                         SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE,
1731                                         SEC_ACE_FLAG_OBJECT_INHERIT,
1732                                         NULL);
1733         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1734
1735         set.set_secdesc.in.sd = sd;
1736         status = smb_raw_setfileinfo(cli->tree, &set);
1737         CHECK_STATUS(status, NT_STATUS_OK);
1738
1739         printf("try and access file with base rights - should be OK\n");
1740         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1741         status = smb_raw_open(cli->tree, tctx, &io);
1742         CHECK_STATUS(status, NT_STATUS_OK);
1743         fnum2 = io.ntcreatex.out.file.fnum;
1744         smbcli_close(cli->tree, fnum2);
1745
1746
1747         printf("try and access now - should be OK if dynamic inheritance works\n");
1748         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1749         status = smb_raw_open(cli->tree, tctx, &io);
1750         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1751                 printf("Server does not have dynamic inheritance\n");
1752         }
1753         if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1754                 printf("Server does have dynamic inheritance\n");
1755         }
1756         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1757
1758         smbcli_unlink(cli->tree, fname1);
1759
1760 done:
1761         printf("put back original sd\n");
1762         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1763         set.set_secdesc.in.file.fnum = fnum;
1764         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1765         set.set_secdesc.in.sd = sd_orig;
1766         status = smb_raw_setfileinfo(cli->tree, &set);
1767
1768         smbcli_close(cli->tree, fnum);
1769         smbcli_rmdir(cli->tree, dname);
1770
1771         return ret;
1772 }
1773
1774 #define CHECK_STATUS_FOR_BIT_ACTION(status, bits, action) do { \
1775         if (!(bits & desired_64)) {\
1776                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); \
1777                 action; \
1778         } else { \
1779                 CHECK_STATUS(status, NT_STATUS_OK); \
1780         } \
1781 } while (0)
1782
1783 #define CHECK_STATUS_FOR_BIT(status, bits, access) do { \
1784         if (NT_STATUS_IS_OK(status)) { \
1785                 if (!(granted & access)) {\
1786                         printf("(%s) %s but flags 0x%08X are not granted! granted[0x%08X] desired[0x%08X]\n", \
1787                                __location__, nt_errstr(status), access, granted, desired); \
1788                         ret = false; \
1789                         goto done; \
1790                 } \
1791         } else { \
1792                 if (granted & access) {\
1793                         printf("(%s) %s but flags 0x%08X are granted! granted[0x%08X] desired[0x%08X]\n", \
1794                                __location__, nt_errstr(status), access, granted, desired); \
1795                         ret = false; \
1796                         goto done; \
1797                 } \
1798         } \
1799         CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \
1800 } while (0)
1801
1802 /* test what access mask is needed for getting and setting security_descriptors */
1803 static bool test_sd_get_set(struct torture_context *tctx, 
1804                                                         struct smbcli_state *cli)
1805 {
1806         NTSTATUS status;
1807         bool ret = true;
1808         union smb_open io;
1809         union smb_fileinfo fi;
1810         union smb_setfileinfo si;
1811         struct security_descriptor *sd;
1812         struct security_descriptor *sd_owner = NULL;
1813         struct security_descriptor *sd_group = NULL;
1814         struct security_descriptor *sd_dacl = NULL;
1815         struct security_descriptor *sd_sacl = NULL;
1816         int fnum=0;
1817         const char *fname = BASEDIR "\\sd_get_set.txt";
1818         uint64_t desired_64;
1819         uint32_t desired = 0, granted;
1820         int i = 0;
1821 #define NO_BITS_HACK (((uint64_t)1)<<32)
1822         uint64_t open_bits =
1823                 SEC_MASK_GENERIC |
1824                 SEC_FLAG_SYSTEM_SECURITY |
1825                 SEC_FLAG_MAXIMUM_ALLOWED |
1826                 SEC_STD_ALL |
1827                 SEC_FILE_ALL | 
1828                 NO_BITS_HACK;
1829         uint64_t get_owner_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1830         uint64_t set_owner_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
1831         uint64_t get_group_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1832         uint64_t set_group_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
1833         uint64_t get_dacl_bits  = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1834         uint64_t set_dacl_bits  = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_DAC;
1835         uint64_t get_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
1836         uint64_t set_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
1837
1838         printf("TESTING ACCESS MASKS FOR SD GET/SET\n");
1839
1840         /* first create a file with full access for everyone */
1841         sd = security_descriptor_dacl_create(tctx,
1842                                         0, SID_NT_ANONYMOUS, SID_BUILTIN_USERS,
1843                                         SID_WORLD,
1844                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1845                                         SEC_GENERIC_ALL,
1846                                         0,
1847                                         NULL);
1848         sd->type |= SEC_DESC_SACL_PRESENT;
1849         sd->sacl = NULL;
1850         io.ntcreatex.level = RAW_OPEN_NTTRANS_CREATE;
1851         io.ntcreatex.in.root_fid = 0;
1852         io.ntcreatex.in.flags = 0;
1853         io.ntcreatex.in.access_mask = SEC_GENERIC_ALL;
1854         io.ntcreatex.in.create_options = 0;
1855         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1856         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1857         io.ntcreatex.in.alloc_size = 0;
1858         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1859         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1860         io.ntcreatex.in.security_flags = 0;
1861         io.ntcreatex.in.fname = fname;
1862         io.ntcreatex.in.sec_desc = sd;
1863         io.ntcreatex.in.ea_list = NULL;
1864         status = smb_raw_open(cli->tree, tctx, &io);
1865         CHECK_STATUS(status, NT_STATUS_OK);
1866         fnum = io.ntcreatex.out.file.fnum;
1867
1868         status = smbcli_close(cli->tree, fnum);
1869         CHECK_STATUS(status, NT_STATUS_OK);
1870
1871         /* 
1872          * now try each access_mask bit and no bit at all in a loop
1873          * and see what's allowed
1874          * NOTE: if i == 32 it means access_mask = 0 (see NO_BITS_HACK above)
1875          */
1876         for (i=0; i <= 32; i++) {
1877                 desired_64 = ((uint64_t)1) << i;
1878                 desired = (uint32_t)desired_64;
1879
1880                 /* first open the file with the desired access */
1881                 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
1882                 io.ntcreatex.in.access_mask = desired;
1883                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1884                 status = smb_raw_open(cli->tree, tctx, &io);
1885                 CHECK_STATUS_FOR_BIT_ACTION(status, open_bits, goto next);
1886                 fnum = io.ntcreatex.out.file.fnum;
1887
1888                 /* then check what access was granted */
1889                 fi.access_information.level             = RAW_FILEINFO_ACCESS_INFORMATION;
1890                 fi.access_information.in.file.fnum      = fnum;
1891                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1892                 CHECK_STATUS(status, NT_STATUS_OK);
1893                 granted = fi.access_information.out.access_flags;
1894
1895                 /* test the owner */
1896                 ZERO_STRUCT(fi);
1897                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
1898                 fi.query_secdesc.in.file.fnum           = fnum;
1899                 fi.query_secdesc.in.secinfo_flags       = SECINFO_OWNER;
1900                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1901                 CHECK_STATUS_FOR_BIT(status, get_owner_bits, SEC_STD_READ_CONTROL);
1902                 if (fi.query_secdesc.out.sd) {
1903                         sd_owner = fi.query_secdesc.out.sd;
1904                 } else if (!sd_owner) {
1905                         sd_owner = sd;
1906                 }
1907                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
1908                 si.set_secdesc.in.file.fnum             = fnum;
1909                 si.set_secdesc.in.secinfo_flags         = SECINFO_OWNER;
1910                 si.set_secdesc.in.sd                    = sd_owner;
1911                 status = smb_raw_setfileinfo(cli->tree, &si);
1912                 CHECK_STATUS_FOR_BIT(status, set_owner_bits, SEC_STD_WRITE_OWNER);
1913
1914                 /* test the group */
1915                 ZERO_STRUCT(fi);
1916                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
1917                 fi.query_secdesc.in.file.fnum           = fnum;
1918                 fi.query_secdesc.in.secinfo_flags       = SECINFO_GROUP;
1919                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1920                 CHECK_STATUS_FOR_BIT(status, get_group_bits, SEC_STD_READ_CONTROL);
1921                 if (fi.query_secdesc.out.sd) {
1922                         sd_group = fi.query_secdesc.out.sd;
1923                 } else if (!sd_group) {
1924                         sd_group = sd;
1925                 }
1926                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
1927                 si.set_secdesc.in.file.fnum             = fnum;
1928                 si.set_secdesc.in.secinfo_flags         = SECINFO_GROUP;
1929                 si.set_secdesc.in.sd                    = sd_group;
1930                 status = smb_raw_setfileinfo(cli->tree, &si);
1931                 CHECK_STATUS_FOR_BIT(status, set_group_bits, SEC_STD_WRITE_OWNER);
1932
1933                 /* test the DACL */
1934                 ZERO_STRUCT(fi);
1935                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
1936                 fi.query_secdesc.in.file.fnum           = fnum;
1937                 fi.query_secdesc.in.secinfo_flags       = SECINFO_DACL;
1938                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1939                 CHECK_STATUS_FOR_BIT(status, get_dacl_bits, SEC_STD_READ_CONTROL);
1940                 if (fi.query_secdesc.out.sd) {
1941                         sd_dacl = fi.query_secdesc.out.sd;
1942                 } else if (!sd_dacl) {
1943                         sd_dacl = sd;
1944                 }
1945                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
1946                 si.set_secdesc.in.file.fnum             = fnum;
1947                 si.set_secdesc.in.secinfo_flags         = SECINFO_DACL;
1948                 si.set_secdesc.in.sd                    = sd_dacl;
1949                 status = smb_raw_setfileinfo(cli->tree, &si);
1950                 CHECK_STATUS_FOR_BIT(status, set_dacl_bits, SEC_STD_WRITE_DAC);
1951
1952                 /* test the SACL */
1953                 ZERO_STRUCT(fi);
1954                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
1955                 fi.query_secdesc.in.file.fnum           = fnum;
1956                 fi.query_secdesc.in.secinfo_flags       = SECINFO_SACL;
1957                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1958                 CHECK_STATUS_FOR_BIT(status, get_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
1959                 if (fi.query_secdesc.out.sd) {
1960                         sd_sacl = fi.query_secdesc.out.sd;
1961                 } else if (!sd_sacl) {
1962                         sd_sacl = sd;
1963                 }
1964                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
1965                 si.set_secdesc.in.file.fnum             = fnum;
1966                 si.set_secdesc.in.secinfo_flags         = SECINFO_SACL;
1967                 si.set_secdesc.in.sd                    = sd_sacl;
1968                 status = smb_raw_setfileinfo(cli->tree, &si);
1969                 CHECK_STATUS_FOR_BIT(status, set_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
1970
1971                 /* close the handle */
1972                 status = smbcli_close(cli->tree, fnum);
1973                 CHECK_STATUS(status, NT_STATUS_OK);
1974 next:
1975                 continue;
1976         }
1977
1978 done:
1979         smbcli_close(cli->tree, fnum);
1980         smbcli_unlink(cli->tree, fname);
1981
1982         return ret;
1983 }
1984
1985
1986 /* 
1987    basic testing of security descriptor calls
1988 */
1989 bool torture_raw_acls(struct torture_context *tctx, struct smbcli_state *cli)
1990 {
1991         bool ret = true;
1992
1993         if (!torture_setup_dir(cli, BASEDIR)) {
1994                 return false;
1995         }
1996
1997         ret &= test_sd(tctx, cli);
1998         ret &= test_nttrans_create(tctx, cli);
1999         ret &= test_nttrans_create_null_dacl(tctx, cli);
2000         ret &= test_creator_sid(tctx, cli);
2001         ret &= test_generic_bits(tctx, cli);
2002         ret &= test_owner_bits(tctx, cli);
2003         ret &= test_inheritance(tctx, cli);
2004         ret &= test_inheritance_dynamic(tctx, cli);
2005         ret &= test_sd_get_set(tctx, cli);
2006
2007         smb_raw_exit(cli->session);
2008         smbcli_deltree(cli->tree, BASEDIR);
2009
2010         return ret;
2011 }