LCOV - code coverage report
Current view: top level - source4/torture/smb2 - acls.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 1251 1353 92.5 %
Date: 2021-08-25 13:27:56 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    test security descriptor operations for SMB2
       5             : 
       6             :    Copyright (C) Zack Kirsch 2009
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "lib/cmdline/cmdline.h"
      24             : #include "libcli/smb2/smb2.h"
      25             : #include "libcli/smb2/smb2_calls.h"
      26             : #include "libcli/smb/smbXcli_base.h"
      27             : #include "torture/torture.h"
      28             : #include "libcli/resolve/resolve.h"
      29             : #include "torture/util.h"
      30             : #include "torture/smb2/proto.h"
      31             : #include "libcli/security/security.h"
      32             : #include "librpc/gen_ndr/ndr_security.h"
      33             : #include "lib/param/param.h"
      34             : 
      35             : #define CHECK_STATUS(status, correct) do { \
      36             :         if (!NT_STATUS_EQUAL(status, correct)) { \
      37             :                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
      38             :                        __location__, nt_errstr(status), nt_errstr(correct)); \
      39             :                 ret = false; \
      40             :                 goto done; \
      41             :         }} while (0)
      42             : 
      43             : #define BASEDIR "smb2-testsd"
      44             : 
      45             : #define CHECK_ACCESS_IGNORE SEC_STD_SYNCHRONIZE
      46             : 
      47             : #define CHECK_ACCESS_FLAGS(_fh, flags) do { \
      48             :         union smb_fileinfo _q; \
      49             :         _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
      50             :         _q.access_information.in.file.handle = (_fh); \
      51             :         status = smb2_getinfo_file(tree, tctx, &_q); \
      52             :         CHECK_STATUS(status, NT_STATUS_OK); \
      53             :         /* Handle a Vista bug where SEC_STD_SYNCHRONIZE doesn't come back. */ \
      54             :         if ((((flags) & CHECK_ACCESS_IGNORE) == CHECK_ACCESS_IGNORE) && \
      55             :             ((_q.access_information.out.access_flags & CHECK_ACCESS_IGNORE) != CHECK_ACCESS_IGNORE)) { \
      56             :                 torture_comment(tctx, "SKIPPING (Vista bug): (%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
      57             :                        __location__, _q.access_information.out.access_flags, (flags)); \
      58             :         } \
      59             :         if ((_q.access_information.out.access_flags & ~CHECK_ACCESS_IGNORE) != \
      60             :             (((flags) & ~CHECK_ACCESS_IGNORE))) { \
      61             :                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
      62             :                        __location__, _q.access_information.out.access_flags, (flags)); \
      63             :                 ret = false; \
      64             :                 goto done; \
      65             :         } \
      66             : } while (0)
      67             : 
      68             : #define FAIL_UNLESS(__cond)                                     \
      69             :         do {                                                    \
      70             :                 if (__cond) {} else {                           \
      71             :                         torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n",    \
      72             :                                __location__, #__cond);          \
      73             :                         ret = false; goto done;                 \
      74             :                 }                                               \
      75             :         } while(0)
      76             : 
      77             : #define CHECK_SECURITY_DESCRIPTOR(_sd1, _sd2) do { \
      78             :         if (!security_descriptor_equal(_sd1, _sd2)) { \
      79             :                 torture_warning(tctx, "security descriptors don't match!\n"); \
      80             :                 torture_warning(tctx, "got:\n"); \
      81             :                 NDR_PRINT_DEBUG(security_descriptor, _sd1); \
      82             :                 torture_warning(tctx, "expected:\n"); \
      83             :                 NDR_PRINT_DEBUG(security_descriptor, _sd2); \
      84             :                 torture_result(tctx, TORTURE_FAIL, \
      85             :                                "%s: security descriptors don't match!\n", \
      86             :                                __location__); \
      87             :                 ret = false; \
      88             :         } \
      89             : } while (0)
      90             : 
      91             : /*
      92             :   test the behaviour of the well known SID_CREATOR_OWNER sid, and some generic
      93             :   mapping bits
      94             :   Note: This test was copied from raw/acls.c.
      95             : */
      96           4 : static bool test_creator_sid(struct torture_context *tctx, struct smb2_tree *tree)
      97             : {
      98             :         NTSTATUS status;
      99             :         struct smb2_create io;
     100           4 :         const char *fname = BASEDIR "\\creator.txt";
     101           4 :         bool ret = true;
     102           4 :         struct smb2_handle handle = {{0}};
     103             :         union smb_fileinfo q;
     104             :         union smb_setfileinfo set;
     105             :         struct security_descriptor *sd, *sd_orig, *sd2;
     106             :         const char *owner_sid;
     107             : 
     108           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     109           0 :                 return false;
     110             : 
     111           4 :         torture_comment(tctx, "TESTING SID_CREATOR_OWNER\n");
     112             : 
     113           4 :         ZERO_STRUCT(io);
     114           4 :         io.level = RAW_OPEN_SMB2;
     115           4 :         io.in.create_flags = 0;
     116           4 :         io.in.desired_access = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER;
     117           4 :         io.in.create_options = 0;
     118           4 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     119           4 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
     120             :                 NTCREATEX_SHARE_ACCESS_READ |
     121             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     122           4 :         io.in.alloc_size = 0;
     123           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     124           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     125           4 :         io.in.security_flags = 0;
     126           4 :         io.in.fname = fname;
     127             : 
     128           4 :         status = smb2_create(tree, tctx, &io);
     129           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     130           4 :         handle = io.out.file.handle;
     131             : 
     132           4 :         torture_comment(tctx, "get the original sd\n");
     133           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     134           4 :         q.query_secdesc.in.file.handle = handle;
     135           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     136           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     137           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     138           4 :         sd_orig = q.query_secdesc.out.sd;
     139             : 
     140           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
     141             : 
     142           4 :         torture_comment(tctx, "set a sec desc allowing no write by CREATOR_OWNER\n");
     143           4 :         sd = security_descriptor_dacl_create(tctx,
     144             :                                         0, NULL, NULL,
     145             :                                         SID_CREATOR_OWNER,
     146             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
     147             :                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
     148             :                                         0,
     149             :                                         NULL);
     150             : 
     151           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     152           4 :         set.set_secdesc.in.file.handle = handle;
     153           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     154           4 :         set.set_secdesc.in.sd = sd;
     155             : 
     156           4 :         status = smb2_setinfo_file(tree, &set);
     157           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     158             : 
     159           4 :         torture_comment(tctx, "try open for write\n");
     160           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
     161           4 :         status = smb2_create(tree, tctx, &io);
     162           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     163             : 
     164           4 :         torture_comment(tctx, "try open for read\n");
     165           4 :         io.in.desired_access = SEC_FILE_READ_DATA;
     166           4 :         status = smb2_create(tree, tctx, &io);
     167           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     168             : 
     169           4 :         torture_comment(tctx, "try open for generic write\n");
     170           4 :         io.in.desired_access = SEC_GENERIC_WRITE;
     171           4 :         status = smb2_create(tree, tctx, &io);
     172           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     173             : 
     174           4 :         torture_comment(tctx, "try open for generic read\n");
     175           4 :         io.in.desired_access = SEC_GENERIC_READ;
     176           4 :         status = smb2_create(tree, tctx, &io);
     177           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     178             : 
     179           4 :         torture_comment(tctx, "set a sec desc allowing no write by owner\n");
     180           4 :         sd = security_descriptor_dacl_create(tctx,
     181             :                                         0, owner_sid, NULL,
     182             :                                         owner_sid,
     183             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
     184             :                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
     185             :                                         0,
     186             :                                         NULL);
     187             : 
     188           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     189           4 :         set.set_secdesc.in.file.handle = handle;
     190           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     191           4 :         set.set_secdesc.in.sd = sd;
     192           4 :         status = smb2_setinfo_file(tree, &set);
     193           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     194             : 
     195           4 :         torture_comment(tctx, "check that sd has been mapped correctly\n");
     196           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     197           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     198           4 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
     199             : 
     200           4 :         torture_comment(tctx, "try open for write\n");
     201           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
     202           4 :         status = smb2_create(tree, tctx, &io);
     203           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     204             : 
     205           4 :         torture_comment(tctx, "try open for read\n");
     206           4 :         io.in.desired_access = SEC_FILE_READ_DATA;
     207           4 :         status = smb2_create(tree, tctx, &io);
     208           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     209           4 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
     210             :                            SEC_FILE_READ_DATA);
     211           4 :         smb2_util_close(tree, io.out.file.handle);
     212             : 
     213           4 :         torture_comment(tctx, "try open for generic write\n");
     214           4 :         io.in.desired_access = SEC_GENERIC_WRITE;
     215           4 :         status = smb2_create(tree, tctx, &io);
     216           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     217             : 
     218           4 :         torture_comment(tctx, "try open for generic read\n");
     219           4 :         io.in.desired_access = SEC_GENERIC_READ;
     220           4 :         status = smb2_create(tree, tctx, &io);
     221           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     222           4 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
     223             :                            SEC_RIGHTS_FILE_READ);
     224           4 :         smb2_util_close(tree, io.out.file.handle);
     225             : 
     226           4 :         torture_comment(tctx, "set a sec desc allowing generic read by owner\n");
     227           4 :         sd = security_descriptor_dacl_create(tctx,
     228             :                                         0, NULL, NULL,
     229             :                                         owner_sid,
     230             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
     231             :                                         SEC_GENERIC_READ | SEC_STD_ALL,
     232             :                                         0,
     233             :                                         NULL);
     234             : 
     235           4 :         set.set_secdesc.in.sd = sd;
     236           4 :         status = smb2_setinfo_file(tree, &set);
     237           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     238             : 
     239           4 :         torture_comment(tctx, "check that generic read has been mapped correctly\n");
     240           4 :         sd2 = security_descriptor_dacl_create(tctx,
     241             :                                          0, owner_sid, NULL,
     242             :                                          owner_sid,
     243             :                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
     244             :                                          SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
     245             :                                          0,
     246             :                                          NULL);
     247             : 
     248           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     249           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     250           4 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     251             : 
     252           4 :         torture_comment(tctx, "try open for write\n");
     253           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
     254           4 :         status = smb2_create(tree, tctx, &io);
     255           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     256             : 
     257           4 :         torture_comment(tctx, "try open for read\n");
     258           4 :         io.in.desired_access = SEC_FILE_READ_DATA;
     259           4 :         status = smb2_create(tree, tctx, &io);
     260           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     261           4 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
     262             :                            SEC_FILE_READ_DATA);
     263           4 :         smb2_util_close(tree, io.out.file.handle);
     264             : 
     265           4 :         torture_comment(tctx, "try open for generic write\n");
     266           4 :         io.in.desired_access = SEC_GENERIC_WRITE;
     267           4 :         status = smb2_create(tree, tctx, &io);
     268           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     269             : 
     270           4 :         torture_comment(tctx, "try open for generic read\n");
     271           4 :         io.in.desired_access = SEC_GENERIC_READ;
     272           4 :         status = smb2_create(tree, tctx, &io);
     273           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     274           4 :         CHECK_ACCESS_FLAGS(io.out.file.handle, SEC_RIGHTS_FILE_READ);
     275           4 :         smb2_util_close(tree, io.out.file.handle);
     276             : 
     277             : 
     278           4 :         torture_comment(tctx, "put back original sd\n");
     279           4 :         set.set_secdesc.in.sd = sd_orig;
     280           4 :         status = smb2_setinfo_file(tree, &set);
     281           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     282             : 
     283             : 
     284           8 : done:
     285           4 :         smb2_util_close(tree, handle);
     286           4 :         smb2_deltree(tree, BASEDIR);
     287           4 :         smb2_tdis(tree);
     288           4 :         smb2_logoff(tree->session);
     289           4 :         return ret;
     290             : }
     291             : 
     292             : 
     293             : /*
     294             :   test the mapping of the SEC_GENERIC_xx bits to SEC_STD_xx and
     295             :   SEC_FILE_xx bits
     296             :   Note: This test was copied from raw/acls.c.
     297             : */
     298           4 : static bool test_generic_bits(struct torture_context *tctx, struct smb2_tree *tree)
     299             : {
     300             :         NTSTATUS status;
     301             :         struct smb2_create io;
     302           4 :         const char *fname = BASEDIR "\\generic.txt";
     303           4 :         bool ret = true;
     304           4 :         struct smb2_handle handle = {{0}};
     305             :         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           4 :         } file_mappings[] = {
     314             :                 { 0,                       0 },
     315             :                 { SEC_GENERIC_READ,        SEC_RIGHTS_FILE_READ },
     316             :                 { SEC_GENERIC_WRITE,       SEC_RIGHTS_FILE_WRITE },
     317             :                 { SEC_GENERIC_EXECUTE,     SEC_RIGHTS_FILE_EXECUTE },
     318             :                 { SEC_GENERIC_ALL,         SEC_RIGHTS_FILE_ALL },
     319             :                 { SEC_FILE_READ_DATA,      SEC_FILE_READ_DATA },
     320             :                 { SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_ATTRIBUTE }
     321             :         };
     322             :         const struct {
     323             :                 uint32_t gen_bits;
     324             :                 uint32_t specific_bits;
     325           4 :         } dir_mappings[] = {
     326             :                 { 0,                   0 },
     327             :                 { SEC_GENERIC_READ,    SEC_RIGHTS_DIR_READ },
     328             :                 { SEC_GENERIC_WRITE,   SEC_RIGHTS_DIR_WRITE },
     329             :                 { SEC_GENERIC_EXECUTE, SEC_RIGHTS_DIR_EXECUTE },
     330             :                 { SEC_GENERIC_ALL,     SEC_RIGHTS_DIR_ALL }
     331             :         };
     332           4 :         bool has_restore_privilege = false;
     333           4 :         bool has_take_ownership_privilege = false;
     334             : 
     335           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     336           0 :                 return false;
     337             : 
     338           4 :         torture_comment(tctx, "TESTING FILE GENERIC BITS\n");
     339             : 
     340           4 :         ZERO_STRUCT(io);
     341           4 :         io.level = RAW_OPEN_SMB2;
     342           4 :         io.in.create_flags = 0;
     343           4 :         io.in.desired_access =
     344             :                 SEC_STD_READ_CONTROL |
     345             :                 SEC_STD_WRITE_DAC |
     346             :                 SEC_STD_WRITE_OWNER;
     347           4 :         io.in.create_options = 0;
     348           4 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     349           4 :         io.in.share_access =
     350             :                 NTCREATEX_SHARE_ACCESS_READ |
     351             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     352           4 :         io.in.alloc_size = 0;
     353           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     354           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     355           4 :         io.in.security_flags = 0;
     356           4 :         io.in.fname = fname;
     357           4 :         status = smb2_create(tree, tctx, &io);
     358           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     359           4 :         handle = io.out.file.handle;
     360             : 
     361           4 :         torture_comment(tctx, "get the original sd\n");
     362           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     363           4 :         q.query_secdesc.in.file.handle = handle;
     364           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     365           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     366           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     367           4 :         sd_orig = q.query_secdesc.out.sd;
     368             : 
     369           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
     370             : 
     371             : /*
     372             :  * XXX: The smblsa calls use SMB as their transport - need to get rid of
     373             :  * dependency.
     374             :  */
     375             : /*
     376             :         status = smblsa_sid_check_privilege(cli,
     377             :                                             owner_sid,
     378             :                                             sec_privilege_name(SEC_PRIV_RESTORE));
     379             :         has_restore_privilege = NT_STATUS_IS_OK(status);
     380             :         if (!NT_STATUS_IS_OK(status)) {
     381             :                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
     382             :         }
     383             :         torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
     384             : 
     385             :         status = smblsa_sid_check_privilege(cli,
     386             :                                             owner_sid,
     387             :                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
     388             :         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
     389             :         if (!NT_STATUS_IS_OK(status)) {
     390             :                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
     391             :         }
     392             :         torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
     393             : */
     394             : 
     395          32 :         for (i=0;i<ARRAY_SIZE(file_mappings);i++) {
     396          28 :                 uint32_t expected_mask =
     397             :                         SEC_STD_WRITE_DAC |
     398             :                         SEC_STD_READ_CONTROL |
     399             :                         SEC_FILE_READ_ATTRIBUTE |
     400             :                         SEC_STD_DELETE;
     401          28 :                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
     402             : 
     403          28 :                 if (has_restore_privilege) {
     404           0 :                         expected_mask_anon |= SEC_STD_DELETE;
     405             :                 }
     406             : 
     407          28 :                 torture_comment(tctx, "Testing generic bits 0x%08x\n",
     408             :                        file_mappings[i].gen_bits);
     409          28 :                 sd = security_descriptor_dacl_create(tctx,
     410             :                                                 0, owner_sid, NULL,
     411             :                                                 owner_sid,
     412             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     413             :                                                 file_mappings[i].gen_bits,
     414             :                                                 0,
     415             :                                                 NULL);
     416             : 
     417          28 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     418          28 :                 set.set_secdesc.in.file.handle = handle;
     419          28 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     420          28 :                 set.set_secdesc.in.sd = sd;
     421             : 
     422          28 :                 status = smb2_setinfo_file(tree, &set);
     423          28 :                 CHECK_STATUS(status, NT_STATUS_OK);
     424             : 
     425          28 :                 sd2 = security_descriptor_dacl_create(tctx,
     426             :                                                  0, owner_sid, NULL,
     427             :                                                  owner_sid,
     428             :                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
     429             :                                                  file_mappings[i].specific_bits,
     430             :                                                  0,
     431             :                                                  NULL);
     432             : 
     433          28 :                 status = smb2_getinfo_file(tree, tctx, &q);
     434          28 :                 CHECK_STATUS(status, NT_STATUS_OK);
     435          28 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     436             : 
     437          28 :                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     438          28 :                 status = smb2_create(tree, tctx, &io);
     439          28 :                 CHECK_STATUS(status, NT_STATUS_OK);
     440          28 :                 CHECK_ACCESS_FLAGS(io.out.file.handle,
     441             :                                    expected_mask | file_mappings[i].specific_bits);
     442          28 :                 smb2_util_close(tree, io.out.file.handle);
     443             : 
     444          28 :                 if (!has_take_ownership_privilege) {
     445          28 :                         continue;
     446             :                 }
     447             : 
     448           0 :                 torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
     449             :                        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             :                                                 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             :                                                  file_mappings[i].specific_bits,
     471             :                                                  0,
     472             :                                                  NULL);
     473             : 
     474           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
     475           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     476           0 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     477             : 
     478           0 :                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     479           0 :                 status = smb2_create(tree, tctx, &io);
     480           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     481           0 :                 CHECK_ACCESS_FLAGS(io.out.file.handle,
     482             :                                    expected_mask_anon | file_mappings[i].specific_bits);
     483           0 :                 smb2_util_close(tree, io.out.file.handle);
     484             :         }
     485             : 
     486           4 :         torture_comment(tctx, "put back original sd\n");
     487           4 :         set.set_secdesc.in.sd = sd_orig;
     488           4 :         status = smb2_setinfo_file(tree, &set);
     489           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     490             : 
     491           4 :         smb2_util_close(tree, handle);
     492           4 :         smb2_util_unlink(tree, fname);
     493             : 
     494             : 
     495           4 :         torture_comment(tctx, "TESTING DIR GENERIC BITS\n");
     496             : 
     497           4 :         ZERO_STRUCT(io);
     498           4 :         io.level = RAW_OPEN_SMB2;
     499           4 :         io.in.create_flags = 0;
     500           4 :         io.in.desired_access =
     501             :                 SEC_STD_READ_CONTROL |
     502             :                 SEC_STD_WRITE_DAC |
     503             :                 SEC_STD_WRITE_OWNER;
     504           4 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     505           4 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     506           4 :         io.in.share_access =
     507             :                 NTCREATEX_SHARE_ACCESS_READ |
     508             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     509           4 :         io.in.alloc_size = 0;
     510           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     511           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     512           4 :         io.in.security_flags = 0;
     513           4 :         io.in.fname = fname;
     514           4 :         status = smb2_create(tree, tctx, &io);
     515           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     516           4 :         handle = io.out.file.handle;
     517             : 
     518           4 :         torture_comment(tctx, "get the original sd\n");
     519           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     520           4 :         q.query_secdesc.in.file.handle = handle;
     521           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     522           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     523           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     524           4 :         sd_orig = q.query_secdesc.out.sd;
     525             : 
     526           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
     527             : 
     528             : /*
     529             :  * XXX: The smblsa calls use SMB as their transport - need to get rid of
     530             :  * dependency.
     531             :  */
     532             : /*
     533             :         status = smblsa_sid_check_privilege(cli,
     534             :                                             owner_sid,
     535             :                                             sec_privilege_name(SEC_PRIV_RESTORE));
     536             :         has_restore_privilege = NT_STATUS_IS_OK(status);
     537             :         if (!NT_STATUS_IS_OK(status)) {
     538             :                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
     539             :         }
     540             :         torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
     541             : 
     542             :         status = smblsa_sid_check_privilege(cli,
     543             :                                             owner_sid,
     544             :                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
     545             :         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
     546             :         if (!NT_STATUS_IS_OK(status)) {
     547             :                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
     548             :         }
     549             :         torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
     550             : 
     551             : */
     552          24 :         for (i=0;i<ARRAY_SIZE(dir_mappings);i++) {
     553          20 :                 uint32_t expected_mask =
     554             :                         SEC_STD_WRITE_DAC |
     555             :                         SEC_STD_READ_CONTROL |
     556             :                         SEC_FILE_READ_ATTRIBUTE |
     557             :                         SEC_STD_DELETE;
     558          20 :                 uint32_t expected_mask_anon = SEC_FILE_READ_ATTRIBUTE;
     559             : 
     560          20 :                 if (has_restore_privilege) {
     561           0 :                         expected_mask_anon |= SEC_STD_DELETE;
     562             :                 }
     563             : 
     564          20 :                 torture_comment(tctx, "Testing generic bits 0x%08x\n",
     565             :                        file_mappings[i].gen_bits);
     566          20 :                 sd = security_descriptor_dacl_create(tctx,
     567             :                                                 0, owner_sid, NULL,
     568             :                                                 owner_sid,
     569             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     570             :                                                 dir_mappings[i].gen_bits,
     571             :                                                 0,
     572             :                                                 NULL);
     573             : 
     574          20 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     575          20 :                 set.set_secdesc.in.file.handle = handle;
     576          20 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     577          20 :                 set.set_secdesc.in.sd = sd;
     578             : 
     579          20 :                 status = smb2_setinfo_file(tree, &set);
     580          20 :                 CHECK_STATUS(status, NT_STATUS_OK);
     581             : 
     582          20 :                 sd2 = security_descriptor_dacl_create(tctx,
     583             :                                                  0, owner_sid, NULL,
     584             :                                                  owner_sid,
     585             :                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
     586             :                                                  dir_mappings[i].specific_bits,
     587             :                                                  0,
     588             :                                                  NULL);
     589             : 
     590          20 :                 status = smb2_getinfo_file(tree, tctx, &q);
     591          20 :                 CHECK_STATUS(status, NT_STATUS_OK);
     592          20 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     593             : 
     594          20 :                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     595          20 :                 status = smb2_create(tree, tctx, &io);
     596          20 :                 CHECK_STATUS(status, NT_STATUS_OK);
     597          20 :                 CHECK_ACCESS_FLAGS(io.out.file.handle,
     598             :                                    expected_mask | dir_mappings[i].specific_bits);
     599          20 :                 smb2_util_close(tree, io.out.file.handle);
     600             : 
     601          20 :                 if (!has_take_ownership_privilege) {
     602          20 :                         continue;
     603             :                 }
     604             : 
     605           0 :                 torture_comment(tctx, "Testing generic bits 0x%08x (anonymous)\n",
     606             :                        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             :                                                 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             :                                                  file_mappings[i].specific_bits,
     628             :                                                  0,
     629             :                                                  NULL);
     630             : 
     631           0 :                 status = smb2_getinfo_file(tree, tctx, &q);
     632           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     633           0 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
     634             : 
     635           0 :                 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     636           0 :                 status = smb2_create(tree, tctx, &io);
     637           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     638           0 :                 CHECK_ACCESS_FLAGS(io.out.file.handle,
     639             :                                    expected_mask_anon | dir_mappings[i].specific_bits);
     640           0 :                 smb2_util_close(tree, io.out.file.handle);
     641             :         }
     642             : 
     643           4 :         torture_comment(tctx, "put back original sd\n");
     644           4 :         set.set_secdesc.in.sd = sd_orig;
     645           4 :         status = smb2_setinfo_file(tree, &set);
     646           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     647             : 
     648           4 :         smb2_util_close(tree, handle);
     649           4 :         smb2_util_unlink(tree, fname);
     650             : 
     651           4 : done:
     652           4 :         smb2_util_close(tree, handle);
     653           4 :         smb2_deltree(tree, BASEDIR);
     654           4 :         smb2_tdis(tree);
     655           4 :         smb2_logoff(tree->session);
     656           4 :         return ret;
     657             : }
     658             : 
     659             : 
     660             : /*
     661             :   see what access bits the owner of a file always gets
     662             :   Note: This test was copied from raw/acls.c.
     663             : */
     664           4 : static bool test_owner_bits(struct torture_context *tctx, struct smb2_tree *tree)
     665             : {
     666             :         NTSTATUS status;
     667             :         struct smb2_create io;
     668           4 :         const char *fname = BASEDIR "\\test_owner_bits.txt";
     669           4 :         bool ret = true;
     670           4 :         struct smb2_handle handle = {{0}};
     671             :         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           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     679           0 :                 return false;
     680             : 
     681           4 :         torture_comment(tctx, "TESTING FILE OWNER BITS\n");
     682             : 
     683           4 :         ZERO_STRUCT(io);
     684           4 :         io.level = RAW_OPEN_SMB2;
     685           4 :         io.in.create_flags = 0;
     686           4 :         io.in.desired_access =
     687             :                 SEC_STD_READ_CONTROL |
     688             :                 SEC_STD_WRITE_DAC |
     689             :                 SEC_STD_WRITE_OWNER;
     690           4 :         io.in.create_options = 0;
     691           4 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     692           4 :         io.in.share_access =
     693             :                 NTCREATEX_SHARE_ACCESS_READ |
     694             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     695           4 :         io.in.alloc_size = 0;
     696           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     697           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     698           4 :         io.in.security_flags = 0;
     699           4 :         io.in.fname = fname;
     700           4 :         status = smb2_create(tree, tctx, &io);
     701           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     702           4 :         handle = io.out.file.handle;
     703             : 
     704           4 :         torture_comment(tctx, "get the original sd\n");
     705           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     706           4 :         q.query_secdesc.in.file.handle = handle;
     707           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     708           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     709           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     710           4 :         sd_orig = q.query_secdesc.out.sd;
     711             : 
     712           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
     713             : 
     714             : /*
     715             :  * XXX: The smblsa calls use SMB as their transport - need to get rid of
     716             :  * dependency.
     717             :  */
     718             : /*
     719             :         status = smblsa_sid_check_privilege(cli,
     720             :                                             owner_sid,
     721             :                                             sec_privilege_name(SEC_PRIV_RESTORE));
     722             :         has_restore_privilege = NT_STATUS_IS_OK(status);
     723             :         if (!NT_STATUS_IS_OK(status)) {
     724             :                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
     725             :         }
     726             :         torture_comment(tctx, "SEC_PRIV_RESTORE - %s\n", has_restore_privilege?"Yes":"No");
     727             : 
     728             :         status = smblsa_sid_check_privilege(cli,
     729             :                                             owner_sid,
     730             :                                             sec_privilege_name(SEC_PRIV_TAKE_OWNERSHIP));
     731             :         has_take_ownership_privilege = NT_STATUS_IS_OK(status);
     732             :         if (!NT_STATUS_IS_OK(status)) {
     733             :                 torture_warning(tctx, "smblsa_sid_check_privilege - %s\n", nt_errstr(status));
     734             :         }
     735             :         torture_comment(tctx, "SEC_PRIV_TAKE_OWNERSHIP - %s\n", has_take_ownership_privilege?"Yes":"No");
     736             : */
     737             : 
     738           4 :         sd = security_descriptor_dacl_create(tctx,
     739             :                                         0, NULL, NULL,
     740             :                                         owner_sid,
     741             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
     742             :                                         SEC_FILE_WRITE_DATA,
     743             :                                         0,
     744             :                                         NULL);
     745             : 
     746           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     747           4 :         set.set_secdesc.in.file.handle = handle;
     748           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
     749           4 :         set.set_secdesc.in.sd = sd;
     750             : 
     751           4 :         status = smb2_setinfo_file(tree, &set);
     752           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     753             : 
     754           4 :         expected_bits = SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE;
     755             : 
     756          68 :         for (i=0;i<16;i++) {
     757          64 :                 uint32_t bit = (1<<i);
     758          64 :                 io.in.desired_access = bit;
     759          64 :                 status = smb2_create(tree, tctx, &io);
     760          64 :                 if (expected_bits & bit) {
     761           8 :                         if (!NT_STATUS_IS_OK(status)) {
     762           0 :                                 torture_warning(tctx, "failed with access mask 0x%08x of expected 0x%08x\n",
     763             :                                        bit, expected_bits);
     764             :                         }
     765           8 :                         CHECK_STATUS(status, NT_STATUS_OK);
     766           8 :                         CHECK_ACCESS_FLAGS(io.out.file.handle, bit);
     767           8 :                         smb2_util_close(tree, io.out.file.handle);
     768             :                 } else {
     769          56 :                         if (NT_STATUS_IS_OK(status)) {
     770           0 :                                 torture_warning(tctx, "open succeeded with access mask 0x%08x of "
     771             :                                         "expected 0x%08x - should fail\n",
     772             :                                        bit, expected_bits);
     773             :                         }
     774          56 :                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     775             :                 }
     776             :         }
     777             : 
     778           4 :         torture_comment(tctx, "put back original sd\n");
     779           4 :         set.set_secdesc.in.sd = sd_orig;
     780           4 :         status = smb2_setinfo_file(tree, &set);
     781           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     782             : 
     783           8 : done:
     784           4 :         smb2_util_close(tree, handle);
     785           4 :         smb2_util_unlink(tree, fname);
     786           4 :         smb2_deltree(tree, BASEDIR);
     787           4 :         smb2_tdis(tree);
     788           4 :         smb2_logoff(tree->session);
     789           4 :         return ret;
     790             : }
     791             : 
     792             : 
     793             : 
     794             : /*
     795             :   test the inheritance of ACL flags onto new files and directories
     796             :   Note: This test was copied from raw/acls.c.
     797             : */
     798           4 : static bool test_inheritance(struct torture_context *tctx, struct smb2_tree *tree)
     799             : {
     800             :         NTSTATUS status;
     801             :         struct smb2_create io;
     802           4 :         const char *dname = BASEDIR "\\inheritance";
     803           4 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
     804           4 :         const char *fname2 = BASEDIR "\\inheritance\\testdir";
     805           4 :         bool ret = true;
     806           4 :         struct smb2_handle handle = {{0}};
     807           4 :         struct smb2_handle handle2 = {{0}};
     808             :         int i;
     809             :         union smb_fileinfo q;
     810             :         union smb_setfileinfo set;
     811           4 :         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           4 :         } test_flags[] = {
     819             :                 {
     820             :                         0,
     821             :                         0,
     822             :                         0
     823             :                 },
     824             :                 {
     825             :                         SEC_ACE_FLAG_OBJECT_INHERIT,
     826             :                         0,
     827             :                         SEC_ACE_FLAG_OBJECT_INHERIT |
     828             :                         SEC_ACE_FLAG_INHERIT_ONLY,
     829             :                 },
     830             :                 {
     831             :                         SEC_ACE_FLAG_CONTAINER_INHERIT,
     832             :                         0,
     833             :                         SEC_ACE_FLAG_CONTAINER_INHERIT,
     834             :                 },
     835             :                 {
     836             :                         SEC_ACE_FLAG_OBJECT_INHERIT |
     837             :                         SEC_ACE_FLAG_CONTAINER_INHERIT,
     838             :                         0,
     839             :                         SEC_ACE_FLAG_OBJECT_INHERIT |
     840             :                         SEC_ACE_FLAG_CONTAINER_INHERIT,
     841             :                 },
     842             :                 {
     843             :                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
     844             :                         0,
     845             :                         0,
     846             :                 },
     847             :                 {
     848             :                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
     849             :                         SEC_ACE_FLAG_OBJECT_INHERIT,
     850             :                         0,
     851             :                         0,
     852             :                 },
     853             :                 {
     854             :                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
     855             :                         SEC_ACE_FLAG_CONTAINER_INHERIT,
     856             :                         0,
     857             :                         0,
     858             :                 },
     859             :                 {
     860             :                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
     861             :                         SEC_ACE_FLAG_CONTAINER_INHERIT |
     862             :                         SEC_ACE_FLAG_OBJECT_INHERIT,
     863             :                         0,
     864             :                         0,
     865             :                 },
     866             :                 {
     867             :                         SEC_ACE_FLAG_INHERIT_ONLY,
     868             :                         0,
     869             :                         0,
     870             :                 },
     871             :                 {
     872             :                         SEC_ACE_FLAG_INHERIT_ONLY |
     873             :                         SEC_ACE_FLAG_OBJECT_INHERIT,
     874             :                         0,
     875             :                         SEC_ACE_FLAG_OBJECT_INHERIT |
     876             :                         SEC_ACE_FLAG_INHERIT_ONLY,
     877             :                 },
     878             :                 {
     879             :                         SEC_ACE_FLAG_INHERIT_ONLY |
     880             :                         SEC_ACE_FLAG_CONTAINER_INHERIT,
     881             :                         0,
     882             :                         SEC_ACE_FLAG_CONTAINER_INHERIT,
     883             :                 },
     884             :                 {
     885             :                         SEC_ACE_FLAG_INHERIT_ONLY |
     886             :                         SEC_ACE_FLAG_CONTAINER_INHERIT |
     887             :                         SEC_ACE_FLAG_OBJECT_INHERIT,
     888             :                         0,
     889             :                         SEC_ACE_FLAG_CONTAINER_INHERIT |
     890             :                         SEC_ACE_FLAG_OBJECT_INHERIT,
     891             :                 },
     892             :                 {
     893             :                         SEC_ACE_FLAG_INHERIT_ONLY |
     894             :                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
     895             :                         0,
     896             :                         0,
     897             :                 },
     898             :                 {
     899             :                         SEC_ACE_FLAG_INHERIT_ONLY |
     900             :                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
     901             :                         SEC_ACE_FLAG_OBJECT_INHERIT,
     902             :                         0,
     903             :                         0,
     904             :                 },
     905             :                 {
     906             :                         SEC_ACE_FLAG_INHERIT_ONLY |
     907             :                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
     908             :                         SEC_ACE_FLAG_CONTAINER_INHERIT,
     909             :                         0,
     910             :                         0,
     911             :                 },
     912             :                 {
     913             :                         SEC_ACE_FLAG_INHERIT_ONLY |
     914             :                         SEC_ACE_FLAG_NO_PROPAGATE_INHERIT |
     915             :                         SEC_ACE_FLAG_CONTAINER_INHERIT |
     916             :                         SEC_ACE_FLAG_OBJECT_INHERIT,
     917             :                         0,
     918             :                         0,
     919             :                 }
     920             :         };
     921             : 
     922           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
     923           0 :                 return false;
     924             : 
     925           4 :         torture_comment(tctx, "TESTING ACL INHERITANCE\n");
     926             : 
     927           4 :         ZERO_STRUCT(io);
     928           4 :         io.level = RAW_OPEN_SMB2;
     929           4 :         io.in.create_flags = 0;
     930           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
     931           4 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     932           4 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     933           4 :         io.in.share_access = 0;
     934           4 :         io.in.alloc_size = 0;
     935           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
     936           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
     937           4 :         io.in.security_flags = 0;
     938           4 :         io.in.fname = dname;
     939             : 
     940           4 :         status = smb2_create(tree, tctx, &io);
     941           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     942           4 :         handle = io.out.file.handle;
     943             : 
     944           4 :         torture_comment(tctx, "get the original sd\n");
     945           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     946           4 :         q.query_secdesc.in.file.handle = handle;
     947           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
     948           4 :         status = smb2_getinfo_file(tree, tctx, &q);
     949           4 :         CHECK_STATUS(status, NT_STATUS_OK);
     950           4 :         sd_orig = q.query_secdesc.out.sd;
     951             : 
     952           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
     953             : 
     954           4 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
     955             : 
     956             :         /*
     957             :          * The Windows Default ACL for a new file, when there is no ACL to be
     958             :          * inherited: FullControl for the owner and SYSTEM.
     959             :          */
     960           4 :         sd_def1 = security_descriptor_dacl_create(tctx,
     961             :                                             0, owner_sid, NULL,
     962             :                                             owner_sid,
     963             :                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
     964             :                                             SEC_RIGHTS_FILE_ALL,
     965             :                                             0,
     966             :                                             SID_NT_SYSTEM,
     967             :                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
     968             :                                             SEC_RIGHTS_FILE_ALL,
     969             :                                             0,
     970             :                                             NULL);
     971             : 
     972             :         /*
     973             :          * Use this in the case the system being tested does not add an ACE for
     974             :          * the SYSTEM SID.
     975             :          */
     976           4 :         sd_def2 = security_descriptor_dacl_create(tctx,
     977             :                                             0, owner_sid, NULL,
     978             :                                             owner_sid,
     979             :                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
     980             :                                             SEC_RIGHTS_FILE_ALL,
     981             :                                             0,
     982             :                                             NULL);
     983             : 
     984           4 :         creator_owner = dom_sid_parse_talloc(tctx, SID_CREATOR_OWNER);
     985             : 
     986          68 :         for (i=0;i<ARRAY_SIZE(test_flags);i++) {
     987          64 :                 sd = security_descriptor_dacl_create(tctx,
     988             :                                                 0, NULL, NULL,
     989             :                                                 SID_CREATOR_OWNER,
     990             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     991             :                                                 SEC_FILE_WRITE_DATA,
     992             :                                                 test_flags[i].parent_flags,
     993             :                                                 SID_WORLD,
     994             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     995             :                                                 SEC_FILE_ALL | SEC_STD_ALL,
     996             :                                                 0,
     997             :                                                 NULL);
     998          64 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
     999          64 :                 set.set_secdesc.in.file.handle = handle;
    1000          64 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1001          64 :                 set.set_secdesc.in.sd = sd;
    1002          64 :                 status = smb2_setinfo_file(tree, &set);
    1003          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1004             : 
    1005          64 :                 io.in.fname = fname1;
    1006          64 :                 io.in.create_options = 0;
    1007          64 :                 status = smb2_create(tree, tctx, &io);
    1008          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1009          64 :                 handle2 = io.out.file.handle;
    1010             : 
    1011          64 :                 q.query_secdesc.in.file.handle = handle2;
    1012          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1013          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1014             : 
    1015          64 :                 smb2_util_close(tree, handle2);
    1016          64 :                 smb2_util_unlink(tree, fname1);
    1017             : 
    1018          64 :                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
    1019          64 :                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
    1020          32 :                             !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
    1021          32 :                                 torture_warning(tctx, "Expected default sd:\n");
    1022          32 :                                 NDR_PRINT_DEBUG(security_descriptor, sd_def1);
    1023          32 :                                 torture_warning(tctx, "at %d - got:\n", i);
    1024          32 :                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1025             :                         }
    1026          32 :                         goto check_dir;
    1027             :                 }
    1028             : 
    1029          64 :                 if (q.query_secdesc.out.sd->dacl == NULL ||
    1030          64 :                     q.query_secdesc.out.sd->dacl->num_aces != 1 ||
    1031          64 :                     q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1032          32 :                     !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1033          32 :                                    sd_orig->owner_sid)) {
    1034           0 :                         torture_warning(tctx, "Bad sd in child file at %d\n", i);
    1035           0 :                         NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1036           0 :                         ret = false;
    1037           0 :                         goto check_dir;
    1038             :                 }
    1039             : 
    1040          64 :                 if (q.query_secdesc.out.sd->dacl->aces[0].flags !=
    1041          32 :                     test_flags[i].file_flags) {
    1042           0 :                         torture_warning(tctx, "incorrect file_flags 0x%x - expected 0x%x for parent 0x%x with (i=%d)\n",
    1043           0 :                                q.query_secdesc.out.sd->dacl->aces[0].flags,
    1044             :                                test_flags[i].file_flags,
    1045             :                                test_flags[i].parent_flags,
    1046             :                                i);
    1047           0 :                         ret = false;
    1048             :                 }
    1049             : 
    1050          96 :         check_dir:
    1051          64 :                 io.in.fname = fname2;
    1052          64 :                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1053          64 :                 status = smb2_create(tree, tctx, &io);
    1054          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1055          64 :                 handle2 = io.out.file.handle;
    1056             : 
    1057          64 :                 q.query_secdesc.in.file.handle = handle2;
    1058          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1059          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1060             : 
    1061          64 :                 smb2_util_close(tree, handle2);
    1062          64 :                 smb2_util_rmdir(tree, fname2);
    1063             : 
    1064          96 :                 if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
    1065          48 :                     (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
    1066          16 :                      (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
    1067          48 :                         if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def1) &&
    1068          24 :                             !security_descriptor_equal(q.query_secdesc.out.sd, sd_def2)) {
    1069          24 :                                 torture_warning(tctx, "Expected default sd for dir at %d:\n", i);
    1070          24 :                                 NDR_PRINT_DEBUG(security_descriptor, sd_def1);
    1071          24 :                                 torture_warning(tctx, "got:\n");
    1072          24 :                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1073             :                         }
    1074          24 :                         continue;
    1075             :                 }
    1076             : 
    1077          72 :                 if ((test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) &&
    1078          32 :                     (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
    1079          48 :                         if (q.query_secdesc.out.sd->dacl == NULL ||
    1080          32 :                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
    1081          32 :                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1082          16 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1083          32 :                                            sd_orig->owner_sid) ||
    1084          16 :                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
    1085           0 :                                 torture_warning(tctx, "(CI & NP) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
    1086             :                                        test_flags[i].dir_flags,
    1087             :                                        test_flags[i].parent_flags, i);
    1088           0 :                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1089           0 :                                 torture_warning(tctx, "FYI, here is the parent sd:\n");
    1090           0 :                                 NDR_PRINT_DEBUG(security_descriptor, sd);
    1091           0 :                                 ret = false;
    1092           0 :                                 continue;
    1093             :                         }
    1094          24 :                 } else if (test_flags[i].parent_flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
    1095          32 :                         if (q.query_secdesc.out.sd->dacl == NULL ||
    1096          32 :                             q.query_secdesc.out.sd->dacl->num_aces != 2 ||
    1097          32 :                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1098          16 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1099          32 :                                            sd_orig->owner_sid) ||
    1100          32 :                             q.query_secdesc.out.sd->dacl->aces[1].access_mask != SEC_FILE_WRITE_DATA ||
    1101          16 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[1].trustee,
    1102          16 :                                            creator_owner) ||
    1103          32 :                             q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
    1104          16 :                             q.query_secdesc.out.sd->dacl->aces[1].flags !=
    1105          16 :                             (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
    1106           0 :                                 torture_warning(tctx, "(CI) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
    1107             :                                        test_flags[i].dir_flags,
    1108             :                                        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          16 :                         if (q.query_secdesc.out.sd->dacl == NULL ||
    1117          16 :                             q.query_secdesc.out.sd->dacl->num_aces != 1 ||
    1118          16 :                             q.query_secdesc.out.sd->dacl->aces[0].access_mask != SEC_FILE_WRITE_DATA ||
    1119           8 :                             !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
    1120           8 :                                            creator_owner) ||
    1121           8 :                             q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
    1122           0 :                                 torture_warning(tctx, "(0) Bad sd in child dir - expected 0x%x for parent 0x%x (i=%d)\n",
    1123             :                                        test_flags[i].dir_flags,
    1124             :                                        test_flags[i].parent_flags, i);
    1125           0 :                                 NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
    1126           0 :                                 torture_warning(tctx, "FYI, here is the parent sd:\n");
    1127           0 :                                 NDR_PRINT_DEBUG(security_descriptor, sd);
    1128           0 :                                 ret = false;
    1129           0 :                                 continue;
    1130             :                         }
    1131             :                 }
    1132             :         }
    1133             : 
    1134           4 :         torture_comment(tctx, "Testing access checks on inherited create with %s\n", fname1);
    1135           4 :         sd = security_descriptor_dacl_create(tctx,
    1136             :                                         0, NULL, NULL,
    1137             :                                         owner_sid,
    1138             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    1139             :                                         SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
    1140             :                                         SEC_ACE_FLAG_OBJECT_INHERIT,
    1141             :                                         SID_WORLD,
    1142             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    1143             :                                         SEC_FILE_ALL | SEC_STD_ALL,
    1144             :                                         0,
    1145             :                                         NULL);
    1146           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1147           4 :         set.set_secdesc.in.file.handle = handle;
    1148           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1149           4 :         set.set_secdesc.in.sd = sd;
    1150           4 :         status = smb2_setinfo_file(tree, &set);
    1151           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1152             : 
    1153             :         /* Check DACL we just set. */
    1154           4 :         torture_comment(tctx, "checking new sd\n");
    1155           4 :         q.query_secdesc.in.file.handle = handle;
    1156           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
    1157           4 :         status = smb2_getinfo_file(tree, tctx, &q);
    1158           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1159           4 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
    1160             : 
    1161           4 :         io.in.fname = fname1;
    1162           4 :         io.in.create_options = 0;
    1163           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1164           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1165           4 :         status = smb2_create(tree, tctx, &io);
    1166           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1167           4 :         handle2 = io.out.file.handle;
    1168           4 :         CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
    1169             : 
    1170           4 :         q.query_secdesc.in.file.handle = handle2;
    1171           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1172           4 :         status = smb2_getinfo_file(tree, tctx, &q);
    1173           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1174           4 :         smb2_util_close(tree, handle2);
    1175             : 
    1176           4 :         sd2 = security_descriptor_dacl_create(tctx,
    1177             :                                          0, owner_sid, NULL,
    1178             :                                          owner_sid,
    1179             :                                          SEC_ACE_TYPE_ACCESS_ALLOWED,
    1180             :                                          SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
    1181             :                                          0,
    1182             :                                          NULL);
    1183           4 :         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1184             : 
    1185           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1186           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1187           4 :         status = smb2_create(tree, tctx, &io);
    1188           4 :         if (NT_STATUS_IS_OK(status)) {
    1189           0 :                 torture_warning(tctx, "failed: w2k3 ACL bug (allowed open when ACL should deny)\n");
    1190           0 :                 ret = false;
    1191           0 :                 handle2 = io.out.file.handle;
    1192           0 :                 CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
    1193           0 :                 smb2_util_close(tree, handle2);
    1194             :         } else {
    1195           4 :                 if (torture_setting_bool(tctx, "hide_on_access_denied",
    1196             :                                          false)) {
    1197           0 :                         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1198             :                 } else {
    1199           4 :                         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1200             :                 }
    1201             :         }
    1202             : 
    1203           4 :         torture_comment(tctx, "trying without execute\n");
    1204           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1205           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE;
    1206           4 :         status = smb2_create(tree, tctx, &io);
    1207           4 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1208           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1209             :         } else {
    1210           4 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1211             :         }
    1212             : 
    1213           4 :         torture_comment(tctx, "and with full permissions again\n");
    1214           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1215           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1216           4 :         status = smb2_create(tree, tctx, &io);
    1217           4 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1218           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1219             :         } else {
    1220           4 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1221             :         }
    1222             : 
    1223           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1224           4 :         status = smb2_create(tree, tctx, &io);
    1225           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1226           4 :         handle2 = io.out.file.handle;
    1227           4 :         CHECK_ACCESS_FLAGS(handle2, SEC_FILE_WRITE_DATA);
    1228           4 :         smb2_util_close(tree, handle2);
    1229             : 
    1230           4 :         torture_comment(tctx, "put back original sd\n");
    1231           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1232           4 :         set.set_secdesc.in.file.handle = handle;
    1233           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1234           4 :         set.set_secdesc.in.sd = sd_orig;
    1235           4 :         status = smb2_setinfo_file(tree, &set);
    1236           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1237             : 
    1238           4 :         smb2_util_close(tree, handle);
    1239             : 
    1240           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1241           4 :         status = smb2_create(tree, tctx, &io);
    1242           4 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1243           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1244             :         } else {
    1245           4 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1246             :         }
    1247             : 
    1248           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1249           4 :         status = smb2_create(tree, tctx, &io);
    1250           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1251           4 :         handle2 = io.out.file.handle;
    1252           4 :         CHECK_ACCESS_FLAGS(handle2, SEC_FILE_WRITE_DATA);
    1253           4 :         smb2_util_close(tree, handle2);
    1254             : 
    1255           4 :         smb2_util_unlink(tree, fname1);
    1256           4 :         smb2_util_rmdir(tree, dname);
    1257             : 
    1258           4 : done:
    1259           4 :         if (sd_orig != NULL) {
    1260           4 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1261           4 :                 set.set_secdesc.in.file.handle = handle;
    1262           4 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1263           4 :                 set.set_secdesc.in.sd = sd_orig;
    1264           4 :                 status = smb2_setinfo_file(tree, &set);
    1265             :         }
    1266             : 
    1267           4 :         smb2_util_close(tree, handle);
    1268           4 :         smb2_deltree(tree, BASEDIR);
    1269           4 :         smb2_tdis(tree);
    1270           4 :         smb2_logoff(tree->session);
    1271           4 :         return ret;
    1272             : }
    1273             : 
    1274           4 : static bool test_inheritance_flags(struct torture_context *tctx,
    1275             :     struct smb2_tree *tree)
    1276             : {
    1277             :         NTSTATUS status;
    1278             :         struct smb2_create io;
    1279           4 :         const char *dname = BASEDIR "\\inheritance";
    1280           4 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
    1281           4 :         bool ret = true;
    1282           4 :         struct smb2_handle handle = {{0}};
    1283           4 :         struct smb2_handle handle2 = {{0}};
    1284             :         int i, j;
    1285             :         union smb_fileinfo q;
    1286             :         union smb_setfileinfo set;
    1287           4 :         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           4 :         } tflags[16] = {{0}}; /* 2^4 */
    1297             : 
    1298          64 :         for (i = 0; i < 15; i++) {
    1299          60 :                 torture_comment(tctx, "i=%d:", i);
    1300             : 
    1301          60 :                 if (i & 1) {
    1302          28 :                         tflags[i].parent_set_sd_type |=
    1303             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1304          28 :                         torture_comment(tctx, "AUTO_INHERITED, ");
    1305             :                 }
    1306          60 :                 if (i & 2) {
    1307          28 :                         tflags[i].parent_set_sd_type |=
    1308             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1309          28 :                         torture_comment(tctx, "AUTO_INHERIT_REQ, ");
    1310             :                 }
    1311          60 :                 if (i & 4) {
    1312          28 :                         tflags[i].parent_set_sd_type |=
    1313             :                             SEC_DESC_DACL_PROTECTED;
    1314          28 :                         torture_comment(tctx, "PROTECTED, ");
    1315          28 :                         tflags[i].parent_get_sd_type |=
    1316             :                             SEC_DESC_DACL_PROTECTED;
    1317             :                 }
    1318          60 :                 if (i & 8) {
    1319          28 :                         tflags[i].parent_set_ace_inherit |=
    1320             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1321          28 :                         torture_comment(tctx, "INHERITED, ");
    1322          28 :                         tflags[i].parent_get_ace_inherit |=
    1323             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1324             :                 }
    1325             : 
    1326          60 :                 if ((tflags[i].parent_set_sd_type &
    1327             :                     (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) ==
    1328             :                     (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) {
    1329          12 :                         tflags[i].parent_get_sd_type |=
    1330             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1331          12 :                         tflags[i].child_get_sd_type |=
    1332             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1333          12 :                         tflags[i].child_get_ace_inherit |=
    1334             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1335          12 :                         torture_comment(tctx, "  ... parent is AUTO INHERITED");
    1336             :                 }
    1337             : 
    1338          60 :                 if (tflags[i].parent_set_ace_inherit &
    1339             :                     SEC_ACE_FLAG_INHERITED_ACE) {
    1340          28 :                         tflags[i].parent_get_ace_inherit =
    1341             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1342          28 :                         torture_comment(tctx, "  ... parent ACE is INHERITED");
    1343             :                 }
    1344             : 
    1345          60 :                 torture_comment(tctx, "\n");
    1346             :         }
    1347             : 
    1348           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
    1349           0 :                 return false;
    1350             : 
    1351           4 :         torture_comment(tctx, "TESTING ACL INHERITANCE FLAGS\n");
    1352             : 
    1353           4 :         ZERO_STRUCT(io);
    1354           4 :         io.level = RAW_OPEN_SMB2;
    1355           4 :         io.in.create_flags = 0;
    1356           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1357           4 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1358           4 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    1359           4 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    1360           4 :         io.in.alloc_size = 0;
    1361           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1362           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1363           4 :         io.in.security_flags = 0;
    1364           4 :         io.in.fname = dname;
    1365             : 
    1366           4 :         torture_comment(tctx, "creating initial directory %s\n", dname);
    1367           4 :         status = smb2_create(tree, tctx, &io);
    1368           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1369           4 :         handle = io.out.file.handle;
    1370             : 
    1371           4 :         torture_comment(tctx, "getting original sd\n");
    1372           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1373           4 :         q.query_secdesc.in.file.handle = handle;
    1374           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1375           4 :         status = smb2_getinfo_file(tree, tctx, &q);
    1376           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1377           4 :         sd_orig = q.query_secdesc.out.sd;
    1378             : 
    1379           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    1380           4 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
    1381             : 
    1382          68 :         for (i=0; i < ARRAY_SIZE(tflags); i++) {
    1383          64 :                 torture_comment(tctx, "setting a new sd on directory, pass #%d\n", i);
    1384             : 
    1385         128 :                 sd = security_descriptor_dacl_create(tctx,
    1386          64 :                                                 tflags[i].parent_set_sd_type,
    1387             :                                                 NULL, NULL,
    1388             :                                                 owner_sid,
    1389             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
    1390             :                                                 SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
    1391             :                                                 SEC_ACE_FLAG_OBJECT_INHERIT |
    1392             :                                                 SEC_ACE_FLAG_CONTAINER_INHERIT |
    1393          64 :                                                 tflags[i].parent_set_ace_inherit,
    1394             :                                                 SID_WORLD,
    1395             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
    1396             :                                                 SEC_FILE_ALL | SEC_STD_ALL,
    1397             :                                                 0,
    1398             :                                                 NULL);
    1399          64 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1400          64 :                 set.set_secdesc.in.file.handle = handle;
    1401          64 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1402          64 :                 set.set_secdesc.in.sd = sd;
    1403          64 :                 status = smb2_setinfo_file(tree, &set);
    1404          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1405             : 
    1406             :                 /*
    1407             :                  * Check DACL we just set, except change the bits to what they
    1408             :                  * should be.
    1409             :                  */
    1410          64 :                 torture_comment(tctx, "  checking new sd\n");
    1411             : 
    1412             :                 /* REQ bit should always be false. */
    1413          64 :                 sd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1414             : 
    1415          64 :                 if ((tflags[i].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1416          52 :                         sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1417             : 
    1418          64 :                 q.query_secdesc.in.file.handle = handle;
    1419          64 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
    1420          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1421          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1422          64 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
    1423             : 
    1424             :                 /* Create file. */
    1425          64 :                 torture_comment(tctx, "  creating file %s\n", fname1);
    1426          64 :                 io.in.fname = fname1;
    1427          64 :                 io.in.create_options = 0;
    1428          64 :                 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1429          64 :                 io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1430          64 :                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1431          64 :                 status = smb2_create(tree, tctx, &io);
    1432          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1433          64 :                 handle2 = io.out.file.handle;
    1434          64 :                 CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
    1435             : 
    1436          64 :                 q.query_secdesc.in.file.handle = handle2;
    1437          64 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1438          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1439          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1440             : 
    1441          64 :                 torture_comment(tctx, "  checking sd on file %s\n", fname1);
    1442         128 :                 sd2 = security_descriptor_dacl_create(tctx,
    1443          64 :                                                  tflags[i].child_get_sd_type,
    1444             :                                                  owner_sid, NULL,
    1445             :                                                  owner_sid,
    1446             :                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
    1447             :                                                  SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
    1448             :                                                  tflags[i].child_get_ace_inherit,
    1449             :                                                  NULL);
    1450          64 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1451             : 
    1452             :                 /*
    1453             :                  * Set new sd on file ... prove that the bits have nothing to
    1454             :                  * do with the parents bits when manually setting an ACL. The
    1455             :                  * _AUTO_INHERITED bit comes directly from the ACL set.
    1456             :                  */
    1457        1088 :                 for (j = 0; j < ARRAY_SIZE(tflags); j++) {
    1458        1024 :                         torture_comment(tctx, "  setting new file sd, pass #%d\n", j);
    1459             : 
    1460             :                         /* Change sd type. */
    1461        1024 :                         sd2->type &= ~(SEC_DESC_DACL_AUTO_INHERITED |
    1462             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ |
    1463             :                             SEC_DESC_DACL_PROTECTED);
    1464        1024 :                         sd2->type |= tflags[j].parent_set_sd_type;
    1465             : 
    1466        1024 :                         sd2->dacl->aces[0].flags &=
    1467             :                             ~SEC_ACE_FLAG_INHERITED_ACE;
    1468        2048 :                         sd2->dacl->aces[0].flags |=
    1469        1024 :                             tflags[j].parent_set_ace_inherit;
    1470             : 
    1471        1024 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1472        1024 :                         set.set_secdesc.in.file.handle = handle2;
    1473        1024 :                         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1474        1024 :                         set.set_secdesc.in.sd = sd2;
    1475        1024 :                         status = smb2_setinfo_file(tree, &set);
    1476        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1477             : 
    1478             :                         /* Check DACL we just set. */
    1479        1024 :                         sd2->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1480        1024 :                         if ((tflags[j].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1481         832 :                                 sd2->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1482             : 
    1483        1024 :                         q.query_secdesc.in.file.handle = handle2;
    1484        1024 :                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1485        1024 :                         status = smb2_getinfo_file(tree, tctx, &q);
    1486        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1487             : 
    1488        1024 :                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1489             :                 }
    1490             : 
    1491          64 :                 smb2_util_close(tree, handle2);
    1492          64 :                 smb2_util_unlink(tree, fname1);
    1493             :         }
    1494             : 
    1495           4 : done:
    1496           4 :         smb2_util_close(tree, handle);
    1497           4 :         smb2_deltree(tree, BASEDIR);
    1498           4 :         smb2_tdis(tree);
    1499           4 :         smb2_logoff(tree->session);
    1500           4 :         return ret;
    1501             : }
    1502             : 
    1503             : /*
    1504             :  * This is basically a copy of test_inheritance_flags() with an additional twist
    1505             :  * to change the owner of the testfile, verifying that the security descriptor
    1506             :  * flags are not altered.
    1507             :  */
    1508           4 : static bool test_sd_flags_vs_chown(struct torture_context *tctx,
    1509             :                                    struct smb2_tree *tree)
    1510             : {
    1511             :         NTSTATUS status;
    1512             :         struct smb2_create io;
    1513           4 :         const char *dname = BASEDIR "\\inheritance";
    1514           4 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
    1515           4 :         bool ret = true;
    1516           4 :         struct smb2_handle handle = {{0}};
    1517           4 :         struct smb2_handle handle2 = {{0}};
    1518             :         int i, j;
    1519             :         union smb_fileinfo q;
    1520             :         union smb_setfileinfo set;
    1521           4 :         struct security_descriptor *sd, *sd2, *sd_orig=NULL;
    1522           4 :         struct security_descriptor *owner_sd = NULL;
    1523           4 :         const char *owner_sid_string = NULL;
    1524           4 :         struct dom_sid *owner_sid = NULL;
    1525           4 :         struct dom_sid world_sid = global_sid_World;
    1526             :         struct {
    1527             :                 uint32_t parent_set_sd_type; /* 3 options */
    1528             :                 uint32_t parent_set_ace_inherit; /* 1 option */
    1529             :                 uint32_t parent_get_sd_type;
    1530             :                 uint32_t parent_get_ace_inherit;
    1531             :                 uint32_t child_get_sd_type;
    1532             :                 uint32_t child_get_ace_inherit;
    1533           4 :         } tflags[16] = {{0}}; /* 2^4 */
    1534             : 
    1535           4 :         owner_sd = security_descriptor_dacl_create(tctx,
    1536             :                                                    0,
    1537             :                                                    SID_WORLD,
    1538             :                                                    NULL,
    1539             :                                                    NULL);
    1540           4 :         torture_assert_not_null_goto(tctx, owner_sd, ret, done,
    1541             :                                      "security_descriptor_dacl_create failed\n");
    1542             : 
    1543          64 :         for (i = 0; i < 15; i++) {
    1544          60 :                 torture_comment(tctx, "i=%d:", i);
    1545             : 
    1546          60 :                 if (i & 1) {
    1547          28 :                         tflags[i].parent_set_sd_type |=
    1548             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1549          28 :                         torture_comment(tctx, "AUTO_INHERITED, ");
    1550             :                 }
    1551          60 :                 if (i & 2) {
    1552          28 :                         tflags[i].parent_set_sd_type |=
    1553             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1554          28 :                         torture_comment(tctx, "AUTO_INHERIT_REQ, ");
    1555             :                 }
    1556          60 :                 if (i & 4) {
    1557          28 :                         tflags[i].parent_set_sd_type |=
    1558             :                             SEC_DESC_DACL_PROTECTED;
    1559          28 :                         torture_comment(tctx, "PROTECTED, ");
    1560          28 :                         tflags[i].parent_get_sd_type |=
    1561             :                             SEC_DESC_DACL_PROTECTED;
    1562             :                 }
    1563          60 :                 if (i & 8) {
    1564          28 :                         tflags[i].parent_set_ace_inherit |=
    1565             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1566          28 :                         torture_comment(tctx, "INHERITED, ");
    1567          28 :                         tflags[i].parent_get_ace_inherit |=
    1568             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1569             :                 }
    1570             : 
    1571          60 :                 if ((tflags[i].parent_set_sd_type &
    1572             :                     (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) ==
    1573             :                     (SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ)) {
    1574          12 :                         tflags[i].parent_get_sd_type |=
    1575             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1576          12 :                         tflags[i].child_get_sd_type |=
    1577             :                             SEC_DESC_DACL_AUTO_INHERITED;
    1578          12 :                         tflags[i].child_get_ace_inherit |=
    1579             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1580          12 :                         torture_comment(tctx, "  ... parent is AUTO INHERITED");
    1581             :                 }
    1582             : 
    1583          60 :                 if (tflags[i].parent_set_ace_inherit &
    1584             :                     SEC_ACE_FLAG_INHERITED_ACE) {
    1585          28 :                         tflags[i].parent_get_ace_inherit =
    1586             :                             SEC_ACE_FLAG_INHERITED_ACE;
    1587          28 :                         torture_comment(tctx, "  ... parent ACE is INHERITED");
    1588             :                 }
    1589             : 
    1590          60 :                 torture_comment(tctx, "\n");
    1591             :         }
    1592             : 
    1593           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
    1594           0 :                 return false;
    1595             : 
    1596           4 :         torture_comment(tctx, "TESTING ACL INHERITANCE FLAGS\n");
    1597             : 
    1598           4 :         ZERO_STRUCT(io);
    1599           4 :         io.level = RAW_OPEN_SMB2;
    1600           4 :         io.in.create_flags = 0;
    1601           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1602           4 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1603           4 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    1604           4 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    1605           4 :         io.in.alloc_size = 0;
    1606           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1607           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1608           4 :         io.in.security_flags = 0;
    1609           4 :         io.in.fname = dname;
    1610             : 
    1611           4 :         torture_comment(tctx, "creating initial directory %s\n", dname);
    1612           4 :         status = smb2_create(tree, tctx, &io);
    1613           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1614           4 :         handle = io.out.file.handle;
    1615             : 
    1616           4 :         torture_comment(tctx, "getting original sd\n");
    1617           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1618           4 :         q.query_secdesc.in.file.handle = handle;
    1619           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1620           4 :         status = smb2_getinfo_file(tree, tctx, &q);
    1621           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1622           4 :         sd_orig = q.query_secdesc.out.sd;
    1623             : 
    1624           4 :         owner_sid = sd_orig->owner_sid;
    1625           4 :         owner_sid_string = dom_sid_string(tctx, sd_orig->owner_sid);
    1626           4 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid_string);
    1627             : 
    1628          68 :         for (i=0; i < ARRAY_SIZE(tflags); i++) {
    1629          64 :                 torture_comment(tctx, "setting a new sd on directory, pass #%d\n", i);
    1630             : 
    1631         128 :                 sd = security_descriptor_dacl_create(tctx,
    1632          64 :                                                 tflags[i].parent_set_sd_type,
    1633             :                                                 NULL, NULL,
    1634             :                                                 owner_sid_string,
    1635             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
    1636             :                                                 SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
    1637             :                                                 SEC_ACE_FLAG_OBJECT_INHERIT |
    1638             :                                                 SEC_ACE_FLAG_CONTAINER_INHERIT |
    1639          64 :                                                 tflags[i].parent_set_ace_inherit,
    1640             :                                                 SID_WORLD,
    1641             :                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
    1642             :                                                 SEC_FILE_ALL | SEC_STD_ALL,
    1643             :                                                 0,
    1644             :                                                 NULL);
    1645          64 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1646          64 :                 set.set_secdesc.in.file.handle = handle;
    1647          64 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1648          64 :                 set.set_secdesc.in.sd = sd;
    1649          64 :                 status = smb2_setinfo_file(tree, &set);
    1650          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1651             : 
    1652             :                 /*
    1653             :                  * Check DACL we just set, except change the bits to what they
    1654             :                  * should be.
    1655             :                  */
    1656          64 :                 torture_comment(tctx, "  checking new sd\n");
    1657             : 
    1658             :                 /* REQ bit should always be false. */
    1659          64 :                 sd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1660             : 
    1661          64 :                 if ((tflags[i].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1662          52 :                         sd->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1663             : 
    1664          64 :                 q.query_secdesc.in.file.handle = handle;
    1665          64 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL;
    1666          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1667          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1668          64 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd);
    1669             : 
    1670             :                 /* Create file. */
    1671          64 :                 torture_comment(tctx, "  creating file %s\n", fname1);
    1672          64 :                 io.in.fname = fname1;
    1673          64 :                 io.in.create_options = 0;
    1674          64 :                 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1675          64 :                 io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1676          64 :                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1677          64 :                 status = smb2_create(tree, tctx, &io);
    1678          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1679          64 :                 handle2 = io.out.file.handle;
    1680          64 :                 CHECK_ACCESS_FLAGS(handle2, SEC_RIGHTS_FILE_ALL);
    1681             : 
    1682          64 :                 q.query_secdesc.in.file.handle = handle2;
    1683          64 :                 q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1684          64 :                 status = smb2_getinfo_file(tree, tctx, &q);
    1685          64 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1686             : 
    1687          64 :                 torture_comment(tctx, "  checking sd on file %s\n", fname1);
    1688         128 :                 sd2 = security_descriptor_dacl_create(tctx,
    1689          64 :                                                  tflags[i].child_get_sd_type,
    1690             :                                                  owner_sid_string, NULL,
    1691             :                                                  owner_sid_string,
    1692             :                                                  SEC_ACE_TYPE_ACCESS_ALLOWED,
    1693             :                                                  SEC_FILE_WRITE_DATA | SEC_STD_WRITE_DAC,
    1694             :                                                  tflags[i].child_get_ace_inherit,
    1695             :                                                  NULL);
    1696          64 :                 CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1697             : 
    1698             :                 /*
    1699             :                  * Set new sd on file ... prove that the bits have nothing to
    1700             :                  * do with the parents bits when manually setting an ACL. The
    1701             :                  * _AUTO_INHERITED bit comes directly from the ACL set.
    1702             :                  */
    1703        1088 :                 for (j = 0; j < ARRAY_SIZE(tflags); j++) {
    1704        1024 :                         torture_comment(tctx, "  setting new file sd, pass #%d\n", j);
    1705             : 
    1706             :                         /* Change sd type. */
    1707        1024 :                         sd2->type &= ~(SEC_DESC_DACL_AUTO_INHERITED |
    1708             :                             SEC_DESC_DACL_AUTO_INHERIT_REQ |
    1709             :                             SEC_DESC_DACL_PROTECTED);
    1710        1024 :                         sd2->type |= tflags[j].parent_set_sd_type;
    1711             : 
    1712        1024 :                         sd2->dacl->aces[0].flags &=
    1713             :                             ~SEC_ACE_FLAG_INHERITED_ACE;
    1714        2048 :                         sd2->dacl->aces[0].flags |=
    1715        1024 :                             tflags[j].parent_set_ace_inherit;
    1716             : 
    1717        1024 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1718        1024 :                         set.set_secdesc.in.file.handle = handle2;
    1719        1024 :                         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1720        1024 :                         set.set_secdesc.in.sd = sd2;
    1721        1024 :                         status = smb2_setinfo_file(tree, &set);
    1722        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1723             : 
    1724             :                         /* Check DACL we just set. */
    1725        1024 :                         sd2->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1726        1024 :                         if ((tflags[j].parent_get_sd_type & SEC_DESC_DACL_AUTO_INHERITED) == 0)
    1727         832 :                                 sd2->type &= ~SEC_DESC_DACL_AUTO_INHERITED;
    1728             : 
    1729        1024 :                         q.query_secdesc.in.file.handle = handle2;
    1730        1024 :                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1731        1024 :                         status = smb2_getinfo_file(tree, tctx, &q);
    1732        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1733             : 
    1734        1024 :                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1735             : 
    1736             :                         /*
    1737             :                          * Check that changing 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        1024 :                         owner_sd->owner_sid = &world_sid;
    1744        1024 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1745        1024 :                         set.set_secdesc.in.file.handle = handle2;
    1746        1024 :                         set.set_secdesc.in.secinfo_flags = SECINFO_OWNER;
    1747        1024 :                         set.set_secdesc.in.sd = owner_sd;
    1748        1024 :                         status = smb2_setinfo_file(tree, &set);
    1749        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1750             : 
    1751        1024 :                         owner_sd->owner_sid = owner_sid;
    1752        1024 :                         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1753        1024 :                         set.set_secdesc.in.file.handle = handle2;
    1754        1024 :                         set.set_secdesc.in.secinfo_flags = SECINFO_OWNER;
    1755        1024 :                         set.set_secdesc.in.sd = owner_sd;
    1756        1024 :                         status = smb2_setinfo_file(tree, &set);
    1757        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1758             : 
    1759        1024 :                         q.query_secdesc.in.file.handle = handle2;
    1760        1024 :                         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1761        1024 :                         status = smb2_getinfo_file(tree, tctx, &q);
    1762        1024 :                         CHECK_STATUS(status, NT_STATUS_OK);
    1763             : 
    1764        1024 :                         CHECK_SECURITY_DESCRIPTOR(q.query_secdesc.out.sd, sd2);
    1765        1024 :                         torture_assert_goto(tctx, ret, ret, done, "CHECK_SECURITY_DESCRIPTOR failed\n");
    1766             :                 }
    1767             : 
    1768          64 :                 smb2_util_close(tree, handle2);
    1769          64 :                 smb2_util_unlink(tree, fname1);
    1770             :         }
    1771             : 
    1772           4 : done:
    1773           4 :         smb2_util_close(tree, handle);
    1774           4 :         smb2_deltree(tree, BASEDIR);
    1775           4 :         smb2_tdis(tree);
    1776           4 :         smb2_logoff(tree->session);
    1777           4 :         return ret;
    1778             : }
    1779             : 
    1780             : /*
    1781             :   test dynamic acl inheritance
    1782             :   Note: This test was copied from raw/acls.c.
    1783             : */
    1784           4 : static bool test_inheritance_dynamic(struct torture_context *tctx,
    1785             :     struct smb2_tree *tree)
    1786             : {
    1787             :         NTSTATUS status;
    1788             :         struct smb2_create io;
    1789           4 :         const char *dname = BASEDIR "\\inheritance";
    1790           4 :         const char *fname1 = BASEDIR "\\inheritance\\testfile";
    1791           4 :         bool ret = true;
    1792           4 :         struct smb2_handle handle = {{0}};
    1793           4 :         struct smb2_handle handle2 = {{0}};
    1794             :         union smb_fileinfo q;
    1795             :         union smb_setfileinfo set;
    1796           4 :         struct security_descriptor *sd, *sd_orig=NULL;
    1797             :         const char *owner_sid;
    1798             : 
    1799           4 :         torture_comment(tctx, "TESTING DYNAMIC ACL INHERITANCE\n");
    1800             : 
    1801           4 :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
    1802           0 :                 return false;
    1803             : 
    1804           4 :         ZERO_STRUCT(io);
    1805           4 :         io.level = RAW_OPEN_SMB2;
    1806           4 :         io.in.create_flags = 0;
    1807           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1808           4 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1809           4 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    1810           4 :         io.in.share_access = 0;
    1811           4 :         io.in.alloc_size = 0;
    1812           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1813           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1814           4 :         io.in.security_flags = 0;
    1815           4 :         io.in.fname = dname;
    1816             : 
    1817           4 :         status = smb2_create(tree, tctx, &io);
    1818           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1819           4 :         handle = io.out.file.handle;
    1820             : 
    1821           4 :         torture_comment(tctx, "get the original sd\n");
    1822           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1823           4 :         q.query_secdesc.in.file.handle = handle;
    1824           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    1825           4 :         status = smb2_getinfo_file(tree, tctx, &q);
    1826           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1827           4 :         sd_orig = q.query_secdesc.out.sd;
    1828             : 
    1829           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    1830             : 
    1831           4 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
    1832             : 
    1833           4 :         sd = security_descriptor_dacl_create(tctx,
    1834             :                                         0, NULL, NULL,
    1835             :                                         owner_sid,
    1836             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    1837             :                                         SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE,
    1838             :                                         SEC_ACE_FLAG_OBJECT_INHERIT,
    1839             :                                         NULL);
    1840           4 :         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1841             : 
    1842           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1843           4 :         set.set_secdesc.in.file.handle = handle;
    1844           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1845           4 :         set.set_secdesc.in.sd = sd;
    1846           4 :         status = smb2_setinfo_file(tree, &set);
    1847           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1848             : 
    1849           4 :         torture_comment(tctx, "create a file with an inherited acl\n");
    1850           4 :         io.in.fname = fname1;
    1851           4 :         io.in.create_options = 0;
    1852           4 :         io.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
    1853           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1854           4 :         status = smb2_create(tree, tctx, &io);
    1855           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1856           4 :         handle2 = io.out.file.handle;
    1857           4 :         smb2_util_close(tree, handle2);
    1858             : 
    1859           4 :         torture_comment(tctx, "try and access file with base rights - should be OK\n");
    1860           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1861           4 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1862           4 :         status = smb2_create(tree, tctx, &io);
    1863           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1864           4 :         handle2 = io.out.file.handle;
    1865           4 :         smb2_util_close(tree, handle2);
    1866             : 
    1867           4 :         torture_comment(tctx, "try and access file with extra rights - should be denied\n");
    1868           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
    1869           4 :         status = smb2_create(tree, tctx, &io);
    1870           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1871             : 
    1872           4 :         torture_comment(tctx, "update parent sd\n");
    1873           4 :         sd = security_descriptor_dacl_create(tctx,
    1874             :                                         0, NULL, NULL,
    1875             :                                         owner_sid,
    1876             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    1877             :                                         SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE,
    1878             :                                         SEC_ACE_FLAG_OBJECT_INHERIT,
    1879             :                                         NULL);
    1880           4 :         sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ;
    1881             : 
    1882           4 :         set.set_secdesc.in.sd = sd;
    1883           4 :         status = smb2_setinfo_file(tree, &set);
    1884           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1885             : 
    1886           4 :         torture_comment(tctx, "try and access file with base rights - should be OK\n");
    1887           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1888           4 :         status = smb2_create(tree, tctx, &io);
    1889           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    1890           4 :         handle2 = io.out.file.handle;
    1891           4 :         smb2_util_close(tree, handle2);
    1892             : 
    1893             : 
    1894           4 :         torture_comment(tctx, "try and access now - should be OK if dynamic inheritance works\n");
    1895           4 :         io.in.desired_access = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE;
    1896           4 :         status = smb2_create(tree, tctx, &io);
    1897           4 :         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    1898           4 :                 torture_comment(tctx, "Server does not have dynamic inheritance\n");
    1899             :         }
    1900           4 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
    1901           0 :                 torture_comment(tctx, "Server does have dynamic inheritance\n");
    1902             :         }
    1903           4 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1904             : 
    1905           4 :         smb2_util_unlink(tree, fname1);
    1906             : 
    1907           4 : done:
    1908           4 :         torture_comment(tctx, "put back original sd\n");
    1909           4 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1910           4 :         set.set_secdesc.in.file.handle = handle;
    1911           4 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1912           4 :         set.set_secdesc.in.sd = sd_orig;
    1913           4 :         status = smb2_setinfo_file(tree, &set);
    1914             : 
    1915           4 :         smb2_util_close(tree, handle);
    1916           4 :         smb2_util_rmdir(tree, dname);
    1917           4 :         smb2_deltree(tree, BASEDIR);
    1918           4 :         smb2_tdis(tree);
    1919           4 :         smb2_logoff(tree->session);
    1920             : 
    1921           4 :         return ret;
    1922             : }
    1923             : 
    1924             : #define CHECK_STATUS_FOR_BIT_ACTION(status, bits, action) do { \
    1925             :         if (!(bits & desired_64)) {\
    1926             :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); \
    1927             :                 action; \
    1928             :         } else { \
    1929             :                 CHECK_STATUS(status, NT_STATUS_OK); \
    1930             :         } \
    1931             : } while (0)
    1932             : 
    1933             : #define CHECK_STATUS_FOR_BIT(status, bits, access) do { \
    1934             :         if (NT_STATUS_IS_OK(status)) { \
    1935             :                 if (!(granted & access)) {\
    1936             :                         ret = false; \
    1937             :                         torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are not granted! granted[0x%08X] desired[0x%08X]\n", \
    1938             :                                __location__, nt_errstr(status), access, granted, desired); \
    1939             :                         goto done; \
    1940             :                 } \
    1941             :         } else { \
    1942             :                 if (granted & access) {\
    1943             :                         ret = false; \
    1944             :                         torture_result(tctx, TORTURE_FAIL, "(%s) %s but flags 0x%08X are granted! granted[0x%08X] desired[0x%08X]\n", \
    1945             :                                __location__, nt_errstr(status), access, granted, desired); \
    1946             :                         goto done; \
    1947             :                 } \
    1948             :         } \
    1949             :         CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \
    1950             : } while (0)
    1951             : 
    1952             : #if 0
    1953             : /* test what access mask is needed for getting and setting security_descriptors */
    1954             : /* Note: This test was copied from raw/acls.c. */
    1955             : static bool test_sd_get_set(struct torture_context *tctx, struct smb2_tree *tree)
    1956             : {
    1957             :         NTSTATUS status;
    1958             :         bool ret = true;
    1959             :         struct smb2_create io;
    1960             :         union smb_fileinfo fi;
    1961             :         union smb_setfileinfo si;
    1962             :         struct security_descriptor *sd;
    1963             :         struct security_descriptor *sd_owner = NULL;
    1964             :         struct security_descriptor *sd_group = NULL;
    1965             :         struct security_descriptor *sd_dacl = NULL;
    1966             :         struct security_descriptor *sd_sacl = NULL;
    1967             :         struct smb2_handle handle;
    1968             :         const char *fname = BASEDIR "\\sd_get_set.txt";
    1969             :         uint64_t desired_64;
    1970             :         uint32_t desired = 0, granted;
    1971             :         int i = 0;
    1972             : #define NO_BITS_HACK (((uint64_t)1)<<32)
    1973             :         uint64_t open_bits =
    1974             :                 SEC_MASK_GENERIC |
    1975             :                 SEC_FLAG_SYSTEM_SECURITY |
    1976             :                 SEC_FLAG_MAXIMUM_ALLOWED |
    1977             :                 SEC_STD_ALL |
    1978             :                 SEC_FILE_ALL |
    1979             :                 NO_BITS_HACK;
    1980             :         uint64_t get_owner_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
    1981             :         uint64_t set_owner_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
    1982             :         uint64_t get_group_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
    1983             :         uint64_t set_group_bits = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER;
    1984             :         uint64_t get_dacl_bits  = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL;
    1985             :         uint64_t set_dacl_bits  = SEC_GENERIC_ALL  | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_DAC;
    1986             :         uint64_t get_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
    1987             :         uint64_t set_sacl_bits  = SEC_FLAG_SYSTEM_SECURITY;
    1988             : 
    1989             :         if (!smb2_util_setup_dir(tctx, tree, BASEDIR))
    1990             :                 return false;
    1991             : 
    1992             :         torture_comment(tctx, "TESTING ACCESS MASKS FOR SD GET/SET\n");
    1993             : 
    1994             :         /* first create a file with full access for everyone */
    1995             :         sd = security_descriptor_dacl_create(tctx,
    1996             :                                         0, SID_NT_ANONYMOUS, SID_BUILTIN_USERS,
    1997             :                                         SID_WORLD,
    1998             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    1999             :                                         SEC_GENERIC_ALL,
    2000             :                                         0,
    2001             :                                         NULL);
    2002             :         sd->type |= SEC_DESC_SACL_PRESENT;
    2003             :         sd->sacl = NULL;
    2004             :         ZERO_STRUCT(io);
    2005             :         io.level = RAW_OPEN_SMB2;
    2006             :         io.in.create_flags = 0;
    2007             :         io.in.desired_access = SEC_GENERIC_ALL;
    2008             :         io.in.create_options = 0;
    2009             :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    2010             :         io.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    2011             :         io.in.alloc_size = 0;
    2012             :         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    2013             :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2014             :         io.in.security_flags = 0;
    2015             :         io.in.fname = fname;
    2016             :         io.in.sec_desc = sd;
    2017             :         status = smb2_create(tree, tctx, &io);
    2018             :         CHECK_STATUS(status, NT_STATUS_OK);
    2019             :         handle = io.out.file.handle;
    2020             : 
    2021             :         status = smb2_util_close(tree, handle);
    2022             :         CHECK_STATUS(status, NT_STATUS_OK);
    2023             : 
    2024             :         /*
    2025             :          * now try each access_mask bit and no bit at all in a loop
    2026             :          * and see what's allowed
    2027             :          * NOTE: if i == 32 it means access_mask = 0 (see NO_BITS_HACK above)
    2028             :          */
    2029             :         for (i=0; i <= 32; i++) {
    2030             :                 desired_64 = ((uint64_t)1) << i;
    2031             :                 desired = (uint32_t)desired_64;
    2032             : 
    2033             :                 /* first open the file with the desired access */
    2034             :                 io.level = RAW_OPEN_SMB2;
    2035             :                 io.in.desired_access = desired;
    2036             :                 io.in.create_disposition = NTCREATEX_DISP_OPEN;
    2037             :                 status = smb2_create(tree, tctx, &io);
    2038             :                 CHECK_STATUS_FOR_BIT_ACTION(status, open_bits, goto next);
    2039             :                 handle = io.out.file.handle;
    2040             : 
    2041             :                 /* then check what access was granted */
    2042             :                 fi.access_information.level             = RAW_FILEINFO_ACCESS_INFORMATION;
    2043             :                 fi.access_information.in.file.handle    = handle;
    2044             :                 status = smb2_getinfo_file(tree, tctx, &fi);
    2045             :                 CHECK_STATUS(status, NT_STATUS_OK);
    2046             :                 granted = fi.access_information.out.access_flags;
    2047             : 
    2048             :                 /* test the owner */
    2049             :                 ZERO_STRUCT(fi);
    2050             :                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
    2051             :                 fi.query_secdesc.in.file.handle         = handle;
    2052             :                 fi.query_secdesc.in.secinfo_flags       = SECINFO_OWNER;
    2053             :                 status = smb2_getinfo_file(tree, tctx, &fi);
    2054             :                 CHECK_STATUS_FOR_BIT(status, get_owner_bits, SEC_STD_READ_CONTROL);
    2055             :                 if (fi.query_secdesc.out.sd) {
    2056             :                         sd_owner = fi.query_secdesc.out.sd;
    2057             :                 } else if (!sd_owner) {
    2058             :                         sd_owner = sd;
    2059             :                 }
    2060             :                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
    2061             :                 si.set_secdesc.in.file.handle           = handle;
    2062             :                 si.set_secdesc.in.secinfo_flags         = SECINFO_OWNER;
    2063             :                 si.set_secdesc.in.sd                    = sd_owner;
    2064             :                 status = smb2_setinfo_file(tree, &si);
    2065             :                 CHECK_STATUS_FOR_BIT(status, set_owner_bits, SEC_STD_WRITE_OWNER);
    2066             : 
    2067             :                 /* test the group */
    2068             :                 ZERO_STRUCT(fi);
    2069             :                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
    2070             :                 fi.query_secdesc.in.file.handle         = handle;
    2071             :                 fi.query_secdesc.in.secinfo_flags       = SECINFO_GROUP;
    2072             :                 status = smb2_getinfo_file(tree, tctx, &fi);
    2073             :                 CHECK_STATUS_FOR_BIT(status, get_group_bits, SEC_STD_READ_CONTROL);
    2074             :                 if (fi.query_secdesc.out.sd) {
    2075             :                         sd_group = fi.query_secdesc.out.sd;
    2076             :                 } else if (!sd_group) {
    2077             :                         sd_group = sd;
    2078             :                 }
    2079             :                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
    2080             :                 si.set_secdesc.in.file.handle           = handle;
    2081             :                 si.set_secdesc.in.secinfo_flags         = SECINFO_GROUP;
    2082             :                 si.set_secdesc.in.sd                    = sd_group;
    2083             :                 status = smb2_setinfo_file(tree, &si);
    2084             :                 CHECK_STATUS_FOR_BIT(status, set_group_bits, SEC_STD_WRITE_OWNER);
    2085             : 
    2086             :                 /* test the DACL */
    2087             :                 ZERO_STRUCT(fi);
    2088             :                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
    2089             :                 fi.query_secdesc.in.file.handle         = handle;
    2090             :                 fi.query_secdesc.in.secinfo_flags       = SECINFO_DACL;
    2091             :                 status = smb2_getinfo_file(tree, tctx, &fi);
    2092             :                 CHECK_STATUS_FOR_BIT(status, get_dacl_bits, SEC_STD_READ_CONTROL);
    2093             :                 if (fi.query_secdesc.out.sd) {
    2094             :                         sd_dacl = fi.query_secdesc.out.sd;
    2095             :                 } else if (!sd_dacl) {
    2096             :                         sd_dacl = sd;
    2097             :                 }
    2098             :                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
    2099             :                 si.set_secdesc.in.file.handle           = handle;
    2100             :                 si.set_secdesc.in.secinfo_flags         = SECINFO_DACL;
    2101             :                 si.set_secdesc.in.sd                    = sd_dacl;
    2102             :                 status = smb2_setinfo_file(tree, &si);
    2103             :                 CHECK_STATUS_FOR_BIT(status, set_dacl_bits, SEC_STD_WRITE_DAC);
    2104             : 
    2105             :                 /* test the SACL */
    2106             :                 ZERO_STRUCT(fi);
    2107             :                 fi.query_secdesc.level                  = RAW_FILEINFO_SEC_DESC;
    2108             :                 fi.query_secdesc.in.file.handle         = handle;
    2109             :                 fi.query_secdesc.in.secinfo_flags       = SECINFO_SACL;
    2110             :                 status = smb2_getinfo_file(tree, tctx, &fi);
    2111             :                 CHECK_STATUS_FOR_BIT(status, get_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
    2112             :                 if (fi.query_secdesc.out.sd) {
    2113             :                         sd_sacl = fi.query_secdesc.out.sd;
    2114             :                 } else if (!sd_sacl) {
    2115             :                         sd_sacl = sd;
    2116             :                 }
    2117             :                 si.set_secdesc.level                    = RAW_SFILEINFO_SEC_DESC;
    2118             :                 si.set_secdesc.in.file.handle           = handle;
    2119             :                 si.set_secdesc.in.secinfo_flags         = SECINFO_SACL;
    2120             :                 si.set_secdesc.in.sd                    = sd_sacl;
    2121             :                 status = smb2_setinfo_file(tree, &si);
    2122             :                 CHECK_STATUS_FOR_BIT(status, set_sacl_bits, SEC_FLAG_SYSTEM_SECURITY);
    2123             : 
    2124             :                 /* close the handle */
    2125             :                 status = smb2_util_close(tree, handle);
    2126             :                 CHECK_STATUS(status, NT_STATUS_OK);
    2127             : next:
    2128             :                 continue;
    2129             :         }
    2130             : 
    2131             : done:
    2132             :         smb2_util_close(tree, handle);
    2133             :         smb2_util_unlink(tree, fname);
    2134             :         smb2_deltree(tree, BASEDIR);
    2135             :         smb2_tdis(tree);
    2136             :         smb2_logoff(tree->session);
    2137             : 
    2138             :         return ret;
    2139             : }
    2140             : #endif
    2141             : 
    2142             : /**
    2143             :  * SMB2 connect with explicit share
    2144             :  **/
    2145           4 : static bool torture_smb2_con_share(struct torture_context *tctx,
    2146             :                            const char *share,
    2147             :                            struct smb2_tree **tree)
    2148             : {
    2149             :         struct smbcli_options options;
    2150             :         NTSTATUS status;
    2151           4 :         const char *host = torture_setting_string(tctx, "host", NULL);
    2152             : 
    2153           4 :         lpcfg_smbcli_options(tctx->lp_ctx, &options);
    2154             : 
    2155           4 :         status = smb2_connect_ext(tctx,
    2156             :                                   host,
    2157             :                                   lpcfg_smb_ports(tctx->lp_ctx),
    2158             :                                   share,
    2159             :                                   lpcfg_resolve_context(tctx->lp_ctx),
    2160             :                                   samba_cmdline_get_creds(),
    2161             :                                   0,
    2162             :                                   tree,
    2163             :                                   tctx->ev,
    2164             :                                   &options,
    2165             :                                   lpcfg_socket_options(tctx->lp_ctx),
    2166             :                                   lpcfg_gensec_settings(tctx, tctx->lp_ctx)
    2167             :                                   );
    2168           4 :         if (!NT_STATUS_IS_OK(status)) {
    2169           0 :                 torture_comment(tctx, "Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
    2170             :                         host, share, nt_errstr(status));
    2171           0 :                 return false;
    2172             :         }
    2173           4 :         return true;
    2174             : }
    2175             : 
    2176           4 : static bool test_access_based(struct torture_context *tctx,
    2177             :                                 struct smb2_tree *tree)
    2178             : {
    2179           4 :         struct smb2_tree *tree1 = NULL;
    2180             :         NTSTATUS status;
    2181             :         struct smb2_create io;
    2182           4 :         const char *fname = BASEDIR "\\testfile";
    2183           4 :         bool ret = true;
    2184             :         struct smb2_handle fhandle, dhandle;
    2185             :         union smb_fileinfo q;
    2186             :         union smb_setfileinfo set;
    2187           4 :         struct security_descriptor *sd, *sd_orig=NULL;
    2188             :         const char *owner_sid;
    2189           4 :         uint32_t flags = 0;
    2190             :         /*
    2191             :          * Can't test without SEC_STD_READ_CONTROL as we
    2192             :          * own the file and implicitly have SEC_STD_READ_CONTROL.
    2193             :         */
    2194           4 :         uint32_t access_masks[] = {
    2195             :                 /* Full READ access. */
    2196             :                 SEC_STD_READ_CONTROL|FILE_READ_DATA|
    2197             :                 FILE_READ_ATTRIBUTES|FILE_READ_EA,
    2198             : 
    2199             :                 /* Missing FILE_READ_EA. */
    2200             :                 SEC_STD_READ_CONTROL|FILE_READ_DATA|
    2201             :                 FILE_READ_ATTRIBUTES,
    2202             : 
    2203             :                 /* Missing FILE_READ_ATTRIBUTES. */
    2204             :                 SEC_STD_READ_CONTROL|FILE_READ_DATA|
    2205             :                 FILE_READ_EA,
    2206             : 
    2207             :                 /* Missing FILE_READ_DATA. */
    2208             :                 SEC_STD_READ_CONTROL|
    2209             :                 FILE_READ_ATTRIBUTES|FILE_READ_EA,
    2210             :         };
    2211             :         unsigned int i;
    2212             :         unsigned int count;
    2213             :         struct smb2_find f;
    2214             :         union smb_search_data *d;
    2215             : 
    2216           4 :         ZERO_STRUCT(fhandle);
    2217           4 :         ZERO_STRUCT(dhandle);
    2218             : 
    2219           4 :         if (!torture_smb2_con_share(tctx, "hideunread", &tree1)) {
    2220           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) Unable to connect "
    2221             :                         "to share 'hideunread'\n",
    2222             :                        __location__);
    2223           0 :                 ret = false;
    2224           0 :                 goto done;
    2225             :         }
    2226             : 
    2227           4 :         flags = smb2cli_tcon_flags(tree1->smbXcli);
    2228             : 
    2229           4 :         smb2_util_unlink(tree1, fname);
    2230           4 :         smb2_deltree(tree1, BASEDIR);
    2231             : 
    2232           4 :         torture_comment(tctx, "TESTING ACCESS BASED ENUMERATION\n");
    2233             : 
    2234           4 :         if ((flags & SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM)==0) {
    2235           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) No access enumeration "
    2236             :                         "on share 'hideunread'\n",
    2237             :                        __location__);
    2238           0 :                 ret = false;
    2239           0 :                 goto done;
    2240             :         }
    2241             : 
    2242           4 :         if (!smb2_util_setup_dir(tctx, tree1, BASEDIR)) {
    2243           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) Unable to setup %s\n",
    2244             :                        __location__, BASEDIR);
    2245           0 :                 ret = false;
    2246           0 :                 goto done;
    2247             :         }
    2248             : 
    2249             :         /* Get a handle to the BASEDIR directory. */
    2250           4 :         status = torture_smb2_testdir(tree1, BASEDIR, &dhandle);
    2251           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    2252           4 :         smb2_util_close(tree1, dhandle);
    2253           4 :         ZERO_STRUCT(dhandle);
    2254             : 
    2255           4 :         ZERO_STRUCT(io);
    2256           4 :         io.level = RAW_OPEN_SMB2;
    2257           4 :         io.in.create_flags = 0;
    2258           4 :         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
    2259           4 :         io.in.create_options = 0;
    2260           4 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    2261           4 :         io.in.share_access = 0;
    2262           4 :         io.in.alloc_size = 0;
    2263           4 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    2264           4 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2265           4 :         io.in.security_flags = 0;
    2266           4 :         io.in.fname = fname;
    2267             : 
    2268           4 :         status = smb2_create(tree1, tctx, &io);
    2269           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    2270           4 :         fhandle = io.out.file.handle;
    2271             : 
    2272           4 :         torture_comment(tctx, "get the original sd\n");
    2273           4 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    2274           4 :         q.query_secdesc.in.file.handle = fhandle;
    2275           4 :         q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER;
    2276           4 :         status = smb2_getinfo_file(tree1, tctx, &q);
    2277           4 :         CHECK_STATUS(status, NT_STATUS_OK);
    2278           4 :         sd_orig = q.query_secdesc.out.sd;
    2279             : 
    2280           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2281             : 
    2282           4 :         torture_comment(tctx, "owner_sid is %s\n", owner_sid);
    2283             : 
    2284             :         /* Setup for the search. */
    2285           4 :         ZERO_STRUCT(f);
    2286           4 :         f.in.pattern            = "*";
    2287           4 :         f.in.continue_flags     = SMB2_CONTINUE_FLAG_REOPEN;
    2288           4 :         f.in.max_response_size  = 0x1000;
    2289           4 :         f.in.level              = SMB2_FIND_DIRECTORY_INFO;
    2290             : 
    2291          20 :         for (i = 0; i < ARRAY_SIZE(access_masks); i++) {
    2292             : 
    2293          16 :                 sd = security_descriptor_dacl_create(tctx,
    2294             :                                         0, NULL, NULL,
    2295             :                                         owner_sid,
    2296             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2297          16 :                                         access_masks[i]|SEC_STD_SYNCHRONIZE,
    2298             :                                         0,
    2299             :                                         NULL);
    2300             : 
    2301          16 :                 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    2302          16 :                 set.set_secdesc.in.file.handle = fhandle;
    2303          16 :                 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    2304          16 :                 set.set_secdesc.in.sd = sd;
    2305          16 :                 status = smb2_setinfo_file(tree1, &set);
    2306          16 :                 CHECK_STATUS(status, NT_STATUS_OK);
    2307             : 
    2308             :                 /* Now see if we can see the file in a directory listing. */
    2309             : 
    2310             :                 /* Re-open dhandle. */
    2311          16 :                 status = torture_smb2_testdir(tree1, BASEDIR, &dhandle);
    2312          16 :                 CHECK_STATUS(status, NT_STATUS_OK);
    2313          16 :                 f.in.file.handle = dhandle;
    2314             : 
    2315          16 :                 count = 0;
    2316          16 :                 d = NULL;
    2317          16 :                 status = smb2_find_level(tree1, tree1, &f, &count, &d);
    2318          16 :                 TALLOC_FREE(d);
    2319             : 
    2320          16 :                 CHECK_STATUS(status, NT_STATUS_OK);
    2321             : 
    2322          16 :                 smb2_util_close(tree1, dhandle);
    2323          16 :                 ZERO_STRUCT(dhandle);
    2324             : 
    2325          16 :                 if (i == 0) {
    2326             :                         /* We should see the first sd. */
    2327           4 :                         if (count != 3) {
    2328           0 :                                 torture_result(tctx, TORTURE_FAIL,
    2329             :                                         "(%s) Normal SD - Unable "
    2330             :                                         "to see file %s\n",
    2331             :                                         __location__,
    2332             :                                         BASEDIR);
    2333           0 :                                 ret = false;
    2334           0 :                                 goto done;
    2335             :                         }
    2336             :                 } else {
    2337             :                         /* But no others. */
    2338          12 :                         if (count != 2) {
    2339           0 :                                 torture_result(tctx, TORTURE_FAIL,
    2340             :                                         "(%s) SD 0x%x - can "
    2341             :                                         "see file %s\n",
    2342             :                                         __location__,
    2343             :                                         access_masks[i],
    2344             :                                         BASEDIR);
    2345           0 :                                 ret = false;
    2346           0 :                                 goto done;
    2347             :                         }
    2348             :                 }
    2349             :         }
    2350             : 
    2351           4 : done:
    2352             : 
    2353           4 :         if (tree1) {
    2354           4 :                 smb2_util_close(tree1, fhandle);
    2355           4 :                 smb2_util_close(tree1, dhandle);
    2356           4 :                 smb2_util_unlink(tree1, fname);
    2357           4 :                 smb2_deltree(tree1, BASEDIR);
    2358           4 :                 smb2_tdis(tree1);
    2359           4 :                 smb2_logoff(tree1->session);
    2360             :         }
    2361           4 :         smb2_tdis(tree);
    2362           4 :         smb2_logoff(tree->session);
    2363           4 :         return ret;
    2364             : }
    2365             : 
    2366             : /*
    2367             :  * test Owner Rights, S-1-3-4
    2368             :  */
    2369           4 : static bool test_owner_rights(struct torture_context *tctx,
    2370             :                               struct smb2_tree *tree)
    2371             : {
    2372           4 :         const char *fname = BASEDIR "\\owner_right.txt";
    2373             :         struct smb2_create cr;
    2374           4 :         struct smb2_handle handle = {{0}};
    2375             :         union smb_fileinfo gi;
    2376             :         union smb_setfileinfo si;
    2377           4 :         struct security_descriptor *sd_orig = NULL;
    2378           4 :         struct security_descriptor *sd = NULL;
    2379           4 :         const char *owner_sid = NULL;
    2380             :         NTSTATUS mxac_status;
    2381             :         NTSTATUS status;
    2382           4 :         bool ret = true;
    2383             : 
    2384           4 :         smb2_deltree(tree, BASEDIR);
    2385             : 
    2386           4 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2387           4 :         torture_assert_goto(tctx, ret, ret, done,
    2388             :                             "smb2_util_setup_dir failed\n");
    2389             : 
    2390           4 :         torture_comment(tctx, "TESTING OWNER RIGHTS\n");
    2391             : 
    2392           4 :         cr = (struct smb2_create) {
    2393             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    2394             :                         SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
    2395             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2396             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2397             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2398             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2399             :                 .in.fname = fname,
    2400             :         };
    2401             : 
    2402           4 :         status = smb2_create(tree, tctx, &cr);
    2403           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2404             :                                         "smb2_create failed\n");
    2405           4 :         handle = cr.out.file.handle;
    2406             : 
    2407           4 :         torture_comment(tctx, "get the original sd\n");
    2408             : 
    2409           4 :         gi = (union smb_fileinfo) {
    2410             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    2411             :                 .query_secdesc.in.file.handle = handle,
    2412             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
    2413             :         };
    2414             : 
    2415           4 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2416           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2417             :                                         "smb2_getinfo_file failed\n");
    2418             : 
    2419           4 :         sd_orig = gi.query_secdesc.out.sd;
    2420           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2421             : 
    2422             :         /*
    2423             :          * Add a 2 element ACL
    2424             :          * SEC_RIGHTS_FILE_READ for the owner,
    2425             :          * SEC_FILE_WRITE_DATA for SID_OWNER_RIGHTS.
    2426             :          *
    2427             :          * Proves that the owner and SID_OWNER_RIGHTS
    2428             :          * ACE entries are additive.
    2429             :          */
    2430           4 :         sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL,
    2431             :                                              owner_sid,
    2432             :                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
    2433             :                                              SEC_RIGHTS_FILE_READ,
    2434             :                                              0,
    2435             :                                              SID_OWNER_RIGHTS,
    2436             :                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
    2437             :                                              SEC_FILE_WRITE_DATA,
    2438             :                                              0,
    2439             :                                              NULL);
    2440           4 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2441             :                                      "SD create failed\n");
    2442             : 
    2443           4 :         si = (union smb_setfileinfo) {
    2444             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    2445             :                 .set_secdesc.in.file.handle = handle,
    2446             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    2447             :                 .set_secdesc.in.sd = sd,
    2448             :         };
    2449             : 
    2450           4 :         status = smb2_setinfo_file(tree, &si);
    2451           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2452             :                                         "smb2_setinfo_file failed\n");
    2453             : 
    2454           4 :         status = smb2_util_close(tree, handle);
    2455           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2456             :                                         "smb2_util_close failed\n");
    2457           4 :         ZERO_STRUCT(handle);
    2458             : 
    2459           4 :         cr = (struct smb2_create) {
    2460             :                 .in.desired_access = SEC_STD_READ_CONTROL,
    2461             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2462             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2463             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2464             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2465             :                 .in.query_maximal_access = true,
    2466             :                 .in.fname = fname,
    2467             :         };
    2468             : 
    2469           4 :         status = smb2_create(tree, tctx, &cr);
    2470           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2471             :                                         "smb2_setinfo_file failed\n");
    2472           4 :         handle = cr.out.file.handle;
    2473             : 
    2474           4 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2475           4 :         torture_assert_ntstatus_ok_goto(tctx, mxac_status, ret, done,
    2476             :                                         "smb2_setinfo_file failed\n");
    2477             : 
    2478             :         /*
    2479             :          * For some reasons Windows 2016 doesn't set SEC_STD_DELETE but we
    2480             :          * do. Mask it out so the test passes against Samba and Windows.
    2481             :          */
    2482           4 :         torture_assert_int_equal_goto(tctx,
    2483             :                                       cr.out.maximal_access & ~SEC_STD_DELETE,
    2484             :                                       SEC_RIGHTS_FILE_READ |
    2485             :                                       SEC_FILE_WRITE_DATA,
    2486             :                                       ret, done,
    2487             :                                       "Wrong maximum access\n");
    2488             : 
    2489           4 :         status = smb2_util_close(tree, handle);
    2490           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2491             :                                         "smb2_util_close failed\n");
    2492           4 :         ZERO_STRUCT(handle);
    2493             : 
    2494           4 : done:
    2495           4 :         if (!smb2_util_handle_empty(handle)) {
    2496           0 :                 smb2_util_close(tree, handle);
    2497             :         }
    2498           4 :         smb2_deltree(tree, BASEDIR);
    2499           4 :         return ret;
    2500             : }
    2501             : 
    2502             : /*
    2503             :  * test Owner Rights with a leading DENY ACE, S-1-3-4
    2504             :  */
    2505           4 : static bool test_owner_rights_deny(struct torture_context *tctx,
    2506             :                                 struct smb2_tree *tree)
    2507             : {
    2508           4 :         const char *fname = BASEDIR "\\owner_right_deny.txt";
    2509             :         struct smb2_create cr;
    2510           4 :         struct smb2_handle handle = {{0}};
    2511             :         union smb_fileinfo gi;
    2512             :         union smb_setfileinfo si;
    2513           4 :         struct security_descriptor *sd_orig = NULL;
    2514           4 :         struct security_descriptor *sd = NULL;
    2515           4 :         const char *owner_sid = NULL;
    2516             :         NTSTATUS mxac_status;
    2517             :         NTSTATUS status;
    2518           4 :         bool ret = true;
    2519             : 
    2520           4 :         smb2_deltree(tree, BASEDIR);
    2521             : 
    2522           4 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2523           4 :         torture_assert_goto(tctx, ret, ret, done,
    2524             :                         "smb2_util_setup_dir failed\n");
    2525             : 
    2526           4 :         torture_comment(tctx, "TESTING OWNER RIGHTS DENY\n");
    2527             : 
    2528           4 :         cr = (struct smb2_create) {
    2529             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    2530             :                         SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
    2531             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2532             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2533             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2534             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2535             :                 .in.fname = fname,
    2536             :         };
    2537             : 
    2538           4 :         status = smb2_create(tree, tctx, &cr);
    2539           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2540             :                                         "smb2_create failed\n");
    2541           4 :         handle = cr.out.file.handle;
    2542             : 
    2543           4 :         torture_comment(tctx, "get the original sd\n");
    2544             : 
    2545           4 :         gi = (union smb_fileinfo) {
    2546             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    2547             :                 .query_secdesc.in.file.handle = handle,
    2548             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
    2549             :         };
    2550             : 
    2551           4 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2552           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2553             :                                 "smb2_getinfo_file failed\n");
    2554             : 
    2555           4 :         sd_orig = gi.query_secdesc.out.sd;
    2556           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2557             : 
    2558             :         /*
    2559             :          * Add a 2 element ACL
    2560             :          * DENY SEC_FILE_DATA_READ for SID_OWNER_RIGHTS
    2561             :          * SEC_FILE_READ_DATA for the owner.
    2562             :          *
    2563             :          * Proves that the owner and SID_OWNER_RIGHTS
    2564             :          * ACE entries are additive.
    2565             :          */
    2566           4 :         sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL,
    2567             :                                         SID_OWNER_RIGHTS,
    2568             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    2569             :                                         SEC_FILE_READ_DATA,
    2570             :                                         0,
    2571             :                                         owner_sid,
    2572             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2573             :                                         SEC_RIGHTS_FILE_READ,
    2574             :                                         0,
    2575             :                                         NULL);
    2576           4 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2577             :                                         "SD create failed\n");
    2578             : 
    2579           4 :         si = (union smb_setfileinfo) {
    2580             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    2581             :                 .set_secdesc.in.file.handle = handle,
    2582             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    2583             :                 .set_secdesc.in.sd = sd,
    2584             :         };
    2585             : 
    2586           4 :         status = smb2_setinfo_file(tree, &si);
    2587           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2588             :                                         "smb2_setinfo_file failed\n");
    2589             : 
    2590           4 :         status = smb2_util_close(tree, handle);
    2591           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2592             :                                         "smb2_util_close failed\n");
    2593           4 :         ZERO_STRUCT(handle);
    2594             : 
    2595           4 :         cr = (struct smb2_create) {
    2596             :                 .in.desired_access = SEC_STD_READ_CONTROL,
    2597             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2598             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2599             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2600             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2601             :                 .in.query_maximal_access = true,
    2602             :                 .in.fname = fname,
    2603             :         };
    2604             : 
    2605           4 :         status = smb2_create(tree, tctx, &cr);
    2606           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2607             :                                         "smb2_setinfo_file failed\n");
    2608           4 :         handle = cr.out.file.handle;
    2609             : 
    2610           4 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2611           4 :         torture_assert_ntstatus_ok_goto(tctx, mxac_status, ret, done,
    2612             :                                         "smb2_setinfo_file failed\n");
    2613             : 
    2614             :         /*
    2615             :          * For some reasons Windows 2016 doesn't set SEC_STD_DELETE but we
    2616             :          * do. Mask it out so the test passes against Samba and Windows.
    2617             :          */
    2618           4 :         torture_assert_int_equal_goto(tctx,
    2619             :                                       cr.out.maximal_access & ~SEC_STD_DELETE,
    2620             :                                       SEC_RIGHTS_FILE_READ & ~SEC_FILE_READ_DATA,
    2621             :                                       ret, done,
    2622             :                                       "Wrong maximum access\n");
    2623             : 
    2624           4 :         status = smb2_util_close(tree, handle);
    2625           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2626             :                                         "smb2_util_close failed\n");
    2627           4 :         ZERO_STRUCT(handle);
    2628             : 
    2629           4 : done:
    2630           4 :         if (!smb2_util_handle_empty(handle)) {
    2631           0 :                 smb2_util_close(tree, handle);
    2632             :         }
    2633           4 :         smb2_deltree(tree, BASEDIR);
    2634           4 :         return ret;
    2635             : }
    2636             : 
    2637             : /*
    2638             :  * test Owner Rights with a trailing DENY ACE, S-1-3-4
    2639             :  */
    2640           4 : static bool test_owner_rights_deny1(struct torture_context *tctx,
    2641             :                                 struct smb2_tree *tree)
    2642             : {
    2643           4 :         const char *fname = BASEDIR "\\owner_right_deny1.txt";
    2644             :         struct smb2_create cr;
    2645           4 :         struct smb2_handle handle = {{0}};
    2646             :         union smb_fileinfo gi;
    2647             :         union smb_setfileinfo si;
    2648           4 :         struct security_descriptor *sd_orig = NULL;
    2649           4 :         struct security_descriptor *sd = NULL;
    2650           4 :         const char *owner_sid = NULL;
    2651             :         NTSTATUS mxac_status;
    2652             :         NTSTATUS status;
    2653           4 :         bool ret = true;
    2654             : 
    2655           4 :         smb2_deltree(tree, BASEDIR);
    2656             : 
    2657           4 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2658           4 :         torture_assert_goto(tctx, ret, ret, done,
    2659             :                         "smb2_util_setup_dir failed\n");
    2660             : 
    2661           4 :         torture_comment(tctx, "TESTING OWNER RIGHTS DENY1\n");
    2662             : 
    2663           4 :         cr = (struct smb2_create) {
    2664             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    2665             :                         SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
    2666             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2667             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2668             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2669             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2670             :                 .in.fname = fname,
    2671             :         };
    2672             : 
    2673           4 :         status = smb2_create(tree, tctx, &cr);
    2674           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2675             :                                         "smb2_create failed\n");
    2676           4 :         handle = cr.out.file.handle;
    2677             : 
    2678           4 :         torture_comment(tctx, "get the original sd\n");
    2679             : 
    2680           4 :         gi = (union smb_fileinfo) {
    2681             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    2682             :                 .query_secdesc.in.file.handle = handle,
    2683             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
    2684             :         };
    2685             : 
    2686           4 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2687           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2688             :                                 "smb2_getinfo_file failed\n");
    2689             : 
    2690           4 :         sd_orig = gi.query_secdesc.out.sd;
    2691           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2692             : 
    2693             :         /*
    2694             :          * Add a 3 element ACL
    2695             :          *
    2696             :          * SEC_RIGHTS_FILE_READ allow for owner.
    2697             :          * SEC_FILE_WRITE_DATA allow for SID-OWNER-RIGHTS.
    2698             :          * SEC_FILE_WRITE_DATA|SEC_FILE_READ_DATA) deny for SID-OWNER-RIGHTS.
    2699             :          *
    2700             :          * Shows on Windows that trailing DENY entries don't
    2701             :          * override granted permissions in max access calculations.
    2702             :          */
    2703           4 :         sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL,
    2704             :                                         owner_sid,
    2705             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2706             :                                         SEC_RIGHTS_FILE_READ,
    2707             :                                         0,
    2708             :                                         SID_OWNER_RIGHTS,
    2709             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2710             :                                         SEC_FILE_WRITE_DATA,
    2711             :                                         0,
    2712             :                                         SID_OWNER_RIGHTS,
    2713             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    2714             :                                         (SEC_FILE_WRITE_DATA|
    2715             :                                                 SEC_FILE_READ_DATA),
    2716             :                                         0,
    2717             :                                         NULL);
    2718           4 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2719             :                                         "SD create failed\n");
    2720             : 
    2721           4 :         si = (union smb_setfileinfo) {
    2722             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    2723             :                 .set_secdesc.in.file.handle = handle,
    2724             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    2725             :                 .set_secdesc.in.sd = sd,
    2726             :         };
    2727             : 
    2728           4 :         status = smb2_setinfo_file(tree, &si);
    2729           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2730             :                                         "smb2_setinfo_file failed\n");
    2731             : 
    2732           4 :         status = smb2_util_close(tree, handle);
    2733           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2734             :                                         "smb2_util_close failed\n");
    2735           4 :         ZERO_STRUCT(handle);
    2736             : 
    2737           4 :         cr = (struct smb2_create) {
    2738             :                 .in.desired_access = SEC_STD_READ_CONTROL,
    2739             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2740             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2741             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2742             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2743             :                 .in.query_maximal_access = true,
    2744             :                 .in.fname = fname,
    2745             :         };
    2746             : 
    2747           4 :         status = smb2_create(tree, tctx, &cr);
    2748           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2749             :                                         "smb2_setinfo_file failed\n");
    2750           4 :         handle = cr.out.file.handle;
    2751             : 
    2752           4 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2753           4 :         torture_assert_ntstatus_ok_goto(tctx, mxac_status, ret, done,
    2754             :                                         "smb2_setinfo_file failed\n");
    2755             : 
    2756             :         /*
    2757             :          * For some reasons Windows 2016 doesn't set SEC_STD_DELETE but we
    2758             :          * do. Mask it out so the test passes against Samba and Windows.
    2759             :          */
    2760           4 :         torture_assert_int_equal_goto(tctx,
    2761             :                                 cr.out.maximal_access & ~SEC_STD_DELETE,
    2762             :                                 SEC_RIGHTS_FILE_READ | SEC_FILE_WRITE_DATA,
    2763             :                                 ret, done,
    2764             :                                 "Wrong maximum access\n");
    2765             : 
    2766           4 :         status = smb2_util_close(tree, handle);
    2767           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2768             :                                         "smb2_util_close failed\n");
    2769           4 :         ZERO_STRUCT(handle);
    2770             : 
    2771           4 : done:
    2772           4 :         if (!smb2_util_handle_empty(handle)) {
    2773           0 :                 smb2_util_close(tree, handle);
    2774             :         }
    2775           4 :         smb2_deltree(tree, BASEDIR);
    2776           4 :         return ret;
    2777             : }
    2778             : 
    2779             : /*
    2780             :  * test that shows that a DENY ACE doesn't remove rights granted
    2781             :  * by a previous ALLOW ACE.
    2782             :  */
    2783           4 : static bool test_deny1(struct torture_context *tctx,
    2784             :                        struct smb2_tree *tree)
    2785             : {
    2786           4 :         const char *fname = BASEDIR "\\test_deny1.txt";
    2787             :         struct smb2_create cr;
    2788           4 :         struct smb2_handle handle = {{0}};
    2789             :         union smb_fileinfo gi;
    2790             :         union smb_setfileinfo si;
    2791           4 :         struct security_descriptor *sd_orig = NULL;
    2792           4 :         struct security_descriptor *sd = NULL;
    2793           4 :         const char *owner_sid = NULL;
    2794             :         NTSTATUS mxac_status;
    2795             :         NTSTATUS status;
    2796           4 :         bool ret = true;
    2797             : 
    2798           4 :         smb2_deltree(tree, BASEDIR);
    2799             : 
    2800           4 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2801           4 :         torture_assert_goto(tctx, ret, ret, done,
    2802             :                         "smb2_util_setup_dir failed\n");
    2803             : 
    2804           4 :         cr = (struct smb2_create) {
    2805             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    2806             :                         SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
    2807             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2808             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2809             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2810             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2811             :                 .in.fname = fname,
    2812             :         };
    2813             : 
    2814           4 :         status = smb2_create(tree, tctx, &cr);
    2815           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2816             :                                         "smb2_create failed\n");
    2817           4 :         handle = cr.out.file.handle;
    2818             : 
    2819           4 :         torture_comment(tctx, "get the original sd\n");
    2820             : 
    2821           4 :         gi = (union smb_fileinfo) {
    2822             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    2823             :                 .query_secdesc.in.file.handle = handle,
    2824             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
    2825             :         };
    2826             : 
    2827           4 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2828           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2829             :                                 "smb2_getinfo_file failed\n");
    2830             : 
    2831           4 :         sd_orig = gi.query_secdesc.out.sd;
    2832           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2833             : 
    2834             :         /*
    2835             :          * Add a 2 element ACL
    2836             :          *
    2837             :          * SEC_RIGHTS_FILE_READ|SEC_FILE_WRITE_DATA allow for owner.
    2838             :          * SEC_FILE_WRITE_DATA deny for owner
    2839             :          *
    2840             :          * Shows on Windows that trailing DENY entries don't
    2841             :          * override granted permissions.
    2842             :          */
    2843           4 :         sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL,
    2844             :                                         owner_sid,
    2845             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2846             :                                         SEC_RIGHTS_FILE_READ|SEC_FILE_WRITE_DATA,
    2847             :                                         0,
    2848             :                                         owner_sid,
    2849             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    2850             :                                         SEC_FILE_WRITE_DATA,
    2851             :                                         0,
    2852             :                                         NULL);
    2853           4 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2854             :                                         "SD create failed\n");
    2855             : 
    2856           4 :         si = (union smb_setfileinfo) {
    2857             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    2858             :                 .set_secdesc.in.file.handle = handle,
    2859             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    2860             :                 .set_secdesc.in.sd = sd,
    2861             :         };
    2862             : 
    2863           4 :         status = smb2_setinfo_file(tree, &si);
    2864           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2865             :                                         "smb2_setinfo_file failed\n");
    2866             : 
    2867           4 :         status = smb2_util_close(tree, handle);
    2868           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2869             :                                         "smb2_util_close failed\n");
    2870           4 :         ZERO_STRUCT(handle);
    2871             : 
    2872           4 :         cr = (struct smb2_create) {
    2873             :                 .in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_WRITE_DATA,
    2874             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2875             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2876             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2877             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2878             :                 .in.query_maximal_access = true,
    2879             :                 .in.fname = fname,
    2880             :         };
    2881             : 
    2882           4 :         status = smb2_create(tree, tctx, &cr);
    2883           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2884             :                                         "smb2_create failed\n");
    2885           4 :         handle = cr.out.file.handle;
    2886             : 
    2887           4 :         mxac_status = NT_STATUS(cr.out.maximal_access_status);
    2888           4 :         torture_assert_ntstatus_ok_goto(tctx, mxac_status, ret, done,
    2889             :                                         "Wrong maximum access status\n");
    2890             : 
    2891             :         /*
    2892             :          * For some reasons Windows 2016 doesn't set SEC_STD_DELETE but we
    2893             :          * do. Mask it out so the test passes against Samba and Windows.
    2894             :          * SEC_STD_WRITE_DAC comes from being the owner.
    2895             :          */
    2896           4 :         torture_assert_int_equal_goto(tctx,
    2897             :                                       cr.out.maximal_access & ~SEC_STD_DELETE,
    2898             :                                       SEC_RIGHTS_FILE_READ |
    2899             :                                       SEC_FILE_WRITE_DATA |
    2900             :                                       SEC_STD_WRITE_DAC,
    2901             :                                       ret, done,
    2902             :                                       "Wrong maximum access\n");
    2903             : 
    2904           4 :         status = smb2_util_close(tree, handle);
    2905           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2906             :                                         "smb2_util_close failed\n");
    2907           4 :         ZERO_STRUCT(handle);
    2908             : 
    2909           4 : done:
    2910           4 :         if (!smb2_util_handle_empty(handle)) {
    2911           0 :                 smb2_util_close(tree, handle);
    2912             :         }
    2913           4 :         smb2_deltree(tree, BASEDIR);
    2914           4 :         return ret;
    2915             : }
    2916             : 
    2917             : /*
    2918             :  * test SEC_FLAG_MAXIMUM_ALLOWED with not-granted access
    2919             :  *
    2920             :  * When access_mask contains SEC_FLAG_MAXIMUM_ALLOWED, the server must still
    2921             :  * proces other bits from access_mask. Eg if access_mask contains a right that
    2922             :  * the requester doesn't have, the function must validate that against the
    2923             :  * effective permissions.
    2924             :  */
    2925           4 : static bool test_mxac_not_granted(struct torture_context *tctx,
    2926             :                                   struct smb2_tree *tree)
    2927             : {
    2928           4 :         const char *fname = BASEDIR "\\test_mxac_not_granted.txt";
    2929             :         struct smb2_create cr;
    2930           4 :         struct smb2_handle handle = {{0}};
    2931             :         union smb_fileinfo gi;
    2932             :         union smb_setfileinfo si;
    2933           4 :         struct security_descriptor *sd_orig = NULL;
    2934           4 :         struct security_descriptor *sd = NULL;
    2935           4 :         const char *owner_sid = NULL;
    2936             :         NTSTATUS status;
    2937           4 :         bool ret = true;
    2938             : 
    2939           4 :         smb2_deltree(tree, BASEDIR);
    2940             : 
    2941           4 :         ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
    2942           4 :         torture_assert_goto(tctx, ret, ret, done,
    2943             :                         "smb2_util_setup_dir failed\n");
    2944             : 
    2945           4 :         torture_comment(tctx, "TESTING OWNER RIGHTS DENY\n");
    2946             : 
    2947           4 :         cr = (struct smb2_create) {
    2948             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    2949             :                         SEC_STD_WRITE_DAC |SEC_STD_WRITE_OWNER,
    2950             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2951             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2952             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2953             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    2954             :                 .in.fname = fname,
    2955             :         };
    2956             : 
    2957           4 :         status = smb2_create(tree, tctx, &cr);
    2958           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2959             :                                         "smb2_create failed\n");
    2960           4 :         handle = cr.out.file.handle;
    2961             : 
    2962           4 :         torture_comment(tctx, "get the original sd\n");
    2963             : 
    2964           4 :         gi = (union smb_fileinfo) {
    2965             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    2966             :                 .query_secdesc.in.file.handle = handle,
    2967             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL|SECINFO_OWNER,
    2968             :         };
    2969             : 
    2970           4 :         status = smb2_getinfo_file(tree, tctx, &gi);
    2971           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2972             :                                 "smb2_getinfo_file failed\n");
    2973             : 
    2974           4 :         sd_orig = gi.query_secdesc.out.sd;
    2975           4 :         owner_sid = dom_sid_string(tctx, sd_orig->owner_sid);
    2976             : 
    2977           4 :         sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL,
    2978             :                                         owner_sid,
    2979             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    2980             :                                         SEC_FILE_READ_DATA,
    2981             :                                         0,
    2982             :                                         NULL);
    2983           4 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    2984             :                                         "SD create failed\n");
    2985             : 
    2986           4 :         si = (union smb_setfileinfo) {
    2987             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    2988             :                 .set_secdesc.in.file.handle = handle,
    2989             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    2990             :                 .set_secdesc.in.sd = sd,
    2991             :         };
    2992             : 
    2993           4 :         status = smb2_setinfo_file(tree, &si);
    2994           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2995             :                                         "smb2_setinfo_file failed\n");
    2996             : 
    2997           4 :         status = smb2_util_close(tree, handle);
    2998           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2999             :                                         "smb2_util_close failed\n");
    3000           4 :         ZERO_STRUCT(handle);
    3001             : 
    3002           4 :         cr = (struct smb2_create) {
    3003             :                 .in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED |
    3004             :                                      SEC_FILE_WRITE_DATA,
    3005             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    3006             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    3007             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    3008             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    3009             :                 .in.fname = fname,
    3010             :         };
    3011             : 
    3012           4 :         status = smb2_create(tree, tctx, &cr);
    3013           4 :         torture_assert_ntstatus_equal_goto(tctx, status,
    3014             :                                            NT_STATUS_ACCESS_DENIED,
    3015             :                                            ret, done,
    3016             :                                            "Wrong smb2_create result\n");
    3017             : 
    3018           4 : done:
    3019           4 :         if (!smb2_util_handle_empty(handle)) {
    3020           0 :                 smb2_util_close(tree, handle);
    3021             :         }
    3022           4 :         smb2_deltree(tree, BASEDIR);
    3023           4 :         return ret;
    3024             : }
    3025             : 
    3026             : /*
    3027             :    basic testing of SMB2 ACLs
    3028             : */
    3029        2353 : struct torture_suite *torture_smb2_acls_init(TALLOC_CTX *ctx)
    3030             : {
    3031        2353 :         struct torture_suite *suite = torture_suite_create(ctx, "acls");
    3032             : 
    3033        2353 :         torture_suite_add_1smb2_test(suite, "CREATOR", test_creator_sid);
    3034        2353 :         torture_suite_add_1smb2_test(suite, "GENERIC", test_generic_bits);
    3035        2353 :         torture_suite_add_1smb2_test(suite, "OWNER", test_owner_bits);
    3036        2353 :         torture_suite_add_1smb2_test(suite, "INHERITANCE", test_inheritance);
    3037        2353 :         torture_suite_add_1smb2_test(suite, "INHERITFLAGS", test_inheritance_flags);
    3038        2353 :         torture_suite_add_1smb2_test(suite, "SDFLAGSVSCHOWN", test_sd_flags_vs_chown);
    3039        2353 :         torture_suite_add_1smb2_test(suite, "DYNAMIC", test_inheritance_dynamic);
    3040             : #if 0
    3041             :         /* XXX This test does not work against XP or Vista. */
    3042             :         torture_suite_add_1smb2_test(suite, "GETSET", test_sd_get_set);
    3043             : #endif
    3044        2353 :         torture_suite_add_1smb2_test(suite, "ACCESSBASED", test_access_based);
    3045        2353 :         torture_suite_add_1smb2_test(suite, "OWNER-RIGHTS", test_owner_rights);
    3046        2353 :         torture_suite_add_1smb2_test(suite, "OWNER-RIGHTS-DENY",
    3047             :                         test_owner_rights_deny);
    3048        2353 :         torture_suite_add_1smb2_test(suite, "OWNER-RIGHTS-DENY1",
    3049             :                         test_owner_rights_deny1);
    3050        2353 :         torture_suite_add_1smb2_test(suite, "DENY1",
    3051             :                         test_deny1);
    3052        2353 :         torture_suite_add_1smb2_test(suite, "MXAC-NOT-GRANTED",
    3053             :                         test_mxac_not_granted);
    3054             : 
    3055        2353 :         suite->description = talloc_strdup(suite, "SMB2-ACLS tests");
    3056             : 
    3057        2353 :         return suite;
    3058             : }
    3059             : 
    3060           2 : static bool test_acls_non_canonical_flags(struct torture_context *tctx,
    3061             :                                           struct smb2_tree *tree)
    3062             : {
    3063           2 :         const char *fname = BASEDIR "\\test_acls_non_canonical_flags.txt";
    3064             :         struct smb2_create cr;
    3065           2 :         struct smb2_handle testdirh = {{0}};
    3066           2 :         struct smb2_handle handle = {{0}};
    3067             :         union smb_fileinfo gi;
    3068             :         union smb_setfileinfo si;
    3069           2 :         struct security_descriptor *sd_orig = NULL;
    3070           2 :         struct security_descriptor *sd = NULL;
    3071             :         NTSTATUS status;
    3072           2 :         bool ret = true;
    3073             : 
    3074           2 :         smb2_deltree(tree, BASEDIR);
    3075             : 
    3076           2 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    3077           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3078             :                                         "torture_smb2_testdir failed\n");
    3079             : 
    3080           2 :         sd = security_descriptor_dacl_create(tctx,
    3081             :                                              SEC_DESC_DACL_AUTO_INHERITED
    3082             :                                              | SEC_DESC_DACL_AUTO_INHERIT_REQ,
    3083             :                                              NULL,
    3084             :                                              NULL,
    3085             :                                              SID_WORLD,
    3086             :                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
    3087             :                                              SEC_RIGHTS_DIR_ALL,
    3088             :                                              SEC_ACE_FLAG_OBJECT_INHERIT
    3089             :                                              | SEC_ACE_FLAG_CONTAINER_INHERIT,
    3090             :                                              NULL);
    3091           2 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    3092             :                                         "SD create failed\n");
    3093             : 
    3094           2 :         si = (union smb_setfileinfo) {
    3095             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    3096             :                 .set_secdesc.in.file.handle = testdirh,
    3097             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    3098             :                 .set_secdesc.in.sd = sd,
    3099             :         };
    3100             : 
    3101           2 :         status = smb2_setinfo_file(tree, &si);
    3102           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3103             :                                         "smb2_setinfo_file failed\n");
    3104             : 
    3105           2 :         gi = (union smb_fileinfo) {
    3106             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    3107             :                 .query_secdesc.in.file.handle = testdirh,
    3108             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL,
    3109             :         };
    3110             : 
    3111           2 :         status = smb2_getinfo_file(tree, tctx, &gi);
    3112           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3113             :                                 "smb2_getinfo_file failed\n");
    3114             : 
    3115           2 :         cr = (struct smb2_create) {
    3116             :                 .in.desired_access = SEC_STD_READ_CONTROL |
    3117             :                         SEC_STD_WRITE_DAC,
    3118             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    3119             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    3120             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    3121             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    3122             :                 .in.fname = fname,
    3123             :         };
    3124             : 
    3125           2 :         status = smb2_create(tree, tctx, &cr);
    3126           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3127             :                                         "smb2_create failed\n");
    3128           2 :         handle = cr.out.file.handle;
    3129             : 
    3130           2 :         torture_comment(tctx, "get the original sd\n");
    3131             : 
    3132           2 :         gi = (union smb_fileinfo) {
    3133             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    3134             :                 .query_secdesc.in.file.handle = handle,
    3135             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL,
    3136             :         };
    3137             : 
    3138           2 :         status = smb2_getinfo_file(tree, tctx, &gi);
    3139           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3140             :                                 "smb2_getinfo_file failed\n");
    3141             : 
    3142           2 :         sd_orig = gi.query_secdesc.out.sd;
    3143             : 
    3144           2 :         torture_assert_goto(tctx, sd_orig->type & SEC_DESC_DACL_AUTO_INHERITED,
    3145             :                             ret, done, "Missing SEC_DESC_DACL_AUTO_INHERITED\n");
    3146             : 
    3147             :         /*
    3148             :          * SD with SEC_DESC_DACL_AUTO_INHERITED but without
    3149             :          * SEC_DESC_DACL_AUTO_INHERITED_REQ, so the resulting SD should not have
    3150             :          * SEC_DESC_DACL_AUTO_INHERITED on a Windows box.
    3151             :          *
    3152             :          * But as we're testing against a share with
    3153             :          *
    3154             :          *    "acl flag inherited canonicalization = no"
    3155             :          *
    3156             :          * the resulting SD should have acl flag inherited canonicalization set.
    3157             :          */
    3158           2 :         sd = security_descriptor_dacl_create(tctx,
    3159             :                                              SEC_DESC_DACL_AUTO_INHERITED,
    3160             :                                              NULL,
    3161             :                                              NULL,
    3162             :                                              SID_WORLD,
    3163             :                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
    3164             :                                              SEC_FILE_ALL,
    3165             :                                              0,
    3166             :                                              NULL);
    3167           2 :         torture_assert_not_null_goto(tctx, sd, ret, done,
    3168             :                                         "SD create failed\n");
    3169             : 
    3170           2 :         si = (union smb_setfileinfo) {
    3171             :                 .set_secdesc.level = RAW_SFILEINFO_SEC_DESC,
    3172             :                 .set_secdesc.in.file.handle = handle,
    3173             :                 .set_secdesc.in.secinfo_flags = SECINFO_DACL,
    3174             :                 .set_secdesc.in.sd = sd,
    3175             :         };
    3176             : 
    3177           2 :         status = smb2_setinfo_file(tree, &si);
    3178           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3179             :                                         "smb2_setinfo_file failed\n");
    3180             : 
    3181           2 :         status = smb2_util_close(tree, handle);
    3182           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3183             :                                         "smb2_util_close failed\n");
    3184           2 :         ZERO_STRUCT(handle);
    3185             : 
    3186           2 :         cr = (struct smb2_create) {
    3187             :                 .in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED ,
    3188             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    3189             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    3190             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    3191             :                 .in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
    3192             :                 .in.fname = fname,
    3193             :         };
    3194             : 
    3195           2 :         status = smb2_create(tree, tctx, &cr);
    3196           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3197             :                                         "smb2_create failed\n");
    3198           2 :         handle = cr.out.file.handle;
    3199             : 
    3200           2 :         gi = (union smb_fileinfo) {
    3201             :                 .query_secdesc.level = RAW_FILEINFO_SEC_DESC,
    3202             :                 .query_secdesc.in.file.handle = handle,
    3203             :                 .query_secdesc.in.secinfo_flags = SECINFO_DACL,
    3204             :         };
    3205             : 
    3206           2 :         status = smb2_getinfo_file(tree, tctx, &gi);
    3207           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3208             :                                 "smb2_getinfo_file failed\n");
    3209             : 
    3210           2 :         sd_orig = gi.query_secdesc.out.sd;
    3211           2 :         torture_assert_goto(tctx, sd_orig->type & SEC_DESC_DACL_AUTO_INHERITED,
    3212             :                             ret, done, "Missing SEC_DESC_DACL_AUTO_INHERITED\n");
    3213             : 
    3214           4 : done:
    3215           2 :         if (!smb2_util_handle_empty(handle)) {
    3216           2 :                 smb2_util_close(tree, testdirh);
    3217             :         }
    3218           2 :         if (!smb2_util_handle_empty(handle)) {
    3219           2 :                 smb2_util_close(tree, handle);
    3220             :         }
    3221           2 :         smb2_deltree(tree, BASEDIR);
    3222           2 :         return ret;
    3223             : }
    3224             : 
    3225        2353 : struct torture_suite *torture_smb2_acls_non_canonical_init(TALLOC_CTX *ctx)
    3226             : {
    3227        2353 :         struct torture_suite *suite = torture_suite_create(ctx, "acls_non_canonical");
    3228             : 
    3229        2353 :         torture_suite_add_1smb2_test(suite, "flags", test_acls_non_canonical_flags);
    3230        2353 :         return suite;
    3231             : }

Generated by: LCOV version 1.13