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