s4:torture/smb2: new test for interaction between chown and SD flags
[samba.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 "lib/cmdline/popt_common.h"
24 #include "libcli/smb2/smb2.h"
25 #include "libcli/smb2/smb2_calls.h"
26 #include "libcli/smb/smbXcli_base.h"
27 #include "torture/torture.h"
28 #include "libcli/resolve/resolve.h"
29 #include "torture/util.h"
30 #include "torture/smb2/proto.h"
31 #include "libcli/security/security.h"
32 #include "librpc/gen_ndr/ndr_security.h"
33 #include "lib/param/param.h"
34
35 #define CHECK_STATUS(status, correct) do { \
36         if (!NT_STATUS_EQUAL(status, correct)) { \
37                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
38                        __location__, nt_errstr(status), nt_errstr(correct)); \
39                 ret = false; \
40                 goto done; \
41         }} while (0)
42
43 #define BASEDIR "smb2-testsd"
44
45 #define CHECK_ACCESS_IGNORE SEC_STD_SYNCHRONIZE
46
47 #define CHECK_ACCESS_FLAGS(_fh, flags) do { \
48         union smb_fileinfo _q; \
49         _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
50         _q.access_information.in.file.handle = (_fh); \
51         status = smb2_getinfo_file(tree, tctx, &_q); \
52         CHECK_STATUS(status, NT_STATUS_OK); \
53         /* Handle a Vista bug where SEC_STD_SYNCHRONIZE doesn't come back. */ \
54         if ((((flags) & CHECK_ACCESS_IGNORE) == CHECK_ACCESS_IGNORE) && \
55             ((_q.access_information.out.access_flags & CHECK_ACCESS_IGNORE) != CHECK_ACCESS_IGNORE)) { \
56                 torture_comment(tctx, "SKIPPING (Vista bug): (%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
57                        __location__, _q.access_information.out.access_flags, (flags)); \
58         } \
59         if ((_q.access_information.out.access_flags & ~CHECK_ACCESS_IGNORE) != \
60             (((flags) & ~CHECK_ACCESS_IGNORE))) { \
61                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
62                        __location__, _q.access_information.out.access_flags, (flags)); \
63                 ret = false; \
64                 goto done; \
65         } \
66 } while (0)
67
68 #define FAIL_UNLESS(__cond)                                     \
69         do {                                                    \
70                 if (__cond) {} else {                           \
71                         torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n",      \
72                                __location__, #__cond);          \
73                         ret = false; goto done;                 \
74                 }                                               \
75         } while(0)
76
77 #define CHECK_SECURITY_DESCRIPTOR(_sd1, _sd2) do { \
78         if (!security_descriptor_equal(_sd1, _sd2)) { \
79                 torture_warning(tctx, "security descriptors don't match!\n"); \
80                 torture_warning(tctx, "got:\n"); \
81                 NDR_PRINT_DEBUG(security_descriptor, _sd1); \
82                 torture_warning(tctx, "expected:\n"); \
83                 NDR_PRINT_DEBUG(security_descriptor, _sd2); \
84                 torture_result(tctx, TORTURE_FAIL, \
85                                "%s: security descriptors don't match!\n", \
86                                __location__); \
87                 ret = false; \
88         } \
89 } while (0)
90
91 /*
92   test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
93   mapping bits
94   Note: This test was copied from raw/acls.c.
95 */
96 static bool test_creator_sid(struct torture_context *tctx, struct smb2_tree *tree)
97 {
98         NTSTATUS status;
99         struct smb2_create io;
100         const char *fname = BASEDIR "\\creator.txt";
101         bool ret = true;
102         struct smb2_handle handle = {{0}};
103         union smb_fileinfo q;
104         union smb_setfileinfo set;
105         struct security_descriptor *sd, *sd_orig, *sd2;
106         const char *owner_sid;
107
108         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
109                 return false;
110
111         torture_comment(tctx, "TESTING SID_CREATOR_OWNER\n");
112
113         ZERO_STRUCT(io);
114         io.level = RAW_OPEN_SMB2;
115         io.in.create_flags = 0;
116         io.in.desired_access = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
117         io.in.create_options = 0;
118         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
119         io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
120                 NTCREATEX_SHARE_ACCESS_READ |
121                 NTCREATEX_SHARE_ACCESS_WRITE;
122         io.in.alloc_size = 0;
123         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
124         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
125         io.in.security_flags = 0;
126         io.in.fname = fname;
127
128         status = smb2_create(tree, tctx, &io);
129         CHECK_STATUS(status, NT_STATUS_OK);
130         handle = io.out.file.handle;
131
132         torture_comment(tctx, "get the original sd\n");
133         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
134         q.query_secdesc.in.file.handle = handle;
135         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
136         status = smb2_getinfo_file(tree, tctx, &q);
137         CHECK_STATUS(status, NT_STATUS_OK);
138         sd_orig = q.query_secdesc.out.sd;
139
140         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
141
142         torture_comment(tctx, "set a sec desc allowing no write by CREATOR_OWNER\n");
143         sd = security_descriptor_dacl_create(tctx,
144                                         0, NULL, NULL,
145                                         SID_CREATOR_OWNER,
146                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
147                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
148                                         0,
149                                         NULL);
150
151         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
152         set.set_secdesc.in.file.handle = handle;
153         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
154         set.set_secdesc.in.sd = sd;
155
156         status = smb2_setinfo_file(tree, &set);
157         CHECK_STATUS(status, NT_STATUS_OK);
158
159         torture_comment(tctx, "try open for write\n");
160         io.in.desired_access = SEC_FILE_WRITE_DATA;
161         status = smb2_create(tree, tctx, &io);
162         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
163
164         torture_comment(tctx, "try open for read\n");
165         io.in.desired_access = SEC_FILE_READ_DATA;
166         status = smb2_create(tree, tctx, &io);
167         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
168
169         torture_comment(tctx, "try open for generic write\n");
170         io.in.desired_access = SEC_GENERIC_WRITE;
171         status = smb2_create(tree, tctx, &io);
172         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
173
174         torture_comment(tctx, "try open for generic read\n");
175         io.in.desired_access = SEC_GENERIC_READ;
176         status = smb2_create(tree, tctx, &io);
177         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
178
179         torture_comment(tctx, "set a sec desc allowing no write by owner\n");
180         sd = security_descriptor_dacl_create(tctx,
181                                         0, owner_sid, NULL,
182                                         owner_sid,
183                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
184                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
185                                         0,
186                                         NULL);
187
188         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
189         set.set_secdesc.in.file.handle = handle;
190         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
191         set.set_secdesc.in.sd = sd;
192         status = smb2_setinfo_file(tree, &set);
193         CHECK_STATUS(status, NT_STATUS_OK);
194
195         torture_comment(tctx, "check that sd has been mapped correctly\n");
196         status = smb2_getinfo_file(tree, tctx, &q);
197         CHECK_STATUS(status, NT_STATUS_OK);
198         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
199
200         torture_comment(tctx, "try open for write\n");
201         io.in.desired_access = SEC_FILE_WRITE_DATA;
202         status = smb2_create(tree, tctx, &io);
203         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
204
205         torture_comment(tctx, "try open for read\n");
206         io.in.desired_access = SEC_FILE_READ_DATA;
207         status = smb2_create(tree, tctx, &io);
208         CHECK_STATUS(status, NT_STATUS_OK);
209         CHECK_ACCESS_FLAGS(io.out.file.handle,
210                            SEC_FILE_READ_DATA);
211         smb2_util_close(tree, io.out.file.handle);
212
213         torture_comment(tctx, "try open for generic write\n");
214         io.in.desired_access = SEC_GENERIC_WRITE;
215         status = smb2_create(tree, tctx, &io);
216         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
217
218         torture_comment(tctx, "try open for generic read\n");
219         io.in.desired_access = SEC_GENERIC_READ;
220         status = smb2_create(tree, tctx, &io);
221         CHECK_STATUS(status, NT_STATUS_OK);
222         CHECK_ACCESS_FLAGS(io.out.file.handle,
223                            SEC_RIGHTS_FILE_READ);
224         smb2_util_close(tree, io.out.file.handle);
225
226         torture_comment(tctx, "set a sec desc allowing generic read by owner\n");
227         sd = security_descriptor_dacl_create(tctx,
228                                         0, NULL, NULL,
229                                         owner_sid,
230                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
231                                         SEC_GENERIC_READ | SEC_STD_ALL,
232                                         0,
233                                         NULL);
234
235         set.set_secdesc.in.sd = sd;
236         status = smb2_setinfo_file(tree, &set);
237         CHECK_STATUS(status, NT_STATUS_OK);
238
239         torture_comment(tctx, "check that generic read has been mapped correctly\n");
240         sd2 = security_descriptor_dacl_create(tctx,
241                                          0, owner_sid, NULL,
242                                          owner_sid,
243                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
244                                          SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
245                                          0,
246                                          NULL);
247
248         status = smb2_getinfo_file(tree, tctx, &q);
249         CHECK_STATUS(status, NT_STATUS_OK);
250         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
251
252         torture_comment(tctx, "try open for write\n");
253         io.in.desired_access = SEC_FILE_WRITE_DATA;
254         status = smb2_create(tree, tctx, &io);
255         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
256
257         torture_comment(tctx, "try open for read\n");
258         io.in.desired_access = SEC_FILE_READ_DATA;
259         status = smb2_create(tree, tctx, &io);
260         CHECK_STATUS(status, NT_STATUS_OK);
261         CHECK_ACCESS_FLAGS(io.out.file.handle,
262                            SEC_FILE_READ_DATA);
263         smb2_util_close(tree, io.out.file.handle);
264
265         torture_comment(tctx, "try open for generic write\n");
266         io.in.desired_access = SEC_GENERIC_WRITE;
267         status = smb2_create(tree, tctx, &io);
268         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
269
270         torture_comment(tctx, "try open for generic read\n");
271         io.in.desired_access = SEC_GENERIC_READ;
272         status = smb2_create(tree, tctx, &io);
273         CHECK_STATUS(status, NT_STATUS_OK);
274         CHECK_ACCESS_FLAGS(io.out.file.handle, SEC_RIGHTS_FILE_READ);
275         smb2_util_close(tree, io.out.file.handle);
276
277
278         torture_comment(tctx, "put back original sd\n");
279         set.set_secdesc.in.sd = sd_orig;
280         status = smb2_setinfo_file(tree, &set);
281         CHECK_STATUS(status, NT_STATUS_OK);
282
283
284 done:
285         smb2_util_close(tree, handle);
286         smb2_deltree(tree, BASEDIR);
287         smb2_tdis(tree);
288         smb2_logoff(tree->session);
289         return ret;
290 }
291
292
293 /*
294   test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
295   SEC_FILE_xx bits
296   Note: This test was copied from raw/acls.c.
297 */
298 static bool test_generic_bits(struct torture_context *tctx, struct smb2_tree *tree)
299 {
300         NTSTATUS status;
301         struct smb2_create io;
302         const char *fname = BASEDIR "\\generic.txt";
303         bool ret = true;
304         struct smb2_handle handle = {{0}};
305         int i;
306         union smb_fileinfo q;
307         union smb_setfileinfo set;
308         struct security_descriptor *sd, *sd_orig, *sd2;
309         const char *owner_sid;
310         const struct {
311                 uint32_t gen_bits;
312                 uint32_t specific_bits;
313         } file_mappings[] = {
314                 { 0,                       0 },
315                 { SEC_GENERIC_READ,        SEC_RIGHTS_FILE_READ },
316                 { SEC_GENERIC_WRITE,       SEC_RIGHTS_FILE_WRITE },
317                 { SEC_GENERIC_EXECUTE,     SEC_RIGHTS_FILE_EXECUTE },
318                 { SEC_GENERIC_ALL,         SEC_RIGHTS_FILE_ALL },
319                 { SEC_FILE_READ_DATA,      SEC_FILE_READ_DATA },
320                 { SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_ATTRIBUTE }
321         };
322         const struct {
323                 uint32_t gen_bits;
324                 uint32_t specific_bits;
325         } dir_mappings[] = {
326                 { 0,                   0 },
327                 { SEC_GENERIC_READ,    SEC_RIGHTS_DIR_READ },
328                 { SEC_GENERIC_WRITE,   SEC_RIGHTS_DIR_WRITE },
329                 { SEC_GENERIC_EXECUTE, SEC_RIGHTS_DIR_EXECUTE },
330                 { SEC_GENERIC_ALL,     SEC_RIGHTS_DIR_ALL }
331         };
332         bool has_restore_privilege = false;
333         bool has_take_ownership_privilege = false;
334
335         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
336                 return false;
337
338         torture_comment(tctx, "TESTING FILE GENERIC BITS\n");
339
340         ZERO_STRUCT(io);
341         io.level = RAW_OPEN_SMB2;
342         io.in.create_flags = 0;
343         io.in.desired_access =
344                 SEC_STD_READ_CONTROL |
345                 SEC_STD_WRITE_DAC |
346                 SEC_STD_WRITE_OWNER;
347         io.in.create_options = 0;
348         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
349         io.in.share_access =
350                 NTCREATEX_SHARE_ACCESS_READ |
351                 NTCREATEX_SHARE_ACCESS_WRITE;
352         io.in.alloc_size = 0;
353         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
354         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
355         io.in.security_flags = 0;
356         io.in.fname = fname;
357         status = smb2_create(tree, tctx, &io);
358         CHECK_STATUS(status, NT_STATUS_OK);
359         handle = io.out.file.handle;
360
361         torture_comment(tctx, "get the original sd\n");
362         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
363         q.query_secdesc.in.file.handle = handle;
364         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
365         status = smb2_getinfo_file(tree, tctx, &q);
366         CHECK_STATUS(status, NT_STATUS_OK);
367         sd_orig = q.query_secdesc.out.sd;
368
369         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
370
371 /*
372  * XXX: The smblsa calls use SMB as their transport - need to get rid of
373  * dependency.
374  */
375 /*
376         status = smblsa_sid_check_privilege(cli,
377                                             owner_sid,
378                                             sec_privilege_name(SEC_PRIV_RESTORE));
379         has_restore_privilege = NT_STATUS_IS_OK(status);
380         if (!NT_STATUS_IS_OK(status)) {
381                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
382         }
383         torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
384
385         status = smblsa_sid_check_privilege(cli,
386                                             owner_sid,
387                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
388         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
389         if (!NT_STATUS_IS_OK(status)) {
390                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
391         }
392         torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
393 */
394
395         for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
396                 uint32_t expected_mask =
397                         SEC_STD_WRITE_DAC |
398                         SEC_STD_READ_CONTROL |
399                         SEC_FILE_READ_ATTRIBUTE |
400                         SEC_STD_DELETE;
401                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
402
403                 if (has_restore_privilege) {
404                         expected_mask_anon |= SEC_STD_DELETE;
405                 }
406
407                 torture_comment(tctx, "Testing generic bits 0x%08x\n",
408                        file_mappings[i].gen_bits);
409                 sd = security_descriptor_dacl_create(tctx,
410                                                 0, owner_sid, NULL,
411                                                 owner_sid,
412                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
413                                                 file_mappings[i].gen_bits,
414                                                 0,
415                                                 NULL);
416
417                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
418                 set.set_secdesc.in.file.handle = handle;
419                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
420                 set.set_secdesc.in.sd = sd;
421
422                 status = smb2_setinfo_file(tree, &set);
423                 CHECK_STATUS(status, NT_STATUS_OK);
424
425                 sd2 = security_descriptor_dacl_create(tctx,
426                                                  0, owner_sid, NULL,
427                                                  owner_sid,
428                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
429                                                  file_mappings[i].specific_bits,
430                                                  0,
431                                                  NULL);
432
433                 status = smb2_getinfo_file(tree, tctx, &q);
434                 CHECK_STATUS(status, NT_STATUS_OK);
435                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
436
437                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
438                 status = smb2_create(tree, tctx, &io);
439                 CHECK_STATUS(status, NT_STATUS_OK);
440                 CHECK_ACCESS_FLAGS(io.out.file.handle,
441                                    expected_mask | file_mappings[i].specific_bits);
442                 smb2_util_close(tree, io.out.file.handle);
443
444                 if (!has_take_ownership_privilege) {
445                         continue;
446                 }
447
448                 torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
449                        file_mappings[i].gen_bits);
450                 sd = security_descriptor_dacl_create(tctx,
451                                                 0, SID_NT_ANONYMOUS, NULL,
452                                                 owner_sid,
453                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
454                                                 file_mappings[i].gen_bits,
455                                                 0,
456                                                 NULL);
457
458                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
459                 set.set_secdesc.in.file.handle = handle;
460                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
461                 set.set_secdesc.in.sd = sd;
462
463                 status = smb2_setinfo_file(tree, &set);
464                 CHECK_STATUS(status, NT_STATUS_OK);
465
466                 sd2 = security_descriptor_dacl_create(tctx,
467                                                  0, SID_NT_ANONYMOUS, NULL,
468                                                  owner_sid,
469                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
470                                                  file_mappings[i].specific_bits,
471                                                  0,
472                                                  NULL);
473
474                 status = smb2_getinfo_file(tree, tctx, &q);
475                 CHECK_STATUS(status, NT_STATUS_OK);
476                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
477
478                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
479                 status = smb2_create(tree, tctx, &io);
480                 CHECK_STATUS(status, NT_STATUS_OK);
481                 CHECK_ACCESS_FLAGS(io.out.file.handle,
482                                    expected_mask_anon | file_mappings[i].specific_bits);
483                 smb2_util_close(tree, io.out.file.handle);
484         }
485
486         torture_comment(tctx, "put back original sd\n");
487         set.set_secdesc.in.sd = sd_orig;
488         status = smb2_setinfo_file(tree, &set);
489         CHECK_STATUS(status, NT_STATUS_OK);
490
491         smb2_util_close(tree, handle);
492         smb2_util_unlink(tree, fname);
493
494
495         torture_comment(tctx, "TESTING DIR GENERIC BITS\n");
496
497         ZERO_STRUCT(io);
498         io.level = RAW_OPEN_SMB2;
499         io.in.create_flags = 0;
500         io.in.desired_access =
501                 SEC_STD_READ_CONTROL |
502                 SEC_STD_WRITE_DAC |
503                 SEC_STD_WRITE_OWNER;
504         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
505         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
506         io.in.share_access =
507                 NTCREATEX_SHARE_ACCESS_READ |
508                 NTCREATEX_SHARE_ACCESS_WRITE;
509         io.in.alloc_size = 0;
510         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
511         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
512         io.in.security_flags = 0;
513         io.in.fname = fname;
514         status = smb2_create(tree, tctx, &io);
515         CHECK_STATUS(status, NT_STATUS_OK);
516         handle = io.out.file.handle;
517
518         torture_comment(tctx, "get the original sd\n");
519         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
520         q.query_secdesc.in.file.handle = handle;
521         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
522         status = smb2_getinfo_file(tree, tctx, &q);
523         CHECK_STATUS(status, NT_STATUS_OK);
524         sd_orig = q.query_secdesc.out.sd;
525
526         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
527
528 /*
529  * XXX: The smblsa calls use SMB as their transport - need to get rid of
530  * dependency.
531  */
532 /*
533         status = smblsa_sid_check_privilege(cli,
534                                             owner_sid,
535                                             sec_privilege_name(SEC_PRIV_RESTORE));
536         has_restore_privilege = NT_STATUS_IS_OK(status);
537         if (!NT_STATUS_IS_OK(status)) {
538                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
539         }
540         torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
541
542         status = smblsa_sid_check_privilege(cli,
543                                             owner_sid,
544                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
545         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
546         if (!NT_STATUS_IS_OK(status)) {
547                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
548         }
549         torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
550
551 */
552         for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
553                 uint32_t expected_mask =
554                         SEC_STD_WRITE_DAC |
555                         SEC_STD_READ_CONTROL |
556                         SEC_FILE_READ_ATTRIBUTE |
557                         SEC_STD_DELETE;
558                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
559
560                 if (has_restore_privilege) {
561                         expected_mask_anon |= SEC_STD_DELETE;
562                 }
563
564                 torture_comment(tctx, "Testing generic bits 0x%08x\n",
565                        file_mappings[i].gen_bits);
566                 sd = security_descriptor_dacl_create(tctx,
567                                                 0, owner_sid, NULL,
568                                                 owner_sid,
569                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
570                                                 dir_mappings[i].gen_bits,
571                                                 0,
572                                                 NULL);
573
574                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
575                 set.set_secdesc.in.file.handle = handle;
576                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
577                 set.set_secdesc.in.sd = sd;
578
579                 status = smb2_setinfo_file(tree, &set);
580                 CHECK_STATUS(status, NT_STATUS_OK);
581
582                 sd2 = security_descriptor_dacl_create(tctx,
583                                                  0, owner_sid, NULL,
584                                                  owner_sid,
585                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
586                                                  dir_mappings[i].specific_bits,
587                                                  0,
588                                                  NULL);
589
590                 status = smb2_getinfo_file(tree, tctx, &q);
591                 CHECK_STATUS(status, NT_STATUS_OK);
592                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
593
594                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
595                 status = smb2_create(tree, tctx, &io);
596                 CHECK_STATUS(status, NT_STATUS_OK);
597                 CHECK_ACCESS_FLAGS(io.out.file.handle,
598                                    expected_mask | dir_mappings[i].specific_bits);
599                 smb2_util_close(tree, io.out.file.handle);
600
601                 if (!has_take_ownership_privilege) {
602                         continue;
603                 }
604
605                 torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
606                        file_mappings[i].gen_bits);
607                 sd = security_descriptor_dacl_create(tctx,
608                                                 0, SID_NT_ANONYMOUS, NULL,
609                                                 owner_sid,
610                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
611                                                 file_mappings[i].gen_bits,
612                                                 0,
613                                                 NULL);
614
615                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
616                 set.set_secdesc.in.file.handle = handle;
617                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
618                 set.set_secdesc.in.sd = sd;
619
620                 status = smb2_setinfo_file(tree, &set);
621                 CHECK_STATUS(status, NT_STATUS_OK);
622
623                 sd2 = security_descriptor_dacl_create(tctx,
624                                                  0, SID_NT_ANONYMOUS, NULL,
625                                                  owner_sid,
626                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
627                                                  file_mappings[i].specific_bits,
628                                                  0,
629                                                  NULL);
630
631                 status = smb2_getinfo_file(tree, tctx, &q);
632                 CHECK_STATUS(status, NT_STATUS_OK);
633                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
634
635                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
636                 status = smb2_create(tree, tctx, &io);
637                 CHECK_STATUS(status, NT_STATUS_OK);
638                 CHECK_ACCESS_FLAGS(io.out.file.handle,
639                                    expected_mask_anon | dir_mappings[i].specific_bits);
640                 smb2_util_close(tree, io.out.file.handle);
641         }
642
643         torture_comment(tctx, "put back original sd\n");
644         set.set_secdesc.in.sd = sd_orig;
645         status = smb2_setinfo_file(tree, &set);
646         CHECK_STATUS(status, NT_STATUS_OK);
647
648         smb2_util_close(tree, handle);
649         smb2_util_unlink(tree, fname);
650
651 done:
652         smb2_util_close(tree, handle);
653         smb2_deltree(tree, BASEDIR);
654         smb2_tdis(tree);
655         smb2_logoff(tree->session);
656         return ret;
657 }
658
659
660 /*
661   see what access bits the owner of a file always gets
662   Note: This test was copied from raw/acls.c.
663 */
664 static bool test_owner_bits(struct torture_context *tctx, struct smb2_tree *tree)
665 {
666         NTSTATUS status;
667         struct smb2_create io;
668         const char *fname = BASEDIR "\\test_owner_bits.txt";
669         bool ret = true;
670         struct smb2_handle handle = {{0}};
671         int i;
672         union smb_fileinfo q;
673         union smb_setfileinfo set;
674         struct security_descriptor *sd, *sd_orig;
675         const char *owner_sid;
676         uint32_t expected_bits;
677
678         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
679                 return false;
680
681         torture_comment(tctx, "TESTING FILE OWNER BITS\n");
682
683         ZERO_STRUCT(io);
684         io.level = RAW_OPEN_SMB2;
685         io.in.create_flags = 0;
686         io.in.desired_access =
687                 SEC_STD_READ_CONTROL |
688                 SEC_STD_WRITE_DAC |
689                 SEC_STD_WRITE_OWNER;
690         io.in.create_options = 0;
691         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
692         io.in.share_access =
693                 NTCREATEX_SHARE_ACCESS_READ |
694                 NTCREATEX_SHARE_ACCESS_WRITE;
695         io.in.alloc_size = 0;
696         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
697         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
698         io.in.security_flags = 0;
699         io.in.fname = fname;
700         status = smb2_create(tree, tctx, &io);
701         CHECK_STATUS(status, NT_STATUS_OK);
702         handle = io.out.file.handle;
703
704         torture_comment(tctx, "get the original sd\n");
705         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
706         q.query_secdesc.in.file.handle = handle;
707         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
708         status = smb2_getinfo_file(tree, tctx, &q);
709         CHECK_STATUS(status, NT_STATUS_OK);
710         sd_orig = q.query_secdesc.out.sd;
711
712         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
713
714 /*
715  * XXX: The smblsa calls use SMB as their transport - need to get rid of
716  * dependency.
717  */
718 /*
719         status = smblsa_sid_check_privilege(cli,
720                                             owner_sid,
721                                             sec_privilege_name(SEC_PRIV_RESTORE));
722         has_restore_privilege = NT_STATUS_IS_OK(status);
723         if (!NT_STATUS_IS_OK(status)) {
724                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
725         }
726         torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
727
728         status = smblsa_sid_check_privilege(cli,
729                                             owner_sid,
730                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
731         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
732         if (!NT_STATUS_IS_OK(status)) {
733                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
734         }
735         torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
736 */
737
738         sd = security_descriptor_dacl_create(tctx,
739                                         0, NULL, NULL,
740                                         owner_sid,
741                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
742                                         SEC_FILE_WRITE_DATA,
743                                         0,
744                                         NULL);
745
746         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
747         set.set_secdesc.in.file.handle = handle;
748         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
749         set.set_secdesc.in.sd = sd;
750
751         status = smb2_setinfo_file(tree, &set);
752         CHECK_STATUS(status, NT_STATUS_OK);
753
754         expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
755
756         for (i=0;i<16;i++) {
757                 uint32_t bit = (1<<i);
758                 io.in.desired_access = bit;
759                 status = smb2_create(tree, tctx, &io);
760                 if (expected_bits & bit) {
761                         if (!NT_STATUS_IS_OK(status)) {
762                                 torture_warning(tctx, "failed with access mask 0x%08x of expected 0x%08x\n",
763                                        bit, expected_bits);
764                         }
765                         CHECK_STATUS(status, NT_STATUS_OK);
766                         CHECK_ACCESS_FLAGS(io.out.file.handle, bit);
767                         smb2_util_close(tree, io.out.file.handle);
768                 } else {
769                         if (NT_STATUS_IS_OK(status)) {
770                                 torture_warning(tctx, "open succeeded with access mask 0x%08x of "
771                                         "expected 0x%08x - should fail\n",
772                                        bit, expected_bits);
773                         }
774                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
775                 }
776         }
777
778         torture_comment(tctx, "put back original sd\n");
779         set.set_secdesc.in.sd = sd_orig;
780         status = smb2_setinfo_file(tree, &set);
781         CHECK_STATUS(status, NT_STATUS_OK);
782
783 done:
784         smb2_util_close(tree, handle);
785         smb2_util_unlink(tree, fname);
786         smb2_deltree(tree, BASEDIR);
787         smb2_tdis(tree);
788         smb2_logoff(tree->session);
789         return ret;
790 }
791
792
793
794 /*
795   test the inheritance of ACL flags onto new files and directories
796   Note: This test was copied from raw/acls.c.
797 */
798 static bool test_inheritance(struct torture_context *tctx, struct smb2_tree *tree)
799 {
800         NTSTATUS status;
801         struct smb2_create io;
802         const char *dname = BASEDIR "\\inheritance";
803         const char *fname1 = BASEDIR "\\inheritance\\testfile";
804         const char *fname2 = BASEDIR "\\inheritance\\testdir";
805         bool ret = true;
806         struct smb2_handle handle = {{0}};
807         struct smb2_handle handle2 = {{0}};
808         int i;
809         union smb_fileinfo q;
810         union smb_setfileinfo set;
811         struct security_descriptor *sd, *sd2, *sd_orig=NULL, *sd_def1, *sd_def2;
812         const char *owner_sid;
813         const struct dom_sid *creator_owner;
814         const struct {
815                 uint32_t parent_flags;
816                 uint32_t file_flags;
817                 uint32_t dir_flags;
818         } test_flags[] = {
819                 {
820                         0,
821                         0,
822                         0
823                 },
824                 {
825                         SEC_ACE_FLAG_OBJECT_INHERIT,
826                         0,
827                         SEC_ACE_FLAG_OBJECT_INHERIT |
828                         SEC_ACE_FLAG_INHERIT_ONLY,
829                 },
830                 {
831                         SEC_ACE_FLAG_CONTAINER_INHERIT,
832                         0,
833                         SEC_ACE_FLAG_CONTAINER_INHERIT,
834                 },
835                 {
836                         SEC_ACE_FLAG_OBJECT_INHERIT |
837                         SEC_ACE_FLAG_CONTAINER_INHERIT,
838                         0,
839                         SEC_ACE_FLAG_OBJECT_INHERIT |
840                         SEC_ACE_FLAG_CONTAINER_INHERIT,
841                 },
842                 {
843                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
844                         0,
845                         0,
846                 },
847                 {
848                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
849                         SEC_ACE_FLAG_OBJECT_INHERIT,
850                         0,
851                         0,
852                 },
853                 {
854                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
855                         SEC_ACE_FLAG_CONTAINER_INHERIT,
856                         0,
857                         0,
858                 },
859                 {
860                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
861                         SEC_ACE_FLAG_CONTAINER_INHERIT |
862                         SEC_ACE_FLAG_OBJECT_INHERIT,
863                         0,
864                         0,
865                 },
866                 {
867                         SEC_ACE_FLAG_INHERIT_ONLY,
868                         0,
869                         0,
870                 },
871                 {
872                         SEC_ACE_FLAG_INHERIT_ONLY |
873                         SEC_ACE_FLAG_OBJECT_INHERIT,
874                         0,
875                         SEC_ACE_FLAG_OBJECT_INHERIT |
876                         SEC_ACE_FLAG_INHERIT_ONLY,
877                 },
878                 {
879                         SEC_ACE_FLAG_INHERIT_ONLY |
880                         SEC_ACE_FLAG_CONTAINER_INHERIT,
881                         0,
882                         SEC_ACE_FLAG_CONTAINER_INHERIT,
883                 },
884                 {
885                         SEC_ACE_FLAG_INHERIT_ONLY |
886                         SEC_ACE_FLAG_CONTAINER_INHERIT |
887                         SEC_ACE_FLAG_OBJECT_INHERIT,
888                         0,
889                         SEC_ACE_FLAG_CONTAINER_INHERIT |
890                         SEC_ACE_FLAG_OBJECT_INHERIT,
891                 },
892                 {
893                         SEC_ACE_FLAG_INHERIT_ONLY |
894                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
895                         0,
896                         0,
897                 },
898                 {
899                         SEC_ACE_FLAG_INHERIT_ONLY |
900                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
901                         SEC_ACE_FLAG_OBJECT_INHERIT,
902                         0,
903                         0,
904                 },
905                 {
906                         SEC_ACE_FLAG_INHERIT_ONLY |
907                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
908                         SEC_ACE_FLAG_CONTAINER_INHERIT,
909                         0,
910                         0,
911                 },
912                 {
913                         SEC_ACE_FLAG_INHERIT_ONLY |
914                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
915                         SEC_ACE_FLAG_CONTAINER_INHERIT |
916                         SEC_ACE_FLAG_OBJECT_INHERIT,
917                         0,
918                         0,
919                 }
920         };
921
922         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
923                 return false;
924
925         torture_comment(tctx, "TESTING ACL INHERITANCE\n");
926
927         ZERO_STRUCT(io);
928         io.level = RAW_OPEN_SMB2;
929         io.in.create_flags = 0;
930         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
931         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
932         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
933         io.in.share_access = 0;
934         io.in.alloc_size = 0;
935         io.in.create_disposition = NTCREATEX_DISP_CREATE;
936         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
937         io.in.security_flags = 0;
938         io.in.fname = dname;
939
940         status = smb2_create(tree, tctx, &io);
941         CHECK_STATUS(status, NT_STATUS_OK);
942         handle = io.out.file.handle;
943
944         torture_comment(tctx, "get the original sd\n");
945         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
946         q.query_secdesc.in.file.handle = handle;
947         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
948         status = smb2_getinfo_file(tree, tctx, &q);
949         CHECK_STATUS(status, NT_STATUS_OK);
950         sd_orig = q.query_secdesc.out.sd;
951
952         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
953
954         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
955
956         /*
957          * The Windows Default ACL for a new file, when there is no ACL to be
958          * inherited: FullControl for the owner and SYSTEM.
959          */
960         sd_def1 = security_descriptor_dacl_create(tctx,
961                                             0, owner_sid, NULL,
962                                             owner_sid,
963                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
964                                             SEC_RIGHTS_FILE_ALL,
965                                             0,
966                                             SID_NT_SYSTEM,
967                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
968                                             SEC_RIGHTS_FILE_ALL,
969                                             0,
970                                             NULL);
971
972         /*
973          * Use this in the case the system being tested does not add an ACE for
974          * the SYSTEM SID.
975          */
976         sd_def2 = security_descriptor_dacl_create(tctx,
977                                             0, owner_sid, NULL,
978                                             owner_sid,
979                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
980                                             SEC_RIGHTS_FILE_ALL,
981                                             0,
982                                             NULL);
983
984         creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER);
985
986         for (i=0;i<ARRAY_SIZE(test_flags);i++) {
987                 sd = security_descriptor_dacl_create(tctx,
988                                                 0, NULL, NULL,
989                                                 SID_CREATOR_OWNER,
990                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
991                                                 SEC_FILE_WRITE_DATA,
992                                                 test_flags[i].parent_flags,
993                                                 SID_WORLD,
994                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
995                                                 SEC_FILE_ALL | SEC_STD_ALL,
996                                                 0,
997                                                 NULL);
998                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
999                 set.set_secdesc.in.file.handle = handle;
1000                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1001                 set.set_secdesc.in.sd = sd;
1002                 status = smb2_setinfo_file(tree, &set);
1003                 CHECK_STATUS(status, NT_STATUS_OK);
1004
1005                 io.in.fname = fname1;
1006                 io.in.create_options = 0;
1007                 status = smb2_create(tree, tctx, &io);
1008                 CHECK_STATUS(status, NT_STATUS_OK);
1009                 handle2 = io.out.file.handle;
1010
1011                 q.query_secdesc.in.file.handle = handle2;
1012                 status = smb2_getinfo_file(tree, tctx, &q);
1013                 CHECK_STATUS(status, NT_STATUS_OK);
1014
1015                 smb2_util_close(tree, handle2);
1016                 smb2_util_unlink(tree, fname1);
1017
1018                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
1019                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
1020                             !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
1021                                 torture_warning(tctx, "Expected default sd:\n");
1022                                 NDR_PRINT_DEBUG(security_descriptor, sd_def1);
1023                                 torture_warning(tctx, "at %d - got:\n", i);
1024                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1025                         }
1026                         goto check_dir;
1027                 }
1028
1029                 if (q.query_secdesc.out.sd->dacl == NULL ||
1030                     q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1031                     q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1032                     !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1033                                    sd_orig->owner_sid)) {
1034                         torture_warning(tctx, "Bad sd in child file at %d\n", i);
1035                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1036                         ret = false;
1037                         goto check_dir;
1038                 }
1039
1040                 if (q.query_secdesc.out.sd->dacl->aces[0].flags !=
1041                     test_flags[i].file_flags) {
1042                         torture_warning(tctx, "incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
1043                                q.query_secdesc.out.sd->dacl->aces[0].flags,
1044                                test_flags[i].file_flags,
1045                                test_flags[i].parent_flags,
1046                                i);
1047                         ret = false;
1048                 }
1049
1050         check_dir:
1051                 io.in.fname = fname2;
1052                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1053                 status = smb2_create(tree, tctx, &io);
1054                 CHECK_STATUS(status, NT_STATUS_OK);
1055                 handle2 = io.out.file.handle;
1056
1057                 q.query_secdesc.in.file.handle = handle2;
1058                 status = smb2_getinfo_file(tree, tctx, &q);
1059                 CHECK_STATUS(status, NT_STATUS_OK);
1060
1061                 smb2_util_close(tree, handle2);
1062                 smb2_util_rmdir(tree, fname2);
1063
1064                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1065                     (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
1066                      (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
1067                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
1068                             !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
1069                                 torture_warning(tctx, "Expected default sd for dir at %d:\n", i);
1070                                 NDR_PRINT_DEBUG(security_descriptor, sd_def1);
1071                                 torture_warning(tctx, "got:\n");
1072                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1073                         }
1074                         continue;
1075                 }
1076
1077                 if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
1078                     (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
1079                         if (q.query_secdesc.out.sd->dacl == NULL ||
1080                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1081                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1082                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1083                                            sd_orig->owner_sid) ||
1084                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1085                                 torture_warning(tctx, "(CI & NP) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1086                                        test_flags[i].dir_flags,
1087                                        test_flags[i].parent_flags, i);
1088                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1089                                 torture_warning(tctx, "FYI, here is the parent sd:\n");
1090                                 NDR_PRINT_DEBUG(security_descriptor, sd);
1091                                 ret = false;
1092                                 continue;
1093                         }
1094                 } else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
1095                         if (q.query_secdesc.out.sd->dacl == NULL ||
1096                             q.query_secdesc.out.sd->dacl->num_aces != 2 ||
1097                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1098                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1099                                            sd_orig->owner_sid) ||
1100                             q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
1101                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
1102                                            creator_owner) ||
1103                             q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
1104                             q.query_secdesc.out.sd->dacl->aces[1].flags !=
1105                             (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
1106                                 torture_warning(tctx, "(CI) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1107                                        test_flags[i].dir_flags,
1108                                        test_flags[i].parent_flags, i);
1109                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1110                                 torture_warning(tctx, "FYI, here is the parent sd:\n");
1111                                 NDR_PRINT_DEBUG(security_descriptor, sd);
1112                                 ret = false;
1113                                 continue;
1114                         }
1115                 } else {
1116                         if (q.query_secdesc.out.sd->dacl == NULL ||
1117                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
1118                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
1119                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
1120                                            creator_owner) ||
1121                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
1122                                 torture_warning(tctx, "(0) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
1123                                        test_flags[i].dir_flags,
1124                                        test_flags[i].parent_flags, i);
1125                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
1126                                 torture_warning(tctx, "FYI, here is the parent sd:\n");
1127                                 NDR_PRINT_DEBUG(security_descriptor, sd);
1128                                 ret = false;
1129                                 continue;
1130                         }
1131                 }
1132         }
1133
1134         torture_comment(tctx, "Testing access checks on inherited create with %s\n", fname1);
1135         sd = security_descriptor_dacl_create(tctx,
1136                                         0, NULL, NULL,
1137                                         owner_sid,
1138                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1139                                         SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1140                                         SEC_ACE_FLAG_OBJECT_INHERIT,
1141                                         SID_WORLD,
1142                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1143                                         SEC_FILE_ALL | SEC_STD_ALL,
1144                                         0,
1145                                         NULL);
1146         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1147         set.set_secdesc.in.file.handle = handle;
1148         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1149         set.set_secdesc.in.sd = sd;
1150         status = smb2_setinfo_file(tree, &set);
1151         CHECK_STATUS(status, NT_STATUS_OK);
1152
1153         /* Check DACL we just set. */
1154         torture_comment(tctx, "checking new sd\n");
1155         q.query_secdesc.in.file.handle = handle;
1156         q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
1157         status = smb2_getinfo_file(tree, tctx, &q);
1158         CHECK_STATUS(status, NT_STATUS_OK);
1159         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
1160
1161         io.in.fname = fname1;
1162         io.in.create_options = 0;
1163         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
1164         io.in.create_disposition = NTCREATEX_DISP_CREATE;
1165         status = smb2_create(tree, tctx, &io);
1166         CHECK_STATUS(status, NT_STATUS_OK);
1167         handle2 = io.out.file.handle;
1168         CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
1169
1170         q.query_secdesc.in.file.handle = handle2;
1171         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1172         status = smb2_getinfo_file(tree, tctx, &q);
1173         CHECK_STATUS(status, NT_STATUS_OK);
1174         smb2_util_close(tree, handle2);
1175
1176         sd2 = security_descriptor_dacl_create(tctx,
1177                                          0, owner_sid, NULL,
1178                                          owner_sid,
1179                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
1180                                          SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1181                                          0,
1182                                          NULL);
1183         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1184
1185         io.in.create_disposition = NTCREATEX_DISP_OPEN;
1186         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
1187         status = smb2_create(tree, tctx, &io);
1188         if (NT_STATUS_IS_OK(status)) {
1189                 torture_warning(tctx, "failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
1190                 ret = false;
1191                 handle2 = io.out.file.handle;
1192                 CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
1193                 smb2_util_close(tree, handle2);
1194         } else {
1195                 if (torture_setting_bool(tctx, "hide_on_access_denied",
1196                                          false)) {
1197                         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1198                 } else {
1199                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1200                 }
1201         }
1202
1203         torture_comment(tctx, "trying without execute\n");
1204         io.in.create_disposition = NTCREATEX_DISP_OPEN;
1205         io.in.desired_access = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
1206         status = smb2_create(tree, tctx, &io);
1207         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1208                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1209         } else {
1210                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1211         }
1212
1213         torture_comment(tctx, "and with full permissions again\n");
1214         io.in.create_disposition = NTCREATEX_DISP_OPEN;
1215         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
1216         status = smb2_create(tree, tctx, &io);
1217         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1218                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1219         } else {
1220                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1221         }
1222
1223         io.in.desired_access = SEC_FILE_WRITE_DATA;
1224         status = smb2_create(tree, tctx, &io);
1225         CHECK_STATUS(status, NT_STATUS_OK);
1226         handle2 = io.out.file.handle;
1227         CHECK_ACCESS_FLAGS(handle2, SEC_FILE_WRITE_DATA);
1228         smb2_util_close(tree, handle2);
1229
1230         torture_comment(tctx, "put back original sd\n");
1231         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1232         set.set_secdesc.in.file.handle = handle;
1233         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1234         set.set_secdesc.in.sd = sd_orig;
1235         status = smb2_setinfo_file(tree, &set);
1236         CHECK_STATUS(status, NT_STATUS_OK);
1237
1238         smb2_util_close(tree, handle);
1239
1240         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
1241         status = smb2_create(tree, tctx, &io);
1242         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
1243                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1244         } else {
1245                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1246         }
1247
1248         io.in.desired_access = SEC_FILE_WRITE_DATA;
1249         status = smb2_create(tree, tctx, &io);
1250         CHECK_STATUS(status, NT_STATUS_OK);
1251         handle2 = io.out.file.handle;
1252         CHECK_ACCESS_FLAGS(handle2, SEC_FILE_WRITE_DATA);
1253         smb2_util_close(tree, handle2);
1254
1255         smb2_util_unlink(tree, fname1);
1256         smb2_util_rmdir(tree, dname);
1257
1258 done:
1259         if (sd_orig != NULL) {
1260                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1261                 set.set_secdesc.in.file.handle = handle;
1262                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1263                 set.set_secdesc.in.sd = sd_orig;
1264                 status = smb2_setinfo_file(tree, &set);
1265         }
1266
1267         smb2_util_close(tree, handle);
1268         smb2_deltree(tree, BASEDIR);
1269         smb2_tdis(tree);
1270         smb2_logoff(tree->session);
1271         return ret;
1272 }
1273
1274 static bool test_inheritance_flags(struct torture_context *tctx,
1275     struct smb2_tree *tree)
1276 {
1277         NTSTATUS status;
1278         struct smb2_create io;
1279         const char *dname = BASEDIR "\\inheritance";
1280         const char *fname1 = BASEDIR "\\inheritance\\testfile";
1281         bool ret = true;
1282         struct smb2_handle handle = {{0}};
1283         struct smb2_handle handle2 = {{0}};
1284         int i, j;
1285         union smb_fileinfo q;
1286         union smb_setfileinfo set;
1287         struct security_descriptor *sd, *sd2, *sd_orig=NULL;
1288         const char *owner_sid;
1289         struct {
1290                 uint32_t parent_set_sd_type; /* 3 options */
1291                 uint32_t parent_set_ace_inherit; /* 1 option */
1292                 uint32_t parent_get_sd_type;
1293                 uint32_t parent_get_ace_inherit;
1294                 uint32_t child_get_sd_type;
1295                 uint32_t child_get_ace_inherit;
1296         } tflags[16] = {{0}}; /* 2^4 */
1297
1298         for (i = 0; i < 15; i++) {
1299                 torture_comment(tctx, "i=%d:", i);
1300
1301                 if (i & 1) {
1302                         tflags[i].parent_set_sd_type |=
1303                             SEC_DESC_DACL_AUTO_INHERITED;
1304                         torture_comment(tctx, "AUTO_INHERITED, ");
1305                 }
1306                 if (i & 2) {
1307                         tflags[i].parent_set_sd_type |=
1308                             SEC_DESC_DACL_AUTO_INHERIT_REQ;
1309                         torture_comment(tctx, "AUTO_INHERIT_REQ, ");
1310                 }
1311                 if (i & 4) {
1312                         tflags[i].parent_set_sd_type |=
1313                             SEC_DESC_DACL_PROTECTED;
1314                         torture_comment(tctx, "PROTECTED, ");
1315                         tflags[i].parent_get_sd_type |=
1316                             SEC_DESC_DACL_PROTECTED;
1317                 }
1318                 if (i & 8) {
1319                         tflags[i].parent_set_ace_inherit |=
1320                             SEC_ACE_FLAG_INHERITED_ACE;
1321                         torture_comment(tctx, "INHERITED, ");
1322                         tflags[i].parent_get_ace_inherit |=
1323                             SEC_ACE_FLAG_INHERITED_ACE;
1324                 }
1325
1326                 if ((tflags[i].parent_set_sd_type &
1327                     (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) ==
1328                     (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) {
1329                         tflags[i].parent_get_sd_type |=
1330                             SEC_DESC_DACL_AUTO_INHERITED;
1331                         tflags[i].child_get_sd_type |=
1332                             SEC_DESC_DACL_AUTO_INHERITED;
1333                         tflags[i].child_get_ace_inherit |=
1334                             SEC_ACE_FLAG_INHERITED_ACE;
1335                         torture_comment(tctx, "  ... parent is AUTO INHERITED");
1336                 }
1337
1338                 if (tflags[i].parent_set_ace_inherit &
1339                     SEC_ACE_FLAG_INHERITED_ACE) {
1340                         tflags[i].parent_get_ace_inherit =
1341                             SEC_ACE_FLAG_INHERITED_ACE;
1342                         torture_comment(tctx, "  ... parent ACE is INHERITED");
1343                 }
1344
1345                 torture_comment(tctx, "\n");
1346         }
1347
1348         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
1349                 return false;
1350
1351         torture_comment(tctx, "TESTING ACL INHERITANCE FLAGS\n");
1352
1353         ZERO_STRUCT(io);
1354         io.level = RAW_OPEN_SMB2;
1355         io.in.create_flags = 0;
1356         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
1357         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1358         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1359         io.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
1360         io.in.alloc_size = 0;
1361         io.in.create_disposition = NTCREATEX_DISP_CREATE;
1362         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
1363         io.in.security_flags = 0;
1364         io.in.fname = dname;
1365
1366         torture_comment(tctx, "creating initial directory %s\n", dname);
1367         status = smb2_create(tree, tctx, &io);
1368         CHECK_STATUS(status, NT_STATUS_OK);
1369         handle = io.out.file.handle;
1370
1371         torture_comment(tctx, "getting original sd\n");
1372         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1373         q.query_secdesc.in.file.handle = handle;
1374         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1375         status = smb2_getinfo_file(tree, tctx, &q);
1376         CHECK_STATUS(status, NT_STATUS_OK);
1377         sd_orig = q.query_secdesc.out.sd;
1378
1379         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1380         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
1381
1382         for (i=0; i < ARRAY_SIZE(tflags); i++) {
1383                 torture_comment(tctx, "setting a new sd on directory, pass #%d\n", i);
1384
1385                 sd = security_descriptor_dacl_create(tctx,
1386                                                 tflags[i].parent_set_sd_type,
1387                                                 NULL, NULL,
1388                                                 owner_sid,
1389                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1390                                                 SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1391                                                 SEC_ACE_FLAG_OBJECT_INHERIT |
1392                                                 SEC_ACE_FLAG_CONTAINER_INHERIT |
1393                                                 tflags[i].parent_set_ace_inherit,
1394                                                 SID_WORLD,
1395                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1396                                                 SEC_FILE_ALL | SEC_STD_ALL,
1397                                                 0,
1398                                                 NULL);
1399                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1400                 set.set_secdesc.in.file.handle = handle;
1401                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1402                 set.set_secdesc.in.sd = sd;
1403                 status = smb2_setinfo_file(tree, &set);
1404                 CHECK_STATUS(status, NT_STATUS_OK);
1405
1406                 /*
1407                  * Check DACL we just set, except change the bits to what they
1408                  * should be.
1409                  */
1410                 torture_comment(tctx, "  checking new sd\n");
1411
1412                 /* REQ bit should always be false. */
1413                 sd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
1414
1415                 if ((tflags[i].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
1416                         sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
1417
1418                 q.query_secdesc.in.file.handle = handle;
1419                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
1420                 status = smb2_getinfo_file(tree, tctx, &q);
1421                 CHECK_STATUS(status, NT_STATUS_OK);
1422                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
1423
1424                 /* Create file. */
1425                 torture_comment(tctx, "  creating file %s\n", fname1);
1426                 io.in.fname = fname1;
1427                 io.in.create_options = 0;
1428                 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1429                 io.in.desired_access = SEC_RIGHTS_FILE_ALL;
1430                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1431                 status = smb2_create(tree, tctx, &io);
1432                 CHECK_STATUS(status, NT_STATUS_OK);
1433                 handle2 = io.out.file.handle;
1434                 CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
1435
1436                 q.query_secdesc.in.file.handle = handle2;
1437                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1438                 status = smb2_getinfo_file(tree, tctx, &q);
1439                 CHECK_STATUS(status, NT_STATUS_OK);
1440
1441                 torture_comment(tctx, "  checking sd on file %s\n", fname1);
1442                 sd2 = security_descriptor_dacl_create(tctx,
1443                                                  tflags[i].child_get_sd_type,
1444                                                  owner_sid, NULL,
1445                                                  owner_sid,
1446                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
1447                                                  SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1448                                                  tflags[i].child_get_ace_inherit,
1449                                                  NULL);
1450                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1451
1452                 /*
1453                  * Set new sd on file ... prove that the bits have nothing to
1454                  * do with the parents bits when manually setting an ACL. The
1455                  * _AUTO_INHERITED bit comes directly from the ACL set.
1456                  */
1457                 for (j = 0; j < ARRAY_SIZE(tflags); j++) {
1458                         torture_comment(tctx, "  setting new file sd, pass #%d\n", j);
1459
1460                         /* Change sd type. */
1461                         sd2->type &= ~(SEC_DESC_DACL_AUTO_INHERITED |
1462                             SEC_DESC_DACL_AUTO_INHERIT_REQ |
1463                             SEC_DESC_DACL_PROTECTED);
1464                         sd2->type |= tflags[j].parent_set_sd_type;
1465
1466                         sd2->dacl->aces[0].flags &=
1467                             ~SEC_ACE_FLAG_INHERITED_ACE;
1468                         sd2->dacl->aces[0].flags |=
1469                             tflags[j].parent_set_ace_inherit;
1470
1471                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1472                         set.set_secdesc.in.file.handle = handle2;
1473                         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1474                         set.set_secdesc.in.sd = sd2;
1475                         status = smb2_setinfo_file(tree, &set);
1476                         CHECK_STATUS(status, NT_STATUS_OK);
1477
1478                         /* Check DACL we just set. */
1479                         sd2->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
1480                         if ((tflags[j].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
1481                                 sd2->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
1482
1483                         q.query_secdesc.in.file.handle = handle2;
1484                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1485                         status = smb2_getinfo_file(tree, tctx, &q);
1486                         CHECK_STATUS(status, NT_STATUS_OK);
1487
1488                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1489                 }
1490
1491                 smb2_util_close(tree, handle2);
1492                 smb2_util_unlink(tree, fname1);
1493         }
1494
1495 done:
1496         smb2_util_close(tree, handle);
1497         smb2_deltree(tree, BASEDIR);
1498         smb2_tdis(tree);
1499         smb2_logoff(tree->session);
1500         return ret;
1501 }
1502
1503 /*
1504  * This is basically a copy of test_inheritance_flags() with an additional twist
1505  * to change the owner of the testfile, verifying that the security descriptor
1506  * flags are not altered.
1507  */
1508 static bool test_sd_flags_vs_chown(struct torture_context *tctx,
1509                                    struct smb2_tree *tree)
1510 {
1511         NTSTATUS status;
1512         struct smb2_create io;
1513         const char *dname = BASEDIR "\\inheritance";
1514         const char *fname1 = BASEDIR "\\inheritance\\testfile";
1515         bool ret = true;
1516         struct smb2_handle handle = {{0}};
1517         struct smb2_handle handle2 = {{0}};
1518         int i, j;
1519         union smb_fileinfo q;
1520         union smb_setfileinfo set;
1521         struct security_descriptor *sd, *sd2, *sd_orig=NULL;
1522         struct security_descriptor *owner_sd = NULL;
1523         const char *owner_sid_string = NULL;
1524         struct dom_sid *owner_sid = NULL;
1525         struct dom_sid world_sid = global_sid_World;
1526         struct {
1527                 uint32_t parent_set_sd_type; /* 3 options */
1528                 uint32_t parent_set_ace_inherit; /* 1 option */
1529                 uint32_t parent_get_sd_type;
1530                 uint32_t parent_get_ace_inherit;
1531                 uint32_t child_get_sd_type;
1532                 uint32_t child_get_ace_inherit;
1533         } tflags[16] = {{0}}; /* 2^4 */
1534
1535         owner_sd = security_descriptor_dacl_create(tctx,
1536                                                    0,
1537                                                    SID_WORLD,
1538                                                    NULL,
1539                                                    NULL);
1540         torture_assert_not_null_goto(tctx, owner_sd, ret, done,
1541                                      "security_descriptor_dacl_create failed\n");
1542
1543         for (i = 0; i < 15; i++) {
1544                 torture_comment(tctx, "i=%d:", i);
1545
1546                 if (i & 1) {
1547                         tflags[i].parent_set_sd_type |=
1548                             SEC_DESC_DACL_AUTO_INHERITED;
1549                         torture_comment(tctx, "AUTO_INHERITED, ");
1550                 }
1551                 if (i & 2) {
1552                         tflags[i].parent_set_sd_type |=
1553                             SEC_DESC_DACL_AUTO_INHERIT_REQ;
1554                         torture_comment(tctx, "AUTO_INHERIT_REQ, ");
1555                 }
1556                 if (i & 4) {
1557                         tflags[i].parent_set_sd_type |=
1558                             SEC_DESC_DACL_PROTECTED;
1559                         torture_comment(tctx, "PROTECTED, ");
1560                         tflags[i].parent_get_sd_type |=
1561                             SEC_DESC_DACL_PROTECTED;
1562                 }
1563                 if (i & 8) {
1564                         tflags[i].parent_set_ace_inherit |=
1565                             SEC_ACE_FLAG_INHERITED_ACE;
1566                         torture_comment(tctx, "INHERITED, ");
1567                         tflags[i].parent_get_ace_inherit |=
1568                             SEC_ACE_FLAG_INHERITED_ACE;
1569                 }
1570
1571                 if ((tflags[i].parent_set_sd_type &
1572                     (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) ==
1573                     (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) {
1574                         tflags[i].parent_get_sd_type |=
1575                             SEC_DESC_DACL_AUTO_INHERITED;
1576                         tflags[i].child_get_sd_type |=
1577                             SEC_DESC_DACL_AUTO_INHERITED;
1578                         tflags[i].child_get_ace_inherit |=
1579                             SEC_ACE_FLAG_INHERITED_ACE;
1580                         torture_comment(tctx, "  ... parent is AUTO INHERITED");
1581                 }
1582
1583                 if (tflags[i].parent_set_ace_inherit &
1584                     SEC_ACE_FLAG_INHERITED_ACE) {
1585                         tflags[i].parent_get_ace_inherit =
1586                             SEC_ACE_FLAG_INHERITED_ACE;
1587                         torture_comment(tctx, "  ... parent ACE is INHERITED");
1588                 }
1589
1590                 torture_comment(tctx, "\n");
1591         }
1592
1593         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
1594                 return false;
1595
1596         torture_comment(tctx, "TESTING ACL INHERITANCE FLAGS\n");
1597
1598         ZERO_STRUCT(io);
1599         io.level = RAW_OPEN_SMB2;
1600         io.in.create_flags = 0;
1601         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
1602         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1603         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1604         io.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
1605         io.in.alloc_size = 0;
1606         io.in.create_disposition = NTCREATEX_DISP_CREATE;
1607         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
1608         io.in.security_flags = 0;
1609         io.in.fname = dname;
1610
1611         torture_comment(tctx, "creating initial directory %s\n", dname);
1612         status = smb2_create(tree, tctx, &io);
1613         CHECK_STATUS(status, NT_STATUS_OK);
1614         handle = io.out.file.handle;
1615
1616         torture_comment(tctx, "getting original sd\n");
1617         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1618         q.query_secdesc.in.file.handle = handle;
1619         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1620         status = smb2_getinfo_file(tree, tctx, &q);
1621         CHECK_STATUS(status, NT_STATUS_OK);
1622         sd_orig = q.query_secdesc.out.sd;
1623
1624         owner_sid = sd_orig->owner_sid;
1625         owner_sid_string = dom_sid_string(tctx, sd_orig->owner_sid);
1626         torture_comment(tctx, "owner_sid is %s\n", owner_sid_string);
1627
1628         for (i=0; i < ARRAY_SIZE(tflags); i++) {
1629                 torture_comment(tctx, "setting a new sd on directory, pass #%d\n", i);
1630
1631                 sd = security_descriptor_dacl_create(tctx,
1632                                                 tflags[i].parent_set_sd_type,
1633                                                 NULL, NULL,
1634                                                 owner_sid_string,
1635                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1636                                                 SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1637                                                 SEC_ACE_FLAG_OBJECT_INHERIT |
1638                                                 SEC_ACE_FLAG_CONTAINER_INHERIT |
1639                                                 tflags[i].parent_set_ace_inherit,
1640                                                 SID_WORLD,
1641                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1642                                                 SEC_FILE_ALL | SEC_STD_ALL,
1643                                                 0,
1644                                                 NULL);
1645                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1646                 set.set_secdesc.in.file.handle = handle;
1647                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1648                 set.set_secdesc.in.sd = sd;
1649                 status = smb2_setinfo_file(tree, &set);
1650                 CHECK_STATUS(status, NT_STATUS_OK);
1651
1652                 /*
1653                  * Check DACL we just set, except change the bits to what they
1654                  * should be.
1655                  */
1656                 torture_comment(tctx, "  checking new sd\n");
1657
1658                 /* REQ bit should always be false. */
1659                 sd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
1660
1661                 if ((tflags[i].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
1662                         sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
1663
1664                 q.query_secdesc.in.file.handle = handle;
1665                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
1666                 status = smb2_getinfo_file(tree, tctx, &q);
1667                 CHECK_STATUS(status, NT_STATUS_OK);
1668                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
1669
1670                 /* Create file. */
1671                 torture_comment(tctx, "  creating file %s\n", fname1);
1672                 io.in.fname = fname1;
1673                 io.in.create_options = 0;
1674                 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1675                 io.in.desired_access = SEC_RIGHTS_FILE_ALL;
1676                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1677                 status = smb2_create(tree, tctx, &io);
1678                 CHECK_STATUS(status, NT_STATUS_OK);
1679                 handle2 = io.out.file.handle;
1680                 CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
1681
1682                 q.query_secdesc.in.file.handle = handle2;
1683                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1684                 status = smb2_getinfo_file(tree, tctx, &q);
1685                 CHECK_STATUS(status, NT_STATUS_OK);
1686
1687                 torture_comment(tctx, "  checking sd on file %s\n", fname1);
1688                 sd2 = security_descriptor_dacl_create(tctx,
1689                                                  tflags[i].child_get_sd_type,
1690                                                  owner_sid_string, NULL,
1691                                                  owner_sid_string,
1692                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
1693                                                  SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
1694                                                  tflags[i].child_get_ace_inherit,
1695                                                  NULL);
1696                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1697
1698                 /*
1699                  * Set new sd on file ... prove that the bits have nothing to
1700                  * do with the parents bits when manually setting an ACL. The
1701                  * _AUTO_INHERITED bit comes directly from the ACL set.
1702                  */
1703                 for (j = 0; j < ARRAY_SIZE(tflags); j++) {
1704                         torture_comment(tctx, "  setting new file sd, pass #%d\n", j);
1705
1706                         /* Change sd type. */
1707                         sd2->type &= ~(SEC_DESC_DACL_AUTO_INHERITED |
1708                             SEC_DESC_DACL_AUTO_INHERIT_REQ |
1709                             SEC_DESC_DACL_PROTECTED);
1710                         sd2->type |= tflags[j].parent_set_sd_type;
1711
1712                         sd2->dacl->aces[0].flags &=
1713                             ~SEC_ACE_FLAG_INHERITED_ACE;
1714                         sd2->dacl->aces[0].flags |=
1715                             tflags[j].parent_set_ace_inherit;
1716
1717                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1718                         set.set_secdesc.in.file.handle = handle2;
1719                         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1720                         set.set_secdesc.in.sd = sd2;
1721                         status = smb2_setinfo_file(tree, &set);
1722                         CHECK_STATUS(status, NT_STATUS_OK);
1723
1724                         /* Check DACL we just set. */
1725                         sd2->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
1726                         if ((tflags[j].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
1727                                 sd2->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
1728
1729                         q.query_secdesc.in.file.handle = handle2;
1730                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1731                         status = smb2_getinfo_file(tree, tctx, &q);
1732                         CHECK_STATUS(status, NT_STATUS_OK);
1733
1734                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1735
1736                         /*
1737                          * Check that changing ownder doesn't affect SD flags.
1738                          *
1739                          * Do this by first changing ownder to world and then
1740                          * back to the original ownder. Afterwards compare SD,
1741                          * should be the same.
1742                          */
1743                         owner_sd->owner_sid = &world_sid;
1744                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1745                         set.set_secdesc.in.file.handle = handle2;
1746                         set.set_secdesc.in.secinfo_flags = SECINFO_OWNER;
1747                         set.set_secdesc.in.sd = owner_sd;
1748                         status = smb2_setinfo_file(tree, &set);
1749                         CHECK_STATUS(status, NT_STATUS_OK);
1750
1751                         owner_sd->owner_sid = owner_sid;
1752                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1753                         set.set_secdesc.in.file.handle = handle2;
1754                         set.set_secdesc.in.secinfo_flags = SECINFO_OWNER;
1755                         set.set_secdesc.in.sd = owner_sd;
1756                         status = smb2_setinfo_file(tree, &set);
1757                         CHECK_STATUS(status, NT_STATUS_OK);
1758
1759                         q.query_secdesc.in.file.handle = handle2;
1760                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1761                         status = smb2_getinfo_file(tree, tctx, &q);
1762                         CHECK_STATUS(status, NT_STATUS_OK);
1763
1764                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
1765                         torture_assert_goto(tctx, ret, ret, done, "CHECK_SECURITY_DESCRIPTOR failed\n");
1766                 }
1767
1768                 smb2_util_close(tree, handle2);
1769                 smb2_util_unlink(tree, fname1);
1770         }
1771
1772 done:
1773         smb2_util_close(tree, handle);
1774         smb2_deltree(tree, BASEDIR);
1775         smb2_tdis(tree);
1776         smb2_logoff(tree->session);
1777         return ret;
1778 }
1779
1780 /*
1781   test dynamic acl inheritance
1782   Note: This test was copied from raw/acls.c.
1783 */
1784 static bool test_inheritance_dynamic(struct torture_context *tctx,
1785     struct smb2_tree *tree)
1786 {
1787         NTSTATUS status;
1788         struct smb2_create io;
1789         const char *dname = BASEDIR "\\inheritance";
1790         const char *fname1 = BASEDIR "\\inheritance\\testfile";
1791         bool ret = true;
1792         struct smb2_handle handle = {{0}};
1793         struct smb2_handle handle2 = {{0}};
1794         union smb_fileinfo q;
1795         union smb_setfileinfo set;
1796         struct security_descriptor *sd, *sd_orig=NULL;
1797         const char *owner_sid;
1798
1799         torture_comment(tctx, "TESTING DYNAMIC ACL INHERITANCE\n");
1800
1801         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
1802                 return false;
1803
1804         ZERO_STRUCT(io);
1805         io.level = RAW_OPEN_SMB2;
1806         io.in.create_flags = 0;
1807         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
1808         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1809         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1810         io.in.share_access = 0;
1811         io.in.alloc_size = 0;
1812         io.in.create_disposition = NTCREATEX_DISP_CREATE;
1813         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
1814         io.in.security_flags = 0;
1815         io.in.fname = dname;
1816
1817         status = smb2_create(tree, tctx, &io);
1818         CHECK_STATUS(status, NT_STATUS_OK);
1819         handle = io.out.file.handle;
1820
1821         torture_comment(tctx, "get the original sd\n");
1822         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
1823         q.query_secdesc.in.file.handle = handle;
1824         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
1825         status = smb2_getinfo_file(tree, tctx, &q);
1826         CHECK_STATUS(status, NT_STATUS_OK);
1827         sd_orig = q.query_secdesc.out.sd;
1828
1829         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
1830
1831         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
1832
1833         sd = security_descriptor_dacl_create(tctx,
1834                                         0, NULL, NULL,
1835                                         owner_sid,
1836                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1837                                         SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
1838                                         SEC_ACE_FLAG_OBJECT_INHERIT,
1839                                         NULL);
1840         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1841
1842         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1843         set.set_secdesc.in.file.handle = handle;
1844         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1845         set.set_secdesc.in.sd = sd;
1846         status = smb2_setinfo_file(tree, &set);
1847         CHECK_STATUS(status, NT_STATUS_OK);
1848
1849         torture_comment(tctx, "create a file with an inherited acl\n");
1850         io.in.fname = fname1;
1851         io.in.create_options = 0;
1852         io.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
1853         io.in.create_disposition = NTCREATEX_DISP_CREATE;
1854         status = smb2_create(tree, tctx, &io);
1855         CHECK_STATUS(status, NT_STATUS_OK);
1856         handle2 = io.out.file.handle;
1857         smb2_util_close(tree, handle2);
1858
1859         torture_comment(tctx, "try and access file with base rights - should be OK\n");
1860         io.in.desired_access = SEC_FILE_WRITE_DATA;
1861         io.in.create_disposition = NTCREATEX_DISP_OPEN;
1862         status = smb2_create(tree, tctx, &io);
1863         CHECK_STATUS(status, NT_STATUS_OK);
1864         handle2 = io.out.file.handle;
1865         smb2_util_close(tree, handle2);
1866
1867         torture_comment(tctx, "try and access file with extra rights - should be denied\n");
1868         io.in.desired_access = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1869         status = smb2_create(tree, tctx, &io);
1870         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1871
1872         torture_comment(tctx, "update parent sd\n");
1873         sd = security_descriptor_dacl_create(tctx,
1874                                         0, NULL, NULL,
1875                                         owner_sid,
1876                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1877                                         SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE,
1878                                         SEC_ACE_FLAG_OBJECT_INHERIT,
1879                                         NULL);
1880         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
1881
1882         set.set_secdesc.in.sd = sd;
1883         status = smb2_setinfo_file(tree, &set);
1884         CHECK_STATUS(status, NT_STATUS_OK);
1885
1886         torture_comment(tctx, "try and access file with base rights - should be OK\n");
1887         io.in.desired_access = SEC_FILE_WRITE_DATA;
1888         status = smb2_create(tree, tctx, &io);
1889         CHECK_STATUS(status, NT_STATUS_OK);
1890         handle2 = io.out.file.handle;
1891         smb2_util_close(tree, handle2);
1892
1893
1894         torture_comment(tctx, "try and access now - should be OK if dynamic inheritance works\n");
1895         io.in.desired_access = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
1896         status = smb2_create(tree, tctx, &io);
1897         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1898                 torture_comment(tctx, "Server does not have dynamic inheritance\n");
1899         }
1900         if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1901                 torture_comment(tctx, "Server does have dynamic inheritance\n");
1902         }
1903         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
1904
1905         smb2_util_unlink(tree, fname1);
1906
1907 done:
1908         torture_comment(tctx, "put back original sd\n");
1909         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
1910         set.set_secdesc.in.file.handle = handle;
1911         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
1912         set.set_secdesc.in.sd = sd_orig;
1913         status = smb2_setinfo_file(tree, &set);
1914
1915         smb2_util_close(tree, handle);
1916         smb2_util_rmdir(tree, dname);
1917         smb2_deltree(tree, BASEDIR);
1918         smb2_tdis(tree);
1919         smb2_logoff(tree->session);
1920
1921         return ret;
1922 }
1923
1924 #define CHECK_STATUS_FOR_BIT_ACTION(status, bits, action) do { \
1925         if (!(bits & desired_64)) {\
1926                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); \
1927                 action; \
1928         } else { \
1929                 CHECK_STATUS(status, NT_STATUS_OK); \
1930         } \
1931 } while (0)
1932
1933 #define CHECK_STATUS_FOR_BIT(status, bits, access) do { \
1934         if (NT_STATUS_IS_OK(status)) { \
1935                 if (!(granted & access)) {\
1936                         ret = false; \
1937                         torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are not granted! granted[0x%08X] desired[0x%08X]\n", \
1938                                __location__, nt_errstr(status), access, granted, desired); \
1939                         goto done; \
1940                 } \
1941         } else { \
1942                 if (granted & access) {\
1943                         ret = false; \
1944                         torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are granted! granted[0x%08X] desired[0x%08X]\n", \
1945                                __location__, nt_errstr(status), access, granted, desired); \
1946                         goto done; \
1947                 } \
1948         } \
1949         CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \
1950 } while (0)
1951
1952 #if 0
1953 /* test what access mask is needed for getting and setting security_descriptors */
1954 /* Note: This test was copied from raw/acls.c. */
1955 static bool test_sd_get_set(struct torture_context *tctx, struct smb2_tree *tree)
1956 {
1957         NTSTATUS status;
1958         bool ret = true;
1959         struct smb2_create io;
1960         union smb_fileinfo fi;
1961         union smb_setfileinfo si;
1962         struct security_descriptor *sd;
1963         struct security_descriptor *sd_owner = NULL;
1964         struct security_descriptor *sd_group = NULL;
1965         struct security_descriptor *sd_dacl = NULL;
1966         struct security_descriptor *sd_sacl = NULL;
1967         struct smb2_handle handle;
1968         const char *fname = BASEDIR "\\sd_get_set.txt";
1969         uint64_t desired_64;
1970         uint32_t desired = 0, granted;
1971         int i = 0;
1972 #define NO_BITS_HACK (((uint64_t)1)<<32)
1973         uint64_t open_bits =
1974                 SEC_MASK_GENERIC |
1975                 SEC_FLAG_SYSTEM_SECURITY |
1976                 SEC_FLAG_MAXIMUM_ALLOWED |
1977                 SEC_STD_ALL |
1978                 SEC_FILE_ALL |
1979                 NO_BITS_HACK;
1980         uint64_t get_owner_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1981         uint64_t set_owner_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
1982         uint64_t get_group_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1983         uint64_t set_group_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
1984         uint64_t get_dacl_bits  = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
1985         uint64_t set_dacl_bits  = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_DAC;
1986         uint64_t get_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
1987         uint64_t set_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
1988
1989         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
1990                 return false;
1991
1992         torture_comment(tctx, "TESTING ACCESS MASKS FOR SD GET/SET\n");
1993
1994         /* first create a file with full access for everyone */
1995         sd = security_descriptor_dacl_create(tctx,
1996                                         0, SID_NT_ANONYMOUS, SID_BUILTIN_USERS,
1997                                         SID_WORLD,
1998                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
1999                                         SEC_GENERIC_ALL,
2000                                         0,
2001                                         NULL);
2002         sd->type |= SEC_DESC_SACL_PRESENT;
2003         sd->sacl = NULL;
2004         ZERO_STRUCT(io);
2005         io.level = RAW_OPEN_SMB2;
2006         io.in.create_flags = 0;
2007         io.in.desired_access = SEC_GENERIC_ALL;
2008         io.in.create_options = 0;
2009         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2010         io.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
2011         io.in.alloc_size = 0;
2012         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2013         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
2014         io.in.security_flags = 0;
2015         io.in.fname = fname;
2016         io.in.sec_desc = sd;
2017         status = smb2_create(tree, tctx, &io);
2018         CHECK_STATUS(status, NT_STATUS_OK);
2019         handle = io.out.file.handle;
2020
2021         status = smb2_util_close(tree, handle);
2022         CHECK_STATUS(status, NT_STATUS_OK);
2023
2024         /*
2025          * now try each access_mask bit and no bit at all in a loop
2026          * and see what's allowed
2027          * NOTE: if i == 32 it means access_mask = 0 (see NO_BITS_HACK above)
2028          */
2029         for (i=0; i <= 32; i++) {
2030                 desired_64 = ((uint64_t)1) << i;
2031                 desired = (uint32_t)desired_64;
2032
2033                 /* first open the file with the desired access */
2034                 io.level = RAW_OPEN_SMB2;
2035                 io.in.desired_access = desired;
2036                 io.in.create_disposition = NTCREATEX_DISP_OPEN;
2037                 status = smb2_create(tree, tctx, &io);
2038                 CHECK_STATUS_FOR_BIT_ACTION(status, open_bits, goto next);
2039                 handle = io.out.file.handle;
2040
2041                 /* then check what access was granted */
2042                 fi.access_information.level             = RAW_FILEINFO_ACCESS_INFORMATION;
2043                 fi.access_information.in.file.handle    = handle;
2044                 status = smb2_getinfo_file(tree, tctx, &fi);
2045                 CHECK_STATUS(status, NT_STATUS_OK);
2046                 granted = fi.access_information.out.access_flags;
2047
2048                 /* test the owner */
2049                 ZERO_STRUCT(fi);
2050                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
2051                 fi.query_secdesc.in.file.handle         = handle;
2052                 fi.query_secdesc.in.secinfo_flags       = SECINFO_OWNER;
2053                 status = smb2_getinfo_file(tree, tctx, &fi);
2054                 CHECK_STATUS_FOR_BIT(status, get_owner_bits, SEC_STD_READ_CONTROL);
2055                 if (fi.query_secdesc.out.sd) {
2056                         sd_owner = fi.query_secdesc.out.sd;
2057                 } else if (!sd_owner) {
2058                         sd_owner = sd;
2059                 }
2060                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
2061                 si.set_secdesc.in.file.handle           = handle;
2062                 si.set_secdesc.in.secinfo_flags         = SECINFO_OWNER;
2063                 si.set_secdesc.in.sd                    = sd_owner;
2064                 status = smb2_setinfo_file(tree, &si);
2065                 CHECK_STATUS_FOR_BIT(status, set_owner_bits, SEC_STD_WRITE_OWNER);
2066
2067                 /* test the group */
2068                 ZERO_STRUCT(fi);
2069                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
2070                 fi.query_secdesc.in.file.handle         = handle;
2071                 fi.query_secdesc.in.secinfo_flags       = SECINFO_GROUP;
2072                 status = smb2_getinfo_file(tree, tctx, &fi);
2073                 CHECK_STATUS_FOR_BIT(status, get_group_bits, SEC_STD_READ_CONTROL);
2074                 if (fi.query_secdesc.out.sd) {
2075                         sd_group = fi.query_secdesc.out.sd;
2076                 } else if (!sd_group) {
2077                         sd_group = sd;
2078                 }
2079                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
2080                 si.set_secdesc.in.file.handle           = handle;
2081                 si.set_secdesc.in.secinfo_flags         = SECINFO_GROUP;
2082                 si.set_secdesc.in.sd                    = sd_group;
2083                 status = smb2_setinfo_file(tree, &si);
2084                 CHECK_STATUS_FOR_BIT(status, set_group_bits, SEC_STD_WRITE_OWNER);
2085
2086                 /* test the DACL */
2087                 ZERO_STRUCT(fi);
2088                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
2089                 fi.query_secdesc.in.file.handle         = handle;
2090                 fi.query_secdesc.in.secinfo_flags       = SECINFO_DACL;
2091                 status = smb2_getinfo_file(tree, tctx, &fi);
2092                 CHECK_STATUS_FOR_BIT(status, get_dacl_bits, SEC_STD_READ_CONTROL);
2093                 if (fi.query_secdesc.out.sd) {
2094                         sd_dacl = fi.query_secdesc.out.sd;
2095                 } else if (!sd_dacl) {
2096                         sd_dacl = sd;
2097                 }
2098                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
2099                 si.set_secdesc.in.file.handle           = handle;
2100                 si.set_secdesc.in.secinfo_flags         = SECINFO_DACL;
2101                 si.set_secdesc.in.sd                    = sd_dacl;
2102                 status = smb2_setinfo_file(tree, &si);
2103                 CHECK_STATUS_FOR_BIT(status, set_dacl_bits, SEC_STD_WRITE_DAC);
2104
2105                 /* test the SACL */
2106                 ZERO_STRUCT(fi);
2107                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
2108                 fi.query_secdesc.in.file.handle         = handle;
2109                 fi.query_secdesc.in.secinfo_flags       = SECINFO_SACL;
2110                 status = smb2_getinfo_file(tree, tctx, &fi);
2111                 CHECK_STATUS_FOR_BIT(status, get_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
2112                 if (fi.query_secdesc.out.sd) {
2113                         sd_sacl = fi.query_secdesc.out.sd;
2114                 } else if (!sd_sacl) {
2115                         sd_sacl = sd;
2116                 }
2117                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
2118                 si.set_secdesc.in.file.handle           = handle;
2119                 si.set_secdesc.in.secinfo_flags         = SECINFO_SACL;
2120                 si.set_secdesc.in.sd                    = sd_sacl;
2121                 status = smb2_setinfo_file(tree, &si);
2122                 CHECK_STATUS_FOR_BIT(status, set_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
2123
2124                 /* close the handle */
2125                 status = smb2_util_close(tree, handle);
2126                 CHECK_STATUS(status, NT_STATUS_OK);
2127 next:
2128                 continue;
2129         }
2130
2131 done:
2132         smb2_util_close(tree, handle);
2133         smb2_util_unlink(tree, fname);
2134         smb2_deltree(tree, BASEDIR);
2135         smb2_tdis(tree);
2136         smb2_logoff(tree->session);
2137
2138         return ret;
2139 }
2140 #endif
2141
2142 /**
2143  * SMB2 connect with explicit share
2144  **/
2145 static bool torture_smb2_con_share(struct torture_context *tctx,
2146                            const char *share,
2147                            struct smb2_tree **tree)
2148 {
2149         struct smbcli_options options;
2150         NTSTATUS status;
2151         const char *host = torture_setting_string(tctx, "host", NULL);
2152
2153         lpcfg_smbcli_options(tctx->lp_ctx, &options);
2154
2155         status = smb2_connect_ext(tctx,
2156                                   host,
2157                                   lpcfg_smb_ports(tctx->lp_ctx),
2158                                   share,
2159                                   lpcfg_resolve_context(tctx->lp_ctx),
2160                                   popt_get_cmdline_credentials(),
2161                                   0,
2162                                   tree,
2163                                   tctx->ev,
2164                                   &options,
2165                                   lpcfg_socket_options(tctx->lp_ctx),
2166                                   lpcfg_gensec_settings(tctx, tctx->lp_ctx)
2167                                   );
2168         if (!NT_STATUS_IS_OK(status)) {
2169                 torture_comment(tctx, "Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
2170                         host, share, nt_errstr(status));
2171                 return false;
2172         }
2173         return true;
2174 }
2175
2176 static bool test_access_based(struct torture_context *tctx,
2177                                 struct smb2_tree *tree)
2178 {
2179         struct smb2_tree *tree1 = NULL;
2180         NTSTATUS status;
2181         struct smb2_create io;
2182         const char *fname = BASEDIR "\\testfile";
2183         bool ret = true;
2184         struct smb2_handle fhandle, dhandle;
2185         union smb_fileinfo q;
2186         union smb_setfileinfo set;
2187         struct security_descriptor *sd, *sd_orig=NULL;
2188         const char *owner_sid;
2189         uint32_t flags = 0;
2190         /*
2191          * Can't test without SEC_STD_READ_CONTROL as we
2192          * own the file and implicitly have SEC_STD_READ_CONTROL.
2193         */
2194         uint32_t access_masks[] = {
2195                 /* Full READ access. */
2196                 SEC_STD_READ_CONTROL|FILE_READ_DATA|
2197                 FILE_READ_ATTRIBUTES|FILE_READ_EA,
2198
2199                 /* Missing FILE_READ_EA. */
2200                 SEC_STD_READ_CONTROL|FILE_READ_DATA|
2201                 FILE_READ_ATTRIBUTES,
2202
2203                 /* Missing FILE_READ_ATTRIBUTES. */
2204                 SEC_STD_READ_CONTROL|FILE_READ_DATA|
2205                 FILE_READ_EA,
2206
2207                 /* Missing FILE_READ_DATA. */
2208                 SEC_STD_READ_CONTROL|
2209                 FILE_READ_ATTRIBUTES|FILE_READ_EA,
2210         };
2211         unsigned int i;
2212         unsigned int count;
2213         struct smb2_find f;
2214         union smb_search_data *d;
2215
2216         ZERO_STRUCT(fhandle);
2217         ZERO_STRUCT(dhandle);
2218
2219         if (!torture_smb2_con_share(tctx, "hideunread", &tree1)) {
2220                 torture_result(tctx, TORTURE_FAIL, "(%s) Unable to connect "
2221                         "to share 'hideunread'\n",
2222                        __location__);
2223                 ret = false;
2224                 goto done;
2225         }
2226
2227         flags = smb2cli_tcon_flags(tree1->smbXcli);
2228
2229         smb2_util_unlink(tree1, fname);
2230         smb2_deltree(tree1, BASEDIR);
2231
2232         torture_comment(tctx, "TESTING ACCESS BASED ENUMERATION\n");
2233
2234         if ((flags & SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM)==0) {
2235                 torture_result(tctx, TORTURE_FAIL, "(%s) No access enumeration "
2236                         "on share 'hideunread'\n",
2237                        __location__);
2238                 ret = false;
2239                 goto done;
2240         }
2241
2242         if (!smb2_util_setup_dir(tctx, tree1, BASEDIR)) {
2243                 torture_result(tctx, TORTURE_FAIL, "(%s) Unable to setup %s\n",
2244                        __location__, BASEDIR);
2245                 ret = false;
2246                 goto done;
2247         }
2248
2249         /* Get a handle to the BASEDIR directory. */
2250         status = torture_smb2_testdir(tree1, BASEDIR, &dhandle);
2251         CHECK_STATUS(status, NT_STATUS_OK);
2252         smb2_util_close(tree1, dhandle);
2253         ZERO_STRUCT(dhandle);
2254
2255         ZERO_STRUCT(io);
2256         io.level = RAW_OPEN_SMB2;
2257         io.in.create_flags = 0;
2258         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
2259         io.in.create_options = 0;
2260         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2261         io.in.share_access = 0;
2262         io.in.alloc_size = 0;
2263         io.in.create_disposition = NTCREATEX_DISP_CREATE;
2264         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
2265         io.in.security_flags = 0;
2266         io.in.fname = fname;
2267
2268         status = smb2_create(tree1, tctx, &io);
2269         CHECK_STATUS(status, NT_STATUS_OK);
2270         fhandle = io.out.file.handle;
2271
2272         torture_comment(tctx, "get the original sd\n");
2273         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
2274         q.query_secdesc.in.file.handle = fhandle;
2275         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
2276         status = smb2_getinfo_file(tree1, tctx, &q);
2277         CHECK_STATUS(status, NT_STATUS_OK);
2278         sd_orig = q.query_secdesc.out.sd;
2279
2280         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
2281
2282         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
2283
2284         /* Setup for the search. */
2285         ZERO_STRUCT(f);
2286         f.in.pattern            = "*";
2287         f.in.continue_flags     = SMB2_CONTINUE_FLAG_REOPEN;
2288         f.in.max_response_size  = 0x1000;
2289         f.in.level              = SMB2_FIND_DIRECTORY_INFO;
2290
2291         for (i = 0; i < ARRAY_SIZE(access_masks); i++) {
2292
2293                 sd = security_descriptor_dacl_create(tctx,
2294                                         0, NULL, NULL,
2295                                         owner_sid,
2296                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
2297                                         access_masks[i]|SEC_STD_SYNCHRONIZE,
2298                                         0,
2299                                         NULL);
2300
2301                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
2302                 set.set_secdesc.in.file.handle = fhandle;
2303                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
2304                 set.set_secdesc.in.sd = sd;
2305                 status = smb2_setinfo_file(tree1, &set);
2306                 CHECK_STATUS(status, NT_STATUS_OK);
2307
2308                 /* Now see if we can see the file in a directory listing. */
2309
2310                 /* Re-open dhandle. */
2311                 status = torture_smb2_testdir(tree1, BASEDIR, &dhandle);
2312                 CHECK_STATUS(status, NT_STATUS_OK);
2313                 f.in.file.handle = dhandle;
2314
2315                 count = 0;
2316                 d = NULL;
2317                 status = smb2_find_level(tree1, tree1, &f, &count, &d);
2318                 TALLOC_FREE(d);
2319
2320                 CHECK_STATUS(status, NT_STATUS_OK);
2321
2322                 smb2_util_close(tree1, dhandle);
2323                 ZERO_STRUCT(dhandle);
2324
2325                 if (i == 0) {
2326                         /* We should see the first sd. */
2327                         if (count != 3) {
2328                                 torture_result(tctx, TORTURE_FAIL,
2329                                         "(%s) Normal SD - Unable "
2330                                         "to see file %s\n",
2331                                         __location__,
2332                                         BASEDIR);
2333                                 ret = false;
2334                                 goto done;
2335                         }
2336                 } else {
2337                         /* But no others. */
2338                         if (count != 2) {
2339                                 torture_result(tctx, TORTURE_FAIL,
2340                                         "(%s) SD 0x%x - can "
2341                                         "see file %s\n",
2342                                         __location__,
2343                                         access_masks[i],
2344                                         BASEDIR);
2345                                 ret = false;
2346                                 goto done;
2347                         }
2348                 }
2349         }
2350
2351 done:
2352
2353         if (tree1) {
2354                 smb2_util_close(tree1, fhandle);
2355                 smb2_util_close(tree1, dhandle);
2356                 smb2_util_unlink(tree1, fname);
2357                 smb2_deltree(tree1, BASEDIR);
2358                 smb2_tdis(tree1);
2359                 smb2_logoff(tree1->session);
2360         }
2361         smb2_tdis(tree);
2362         smb2_logoff(tree->session);
2363         return ret;
2364 }
2365
2366 /*
2367    basic testing of SMB2 ACLs
2368 */
2369 struct torture_suite *torture_smb2_acls_init(TALLOC_CTX *ctx)
2370 {
2371         struct torture_suite *suite = torture_suite_create(ctx, "acls");
2372
2373         torture_suite_add_1smb2_test(suite, "CREATOR", test_creator_sid);
2374         torture_suite_add_1smb2_test(suite, "GENERIC", test_generic_bits);
2375         torture_suite_add_1smb2_test(suite, "OWNER", test_owner_bits);
2376         torture_suite_add_1smb2_test(suite, "INHERITANCE", test_inheritance);
2377         torture_suite_add_1smb2_test(suite, "INHERITFLAGS", test_inheritance_flags);
2378         torture_suite_add_1smb2_test(suite, "SDFLAGSVSCHOWN", test_sd_flags_vs_chown);
2379         torture_suite_add_1smb2_test(suite, "DYNAMIC", test_inheritance_dynamic);
2380 #if 0
2381         /* XXX This test does not work against XP or Vista. */
2382         torture_suite_add_1smb2_test(suite, "GETSET", test_sd_get_set);
2383 #endif
2384         torture_suite_add_1smb2_test(suite, "ACCESSBASED", test_access_based);
2385
2386         suite->description = talloc_strdup(suite, "SMB2-ACLS tests");
2387
2388         return suite;
2389 }