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