8fde373dce8cbcfe1c6866b77c595b3df8271b06
[gd/samba/.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.fnum = 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.fnum = 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.fnum = 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.fnum = 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.fnum = 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 = torture_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("torture_check_privilege - %s\n", nt_errstr(status));
787         }
788         printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
789
790         status = torture_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("torture_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.fnum = 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 = torture_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("torture_check_privilege - %s\n", nt_errstr(status));
952         }
953         printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
954
955         status = torture_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("torture_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.fnum = 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 = torture_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("torture_check_privilege - %s\n", nt_errstr(status));
1141         }
1142         printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
1143
1144         status = torture_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("torture_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, *group_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.fnum = 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 | SECINFO_GROUP;
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         group_sid = dom_sid_string(tctx, sd_orig->group_sid);
1363
1364         printf("owner_sid is %s\n", owner_sid);
1365         printf("group_sid is %s\n", group_sid);
1366
1367         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1368
1369         if (torture_setting_bool(tctx, "samba4", false)) {
1370                 /* the default ACL in Samba4 includes the group and
1371                    other permissions */
1372                 sd_def = security_descriptor_dacl_create(tctx,
1373                                                          0, owner_sid, NULL,
1374                                                          owner_sid,
1375                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1376                                                          SEC_RIGHTS_FILE_ALL,
1377                                                          0,
1378                                                          group_sid,
1379                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1380                                                          SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE,
1381                                                          0,
1382                                                          SID_WORLD,
1383                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1384                                                          SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE,
1385                                                          0,
1386                                                          SID_NT_SYSTEM,
1387                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1388                                                          SEC_RIGHTS_FILE_ALL,
1389                                                          0,
1390                                                          NULL);
1391         } else {
1392                 sd_def = security_descriptor_dacl_create(tctx,
1393                                                          0, owner_sid, NULL,
1394                                                          owner_sid,
1395                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1396                                                          SEC_RIGHTS_FILE_ALL,
1397                                                          0,
1398                                                          SID_NT_SYSTEM,
1399                                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1400                                                          SEC_RIGHTS_FILE_ALL,
1401                                                          0,
1402                                                          NULL);
1403         }
1404
1405         creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER);
1406
1407         for (i=0;i<ARRAY_SIZE(test_flags);i++) {
1408                 sd = security_descriptor_dacl_create(tctx,
1409                                                 0, NULL, NULL,
1410                                                 SID_CREATOR_OWNER,
1411                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1412                                                 SEC_FILE_WRITE_DATA,
1413                                                 test_flags[i].parent_flags,
1414                                                 SID_WORLD,
1415                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1416                                                 SEC_FILE_ALL | SEC_STD_ALL,
1417                                                 0,
1418                                                 NULL);
1419                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1420                 set.set_secdesc.in.file.fnum = fnum;
1421                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1422                 set.set_secdesc.in.sd = sd;
1423                 status = smb_raw_setfileinfo(cli->tree, &set);
1424                 CHECK_STATUS(status, NT_STATUS_OK);
1425
1426                 io.ntcreatex.in.fname = fname1;
1427                 io.ntcreatex.in.create_options = 0;
1428                 status = smb_raw_open(cli->tree, tctx, &io);
1429                 CHECK_STATUS(status, NT_STATUS_OK);
1430                 fnum2 = io.ntcreatex.out.file.fnum;
1431
1432                 q.query_secdesc.in.file.fnum = fnum2;
1433                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1434                 CHECK_STATUS(status, NT_STATUS_OK);
1435
1436                 smbcli_close(cli->tree, fnum2);
1437                 smbcli_unlink(cli->tree, fname1);
1438
1439                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
1440                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1441                                 printf(__location__ ": Expected default sd for i=%d:\n", i);
1442                                 NDR_PRINT_DEBUG(security_descriptor, sd_def);
1443                                 printf("at %d - got:\n", i);
1444                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1445                         }
1446                         goto check_dir;
1447                 }
1448
1449                 if (q.query_secdesc.out.sd->dacl == NULL ||
1450                     q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1451                     q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1452                     !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1453                                    sd_orig->owner_sid)) {
1454                         printf("Bad sd in child file at %d\n", i);
1455                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1456                         ret = false;
1457                         goto check_dir;
1458                 }
1459
1460                 if (q.query_secdesc.out.sd->dacl->aces[0].flags != 
1461                     test_flags[i].file_flags) {
1462                         printf("incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
1463                                q.query_secdesc.out.sd->dacl->aces[0].flags,
1464                                test_flags[i].file_flags,
1465                                test_flags[i].parent_flags,
1466                                i);
1467                         ret = false;
1468                 }
1469
1470         check_dir:
1471                 io.ntcreatex.in.fname = fname2;
1472                 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1473                 status = smb_raw_open(cli->tree, tctx, &io);
1474                 CHECK_STATUS(status, NT_STATUS_OK);
1475                 fnum2 = io.ntcreatex.out.file.fnum;
1476
1477                 q.query_secdesc.in.file.fnum = fnum2;
1478                 status = smb_raw_fileinfo(cli->tree, tctx, &q);
1479                 CHECK_STATUS(status, NT_STATUS_OK);
1480
1481                 smbcli_close(cli->tree, fnum2);
1482                 smbcli_rmdir(cli->tree, fname2);
1483
1484                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1485                     (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
1486                      (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
1487                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1488                                 printf("Expected default sd for dir at %d:\n", i);
1489                                 NDR_PRINT_DEBUG(security_descriptor, sd_def);
1490                                 printf("got:\n");
1491                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1492                         }
1493                         continue;
1494                 }
1495
1496                 if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) && 
1497                     (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
1498                         if (q.query_secdesc.out.sd->dacl == NULL ||
1499                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1500                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1501                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1502                                            sd_orig->owner_sid) ||
1503                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1504                                 printf("(CI & NP) Bad sd in child dir at %d (parent 0x%x)\n", 
1505                                        i, test_flags[i].parent_flags);
1506                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1507                                 ret = false;
1508                                 continue;
1509                         }
1510                 } else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
1511                         if (q.query_secdesc.out.sd->dacl == NULL ||
1512                             q.query_secdesc.out.sd->dacl->num_aces != 2 ||
1513                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1514                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1515                                            sd_orig->owner_sid) ||
1516                             q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
1517                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
1518                                            creator_owner) ||
1519                             q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
1520                             q.query_secdesc.out.sd->dacl->aces[1].flags != 
1521                             (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
1522                                 printf("(CI) Bad sd in child dir at %d (parent 0x%x)\n", 
1523                                        i, test_flags[i].parent_flags);
1524                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1525                                 ret = false;
1526                                 continue;
1527                         }
1528                 } else {
1529                         if (q.query_secdesc.out.sd->dacl == NULL ||
1530                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1531                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1532                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1533                                            creator_owner) ||
1534                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1535                                 printf("(0) Bad sd in child dir at %d (parent 0x%x)\n", 
1536                                         i, test_flags[i].parent_flags);
1537                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1538                                 ret = false;
1539                                 continue;
1540                         }
1541                 }
1542         }
1543
1544         printf("testing access checks on inherited create with %s\n", fname1);
1545         sd = security_descriptor_dacl_create(tctx,
1546                                         0, NULL, NULL,
1547                                         owner_sid,
1548                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1549                                         SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1550                                         SEC_ACE_FLAG_OBJECT_INHERIT,
1551                                         SID_WORLD,
1552                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1553                                         SEC_FILE_ALL | SEC_STD_ALL,
1554                                         0,
1555                                         NULL);
1556         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1557         set.set_secdesc.in.file.fnum = fnum;
1558         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1559         set.set_secdesc.in.sd = sd;
1560         status = smb_raw_setfileinfo(cli->tree, &set);
1561         CHECK_STATUS(status, NT_STATUS_OK);
1562
1563         io.ntcreatex.in.fname = fname1;
1564         io.ntcreatex.in.create_options = 0;
1565         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1566         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1567         status = smb_raw_open(cli->tree, tctx, &io);
1568         CHECK_STATUS(status, NT_STATUS_OK);
1569         fnum2 = io.ntcreatex.out.file.fnum;
1570         CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1571
1572         q.query_secdesc.in.file.fnum = fnum2;
1573         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1574         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1575         CHECK_STATUS(status, NT_STATUS_OK);
1576         smbcli_close(cli->tree, fnum2);
1577
1578         sd2 = security_descriptor_dacl_create(tctx,
1579                                          0, owner_sid, NULL,
1580                                          owner_sid,
1581                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1582                                          SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1583                                          0,
1584                                          NULL);
1585         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
1586                 printf("%s: security descriptors don't match!\n", __location__);
1587                 printf("got:\n");
1588                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1589                 printf("expected:\n");
1590                 NDR_PRINT_DEBUG(security_descriptor, sd2);
1591                 ret = false;
1592         }
1593
1594         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1595         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1596         status = smb_raw_open(cli->tree, tctx, &io);
1597         if (NT_STATUS_IS_OK(status)) {
1598                 printf("failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
1599                 ret = false;
1600                 fnum2 = io.ntcreatex.out.file.fnum;
1601                 CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1602                 smbcli_close(cli->tree, fnum2);
1603         } else {
1604                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1605         }
1606
1607         printf("trying without execute\n");
1608         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1609         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
1610         status = smb_raw_open(cli->tree, tctx, &io);
1611         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1612
1613         printf("and with full permissions again\n");
1614         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1615         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1616         status = smb_raw_open(cli->tree, tctx, &io);
1617         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1618
1619         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1620         status = smb_raw_open(cli->tree, tctx, &io);
1621         CHECK_STATUS(status, NT_STATUS_OK);
1622         fnum2 = io.ntcreatex.out.file.fnum;
1623         CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1624         smbcli_close(cli->tree, fnum2);
1625
1626         printf("put back original sd\n");
1627         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1628         set.set_secdesc.in.file.fnum = fnum;
1629         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1630         set.set_secdesc.in.sd = sd_orig;
1631         status = smb_raw_setfileinfo(cli->tree, &set);
1632         CHECK_STATUS(status, NT_STATUS_OK);
1633
1634         smbcli_close(cli->tree, fnum);
1635
1636         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1637         status = smb_raw_open(cli->tree, tctx, &io);
1638         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1639
1640         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1641         status = smb_raw_open(cli->tree, tctx, &io);
1642         CHECK_STATUS(status, NT_STATUS_OK);
1643         fnum2 = io.ntcreatex.out.file.fnum;
1644         CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1645         smbcli_close(cli->tree, fnum2);
1646
1647         smbcli_unlink(cli->tree, fname1);
1648         smbcli_rmdir(cli->tree, dname);
1649
1650 done:
1651         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1652         set.set_secdesc.in.file.fnum = fnum;
1653         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1654         set.set_secdesc.in.sd = sd_orig;
1655         status = smb_raw_setfileinfo(cli->tree, &set);
1656
1657         smbcli_close(cli->tree, fnum);
1658         return ret;
1659 }
1660
1661
1662 /*
1663   test dynamic acl inheritance
1664 */
1665 static bool test_inheritance_dynamic(struct torture_context *tctx, 
1666                                                                          struct smbcli_state *cli)
1667 {
1668         NTSTATUS status;
1669         union smb_open io;
1670         const char *dname = BASEDIR "\\inheritance2";
1671         const char *fname1 = BASEDIR "\\inheritance2\\testfile";
1672         bool ret = true;
1673         int fnum=0, fnum2;
1674         union smb_fileinfo q;
1675         union smb_setfileinfo set;
1676         struct security_descriptor *sd, *sd_orig=NULL;
1677         const char *owner_sid;
1678         
1679         printf("TESTING DYNAMIC ACL INHERITANCE\n");
1680
1681         if (!torture_setup_dir(cli, BASEDIR)) {
1682                 return false;
1683         }
1684
1685         io.generic.level = RAW_OPEN_NTCREATEX;
1686         io.ntcreatex.in.root_fid.fnum = 0;
1687         io.ntcreatex.in.flags = 0;
1688         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1689         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1690         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1691         io.ntcreatex.in.share_access = 0;
1692         io.ntcreatex.in.alloc_size = 0;
1693         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1694         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1695         io.ntcreatex.in.security_flags = 0;
1696         io.ntcreatex.in.fname = dname;
1697
1698         status = smb_raw_open(cli->tree, tctx, &io);
1699         CHECK_STATUS(status, NT_STATUS_OK);
1700         fnum = io.ntcreatex.out.file.fnum;
1701
1702         printf("get the original sd\n");
1703         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1704         q.query_secdesc.in.file.fnum = fnum;
1705         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1706         status = smb_raw_fileinfo(cli->tree, tctx, &q);
1707         CHECK_STATUS(status, NT_STATUS_OK);
1708         sd_orig = q.query_secdesc.out.sd;
1709
1710         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1711
1712         printf("owner_sid is %s\n", owner_sid);
1713
1714         sd = security_descriptor_dacl_create(tctx,
1715                                         0, NULL, NULL,
1716                                         owner_sid,
1717                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1718                                         SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
1719                                         SEC_ACE_FLAG_OBJECT_INHERIT,
1720                                         NULL);
1721         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1722
1723         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1724         set.set_secdesc.in.file.fnum = fnum;
1725         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1726         set.set_secdesc.in.sd = sd;
1727         status = smb_raw_setfileinfo(cli->tree, &set);
1728         CHECK_STATUS(status, NT_STATUS_OK);
1729
1730         printf("create a file with an inherited acl\n");
1731         io.ntcreatex.in.fname = fname1;
1732         io.ntcreatex.in.create_options = 0;
1733         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE;
1734         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1735         status = smb_raw_open(cli->tree, tctx, &io);
1736         CHECK_STATUS(status, NT_STATUS_OK);
1737         fnum2 = io.ntcreatex.out.file.fnum;
1738         smbcli_close(cli->tree, fnum2);
1739
1740         printf("try and access file with base rights - should be OK\n");
1741         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1742         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1743         status = smb_raw_open(cli->tree, tctx, &io);
1744         CHECK_STATUS(status, NT_STATUS_OK);
1745         fnum2 = io.ntcreatex.out.file.fnum;
1746         smbcli_close(cli->tree, fnum2);
1747
1748         printf("try and access file with extra rights - should be denied\n");
1749         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1750         status = smb_raw_open(cli->tree, tctx, &io);
1751         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1752
1753         printf("update parent sd\n");
1754         sd = security_descriptor_dacl_create(tctx,
1755                                         0, NULL, NULL,
1756                                         owner_sid,
1757                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1758                                         SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE,
1759                                         SEC_ACE_FLAG_OBJECT_INHERIT,
1760                                         NULL);
1761         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1762
1763         set.set_secdesc.in.sd = sd;
1764         status = smb_raw_setfileinfo(cli->tree, &set);
1765         CHECK_STATUS(status, NT_STATUS_OK);
1766
1767         printf("try and access file with base rights - should be OK\n");
1768         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1769         status = smb_raw_open(cli->tree, tctx, &io);
1770         CHECK_STATUS(status, NT_STATUS_OK);
1771         fnum2 = io.ntcreatex.out.file.fnum;
1772         smbcli_close(cli->tree, fnum2);
1773
1774
1775         printf("try and access now - should be OK if dynamic inheritance works\n");
1776         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1777         status = smb_raw_open(cli->tree, tctx, &io);
1778         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1779                 printf("Server does not have dynamic inheritance\n");
1780         }
1781         if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1782                 printf("Server does have dynamic inheritance\n");
1783         }
1784         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1785
1786         smbcli_unlink(cli->tree, fname1);
1787
1788 done:
1789         printf("put back original sd\n");
1790         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1791         set.set_secdesc.in.file.fnum = fnum;
1792         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1793         set.set_secdesc.in.sd = sd_orig;
1794         status = smb_raw_setfileinfo(cli->tree, &set);
1795
1796         smbcli_close(cli->tree, fnum);
1797         smbcli_rmdir(cli->tree, dname);
1798
1799         return ret;
1800 }
1801
1802 #define CHECK_STATUS_FOR_BIT_ACTION(status, bits, action) do { \
1803         if (!(bits & desired_64)) {\
1804                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); \
1805                 action; \
1806         } else { \
1807                 CHECK_STATUS(status, NT_STATUS_OK); \
1808         } \
1809 } while (0)
1810
1811 #define CHECK_STATUS_FOR_BIT(status, bits, access) do { \
1812         if (NT_STATUS_IS_OK(status)) { \
1813                 if (!(granted & access)) {\
1814                         printf("(%s) %s but flags 0x%08X are not granted! granted[0x%08X] desired[0x%08X]\n", \
1815                                __location__, nt_errstr(status), access, granted, desired); \
1816                         ret = false; \
1817                         goto done; \
1818                 } \
1819         } else { \
1820                 if (granted & access) {\
1821                         printf("(%s) %s but flags 0x%08X are granted! granted[0x%08X] desired[0x%08X]\n", \
1822                                __location__, nt_errstr(status), access, granted, desired); \
1823                         ret = false; \
1824                         goto done; \
1825                 } \
1826         } \
1827         CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \
1828 } while (0)
1829
1830 /* test what access mask is needed for getting and setting security_descriptors */
1831 static bool test_sd_get_set(struct torture_context *tctx, 
1832                                                         struct smbcli_state *cli)
1833 {
1834         NTSTATUS status;
1835         bool ret = true;
1836         union smb_open io;
1837         union smb_fileinfo fi;
1838         union smb_setfileinfo si;
1839         struct security_descriptor *sd;
1840         struct security_descriptor *sd_owner = NULL;
1841         struct security_descriptor *sd_group = NULL;
1842         struct security_descriptor *sd_dacl = NULL;
1843         struct security_descriptor *sd_sacl = NULL;
1844         int fnum=0;
1845         const char *fname = BASEDIR "\\sd_get_set.txt";
1846         uint64_t desired_64;
1847         uint32_t desired = 0, granted;
1848         int i = 0;
1849 #define NO_BITS_HACK (((uint64_t)1)<<32)
1850         uint64_t open_bits =
1851                 SEC_MASK_GENERIC |
1852                 SEC_FLAG_SYSTEM_SECURITY |
1853                 SEC_FLAG_MAXIMUM_ALLOWED |
1854                 SEC_STD_ALL |
1855                 SEC_FILE_ALL | 
1856                 NO_BITS_HACK;
1857         uint64_t get_owner_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1858         uint64_t set_owner_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
1859         uint64_t get_group_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1860         uint64_t set_group_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
1861         uint64_t get_dacl_bits  = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1862         uint64_t set_dacl_bits  = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_DAC;
1863         uint64_t get_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
1864         uint64_t set_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
1865
1866         printf("TESTING ACCESS MASKS FOR SD GET/SET\n");
1867
1868         /* first create a file with full access for everyone */
1869         sd = security_descriptor_dacl_create(tctx,
1870                                         0, SID_NT_ANONYMOUS, SID_BUILTIN_USERS,
1871                                         SID_WORLD,
1872                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1873                                         SEC_GENERIC_ALL,
1874                                         0,
1875                                         NULL);
1876         sd->type |= SEC_DESC_SACL_PRESENT;
1877         sd->sacl = NULL;
1878         io.ntcreatex.level = RAW_OPEN_NTTRANS_CREATE;
1879         io.ntcreatex.in.root_fid.fnum = 0;
1880         io.ntcreatex.in.flags = 0;
1881         io.ntcreatex.in.access_mask = SEC_GENERIC_ALL;
1882         io.ntcreatex.in.create_options = 0;
1883         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1884         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1885         io.ntcreatex.in.alloc_size = 0;
1886         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1887         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1888         io.ntcreatex.in.security_flags = 0;
1889         io.ntcreatex.in.fname = fname;
1890         io.ntcreatex.in.sec_desc = sd;
1891         io.ntcreatex.in.ea_list = NULL;
1892         status = smb_raw_open(cli->tree, tctx, &io);
1893         CHECK_STATUS(status, NT_STATUS_OK);
1894         fnum = io.ntcreatex.out.file.fnum;
1895
1896         status = smbcli_close(cli->tree, fnum);
1897         CHECK_STATUS(status, NT_STATUS_OK);
1898
1899         /* 
1900          * now try each access_mask bit and no bit at all in a loop
1901          * and see what's allowed
1902          * NOTE: if i == 32 it means access_mask = 0 (see NO_BITS_HACK above)
1903          */
1904         for (i=0; i <= 32; i++) {
1905                 desired_64 = ((uint64_t)1) << i;
1906                 desired = (uint32_t)desired_64;
1907
1908                 /* first open the file with the desired access */
1909                 io.ntcreatex.level = RAW_OPEN_NTCREATEX;
1910                 io.ntcreatex.in.access_mask = desired;
1911                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1912                 status = smb_raw_open(cli->tree, tctx, &io);
1913                 CHECK_STATUS_FOR_BIT_ACTION(status, open_bits, goto next);
1914                 fnum = io.ntcreatex.out.file.fnum;
1915
1916                 /* then check what access was granted */
1917                 fi.access_information.level             = RAW_FILEINFO_ACCESS_INFORMATION;
1918                 fi.access_information.in.file.fnum      = fnum;
1919                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1920                 CHECK_STATUS(status, NT_STATUS_OK);
1921                 granted = fi.access_information.out.access_flags;
1922
1923                 /* test the owner */
1924                 ZERO_STRUCT(fi);
1925                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
1926                 fi.query_secdesc.in.file.fnum           = fnum;
1927                 fi.query_secdesc.in.secinfo_flags       = SECINFO_OWNER;
1928                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1929                 CHECK_STATUS_FOR_BIT(status, get_owner_bits, SEC_STD_READ_CONTROL);
1930                 if (fi.query_secdesc.out.sd) {
1931                         sd_owner = fi.query_secdesc.out.sd;
1932                 } else if (!sd_owner) {
1933                         sd_owner = sd;
1934                 }
1935                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
1936                 si.set_secdesc.in.file.fnum             = fnum;
1937                 si.set_secdesc.in.secinfo_flags         = SECINFO_OWNER;
1938                 si.set_secdesc.in.sd                    = sd_owner;
1939                 status = smb_raw_setfileinfo(cli->tree, &si);
1940                 CHECK_STATUS_FOR_BIT(status, set_owner_bits, SEC_STD_WRITE_OWNER);
1941
1942                 /* test the group */
1943                 ZERO_STRUCT(fi);
1944                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
1945                 fi.query_secdesc.in.file.fnum           = fnum;
1946                 fi.query_secdesc.in.secinfo_flags       = SECINFO_GROUP;
1947                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1948                 CHECK_STATUS_FOR_BIT(status, get_group_bits, SEC_STD_READ_CONTROL);
1949                 if (fi.query_secdesc.out.sd) {
1950                         sd_group = fi.query_secdesc.out.sd;
1951                 } else if (!sd_group) {
1952                         sd_group = sd;
1953                 }
1954                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
1955                 si.set_secdesc.in.file.fnum             = fnum;
1956                 si.set_secdesc.in.secinfo_flags         = SECINFO_GROUP;
1957                 si.set_secdesc.in.sd                    = sd_group;
1958                 status = smb_raw_setfileinfo(cli->tree, &si);
1959                 CHECK_STATUS_FOR_BIT(status, set_group_bits, SEC_STD_WRITE_OWNER);
1960
1961                 /* test the DACL */
1962                 ZERO_STRUCT(fi);
1963                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
1964                 fi.query_secdesc.in.file.fnum           = fnum;
1965                 fi.query_secdesc.in.secinfo_flags       = SECINFO_DACL;
1966                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1967                 CHECK_STATUS_FOR_BIT(status, get_dacl_bits, SEC_STD_READ_CONTROL);
1968                 if (fi.query_secdesc.out.sd) {
1969                         sd_dacl = fi.query_secdesc.out.sd;
1970                 } else if (!sd_dacl) {
1971                         sd_dacl = sd;
1972                 }
1973                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
1974                 si.set_secdesc.in.file.fnum             = fnum;
1975                 si.set_secdesc.in.secinfo_flags         = SECINFO_DACL;
1976                 si.set_secdesc.in.sd                    = sd_dacl;
1977                 status = smb_raw_setfileinfo(cli->tree, &si);
1978                 CHECK_STATUS_FOR_BIT(status, set_dacl_bits, SEC_STD_WRITE_DAC);
1979
1980                 /* test the SACL */
1981                 ZERO_STRUCT(fi);
1982                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
1983                 fi.query_secdesc.in.file.fnum           = fnum;
1984                 fi.query_secdesc.in.secinfo_flags       = SECINFO_SACL;
1985                 status = smb_raw_fileinfo(cli->tree, tctx, &fi);
1986                 CHECK_STATUS_FOR_BIT(status, get_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
1987                 if (fi.query_secdesc.out.sd) {
1988                         sd_sacl = fi.query_secdesc.out.sd;
1989                 } else if (!sd_sacl) {
1990                         sd_sacl = sd;
1991                 }
1992                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
1993                 si.set_secdesc.in.file.fnum             = fnum;
1994                 si.set_secdesc.in.secinfo_flags         = SECINFO_SACL;
1995                 si.set_secdesc.in.sd                    = sd_sacl;
1996                 status = smb_raw_setfileinfo(cli->tree, &si);
1997                 CHECK_STATUS_FOR_BIT(status, set_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
1998
1999                 /* close the handle */
2000                 status = smbcli_close(cli->tree, fnum);
2001                 CHECK_STATUS(status, NT_STATUS_OK);
2002 next:
2003                 continue;
2004         }
2005
2006 done:
2007         smbcli_close(cli->tree, fnum);
2008         smbcli_unlink(cli->tree, fname);
2009
2010         return ret;
2011 }
2012
2013
2014 /* 
2015    basic testing of security descriptor calls
2016 */
2017 bool torture_raw_acls(struct torture_context *tctx, struct smbcli_state *cli)
2018 {
2019         bool ret = true;
2020
2021         if (!torture_setup_dir(cli, BASEDIR)) {
2022                 return false;
2023         }
2024
2025         ret &= test_sd(tctx, cli);
2026         ret &= test_nttrans_create(tctx, cli);
2027         ret &= test_nttrans_create_null_dacl(tctx, cli);
2028         ret &= test_creator_sid(tctx, cli);
2029         ret &= test_generic_bits(tctx, cli);
2030         ret &= test_owner_bits(tctx, cli);
2031         ret &= test_inheritance(tctx, cli);
2032         ret &= test_inheritance_dynamic(tctx, cli);
2033         ret &= test_sd_get_set(tctx, cli);
2034
2035         smb_raw_exit(cli->session);
2036         smbcli_deltree(cli->tree, BASEDIR);
2037
2038         return ret;
2039 }