LCOV - code coverage report
Current view: top level - source4/torture/smb2 - acls.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 1311 1519 86.3 %
Date: 2024-02-28 12:06:22 Functions: 17 17 100.0 %

          Line data    Source code
       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/cmdline.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           4 : static bool test_creator_sid(struct torture_context *tctx, struct smb2_tree *tree)
      97             : {
      98           0 :         NTSTATUS status;
      99           0 :         struct smb2_create io;
     100           4 :         const char *fname = BASEDIR "\\creator.txt";
     101           4 :         bool ret = true;
     102           4 :         struct smb2_handle handle = {{0}};
     103           0 :         union smb_fileinfo q;
     104           0 :         union smb_setfileinfo set;
     105           0 :         struct security_descriptor *sd, *sd_orig, *sd2;
     106           0 :         const char *owner_sid;
     107             : 
     108           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     109           0 :                 return false;
     110             : 
     111           4 :         torture_comment(tctx, "TESTING SID_CREATOR_OWNER\n");
     112             : 
     113           4 :         ZERO_STRUCT(io);
     114           4 :         io.level = RAW_OPEN_SMB2;
     115           4 :         io.in.create_flags = 0;
     116           4 :         io.in.desired_access = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
     117           4 :         io.in.create_options = 0;
     118           4 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     119           4 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
     120             :                 NTCREATEX_SHARE_ACCESS_READ |
     121             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     122           4 :         io.in.alloc_size = 0;
     123           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     124           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     125           4 :         io.in.security_flags = 0;
     126           4 :         io.in.fname = fname;
     127             : 
     128           4 :         status = smb2_create(tree, tctx, &io);
     129           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     130           4 :         handle = io.out.file.handle;
     131             : 
     132           4 :         torture_comment(tctx, "get the original sd\n");
     133           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     134           4 :         q.query_secdesc.in.file.handle = handle;
     135           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     136           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     137           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     138           4 :         sd_orig = q.query_secdesc.out.sd;
     139             : 
     140           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
     141             : 
     142           4 :         torture_comment(tctx, "set a sec desc allowing no write by CREATOR_OWNER\n");
     143           4 :         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           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     152           4 :         set.set_secdesc.in.file.handle = handle;
     153           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     154           4 :         set.set_secdesc.in.sd = sd;
     155             : 
     156           4 :         status = smb2_setinfo_file(tree, &set);
     157           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     158             : 
     159           4 :         torture_comment(tctx, "try open for write\n");
     160           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
     161           4 :         status = smb2_create(tree, tctx, &io);
     162           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     163             : 
     164           4 :         torture_comment(tctx, "try open for read\n");
     165           4 :         io.in.desired_access = SEC_FILE_READ_DATA;
     166           4 :         status = smb2_create(tree, tctx, &io);
     167           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     168             : 
     169           4 :         torture_comment(tctx, "try open for generic write\n");
     170           4 :         io.in.desired_access = SEC_GENERIC_WRITE;
     171           4 :         status = smb2_create(tree, tctx, &io);
     172           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     173             : 
     174           4 :         torture_comment(tctx, "try open for generic read\n");
     175           4 :         io.in.desired_access = SEC_GENERIC_READ;
     176           4 :         status = smb2_create(tree, tctx, &io);
     177           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     178             : 
     179           4 :         torture_comment(tctx, "set a sec desc allowing no write by owner\n");
     180           4 :         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           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     189           4 :         set.set_secdesc.in.file.handle = handle;
     190           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     191           4 :         set.set_secdesc.in.sd = sd;
     192           4 :         status = smb2_setinfo_file(tree, &set);
     193           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     194             : 
     195           4 :         torture_comment(tctx, "check that sd has been mapped correctly\n");
     196           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     197           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     198           4 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
     199             : 
     200           4 :         torture_comment(tctx, "try open for write\n");
     201           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
     202           4 :         status = smb2_create(tree, tctx, &io);
     203           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     204             : 
     205           4 :         torture_comment(tctx, "try open for read\n");
     206           4 :         io.in.desired_access = SEC_FILE_READ_DATA;
     207           4 :         status = smb2_create(tree, tctx, &io);
     208           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     209           8 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
     210             :                            SEC_FILE_READ_DATA);
     211           4 :         smb2_util_close(tree, io.out.file.handle);
     212             : 
     213           4 :         torture_comment(tctx, "try open for generic write\n");
     214           4 :         io.in.desired_access = SEC_GENERIC_WRITE;
     215           4 :         status = smb2_create(tree, tctx, &io);
     216           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     217             : 
     218           4 :         torture_comment(tctx, "try open for generic read\n");
     219           4 :         io.in.desired_access = SEC_GENERIC_READ;
     220           4 :         status = smb2_create(tree, tctx, &io);
     221           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     222           4 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
     223             :                            SEC_RIGHTS_FILE_READ);
     224           4 :         smb2_util_close(tree, io.out.file.handle);
     225             : 
     226           4 :         torture_comment(tctx, "set a sec desc allowing generic read by owner\n");
     227           4 :         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           4 :         set.set_secdesc.in.sd = sd;
     236           4 :         status = smb2_setinfo_file(tree, &set);
     237           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     238             : 
     239           4 :         torture_comment(tctx, "check that generic read has been mapped correctly\n");
     240           4 :         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           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     249           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     250           4 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     251             : 
     252           4 :         torture_comment(tctx, "try open for write\n");
     253           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
     254           4 :         status = smb2_create(tree, tctx, &io);
     255           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     256             : 
     257           4 :         torture_comment(tctx, "try open for read\n");
     258           4 :         io.in.desired_access = SEC_FILE_READ_DATA;
     259           4 :         status = smb2_create(tree, tctx, &io);
     260           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     261           8 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
     262             :                            SEC_FILE_READ_DATA);
     263           4 :         smb2_util_close(tree, io.out.file.handle);
     264             : 
     265           4 :         torture_comment(tctx, "try open for generic write\n");
     266           4 :         io.in.desired_access = SEC_GENERIC_WRITE;
     267           4 :         status = smb2_create(tree, tctx, &io);
     268           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     269             : 
     270           4 :         torture_comment(tctx, "try open for generic read\n");
     271           4 :         io.in.desired_access = SEC_GENERIC_READ;
     272           4 :         status = smb2_create(tree, tctx, &io);
     273           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     274           4 :         CHECK_ACCESS_FLAGS(io.out.file.handle, SEC_RIGHTS_FILE_READ);
     275           4 :         smb2_util_close(tree, io.out.file.handle);
     276             : 
     277             : 
     278           4 :         torture_comment(tctx, "put back original sd\n");
     279           4 :         set.set_secdesc.in.sd = sd_orig;
     280           4 :         status = smb2_setinfo_file(tree, &set);
     281           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     282             : 
     283             : 
     284           4 : done:
     285           4 :         smb2_util_close(tree, handle);
     286           4 :         smb2_deltree(tree, BASEDIR);
     287           4 :         smb2_tdis(tree);
     288           4 :         smb2_logoff(tree->session);
     289           4 :         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           4 : static bool test_generic_bits(struct torture_context *tctx, struct smb2_tree *tree)
     299             : {
     300           0 :         NTSTATUS status;
     301           0 :         struct smb2_create io;
     302           4 :         const char *fname = BASEDIR "\\generic.txt";
     303           4 :         bool ret = true;
     304           4 :         struct smb2_handle handle = {{0}};
     305           0 :         int i;
     306           0 :         union smb_fileinfo q;
     307           0 :         union smb_setfileinfo set;
     308           0 :         struct security_descriptor *sd, *sd_orig, *sd2;
     309           0 :         const char *owner_sid;
     310           0 :         const struct {
     311             :                 uint32_t gen_bits;
     312             :                 uint32_t specific_bits;
     313           4 :         } 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           0 :         const struct {
     323             :                 uint32_t gen_bits;
     324             :                 uint32_t specific_bits;
     325           4 :         } 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           4 :         bool has_restore_privilege = false;
     333           4 :         bool has_take_ownership_privilege = false;
     334             : 
     335           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     336           0 :                 return false;
     337             : 
     338           4 :         torture_comment(tctx, "TESTING FILE GENERIC BITS\n");
     339             : 
     340           4 :         ZERO_STRUCT(io);
     341           4 :         io.level = RAW_OPEN_SMB2;
     342           4 :         io.in.create_flags = 0;
     343           4 :         io.in.desired_access =
     344             :                 SEC_STD_READ_CONTROL |
     345             :                 SEC_STD_WRITE_DAC |
     346             :                 SEC_STD_WRITE_OWNER;
     347           4 :         io.in.create_options = 0;
     348           4 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     349           4 :         io.in.share_access =
     350             :                 NTCREATEX_SHARE_ACCESS_READ |
     351             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     352           4 :         io.in.alloc_size = 0;
     353           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     354           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     355           4 :         io.in.security_flags = 0;
     356           4 :         io.in.fname = fname;
     357           4 :         status = smb2_create(tree, tctx, &io);
     358           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     359           4 :         handle = io.out.file.handle;
     360             : 
     361           4 :         torture_comment(tctx, "get the original sd\n");
     362           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     363           4 :         q.query_secdesc.in.file.handle = handle;
     364           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     365           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     366           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     367           4 :         sd_orig = q.query_secdesc.out.sd;
     368             : 
     369           4 :         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          32 :         for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
     396          28 :                 uint32_t expected_mask =
     397             :                         SEC_STD_WRITE_DAC |
     398             :                         SEC_STD_READ_CONTROL |
     399             :                         SEC_FILE_READ_ATTRIBUTE |
     400             :                         SEC_STD_DELETE;
     401          28 :                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
     402             : 
     403          28 :                 if (has_restore_privilege) {
     404           0 :                         expected_mask_anon |= SEC_STD_DELETE;
     405             :                 }
     406             : 
     407          28 :                 torture_comment(tctx, "Testing generic bits 0x%08x\n",
     408          28 :                        file_mappings[i].gen_bits);
     409          28 :                 sd = security_descriptor_dacl_create(tctx,
     410             :                                                 0, owner_sid, NULL,
     411             :                                                 owner_sid,
     412             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     413          28 :                                                 file_mappings[i].gen_bits,
     414             :                                                 0,
     415             :                                                 NULL);
     416             : 
     417          28 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     418          28 :                 set.set_secdesc.in.file.handle = handle;
     419          28 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     420          28 :                 set.set_secdesc.in.sd = sd;
     421             : 
     422          28 :                 status = smb2_setinfo_file(tree, &set);
     423          28 :                 CHECK_STATUS(status, NT_STATUS_OK);
     424             : 
     425          28 :                 sd2 = security_descriptor_dacl_create(tctx,
     426             :                                                  0, owner_sid, NULL,
     427             :                                                  owner_sid,
     428             :                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
     429          28 :                                                  file_mappings[i].specific_bits,
     430             :                                                  0,
     431             :                                                  NULL);
     432             : 
     433          28 :                 status = smb2_getinfo_file(tree, tctx, &q);
     434          28 :                 CHECK_STATUS(status, NT_STATUS_OK);
     435          28 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     436             : 
     437          28 :                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     438          28 :                 status = smb2_create(tree, tctx, &io);
     439          28 :                 CHECK_STATUS(status, NT_STATUS_OK);
     440          28 :                 CHECK_ACCESS_FLAGS(io.out.file.handle,
     441             :                                    expected_mask | file_mappings[i].specific_bits);
     442          28 :                 smb2_util_close(tree, io.out.file.handle);
     443             : 
     444          28 :                 if (!has_take_ownership_privilege) {
     445          28 :                         continue;
     446             :                 }
     447             : 
     448           0 :                 torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
     449           0 :                        file_mappings[i].gen_bits);
     450           0 :                 sd = security_descriptor_dacl_create(tctx,
     451             :                                                 0, SID_NT_ANONYMOUS, NULL,
     452             :                                                 owner_sid,
     453             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     454           0 :                                                 file_mappings[i].gen_bits,
     455             :                                                 0,
     456             :                                                 NULL);
     457             : 
     458           0 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     459           0 :                 set.set_secdesc.in.file.handle = handle;
     460           0 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     461           0 :                 set.set_secdesc.in.sd = sd;
     462             : 
     463           0 :                 status = smb2_setinfo_file(tree, &set);
     464           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     465             : 
     466           0 :                 sd2 = security_descriptor_dacl_create(tctx,
     467             :                                                  0, SID_NT_ANONYMOUS, NULL,
     468             :                                                  owner_sid,
     469             :                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
     470           0 :                                                  file_mappings[i].specific_bits,
     471             :                                                  0,
     472             :                                                  NULL);
     473             : 
     474           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
     475           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     476           0 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     477             : 
     478           0 :                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     479           0 :                 status = smb2_create(tree, tctx, &io);
     480           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     481           0 :                 CHECK_ACCESS_FLAGS(io.out.file.handle,
     482             :                                    expected_mask_anon | file_mappings[i].specific_bits);
     483           0 :                 smb2_util_close(tree, io.out.file.handle);
     484             :         }
     485             : 
     486           4 :         torture_comment(tctx, "put back original sd\n");
     487           4 :         set.set_secdesc.in.sd = sd_orig;
     488           4 :         status = smb2_setinfo_file(tree, &set);
     489           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     490             : 
     491           4 :         smb2_util_close(tree, handle);
     492           4 :         smb2_util_unlink(tree, fname);
     493             : 
     494             : 
     495           4 :         torture_comment(tctx, "TESTING DIR GENERIC BITS\n");
     496             : 
     497           4 :         ZERO_STRUCT(io);
     498           4 :         io.level = RAW_OPEN_SMB2;
     499           4 :         io.in.create_flags = 0;
     500           4 :         io.in.desired_access =
     501             :                 SEC_STD_READ_CONTROL |
     502             :                 SEC_STD_WRITE_DAC |
     503             :                 SEC_STD_WRITE_OWNER;
     504           4 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     505           4 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     506           4 :         io.in.share_access =
     507             :                 NTCREATEX_SHARE_ACCESS_READ |
     508             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     509           4 :         io.in.alloc_size = 0;
     510           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     511           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     512           4 :         io.in.security_flags = 0;
     513           4 :         io.in.fname = fname;
     514           4 :         status = smb2_create(tree, tctx, &io);
     515           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     516           4 :         handle = io.out.file.handle;
     517             : 
     518           4 :         torture_comment(tctx, "get the original sd\n");
     519           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     520           4 :         q.query_secdesc.in.file.handle = handle;
     521           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     522           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     523           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     524           4 :         sd_orig = q.query_secdesc.out.sd;
     525             : 
     526           4 :         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          24 :         for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
     553          20 :                 uint32_t expected_mask =
     554             :                         SEC_STD_WRITE_DAC |
     555             :                         SEC_STD_READ_CONTROL |
     556             :                         SEC_FILE_READ_ATTRIBUTE |
     557             :                         SEC_STD_DELETE;
     558          20 :                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
     559             : 
     560          20 :                 if (has_restore_privilege) {
     561           0 :                         expected_mask_anon |= SEC_STD_DELETE;
     562             :                 }
     563             : 
     564          20 :                 torture_comment(tctx, "Testing generic bits 0x%08x\n",
     565          20 :                        file_mappings[i].gen_bits);
     566          20 :                 sd = security_descriptor_dacl_create(tctx,
     567             :                                                 0, owner_sid, NULL,
     568             :                                                 owner_sid,
     569             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     570          20 :                                                 dir_mappings[i].gen_bits,
     571             :                                                 0,
     572             :                                                 NULL);
     573             : 
     574          20 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     575          20 :                 set.set_secdesc.in.file.handle = handle;
     576          20 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     577          20 :                 set.set_secdesc.in.sd = sd;
     578             : 
     579          20 :                 status = smb2_setinfo_file(tree, &set);
     580          20 :                 CHECK_STATUS(status, NT_STATUS_OK);
     581             : 
     582          20 :                 sd2 = security_descriptor_dacl_create(tctx,
     583             :                                                  0, owner_sid, NULL,
     584             :                                                  owner_sid,
     585             :                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
     586          20 :                                                  dir_mappings[i].specific_bits,
     587             :                                                  0,
     588             :                                                  NULL);
     589             : 
     590          20 :                 status = smb2_getinfo_file(tree, tctx, &q);
     591          20 :                 CHECK_STATUS(status, NT_STATUS_OK);
     592          20 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     593             : 
     594          20 :                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     595          20 :                 status = smb2_create(tree, tctx, &io);
     596          20 :                 CHECK_STATUS(status, NT_STATUS_OK);
     597          20 :                 CHECK_ACCESS_FLAGS(io.out.file.handle,
     598             :                                    expected_mask | dir_mappings[i].specific_bits);
     599          20 :                 smb2_util_close(tree, io.out.file.handle);
     600             : 
     601          20 :                 if (!has_take_ownership_privilege) {
     602          20 :                         continue;
     603             :                 }
     604             : 
     605           0 :                 torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
     606           0 :                        file_mappings[i].gen_bits);
     607           0 :                 sd = security_descriptor_dacl_create(tctx,
     608             :                                                 0, SID_NT_ANONYMOUS, NULL,
     609             :                                                 owner_sid,
     610             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     611           0 :                                                 file_mappings[i].gen_bits,
     612             :                                                 0,
     613             :                                                 NULL);
     614             : 
     615           0 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     616           0 :                 set.set_secdesc.in.file.handle = handle;
     617           0 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     618           0 :                 set.set_secdesc.in.sd = sd;
     619             : 
     620           0 :                 status = smb2_setinfo_file(tree, &set);
     621           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     622             : 
     623           0 :                 sd2 = security_descriptor_dacl_create(tctx,
     624             :                                                  0, SID_NT_ANONYMOUS, NULL,
     625             :                                                  owner_sid,
     626             :                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
     627           0 :                                                  file_mappings[i].specific_bits,
     628             :                                                  0,
     629             :                                                  NULL);
     630             : 
     631           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
     632           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     633           0 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     634             : 
     635           0 :                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     636           0 :                 status = smb2_create(tree, tctx, &io);
     637           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     638           0 :                 CHECK_ACCESS_FLAGS(io.out.file.handle,
     639             :                                    expected_mask_anon | dir_mappings[i].specific_bits);
     640           0 :                 smb2_util_close(tree, io.out.file.handle);
     641             :         }
     642             : 
     643           4 :         torture_comment(tctx, "put back original sd\n");
     644           4 :         set.set_secdesc.in.sd = sd_orig;
     645           4 :         status = smb2_setinfo_file(tree, &set);
     646           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     647             : 
     648           4 :         smb2_util_close(tree, handle);
     649           4 :         smb2_util_unlink(tree, fname);
     650             : 
     651           4 : done:
     652           4 :         smb2_util_close(tree, handle);
     653           4 :         smb2_deltree(tree, BASEDIR);
     654           4 :         smb2_tdis(tree);
     655           4 :         smb2_logoff(tree->session);
     656           4 :         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           4 : static bool test_owner_bits(struct torture_context *tctx, struct smb2_tree *tree)
     665             : {
     666           0 :         NTSTATUS status;
     667           0 :         struct smb2_create io;
     668           4 :         const char *fname = BASEDIR "\\test_owner_bits.txt";
     669           4 :         bool ret = true;
     670           4 :         struct smb2_handle handle = {{0}};
     671           0 :         int i;
     672           0 :         union smb_fileinfo q;
     673           0 :         union smb_setfileinfo set;
     674           0 :         struct security_descriptor *sd, *sd_orig;
     675           0 :         const char *owner_sid;
     676           0 :         uint32_t expected_bits;
     677             : 
     678           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     679           0 :                 return false;
     680             : 
     681           4 :         torture_comment(tctx, "TESTING FILE OWNER BITS\n");
     682             : 
     683           4 :         ZERO_STRUCT(io);
     684           4 :         io.level = RAW_OPEN_SMB2;
     685           4 :         io.in.create_flags = 0;
     686           4 :         io.in.desired_access =
     687             :                 SEC_STD_READ_CONTROL |
     688             :                 SEC_STD_WRITE_DAC |
     689             :                 SEC_STD_WRITE_OWNER;
     690           4 :         io.in.create_options = 0;
     691           4 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     692           4 :         io.in.share_access =
     693             :                 NTCREATEX_SHARE_ACCESS_READ |
     694             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     695           4 :         io.in.alloc_size = 0;
     696           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     697           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     698           4 :         io.in.security_flags = 0;
     699           4 :         io.in.fname = fname;
     700           4 :         status = smb2_create(tree, tctx, &io);
     701           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     702           4 :         handle = io.out.file.handle;
     703             : 
     704           4 :         torture_comment(tctx, "get the original sd\n");
     705           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     706           4 :         q.query_secdesc.in.file.handle = handle;
     707           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     708           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     709           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     710           4 :         sd_orig = q.query_secdesc.out.sd;
     711             : 
     712           4 :         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           4 :         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           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     747           4 :         set.set_secdesc.in.file.handle = handle;
     748           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     749           4 :         set.set_secdesc.in.sd = sd;
     750             : 
     751           4 :         status = smb2_setinfo_file(tree, &set);
     752           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     753             : 
     754           4 :         expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
     755             : 
     756          68 :         for (i=0;i<16;i++) {
     757          64 :                 uint32_t bit = (1<<i);
     758          64 :                 io.in.desired_access = bit;
     759          64 :                 status = smb2_create(tree, tctx, &io);
     760          64 :                 if (expected_bits & bit) {
     761           8 :                         if (!NT_STATUS_IS_OK(status)) {
     762           0 :                                 torture_warning(tctx, "failed with access mask 0x%08x of expected 0x%08x\n",
     763             :                                        bit, expected_bits);
     764             :                         }
     765           8 :                         CHECK_STATUS(status, NT_STATUS_OK);
     766           8 :                         CHECK_ACCESS_FLAGS(io.out.file.handle, bit);
     767           8 :                         smb2_util_close(tree, io.out.file.handle);
     768             :                 } else {
     769          56 :                         if (NT_STATUS_IS_OK(status)) {
     770           0 :                                 torture_warning(tctx, "open succeeded with access mask 0x%08x of "
     771             :                                         "expected 0x%08x - should fail\n",
     772             :                                        bit, expected_bits);
     773             :                         }
     774          56 :                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     775             :                 }
     776             :         }
     777             : 
     778           4 :         torture_comment(tctx, "put back original sd\n");
     779           4 :         set.set_secdesc.in.sd = sd_orig;
     780           4 :         status = smb2_setinfo_file(tree, &set);
     781           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     782             : 
     783           4 : done:
     784           4 :         smb2_util_close(tree, handle);
     785           4 :         smb2_util_unlink(tree, fname);
     786           4 :         smb2_deltree(tree, BASEDIR);
     787           4 :         smb2_tdis(tree);
     788           4 :         smb2_logoff(tree->session);
     789           4 :         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           4 : static bool test_inheritance(struct torture_context *tctx, struct smb2_tree *tree)
     799             : {
     800           0 :         NTSTATUS status;
     801           0 :         struct smb2_create io;
     802           4 :         const char *dname = BASEDIR "\\inheritance";
     803           4 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
     804           4 :         const char *fname2 = BASEDIR "\\inheritance\\testdir";
     805           4 :         bool ret = true;
     806           4 :         struct smb2_handle handle = {{0}};
     807           4 :         struct smb2_handle handle2 = {{0}};
     808           0 :         int i;
     809           0 :         union smb_fileinfo q;
     810           0 :         union smb_setfileinfo set;
     811           4 :         struct security_descriptor *sd, *sd2, *sd_orig=NULL, *sd_def1, *sd_def2;
     812           0 :         const char *owner_sid;
     813           0 :         const struct dom_sid *creator_owner;
     814           0 :         const struct {
     815             :                 uint32_t parent_flags;
     816             :                 uint32_t file_flags;
     817             :                 uint32_t dir_flags;
     818           4 :         } 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           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     923           0 :                 return false;
     924             : 
     925           4 :         torture_comment(tctx, "TESTING ACL INHERITANCE\n");
     926             : 
     927           4 :         ZERO_STRUCT(io);
     928           4 :         io.level = RAW_OPEN_SMB2;
     929           4 :         io.in.create_flags = 0;
     930           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
     931           4 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     932           4 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     933           4 :         io.in.share_access = 0;
     934           4 :         io.in.alloc_size = 0;
     935           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
     936           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     937           4 :         io.in.security_flags = 0;
     938           4 :         io.in.fname = dname;
     939             : 
     940           4 :         status = smb2_create(tree, tctx, &io);
     941           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     942           4 :         handle = io.out.file.handle;
     943             : 
     944           4 :         torture_comment(tctx, "get the original sd\n");
     945           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     946           4 :         q.query_secdesc.in.file.handle = handle;
     947           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     948           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     949           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     950           4 :         sd_orig = q.query_secdesc.out.sd;
     951             : 
     952           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
     953             : 
     954           4 :         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           4 :         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           4 :         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           4 :         creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER);
     985             : 
     986          68 :         for (i=0;i<ARRAY_SIZE(test_flags);i++) {
     987          64 :                 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          64 :                                                 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          64 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     999          64 :                 set.set_secdesc.in.file.handle = handle;
    1000          64 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1001          64 :                 set.set_secdesc.in.sd = sd;
    1002          64 :                 status = smb2_setinfo_file(tree, &set);
    1003          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1004             : 
    1005          64 :                 io.in.fname = fname1;
    1006          64 :                 io.in.create_options = 0;
    1007          64 :                 status = smb2_create(tree, tctx, &io);
    1008          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1009          64 :                 handle2 = io.out.file.handle;
    1010             : 
    1011          64 :                 q.query_secdesc.in.file.handle = handle2;
    1012          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1013          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1014             : 
    1015          64 :                 smb2_util_close(tree, handle2);
    1016          64 :                 smb2_util_unlink(tree, fname1);
    1017             : 
    1018          64 :                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
    1019          32 :                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
    1020          32 :                             !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
    1021          32 :                                 torture_warning(tctx, "Expected default sd:\n");
    1022          32 :                                 NDR_PRINT_DEBUG(security_descriptor, sd_def1);
    1023          32 :                                 torture_warning(tctx, "at %d - got:\n", i);
    1024          32 :                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1025             :                         }
    1026          32 :                         goto check_dir;
    1027             :                 }
    1028             : 
    1029          32 :                 if (q.query_secdesc.out.sd->dacl == NULL ||
    1030          32 :                     q.query_secdesc.out.sd->dacl->num_aces != 1 ||
    1031          32 :                     q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1032          32 :                     !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1033          32 :                                    sd_orig->owner_sid)) {
    1034           0 :                         torture_warning(tctx, "Bad sd in child file at %d\n", i);
    1035           0 :                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1036           0 :                         ret = false;
    1037           0 :                         goto check_dir;
    1038             :                 }
    1039             : 
    1040          32 :                 if (q.query_secdesc.out.sd->dacl->aces[0].flags !=
    1041          32 :                     test_flags[i].file_flags) {
    1042           0 :                         torture_warning(tctx, "incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
    1043           0 :                                q.query_secdesc.out.sd->dacl->aces[0].flags,
    1044           0 :                                test_flags[i].file_flags,
    1045           0 :                                test_flags[i].parent_flags,
    1046             :                                i);
    1047           0 :                         ret = false;
    1048             :                 }
    1049             : 
    1050          32 :         check_dir:
    1051          64 :                 io.in.fname = fname2;
    1052          64 :                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1053          64 :                 status = smb2_create(tree, tctx, &io);
    1054          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1055          64 :                 handle2 = io.out.file.handle;
    1056             : 
    1057          64 :                 q.query_secdesc.in.file.handle = handle2;
    1058          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1059          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1060             : 
    1061          64 :                 smb2_util_close(tree, handle2);
    1062          64 :                 smb2_util_rmdir(tree, fname2);
    1063             : 
    1064          64 :                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
    1065          32 :                     (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
    1066          16 :                      (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
    1067          24 :                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
    1068          24 :                             !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
    1069          24 :                                 torture_warning(tctx, "Expected default sd for dir at %d:\n", i);
    1070          24 :                                 NDR_PRINT_DEBUG(security_descriptor, sd_def1);
    1071          24 :                                 torture_warning(tctx, "got:\n");
    1072          24 :                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1073             :                         }
    1074          24 :                         continue;
    1075             :                 }
    1076             : 
    1077          40 :                 if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
    1078          32 :                     (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
    1079          16 :                         if (q.query_secdesc.out.sd->dacl == NULL ||
    1080          16 :                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
    1081          16 :                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1082          16 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1083          16 :                                            sd_orig->owner_sid) ||
    1084          16 :                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
    1085           0 :                                 torture_warning(tctx, "(CI & NP) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
    1086           0 :                                        test_flags[i].dir_flags,
    1087           0 :                                        test_flags[i].parent_flags, i);
    1088           0 :                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1089           0 :                                 torture_warning(tctx, "FYI, here is the parent sd:\n");
    1090           0 :                                 NDR_PRINT_DEBUG(security_descriptor, sd);
    1091           0 :                                 ret = false;
    1092           0 :                                 continue;
    1093             :                         }
    1094          24 :                 } else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
    1095          16 :                         if (q.query_secdesc.out.sd->dacl == NULL ||
    1096          16 :                             q.query_secdesc.out.sd->dacl->num_aces != 2 ||
    1097          16 :                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1098          16 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1099          16 :                                            sd_orig->owner_sid) ||
    1100          16 :                             q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
    1101          16 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
    1102          16 :                                            creator_owner) ||
    1103          16 :                             q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
    1104          16 :                             q.query_secdesc.out.sd->dacl->aces[1].flags !=
    1105          16 :                             (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
    1106           0 :                                 torture_warning(tctx, "(CI) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
    1107           0 :                                        test_flags[i].dir_flags,
    1108           0 :                                        test_flags[i].parent_flags, i);
    1109           0 :                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1110           0 :                                 torture_warning(tctx, "FYI, here is the parent sd:\n");
    1111           0 :                                 NDR_PRINT_DEBUG(security_descriptor, sd);
    1112           0 :                                 ret = false;
    1113           0 :                                 continue;
    1114             :                         }
    1115             :                 } else {
    1116           8 :                         if (q.query_secdesc.out.sd->dacl == NULL ||
    1117           8 :                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
    1118           8 :                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1119           8 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1120           8 :                                            creator_owner) ||
    1121           8 :                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
    1122           0 :                                 torture_warning(tctx, "(0) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
    1123           0 :                                        test_flags[i].dir_flags,
    1124           0 :                                        test_flags[i].parent_flags, i);
    1125           0 :                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1126           0 :                                 torture_warning(tctx, "FYI, here is the parent sd:\n");
    1127           0 :                                 NDR_PRINT_DEBUG(security_descriptor, sd);
    1128           0 :                                 ret = false;
    1129           0 :                                 continue;
    1130             :                         }
    1131             :                 }
    1132             :         }
    1133             : 
    1134           4 :         torture_comment(tctx, "Testing access checks on inherited create with %s\n", fname1);
    1135           4 :         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           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1147           4 :         set.set_secdesc.in.file.handle = handle;
    1148           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1149           4 :         set.set_secdesc.in.sd = sd;
    1150           4 :         status = smb2_setinfo_file(tree, &set);
    1151           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1152             : 
    1153             :         /* Check DACL we just set. */
    1154           4 :         torture_comment(tctx, "checking new sd\n");
    1155           4 :         q.query_secdesc.in.file.handle = handle;
    1156           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
    1157           4 :         status = smb2_getinfo_file(tree, tctx, &q);
    1158           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1159           4 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
    1160             : 
    1161           4 :         io.in.fname = fname1;
    1162           4 :         io.in.create_options = 0;
    1163           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1164           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1165           4 :         status = smb2_create(tree, tctx, &io);
    1166           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1167           4 :         handle2 = io.out.file.handle;
    1168           4 :         CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
    1169             : 
    1170           4 :         q.query_secdesc.in.file.handle = handle2;
    1171           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1172           4 :         status = smb2_getinfo_file(tree, tctx, &q);
    1173           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1174           4 :         smb2_util_close(tree, handle2);
    1175             : 
    1176           4 :         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           4 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1184             : 
    1185           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1186           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1187           4 :         status = smb2_create(tree, tctx, &io);
    1188           4 :         if (NT_STATUS_IS_OK(status)) {
    1189           0 :                 torture_warning(tctx, "failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
    1190           0 :                 ret = false;
    1191           0 :                 handle2 = io.out.file.handle;
    1192           0 :                 CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
    1193           0 :                 smb2_util_close(tree, handle2);
    1194             :         } else {
    1195           4 :                 if (torture_setting_bool(tctx, "hide_on_access_denied",
    1196             :                                          false)) {
    1197           0 :                         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1198             :                 } else {
    1199           4 :                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1200             :                 }
    1201             :         }
    1202             : 
    1203           4 :         torture_comment(tctx, "trying without execute\n");
    1204           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1205           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
    1206           4 :         status = smb2_create(tree, tctx, &io);
    1207           4 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1208           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1209             :         } else {
    1210           4 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1211             :         }
    1212             : 
    1213           4 :         torture_comment(tctx, "and with full permissions again\n");
    1214           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1215           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1216           4 :         status = smb2_create(tree, tctx, &io);
    1217           4 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1218           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1219             :         } else {
    1220           4 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1221             :         }
    1222             : 
    1223           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1224           4 :         status = smb2_create(tree, tctx, &io);
    1225           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1226           4 :         handle2 = io.out.file.handle;
    1227           8 :         CHECK_ACCESS_FLAGS(handle2, SEC_FILE_WRITE_DATA);
    1228           4 :         smb2_util_close(tree, handle2);
    1229             : 
    1230           4 :         torture_comment(tctx, "put back original sd\n");
    1231           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1232           4 :         set.set_secdesc.in.file.handle = handle;
    1233           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1234           4 :         set.set_secdesc.in.sd = sd_orig;
    1235           4 :         status = smb2_setinfo_file(tree, &set);
    1236           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1237             : 
    1238           4 :         smb2_util_close(tree, handle);
    1239             : 
    1240           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1241           4 :         status = smb2_create(tree, tctx, &io);
    1242           4 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1243           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1244             :         } else {
    1245           4 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1246             :         }
    1247             : 
    1248           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1249           4 :         status = smb2_create(tree, tctx, &io);
    1250           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1251           4 :         handle2 = io.out.file.handle;
    1252           8 :         CHECK_ACCESS_FLAGS(handle2, SEC_FILE_WRITE_DATA);
    1253           4 :         smb2_util_close(tree, handle2);
    1254             : 
    1255           4 :         smb2_util_unlink(tree, fname1);
    1256           4 :         smb2_util_rmdir(tree, dname);
    1257             : 
    1258           4 : done:
    1259           4 :         if (sd_orig != NULL) {
    1260           4 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1261           4 :                 set.set_secdesc.in.file.handle = handle;
    1262           4 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1263           4 :                 set.set_secdesc.in.sd = sd_orig;
    1264           4 :                 status = smb2_setinfo_file(tree, &set);
    1265             :         }
    1266             : 
    1267           4 :         smb2_util_close(tree, handle);
    1268           4 :         smb2_deltree(tree, BASEDIR);
    1269           4 :         smb2_tdis(tree);
    1270           4 :         smb2_logoff(tree->session);
    1271           4 :         return ret;
    1272             : }
    1273             : 
    1274           4 : static bool test_inheritance_flags(struct torture_context *tctx,
    1275             :     struct smb2_tree *tree)
    1276             : {
    1277           0 :         NTSTATUS status;
    1278           0 :         struct smb2_create io;
    1279           4 :         const char *dname = BASEDIR "\\inheritance";
    1280           4 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
    1281           4 :         bool ret = true;
    1282           4 :         struct smb2_handle handle = {{0}};
    1283           4 :         struct smb2_handle handle2 = {{0}};
    1284           0 :         int i, j;
    1285           0 :         union smb_fileinfo q;
    1286           0 :         union smb_setfileinfo set;
    1287           4 :         struct security_descriptor *sd, *sd2, *sd_orig=NULL;
    1288           0 :         const char *owner_sid;
    1289           0 :         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           4 :         } tflags[16] = {{0}}; /* 2^4 */
    1297             : 
    1298          64 :         for (i = 0; i < 15; i++) {
    1299          60 :                 torture_comment(tctx, "i=%d:", i);
    1300             : 
    1301          60 :                 if (i & 1) {
    1302          28 :                         tflags[i].parent_set_sd_type |=
    1303             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1304          28 :                         torture_comment(tctx, "AUTO_INHERITED, ");
    1305             :                 }
    1306          60 :                 if (i & 2) {
    1307          28 :                         tflags[i].parent_set_sd_type |=
    1308             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1309          28 :                         torture_comment(tctx, "AUTO_INHERIT_REQ, ");
    1310             :                 }
    1311          60 :                 if (i & 4) {
    1312          28 :                         tflags[i].parent_set_sd_type |=
    1313             :                             SEC_DESC_DACL_PROTECTED;
    1314          28 :                         torture_comment(tctx, "PROTECTED, ");
    1315          28 :                         tflags[i].parent_get_sd_type |=
    1316             :                             SEC_DESC_DACL_PROTECTED;
    1317             :                 }
    1318          60 :                 if (i & 8) {
    1319          28 :                         tflags[i].parent_set_ace_inherit |=
    1320             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1321          28 :                         torture_comment(tctx, "INHERITED, ");
    1322          28 :                         tflags[i].parent_get_ace_inherit |=
    1323             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1324             :                 }
    1325             : 
    1326          60 :                 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          12 :                         tflags[i].parent_get_sd_type |=
    1330             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1331          12 :                         tflags[i].child_get_sd_type |=
    1332             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1333          12 :                         tflags[i].child_get_ace_inherit |=
    1334             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1335          12 :                         torture_comment(tctx, "  ... parent is AUTO INHERITED");
    1336             :                 }
    1337             : 
    1338          60 :                 if (tflags[i].parent_set_ace_inherit &
    1339             :                     SEC_ACE_FLAG_INHERITED_ACE) {
    1340          28 :                         tflags[i].parent_get_ace_inherit =
    1341             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1342          28 :                         torture_comment(tctx, "  ... parent ACE is INHERITED");
    1343             :                 }
    1344             : 
    1345          60 :                 torture_comment(tctx, "\n");
    1346             :         }
    1347             : 
    1348           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
    1349           0 :                 return false;
    1350             : 
    1351           4 :         torture_comment(tctx, "TESTING ACL INHERITANCE FLAGS\n");
    1352             : 
    1353           4 :         ZERO_STRUCT(io);
    1354           4 :         io.level = RAW_OPEN_SMB2;
    1355           4 :         io.in.create_flags = 0;
    1356           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1357           4 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1358           4 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    1359           4 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    1360           4 :         io.in.alloc_size = 0;
    1361           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1362           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1363           4 :         io.in.security_flags = 0;
    1364           4 :         io.in.fname = dname;
    1365             : 
    1366           4 :         torture_comment(tctx, "creating initial directory %s\n", dname);
    1367           4 :         status = smb2_create(tree, tctx, &io);
    1368           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1369           4 :         handle = io.out.file.handle;
    1370             : 
    1371           4 :         torture_comment(tctx, "getting original sd\n");
    1372           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1373           4 :         q.query_secdesc.in.file.handle = handle;
    1374           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1375           4 :         status = smb2_getinfo_file(tree, tctx, &q);
    1376           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1377           4 :         sd_orig = q.query_secdesc.out.sd;
    1378             : 
    1379           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    1380           4 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
    1381             : 
    1382          68 :         for (i=0; i < ARRAY_SIZE(tflags); i++) {
    1383          64 :                 torture_comment(tctx, "setting a new sd on directory, pass #%d\n", i);
    1384             : 
    1385          64 :                 sd = security_descriptor_dacl_create(tctx,
    1386          64 :                                                 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          64 :                                                 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          64 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1400          64 :                 set.set_secdesc.in.file.handle = handle;
    1401          64 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1402          64 :                 set.set_secdesc.in.sd = sd;
    1403          64 :                 status = smb2_setinfo_file(tree, &set);
    1404          64 :                 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          64 :                 torture_comment(tctx, "  checking new sd\n");
    1411             : 
    1412             :                 /* REQ bit should always be false. */
    1413          64 :                 sd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1414             : 
    1415          64 :                 if ((tflags[i].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1416          52 :                         sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1417             : 
    1418          64 :                 q.query_secdesc.in.file.handle = handle;
    1419          64 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
    1420          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1421          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1422          64 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
    1423             : 
    1424             :                 /* Create file. */
    1425          64 :                 torture_comment(tctx, "  creating file %s\n", fname1);
    1426          64 :                 io.in.fname = fname1;
    1427          64 :                 io.in.create_options = 0;
    1428          64 :                 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1429          64 :                 io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1430          64 :                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1431          64 :                 status = smb2_create(tree, tctx, &io);
    1432          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1433          64 :                 handle2 = io.out.file.handle;
    1434          64 :                 CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
    1435             : 
    1436          64 :                 q.query_secdesc.in.file.handle = handle2;
    1437          64 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1438          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1439          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1440             : 
    1441          64 :                 torture_comment(tctx, "  checking sd on file %s\n", fname1);
    1442          64 :                 sd2 = security_descriptor_dacl_create(tctx,
    1443          64 :                                                  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          64 :                 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        1088 :                 for (j = 0; j < ARRAY_SIZE(tflags); j++) {
    1458        1024 :                         torture_comment(tctx, "  setting new file sd, pass #%d\n", j);
    1459             : 
    1460             :                         /* Change sd type. */
    1461        1024 :                         sd2->type &= ~(SEC_DESC_DACL_AUTO_INHERITED |
    1462             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ |
    1463             :                             SEC_DESC_DACL_PROTECTED);
    1464        1024 :                         sd2->type |= tflags[j].parent_set_sd_type;
    1465             : 
    1466        1024 :                         sd2->dacl->aces[0].flags &=
    1467             :                             ~SEC_ACE_FLAG_INHERITED_ACE;
    1468        1024 :                         sd2->dacl->aces[0].flags |=
    1469        1024 :                             tflags[j].parent_set_ace_inherit;
    1470             : 
    1471        1024 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1472        1024 :                         set.set_secdesc.in.file.handle = handle2;
    1473        1024 :                         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1474        1024 :                         set.set_secdesc.in.sd = sd2;
    1475        1024 :                         status = smb2_setinfo_file(tree, &set);
    1476        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1477             : 
    1478             :                         /* Check DACL we just set. */
    1479        1024 :                         sd2->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1480        1024 :                         if ((tflags[j].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1481         832 :                                 sd2->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1482             : 
    1483        1024 :                         q.query_secdesc.in.file.handle = handle2;
    1484        1024 :                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1485        1024 :                         status = smb2_getinfo_file(tree, tctx, &q);
    1486        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1487             : 
    1488        1024 :                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1489             :                 }
    1490             : 
    1491          64 :                 smb2_util_close(tree, handle2);
    1492          64 :                 smb2_util_unlink(tree, fname1);
    1493             :         }
    1494             : 
    1495           4 : done:
    1496           4 :         smb2_util_close(tree, handle);
    1497           4 :         smb2_deltree(tree, BASEDIR);
    1498           4 :         smb2_tdis(tree);
    1499           4 :         smb2_logoff(tree->session);
    1500           4 :         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           4 : static bool test_sd_flags_vs_chown(struct torture_context *tctx,
    1509             :                                    struct smb2_tree *tree)
    1510             : {
    1511           0 :         NTSTATUS status;
    1512           0 :         struct smb2_create io;
    1513           4 :         const char *dname = BASEDIR "\\inheritance";
    1514           4 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
    1515           4 :         bool ret = true;
    1516           4 :         struct smb2_handle handle = {{0}};
    1517           4 :         struct smb2_handle handle2 = {{0}};
    1518           0 :         int i, j;
    1519           0 :         union smb_fileinfo q;
    1520           0 :         union smb_setfileinfo set;
    1521           4 :         struct security_descriptor *sd, *sd2, *sd_orig=NULL;
    1522           4 :         struct security_descriptor *owner_sd = NULL;
    1523           4 :         const char *owner_sid_string = NULL;
    1524           4 :         struct dom_sid *owner_sid = NULL;
    1525           4 :         struct dom_sid world_sid = global_sid_World;
    1526           0 :         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           4 :         } tflags[16] = {{0}}; /* 2^4 */
    1534             : 
    1535           4 :         owner_sd = security_descriptor_dacl_create(tctx,
    1536             :                                                    0,
    1537             :                                                    SID_WORLD,
    1538             :                                                    NULL,
    1539             :                                                    NULL);
    1540           4 :         torture_assert_not_null_goto(tctx, owner_sd, ret, done,
    1541             :                                      "security_descriptor_dacl_create failed\n");
    1542             : 
    1543          64 :         for (i = 0; i < 15; i++) {
    1544          60 :                 torture_comment(tctx, "i=%d:", i);
    1545             : 
    1546          60 :                 if (i & 1) {
    1547          28 :                         tflags[i].parent_set_sd_type |=
    1548             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1549          28 :                         torture_comment(tctx, "AUTO_INHERITED, ");
    1550             :                 }
    1551          60 :                 if (i & 2) {
    1552          28 :                         tflags[i].parent_set_sd_type |=
    1553             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1554          28 :                         torture_comment(tctx, "AUTO_INHERIT_REQ, ");
    1555             :                 }
    1556          60 :                 if (i & 4) {
    1557          28 :                         tflags[i].parent_set_sd_type |=
    1558             :                             SEC_DESC_DACL_PROTECTED;
    1559          28 :                         torture_comment(tctx, "PROTECTED, ");
    1560          28 :                         tflags[i].parent_get_sd_type |=
    1561             :                             SEC_DESC_DACL_PROTECTED;
    1562             :                 }
    1563          60 :                 if (i & 8) {
    1564          28 :                         tflags[i].parent_set_ace_inherit |=
    1565             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1566          28 :                         torture_comment(tctx, "INHERITED, ");
    1567          28 :                         tflags[i].parent_get_ace_inherit |=
    1568             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1569             :                 }
    1570             : 
    1571          60 :                 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          12 :                         tflags[i].parent_get_sd_type |=
    1575             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1576          12 :                         tflags[i].child_get_sd_type |=
    1577             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1578          12 :                         tflags[i].child_get_ace_inherit |=
    1579             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1580          12 :                         torture_comment(tctx, "  ... parent is AUTO INHERITED");
    1581             :                 }
    1582             : 
    1583          60 :                 if (tflags[i].parent_set_ace_inherit &
    1584             :                     SEC_ACE_FLAG_INHERITED_ACE) {
    1585          28 :                         tflags[i].parent_get_ace_inherit =
    1586             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1587          28 :                         torture_comment(tctx, "  ... parent ACE is INHERITED");
    1588             :                 }
    1589             : 
    1590          60 :                 torture_comment(tctx, "\n");
    1591             :         }
    1592             : 
    1593           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
    1594           0 :                 return false;
    1595             : 
    1596           4 :         torture_comment(tctx, "TESTING ACL INHERITANCE FLAGS\n");
    1597             : 
    1598           4 :         ZERO_STRUCT(io);
    1599           4 :         io.level = RAW_OPEN_SMB2;
    1600           4 :         io.in.create_flags = 0;
    1601           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1602           4 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1603           4 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    1604           4 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    1605           4 :         io.in.alloc_size = 0;
    1606           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1607           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1608           4 :         io.in.security_flags = 0;
    1609           4 :         io.in.fname = dname;
    1610             : 
    1611           4 :         torture_comment(tctx, "creating initial directory %s\n", dname);
    1612           4 :         status = smb2_create(tree, tctx, &io);
    1613           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1614           4 :         handle = io.out.file.handle;
    1615             : 
    1616           4 :         torture_comment(tctx, "getting original sd\n");
    1617           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1618           4 :         q.query_secdesc.in.file.handle = handle;
    1619           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1620           4 :         status = smb2_getinfo_file(tree, tctx, &q);
    1621           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1622           4 :         sd_orig = q.query_secdesc.out.sd;
    1623             : 
    1624           4 :         owner_sid = sd_orig->owner_sid;
    1625           4 :         owner_sid_string = dom_sid_string(tctx, sd_orig->owner_sid);
    1626           4 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid_string);
    1627             : 
    1628          68 :         for (i=0; i < ARRAY_SIZE(tflags); i++) {
    1629          64 :                 torture_comment(tctx, "setting a new sd on directory, pass #%d\n", i);
    1630             : 
    1631          64 :                 sd = security_descriptor_dacl_create(tctx,
    1632          64 :                                                 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          64 :                                                 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          64 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1646          64 :                 set.set_secdesc.in.file.handle = handle;
    1647          64 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1648          64 :                 set.set_secdesc.in.sd = sd;
    1649          64 :                 status = smb2_setinfo_file(tree, &set);
    1650          64 :                 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          64 :                 torture_comment(tctx, "  checking new sd\n");
    1657             : 
    1658             :                 /* REQ bit should always be false. */
    1659          64 :                 sd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1660             : 
    1661          64 :                 if ((tflags[i].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1662          52 :                         sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1663             : 
    1664          64 :                 q.query_secdesc.in.file.handle = handle;
    1665          64 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
    1666          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1667          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1668          64 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
    1669             : 
    1670             :                 /* Create file. */
    1671          64 :                 torture_comment(tctx, "  creating file %s\n", fname1);
    1672          64 :                 io.in.fname = fname1;
    1673          64 :                 io.in.create_options = 0;
    1674          64 :                 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1675          64 :                 io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1676          64 :                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1677          64 :                 status = smb2_create(tree, tctx, &io);
    1678          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1679          64 :                 handle2 = io.out.file.handle;
    1680          64 :                 CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
    1681             : 
    1682          64 :                 q.query_secdesc.in.file.handle = handle2;
    1683          64 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1684          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1685          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1686             : 
    1687          64 :                 torture_comment(tctx, "  checking sd on file %s\n", fname1);
    1688          64 :                 sd2 = security_descriptor_dacl_create(tctx,
    1689          64 :                                                  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          64 :                 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        1088 :                 for (j = 0; j < ARRAY_SIZE(tflags); j++) {
    1704        1024 :                         torture_comment(tctx, "  setting new file sd, pass #%d\n", j);
    1705             : 
    1706             :                         /* Change sd type. */
    1707        1024 :                         sd2->type &= ~(SEC_DESC_DACL_AUTO_INHERITED |
    1708             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ |
    1709             :                             SEC_DESC_DACL_PROTECTED);
    1710        1024 :                         sd2->type |= tflags[j].parent_set_sd_type;
    1711             : 
    1712        1024 :                         sd2->dacl->aces[0].flags &=
    1713             :                             ~SEC_ACE_FLAG_INHERITED_ACE;
    1714        1024 :                         sd2->dacl->aces[0].flags |=
    1715        1024 :                             tflags[j].parent_set_ace_inherit;
    1716             : 
    1717        1024 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1718        1024 :                         set.set_secdesc.in.file.handle = handle2;
    1719        1024 :                         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1720        1024 :                         set.set_secdesc.in.sd = sd2;
    1721        1024 :                         status = smb2_setinfo_file(tree, &set);
    1722        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1723             : 
    1724             :                         /* Check DACL we just set. */
    1725        1024 :                         sd2->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1726        1024 :                         if ((tflags[j].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1727         832 :                                 sd2->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1728             : 
    1729        1024 :                         q.query_secdesc.in.file.handle = handle2;
    1730        1024 :                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1731        1024 :                         status = smb2_getinfo_file(tree, tctx, &q);
    1732        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1733             : 
    1734        1024 :                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1735             : 
    1736             :                         /*
    1737             :                          * Check that changing owner doesn't affect SD flags.
    1738             :                          *
    1739             :                          * Do this by first changing owner to world and then
    1740             :                          * back to the original owner. Afterwards compare SD,
    1741             :                          * should be the same.
    1742             :                          */
    1743        1024 :                         owner_sd->owner_sid = &world_sid;
    1744        1024 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1745        1024 :                         set.set_secdesc.in.file.handle = handle2;
    1746        1024 :                         set.set_secdesc.in.secinfo_flags = SECINFO_OWNER;
    1747        1024 :                         set.set_secdesc.in.sd = owner_sd;
    1748        1024 :                         status = smb2_setinfo_file(tree, &set);
    1749        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1750             : 
    1751        1024 :                         owner_sd->owner_sid = owner_sid;
    1752        1024 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1753        1024 :                         set.set_secdesc.in.file.handle = handle2;
    1754        1024 :                         set.set_secdesc.in.secinfo_flags = SECINFO_OWNER;
    1755        1024 :                         set.set_secdesc.in.sd = owner_sd;
    1756        1024 :                         status = smb2_setinfo_file(tree, &set);
    1757        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1758             : 
    1759        1024 :                         q.query_secdesc.in.file.handle = handle2;
    1760        1024 :                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1761        1024 :                         status = smb2_getinfo_file(tree, tctx, &q);
    1762        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1763             : 
    1764        1024 :                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1765        1024 :                         torture_assert_goto(tctx, ret, ret, done, "CHECK_SECURITY_DESCRIPTOR failed\n");
    1766             :                 }
    1767             : 
    1768          64 :                 smb2_util_close(tree, handle2);
    1769          64 :                 smb2_util_unlink(tree, fname1);
    1770             :         }
    1771             : 
    1772           4 : done:
    1773           4 :         smb2_util_close(tree, handle);
    1774           4 :         smb2_deltree(tree, BASEDIR);
    1775           4 :         smb2_tdis(tree);
    1776           4 :         smb2_logoff(tree->session);
    1777           4 :         return ret;
    1778             : }
    1779             : 
    1780             : /*
    1781             :   test dynamic acl inheritance
    1782             :   Note: This test was copied from raw/acls.c.
    1783             : */
    1784           4 : static bool test_inheritance_dynamic(struct torture_context *tctx,
    1785             :     struct smb2_tree *tree)
    1786             : {
    1787           0 :         NTSTATUS status;
    1788           0 :         struct smb2_create io;
    1789           4 :         const char *dname = BASEDIR "\\inheritance";
    1790           4 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
    1791           4 :         bool ret = true;
    1792           4 :         struct smb2_handle handle = {{0}};
    1793           4 :         struct smb2_handle handle2 = {{0}};
    1794           0 :         union smb_fileinfo q;
    1795           0 :         union smb_setfileinfo set;
    1796           4 :         struct security_descriptor *sd, *sd_orig=NULL;
    1797           0 :         const char *owner_sid;
    1798             : 
    1799           4 :         torture_comment(tctx, "TESTING DYNAMIC ACL INHERITANCE\n");
    1800             : 
    1801           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
    1802           0 :                 return false;
    1803             : 
    1804           4 :         ZERO_STRUCT(io);
    1805           4 :         io.level = RAW_OPEN_SMB2;
    1806           4 :         io.in.create_flags = 0;
    1807           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1808           4 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1809           4 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    1810           4 :         io.in.share_access = 0;
    1811           4 :         io.in.alloc_size = 0;
    1812           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1813           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1814           4 :         io.in.security_flags = 0;
    1815           4 :         io.in.fname = dname;
    1816             : 
    1817           4 :         status = smb2_create(tree, tctx, &io);
    1818           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1819           4 :         handle = io.out.file.handle;
    1820             : 
    1821           4 :         torture_comment(tctx, "get the original sd\n");
    1822           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1823           4 :         q.query_secdesc.in.file.handle = handle;
    1824           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1825           4 :         status = smb2_getinfo_file(tree, tctx, &q);
    1826           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1827           4 :         sd_orig = q.query_secdesc.out.sd;
    1828             : 
    1829           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    1830             : 
    1831           4 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
    1832             : 
    1833           4 :         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           4 :         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1841             : 
    1842           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1843           4 :         set.set_secdesc.in.file.handle = handle;
    1844           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1845           4 :         set.set_secdesc.in.sd = sd;
    1846           4 :         status = smb2_setinfo_file(tree, &set);
    1847           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1848             : 
    1849           4 :         torture_comment(tctx, "create a file with an inherited acl\n");
    1850           4 :         io.in.fname = fname1;
    1851           4 :         io.in.create_options = 0;
    1852           4 :         io.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
    1853           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1854           4 :         status = smb2_create(tree, tctx, &io);
    1855           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1856           4 :         handle2 = io.out.file.handle;
    1857           4 :         smb2_util_close(tree, handle2);
    1858             : 
    1859           4 :         torture_comment(tctx, "try and access file with base rights - should be OK\n");
    1860           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1861           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1862           4 :         status = smb2_create(tree, tctx, &io);
    1863           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1864           4 :         handle2 = io.out.file.handle;
    1865           4 :         smb2_util_close(tree, handle2);
    1866             : 
    1867           4 :         torture_comment(tctx, "try and access file with extra rights - should be denied\n");
    1868           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
    1869           4 :         status = smb2_create(tree, tctx, &io);
    1870           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1871             : 
    1872           4 :         torture_comment(tctx, "update parent sd\n");
    1873           4 :         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           4 :         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1881             : 
    1882           4 :         set.set_secdesc.in.sd = sd;
    1883           4 :         status = smb2_setinfo_file(tree, &set);
    1884           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1885             : 
    1886           4 :         torture_comment(tctx, "try and access file with base rights - should be OK\n");
    1887           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1888           4 :         status = smb2_create(tree, tctx, &io);
    1889           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1890           4 :         handle2 = io.out.file.handle;
    1891           4 :         smb2_util_close(tree, handle2);
    1892             : 
    1893             : 
    1894           4 :         torture_comment(tctx, "try and access now - should be OK if dynamic inheritance works\n");
    1895           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
    1896           4 :         status = smb2_create(tree, tctx, &io);
    1897           4 :         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    1898           4 :                 torture_comment(tctx, "Server does not have dynamic inheritance\n");
    1899             :         }
    1900           4 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
    1901           0 :                 torture_comment(tctx, "Server does have dynamic inheritance\n");
    1902             :         }
    1903           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1904             : 
    1905           4 :         smb2_util_unlink(tree, fname1);
    1906             : 
    1907           4 : done:
    1908           4 :         torture_comment(tctx, "put back original sd\n");
    1909           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1910           4 :         set.set_secdesc.in.file.handle = handle;
    1911           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1912           4 :         set.set_secdesc.in.sd = sd_orig;
    1913           4 :         status = smb2_setinfo_file(tree, &set);
    1914             : 
    1915           4 :         smb2_util_close(tree, handle);
    1916           4 :         smb2_util_rmdir(tree, dname);
    1917           4 :         smb2_deltree(tree, BASEDIR);
    1918           4 :         smb2_tdis(tree);
    1919           4 :         smb2_logoff(tree->session);
    1920             : 
    1921           4 :         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           4 : static bool test_access_based(struct torture_context *tctx,
    2143             :                                 struct smb2_tree *tree)
    2144             : {
    2145           4 :         struct smb2_tree *tree1 = NULL;
    2146           0 :         NTSTATUS status;
    2147           0 :         struct smb2_create io;
    2148           4 :         const char *fname = BASEDIR "\\testfile";
    2149           4 :         bool ret = true;
    2150           0 :         struct smb2_handle fhandle, dhandle;
    2151           0 :         union smb_fileinfo q;
    2152           0 :         union smb_setfileinfo set;
    2153           4 :         struct security_descriptor *sd, *sd_orig=NULL;
    2154           0 :         const char *owner_sid;
    2155           4 :         uint32_t flags = 0;
    2156             :         /*
    2157             :          * Can't test without SEC_STD_READ_CONTROL as we
    2158             :          * own the file and implicitly have SEC_STD_READ_CONTROL.
    2159             :         */
    2160           4 :         uint32_t access_masks[] = {
    2161             :                 /* Full READ access. */
    2162             :                 SEC_STD_READ_CONTROL|FILE_READ_DATA|
    2163             :                 FILE_READ_ATTRIBUTES|FILE_READ_EA,
    2164             : 
    2165             :                 /* Missing FILE_READ_EA. */
    2166             :                 SEC_STD_READ_CONTROL|FILE_READ_DATA|
    2167             :                 FILE_READ_ATTRIBUTES,
    2168             : 
    2169             :                 /* Missing FILE_READ_ATTRIBUTES. */
    2170             :                 SEC_STD_READ_CONTROL|FILE_READ_DATA|
    2171             :                 FILE_READ_EA,
    2172             : 
    2173             :                 /* Missing FILE_READ_DATA. */
    2174             :                 SEC_STD_READ_CONTROL|
    2175             :                 FILE_READ_ATTRIBUTES|FILE_READ_EA,
    2176             :         };
    2177           0 :         unsigned int i;
    2178           0 :         unsigned int count;
    2179           0 :         struct smb2_find f;
    2180           0 :         union smb_search_data *d;
    2181             : 
    2182           4 :         ZERO_STRUCT(fhandle);
    2183           4 :         ZERO_STRUCT(dhandle);
    2184             : 
    2185           4 :         if (!torture_smb2_con_share(tctx, "hideunread", &tree1)) {
    2186           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) Unable to connect "
    2187             :                         "to share 'hideunread'\n",
    2188             :                        __location__);
    2189           0 :                 ret = false;
    2190           0 :                 goto done;
    2191             :         }
    2192             : 
    2193           4 :         flags = smb2cli_tcon_flags(tree1->smbXcli);
    2194             : 
    2195           4 :         smb2_util_unlink(tree1, fname);
    2196           4 :         smb2_deltree(tree1, BASEDIR);
    2197             : 
    2198           4 :         torture_comment(tctx, "TESTING ACCESS BASED ENUMERATION\n");
    2199             : 
    2200           4 :         if ((flags & SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM)==0) {
    2201           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) No access enumeration "
    2202             :                         "on share 'hideunread'\n",
    2203             :                        __location__);
    2204           0 :                 ret = false;
    2205           0 :                 goto done;
    2206             :         }
    2207             : 
    2208           4 :         if (!smb2_util_setup_dir(tctx, tree1, BASEDIR)) {
    2209           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) Unable to setup %s\n",
    2210             :                        __location__, BASEDIR);
    2211           0 :                 ret = false;
    2212           0 :                 goto done;
    2213             :         }
    2214             : 
    2215             :         /* Get a handle to the BASEDIR directory. */
    2216           4 :         status = torture_smb2_testdir(tree1, BASEDIR, &dhandle);
    2217           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    2218           4 :         smb2_util_close(tree1, dhandle);
    2219           4 :         ZERO_STRUCT(dhandle);
    2220             : 
    2221           4 :         ZERO_STRUCT(io);
    2222           4 :         io.level = RAW_OPEN_SMB2;
    2223           4 :         io.in.create_flags = 0;
    2224           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    2225           4 :         io.in.create_options = 0;
    2226           4 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    2227           4 :         io.in.share_access = 0;
    2228           4 :         io.in.alloc_size = 0;
    2229           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    2230           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2231           4 :         io.in.security_flags = 0;
    2232           4 :         io.in.fname = fname;
    2233             : 
    2234           4 :         status = smb2_create(tree1, tctx, &io);
    2235           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    2236           4 :         fhandle = io.out.file.handle;
    2237             : 
    2238           4 :         torture_comment(tctx, "get the original sd\n");
    2239           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    2240           4 :         q.query_secdesc.in.file.handle = fhandle;
    2241           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    2242           4 :         status = smb2_getinfo_file(tree1, tctx, &q);
    2243           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    2244           4 :         sd_orig = q.query_secdesc.out.sd;
    2245             : 
    2246           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2247             : 
    2248           4 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
    2249             : 
    2250             :         /* Setup for the search. */
    2251           4 :         ZERO_STRUCT(f);
    2252           4 :         f.in.pattern            = "*";
    2253           4 :         f.in.continue_flags     = SMB2_CONTINUE_FLAG_REOPEN;
    2254           4 :         f.in.max_response_size  = 0x1000;
    2255           4 :         f.in.level              = SMB2_FIND_DIRECTORY_INFO;
    2256             : 
    2257          20 :         for (i = 0; i < ARRAY_SIZE(access_masks); i++) {
    2258             : 
    2259          16 :                 sd = security_descriptor_dacl_create(tctx,
    2260             :                                         0, NULL, NULL,
    2261             :                                         owner_sid,
    2262             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2263          16 :                                         access_masks[i]|SEC_STD_SYNCHRONIZE,
    2264             :                                         0,
    2265             :                                         NULL);
    2266             : 
    2267          16 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    2268          16 :                 set.set_secdesc.in.file.handle = fhandle;
    2269          16 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    2270          16 :                 set.set_secdesc.in.sd = sd;
    2271          16 :                 status = smb2_setinfo_file(tree1, &set);
    2272          16 :                 CHECK_STATUS(status, NT_STATUS_OK);
    2273             : 
    2274             :                 /* Now see if we can see the file in a directory listing. */
    2275             : 
    2276             :                 /* Re-open dhandle. */
    2277          16 :                 status = torture_smb2_testdir(tree1, BASEDIR, &dhandle);
    2278          16 :                 CHECK_STATUS(status, NT_STATUS_OK);
    2279          16 :                 f.in.file.handle = dhandle;
    2280             : 
    2281          16 :                 count = 0;
    2282          16 :                 d = NULL;
    2283          16 :                 status = smb2_find_level(tree1, tree1, &f, &count, &d);
    2284          16 :                 TALLOC_FREE(d);
    2285             : 
    2286          16 :                 CHECK_STATUS(status, NT_STATUS_OK);
    2287             : 
    2288          16 :                 smb2_util_close(tree1, dhandle);
    2289          16 :                 ZERO_STRUCT(dhandle);
    2290             : 
    2291          16 :                 if (i == 0) {
    2292             :                         /* We should see the first sd. */
    2293           4 :                         if (count != 3) {
    2294           0 :                                 torture_result(tctx, TORTURE_FAIL,
    2295             :                                         "(%s) Normal SD - Unable "
    2296             :                                         "to see file %s\n",
    2297             :                                         __location__,
    2298             :                                         BASEDIR);
    2299           0 :                                 ret = false;
    2300           0 :                                 goto done;
    2301             :                         }
    2302             :                 } else {
    2303             :                         /* But no others. */
    2304          12 :                         if (count != 2) {
    2305           0 :                                 torture_result(tctx, TORTURE_FAIL,
    2306             :                                         "(%s) SD 0x%x - can "
    2307             :                                         "see file %s\n",
    2308             :                                         __location__,
    2309             :                                         access_masks[i],
    2310             :                                         BASEDIR);
    2311           0 :                                 ret = false;
    2312           0 :                                 goto done;
    2313             :                         }
    2314             :                 }
    2315             :         }
    2316             : 
    2317           4 : done:
    2318             : 
    2319           4 :         if (tree1) {
    2320           4 :                 smb2_util_close(tree1, fhandle);
    2321           4 :                 smb2_util_close(tree1, dhandle);
    2322           4 :                 smb2_util_unlink(tree1, fname);
    2323           4 :                 smb2_deltree(tree1, BASEDIR);
    2324           4 :                 smb2_tdis(tree1);
    2325           4 :                 smb2_logoff(tree1->session);
    2326             :         }
    2327           4 :         smb2_tdis(tree);
    2328           4 :         smb2_logoff(tree->session);
    2329           4 :         return ret;
    2330             : }
    2331             : 
    2332             : /*
    2333             :  * test Owner Rights, S-1-3-4
    2334             :  */
    2335           4 : static bool test_owner_rights(struct torture_context *tctx,
    2336             :                               struct smb2_tree *tree)
    2337             : {
    2338           4 :         const char *fname = BASEDIR "\\owner_right.txt";
    2339           0 :         struct smb2_create cr;
    2340           4 :         struct smb2_handle handle = {{0}};
    2341           0 :         union smb_fileinfo gi;
    2342           0 :         union smb_setfileinfo si;
    2343           4 :         struct security_descriptor *sd_orig = NULL;
    2344           4 :         struct security_descriptor *sd = NULL;
    2345           4 :         const char *owner_sid = NULL;
    2346           0 :         NTSTATUS mxac_status;
    2347           0 :         NTSTATUS status;
    2348           4 :         bool ret = true;
    2349             : 
    2350           4 :         smb2_deltree(tree, BASEDIR);
    2351             : 
    2352           4 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2353           4 :         torture_assert_goto(tctx, ret, ret, done,
    2354             :                             "smb2_util_setup_dir failed\n");
    2355             : 
    2356           4 :         torture_comment(tctx, "TESTING OWNER RIGHTS\n");
    2357             : 
    2358           4 :         cr = (struct smb2_create) {
    2359             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    2360             :                         SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
    2361             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2362             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2363             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2364             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2365             :                 .in.fname = fname,
    2366             :         };
    2367             : 
    2368           4 :         status = smb2_create(tree, tctx, &cr);
    2369           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2370             :                                         "smb2_create failed\n");
    2371           4 :         handle = cr.out.file.handle;
    2372             : 
    2373           4 :         torture_comment(tctx, "get the original sd\n");
    2374             : 
    2375           4 :         gi = (union smb_fileinfo) {
    2376             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    2377             :                 .query_secdesc.in.file.handle = handle,
    2378             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
    2379             :         };
    2380             : 
    2381           4 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2382           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2383             :                                         "smb2_getinfo_file failed\n");
    2384             : 
    2385           4 :         sd_orig = gi.query_secdesc.out.sd;
    2386           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2387             : 
    2388             :         /*
    2389             :          * Add a 2 element ACL
    2390             :          * SEC_RIGHTS_FILE_READ for the owner,
    2391             :          * SEC_FILE_WRITE_DATA for SID_OWNER_RIGHTS.
    2392             :          *
    2393             :          * Proves that the owner and SID_OWNER_RIGHTS
    2394             :          * ACE entries are additive.
    2395             :          */
    2396           4 :         sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL,
    2397             :                                              owner_sid,
    2398             :                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
    2399             :                                              SEC_RIGHTS_FILE_READ,
    2400             :                                              0,
    2401             :                                              SID_OWNER_RIGHTS,
    2402             :                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
    2403             :                                              SEC_FILE_WRITE_DATA,
    2404             :                                              0,
    2405             :                                              NULL);
    2406           4 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2407             :                                      "SD create failed\n");
    2408             : 
    2409           4 :         si = (union smb_setfileinfo) {
    2410             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    2411             :                 .set_secdesc.in.file.handle = handle,
    2412             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    2413             :                 .set_secdesc.in.sd = sd,
    2414             :         };
    2415             : 
    2416           4 :         status = smb2_setinfo_file(tree, &si);
    2417           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2418             :                                         "smb2_setinfo_file failed\n");
    2419             : 
    2420           4 :         status = smb2_util_close(tree, handle);
    2421           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2422             :                                         "smb2_util_close failed\n");
    2423           4 :         ZERO_STRUCT(handle);
    2424             : 
    2425           4 :         cr = (struct smb2_create) {
    2426             :                 .in.desired_access = SEC_STD_READ_CONTROL,
    2427             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2428             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2429             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2430             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2431             :                 .in.query_maximal_access = true,
    2432             :                 .in.fname = fname,
    2433             :         };
    2434             : 
    2435           4 :         status = smb2_create(tree, tctx, &cr);
    2436           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2437             :                                         "smb2_setinfo_file failed\n");
    2438           4 :         handle = cr.out.file.handle;
    2439             : 
    2440           4 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2441           4 :         torture_assert_ntstatus_ok_goto(tctx, mxac_status, ret, done,
    2442             :                                         "smb2_setinfo_file failed\n");
    2443             : 
    2444             :         /*
    2445             :          * For some reasons Windows 2016 doesn't set SEC_STD_DELETE but we
    2446             :          * do. Mask it out so the test passes against Samba and Windows.
    2447             :          */
    2448           4 :         torture_assert_int_equal_goto(tctx,
    2449             :                                       cr.out.maximal_access & ~SEC_STD_DELETE,
    2450             :                                       SEC_RIGHTS_FILE_READ |
    2451             :                                       SEC_FILE_WRITE_DATA,
    2452             :                                       ret, done,
    2453             :                                       "Wrong maximum access\n");
    2454             : 
    2455           4 :         status = smb2_util_close(tree, handle);
    2456           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2457             :                                         "smb2_util_close failed\n");
    2458           4 :         ZERO_STRUCT(handle);
    2459             : 
    2460           4 : done:
    2461           4 :         if (!smb2_util_handle_empty(handle)) {
    2462           0 :                 smb2_util_close(tree, handle);
    2463             :         }
    2464           4 :         smb2_deltree(tree, BASEDIR);
    2465           4 :         return ret;
    2466             : }
    2467             : 
    2468             : /*
    2469             :  * test Owner Rights with a leading DENY ACE, S-1-3-4
    2470             :  */
    2471           4 : static bool test_owner_rights_deny(struct torture_context *tctx,
    2472             :                                 struct smb2_tree *tree)
    2473             : {
    2474           4 :         const char *fname = BASEDIR "\\owner_right_deny.txt";
    2475           0 :         struct smb2_create cr;
    2476           4 :         struct smb2_handle handle = {{0}};
    2477           0 :         union smb_fileinfo gi;
    2478           0 :         union smb_setfileinfo si;
    2479           4 :         struct security_descriptor *sd_orig = NULL;
    2480           4 :         struct security_descriptor *sd = NULL;
    2481           4 :         const char *owner_sid = NULL;
    2482           0 :         NTSTATUS mxac_status;
    2483           0 :         NTSTATUS status;
    2484           4 :         bool ret = true;
    2485             : 
    2486           4 :         smb2_deltree(tree, BASEDIR);
    2487             : 
    2488           4 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2489           4 :         torture_assert_goto(tctx, ret, ret, done,
    2490             :                         "smb2_util_setup_dir failed\n");
    2491             : 
    2492           4 :         torture_comment(tctx, "TESTING OWNER RIGHTS DENY\n");
    2493             : 
    2494           4 :         cr = (struct smb2_create) {
    2495             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    2496             :                         SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
    2497             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2498             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2499             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2500             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2501             :                 .in.fname = fname,
    2502             :         };
    2503             : 
    2504           4 :         status = smb2_create(tree, tctx, &cr);
    2505           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2506             :                                         "smb2_create failed\n");
    2507           4 :         handle = cr.out.file.handle;
    2508             : 
    2509           4 :         torture_comment(tctx, "get the original sd\n");
    2510             : 
    2511           4 :         gi = (union smb_fileinfo) {
    2512             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    2513             :                 .query_secdesc.in.file.handle = handle,
    2514             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
    2515             :         };
    2516             : 
    2517           4 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2518           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2519             :                                 "smb2_getinfo_file failed\n");
    2520             : 
    2521           4 :         sd_orig = gi.query_secdesc.out.sd;
    2522           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2523             : 
    2524             :         /*
    2525             :          * Add a 2 element ACL
    2526             :          * DENY SEC_FILE_DATA_READ for SID_OWNER_RIGHTS
    2527             :          * SEC_FILE_READ_DATA for the owner.
    2528             :          *
    2529             :          * Proves that the owner and SID_OWNER_RIGHTS
    2530             :          * ACE entries are additive.
    2531             :          */
    2532           4 :         sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL,
    2533             :                                         SID_OWNER_RIGHTS,
    2534             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    2535             :                                         SEC_FILE_READ_DATA,
    2536             :                                         0,
    2537             :                                         owner_sid,
    2538             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2539             :                                         SEC_RIGHTS_FILE_READ,
    2540             :                                         0,
    2541             :                                         NULL);
    2542           4 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2543             :                                         "SD create failed\n");
    2544             : 
    2545           4 :         si = (union smb_setfileinfo) {
    2546             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    2547             :                 .set_secdesc.in.file.handle = handle,
    2548             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    2549             :                 .set_secdesc.in.sd = sd,
    2550             :         };
    2551             : 
    2552           4 :         status = smb2_setinfo_file(tree, &si);
    2553           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2554             :                                         "smb2_setinfo_file failed\n");
    2555             : 
    2556           4 :         status = smb2_util_close(tree, handle);
    2557           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2558             :                                         "smb2_util_close failed\n");
    2559           4 :         ZERO_STRUCT(handle);
    2560             : 
    2561           4 :         cr = (struct smb2_create) {
    2562             :                 .in.desired_access = SEC_STD_READ_CONTROL,
    2563             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2564             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2565             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2566             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2567             :                 .in.query_maximal_access = true,
    2568             :                 .in.fname = fname,
    2569             :         };
    2570             : 
    2571           4 :         status = smb2_create(tree, tctx, &cr);
    2572           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2573             :                                         "smb2_setinfo_file failed\n");
    2574           4 :         handle = cr.out.file.handle;
    2575             : 
    2576           4 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2577           4 :         torture_assert_ntstatus_ok_goto(tctx, mxac_status, ret, done,
    2578             :                                         "smb2_setinfo_file failed\n");
    2579             : 
    2580             :         /*
    2581             :          * For some reasons Windows 2016 doesn't set SEC_STD_DELETE but we
    2582             :          * do. Mask it out so the test passes against Samba and Windows.
    2583             :          */
    2584           4 :         torture_assert_int_equal_goto(tctx,
    2585             :                                       cr.out.maximal_access & ~SEC_STD_DELETE,
    2586             :                                       SEC_RIGHTS_FILE_READ & ~SEC_FILE_READ_DATA,
    2587             :                                       ret, done,
    2588             :                                       "Wrong maximum access\n");
    2589             : 
    2590           4 :         status = smb2_util_close(tree, handle);
    2591           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2592             :                                         "smb2_util_close failed\n");
    2593           4 :         ZERO_STRUCT(handle);
    2594             : 
    2595           4 : done:
    2596           4 :         if (!smb2_util_handle_empty(handle)) {
    2597           0 :                 smb2_util_close(tree, handle);
    2598             :         }
    2599           4 :         smb2_deltree(tree, BASEDIR);
    2600           4 :         return ret;
    2601             : }
    2602             : 
    2603             : /*
    2604             :  * test Owner Rights with a trailing DENY ACE, S-1-3-4
    2605             :  */
    2606           4 : static bool test_owner_rights_deny1(struct torture_context *tctx,
    2607             :                                 struct smb2_tree *tree)
    2608             : {
    2609           4 :         const char *fname = BASEDIR "\\owner_right_deny1.txt";
    2610           0 :         struct smb2_create cr;
    2611           4 :         struct smb2_handle handle = {{0}};
    2612           0 :         union smb_fileinfo gi;
    2613           0 :         union smb_setfileinfo si;
    2614           4 :         struct security_descriptor *sd_orig = NULL;
    2615           4 :         struct security_descriptor *sd = NULL;
    2616           4 :         const char *owner_sid = NULL;
    2617           0 :         NTSTATUS mxac_status;
    2618           0 :         NTSTATUS status;
    2619           4 :         bool ret = true;
    2620             : 
    2621           4 :         smb2_deltree(tree, BASEDIR);
    2622             : 
    2623           4 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2624           4 :         torture_assert_goto(tctx, ret, ret, done,
    2625             :                         "smb2_util_setup_dir failed\n");
    2626             : 
    2627           4 :         torture_comment(tctx, "TESTING OWNER RIGHTS DENY1\n");
    2628             : 
    2629           4 :         cr = (struct smb2_create) {
    2630             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    2631             :                         SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
    2632             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2633             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2634             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2635             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2636             :                 .in.fname = fname,
    2637             :         };
    2638             : 
    2639           4 :         status = smb2_create(tree, tctx, &cr);
    2640           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2641             :                                         "smb2_create failed\n");
    2642           4 :         handle = cr.out.file.handle;
    2643             : 
    2644           4 :         torture_comment(tctx, "get the original sd\n");
    2645             : 
    2646           4 :         gi = (union smb_fileinfo) {
    2647             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    2648             :                 .query_secdesc.in.file.handle = handle,
    2649             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
    2650             :         };
    2651             : 
    2652           4 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2653           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2654             :                                 "smb2_getinfo_file failed\n");
    2655             : 
    2656           4 :         sd_orig = gi.query_secdesc.out.sd;
    2657           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2658             : 
    2659             :         /*
    2660             :          * Add a 3 element ACL
    2661             :          *
    2662             :          * SEC_RIGHTS_FILE_READ allow for owner.
    2663             :          * SEC_FILE_WRITE_DATA allow for SID-OWNER-RIGHTS.
    2664             :          * SEC_FILE_WRITE_DATA|SEC_FILE_READ_DATA) deny for SID-OWNER-RIGHTS.
    2665             :          *
    2666             :          * Shows on Windows that trailing DENY entries don't
    2667             :          * override granted permissions in max access calculations.
    2668             :          */
    2669           4 :         sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL,
    2670             :                                         owner_sid,
    2671             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2672             :                                         SEC_RIGHTS_FILE_READ,
    2673             :                                         0,
    2674             :                                         SID_OWNER_RIGHTS,
    2675             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2676             :                                         SEC_FILE_WRITE_DATA,
    2677             :                                         0,
    2678             :                                         SID_OWNER_RIGHTS,
    2679             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    2680             :                                         (SEC_FILE_WRITE_DATA|
    2681             :                                                 SEC_FILE_READ_DATA),
    2682             :                                         0,
    2683             :                                         NULL);
    2684           4 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2685             :                                         "SD create failed\n");
    2686             : 
    2687           4 :         si = (union smb_setfileinfo) {
    2688             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    2689             :                 .set_secdesc.in.file.handle = handle,
    2690             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    2691             :                 .set_secdesc.in.sd = sd,
    2692             :         };
    2693             : 
    2694           4 :         status = smb2_setinfo_file(tree, &si);
    2695           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2696             :                                         "smb2_setinfo_file failed\n");
    2697             : 
    2698           4 :         status = smb2_util_close(tree, handle);
    2699           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2700             :                                         "smb2_util_close failed\n");
    2701           4 :         ZERO_STRUCT(handle);
    2702             : 
    2703           4 :         cr = (struct smb2_create) {
    2704             :                 .in.desired_access = SEC_STD_READ_CONTROL,
    2705             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2706             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2707             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2708             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2709             :                 .in.query_maximal_access = true,
    2710             :                 .in.fname = fname,
    2711             :         };
    2712             : 
    2713           4 :         status = smb2_create(tree, tctx, &cr);
    2714           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2715             :                                         "smb2_setinfo_file failed\n");
    2716           4 :         handle = cr.out.file.handle;
    2717             : 
    2718           4 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2719           4 :         torture_assert_ntstatus_ok_goto(tctx, mxac_status, ret, done,
    2720             :                                         "smb2_setinfo_file failed\n");
    2721             : 
    2722             :         /*
    2723             :          * For some reasons Windows 2016 doesn't set SEC_STD_DELETE but we
    2724             :          * do. Mask it out so the test passes against Samba and Windows.
    2725             :          */
    2726           4 :         torture_assert_int_equal_goto(tctx,
    2727             :                                 cr.out.maximal_access & ~SEC_STD_DELETE,
    2728             :                                 SEC_RIGHTS_FILE_READ | SEC_FILE_WRITE_DATA,
    2729             :                                 ret, done,
    2730             :                                 "Wrong maximum access\n");
    2731             : 
    2732           4 :         status = smb2_util_close(tree, handle);
    2733           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2734             :                                         "smb2_util_close failed\n");
    2735           4 :         ZERO_STRUCT(handle);
    2736             : 
    2737           4 : done:
    2738           4 :         if (!smb2_util_handle_empty(handle)) {
    2739           0 :                 smb2_util_close(tree, handle);
    2740             :         }
    2741           4 :         smb2_deltree(tree, BASEDIR);
    2742           4 :         return ret;
    2743             : }
    2744             : 
    2745             : /*
    2746             :  * test that shows that a DENY ACE doesn't remove rights granted
    2747             :  * by a previous ALLOW ACE.
    2748             :  */
    2749           4 : static bool test_deny1(struct torture_context *tctx,
    2750             :                        struct smb2_tree *tree)
    2751             : {
    2752           4 :         const char *fname = BASEDIR "\\test_deny1.txt";
    2753           0 :         struct smb2_create cr;
    2754           4 :         struct smb2_handle handle = {{0}};
    2755           0 :         union smb_fileinfo gi;
    2756           0 :         union smb_setfileinfo si;
    2757           4 :         struct security_descriptor *sd_orig = NULL;
    2758           4 :         struct security_descriptor *sd = NULL;
    2759           4 :         const char *owner_sid = NULL;
    2760           0 :         NTSTATUS mxac_status;
    2761           0 :         NTSTATUS status;
    2762           4 :         bool ret = true;
    2763             : 
    2764           4 :         smb2_deltree(tree, BASEDIR);
    2765             : 
    2766           4 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2767           4 :         torture_assert_goto(tctx, ret, ret, done,
    2768             :                         "smb2_util_setup_dir failed\n");
    2769             : 
    2770           4 :         cr = (struct smb2_create) {
    2771             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    2772             :                         SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
    2773             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2774             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2775             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2776             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2777             :                 .in.fname = fname,
    2778             :         };
    2779             : 
    2780           4 :         status = smb2_create(tree, tctx, &cr);
    2781           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2782             :                                         "smb2_create failed\n");
    2783           4 :         handle = cr.out.file.handle;
    2784             : 
    2785           4 :         torture_comment(tctx, "get the original sd\n");
    2786             : 
    2787           4 :         gi = (union smb_fileinfo) {
    2788             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    2789             :                 .query_secdesc.in.file.handle = handle,
    2790             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
    2791             :         };
    2792             : 
    2793           4 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2794           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2795             :                                 "smb2_getinfo_file failed\n");
    2796             : 
    2797           4 :         sd_orig = gi.query_secdesc.out.sd;
    2798           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2799             : 
    2800             :         /*
    2801             :          * Add a 2 element ACL
    2802             :          *
    2803             :          * SEC_RIGHTS_FILE_READ|SEC_FILE_WRITE_DATA allow for owner.
    2804             :          * SEC_FILE_WRITE_DATA deny for owner
    2805             :          *
    2806             :          * Shows on Windows that trailing DENY entries don't
    2807             :          * override granted permissions.
    2808             :          */
    2809           4 :         sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL,
    2810             :                                         owner_sid,
    2811             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2812             :                                         SEC_RIGHTS_FILE_READ|SEC_FILE_WRITE_DATA,
    2813             :                                         0,
    2814             :                                         owner_sid,
    2815             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    2816             :                                         SEC_FILE_WRITE_DATA,
    2817             :                                         0,
    2818             :                                         NULL);
    2819           4 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2820             :                                         "SD create failed\n");
    2821             : 
    2822           4 :         si = (union smb_setfileinfo) {
    2823             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    2824             :                 .set_secdesc.in.file.handle = handle,
    2825             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    2826             :                 .set_secdesc.in.sd = sd,
    2827             :         };
    2828             : 
    2829           4 :         status = smb2_setinfo_file(tree, &si);
    2830           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2831             :                                         "smb2_setinfo_file failed\n");
    2832             : 
    2833           4 :         status = smb2_util_close(tree, handle);
    2834           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2835             :                                         "smb2_util_close failed\n");
    2836           4 :         ZERO_STRUCT(handle);
    2837             : 
    2838           4 :         cr = (struct smb2_create) {
    2839             :                 .in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_WRITE_DATA,
    2840             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2841             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2842             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2843             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2844             :                 .in.query_maximal_access = true,
    2845             :                 .in.fname = fname,
    2846             :         };
    2847             : 
    2848           4 :         status = smb2_create(tree, tctx, &cr);
    2849           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2850             :                                         "smb2_create failed\n");
    2851           4 :         handle = cr.out.file.handle;
    2852             : 
    2853           4 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2854           4 :         torture_assert_ntstatus_ok_goto(tctx, mxac_status, ret, done,
    2855             :                                         "Wrong maximum access status\n");
    2856             : 
    2857             :         /*
    2858             :          * For some reasons Windows 2016 doesn't set SEC_STD_DELETE but we
    2859             :          * do. Mask it out so the test passes against Samba and Windows.
    2860             :          * SEC_STD_WRITE_DAC comes from being the owner.
    2861             :          */
    2862           4 :         torture_assert_int_equal_goto(tctx,
    2863             :                                       cr.out.maximal_access & ~SEC_STD_DELETE,
    2864             :                                       SEC_RIGHTS_FILE_READ |
    2865             :                                       SEC_FILE_WRITE_DATA |
    2866             :                                       SEC_STD_WRITE_DAC,
    2867             :                                       ret, done,
    2868             :                                       "Wrong maximum access\n");
    2869             : 
    2870           4 :         status = smb2_util_close(tree, handle);
    2871           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2872             :                                         "smb2_util_close failed\n");
    2873           4 :         ZERO_STRUCT(handle);
    2874             : 
    2875           4 : done:
    2876           4 :         if (!smb2_util_handle_empty(handle)) {
    2877           0 :                 smb2_util_close(tree, handle);
    2878             :         }
    2879           4 :         smb2_deltree(tree, BASEDIR);
    2880           4 :         return ret;
    2881             : }
    2882             : 
    2883             : /*
    2884             :  * test SEC_FLAG_MAXIMUM_ALLOWED with not-granted access
    2885             :  *
    2886             :  * When access_mask contains SEC_FLAG_MAXIMUM_ALLOWED, the server must still
    2887             :  * process other bits from access_mask. Eg if access_mask contains a right that
    2888             :  * the requester doesn't have, the function must validate that against the
    2889             :  * effective permissions.
    2890             :  */
    2891           4 : static bool test_mxac_not_granted(struct torture_context *tctx,
    2892             :                                   struct smb2_tree *tree)
    2893             : {
    2894           4 :         const char *fname = BASEDIR "\\test_mxac_not_granted.txt";
    2895           0 :         struct smb2_create cr;
    2896           4 :         struct smb2_handle handle = {{0}};
    2897           0 :         union smb_fileinfo gi;
    2898           0 :         union smb_setfileinfo si;
    2899           4 :         struct security_descriptor *sd_orig = NULL;
    2900           4 :         struct security_descriptor *sd = NULL;
    2901           4 :         const char *owner_sid = NULL;
    2902           0 :         NTSTATUS status;
    2903           4 :         bool ret = true;
    2904             : 
    2905           4 :         smb2_deltree(tree, BASEDIR);
    2906             : 
    2907           4 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2908           4 :         torture_assert_goto(tctx, ret, ret, done,
    2909             :                         "smb2_util_setup_dir failed\n");
    2910             : 
    2911           4 :         torture_comment(tctx, "TESTING OWNER RIGHTS DENY\n");
    2912             : 
    2913           4 :         cr = (struct smb2_create) {
    2914             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    2915             :                         SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
    2916             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2917             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2918             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2919             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2920             :                 .in.fname = fname,
    2921             :         };
    2922             : 
    2923           4 :         status = smb2_create(tree, tctx, &cr);
    2924           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2925             :                                         "smb2_create failed\n");
    2926           4 :         handle = cr.out.file.handle;
    2927             : 
    2928           4 :         torture_comment(tctx, "get the original sd\n");
    2929             : 
    2930           4 :         gi = (union smb_fileinfo) {
    2931             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    2932             :                 .query_secdesc.in.file.handle = handle,
    2933             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
    2934             :         };
    2935             : 
    2936           4 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2937           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2938             :                                 "smb2_getinfo_file failed\n");
    2939             : 
    2940           4 :         sd_orig = gi.query_secdesc.out.sd;
    2941           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2942             : 
    2943           4 :         sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL,
    2944             :                                         owner_sid,
    2945             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2946             :                                         SEC_FILE_READ_DATA,
    2947             :                                         0,
    2948             :                                         NULL);
    2949           4 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2950             :                                         "SD create failed\n");
    2951             : 
    2952           4 :         si = (union smb_setfileinfo) {
    2953             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    2954             :                 .set_secdesc.in.file.handle = handle,
    2955             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    2956             :                 .set_secdesc.in.sd = sd,
    2957             :         };
    2958             : 
    2959           4 :         status = smb2_setinfo_file(tree, &si);
    2960           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2961             :                                         "smb2_setinfo_file failed\n");
    2962             : 
    2963           4 :         status = smb2_util_close(tree, handle);
    2964           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2965             :                                         "smb2_util_close failed\n");
    2966           4 :         ZERO_STRUCT(handle);
    2967             : 
    2968           4 :         cr = (struct smb2_create) {
    2969             :                 .in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED |
    2970             :                                      SEC_FILE_WRITE_DATA,
    2971             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2972             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2973             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2974             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2975             :                 .in.fname = fname,
    2976             :         };
    2977             : 
    2978           4 :         status = smb2_create(tree, tctx, &cr);
    2979           4 :         torture_assert_ntstatus_equal_goto(tctx, status,
    2980             :                                            NT_STATUS_ACCESS_DENIED,
    2981             :                                            ret, done,
    2982             :                                            "Wrong smb2_create result\n");
    2983             : 
    2984           4 : done:
    2985           4 :         if (!smb2_util_handle_empty(handle)) {
    2986           0 :                 smb2_util_close(tree, handle);
    2987             :         }
    2988           4 :         smb2_deltree(tree, BASEDIR);
    2989           4 :         return ret;
    2990             : }
    2991             : 
    2992           4 : static bool test_overwrite_read_only_file(struct torture_context *tctx,
    2993             :                                           struct smb2_tree *tree)
    2994             : {
    2995           0 :         NTSTATUS status;
    2996           0 :         struct smb2_create c;
    2997           4 :         const char *fname = BASEDIR "\\test_overwrite_read_only_file.txt";
    2998           4 :         struct smb2_handle handle = {{0}};
    2999           0 :         union smb_fileinfo q;
    3000           0 :         union smb_setfileinfo set;
    3001           4 :         struct security_descriptor *sd = NULL, *sd_orig = NULL;
    3002           4 :         const char *owner_sid = NULL;
    3003           0 :         int i;
    3004           4 :         bool ret = true;
    3005             : 
    3006           0 :         struct tcase {
    3007             :                 int disposition;
    3008             :                 const char *disposition_string;
    3009             :                 NTSTATUS expected_status;
    3010           4 :         } tcases[] = {
    3011             : #define TCASE(d, s) {                           \
    3012             :                 .disposition = d,               \
    3013             :                 .disposition_string = #d,       \
    3014             :                 .expected_status = s,           \
    3015             :         }
    3016             :                 TCASE(NTCREATEX_DISP_OPEN, NT_STATUS_OK),
    3017             :                 TCASE(NTCREATEX_DISP_SUPERSEDE, NT_STATUS_ACCESS_DENIED),
    3018             :                 TCASE(NTCREATEX_DISP_OVERWRITE, NT_STATUS_ACCESS_DENIED),
    3019             :                 TCASE(NTCREATEX_DISP_OVERWRITE_IF, NT_STATUS_ACCESS_DENIED),
    3020             :         };
    3021             : #undef TCASE
    3022             : 
    3023           4 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    3024           4 :         torture_assert_goto(tctx, ret, ret, done, "smb2_util_setup_dir not ok");
    3025             : 
    3026           4 :         c = (struct smb2_create) {
    3027             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    3028             :                         SEC_STD_WRITE_DAC |
    3029             :                         SEC_STD_WRITE_OWNER,
    3030             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    3031             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    3032             :                         NTCREATEX_SHARE_ACCESS_WRITE,
    3033             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    3034             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    3035             :                 .in.fname = fname,
    3036             :         };
    3037             : 
    3038           4 :         status = smb2_create(tree, tctx, &c);
    3039           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3040             :                                         "smb2_create failed\n");
    3041           4 :         handle = c.out.file.handle;
    3042             : 
    3043           4 :         torture_comment(tctx, "get the original sd\n");
    3044             : 
    3045           4 :         ZERO_STRUCT(q);
    3046           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    3047           4 :         q.query_secdesc.in.file.handle = handle;
    3048           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    3049             : 
    3050           4 :         status = smb2_getinfo_file(tree, tctx, &q);
    3051           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3052             :                                         "smb2_getinfo_file failed\n");
    3053           4 :         sd_orig = q.query_secdesc.out.sd;
    3054             : 
    3055           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    3056             : 
    3057           4 :         sd = security_descriptor_dacl_create(tctx,
    3058             :                                         0, NULL, NULL,
    3059             :                                         owner_sid,
    3060             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    3061             :                                         SEC_FILE_READ_DATA,
    3062             :                                         0,
    3063             :                                         NULL);
    3064             : 
    3065           4 :         ZERO_STRUCT(set);
    3066           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    3067           4 :         set.set_secdesc.in.file.handle = handle;
    3068           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    3069           4 :         set.set_secdesc.in.sd = sd;
    3070             : 
    3071           4 :         status = smb2_setinfo_file(tree, &set);
    3072           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3073             :                                         "smb2_setinfo_file failed\n");
    3074             : 
    3075           4 :         smb2_util_close(tree, handle);
    3076           4 :         ZERO_STRUCT(handle);
    3077             : 
    3078          20 :         for (i = 0; i < ARRAY_SIZE(tcases); i++) {
    3079          16 :                 torture_comment(tctx, "Verify open with %s disposition\n",
    3080             :                                 tcases[i].disposition_string);
    3081             : 
    3082          16 :                 c = (struct smb2_create) {
    3083          16 :                         .in.create_disposition = tcases[i].disposition,
    3084             :                         .in.desired_access = SEC_FILE_READ_DATA,
    3085             :                         .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    3086             :                         .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    3087             :                         .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    3088             :                         .in.fname = fname,
    3089             :                 };
    3090             : 
    3091          16 :                 status = smb2_create(tree, tctx, &c);
    3092          16 :                 smb2_util_close(tree, c.out.file.handle);
    3093          16 :                 torture_assert_ntstatus_equal_goto(
    3094             :                         tctx, status, tcases[i].expected_status, ret, done,
    3095             :                         "smb2_create failed\n");
    3096           0 :         };
    3097             : 
    3098           4 :         torture_comment(tctx, "put back original sd\n");
    3099             : 
    3100           4 :         c = (struct smb2_create) {
    3101             :                 .in.desired_access = SEC_STD_WRITE_DAC,
    3102             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    3103             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    3104             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    3105             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    3106             :                 .in.fname = fname,
    3107             :         };
    3108             : 
    3109           4 :         status = smb2_create(tree, tctx, &c);
    3110           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3111             :                                         "smb2_create failed\n");
    3112           4 :         handle = c.out.file.handle;
    3113             : 
    3114           4 :         ZERO_STRUCT(set);
    3115           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    3116           4 :         set.set_secdesc.in.file.handle = handle;
    3117           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    3118           4 :         set.set_secdesc.in.sd = sd_orig;
    3119             : 
    3120           4 :         status = smb2_setinfo_file(tree, &set);
    3121           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3122             :                                         "smb2_setinfo_file failed\n");
    3123             : 
    3124           4 :         smb2_util_close(tree, handle);
    3125           4 :         ZERO_STRUCT(handle);
    3126             : 
    3127           4 : done:
    3128           4 :         smb2_util_close(tree, handle);
    3129           4 :         smb2_util_unlink(tree, fname);
    3130           4 :         smb2_deltree(tree, BASEDIR);
    3131           4 :         return ret;
    3132             : }
    3133             : 
    3134             : /*
    3135             :    basic testing of SMB2 ACLs
    3136             : */
    3137        2379 : struct torture_suite *torture_smb2_acls_init(TALLOC_CTX *ctx)
    3138             : {
    3139        2379 :         struct torture_suite *suite = torture_suite_create(ctx, "acls");
    3140             : 
    3141        2379 :         torture_suite_add_1smb2_test(suite, "CREATOR", test_creator_sid);
    3142        2379 :         torture_suite_add_1smb2_test(suite, "GENERIC", test_generic_bits);
    3143        2379 :         torture_suite_add_1smb2_test(suite, "OWNER", test_owner_bits);
    3144        2379 :         torture_suite_add_1smb2_test(suite, "INHERITANCE", test_inheritance);
    3145        2379 :         torture_suite_add_1smb2_test(suite, "INHERITFLAGS", test_inheritance_flags);
    3146        2379 :         torture_suite_add_1smb2_test(suite, "SDFLAGSVSCHOWN", test_sd_flags_vs_chown);
    3147        2379 :         torture_suite_add_1smb2_test(suite, "DYNAMIC", test_inheritance_dynamic);
    3148             : #if 0
    3149             :         /* XXX This test does not work against XP or Vista. */
    3150             :         torture_suite_add_1smb2_test(suite, "GETSET", test_sd_get_set);
    3151             : #endif
    3152        2379 :         torture_suite_add_1smb2_test(suite, "ACCESSBASED", test_access_based);
    3153        2379 :         torture_suite_add_1smb2_test(suite, "OWNER-RIGHTS", test_owner_rights);
    3154        2379 :         torture_suite_add_1smb2_test(suite, "OWNER-RIGHTS-DENY",
    3155             :                         test_owner_rights_deny);
    3156        2379 :         torture_suite_add_1smb2_test(suite, "OWNER-RIGHTS-DENY1",
    3157             :                         test_owner_rights_deny1);
    3158        2379 :         torture_suite_add_1smb2_test(suite, "DENY1",
    3159             :                         test_deny1);
    3160        2379 :         torture_suite_add_1smb2_test(suite, "MXAC-NOT-GRANTED",
    3161             :                         test_mxac_not_granted);
    3162        2379 :         torture_suite_add_1smb2_test(suite, "OVERWRITE_READ_ONLY_FILE", test_overwrite_read_only_file);
    3163             : 
    3164        2379 :         suite->description = talloc_strdup(suite, "SMB2-ACLS tests");
    3165             : 
    3166        2379 :         return suite;
    3167             : }
    3168             : 
    3169           2 : static bool test_acls_non_canonical_flags(struct torture_context *tctx,
    3170             :                                           struct smb2_tree *tree)
    3171             : {
    3172           2 :         const char *fname = BASEDIR "\\test_acls_non_canonical_flags.txt";
    3173           0 :         struct smb2_create cr;
    3174           2 :         struct smb2_handle testdirh = {{0}};
    3175           2 :         struct smb2_handle handle = {{0}};
    3176           0 :         union smb_fileinfo gi;
    3177           0 :         union smb_setfileinfo si;
    3178           2 :         struct security_descriptor *sd_orig = NULL;
    3179           2 :         struct security_descriptor *sd = NULL;
    3180           0 :         NTSTATUS status;
    3181           2 :         bool ret = true;
    3182             : 
    3183           2 :         smb2_deltree(tree, BASEDIR);
    3184             : 
    3185           2 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    3186           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3187             :                                         "torture_smb2_testdir failed\n");
    3188             : 
    3189           2 :         sd = security_descriptor_dacl_create(tctx,
    3190             :                                              SEC_DESC_DACL_AUTO_INHERITED
    3191             :                                              | SEC_DESC_DACL_AUTO_INHERIT_REQ,
    3192             :                                              NULL,
    3193             :                                              NULL,
    3194             :                                              SID_WORLD,
    3195             :                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
    3196             :                                              SEC_RIGHTS_DIR_ALL,
    3197             :                                              SEC_ACE_FLAG_OBJECT_INHERIT
    3198             :                                              | SEC_ACE_FLAG_CONTAINER_INHERIT,
    3199             :                                              NULL);
    3200           2 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    3201             :                                         "SD create failed\n");
    3202             : 
    3203           2 :         si = (union smb_setfileinfo) {
    3204             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    3205             :                 .set_secdesc.in.file.handle = testdirh,
    3206             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    3207             :                 .set_secdesc.in.sd = sd,
    3208             :         };
    3209             : 
    3210           2 :         status = smb2_setinfo_file(tree, &si);
    3211           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3212             :                                         "smb2_setinfo_file failed\n");
    3213             : 
    3214           2 :         gi = (union smb_fileinfo) {
    3215             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    3216             :                 .query_secdesc.in.file.handle = testdirh,
    3217             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL,
    3218             :         };
    3219             : 
    3220           2 :         status = smb2_getinfo_file(tree, tctx, &gi);
    3221           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3222             :                                 "smb2_getinfo_file failed\n");
    3223             : 
    3224           2 :         cr = (struct smb2_create) {
    3225             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    3226             :                         SEC_STD_WRITE_DAC,
    3227             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    3228             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    3229             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    3230             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    3231             :                 .in.fname = fname,
    3232             :         };
    3233             : 
    3234           2 :         status = smb2_create(tree, tctx, &cr);
    3235           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3236             :                                         "smb2_create failed\n");
    3237           2 :         handle = cr.out.file.handle;
    3238             : 
    3239           2 :         torture_comment(tctx, "get the original sd\n");
    3240             : 
    3241           2 :         gi = (union smb_fileinfo) {
    3242             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    3243             :                 .query_secdesc.in.file.handle = handle,
    3244             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL,
    3245             :         };
    3246             : 
    3247           2 :         status = smb2_getinfo_file(tree, tctx, &gi);
    3248           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3249             :                                 "smb2_getinfo_file failed\n");
    3250             : 
    3251           2 :         sd_orig = gi.query_secdesc.out.sd;
    3252             : 
    3253           2 :         torture_assert_goto(tctx, sd_orig->type & SEC_DESC_DACL_AUTO_INHERITED,
    3254             :                             ret, done, "Missing SEC_DESC_DACL_AUTO_INHERITED\n");
    3255             : 
    3256             :         /*
    3257             :          * SD with SEC_DESC_DACL_AUTO_INHERITED but without
    3258             :          * SEC_DESC_DACL_AUTO_INHERITED_REQ, so the resulting SD should not have
    3259             :          * SEC_DESC_DACL_AUTO_INHERITED on a Windows box.
    3260             :          *
    3261             :          * But as we're testing against a share with
    3262             :          *
    3263             :          *    "acl flag inherited canonicalization = no"
    3264             :          *
    3265             :          * the resulting SD should have acl flag inherited canonicalization set.
    3266             :          */
    3267           2 :         sd = security_descriptor_dacl_create(tctx,
    3268             :                                              SEC_DESC_DACL_AUTO_INHERITED,
    3269             :                                              NULL,
    3270             :                                              NULL,
    3271             :                                              SID_WORLD,
    3272             :                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
    3273             :                                              SEC_FILE_ALL,
    3274             :                                              0,
    3275             :                                              NULL);
    3276           2 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    3277             :                                         "SD create failed\n");
    3278             : 
    3279           2 :         si = (union smb_setfileinfo) {
    3280             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    3281             :                 .set_secdesc.in.file.handle = handle,
    3282             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    3283             :                 .set_secdesc.in.sd = sd,
    3284             :         };
    3285             : 
    3286           2 :         status = smb2_setinfo_file(tree, &si);
    3287           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3288             :                                         "smb2_setinfo_file failed\n");
    3289             : 
    3290           2 :         status = smb2_util_close(tree, handle);
    3291           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3292             :                                         "smb2_util_close failed\n");
    3293           2 :         ZERO_STRUCT(handle);
    3294             : 
    3295           2 :         cr = (struct smb2_create) {
    3296             :                 .in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED ,
    3297             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    3298             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    3299             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    3300             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    3301             :                 .in.fname = fname,
    3302             :         };
    3303             : 
    3304           2 :         status = smb2_create(tree, tctx, &cr);
    3305           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3306             :                                         "smb2_create failed\n");
    3307           2 :         handle = cr.out.file.handle;
    3308             : 
    3309           2 :         gi = (union smb_fileinfo) {
    3310             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    3311             :                 .query_secdesc.in.file.handle = handle,
    3312             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL,
    3313             :         };
    3314             : 
    3315           2 :         status = smb2_getinfo_file(tree, tctx, &gi);
    3316           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3317             :                                 "smb2_getinfo_file failed\n");
    3318             : 
    3319           2 :         sd_orig = gi.query_secdesc.out.sd;
    3320           2 :         torture_assert_goto(tctx, sd_orig->type & SEC_DESC_DACL_AUTO_INHERITED,
    3321             :                             ret, done, "Missing SEC_DESC_DACL_AUTO_INHERITED\n");
    3322             : 
    3323           2 : done:
    3324           2 :         if (!smb2_util_handle_empty(handle)) {
    3325           2 :                 smb2_util_close(tree, testdirh);
    3326             :         }
    3327           2 :         if (!smb2_util_handle_empty(handle)) {
    3328           2 :                 smb2_util_close(tree, handle);
    3329             :         }
    3330           2 :         smb2_deltree(tree, BASEDIR);
    3331           2 :         return ret;
    3332             : }
    3333             : 
    3334        2379 : struct torture_suite *torture_smb2_acls_non_canonical_init(TALLOC_CTX *ctx)
    3335             : {
    3336        2379 :         struct torture_suite *suite = torture_suite_create(ctx, "acls_non_canonical");
    3337             : 
    3338        2379 :         torture_suite_add_1smb2_test(suite, "flags", test_acls_non_canonical_flags);
    3339        2379 :         return suite;
    3340             : }

Generated by: LCOV version 1.14