LCOV - code coverage report
Current view: top level - source4/torture/smb2 - acls.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 22 1425 1.5 %
Date: 2024-06-13 04:01:37 Functions: 2 17 11.8 %

          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           0 : static bool test_creator_sid(struct torture_context *tctx, struct smb2_tree *tree)
      97             : {
      98             :         NTSTATUS status;
      99             :         struct smb2_create io;
     100           0 :         const char *fname = BASEDIR "\\creator.txt";
     101           0 :         bool ret = true;
     102           0 :         struct smb2_handle handle = {{0}};
     103             :         union smb_fileinfo q;
     104             :         union smb_setfileinfo set;
     105             :         struct security_descriptor *sd, *sd_orig, *sd2;
     106             :         const char *owner_sid;
     107             : 
     108           0 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     109           0 :                 return false;
     110             : 
     111           0 :         torture_comment(tctx, "TESTING SID_CREATOR_OWNER\n");
     112             : 
     113           0 :         ZERO_STRUCT(io);
     114           0 :         io.level = RAW_OPEN_SMB2;
     115           0 :         io.in.create_flags = 0;
     116           0 :         io.in.desired_access = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
     117           0 :         io.in.create_options = 0;
     118           0 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     119           0 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
     120             :                 NTCREATEX_SHARE_ACCESS_READ |
     121             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     122           0 :         io.in.alloc_size = 0;
     123           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     124           0 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     125           0 :         io.in.security_flags = 0;
     126           0 :         io.in.fname = fname;
     127             : 
     128           0 :         status = smb2_create(tree, tctx, &io);
     129           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     130           0 :         handle = io.out.file.handle;
     131             : 
     132           0 :         torture_comment(tctx, "get the original sd\n");
     133           0 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     134           0 :         q.query_secdesc.in.file.handle = handle;
     135           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     136           0 :         status = smb2_getinfo_file(tree, tctx, &q);
     137           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     138           0 :         sd_orig = q.query_secdesc.out.sd;
     139             : 
     140           0 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
     141             : 
     142           0 :         torture_comment(tctx, "set a sec desc allowing no write by CREATOR_OWNER\n");
     143           0 :         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           0 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     152           0 :         set.set_secdesc.in.file.handle = handle;
     153           0 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     154           0 :         set.set_secdesc.in.sd = sd;
     155             : 
     156           0 :         status = smb2_setinfo_file(tree, &set);
     157           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     158             : 
     159           0 :         torture_comment(tctx, "try open for write\n");
     160           0 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
     161           0 :         status = smb2_create(tree, tctx, &io);
     162           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     163             : 
     164           0 :         torture_comment(tctx, "try open for read\n");
     165           0 :         io.in.desired_access = SEC_FILE_READ_DATA;
     166           0 :         status = smb2_create(tree, tctx, &io);
     167           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     168             : 
     169           0 :         torture_comment(tctx, "try open for generic write\n");
     170           0 :         io.in.desired_access = SEC_GENERIC_WRITE;
     171           0 :         status = smb2_create(tree, tctx, &io);
     172           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     173             : 
     174           0 :         torture_comment(tctx, "try open for generic read\n");
     175           0 :         io.in.desired_access = SEC_GENERIC_READ;
     176           0 :         status = smb2_create(tree, tctx, &io);
     177           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     178             : 
     179           0 :         torture_comment(tctx, "set a sec desc allowing no write by owner\n");
     180           0 :         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           0 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     189           0 :         set.set_secdesc.in.file.handle = handle;
     190           0 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     191           0 :         set.set_secdesc.in.sd = sd;
     192           0 :         status = smb2_setinfo_file(tree, &set);
     193           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     194             : 
     195           0 :         torture_comment(tctx, "check that sd has been mapped correctly\n");
     196           0 :         status = smb2_getinfo_file(tree, tctx, &q);
     197           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     198           0 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
     199             : 
     200           0 :         torture_comment(tctx, "try open for write\n");
     201           0 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
     202           0 :         status = smb2_create(tree, tctx, &io);
     203           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     204             : 
     205           0 :         torture_comment(tctx, "try open for read\n");
     206           0 :         io.in.desired_access = SEC_FILE_READ_DATA;
     207           0 :         status = smb2_create(tree, tctx, &io);
     208           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     209           0 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
     210             :                            SEC_FILE_READ_DATA);
     211           0 :         smb2_util_close(tree, io.out.file.handle);
     212             : 
     213           0 :         torture_comment(tctx, "try open for generic write\n");
     214           0 :         io.in.desired_access = SEC_GENERIC_WRITE;
     215           0 :         status = smb2_create(tree, tctx, &io);
     216           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     217             : 
     218           0 :         torture_comment(tctx, "try open for generic read\n");
     219           0 :         io.in.desired_access = SEC_GENERIC_READ;
     220           0 :         status = smb2_create(tree, tctx, &io);
     221           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     222           0 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
     223             :                            SEC_RIGHTS_FILE_READ);
     224           0 :         smb2_util_close(tree, io.out.file.handle);
     225             : 
     226           0 :         torture_comment(tctx, "set a sec desc allowing generic read by owner\n");
     227           0 :         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           0 :         set.set_secdesc.in.sd = sd;
     236           0 :         status = smb2_setinfo_file(tree, &set);
     237           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     238             : 
     239           0 :         torture_comment(tctx, "check that generic read has been mapped correctly\n");
     240           0 :         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           0 :         status = smb2_getinfo_file(tree, tctx, &q);
     249           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     250           0 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     251             : 
     252           0 :         torture_comment(tctx, "try open for write\n");
     253           0 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
     254           0 :         status = smb2_create(tree, tctx, &io);
     255           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     256             : 
     257           0 :         torture_comment(tctx, "try open for read\n");
     258           0 :         io.in.desired_access = SEC_FILE_READ_DATA;
     259           0 :         status = smb2_create(tree, tctx, &io);
     260           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     261           0 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
     262             :                            SEC_FILE_READ_DATA);
     263           0 :         smb2_util_close(tree, io.out.file.handle);
     264             : 
     265           0 :         torture_comment(tctx, "try open for generic write\n");
     266           0 :         io.in.desired_access = SEC_GENERIC_WRITE;
     267           0 :         status = smb2_create(tree, tctx, &io);
     268           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     269             : 
     270           0 :         torture_comment(tctx, "try open for generic read\n");
     271           0 :         io.in.desired_access = SEC_GENERIC_READ;
     272           0 :         status = smb2_create(tree, tctx, &io);
     273           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     274           0 :         CHECK_ACCESS_FLAGS(io.out.file.handle, SEC_RIGHTS_FILE_READ);
     275           0 :         smb2_util_close(tree, io.out.file.handle);
     276             : 
     277             : 
     278           0 :         torture_comment(tctx, "put back original sd\n");
     279           0 :         set.set_secdesc.in.sd = sd_orig;
     280           0 :         status = smb2_setinfo_file(tree, &set);
     281           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     282             : 
     283             : 
     284           0 : done:
     285           0 :         smb2_util_close(tree, handle);
     286           0 :         smb2_deltree(tree, BASEDIR);
     287           0 :         smb2_tdis(tree);
     288           0 :         smb2_logoff(tree->session);
     289           0 :         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           0 : static bool test_generic_bits(struct torture_context *tctx, struct smb2_tree *tree)
     299             : {
     300             :         NTSTATUS status;
     301             :         struct smb2_create io;
     302           0 :         const char *fname = BASEDIR "\\generic.txt";
     303           0 :         bool ret = true;
     304           0 :         struct smb2_handle handle = {{0}};
     305             :         int i;
     306             :         union smb_fileinfo q;
     307             :         union smb_setfileinfo set;
     308             :         struct security_descriptor *sd, *sd_orig, *sd2;
     309             :         const char *owner_sid;
     310             :         const struct {
     311             :                 uint32_t gen_bits;
     312             :                 uint32_t specific_bits;
     313           0 :         } file_mappings[] = {
     314             :                 { 0,                       0 },
     315             :                 { SEC_GENERIC_READ,        SEC_RIGHTS_FILE_READ },
     316             :                 { SEC_GENERIC_WRITE,       SEC_RIGHTS_FILE_WRITE },
     317             :                 { SEC_GENERIC_EXECUTE,     SEC_RIGHTS_FILE_EXECUTE },
     318             :                 { SEC_GENERIC_ALL,         SEC_RIGHTS_FILE_ALL },
     319             :                 { SEC_FILE_READ_DATA,      SEC_FILE_READ_DATA },
     320             :                 { SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_ATTRIBUTE }
     321             :         };
     322             :         const struct {
     323             :                 uint32_t gen_bits;
     324             :                 uint32_t specific_bits;
     325           0 :         } 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           0 :         bool has_restore_privilege = false;
     333           0 :         bool has_take_ownership_privilege = false;
     334             : 
     335           0 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     336           0 :                 return false;
     337             : 
     338           0 :         torture_comment(tctx, "TESTING FILE GENERIC BITS\n");
     339             : 
     340           0 :         ZERO_STRUCT(io);
     341           0 :         io.level = RAW_OPEN_SMB2;
     342           0 :         io.in.create_flags = 0;
     343           0 :         io.in.desired_access =
     344             :                 SEC_STD_READ_CONTROL |
     345             :                 SEC_STD_WRITE_DAC |
     346             :                 SEC_STD_WRITE_OWNER;
     347           0 :         io.in.create_options = 0;
     348           0 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     349           0 :         io.in.share_access =
     350             :                 NTCREATEX_SHARE_ACCESS_READ |
     351             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     352           0 :         io.in.alloc_size = 0;
     353           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     354           0 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     355           0 :         io.in.security_flags = 0;
     356           0 :         io.in.fname = fname;
     357           0 :         status = smb2_create(tree, tctx, &io);
     358           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     359           0 :         handle = io.out.file.handle;
     360             : 
     361           0 :         torture_comment(tctx, "get the original sd\n");
     362           0 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     363           0 :         q.query_secdesc.in.file.handle = handle;
     364           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     365           0 :         status = smb2_getinfo_file(tree, tctx, &q);
     366           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     367           0 :         sd_orig = q.query_secdesc.out.sd;
     368             : 
     369           0 :         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           0 :         for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
     396           0 :                 uint32_t expected_mask =
     397             :                         SEC_STD_WRITE_DAC |
     398             :                         SEC_STD_READ_CONTROL |
     399             :                         SEC_FILE_READ_ATTRIBUTE |
     400             :                         SEC_STD_DELETE;
     401           0 :                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
     402             : 
     403           0 :                 if (has_restore_privilege) {
     404           0 :                         expected_mask_anon |= SEC_STD_DELETE;
     405             :                 }
     406             : 
     407           0 :                 torture_comment(tctx, "Testing generic bits 0x%08x\n",
     408           0 :                        file_mappings[i].gen_bits);
     409           0 :                 sd = security_descriptor_dacl_create(tctx,
     410             :                                                 0, owner_sid, NULL,
     411             :                                                 owner_sid,
     412             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     413           0 :                                                 file_mappings[i].gen_bits,
     414             :                                                 0,
     415             :                                                 NULL);
     416             : 
     417           0 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     418           0 :                 set.set_secdesc.in.file.handle = handle;
     419           0 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     420           0 :                 set.set_secdesc.in.sd = sd;
     421             : 
     422           0 :                 status = smb2_setinfo_file(tree, &set);
     423           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     424             : 
     425           0 :                 sd2 = security_descriptor_dacl_create(tctx,
     426             :                                                  0, owner_sid, NULL,
     427             :                                                  owner_sid,
     428             :                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
     429           0 :                                                  file_mappings[i].specific_bits,
     430             :                                                  0,
     431             :                                                  NULL);
     432             : 
     433           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
     434           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     435           0 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     436             : 
     437           0 :                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     438           0 :                 status = smb2_create(tree, tctx, &io);
     439           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     440           0 :                 CHECK_ACCESS_FLAGS(io.out.file.handle,
     441             :                                    expected_mask | file_mappings[i].specific_bits);
     442           0 :                 smb2_util_close(tree, io.out.file.handle);
     443             : 
     444           0 :                 if (!has_take_ownership_privilege) {
     445           0 :                         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           0 :         torture_comment(tctx, "put back original sd\n");
     487           0 :         set.set_secdesc.in.sd = sd_orig;
     488           0 :         status = smb2_setinfo_file(tree, &set);
     489           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     490             : 
     491           0 :         smb2_util_close(tree, handle);
     492           0 :         smb2_util_unlink(tree, fname);
     493             : 
     494             : 
     495           0 :         torture_comment(tctx, "TESTING DIR GENERIC BITS\n");
     496             : 
     497           0 :         ZERO_STRUCT(io);
     498           0 :         io.level = RAW_OPEN_SMB2;
     499           0 :         io.in.create_flags = 0;
     500           0 :         io.in.desired_access =
     501             :                 SEC_STD_READ_CONTROL |
     502             :                 SEC_STD_WRITE_DAC |
     503             :                 SEC_STD_WRITE_OWNER;
     504           0 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     505           0 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     506           0 :         io.in.share_access =
     507             :                 NTCREATEX_SHARE_ACCESS_READ |
     508             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     509           0 :         io.in.alloc_size = 0;
     510           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     511           0 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     512           0 :         io.in.security_flags = 0;
     513           0 :         io.in.fname = fname;
     514           0 :         status = smb2_create(tree, tctx, &io);
     515           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     516           0 :         handle = io.out.file.handle;
     517             : 
     518           0 :         torture_comment(tctx, "get the original sd\n");
     519           0 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     520           0 :         q.query_secdesc.in.file.handle = handle;
     521           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     522           0 :         status = smb2_getinfo_file(tree, tctx, &q);
     523           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     524           0 :         sd_orig = q.query_secdesc.out.sd;
     525             : 
     526           0 :         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           0 :         for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
     553           0 :                 uint32_t expected_mask =
     554             :                         SEC_STD_WRITE_DAC |
     555             :                         SEC_STD_READ_CONTROL |
     556             :                         SEC_FILE_READ_ATTRIBUTE |
     557             :                         SEC_STD_DELETE;
     558           0 :                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
     559             : 
     560           0 :                 if (has_restore_privilege) {
     561           0 :                         expected_mask_anon |= SEC_STD_DELETE;
     562             :                 }
     563             : 
     564           0 :                 torture_comment(tctx, "Testing generic bits 0x%08x\n",
     565           0 :                        file_mappings[i].gen_bits);
     566           0 :                 sd = security_descriptor_dacl_create(tctx,
     567             :                                                 0, owner_sid, NULL,
     568             :                                                 owner_sid,
     569             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     570           0 :                                                 dir_mappings[i].gen_bits,
     571             :                                                 0,
     572             :                                                 NULL);
     573             : 
     574           0 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     575           0 :                 set.set_secdesc.in.file.handle = handle;
     576           0 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     577           0 :                 set.set_secdesc.in.sd = sd;
     578             : 
     579           0 :                 status = smb2_setinfo_file(tree, &set);
     580           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     581             : 
     582           0 :                 sd2 = security_descriptor_dacl_create(tctx,
     583             :                                                  0, owner_sid, NULL,
     584             :                                                  owner_sid,
     585             :                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
     586           0 :                                                  dir_mappings[i].specific_bits,
     587             :                                                  0,
     588             :                                                  NULL);
     589             : 
     590           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
     591           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     592           0 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     593             : 
     594           0 :                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     595           0 :                 status = smb2_create(tree, tctx, &io);
     596           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     597           0 :                 CHECK_ACCESS_FLAGS(io.out.file.handle,
     598             :                                    expected_mask | dir_mappings[i].specific_bits);
     599           0 :                 smb2_util_close(tree, io.out.file.handle);
     600             : 
     601           0 :                 if (!has_take_ownership_privilege) {
     602           0 :                         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           0 :         torture_comment(tctx, "put back original sd\n");
     644           0 :         set.set_secdesc.in.sd = sd_orig;
     645           0 :         status = smb2_setinfo_file(tree, &set);
     646           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     647             : 
     648           0 :         smb2_util_close(tree, handle);
     649           0 :         smb2_util_unlink(tree, fname);
     650             : 
     651           0 : done:
     652           0 :         smb2_util_close(tree, handle);
     653           0 :         smb2_deltree(tree, BASEDIR);
     654           0 :         smb2_tdis(tree);
     655           0 :         smb2_logoff(tree->session);
     656           0 :         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           0 : static bool test_owner_bits(struct torture_context *tctx, struct smb2_tree *tree)
     665             : {
     666             :         NTSTATUS status;
     667             :         struct smb2_create io;
     668           0 :         const char *fname = BASEDIR "\\test_owner_bits.txt";
     669           0 :         bool ret = true;
     670           0 :         struct smb2_handle handle = {{0}};
     671             :         int i;
     672             :         union smb_fileinfo q;
     673             :         union smb_setfileinfo set;
     674             :         struct security_descriptor *sd, *sd_orig;
     675             :         const char *owner_sid;
     676             :         uint32_t expected_bits;
     677             : 
     678           0 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     679           0 :                 return false;
     680             : 
     681           0 :         torture_comment(tctx, "TESTING FILE OWNER BITS\n");
     682             : 
     683           0 :         ZERO_STRUCT(io);
     684           0 :         io.level = RAW_OPEN_SMB2;
     685           0 :         io.in.create_flags = 0;
     686           0 :         io.in.desired_access =
     687             :                 SEC_STD_READ_CONTROL |
     688             :                 SEC_STD_WRITE_DAC |
     689             :                 SEC_STD_WRITE_OWNER;
     690           0 :         io.in.create_options = 0;
     691           0 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     692           0 :         io.in.share_access =
     693             :                 NTCREATEX_SHARE_ACCESS_READ |
     694             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     695           0 :         io.in.alloc_size = 0;
     696           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     697           0 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     698           0 :         io.in.security_flags = 0;
     699           0 :         io.in.fname = fname;
     700           0 :         status = smb2_create(tree, tctx, &io);
     701           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     702           0 :         handle = io.out.file.handle;
     703             : 
     704           0 :         torture_comment(tctx, "get the original sd\n");
     705           0 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     706           0 :         q.query_secdesc.in.file.handle = handle;
     707           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     708           0 :         status = smb2_getinfo_file(tree, tctx, &q);
     709           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     710           0 :         sd_orig = q.query_secdesc.out.sd;
     711             : 
     712           0 :         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           0 :         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           0 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     747           0 :         set.set_secdesc.in.file.handle = handle;
     748           0 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     749           0 :         set.set_secdesc.in.sd = sd;
     750             : 
     751           0 :         status = smb2_setinfo_file(tree, &set);
     752           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     753             : 
     754           0 :         expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
     755             : 
     756           0 :         for (i=0;i<16;i++) {
     757           0 :                 uint32_t bit = (1<<i);
     758           0 :                 io.in.desired_access = bit;
     759           0 :                 status = smb2_create(tree, tctx, &io);
     760           0 :                 if (expected_bits & bit) {
     761           0 :                         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           0 :                         CHECK_STATUS(status, NT_STATUS_OK);
     766           0 :                         CHECK_ACCESS_FLAGS(io.out.file.handle, bit);
     767           0 :                         smb2_util_close(tree, io.out.file.handle);
     768             :                 } else {
     769           0 :                         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           0 :                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     775             :                 }
     776             :         }
     777             : 
     778           0 :         torture_comment(tctx, "put back original sd\n");
     779           0 :         set.set_secdesc.in.sd = sd_orig;
     780           0 :         status = smb2_setinfo_file(tree, &set);
     781           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     782             : 
     783           0 : done:
     784           0 :         smb2_util_close(tree, handle);
     785           0 :         smb2_util_unlink(tree, fname);
     786           0 :         smb2_deltree(tree, BASEDIR);
     787           0 :         smb2_tdis(tree);
     788           0 :         smb2_logoff(tree->session);
     789           0 :         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           0 : static bool test_inheritance(struct torture_context *tctx, struct smb2_tree *tree)
     799             : {
     800             :         NTSTATUS status;
     801             :         struct smb2_create io;
     802           0 :         const char *dname = BASEDIR "\\inheritance";
     803           0 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
     804           0 :         const char *fname2 = BASEDIR "\\inheritance\\testdir";
     805           0 :         bool ret = true;
     806           0 :         struct smb2_handle handle = {{0}};
     807           0 :         struct smb2_handle handle2 = {{0}};
     808             :         int i;
     809             :         union smb_fileinfo q;
     810             :         union smb_setfileinfo set;
     811           0 :         struct security_descriptor *sd, *sd2, *sd_orig=NULL, *sd_def1, *sd_def2;
     812             :         const char *owner_sid;
     813             :         const struct dom_sid *creator_owner;
     814             :         const struct {
     815             :                 uint32_t parent_flags;
     816             :                 uint32_t file_flags;
     817             :                 uint32_t dir_flags;
     818           0 :         } 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           0 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     923           0 :                 return false;
     924             : 
     925           0 :         torture_comment(tctx, "TESTING ACL INHERITANCE\n");
     926             : 
     927           0 :         ZERO_STRUCT(io);
     928           0 :         io.level = RAW_OPEN_SMB2;
     929           0 :         io.in.create_flags = 0;
     930           0 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
     931           0 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     932           0 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     933           0 :         io.in.share_access = 0;
     934           0 :         io.in.alloc_size = 0;
     935           0 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
     936           0 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     937           0 :         io.in.security_flags = 0;
     938           0 :         io.in.fname = dname;
     939             : 
     940           0 :         status = smb2_create(tree, tctx, &io);
     941           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     942           0 :         handle = io.out.file.handle;
     943             : 
     944           0 :         torture_comment(tctx, "get the original sd\n");
     945           0 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     946           0 :         q.query_secdesc.in.file.handle = handle;
     947           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     948           0 :         status = smb2_getinfo_file(tree, tctx, &q);
     949           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     950           0 :         sd_orig = q.query_secdesc.out.sd;
     951             : 
     952           0 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
     953             : 
     954           0 :         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           0 :         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           0 :         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           0 :         creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER);
     985             : 
     986           0 :         for (i=0;i<ARRAY_SIZE(test_flags);i++) {
     987           0 :                 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           0 :                                                 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           0 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     999           0 :                 set.set_secdesc.in.file.handle = handle;
    1000           0 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1001           0 :                 set.set_secdesc.in.sd = sd;
    1002           0 :                 status = smb2_setinfo_file(tree, &set);
    1003           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1004             : 
    1005           0 :                 io.in.fname = fname1;
    1006           0 :                 io.in.create_options = 0;
    1007           0 :                 status = smb2_create(tree, tctx, &io);
    1008           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1009           0 :                 handle2 = io.out.file.handle;
    1010             : 
    1011           0 :                 q.query_secdesc.in.file.handle = handle2;
    1012           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1013           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1014             : 
    1015           0 :                 smb2_util_close(tree, handle2);
    1016           0 :                 smb2_util_unlink(tree, fname1);
    1017             : 
    1018           0 :                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
    1019           0 :                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
    1020           0 :                             !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
    1021           0 :                                 torture_warning(tctx, "Expected default sd:\n");
    1022           0 :                                 NDR_PRINT_DEBUG(security_descriptor, sd_def1);
    1023           0 :                                 torture_warning(tctx, "at %d - got:\n", i);
    1024           0 :                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1025             :                         }
    1026           0 :                         goto check_dir;
    1027             :                 }
    1028             : 
    1029           0 :                 if (q.query_secdesc.out.sd->dacl == NULL ||
    1030           0 :                     q.query_secdesc.out.sd->dacl->num_aces != 1 ||
    1031           0 :                     q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1032           0 :                     !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1033           0 :                                    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           0 :                 if (q.query_secdesc.out.sd->dacl->aces[0].flags !=
    1041           0 :                     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           0 :         check_dir:
    1051           0 :                 io.in.fname = fname2;
    1052           0 :                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1053           0 :                 status = smb2_create(tree, tctx, &io);
    1054           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1055           0 :                 handle2 = io.out.file.handle;
    1056             : 
    1057           0 :                 q.query_secdesc.in.file.handle = handle2;
    1058           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1059           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1060             : 
    1061           0 :                 smb2_util_close(tree, handle2);
    1062           0 :                 smb2_util_rmdir(tree, fname2);
    1063             : 
    1064           0 :                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
    1065           0 :                     (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
    1066           0 :                      (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
    1067           0 :                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
    1068           0 :                             !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
    1069           0 :                                 torture_warning(tctx, "Expected default sd for dir at %d:\n", i);
    1070           0 :                                 NDR_PRINT_DEBUG(security_descriptor, sd_def1);
    1071           0 :                                 torture_warning(tctx, "got:\n");
    1072           0 :                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1073             :                         }
    1074           0 :                         continue;
    1075             :                 }
    1076             : 
    1077           0 :                 if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
    1078           0 :                     (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
    1079           0 :                         if (q.query_secdesc.out.sd->dacl == NULL ||
    1080           0 :                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
    1081           0 :                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1082           0 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1083           0 :                                            sd_orig->owner_sid) ||
    1084           0 :                             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           0 :                 } else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
    1095           0 :                         if (q.query_secdesc.out.sd->dacl == NULL ||
    1096           0 :                             q.query_secdesc.out.sd->dacl->num_aces != 2 ||
    1097           0 :                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1098           0 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1099           0 :                                            sd_orig->owner_sid) ||
    1100           0 :                             q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
    1101           0 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
    1102           0 :                                            creator_owner) ||
    1103           0 :                             q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
    1104           0 :                             q.query_secdesc.out.sd->dacl->aces[1].flags !=
    1105           0 :                             (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           0 :                         if (q.query_secdesc.out.sd->dacl == NULL ||
    1117           0 :                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
    1118           0 :                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1119           0 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1120           0 :                                            creator_owner) ||
    1121           0 :                             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           0 :         torture_comment(tctx, "Testing access checks on inherited create with %s\n", fname1);
    1135           0 :         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           0 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1147           0 :         set.set_secdesc.in.file.handle = handle;
    1148           0 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1149           0 :         set.set_secdesc.in.sd = sd;
    1150           0 :         status = smb2_setinfo_file(tree, &set);
    1151           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1152             : 
    1153             :         /* Check DACL we just set. */
    1154           0 :         torture_comment(tctx, "checking new sd\n");
    1155           0 :         q.query_secdesc.in.file.handle = handle;
    1156           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
    1157           0 :         status = smb2_getinfo_file(tree, tctx, &q);
    1158           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1159           0 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
    1160             : 
    1161           0 :         io.in.fname = fname1;
    1162           0 :         io.in.create_options = 0;
    1163           0 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1164           0 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1165           0 :         status = smb2_create(tree, tctx, &io);
    1166           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1167           0 :         handle2 = io.out.file.handle;
    1168           0 :         CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
    1169             : 
    1170           0 :         q.query_secdesc.in.file.handle = handle2;
    1171           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1172           0 :         status = smb2_getinfo_file(tree, tctx, &q);
    1173           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1174           0 :         smb2_util_close(tree, handle2);
    1175             : 
    1176           0 :         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           0 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1184             : 
    1185           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1186           0 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1187           0 :         status = smb2_create(tree, tctx, &io);
    1188           0 :         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           0 :                 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           0 :                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1200             :                 }
    1201             :         }
    1202             : 
    1203           0 :         torture_comment(tctx, "trying without execute\n");
    1204           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1205           0 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
    1206           0 :         status = smb2_create(tree, tctx, &io);
    1207           0 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1208           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1209             :         } else {
    1210           0 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1211             :         }
    1212             : 
    1213           0 :         torture_comment(tctx, "and with full permissions again\n");
    1214           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1215           0 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1216           0 :         status = smb2_create(tree, tctx, &io);
    1217           0 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1218           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1219             :         } else {
    1220           0 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1221             :         }
    1222             : 
    1223           0 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1224           0 :         status = smb2_create(tree, tctx, &io);
    1225           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1226           0 :         handle2 = io.out.file.handle;
    1227           0 :         CHECK_ACCESS_FLAGS(handle2, SEC_FILE_WRITE_DATA);
    1228           0 :         smb2_util_close(tree, handle2);
    1229             : 
    1230           0 :         torture_comment(tctx, "put back original sd\n");
    1231           0 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1232           0 :         set.set_secdesc.in.file.handle = handle;
    1233           0 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1234           0 :         set.set_secdesc.in.sd = sd_orig;
    1235           0 :         status = smb2_setinfo_file(tree, &set);
    1236           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1237             : 
    1238           0 :         smb2_util_close(tree, handle);
    1239             : 
    1240           0 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1241           0 :         status = smb2_create(tree, tctx, &io);
    1242           0 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1243           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1244             :         } else {
    1245           0 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1246             :         }
    1247             : 
    1248           0 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1249           0 :         status = smb2_create(tree, tctx, &io);
    1250           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1251           0 :         handle2 = io.out.file.handle;
    1252           0 :         CHECK_ACCESS_FLAGS(handle2, SEC_FILE_WRITE_DATA);
    1253           0 :         smb2_util_close(tree, handle2);
    1254             : 
    1255           0 :         smb2_util_unlink(tree, fname1);
    1256           0 :         smb2_util_rmdir(tree, dname);
    1257             : 
    1258           0 : done:
    1259           0 :         if (sd_orig != NULL) {
    1260           0 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1261           0 :                 set.set_secdesc.in.file.handle = handle;
    1262           0 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1263           0 :                 set.set_secdesc.in.sd = sd_orig;
    1264           0 :                 status = smb2_setinfo_file(tree, &set);
    1265             :         }
    1266             : 
    1267           0 :         smb2_util_close(tree, handle);
    1268           0 :         smb2_deltree(tree, BASEDIR);
    1269           0 :         smb2_tdis(tree);
    1270           0 :         smb2_logoff(tree->session);
    1271           0 :         return ret;
    1272             : }
    1273             : 
    1274           0 : static bool test_inheritance_flags(struct torture_context *tctx,
    1275             :     struct smb2_tree *tree)
    1276             : {
    1277             :         NTSTATUS status;
    1278             :         struct smb2_create io;
    1279           0 :         const char *dname = BASEDIR "\\inheritance";
    1280           0 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
    1281           0 :         bool ret = true;
    1282           0 :         struct smb2_handle handle = {{0}};
    1283           0 :         struct smb2_handle handle2 = {{0}};
    1284             :         int i, j;
    1285             :         union smb_fileinfo q;
    1286             :         union smb_setfileinfo set;
    1287           0 :         struct security_descriptor *sd, *sd2, *sd_orig=NULL;
    1288             :         const char *owner_sid;
    1289             :         struct {
    1290             :                 uint32_t parent_set_sd_type; /* 3 options */
    1291             :                 uint32_t parent_set_ace_inherit; /* 1 option */
    1292             :                 uint32_t parent_get_sd_type;
    1293             :                 uint32_t parent_get_ace_inherit;
    1294             :                 uint32_t child_get_sd_type;
    1295             :                 uint32_t child_get_ace_inherit;
    1296           0 :         } tflags[16] = {{0}}; /* 2^4 */
    1297             : 
    1298           0 :         for (i = 0; i < 15; i++) {
    1299           0 :                 torture_comment(tctx, "i=%d:", i);
    1300             : 
    1301           0 :                 if (i & 1) {
    1302           0 :                         tflags[i].parent_set_sd_type |=
    1303             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1304           0 :                         torture_comment(tctx, "AUTO_INHERITED, ");
    1305             :                 }
    1306           0 :                 if (i & 2) {
    1307           0 :                         tflags[i].parent_set_sd_type |=
    1308             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1309           0 :                         torture_comment(tctx, "AUTO_INHERIT_REQ, ");
    1310             :                 }
    1311           0 :                 if (i & 4) {
    1312           0 :                         tflags[i].parent_set_sd_type |=
    1313             :                             SEC_DESC_DACL_PROTECTED;
    1314           0 :                         torture_comment(tctx, "PROTECTED, ");
    1315           0 :                         tflags[i].parent_get_sd_type |=
    1316             :                             SEC_DESC_DACL_PROTECTED;
    1317             :                 }
    1318           0 :                 if (i & 8) {
    1319           0 :                         tflags[i].parent_set_ace_inherit |=
    1320             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1321           0 :                         torture_comment(tctx, "INHERITED, ");
    1322           0 :                         tflags[i].parent_get_ace_inherit |=
    1323             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1324             :                 }
    1325             : 
    1326           0 :                 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           0 :                         tflags[i].parent_get_sd_type |=
    1330             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1331           0 :                         tflags[i].child_get_sd_type |=
    1332             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1333           0 :                         tflags[i].child_get_ace_inherit |=
    1334             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1335           0 :                         torture_comment(tctx, "  ... parent is AUTO INHERITED");
    1336             :                 }
    1337             : 
    1338           0 :                 if (tflags[i].parent_set_ace_inherit &
    1339             :                     SEC_ACE_FLAG_INHERITED_ACE) {
    1340           0 :                         tflags[i].parent_get_ace_inherit =
    1341             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1342           0 :                         torture_comment(tctx, "  ... parent ACE is INHERITED");
    1343             :                 }
    1344             : 
    1345           0 :                 torture_comment(tctx, "\n");
    1346             :         }
    1347             : 
    1348           0 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
    1349           0 :                 return false;
    1350             : 
    1351           0 :         torture_comment(tctx, "TESTING ACL INHERITANCE FLAGS\n");
    1352             : 
    1353           0 :         ZERO_STRUCT(io);
    1354           0 :         io.level = RAW_OPEN_SMB2;
    1355           0 :         io.in.create_flags = 0;
    1356           0 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1357           0 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1358           0 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    1359           0 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    1360           0 :         io.in.alloc_size = 0;
    1361           0 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1362           0 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1363           0 :         io.in.security_flags = 0;
    1364           0 :         io.in.fname = dname;
    1365             : 
    1366           0 :         torture_comment(tctx, "creating initial directory %s\n", dname);
    1367           0 :         status = smb2_create(tree, tctx, &io);
    1368           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1369           0 :         handle = io.out.file.handle;
    1370             : 
    1371           0 :         torture_comment(tctx, "getting original sd\n");
    1372           0 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1373           0 :         q.query_secdesc.in.file.handle = handle;
    1374           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1375           0 :         status = smb2_getinfo_file(tree, tctx, &q);
    1376           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1377           0 :         sd_orig = q.query_secdesc.out.sd;
    1378             : 
    1379           0 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    1380           0 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
    1381             : 
    1382           0 :         for (i=0; i < ARRAY_SIZE(tflags); i++) {
    1383           0 :                 torture_comment(tctx, "setting a new sd on directory, pass #%d\n", i);
    1384             : 
    1385           0 :                 sd = security_descriptor_dacl_create(tctx,
    1386           0 :                                                 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           0 :                                                 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           0 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1400           0 :                 set.set_secdesc.in.file.handle = handle;
    1401           0 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1402           0 :                 set.set_secdesc.in.sd = sd;
    1403           0 :                 status = smb2_setinfo_file(tree, &set);
    1404           0 :                 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           0 :                 torture_comment(tctx, "  checking new sd\n");
    1411             : 
    1412             :                 /* REQ bit should always be false. */
    1413           0 :                 sd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1414             : 
    1415           0 :                 if ((tflags[i].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1416           0 :                         sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1417             : 
    1418           0 :                 q.query_secdesc.in.file.handle = handle;
    1419           0 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
    1420           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1421           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1422           0 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
    1423             : 
    1424             :                 /* Create file. */
    1425           0 :                 torture_comment(tctx, "  creating file %s\n", fname1);
    1426           0 :                 io.in.fname = fname1;
    1427           0 :                 io.in.create_options = 0;
    1428           0 :                 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1429           0 :                 io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1430           0 :                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1431           0 :                 status = smb2_create(tree, tctx, &io);
    1432           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1433           0 :                 handle2 = io.out.file.handle;
    1434           0 :                 CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
    1435             : 
    1436           0 :                 q.query_secdesc.in.file.handle = handle2;
    1437           0 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1438           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1439           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1440             : 
    1441           0 :                 torture_comment(tctx, "  checking sd on file %s\n", fname1);
    1442           0 :                 sd2 = security_descriptor_dacl_create(tctx,
    1443           0 :                                                  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           0 :                 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           0 :                 for (j = 0; j < ARRAY_SIZE(tflags); j++) {
    1458           0 :                         torture_comment(tctx, "  setting new file sd, pass #%d\n", j);
    1459             : 
    1460             :                         /* Change sd type. */
    1461           0 :                         sd2->type &= ~(SEC_DESC_DACL_AUTO_INHERITED |
    1462             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ |
    1463             :                             SEC_DESC_DACL_PROTECTED);
    1464           0 :                         sd2->type |= tflags[j].parent_set_sd_type;
    1465             : 
    1466           0 :                         sd2->dacl->aces[0].flags &=
    1467             :                             ~SEC_ACE_FLAG_INHERITED_ACE;
    1468           0 :                         sd2->dacl->aces[0].flags |=
    1469           0 :                             tflags[j].parent_set_ace_inherit;
    1470             : 
    1471           0 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1472           0 :                         set.set_secdesc.in.file.handle = handle2;
    1473           0 :                         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1474           0 :                         set.set_secdesc.in.sd = sd2;
    1475           0 :                         status = smb2_setinfo_file(tree, &set);
    1476           0 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1477             : 
    1478             :                         /* Check DACL we just set. */
    1479           0 :                         sd2->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1480           0 :                         if ((tflags[j].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1481           0 :                                 sd2->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1482             : 
    1483           0 :                         q.query_secdesc.in.file.handle = handle2;
    1484           0 :                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1485           0 :                         status = smb2_getinfo_file(tree, tctx, &q);
    1486           0 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1487             : 
    1488           0 :                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1489             :                 }
    1490             : 
    1491           0 :                 smb2_util_close(tree, handle2);
    1492           0 :                 smb2_util_unlink(tree, fname1);
    1493             :         }
    1494             : 
    1495           0 : done:
    1496           0 :         smb2_util_close(tree, handle);
    1497           0 :         smb2_deltree(tree, BASEDIR);
    1498           0 :         smb2_tdis(tree);
    1499           0 :         smb2_logoff(tree->session);
    1500           0 :         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           0 : static bool test_sd_flags_vs_chown(struct torture_context *tctx,
    1509             :                                    struct smb2_tree *tree)
    1510             : {
    1511             :         NTSTATUS status;
    1512             :         struct smb2_create io;
    1513           0 :         const char *dname = BASEDIR "\\inheritance";
    1514           0 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
    1515           0 :         bool ret = true;
    1516           0 :         struct smb2_handle handle = {{0}};
    1517           0 :         struct smb2_handle handle2 = {{0}};
    1518             :         int i, j;
    1519             :         union smb_fileinfo q;
    1520             :         union smb_setfileinfo set;
    1521           0 :         struct security_descriptor *sd, *sd2, *sd_orig=NULL;
    1522           0 :         struct security_descriptor *owner_sd = NULL;
    1523           0 :         const char *owner_sid_string = NULL;
    1524           0 :         struct dom_sid *owner_sid = NULL;
    1525           0 :         struct dom_sid world_sid = global_sid_World;
    1526             :         struct {
    1527             :                 uint32_t parent_set_sd_type; /* 3 options */
    1528             :                 uint32_t parent_set_ace_inherit; /* 1 option */
    1529             :                 uint32_t parent_get_sd_type;
    1530             :                 uint32_t parent_get_ace_inherit;
    1531             :                 uint32_t child_get_sd_type;
    1532             :                 uint32_t child_get_ace_inherit;
    1533           0 :         } tflags[16] = {{0}}; /* 2^4 */
    1534             : 
    1535           0 :         owner_sd = security_descriptor_dacl_create(tctx,
    1536             :                                                    0,
    1537             :                                                    SID_WORLD,
    1538             :                                                    NULL,
    1539             :                                                    NULL);
    1540           0 :         torture_assert_not_null_goto(tctx, owner_sd, ret, done,
    1541             :                                      "security_descriptor_dacl_create failed\n");
    1542             : 
    1543           0 :         for (i = 0; i < 15; i++) {
    1544           0 :                 torture_comment(tctx, "i=%d:", i);
    1545             : 
    1546           0 :                 if (i & 1) {
    1547           0 :                         tflags[i].parent_set_sd_type |=
    1548             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1549           0 :                         torture_comment(tctx, "AUTO_INHERITED, ");
    1550             :                 }
    1551           0 :                 if (i & 2) {
    1552           0 :                         tflags[i].parent_set_sd_type |=
    1553             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1554           0 :                         torture_comment(tctx, "AUTO_INHERIT_REQ, ");
    1555             :                 }
    1556           0 :                 if (i & 4) {
    1557           0 :                         tflags[i].parent_set_sd_type |=
    1558             :                             SEC_DESC_DACL_PROTECTED;
    1559           0 :                         torture_comment(tctx, "PROTECTED, ");
    1560           0 :                         tflags[i].parent_get_sd_type |=
    1561             :                             SEC_DESC_DACL_PROTECTED;
    1562             :                 }
    1563           0 :                 if (i & 8) {
    1564           0 :                         tflags[i].parent_set_ace_inherit |=
    1565             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1566           0 :                         torture_comment(tctx, "INHERITED, ");
    1567           0 :                         tflags[i].parent_get_ace_inherit |=
    1568             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1569             :                 }
    1570             : 
    1571           0 :                 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           0 :                         tflags[i].parent_get_sd_type |=
    1575             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1576           0 :                         tflags[i].child_get_sd_type |=
    1577             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1578           0 :                         tflags[i].child_get_ace_inherit |=
    1579             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1580           0 :                         torture_comment(tctx, "  ... parent is AUTO INHERITED");
    1581             :                 }
    1582             : 
    1583           0 :                 if (tflags[i].parent_set_ace_inherit &
    1584             :                     SEC_ACE_FLAG_INHERITED_ACE) {
    1585           0 :                         tflags[i].parent_get_ace_inherit =
    1586             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1587           0 :                         torture_comment(tctx, "  ... parent ACE is INHERITED");
    1588             :                 }
    1589             : 
    1590           0 :                 torture_comment(tctx, "\n");
    1591             :         }
    1592             : 
    1593           0 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
    1594           0 :                 return false;
    1595             : 
    1596           0 :         torture_comment(tctx, "TESTING ACL INHERITANCE FLAGS\n");
    1597             : 
    1598           0 :         ZERO_STRUCT(io);
    1599           0 :         io.level = RAW_OPEN_SMB2;
    1600           0 :         io.in.create_flags = 0;
    1601           0 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1602           0 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1603           0 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    1604           0 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    1605           0 :         io.in.alloc_size = 0;
    1606           0 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1607           0 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1608           0 :         io.in.security_flags = 0;
    1609           0 :         io.in.fname = dname;
    1610             : 
    1611           0 :         torture_comment(tctx, "creating initial directory %s\n", dname);
    1612           0 :         status = smb2_create(tree, tctx, &io);
    1613           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1614           0 :         handle = io.out.file.handle;
    1615             : 
    1616           0 :         torture_comment(tctx, "getting original sd\n");
    1617           0 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1618           0 :         q.query_secdesc.in.file.handle = handle;
    1619           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1620           0 :         status = smb2_getinfo_file(tree, tctx, &q);
    1621           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1622           0 :         sd_orig = q.query_secdesc.out.sd;
    1623             : 
    1624           0 :         owner_sid = sd_orig->owner_sid;
    1625           0 :         owner_sid_string = dom_sid_string(tctx, sd_orig->owner_sid);
    1626           0 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid_string);
    1627             : 
    1628           0 :         for (i=0; i < ARRAY_SIZE(tflags); i++) {
    1629           0 :                 torture_comment(tctx, "setting a new sd on directory, pass #%d\n", i);
    1630             : 
    1631           0 :                 sd = security_descriptor_dacl_create(tctx,
    1632           0 :                                                 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           0 :                                                 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           0 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1646           0 :                 set.set_secdesc.in.file.handle = handle;
    1647           0 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1648           0 :                 set.set_secdesc.in.sd = sd;
    1649           0 :                 status = smb2_setinfo_file(tree, &set);
    1650           0 :                 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           0 :                 torture_comment(tctx, "  checking new sd\n");
    1657             : 
    1658             :                 /* REQ bit should always be false. */
    1659           0 :                 sd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1660             : 
    1661           0 :                 if ((tflags[i].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1662           0 :                         sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1663             : 
    1664           0 :                 q.query_secdesc.in.file.handle = handle;
    1665           0 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
    1666           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1667           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1668           0 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
    1669             : 
    1670             :                 /* Create file. */
    1671           0 :                 torture_comment(tctx, "  creating file %s\n", fname1);
    1672           0 :                 io.in.fname = fname1;
    1673           0 :                 io.in.create_options = 0;
    1674           0 :                 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1675           0 :                 io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1676           0 :                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1677           0 :                 status = smb2_create(tree, tctx, &io);
    1678           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1679           0 :                 handle2 = io.out.file.handle;
    1680           0 :                 CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
    1681             : 
    1682           0 :                 q.query_secdesc.in.file.handle = handle2;
    1683           0 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1684           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1685           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1686             : 
    1687           0 :                 torture_comment(tctx, "  checking sd on file %s\n", fname1);
    1688           0 :                 sd2 = security_descriptor_dacl_create(tctx,
    1689           0 :                                                  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           0 :                 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           0 :                 for (j = 0; j < ARRAY_SIZE(tflags); j++) {
    1704           0 :                         torture_comment(tctx, "  setting new file sd, pass #%d\n", j);
    1705             : 
    1706             :                         /* Change sd type. */
    1707           0 :                         sd2->type &= ~(SEC_DESC_DACL_AUTO_INHERITED |
    1708             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ |
    1709             :                             SEC_DESC_DACL_PROTECTED);
    1710           0 :                         sd2->type |= tflags[j].parent_set_sd_type;
    1711             : 
    1712           0 :                         sd2->dacl->aces[0].flags &=
    1713             :                             ~SEC_ACE_FLAG_INHERITED_ACE;
    1714           0 :                         sd2->dacl->aces[0].flags |=
    1715           0 :                             tflags[j].parent_set_ace_inherit;
    1716             : 
    1717           0 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1718           0 :                         set.set_secdesc.in.file.handle = handle2;
    1719           0 :                         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1720           0 :                         set.set_secdesc.in.sd = sd2;
    1721           0 :                         status = smb2_setinfo_file(tree, &set);
    1722           0 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1723             : 
    1724             :                         /* Check DACL we just set. */
    1725           0 :                         sd2->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1726           0 :                         if ((tflags[j].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1727           0 :                                 sd2->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1728             : 
    1729           0 :                         q.query_secdesc.in.file.handle = handle2;
    1730           0 :                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1731           0 :                         status = smb2_getinfo_file(tree, tctx, &q);
    1732           0 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1733             : 
    1734           0 :                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1735             : 
    1736             :                         /*
    1737             :                          * Check that changing ownder doesn't affect SD flags.
    1738             :                          *
    1739             :                          * Do this by first changing ownder to world and then
    1740             :                          * back to the original ownder. Afterwards compare SD,
    1741             :                          * should be the same.
    1742             :                          */
    1743           0 :                         owner_sd->owner_sid = &world_sid;
    1744           0 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1745           0 :                         set.set_secdesc.in.file.handle = handle2;
    1746           0 :                         set.set_secdesc.in.secinfo_flags = SECINFO_OWNER;
    1747           0 :                         set.set_secdesc.in.sd = owner_sd;
    1748           0 :                         status = smb2_setinfo_file(tree, &set);
    1749           0 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1750             : 
    1751           0 :                         owner_sd->owner_sid = owner_sid;
    1752           0 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1753           0 :                         set.set_secdesc.in.file.handle = handle2;
    1754           0 :                         set.set_secdesc.in.secinfo_flags = SECINFO_OWNER;
    1755           0 :                         set.set_secdesc.in.sd = owner_sd;
    1756           0 :                         status = smb2_setinfo_file(tree, &set);
    1757           0 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1758             : 
    1759           0 :                         q.query_secdesc.in.file.handle = handle2;
    1760           0 :                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1761           0 :                         status = smb2_getinfo_file(tree, tctx, &q);
    1762           0 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1763             : 
    1764           0 :                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1765           0 :                         torture_assert_goto(tctx, ret, ret, done, "CHECK_SECURITY_DESCRIPTOR failed\n");
    1766             :                 }
    1767             : 
    1768           0 :                 smb2_util_close(tree, handle2);
    1769           0 :                 smb2_util_unlink(tree, fname1);
    1770             :         }
    1771             : 
    1772           0 : done:
    1773           0 :         smb2_util_close(tree, handle);
    1774           0 :         smb2_deltree(tree, BASEDIR);
    1775           0 :         smb2_tdis(tree);
    1776           0 :         smb2_logoff(tree->session);
    1777           0 :         return ret;
    1778             : }
    1779             : 
    1780             : /*
    1781             :   test dynamic acl inheritance
    1782             :   Note: This test was copied from raw/acls.c.
    1783             : */
    1784           0 : static bool test_inheritance_dynamic(struct torture_context *tctx,
    1785             :     struct smb2_tree *tree)
    1786             : {
    1787             :         NTSTATUS status;
    1788             :         struct smb2_create io;
    1789           0 :         const char *dname = BASEDIR "\\inheritance";
    1790           0 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
    1791           0 :         bool ret = true;
    1792           0 :         struct smb2_handle handle = {{0}};
    1793           0 :         struct smb2_handle handle2 = {{0}};
    1794             :         union smb_fileinfo q;
    1795             :         union smb_setfileinfo set;
    1796           0 :         struct security_descriptor *sd, *sd_orig=NULL;
    1797             :         const char *owner_sid;
    1798             : 
    1799           0 :         torture_comment(tctx, "TESTING DYNAMIC ACL INHERITANCE\n");
    1800             : 
    1801           0 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
    1802           0 :                 return false;
    1803             : 
    1804           0 :         ZERO_STRUCT(io);
    1805           0 :         io.level = RAW_OPEN_SMB2;
    1806           0 :         io.in.create_flags = 0;
    1807           0 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1808           0 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1809           0 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    1810           0 :         io.in.share_access = 0;
    1811           0 :         io.in.alloc_size = 0;
    1812           0 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1813           0 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1814           0 :         io.in.security_flags = 0;
    1815           0 :         io.in.fname = dname;
    1816             : 
    1817           0 :         status = smb2_create(tree, tctx, &io);
    1818           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1819           0 :         handle = io.out.file.handle;
    1820             : 
    1821           0 :         torture_comment(tctx, "get the original sd\n");
    1822           0 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1823           0 :         q.query_secdesc.in.file.handle = handle;
    1824           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1825           0 :         status = smb2_getinfo_file(tree, tctx, &q);
    1826           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1827           0 :         sd_orig = q.query_secdesc.out.sd;
    1828             : 
    1829           0 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    1830             : 
    1831           0 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
    1832             : 
    1833           0 :         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           0 :         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1841             : 
    1842           0 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1843           0 :         set.set_secdesc.in.file.handle = handle;
    1844           0 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1845           0 :         set.set_secdesc.in.sd = sd;
    1846           0 :         status = smb2_setinfo_file(tree, &set);
    1847           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1848             : 
    1849           0 :         torture_comment(tctx, "create a file with an inherited acl\n");
    1850           0 :         io.in.fname = fname1;
    1851           0 :         io.in.create_options = 0;
    1852           0 :         io.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
    1853           0 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1854           0 :         status = smb2_create(tree, tctx, &io);
    1855           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1856           0 :         handle2 = io.out.file.handle;
    1857           0 :         smb2_util_close(tree, handle2);
    1858             : 
    1859           0 :         torture_comment(tctx, "try and access file with base rights - should be OK\n");
    1860           0 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1861           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1862           0 :         status = smb2_create(tree, tctx, &io);
    1863           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1864           0 :         handle2 = io.out.file.handle;
    1865           0 :         smb2_util_close(tree, handle2);
    1866             : 
    1867           0 :         torture_comment(tctx, "try and access file with extra rights - should be denied\n");
    1868           0 :         io.in.desired_access = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
    1869           0 :         status = smb2_create(tree, tctx, &io);
    1870           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1871             : 
    1872           0 :         torture_comment(tctx, "update parent sd\n");
    1873           0 :         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           0 :         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1881             : 
    1882           0 :         set.set_secdesc.in.sd = sd;
    1883           0 :         status = smb2_setinfo_file(tree, &set);
    1884           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1885             : 
    1886           0 :         torture_comment(tctx, "try and access file with base rights - should be OK\n");
    1887           0 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1888           0 :         status = smb2_create(tree, tctx, &io);
    1889           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1890           0 :         handle2 = io.out.file.handle;
    1891           0 :         smb2_util_close(tree, handle2);
    1892             : 
    1893             : 
    1894           0 :         torture_comment(tctx, "try and access now - should be OK if dynamic inheritance works\n");
    1895           0 :         io.in.desired_access = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
    1896           0 :         status = smb2_create(tree, tctx, &io);
    1897           0 :         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    1898           0 :                 torture_comment(tctx, "Server does not have dynamic inheritance\n");
    1899             :         }
    1900           0 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
    1901           0 :                 torture_comment(tctx, "Server does have dynamic inheritance\n");
    1902             :         }
    1903           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1904             : 
    1905           0 :         smb2_util_unlink(tree, fname1);
    1906             : 
    1907           0 : done:
    1908           0 :         torture_comment(tctx, "put back original sd\n");
    1909           0 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1910           0 :         set.set_secdesc.in.file.handle = handle;
    1911           0 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1912           0 :         set.set_secdesc.in.sd = sd_orig;
    1913           0 :         status = smb2_setinfo_file(tree, &set);
    1914             : 
    1915           0 :         smb2_util_close(tree, handle);
    1916           0 :         smb2_util_rmdir(tree, dname);
    1917           0 :         smb2_deltree(tree, BASEDIR);
    1918           0 :         smb2_tdis(tree);
    1919           0 :         smb2_logoff(tree->session);
    1920             : 
    1921           0 :         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           0 : static bool test_access_based(struct torture_context *tctx,
    2143             :                                 struct smb2_tree *tree)
    2144             : {
    2145           0 :         struct smb2_tree *tree1 = NULL;
    2146             :         NTSTATUS status;
    2147             :         struct smb2_create io;
    2148           0 :         const char *fname = BASEDIR "\\testfile";
    2149           0 :         bool ret = true;
    2150             :         struct smb2_handle fhandle, dhandle;
    2151             :         union smb_fileinfo q;
    2152             :         union smb_setfileinfo set;
    2153           0 :         struct security_descriptor *sd, *sd_orig=NULL;
    2154             :         const char *owner_sid;
    2155           0 :         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           0 :         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             :         unsigned int i;
    2178             :         unsigned int count;
    2179             :         struct smb2_find f;
    2180             :         union smb_search_data *d;
    2181             : 
    2182           0 :         ZERO_STRUCT(fhandle);
    2183           0 :         ZERO_STRUCT(dhandle);
    2184             : 
    2185           0 :         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           0 :         flags = smb2cli_tcon_flags(tree1->smbXcli);
    2194             : 
    2195           0 :         smb2_util_unlink(tree1, fname);
    2196           0 :         smb2_deltree(tree1, BASEDIR);
    2197             : 
    2198           0 :         torture_comment(tctx, "TESTING ACCESS BASED ENUMERATION\n");
    2199             : 
    2200           0 :         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           0 :         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           0 :         status = torture_smb2_testdir(tree1, BASEDIR, &dhandle);
    2217           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    2218           0 :         smb2_util_close(tree1, dhandle);
    2219           0 :         ZERO_STRUCT(dhandle);
    2220             : 
    2221           0 :         ZERO_STRUCT(io);
    2222           0 :         io.level = RAW_OPEN_SMB2;
    2223           0 :         io.in.create_flags = 0;
    2224           0 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    2225           0 :         io.in.create_options = 0;
    2226           0 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    2227           0 :         io.in.share_access = 0;
    2228           0 :         io.in.alloc_size = 0;
    2229           0 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    2230           0 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2231           0 :         io.in.security_flags = 0;
    2232           0 :         io.in.fname = fname;
    2233             : 
    2234           0 :         status = smb2_create(tree1, tctx, &io);
    2235           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    2236           0 :         fhandle = io.out.file.handle;
    2237             : 
    2238           0 :         torture_comment(tctx, "get the original sd\n");
    2239           0 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    2240           0 :         q.query_secdesc.in.file.handle = fhandle;
    2241           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    2242           0 :         status = smb2_getinfo_file(tree1, tctx, &q);
    2243           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    2244           0 :         sd_orig = q.query_secdesc.out.sd;
    2245             : 
    2246           0 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2247             : 
    2248           0 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
    2249             : 
    2250             :         /* Setup for the search. */
    2251           0 :         ZERO_STRUCT(f);
    2252           0 :         f.in.pattern            = "*";
    2253           0 :         f.in.continue_flags     = SMB2_CONTINUE_FLAG_REOPEN;
    2254           0 :         f.in.max_response_size  = 0x1000;
    2255           0 :         f.in.level              = SMB2_FIND_DIRECTORY_INFO;
    2256             : 
    2257           0 :         for (i = 0; i < ARRAY_SIZE(access_masks); i++) {
    2258             : 
    2259           0 :                 sd = security_descriptor_dacl_create(tctx,
    2260             :                                         0, NULL, NULL,
    2261             :                                         owner_sid,
    2262             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2263           0 :                                         access_masks[i]|SEC_STD_SYNCHRONIZE,
    2264             :                                         0,
    2265             :                                         NULL);
    2266             : 
    2267           0 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    2268           0 :                 set.set_secdesc.in.file.handle = fhandle;
    2269           0 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    2270           0 :                 set.set_secdesc.in.sd = sd;
    2271           0 :                 status = smb2_setinfo_file(tree1, &set);
    2272           0 :                 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           0 :                 status = torture_smb2_testdir(tree1, BASEDIR, &dhandle);
    2278           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    2279           0 :                 f.in.file.handle = dhandle;
    2280             : 
    2281           0 :                 count = 0;
    2282           0 :                 d = NULL;
    2283           0 :                 status = smb2_find_level(tree1, tree1, &f, &count, &d);
    2284           0 :                 TALLOC_FREE(d);
    2285             : 
    2286           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
    2287             : 
    2288           0 :                 smb2_util_close(tree1, dhandle);
    2289           0 :                 ZERO_STRUCT(dhandle);
    2290             : 
    2291           0 :                 if (i == 0) {
    2292             :                         /* We should see the first sd. */
    2293           0 :                         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           0 :                         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           0 : done:
    2318             : 
    2319           0 :         if (tree1) {
    2320           0 :                 smb2_util_close(tree1, fhandle);
    2321           0 :                 smb2_util_close(tree1, dhandle);
    2322           0 :                 smb2_util_unlink(tree1, fname);
    2323           0 :                 smb2_deltree(tree1, BASEDIR);
    2324           0 :                 smb2_tdis(tree1);
    2325           0 :                 smb2_logoff(tree1->session);
    2326             :         }
    2327           0 :         smb2_tdis(tree);
    2328           0 :         smb2_logoff(tree->session);
    2329           0 :         return ret;
    2330             : }
    2331             : 
    2332             : /*
    2333             :  * test Owner Rights, S-1-3-4
    2334             :  */
    2335           0 : static bool test_owner_rights(struct torture_context *tctx,
    2336             :                               struct smb2_tree *tree)
    2337             : {
    2338           0 :         const char *fname = BASEDIR "\\owner_right.txt";
    2339             :         struct smb2_create cr;
    2340           0 :         struct smb2_handle handle = {{0}};
    2341             :         union smb_fileinfo gi;
    2342             :         union smb_setfileinfo si;
    2343           0 :         struct security_descriptor *sd_orig = NULL;
    2344           0 :         struct security_descriptor *sd = NULL;
    2345           0 :         const char *owner_sid = NULL;
    2346             :         NTSTATUS mxac_status;
    2347             :         NTSTATUS status;
    2348           0 :         bool ret = true;
    2349             : 
    2350           0 :         smb2_deltree(tree, BASEDIR);
    2351             : 
    2352           0 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2353           0 :         torture_assert_goto(tctx, ret, ret, done,
    2354             :                             "smb2_util_setup_dir failed\n");
    2355             : 
    2356           0 :         torture_comment(tctx, "TESTING OWNER RIGHTS\n");
    2357             : 
    2358           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    2369           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2370             :                                         "smb2_create failed\n");
    2371           0 :         handle = cr.out.file.handle;
    2372             : 
    2373           0 :         torture_comment(tctx, "get the original sd\n");
    2374             : 
    2375           0 :         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           0 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2382           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2383             :                                         "smb2_getinfo_file failed\n");
    2384             : 
    2385           0 :         sd_orig = gi.query_secdesc.out.sd;
    2386           0 :         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           0 :         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           0 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2407             :                                      "SD create failed\n");
    2408             : 
    2409           0 :         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           0 :         status = smb2_setinfo_file(tree, &si);
    2417           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2418             :                                         "smb2_setinfo_file failed\n");
    2419             : 
    2420           0 :         status = smb2_util_close(tree, handle);
    2421           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2422             :                                         "smb2_util_close failed\n");
    2423           0 :         ZERO_STRUCT(handle);
    2424             : 
    2425           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    2436           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2437             :                                         "smb2_setinfo_file failed\n");
    2438           0 :         handle = cr.out.file.handle;
    2439             : 
    2440           0 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2441           0 :         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           0 :         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           0 :         status = smb2_util_close(tree, handle);
    2456           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2457             :                                         "smb2_util_close failed\n");
    2458           0 :         ZERO_STRUCT(handle);
    2459             : 
    2460           0 : done:
    2461           0 :         if (!smb2_util_handle_empty(handle)) {
    2462           0 :                 smb2_util_close(tree, handle);
    2463             :         }
    2464           0 :         smb2_deltree(tree, BASEDIR);
    2465           0 :         return ret;
    2466             : }
    2467             : 
    2468             : /*
    2469             :  * test Owner Rights with a leading DENY ACE, S-1-3-4
    2470             :  */
    2471           0 : static bool test_owner_rights_deny(struct torture_context *tctx,
    2472             :                                 struct smb2_tree *tree)
    2473             : {
    2474           0 :         const char *fname = BASEDIR "\\owner_right_deny.txt";
    2475             :         struct smb2_create cr;
    2476           0 :         struct smb2_handle handle = {{0}};
    2477             :         union smb_fileinfo gi;
    2478             :         union smb_setfileinfo si;
    2479           0 :         struct security_descriptor *sd_orig = NULL;
    2480           0 :         struct security_descriptor *sd = NULL;
    2481           0 :         const char *owner_sid = NULL;
    2482             :         NTSTATUS mxac_status;
    2483             :         NTSTATUS status;
    2484           0 :         bool ret = true;
    2485             : 
    2486           0 :         smb2_deltree(tree, BASEDIR);
    2487             : 
    2488           0 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2489           0 :         torture_assert_goto(tctx, ret, ret, done,
    2490             :                         "smb2_util_setup_dir failed\n");
    2491             : 
    2492           0 :         torture_comment(tctx, "TESTING OWNER RIGHTS DENY\n");
    2493             : 
    2494           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    2505           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2506             :                                         "smb2_create failed\n");
    2507           0 :         handle = cr.out.file.handle;
    2508             : 
    2509           0 :         torture_comment(tctx, "get the original sd\n");
    2510             : 
    2511           0 :         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           0 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2518           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2519             :                                 "smb2_getinfo_file failed\n");
    2520             : 
    2521           0 :         sd_orig = gi.query_secdesc.out.sd;
    2522           0 :         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           0 :         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           0 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2543             :                                         "SD create failed\n");
    2544             : 
    2545           0 :         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           0 :         status = smb2_setinfo_file(tree, &si);
    2553           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2554             :                                         "smb2_setinfo_file failed\n");
    2555             : 
    2556           0 :         status = smb2_util_close(tree, handle);
    2557           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2558             :                                         "smb2_util_close failed\n");
    2559           0 :         ZERO_STRUCT(handle);
    2560             : 
    2561           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    2572           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2573             :                                         "smb2_setinfo_file failed\n");
    2574           0 :         handle = cr.out.file.handle;
    2575             : 
    2576           0 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2577           0 :         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           0 :         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           0 :         status = smb2_util_close(tree, handle);
    2591           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2592             :                                         "smb2_util_close failed\n");
    2593           0 :         ZERO_STRUCT(handle);
    2594             : 
    2595           0 : done:
    2596           0 :         if (!smb2_util_handle_empty(handle)) {
    2597           0 :                 smb2_util_close(tree, handle);
    2598             :         }
    2599           0 :         smb2_deltree(tree, BASEDIR);
    2600           0 :         return ret;
    2601             : }
    2602             : 
    2603             : /*
    2604             :  * test Owner Rights with a trailing DENY ACE, S-1-3-4
    2605             :  */
    2606           0 : static bool test_owner_rights_deny1(struct torture_context *tctx,
    2607             :                                 struct smb2_tree *tree)
    2608             : {
    2609           0 :         const char *fname = BASEDIR "\\owner_right_deny1.txt";
    2610             :         struct smb2_create cr;
    2611           0 :         struct smb2_handle handle = {{0}};
    2612             :         union smb_fileinfo gi;
    2613             :         union smb_setfileinfo si;
    2614           0 :         struct security_descriptor *sd_orig = NULL;
    2615           0 :         struct security_descriptor *sd = NULL;
    2616           0 :         const char *owner_sid = NULL;
    2617             :         NTSTATUS mxac_status;
    2618             :         NTSTATUS status;
    2619           0 :         bool ret = true;
    2620             : 
    2621           0 :         smb2_deltree(tree, BASEDIR);
    2622             : 
    2623           0 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2624           0 :         torture_assert_goto(tctx, ret, ret, done,
    2625             :                         "smb2_util_setup_dir failed\n");
    2626             : 
    2627           0 :         torture_comment(tctx, "TESTING OWNER RIGHTS DENY1\n");
    2628             : 
    2629           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    2640           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2641             :                                         "smb2_create failed\n");
    2642           0 :         handle = cr.out.file.handle;
    2643             : 
    2644           0 :         torture_comment(tctx, "get the original sd\n");
    2645             : 
    2646           0 :         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           0 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2653           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2654             :                                 "smb2_getinfo_file failed\n");
    2655             : 
    2656           0 :         sd_orig = gi.query_secdesc.out.sd;
    2657           0 :         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           0 :         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           0 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2685             :                                         "SD create failed\n");
    2686             : 
    2687           0 :         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           0 :         status = smb2_setinfo_file(tree, &si);
    2695           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2696             :                                         "smb2_setinfo_file failed\n");
    2697             : 
    2698           0 :         status = smb2_util_close(tree, handle);
    2699           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2700             :                                         "smb2_util_close failed\n");
    2701           0 :         ZERO_STRUCT(handle);
    2702             : 
    2703           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    2714           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2715             :                                         "smb2_setinfo_file failed\n");
    2716           0 :         handle = cr.out.file.handle;
    2717             : 
    2718           0 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2719           0 :         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           0 :         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           0 :         status = smb2_util_close(tree, handle);
    2733           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2734             :                                         "smb2_util_close failed\n");
    2735           0 :         ZERO_STRUCT(handle);
    2736             : 
    2737           0 : done:
    2738           0 :         if (!smb2_util_handle_empty(handle)) {
    2739           0 :                 smb2_util_close(tree, handle);
    2740             :         }
    2741           0 :         smb2_deltree(tree, BASEDIR);
    2742           0 :         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           0 : static bool test_deny1(struct torture_context *tctx,
    2750             :                        struct smb2_tree *tree)
    2751             : {
    2752           0 :         const char *fname = BASEDIR "\\test_deny1.txt";
    2753             :         struct smb2_create cr;
    2754           0 :         struct smb2_handle handle = {{0}};
    2755             :         union smb_fileinfo gi;
    2756             :         union smb_setfileinfo si;
    2757           0 :         struct security_descriptor *sd_orig = NULL;
    2758           0 :         struct security_descriptor *sd = NULL;
    2759           0 :         const char *owner_sid = NULL;
    2760             :         NTSTATUS mxac_status;
    2761             :         NTSTATUS status;
    2762           0 :         bool ret = true;
    2763             : 
    2764           0 :         smb2_deltree(tree, BASEDIR);
    2765             : 
    2766           0 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2767           0 :         torture_assert_goto(tctx, ret, ret, done,
    2768             :                         "smb2_util_setup_dir failed\n");
    2769             : 
    2770           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    2781           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2782             :                                         "smb2_create failed\n");
    2783           0 :         handle = cr.out.file.handle;
    2784             : 
    2785           0 :         torture_comment(tctx, "get the original sd\n");
    2786             : 
    2787           0 :         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           0 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2794           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2795             :                                 "smb2_getinfo_file failed\n");
    2796             : 
    2797           0 :         sd_orig = gi.query_secdesc.out.sd;
    2798           0 :         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           0 :         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           0 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2820             :                                         "SD create failed\n");
    2821             : 
    2822           0 :         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           0 :         status = smb2_setinfo_file(tree, &si);
    2830           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2831             :                                         "smb2_setinfo_file failed\n");
    2832             : 
    2833           0 :         status = smb2_util_close(tree, handle);
    2834           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2835             :                                         "smb2_util_close failed\n");
    2836           0 :         ZERO_STRUCT(handle);
    2837             : 
    2838           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    2849           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2850             :                                         "smb2_create failed\n");
    2851           0 :         handle = cr.out.file.handle;
    2852             : 
    2853           0 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2854           0 :         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           0 :         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           0 :         status = smb2_util_close(tree, handle);
    2871           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2872             :                                         "smb2_util_close failed\n");
    2873           0 :         ZERO_STRUCT(handle);
    2874             : 
    2875           0 : done:
    2876           0 :         if (!smb2_util_handle_empty(handle)) {
    2877           0 :                 smb2_util_close(tree, handle);
    2878             :         }
    2879           0 :         smb2_deltree(tree, BASEDIR);
    2880           0 :         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             :  * proces 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           0 : static bool test_mxac_not_granted(struct torture_context *tctx,
    2892             :                                   struct smb2_tree *tree)
    2893             : {
    2894           0 :         const char *fname = BASEDIR "\\test_mxac_not_granted.txt";
    2895             :         struct smb2_create cr;
    2896           0 :         struct smb2_handle handle = {{0}};
    2897             :         union smb_fileinfo gi;
    2898             :         union smb_setfileinfo si;
    2899           0 :         struct security_descriptor *sd_orig = NULL;
    2900           0 :         struct security_descriptor *sd = NULL;
    2901           0 :         const char *owner_sid = NULL;
    2902             :         NTSTATUS status;
    2903           0 :         bool ret = true;
    2904             : 
    2905           0 :         smb2_deltree(tree, BASEDIR);
    2906             : 
    2907           0 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2908           0 :         torture_assert_goto(tctx, ret, ret, done,
    2909             :                         "smb2_util_setup_dir failed\n");
    2910             : 
    2911           0 :         torture_comment(tctx, "TESTING OWNER RIGHTS DENY\n");
    2912             : 
    2913           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    2924           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2925             :                                         "smb2_create failed\n");
    2926           0 :         handle = cr.out.file.handle;
    2927             : 
    2928           0 :         torture_comment(tctx, "get the original sd\n");
    2929             : 
    2930           0 :         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           0 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2937           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2938             :                                 "smb2_getinfo_file failed\n");
    2939             : 
    2940           0 :         sd_orig = gi.query_secdesc.out.sd;
    2941           0 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2942             : 
    2943           0 :         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           0 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2950             :                                         "SD create failed\n");
    2951             : 
    2952           0 :         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           0 :         status = smb2_setinfo_file(tree, &si);
    2960           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2961             :                                         "smb2_setinfo_file failed\n");
    2962             : 
    2963           0 :         status = smb2_util_close(tree, handle);
    2964           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2965             :                                         "smb2_util_close failed\n");
    2966           0 :         ZERO_STRUCT(handle);
    2967             : 
    2968           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    2979           0 :         torture_assert_ntstatus_equal_goto(tctx, status,
    2980             :                                            NT_STATUS_ACCESS_DENIED,
    2981             :                                            ret, done,
    2982             :                                            "Wrong smb2_create result\n");
    2983             : 
    2984           0 : done:
    2985           0 :         if (!smb2_util_handle_empty(handle)) {
    2986           0 :                 smb2_util_close(tree, handle);
    2987             :         }
    2988           0 :         smb2_deltree(tree, BASEDIR);
    2989           0 :         return ret;
    2990             : }
    2991             : 
    2992           0 : static bool test_overwrite_read_only_file(struct torture_context *tctx,
    2993             :                                           struct smb2_tree *tree)
    2994             : {
    2995             :         NTSTATUS status;
    2996             :         struct smb2_create c;
    2997           0 :         const char *fname = BASEDIR "\\test_overwrite_read_only_file.txt";
    2998           0 :         struct smb2_handle handle = {{0}};
    2999             :         union smb_fileinfo q;
    3000             :         union smb_setfileinfo set;
    3001           0 :         struct security_descriptor *sd = NULL, *sd_orig = NULL;
    3002           0 :         const char *owner_sid = NULL;
    3003             :         int i;
    3004           0 :         bool ret = true;
    3005             : 
    3006             :         struct tcase {
    3007             :                 int disposition;
    3008             :                 const char *disposition_string;
    3009             :                 NTSTATUS expected_status;
    3010           0 :         } 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           0 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    3024           0 :         torture_assert_goto(tctx, ret, ret, done, "smb2_util_setup_dir not ok");
    3025             : 
    3026           0 :         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           0 :         status = smb2_create(tree, tctx, &c);
    3039           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3040             :                                         "smb2_create failed\n");
    3041           0 :         handle = c.out.file.handle;
    3042             : 
    3043           0 :         torture_comment(tctx, "get the original sd\n");
    3044             : 
    3045           0 :         ZERO_STRUCT(q);
    3046           0 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    3047           0 :         q.query_secdesc.in.file.handle = handle;
    3048           0 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    3049             : 
    3050           0 :         status = smb2_getinfo_file(tree, tctx, &q);
    3051           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3052             :                                         "smb2_getinfo_file failed\n");
    3053           0 :         sd_orig = q.query_secdesc.out.sd;
    3054             : 
    3055           0 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    3056             : 
    3057           0 :         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           0 :         ZERO_STRUCT(set);
    3066           0 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    3067           0 :         set.set_secdesc.in.file.handle = handle;
    3068           0 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    3069           0 :         set.set_secdesc.in.sd = sd;
    3070             : 
    3071           0 :         status = smb2_setinfo_file(tree, &set);
    3072           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3073             :                                         "smb2_setinfo_file failed\n");
    3074             : 
    3075           0 :         smb2_util_close(tree, handle);
    3076           0 :         ZERO_STRUCT(handle);
    3077             : 
    3078           0 :         for (i = 0; i < ARRAY_SIZE(tcases); i++) {
    3079           0 :                 torture_comment(tctx, "Verify open with %s dispostion\n",
    3080             :                                 tcases[i].disposition_string);
    3081             : 
    3082           0 :                 c = (struct smb2_create) {
    3083           0 :                         .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           0 :                 status = smb2_create(tree, tctx, &c);
    3092           0 :                 smb2_util_close(tree, c.out.file.handle);
    3093           0 :                 torture_assert_ntstatus_equal_goto(
    3094             :                         tctx, status, tcases[i].expected_status, ret, done,
    3095             :                         "smb2_create failed\n");
    3096             :         };
    3097             : 
    3098           0 :         torture_comment(tctx, "put back original sd\n");
    3099             : 
    3100           0 :         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           0 :         status = smb2_create(tree, tctx, &c);
    3110           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3111             :                                         "smb2_create failed\n");
    3112           0 :         handle = c.out.file.handle;
    3113             : 
    3114           0 :         ZERO_STRUCT(set);
    3115           0 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    3116           0 :         set.set_secdesc.in.file.handle = handle;
    3117           0 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    3118           0 :         set.set_secdesc.in.sd = sd_orig;
    3119             : 
    3120           0 :         status = smb2_setinfo_file(tree, &set);
    3121           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3122             :                                         "smb2_setinfo_file failed\n");
    3123             : 
    3124           0 :         smb2_util_close(tree, handle);
    3125           0 :         ZERO_STRUCT(handle);
    3126             : 
    3127           0 : done:
    3128           0 :         smb2_util_close(tree, handle);
    3129           0 :         smb2_util_unlink(tree, fname);
    3130           0 :         smb2_deltree(tree, BASEDIR);
    3131           0 :         return ret;
    3132             : }
    3133             : 
    3134             : /*
    3135             :    basic testing of SMB2 ACLs
    3136             : */
    3137         964 : struct torture_suite *torture_smb2_acls_init(TALLOC_CTX *ctx)
    3138             : {
    3139         964 :         struct torture_suite *suite = torture_suite_create(ctx, "acls");
    3140             : 
    3141         964 :         torture_suite_add_1smb2_test(suite, "CREATOR", test_creator_sid);
    3142         964 :         torture_suite_add_1smb2_test(suite, "GENERIC", test_generic_bits);
    3143         964 :         torture_suite_add_1smb2_test(suite, "OWNER", test_owner_bits);
    3144         964 :         torture_suite_add_1smb2_test(suite, "INHERITANCE", test_inheritance);
    3145         964 :         torture_suite_add_1smb2_test(suite, "INHERITFLAGS", test_inheritance_flags);
    3146         964 :         torture_suite_add_1smb2_test(suite, "SDFLAGSVSCHOWN", test_sd_flags_vs_chown);
    3147         964 :         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         964 :         torture_suite_add_1smb2_test(suite, "ACCESSBASED", test_access_based);
    3153         964 :         torture_suite_add_1smb2_test(suite, "OWNER-RIGHTS", test_owner_rights);
    3154         964 :         torture_suite_add_1smb2_test(suite, "OWNER-RIGHTS-DENY",
    3155             :                         test_owner_rights_deny);
    3156         964 :         torture_suite_add_1smb2_test(suite, "OWNER-RIGHTS-DENY1",
    3157             :                         test_owner_rights_deny1);
    3158         964 :         torture_suite_add_1smb2_test(suite, "DENY1",
    3159             :                         test_deny1);
    3160         964 :         torture_suite_add_1smb2_test(suite, "MXAC-NOT-GRANTED",
    3161             :                         test_mxac_not_granted);
    3162         964 :         torture_suite_add_1smb2_test(suite, "OVERWRITE_READ_ONLY_FILE", test_overwrite_read_only_file);
    3163             : 
    3164         964 :         suite->description = talloc_strdup(suite, "SMB2-ACLS tests");
    3165             : 
    3166         964 :         return suite;
    3167             : }
    3168             : 
    3169           0 : static bool test_acls_non_canonical_flags(struct torture_context *tctx,
    3170             :                                           struct smb2_tree *tree)
    3171             : {
    3172           0 :         const char *fname = BASEDIR "\\test_acls_non_canonical_flags.txt";
    3173             :         struct smb2_create cr;
    3174           0 :         struct smb2_handle testdirh = {{0}};
    3175           0 :         struct smb2_handle handle = {{0}};
    3176             :         union smb_fileinfo gi;
    3177             :         union smb_setfileinfo si;
    3178           0 :         struct security_descriptor *sd_orig = NULL;
    3179           0 :         struct security_descriptor *sd = NULL;
    3180             :         NTSTATUS status;
    3181           0 :         bool ret = true;
    3182             : 
    3183           0 :         smb2_deltree(tree, BASEDIR);
    3184             : 
    3185           0 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    3186           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3187             :                                         "torture_smb2_testdir failed\n");
    3188             : 
    3189           0 :         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           0 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    3201             :                                         "SD create failed\n");
    3202             : 
    3203           0 :         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           0 :         status = smb2_setinfo_file(tree, &si);
    3211           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3212             :                                         "smb2_setinfo_file failed\n");
    3213             : 
    3214           0 :         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           0 :         status = smb2_getinfo_file(tree, tctx, &gi);
    3221           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3222             :                                 "smb2_getinfo_file failed\n");
    3223             : 
    3224           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    3235           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3236             :                                         "smb2_create failed\n");
    3237           0 :         handle = cr.out.file.handle;
    3238             : 
    3239           0 :         torture_comment(tctx, "get the original sd\n");
    3240             : 
    3241           0 :         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           0 :         status = smb2_getinfo_file(tree, tctx, &gi);
    3248           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3249             :                                 "smb2_getinfo_file failed\n");
    3250             : 
    3251           0 :         sd_orig = gi.query_secdesc.out.sd;
    3252             : 
    3253           0 :         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           0 :         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           0 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    3277             :                                         "SD create failed\n");
    3278             : 
    3279           0 :         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           0 :         status = smb2_setinfo_file(tree, &si);
    3287           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3288             :                                         "smb2_setinfo_file failed\n");
    3289             : 
    3290           0 :         status = smb2_util_close(tree, handle);
    3291           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3292             :                                         "smb2_util_close failed\n");
    3293           0 :         ZERO_STRUCT(handle);
    3294             : 
    3295           0 :         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           0 :         status = smb2_create(tree, tctx, &cr);
    3305           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3306             :                                         "smb2_create failed\n");
    3307           0 :         handle = cr.out.file.handle;
    3308             : 
    3309           0 :         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           0 :         status = smb2_getinfo_file(tree, tctx, &gi);
    3316           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3317             :                                 "smb2_getinfo_file failed\n");
    3318             : 
    3319           0 :         sd_orig = gi.query_secdesc.out.sd;
    3320           0 :         torture_assert_goto(tctx, sd_orig->type & SEC_DESC_DACL_AUTO_INHERITED,
    3321             :                             ret, done, "Missing SEC_DESC_DACL_AUTO_INHERITED\n");
    3322             : 
    3323           0 : done:
    3324           0 :         if (!smb2_util_handle_empty(handle)) {
    3325           0 :                 smb2_util_close(tree, testdirh);
    3326             :         }
    3327           0 :         if (!smb2_util_handle_empty(handle)) {
    3328           0 :                 smb2_util_close(tree, handle);
    3329             :         }
    3330           0 :         smb2_deltree(tree, BASEDIR);
    3331           0 :         return ret;
    3332             : }
    3333             : 
    3334         964 : struct torture_suite *torture_smb2_acls_non_canonical_init(TALLOC_CTX *ctx)
    3335             : {
    3336         964 :         struct torture_suite *suite = torture_suite_create(ctx, "acls_non_canonical");
    3337             : 
    3338         964 :         torture_suite_add_1smb2_test(suite, "flags", test_acls_non_canonical_flags);
    3339         964 :         return suite;
    3340             : }

Generated by: LCOV version 1.13