r4582: finally worked out what is going on with the inherited ACLs test and win2003...
[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 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26
27 #define BASEDIR "\\testsd"
28
29 #define CHECK_STATUS(status, correct) do { \
30         if (!NT_STATUS_EQUAL(status, correct)) { \
31                 printf("(%s) Incorrect status %s - should be %s\n", \
32                        __location__, nt_errstr(status), nt_errstr(correct)); \
33                 ret = False; \
34                 goto done; \
35         }} while (0)
36
37
38 static BOOL test_sd(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
39 {
40         NTSTATUS status;
41         union smb_open io;
42         const char *fname = BASEDIR "\\sd.txt";
43         BOOL ret = True;
44         int fnum = -1;
45         union smb_fileinfo q;
46         union smb_setfileinfo set;
47         struct security_ace ace;
48         struct security_descriptor *sd;
49         struct dom_sid *test_sid;
50
51         printf("TESTING SETFILEINFO EA_SET\n");
52
53         io.generic.level = RAW_OPEN_NTCREATEX;
54         io.ntcreatex.in.root_fid = 0;
55         io.ntcreatex.in.flags = 0;
56         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
57         io.ntcreatex.in.create_options = 0;
58         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
59         io.ntcreatex.in.share_access = 
60                 NTCREATEX_SHARE_ACCESS_READ | 
61                 NTCREATEX_SHARE_ACCESS_WRITE;
62         io.ntcreatex.in.alloc_size = 0;
63         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
64         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
65         io.ntcreatex.in.security_flags = 0;
66         io.ntcreatex.in.fname = fname;
67         status = smb_raw_open(cli->tree, mem_ctx, &io);
68         CHECK_STATUS(status, NT_STATUS_OK);
69         fnum = io.ntcreatex.out.fnum;
70         
71         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
72         q.query_secdesc.in.fnum = fnum;
73         q.query_secdesc.in.secinfo_flags = 
74                 SECINFO_OWNER |
75                 SECINFO_GROUP |
76                 SECINFO_DACL;
77         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
78         CHECK_STATUS(status, NT_STATUS_OK);
79         sd = q.query_secdesc.out.sd;
80
81         printf("add a new ACE to the DACL\n");
82
83         test_sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1234-5432");
84
85         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
86         ace.flags = 0;
87         ace.access_mask = SEC_STD_ALL;
88         ace.trustee = *test_sid;
89
90         status = security_descriptor_dacl_add(sd, &ace);
91         CHECK_STATUS(status, NT_STATUS_OK);
92
93         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
94         set.set_secdesc.file.fnum = fnum;
95         set.set_secdesc.in.secinfo_flags = q.query_secdesc.in.secinfo_flags;
96         set.set_secdesc.in.sd = sd;
97
98         status = smb_raw_setfileinfo(cli->tree, &set);
99         CHECK_STATUS(status, NT_STATUS_OK);
100
101         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
102         CHECK_STATUS(status, NT_STATUS_OK);
103
104         if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
105                 printf("%s: security descriptors don't match!\n", __location__);
106                 printf("got:\n");
107                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
108                 printf("expected:\n");
109                 NDR_PRINT_DEBUG(security_descriptor, sd);
110                 ret = False;
111         }
112
113         printf("remove it again\n");
114
115         status = security_descriptor_dacl_del(sd, test_sid);
116         CHECK_STATUS(status, NT_STATUS_OK);
117
118         status = smb_raw_setfileinfo(cli->tree, &set);
119         CHECK_STATUS(status, NT_STATUS_OK);
120
121         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
122         CHECK_STATUS(status, NT_STATUS_OK);
123
124         if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
125                 printf("%s: security descriptors don't match!\n", __location__);
126                 printf("got:\n");
127                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
128                 printf("expected:\n");
129                 NDR_PRINT_DEBUG(security_descriptor, sd);
130                 ret = False;
131         }
132
133 done:
134         smbcli_close(cli->tree, fnum);
135         return ret;
136 }
137
138
139 /*
140   test using NTTRANS CREATE to create a file with an initial ACL set
141 */
142 static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
143 {
144         NTSTATUS status;
145         union smb_open io;
146         const char *fname = BASEDIR "\\acl2.txt";
147         BOOL ret = True;
148         int fnum = -1;
149         union smb_fileinfo q;
150         struct security_ace ace;
151         struct security_descriptor *sd;
152         struct dom_sid *test_sid;
153
154         printf("TESTING NTTRANS CREATE WITH SEC_DESC\n");
155
156         io.generic.level = RAW_OPEN_NTTRANS_CREATE;
157         io.ntcreatex.in.root_fid = 0;
158         io.ntcreatex.in.flags = 0;
159         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
160         io.ntcreatex.in.create_options = 0;
161         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
162         io.ntcreatex.in.share_access = 
163                 NTCREATEX_SHARE_ACCESS_READ | 
164                 NTCREATEX_SHARE_ACCESS_WRITE;
165         io.ntcreatex.in.alloc_size = 0;
166         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
167         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
168         io.ntcreatex.in.security_flags = 0;
169         io.ntcreatex.in.fname = fname;
170         io.ntcreatex.in.sec_desc = NULL;
171         io.ntcreatex.in.ea_list = NULL;
172
173         printf("creating normal file\n");
174
175         status = smb_raw_open(cli->tree, mem_ctx, &io);
176         CHECK_STATUS(status, NT_STATUS_OK);
177         fnum = io.ntcreatex.out.fnum;
178
179         printf("querying ACL\n");
180
181         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
182         q.query_secdesc.in.fnum = fnum;
183         q.query_secdesc.in.secinfo_flags = 
184                 SECINFO_OWNER |
185                 SECINFO_GROUP |
186                 SECINFO_DACL;
187         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
188         CHECK_STATUS(status, NT_STATUS_OK);
189         sd = q.query_secdesc.out.sd;
190
191         smbcli_close(cli->tree, fnum);
192         smbcli_unlink(cli->tree, fname);
193
194         printf("adding a new ACE\n");
195         test_sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1234-54321");
196
197         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
198         ace.flags = 0;
199         ace.access_mask = SEC_STD_ALL;
200         ace.trustee = *test_sid;
201
202         status = security_descriptor_dacl_add(sd, &ace);
203         CHECK_STATUS(status, NT_STATUS_OK);
204         
205         printf("creating a file with an initial ACL\n");
206
207         io.ntcreatex.in.sec_desc = sd;
208         status = smb_raw_open(cli->tree, mem_ctx, &io);
209         CHECK_STATUS(status, NT_STATUS_OK);
210         fnum = io.ntcreatex.out.fnum;
211         
212         q.query_secdesc.in.fnum = fnum;
213         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
214         CHECK_STATUS(status, NT_STATUS_OK);
215
216         if (!security_acl_equal(q.query_secdesc.out.sd->dacl, sd->dacl)) {
217                 printf("%s: security descriptors don't match!\n", __location__);
218                 printf("got:\n");
219                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
220                 printf("expected:\n");
221                 NDR_PRINT_DEBUG(security_descriptor, sd);
222                 ret = False;
223         }
224
225 done:
226         smbcli_close(cli->tree, fnum);
227         return ret;
228 }
229
230 #define CHECK_ACCESS_FLAGS(_fnum, flags) do { \
231         union smb_fileinfo _q; \
232         _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
233         _q.access_information.in.fnum = (_fnum); \
234         status = smb_raw_fileinfo(cli->tree, mem_ctx, &_q); \
235         CHECK_STATUS(status, NT_STATUS_OK); \
236         if (_q.access_information.out.access_flags != (flags)) { \
237                 printf("(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
238                        __location__, _q.access_information.out.access_flags, (flags)); \
239                 ret = False; \
240                 goto done; \
241         } \
242 } while (0)
243
244
245 /*
246   test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
247   mapping bits
248 */
249 static BOOL test_creator_sid(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
250 {
251         NTSTATUS status;
252         union smb_open io;
253         const char *fname = BASEDIR "\\creator.txt";
254         BOOL ret = True;
255         int fnum = -1;
256         union smb_fileinfo q;
257         union smb_setfileinfo set;
258         struct security_descriptor *sd, *sd_orig, *sd2;
259         const char *owner_sid;
260
261         printf("TESTING SID_CREATOR_OWNER\n");
262
263         io.generic.level = RAW_OPEN_NTCREATEX;
264         io.ntcreatex.in.root_fid = 0;
265         io.ntcreatex.in.flags = 0;
266         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
267         io.ntcreatex.in.create_options = 0;
268         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
269         io.ntcreatex.in.share_access = 
270                 NTCREATEX_SHARE_ACCESS_READ | 
271                 NTCREATEX_SHARE_ACCESS_WRITE;
272         io.ntcreatex.in.alloc_size = 0;
273         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
274         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
275         io.ntcreatex.in.security_flags = 0;
276         io.ntcreatex.in.fname = fname;
277         status = smb_raw_open(cli->tree, mem_ctx, &io);
278         CHECK_STATUS(status, NT_STATUS_OK);
279         fnum = io.ntcreatex.out.fnum;
280
281         printf("get the original sd\n");
282         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
283         q.query_secdesc.in.fnum = fnum;
284         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
285         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
286         CHECK_STATUS(status, NT_STATUS_OK);
287         sd_orig = q.query_secdesc.out.sd;
288
289         owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
290
291         printf("set a sec desc allowing no write by CREATOR_OWNER\n");
292         sd = security_descriptor_create(mem_ctx,
293                                         NULL, NULL,
294                                         SID_CREATOR_OWNER,
295                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
296                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
297                                         0,
298                                         NULL);
299
300         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
301         set.set_secdesc.file.fnum = fnum;
302         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
303         set.set_secdesc.in.sd = sd;
304
305         status = smb_raw_setfileinfo(cli->tree, &set);
306         CHECK_STATUS(status, NT_STATUS_OK);
307
308         printf("try open for write\n");
309         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
310         status = smb_raw_open(cli->tree, mem_ctx, &io);
311         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
312
313         printf("try open for read\n");
314         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
315         status = smb_raw_open(cli->tree, mem_ctx, &io);
316         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
317
318         printf("try open for generic write\n");
319         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
320         status = smb_raw_open(cli->tree, mem_ctx, &io);
321         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
322
323         printf("try open for generic read\n");
324         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
325         status = smb_raw_open(cli->tree, mem_ctx, &io);
326         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
327
328         printf("set a sec desc allowing no write by owner\n");
329         sd = security_descriptor_create(mem_ctx,
330                                         owner_sid, NULL,
331                                         owner_sid,
332                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
333                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
334                                         0,
335                                         NULL);
336
337         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
338         set.set_secdesc.file.fnum = fnum;
339         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
340         set.set_secdesc.in.sd = sd;
341         status = smb_raw_setfileinfo(cli->tree, &set);
342         CHECK_STATUS(status, NT_STATUS_OK);
343
344         printf("check that sd has been mapped correctly\n");
345         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
346         CHECK_STATUS(status, NT_STATUS_OK);
347         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd)) {
348                 printf("%s: security descriptors don't match!\n", __location__);
349                 printf("got:\n");
350                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
351                 printf("expected:\n");
352                 NDR_PRINT_DEBUG(security_descriptor, sd);
353                 ret = False;
354         }
355
356         printf("try open for write\n");
357         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
358         status = smb_raw_open(cli->tree, mem_ctx, &io);
359         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
360
361         printf("try open for read\n");
362         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
363         status = smb_raw_open(cli->tree, mem_ctx, &io);
364         CHECK_STATUS(status, NT_STATUS_OK);
365         CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum, 
366                            SEC_FILE_READ_DATA|
367                            SEC_FILE_READ_ATTRIBUTE);
368         smbcli_close(cli->tree, io.ntcreatex.out.fnum);
369
370         printf("try open for generic write\n");
371         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
372         status = smb_raw_open(cli->tree, mem_ctx, &io);
373         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
374
375         printf("try open for generic read\n");
376         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
377         status = smb_raw_open(cli->tree, mem_ctx, &io);
378         CHECK_STATUS(status, NT_STATUS_OK);
379         CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum, 
380                            SEC_RIGHTS_FILE_READ);
381         smbcli_close(cli->tree, io.ntcreatex.out.fnum);
382
383         printf("set a sec desc allowing generic read by owner\n");
384         sd = security_descriptor_create(mem_ctx,
385                                         NULL, NULL,
386                                         owner_sid,
387                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
388                                         SEC_GENERIC_READ | SEC_STD_ALL,
389                                         0,
390                                         NULL);
391
392         set.set_secdesc.in.sd = sd;
393         status = smb_raw_setfileinfo(cli->tree, &set);
394         CHECK_STATUS(status, NT_STATUS_OK);
395
396         printf("check that generic read has been mapped correctly\n");
397         sd2 = security_descriptor_create(mem_ctx,
398                                          owner_sid, NULL,
399                                          owner_sid,
400                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
401                                          SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
402                                          0,
403                                          NULL);
404
405         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
406         CHECK_STATUS(status, NT_STATUS_OK);
407         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
408                 printf("%s: security descriptors don't match!\n", __location__);
409                 printf("got:\n");
410                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
411                 printf("expected:\n");
412                 NDR_PRINT_DEBUG(security_descriptor, sd2);
413                 ret = False;
414         }
415         
416
417         printf("try open for write\n");
418         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
419         status = smb_raw_open(cli->tree, mem_ctx, &io);
420         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
421
422         printf("try open for read\n");
423         io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
424         status = smb_raw_open(cli->tree, mem_ctx, &io);
425         CHECK_STATUS(status, NT_STATUS_OK);
426         CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum, 
427                            SEC_FILE_READ_DATA | 
428                            SEC_FILE_READ_ATTRIBUTE);
429         smbcli_close(cli->tree, io.ntcreatex.out.fnum);
430
431         printf("try open for generic write\n");
432         io.ntcreatex.in.access_mask = SEC_GENERIC_WRITE;
433         status = smb_raw_open(cli->tree, mem_ctx, &io);
434         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
435
436         printf("try open for generic read\n");
437         io.ntcreatex.in.access_mask = SEC_GENERIC_READ;
438         status = smb_raw_open(cli->tree, mem_ctx, &io);
439         CHECK_STATUS(status, NT_STATUS_OK);
440         CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum, SEC_RIGHTS_FILE_READ);
441         smbcli_close(cli->tree, io.ntcreatex.out.fnum);
442
443
444         printf("put back original sd\n");
445         set.set_secdesc.in.sd = sd_orig;
446         status = smb_raw_setfileinfo(cli->tree, &set);
447         CHECK_STATUS(status, NT_STATUS_OK);
448
449
450 done:
451         smbcli_close(cli->tree, fnum);
452         return ret;
453 }
454
455
456 /*
457   test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
458   SEC_FILE_xx bits
459 */
460 static BOOL test_generic_bits(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
461 {
462         NTSTATUS status;
463         union smb_open io;
464         const char *fname = BASEDIR "\\generic.txt";
465         BOOL ret = True;
466         int fnum = -1, i;
467         union smb_fileinfo q;
468         union smb_setfileinfo set;
469         struct security_descriptor *sd, *sd_orig, *sd2;
470         const char *owner_sid;
471         const struct {
472                 uint32_t gen_bits;
473                 uint32_t specific_bits;
474         } file_mappings[] = {
475                 { 0,                       0 },
476                 { SEC_GENERIC_READ,        SEC_RIGHTS_FILE_READ },
477                 { SEC_GENERIC_WRITE,       SEC_RIGHTS_FILE_WRITE },
478                 { SEC_GENERIC_EXECUTE,     SEC_RIGHTS_FILE_EXECUTE },
479                 { SEC_GENERIC_ALL,         SEC_RIGHTS_FILE_ALL },
480                 { SEC_FILE_READ_DATA,      SEC_FILE_READ_DATA },
481                 { SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_ATTRIBUTE }
482         };
483         const struct {
484                 uint32_t gen_bits;
485                 uint32_t specific_bits;
486         } dir_mappings[] = {
487                 { 0,                   0 },
488                 { SEC_GENERIC_READ,    SEC_RIGHTS_DIR_READ },
489                 { SEC_GENERIC_WRITE,   SEC_RIGHTS_DIR_WRITE },
490                 { SEC_GENERIC_EXECUTE, SEC_RIGHTS_DIR_EXECUTE },
491                 { SEC_GENERIC_ALL,     SEC_RIGHTS_DIR_ALL }
492         };
493         BOOL has_restore_privilege;
494         BOOL has_take_ownership_privilege;
495
496         printf("TESTING FILE GENERIC BITS\n");
497
498         io.generic.level = RAW_OPEN_NTCREATEX;
499         io.ntcreatex.in.root_fid = 0;
500         io.ntcreatex.in.flags = 0;
501         io.ntcreatex.in.access_mask = 
502                 SEC_STD_READ_CONTROL | 
503                 SEC_STD_WRITE_DAC | 
504                 SEC_STD_WRITE_OWNER;
505         io.ntcreatex.in.create_options = 0;
506         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
507         io.ntcreatex.in.share_access = 
508                 NTCREATEX_SHARE_ACCESS_READ | 
509                 NTCREATEX_SHARE_ACCESS_WRITE;
510         io.ntcreatex.in.alloc_size = 0;
511         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
512         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
513         io.ntcreatex.in.security_flags = 0;
514         io.ntcreatex.in.fname = fname;
515         status = smb_raw_open(cli->tree, mem_ctx, &io);
516         CHECK_STATUS(status, NT_STATUS_OK);
517         fnum = io.ntcreatex.out.fnum;
518
519         printf("get the original sd\n");
520         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
521         q.query_secdesc.in.fnum = fnum;
522         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
523         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
524         CHECK_STATUS(status, NT_STATUS_OK);
525         sd_orig = q.query_secdesc.out.sd;
526
527         owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
528
529         status = smblsa_sid_check_privilege(cli, 
530                                             owner_sid, 
531                                             sec_privilege_name(SEC_PRIV_RESTORE));
532         has_restore_privilege = NT_STATUS_IS_OK(status);
533         if (!NT_STATUS_IS_OK(status)) {
534                 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
535         }
536         printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
537
538         status = smblsa_sid_check_privilege(cli, 
539                                             owner_sid, 
540                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
541         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
542         if (!NT_STATUS_IS_OK(status)) {
543                 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
544         }
545         printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_restore_privilege?"Yes":"No");
546
547         for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
548                 uint32_t expected_mask = 
549                         SEC_STD_WRITE_DAC | 
550                         SEC_STD_READ_CONTROL | 
551                         SEC_FILE_READ_ATTRIBUTE |
552                         SEC_STD_DELETE;
553                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
554
555                 if (has_restore_privilege) {
556                         expected_mask_anon |= SEC_STD_DELETE;
557                 }
558
559                 printf("testing generic bits 0x%08x\n", 
560                        file_mappings[i].gen_bits);
561                 sd = security_descriptor_create(mem_ctx,
562                                                 owner_sid, NULL,
563                                                 owner_sid,
564                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
565                                                 file_mappings[i].gen_bits,
566                                                 0,
567                                                 NULL);
568
569                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
570                 set.set_secdesc.file.fnum = fnum;
571                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
572                 set.set_secdesc.in.sd = sd;
573
574                 status = smb_raw_setfileinfo(cli->tree, &set);
575                 CHECK_STATUS(status, NT_STATUS_OK);
576
577                 sd2 = security_descriptor_create(mem_ctx,
578                                                  owner_sid, NULL,
579                                                  owner_sid,
580                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
581                                                  file_mappings[i].specific_bits,
582                                                  0,
583                                                  NULL);
584
585                 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
586                 CHECK_STATUS(status, NT_STATUS_OK);
587                 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
588                         printf("%s: security descriptors don't match!\n", __location__);
589                         printf("got:\n");
590                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
591                         printf("expected:\n");
592                         NDR_PRINT_DEBUG(security_descriptor, sd2);
593                         ret = False;
594                 }
595
596                 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
597                 status = smb_raw_open(cli->tree, mem_ctx, &io);
598                 CHECK_STATUS(status, NT_STATUS_OK);
599                 CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum, 
600                                    expected_mask | file_mappings[i].specific_bits);
601                 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
602
603                 if (!has_take_ownership_privilege) {
604                         continue;
605                 }
606
607                 printf("testing generic bits 0x%08x (anonymous)\n", 
608                        file_mappings[i].gen_bits);
609                 sd = security_descriptor_create(mem_ctx,
610                                                 SID_NT_ANONYMOUS, NULL,
611                                                 owner_sid,
612                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
613                                                 file_mappings[i].gen_bits,
614                                                 0,
615                                                 NULL);
616
617                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
618                 set.set_secdesc.file.fnum = fnum;
619                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
620                 set.set_secdesc.in.sd = sd;
621
622                 status = smb_raw_setfileinfo(cli->tree, &set);
623                 CHECK_STATUS(status, NT_STATUS_OK);
624
625                 sd2 = security_descriptor_create(mem_ctx,
626                                                  SID_NT_ANONYMOUS, NULL,
627                                                  owner_sid,
628                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
629                                                  file_mappings[i].specific_bits,
630                                                  0,
631                                                  NULL);
632
633                 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
634                 CHECK_STATUS(status, NT_STATUS_OK);
635                 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
636                         printf("%s: security descriptors don't match!\n", __location__);
637                         printf("got:\n");
638                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
639                         printf("expected:\n");
640                         NDR_PRINT_DEBUG(security_descriptor, sd2);
641                         ret = False;
642                 }
643
644                 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
645                 status = smb_raw_open(cli->tree, mem_ctx, &io);
646                 CHECK_STATUS(status, NT_STATUS_OK);
647                 CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum, 
648                                    expected_mask_anon | file_mappings[i].specific_bits);
649                 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
650         }
651
652         printf("put back original sd\n");
653         set.set_secdesc.in.sd = sd_orig;
654         status = smb_raw_setfileinfo(cli->tree, &set);
655         CHECK_STATUS(status, NT_STATUS_OK);
656
657         smbcli_close(cli->tree, fnum);
658         smbcli_unlink(cli->tree, fname);
659
660
661         printf("TESTING DIR GENERIC BITS\n");
662
663         io.generic.level = RAW_OPEN_NTCREATEX;
664         io.ntcreatex.in.root_fid = 0;
665         io.ntcreatex.in.flags = 0;
666         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC;
667         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
668         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
669         io.ntcreatex.in.share_access = 
670                 NTCREATEX_SHARE_ACCESS_READ | 
671                 NTCREATEX_SHARE_ACCESS_WRITE;
672         io.ntcreatex.in.alloc_size = 0;
673         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
674         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
675         io.ntcreatex.in.security_flags = 0;
676         io.ntcreatex.in.fname = fname;
677         status = smb_raw_open(cli->tree, mem_ctx, &io);
678         CHECK_STATUS(status, NT_STATUS_OK);
679         fnum = io.ntcreatex.out.fnum;
680
681         printf("get the original sd\n");
682         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
683         q.query_secdesc.in.fnum = fnum;
684         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
685         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
686         CHECK_STATUS(status, NT_STATUS_OK);
687         sd_orig = q.query_secdesc.out.sd;
688
689         owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
690
691
692         for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
693                 uint32_t expected_mask = 
694                         SEC_STD_WRITE_DAC | 
695                         SEC_STD_READ_CONTROL | 
696                         SEC_FILE_READ_ATTRIBUTE |
697                         SEC_STD_DELETE;
698
699                 printf("testing generic bits 0x%08x\n", 
700                        file_mappings[i].gen_bits);
701                 sd = security_descriptor_create(mem_ctx,
702                                                 NULL, NULL,
703                                                 owner_sid,
704                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
705                                                 dir_mappings[i].gen_bits,
706                                                 0,
707                                                 NULL);
708
709                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
710                 set.set_secdesc.file.fnum = fnum;
711                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
712                 set.set_secdesc.in.sd = sd;
713
714                 status = smb_raw_setfileinfo(cli->tree, &set);
715                 CHECK_STATUS(status, NT_STATUS_OK);
716
717                 sd2 = security_descriptor_create(mem_ctx,
718                                                  owner_sid, NULL,
719                                                  owner_sid,
720                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
721                                                  dir_mappings[i].specific_bits,
722                                                  0,
723                                                  NULL);
724
725                 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
726                 CHECK_STATUS(status, NT_STATUS_OK);
727                 if (!security_descriptor_equal(q.query_secdesc.out.sd, sd2)) {
728                         printf("%s: security descriptors don't match!\n", __location__);
729                         printf("got:\n");
730                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
731                         printf("expected:\n");
732                         NDR_PRINT_DEBUG(security_descriptor, sd2);
733                         ret = False;
734                 }
735
736                 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
737                 status = smb_raw_open(cli->tree, mem_ctx, &io);
738                 CHECK_STATUS(status, NT_STATUS_OK);
739                 CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum, 
740                                    expected_mask | dir_mappings[i].specific_bits);
741                 smbcli_close(cli->tree, io.ntcreatex.out.fnum);
742         }
743
744         printf("put back original sd\n");
745         set.set_secdesc.in.sd = sd_orig;
746         status = smb_raw_setfileinfo(cli->tree, &set);
747         CHECK_STATUS(status, NT_STATUS_OK);
748
749         smbcli_close(cli->tree, fnum);
750         smbcli_unlink(cli->tree, fname);
751
752 done:
753         smbcli_close(cli->tree, fnum);
754         return ret;
755 }
756
757
758 /*
759   see what access bits the owner of a file always gets
760 */
761 static BOOL test_owner_bits(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
762 {
763         NTSTATUS status;
764         union smb_open io;
765         const char *fname = BASEDIR "\\generic.txt";
766         BOOL ret = True;
767         int fnum = -1, i;
768         union smb_fileinfo q;
769         union smb_setfileinfo set;
770         struct security_descriptor *sd, *sd_orig;
771         const char *owner_sid;
772         BOOL has_restore_privilege;
773         BOOL has_take_ownership_privilege;
774         uint32_t expected_bits;
775
776         printf("TESTING FILE OWNER BITS\n");
777
778         io.generic.level = RAW_OPEN_NTCREATEX;
779         io.ntcreatex.in.root_fid = 0;
780         io.ntcreatex.in.flags = 0;
781         io.ntcreatex.in.access_mask = 
782                 SEC_STD_READ_CONTROL | 
783                 SEC_STD_WRITE_DAC | 
784                 SEC_STD_WRITE_OWNER;
785         io.ntcreatex.in.create_options = 0;
786         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
787         io.ntcreatex.in.share_access = 
788                 NTCREATEX_SHARE_ACCESS_READ | 
789                 NTCREATEX_SHARE_ACCESS_WRITE;
790         io.ntcreatex.in.alloc_size = 0;
791         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
792         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
793         io.ntcreatex.in.security_flags = 0;
794         io.ntcreatex.in.fname = fname;
795         status = smb_raw_open(cli->tree, mem_ctx, &io);
796         CHECK_STATUS(status, NT_STATUS_OK);
797         fnum = io.ntcreatex.out.fnum;
798
799         printf("get the original sd\n");
800         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
801         q.query_secdesc.in.fnum = fnum;
802         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
803         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
804         CHECK_STATUS(status, NT_STATUS_OK);
805         sd_orig = q.query_secdesc.out.sd;
806
807         owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
808
809         status = smblsa_sid_check_privilege(cli, 
810                                             owner_sid, 
811                                             sec_privilege_name(SEC_PRIV_RESTORE));
812         has_restore_privilege = NT_STATUS_IS_OK(status);
813         if (!NT_STATUS_IS_OK(status)) {
814                 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
815         }
816         printf("SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
817
818         status = smblsa_sid_check_privilege(cli, 
819                                             owner_sid, 
820                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
821         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
822         if (!NT_STATUS_IS_OK(status)) {
823                 printf("smblsa_sid_check_privilege - %s\n", nt_errstr(status));
824         }
825         printf("SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_restore_privilege?"Yes":"No");
826
827         sd = security_descriptor_create(mem_ctx,
828                                         NULL, NULL,
829                                         owner_sid,
830                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
831                                         SEC_FILE_WRITE_DATA,
832                                         0,
833                                         NULL);
834
835         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
836         set.set_secdesc.file.fnum = fnum;
837         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
838         set.set_secdesc.in.sd = sd;
839
840         status = smb_raw_setfileinfo(cli->tree, &set);
841         CHECK_STATUS(status, NT_STATUS_OK);
842
843         expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
844
845         for (i=0;i<16;i++) {
846                 uint32 bit = (1<<i);
847                 io.ntcreatex.in.access_mask = bit;
848                 status = smb_raw_open(cli->tree, mem_ctx, &io);
849                 if (expected_bits & bit) {
850                         CHECK_STATUS(status, NT_STATUS_OK);
851                         CHECK_ACCESS_FLAGS(io.ntcreatex.out.fnum, bit | SEC_FILE_READ_ATTRIBUTE);
852                         smbcli_close(cli->tree, io.ntcreatex.out.fnum);
853                 } else {
854                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
855                 }
856         }
857
858         printf("put back original sd\n");
859         set.set_secdesc.in.sd = sd_orig;
860         status = smb_raw_setfileinfo(cli->tree, &set);
861         CHECK_STATUS(status, NT_STATUS_OK);
862
863 done:
864         smbcli_close(cli->tree, fnum);
865         smbcli_unlink(cli->tree, fname);
866         return ret;
867 }
868
869
870
871 /*
872   test the inheritance of ACL flags onto new files and directories
873 */
874 static BOOL test_inheritance(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
875 {
876         NTSTATUS status;
877         union smb_open io;
878         const char *dname = BASEDIR "\\inheritance";
879         const char *fname1 = BASEDIR "\\inheritance\\testfile";
880         const char *fname2 = BASEDIR "\\inheritance\\testdir";
881         BOOL ret = True;
882         int fnum, fnum2, i;
883         union smb_fileinfo q;
884         union smb_setfileinfo set;
885         struct security_descriptor *sd, *sd_orig, *sd_def;
886         const char *owner_sid;
887         const struct dom_sid *creator_owner;
888         const struct {
889                 uint32_t parent_flags;
890                 uint32_t file_flags;
891                 uint32_t dir_flags;
892         } test_flags[] = {
893                 {
894                         0, 
895                         0,
896                         0
897                 },
898                 {
899                         SEC_ACE_FLAG_OBJECT_INHERIT,
900                         0,
901                         SEC_ACE_FLAG_OBJECT_INHERIT | 
902                         SEC_ACE_FLAG_INHERIT_ONLY,
903                 },
904                 {
905                         SEC_ACE_FLAG_CONTAINER_INHERIT,
906                         0,
907                         SEC_ACE_FLAG_CONTAINER_INHERIT,
908                 },
909                 {
910                         SEC_ACE_FLAG_OBJECT_INHERIT | 
911                         SEC_ACE_FLAG_CONTAINER_INHERIT,
912                         0,
913                         SEC_ACE_FLAG_OBJECT_INHERIT | 
914                         SEC_ACE_FLAG_CONTAINER_INHERIT,
915                 },
916                 {
917                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
918                         0,
919                         0,
920                 },
921                 {
922                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
923                         SEC_ACE_FLAG_OBJECT_INHERIT,
924                         0,
925                         0,
926                 },
927                 {
928                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
929                         SEC_ACE_FLAG_CONTAINER_INHERIT,
930                         0,
931                         0,
932                 },
933                 {
934                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
935                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
936                         SEC_ACE_FLAG_OBJECT_INHERIT,
937                         0,
938                         0,
939                 },
940                 {
941                         SEC_ACE_FLAG_INHERIT_ONLY,
942                         0,
943                         0,
944                 },
945                 {
946                         SEC_ACE_FLAG_INHERIT_ONLY | 
947                         SEC_ACE_FLAG_OBJECT_INHERIT,
948                         0,
949                         SEC_ACE_FLAG_OBJECT_INHERIT | 
950                         SEC_ACE_FLAG_INHERIT_ONLY,
951                 },
952                 {
953                         SEC_ACE_FLAG_INHERIT_ONLY | 
954                         SEC_ACE_FLAG_CONTAINER_INHERIT,
955                         0,
956                         SEC_ACE_FLAG_CONTAINER_INHERIT,
957                 },
958                 {
959                         SEC_ACE_FLAG_INHERIT_ONLY | 
960                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
961                         SEC_ACE_FLAG_OBJECT_INHERIT,
962                         0,
963                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
964                         SEC_ACE_FLAG_OBJECT_INHERIT,
965                 },
966                 {
967                         SEC_ACE_FLAG_INHERIT_ONLY | 
968                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
969                         0,
970                         0,
971                 },
972                 {
973                         SEC_ACE_FLAG_INHERIT_ONLY | 
974                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
975                         SEC_ACE_FLAG_OBJECT_INHERIT,
976                         0,
977                         0,
978                 },
979                 {
980                         SEC_ACE_FLAG_INHERIT_ONLY | 
981                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
982                         SEC_ACE_FLAG_CONTAINER_INHERIT,
983                         0,
984                         0,
985                 },
986                 {
987                         SEC_ACE_FLAG_INHERIT_ONLY | 
988                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT | 
989                         SEC_ACE_FLAG_CONTAINER_INHERIT | 
990                         SEC_ACE_FLAG_OBJECT_INHERIT,
991                         0,
992                         0,
993                 }
994         };
995
996         printf("TESTING ACL INHERITANCE\n");
997
998         io.generic.level = RAW_OPEN_NTCREATEX;
999         io.ntcreatex.in.root_fid = 0;
1000         io.ntcreatex.in.flags = 0;
1001         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1002         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1003         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1004         io.ntcreatex.in.share_access = 0;
1005         io.ntcreatex.in.alloc_size = 0;
1006         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1007         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1008         io.ntcreatex.in.security_flags = 0;
1009         io.ntcreatex.in.fname = dname;
1010
1011         status = smb_raw_open(cli->tree, mem_ctx, &io);
1012         CHECK_STATUS(status, NT_STATUS_OK);
1013         fnum = io.ntcreatex.out.fnum;
1014
1015         printf("get the original sd\n");
1016         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1017         q.query_secdesc.in.fnum = fnum;
1018         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1019         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1020         CHECK_STATUS(status, NT_STATUS_OK);
1021         sd_orig = q.query_secdesc.out.sd;
1022
1023         owner_sid = dom_sid_string(mem_ctx, sd_orig->owner_sid);
1024
1025         printf("owner_sid is %s\n", owner_sid);
1026
1027         sd_def = security_descriptor_create(mem_ctx,
1028                                             owner_sid, NULL,
1029                                             owner_sid,
1030                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
1031                                             SEC_RIGHTS_FILE_ALL,
1032                                             0,
1033                                             SID_NT_SYSTEM,
1034                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
1035                                             SEC_RIGHTS_FILE_ALL,
1036                                             0,
1037                                             NULL);
1038
1039         creator_owner = dom_sid_parse_talloc(mem_ctx, SID_CREATOR_OWNER);
1040
1041         for (i=0;i<ARRAY_SIZE(test_flags);i++) {
1042                 sd = security_descriptor_create(mem_ctx,
1043                                                 NULL, NULL,
1044                                                 SID_CREATOR_OWNER,
1045                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1046                                                 SEC_FILE_WRITE_DATA,
1047                                                 test_flags[i].parent_flags,
1048                                                 SID_WORLD,
1049                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1050                                                 SEC_FILE_ALL | SEC_STD_ALL,
1051                                                 0,
1052                                                 NULL);
1053                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1054                 set.set_secdesc.file.fnum = fnum;
1055                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1056                 set.set_secdesc.in.sd = sd;
1057                 status = smb_raw_setfileinfo(cli->tree, &set);
1058                 CHECK_STATUS(status, NT_STATUS_OK);
1059
1060                 io.ntcreatex.in.fname = fname1;
1061                 io.ntcreatex.in.create_options = 0;
1062                 status = smb_raw_open(cli->tree, mem_ctx, &io);
1063                 CHECK_STATUS(status, NT_STATUS_OK);
1064                 fnum2 = io.ntcreatex.out.fnum;
1065
1066                 q.query_secdesc.in.fnum = fnum2;
1067                 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1068                 CHECK_STATUS(status, NT_STATUS_OK);
1069
1070                 smbcli_close(cli->tree, fnum2);
1071                 smbcli_unlink(cli->tree, fname1);
1072
1073                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
1074                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1075                                 printf("Expected default sd at %d - got:\n", i);
1076                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1077                         }
1078                         goto check_dir;
1079                 }
1080
1081                 if (q.query_secdesc.out.sd->dacl == NULL ||
1082                     q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1083                     q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1084                     !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1085                                    sd_orig->owner_sid)) {
1086                         printf("Bad sd in child file at %d\n", i);
1087                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1088                         ret = False;
1089                         goto check_dir;
1090                 }
1091
1092                 if (q.query_secdesc.out.sd->dacl->aces[0].flags != 
1093                     test_flags[i].file_flags) {
1094                         printf("incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
1095                                q.query_secdesc.out.sd->dacl->aces[0].flags,
1096                                test_flags[i].file_flags,
1097                                test_flags[i].parent_flags,
1098                                i);
1099                         ret = False;
1100                 }
1101
1102         check_dir:
1103                 io.ntcreatex.in.fname = fname2;
1104                 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1105                 status = smb_raw_open(cli->tree, mem_ctx, &io);
1106                 CHECK_STATUS(status, NT_STATUS_OK);
1107                 fnum2 = io.ntcreatex.out.fnum;
1108
1109                 q.query_secdesc.in.fnum = fnum2;
1110                 status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1111                 CHECK_STATUS(status, NT_STATUS_OK);
1112
1113                 smbcli_close(cli->tree, fnum2);
1114                 smbcli_rmdir(cli->tree, fname2);
1115
1116                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1117                     (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
1118                      (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
1119                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
1120                                 printf("Expected default sd for dir at %d - got:\n", i);
1121                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1122                         }
1123                         continue;
1124                 }
1125
1126                 if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) && 
1127                     (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
1128                         if (q.query_secdesc.out.sd->dacl == NULL ||
1129                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1130                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1131                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1132                                            sd_orig->owner_sid) ||
1133                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1134                                 printf("Bad sd in child dir at %d (parent 0x%x)\n", 
1135                                        i, test_flags[i].parent_flags);
1136                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1137                                 ret = False;
1138                                 continue;
1139                         }
1140                 } else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
1141                         if (q.query_secdesc.out.sd->dacl == NULL ||
1142                             q.query_secdesc.out.sd->dacl->num_aces != 2 ||
1143                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1144                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1145                                            sd_orig->owner_sid) ||
1146                             q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
1147                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
1148                                            creator_owner) ||
1149                             q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
1150                             q.query_secdesc.out.sd->dacl->aces[1].flags != 
1151                             (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
1152                                 printf("Bad sd in child dir at %d (parent 0x%x)\n", 
1153                                        i, test_flags[i].parent_flags);
1154                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1155                                 ret = False;
1156                                 continue;
1157                         }
1158                 } else {
1159                         if (q.query_secdesc.out.sd->dacl == NULL ||
1160                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1161                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1162                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1163                                            creator_owner) ||
1164                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1165                                 printf("Bad sd in child dir at %d (parent 0x%x)\n", 
1166                                        i, test_flags[i].parent_flags);
1167                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1168                                 ret = False;
1169                                 continue;
1170                         }
1171                 }
1172         }
1173
1174         printf("testing access checks on inherited create with %s\n", fname1);
1175         sd = security_descriptor_create(mem_ctx,
1176                                         NULL, NULL,
1177                                         owner_sid,
1178                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1179                                         SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1180                                         SEC_ACE_FLAG_OBJECT_INHERIT,
1181                                         SID_WORLD,
1182                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1183                                         SEC_FILE_ALL | SEC_STD_ALL,
1184                                         0,
1185                                         NULL);
1186         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1187         set.set_secdesc.file.fnum = fnum;
1188         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1189         set.set_secdesc.in.sd = sd;
1190         status = smb_raw_setfileinfo(cli->tree, &set);
1191         CHECK_STATUS(status, NT_STATUS_OK);
1192
1193         io.ntcreatex.in.fname = fname1;
1194         io.ntcreatex.in.create_options = 0;
1195         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1196         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1197         status = smb_raw_open(cli->tree, mem_ctx, &io);
1198         CHECK_STATUS(status, NT_STATUS_OK);
1199         fnum2 = io.ntcreatex.out.fnum;
1200         CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL);
1201
1202         q.query_secdesc.in.fnum = fnum2;
1203         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1204         status = smb_raw_fileinfo(cli->tree, mem_ctx, &q);
1205         CHECK_STATUS(status, NT_STATUS_OK);
1206         smbcli_close(cli->tree, fnum2);
1207
1208         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1209         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1210         status = smb_raw_open(cli->tree, mem_ctx, &io);
1211         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1212
1213         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1214         status = smb_raw_open(cli->tree, mem_ctx, &io);
1215         CHECK_STATUS(status, NT_STATUS_OK);
1216         fnum2 = io.ntcreatex.out.fnum;
1217         CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1218         smbcli_close(cli->tree, fnum2);
1219
1220         printf("put back original sd\n");
1221         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1222         set.set_secdesc.file.fnum = fnum;
1223         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1224         set.set_secdesc.in.sd = sd_orig;
1225         status = smb_raw_setfileinfo(cli->tree, &set);
1226         CHECK_STATUS(status, NT_STATUS_OK);
1227
1228         smbcli_close(cli->tree, fnum);
1229
1230         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1231         status = smb_raw_open(cli->tree, mem_ctx, &io);
1232         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1233
1234         io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
1235         status = smb_raw_open(cli->tree, mem_ctx, &io);
1236         CHECK_STATUS(status, NT_STATUS_OK);
1237         fnum2 = io.ntcreatex.out.fnum;
1238         CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE);
1239         smbcli_close(cli->tree, fnum2);
1240
1241         smbcli_unlink(cli->tree, fname1);
1242         smbcli_rmdir(cli->tree, dname);
1243
1244 done:
1245         smbcli_close(cli->tree, fnum);
1246         return ret;
1247 }
1248
1249
1250 /* 
1251    basic testing of security descriptor calls
1252 */
1253 BOOL torture_raw_acls(void)
1254 {
1255         struct smbcli_state *cli;
1256         BOOL ret = True;
1257         TALLOC_CTX *mem_ctx;
1258
1259         if (!torture_open_connection(&cli)) {
1260                 return False;
1261         }
1262
1263         mem_ctx = talloc_init("torture_raw_acls");
1264
1265         if (!torture_setup_dir(cli, BASEDIR)) {
1266                 return False;
1267         }
1268
1269         ret &= test_sd(cli, mem_ctx);
1270         ret &= test_nttrans_create(cli, mem_ctx);
1271         ret &= test_creator_sid(cli, mem_ctx);
1272         ret &= test_generic_bits(cli, mem_ctx);
1273         ret &= test_owner_bits(cli, mem_ctx);
1274         ret &= test_inheritance(cli, mem_ctx);
1275
1276         printf("\n *** NOTE! need to add dynamic inheritance test **\n");
1277 #if 0
1278         ret &= test_inheritance_dynamic(cli, mem_ctx);
1279         
1280 /*
1281   open questions:
1282     - does "create with ACL" have to obey the ACL that is supplied?
1283     - does "create with ACL" look at the owner_sid and group_sid at all?
1284 */
1285 #endif
1286
1287         smb_raw_exit(cli->session);
1288         smbcli_deltree(cli->tree, BASEDIR);
1289
1290         torture_close_connection(cli);
1291         talloc_destroy(mem_ctx);
1292         return ret;
1293 }