LCOV - code coverage report
Current view: top level - source4/torture/smb2 - sharemode.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 129 252 51.2 %
Date: 2024-04-13 12:30:31 Functions: 4 7 57.1 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    test suite for SMB2 sharemodes
       5             : 
       6             :    Copyright (C) Christof Schmitt 2017
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "libcli/smb2/smb2.h"
      24             : #include "libcli/smb2/smb2_calls.h"
      25             : #include "libcli/security/security.h"
      26             : #include "torture/torture.h"
      27             : #include "torture/smb2/proto.h"
      28             : #include "lib/util/smb_strtox.h"
      29             : #include <tevent.h>
      30             : 
      31             : #define BASEDIRHOLD "sharemode_hold_test"
      32             : 
      33             : struct hold_sharemode_info {
      34             :         const char *sharemode;
      35             :         const char *filename;
      36             :         struct smb2_handle handle;
      37             : } hold_sharemode_table[] = {
      38             :         {
      39             :                 .sharemode = "",
      40             :                 .filename  = BASEDIRHOLD "\\N",
      41             :         },
      42             :         {
      43             :                 .sharemode = "R",
      44             :                 .filename  = BASEDIRHOLD "\\R",
      45             :         },
      46             :         {
      47             :                 .sharemode = "W",
      48             :                 .filename  = BASEDIRHOLD "\\W",
      49             :         },
      50             :         {
      51             :                 .sharemode = "D",
      52             :                 .filename  = BASEDIRHOLD "\\D",
      53             :         },
      54             :         {
      55             :                 .sharemode = "RW",
      56             :                 .filename  = BASEDIRHOLD "\\RW",
      57             :         },
      58             :         {
      59             :                 .sharemode = "RD",
      60             :                 .filename  = BASEDIRHOLD "\\RD",
      61             :         },
      62             :         {
      63             :                 .sharemode = "WD",
      64             :                 .filename  = BASEDIRHOLD "\\WD",
      65             :         },
      66             :         {
      67             :                 .sharemode = "RWD",
      68             :                 .filename  = BASEDIRHOLD "\\RWD",
      69             :         },
      70             : };
      71             : 
      72           0 : static void signal_handler(struct tevent_context *ev,
      73             :                            struct tevent_signal *se,
      74             :                            int signum,
      75             :                            int count,
      76             :                            void *siginfo,
      77             :                            void *private_data)
      78             : {
      79           0 :         struct torture_context *tctx = private_data;
      80             : 
      81           0 :         torture_comment(tctx, "Received signal %d\n", signum);
      82           0 : }
      83             : 
      84             : /*
      85             :  * Used for manual testing of sharemodes - especially interaction with
      86             :  * other filesystems (such as NFS and local access). The scenario is
      87             :  * that this test holds files open and then concurrent access to the same
      88             :  * files outside of Samba can be tested.
      89             :  */
      90           0 : bool torture_smb2_hold_sharemode(struct torture_context *tctx)
      91             : {
      92           0 :         struct tevent_context *ev = tctx->ev;
      93           0 :         struct smb2_tree *tree = NULL;
      94           0 :         struct smb2_handle dir_handle;
      95           0 :         struct tevent_signal *s;
      96           0 :         NTSTATUS status;
      97           0 :         bool ret = true;
      98           0 :         int i;
      99             : 
     100           0 :         if (!torture_smb2_connection(tctx, &tree)) {
     101           0 :                 torture_comment(tctx, "Initializing smb2 connection failed.\n");
     102           0 :                 return false;
     103             :         }
     104             : 
     105           0 :         s = tevent_add_signal(ev, tctx, SIGINT, 0, signal_handler, tctx);
     106           0 :         torture_assert_not_null_goto(tctx, s, ret, done,
     107             :                                      "Error registering signal handler.");
     108             : 
     109           0 :         torture_comment(tctx, "Setting up open files with sharemodes in %s\n",
     110             :                         BASEDIRHOLD);
     111             : 
     112           0 :         status = torture_smb2_testdir(tree, BASEDIRHOLD, &dir_handle);
     113           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     114             :                                         "Error creating directory.");
     115             : 
     116           0 :         for (i = 0; i < ARRAY_SIZE(hold_sharemode_table); i++) {
     117           0 :                 struct hold_sharemode_info *info = &hold_sharemode_table[i];
     118           0 :                 struct smb2_create create = { 0 };
     119             : 
     120           0 :                 create.in.desired_access = SEC_RIGHTS_FILE_ALL;
     121           0 :                 create.in.alloc_size = 0;
     122           0 :                 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     123           0 :                 create.in.share_access =
     124           0 :                         smb2_util_share_access(info->sharemode);
     125           0 :                 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     126           0 :                 create.in.create_options = 0;
     127           0 :                 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     128           0 :                 create.in.security_flags = 0;
     129           0 :                 create.in.fname = info->filename;
     130           0 :                 create.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     131           0 :                 create.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
     132             : 
     133           0 :                 torture_comment(tctx, "opening %s\n", info->filename);
     134             : 
     135           0 :                 status = smb2_create(tree, tctx, &create);
     136             : 
     137           0 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     138             :                                                 "CREATE file failed\n");
     139             : 
     140           0 :                 info->handle = create.out.file.handle;
     141             :         }
     142             : 
     143           0 :         torture_comment(tctx, "Waiting for SIGINT (ctrl-c)\n");
     144           0 :         tevent_loop_wait(ev);
     145             : 
     146           0 :         torture_comment(tctx, "Closing and deleting files\n");
     147             : 
     148           0 :         for (i = 0; i < ARRAY_SIZE(hold_sharemode_table); i++) {
     149           0 :                 struct hold_sharemode_info *info = &hold_sharemode_table[i];
     150             : 
     151           0 :                 union smb_setfileinfo sfinfo = { };
     152             : 
     153           0 :                 sfinfo.disposition_info.in.delete_on_close = 1;
     154           0 :                 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
     155           0 :                 sfinfo.generic.in.file.handle = info->handle;
     156           0 :                 status = smb2_setinfo_file(tree, &sfinfo);
     157           0 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     158             :                                                 "SETINFO failed\n");
     159             : 
     160           0 :                 status = smb2_util_close(tree, info->handle);
     161           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     162           0 :                         torture_comment(tctx, "File %s not found, could have "
     163             :                                         "been deleted outside of SMB\n",
     164             :                                         info->filename);
     165           0 :                         continue;
     166             :                 }
     167           0 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     168             :                                                 "CLOSE failed\n");
     169             : }
     170             : 
     171           0 : done:
     172           0 :         smb2_deltree(tree, BASEDIRHOLD);
     173           0 :         return ret;
     174             : }
     175             : 
     176             : /*
     177             :  * Used for manual testing of sharemodes, especially interaction with
     178             :  * file systems that can enforce sharemodes. The scenario here is that
     179             :  * a file is already open outside of Samba with a sharemode and this
     180             :  * can be used to test accessing the same file from Samba.
     181             :  */
     182           0 : bool torture_smb2_check_sharemode(struct torture_context *tctx)
     183             : {
     184           0 :         const char *sharemode_string, *access_string, *filename, *operation;
     185           0 :         uint32_t sharemode, access;
     186           0 :         struct smb2_tree *tree;
     187           0 :         struct smb2_create create = { 0 };
     188           0 :         NTSTATUS status;
     189           0 :         bool ret = true;
     190           0 :         int error = 0;
     191             : 
     192           0 :         sharemode_string = torture_setting_string(tctx, "sharemode", "RWD");
     193           0 :         sharemode = smb2_util_share_access(sharemode_string);
     194             : 
     195           0 :         access_string = torture_setting_string(tctx, "access", "0xf01ff");
     196           0 :         access = smb_strtoul(access_string, NULL, 0, &error, SMB_STR_STANDARD);
     197           0 :         if (error != 0) {
     198           0 :                 torture_comment(tctx, "Initializing access failed.\n");
     199           0 :                 return false;
     200             :         }
     201             : 
     202           0 :         filename = torture_setting_string(tctx, "filename", "testfile");
     203           0 :         operation = torture_setting_string(tctx, "operation", "WD");
     204             : 
     205           0 :         if (!torture_smb2_connection(tctx, &tree)) {
     206           0 :                 torture_comment(tctx, "Initializing smb2 connection failed.\n");
     207           0 :                 return false;
     208             :         }
     209             : 
     210           0 :         create.in.desired_access = access;
     211           0 :         create.in.alloc_size = 0;
     212           0 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     213           0 :         create.in.share_access = sharemode;
     214           0 :         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     215           0 :         create.in.create_options = 0;
     216           0 :         create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     217           0 :         create.in.security_flags = 0;
     218           0 :         create.in.fname = filename;
     219           0 :         create.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     220           0 :         create.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
     221             : 
     222           0 :         status = smb2_create(tree, tctx, &create);
     223           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     224             :                                         "CREATE failed\n");
     225             : 
     226           0 :         if (strchr(operation, 'R')) {
     227           0 :                 struct smb2_read read = { 0 };
     228             : 
     229           0 :                 read.in.file.handle = create.out.file.handle;
     230           0 :                 read.in.offset = 0;
     231           0 :                 read.in.length = 1;
     232             : 
     233           0 :                 status = smb2_read(tree, tctx, &read);
     234           0 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     235             :                                                 "READ failed\n");
     236             :         }
     237             : 
     238           0 :         if (strchr(operation, 'W')) {
     239           0 :                 char buf[1];
     240           0 :                 status = smb2_util_write(tree, create.out.file.handle,
     241             :                                          &buf, 0, sizeof(buf));
     242           0 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     243             :                                                 "WRITE failed\n");
     244             :         }
     245             : 
     246           0 :         if (strchr(operation, 'D')) {
     247           0 :                 union smb_setfileinfo sfinfo = { };
     248             : 
     249           0 :                 sfinfo.disposition_info.in.delete_on_close = 1;
     250           0 :                 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
     251           0 :                 sfinfo.generic.in.file.handle = create.out.file.handle;
     252             : 
     253           0 :                 status = smb2_setinfo_file(tree, &sfinfo);
     254           0 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     255             :                                                 "SETINFO failed\n");
     256             : 
     257           0 :                 status = smb2_util_close(tree, create.out.file.handle);
     258           0 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     259             :                                                 "CLOSE failed\n");
     260             :         }
     261             : 
     262           0 : done:
     263           0 :         return ret;
     264             : }
     265             : 
     266             : struct sharemode_info {
     267             :         const char *sharemode;
     268             :         uint32_t access_mask;
     269             :         bool expect_ok;
     270             : } sharemode_table[] = {
     271             : 
     272             :         /*
     273             :          * Basic tests, check each permission bit against every
     274             :          * possible sharemode combination.
     275             :          */
     276             : 
     277             :         { "R",         SEC_FILE_READ_DATA,            true,   },
     278             :         { "R",         SEC_FILE_WRITE_DATA,           false,  },
     279             :         { "R",         SEC_FILE_APPEND_DATA,          false,  },
     280             :         { "R",         SEC_FILE_READ_EA,              true,   },
     281             :         { "R",         SEC_FILE_WRITE_EA,             true,   },
     282             :         { "R",         SEC_FILE_EXECUTE,              true,   },
     283             :         { "R",         SEC_FILE_READ_ATTRIBUTE,       true,   },
     284             :         { "R",         SEC_FILE_WRITE_ATTRIBUTE,      true,   },
     285             :         { "R",         SEC_STD_DELETE,                false,  },
     286             :         { "R",         SEC_STD_READ_CONTROL,          true,   },
     287             :         { "R",         SEC_STD_WRITE_DAC,             true,   },
     288             :         { "R",         SEC_STD_WRITE_OWNER,           true,   },
     289             :         { "R",         SEC_STD_SYNCHRONIZE,           true,   },
     290             : 
     291             :         { "W",         SEC_FILE_READ_DATA,            false   },
     292             :         { "W",         SEC_FILE_WRITE_DATA,           true,   },
     293             :         { "W",         SEC_FILE_APPEND_DATA,          true,   },
     294             :         { "W",         SEC_FILE_READ_EA,              true,   },
     295             :         { "W",         SEC_FILE_WRITE_EA,             true,   },
     296             :         { "W",         SEC_FILE_EXECUTE,              false,  },
     297             :         { "W",         SEC_FILE_READ_ATTRIBUTE,       true,   },
     298             :         { "W",         SEC_FILE_WRITE_ATTRIBUTE,      true,   },
     299             :         { "W",         SEC_STD_DELETE,                false,  },
     300             :         { "W",         SEC_STD_READ_CONTROL,          true,   },
     301             :         { "W",         SEC_STD_WRITE_DAC,             true,   },
     302             :         { "W",         SEC_STD_WRITE_OWNER,           true,   },
     303             :         { "W",         SEC_STD_SYNCHRONIZE,           true,   },
     304             : 
     305             :         { "D",         SEC_FILE_READ_DATA,            false   },
     306             :         { "D",         SEC_FILE_WRITE_DATA,           false   },
     307             :         { "D",         SEC_FILE_APPEND_DATA,          false   },
     308             :         { "D",         SEC_FILE_READ_EA,              true,   },
     309             :         { "D",         SEC_FILE_WRITE_EA,             true,   },
     310             :         { "D",         SEC_FILE_EXECUTE,              false,  },
     311             :         { "D",         SEC_FILE_READ_ATTRIBUTE,       true,   },
     312             :         { "D",         SEC_FILE_WRITE_ATTRIBUTE,      true,   },
     313             :         { "D",         SEC_STD_DELETE,                true,   },
     314             :         { "D",         SEC_STD_READ_CONTROL,          true,   },
     315             :         { "D",         SEC_STD_WRITE_DAC,             true,   },
     316             :         { "D",         SEC_STD_WRITE_OWNER,           true,   },
     317             :         { "D",         SEC_STD_SYNCHRONIZE,           true,   },
     318             : 
     319             :         { "RW",  SEC_FILE_READ_DATA,          true,   },
     320             :         { "RW",  SEC_FILE_WRITE_DATA,         true,   },
     321             :         { "RW",  SEC_FILE_APPEND_DATA,                true,   },
     322             :         { "RW",  SEC_FILE_READ_EA,            true,   },
     323             :         { "RW",  SEC_FILE_WRITE_EA,           true,   },
     324             :         { "RW",  SEC_FILE_EXECUTE,            true,   },
     325             :         { "RW",  SEC_FILE_READ_ATTRIBUTE,     true,   },
     326             :         { "RW",  SEC_FILE_WRITE_ATTRIBUTE,    true,   },
     327             :         { "RW",  SEC_STD_DELETE,              false,  },
     328             :         { "RW",  SEC_STD_READ_CONTROL,                true,   },
     329             :         { "RW",  SEC_STD_WRITE_DAC,           true,   },
     330             :         { "RW",  SEC_STD_WRITE_OWNER,         true,   },
     331             :         { "RW",  SEC_STD_SYNCHRONIZE,         true,   },
     332             : 
     333             :         { "RD",  SEC_FILE_READ_DATA,          true,   },
     334             :         { "RD",  SEC_FILE_WRITE_DATA,         false,  },
     335             :         { "RD",  SEC_FILE_APPEND_DATA,                false,  },
     336             :         { "RD",  SEC_FILE_READ_EA,            true,   },
     337             :         { "RD",  SEC_FILE_WRITE_EA,           true,   },
     338             :         { "RD",  SEC_FILE_EXECUTE,            true,   },
     339             :         { "RD",  SEC_FILE_READ_ATTRIBUTE,     true,   },
     340             :         { "RD",  SEC_FILE_WRITE_ATTRIBUTE,    true,   },
     341             :         { "RD",  SEC_STD_DELETE,              true,   },
     342             :         { "RD",  SEC_STD_READ_CONTROL,                true,   },
     343             :         { "RD",  SEC_STD_WRITE_DAC,           true,   },
     344             :         { "RD",  SEC_STD_WRITE_OWNER,         true,   },
     345             :         { "RD",  SEC_STD_SYNCHRONIZE,         true,   },
     346             : 
     347             :         { "WD",  SEC_FILE_READ_DATA,          false   },
     348             :         { "WD",  SEC_FILE_WRITE_DATA,         true,   },
     349             :         { "WD",  SEC_FILE_APPEND_DATA,                true,   },
     350             :         { "WD",  SEC_FILE_READ_EA,            true    },
     351             :         { "WD",  SEC_FILE_WRITE_EA,           true,   },
     352             :         { "WD",  SEC_FILE_EXECUTE,            false   },
     353             :         { "WD",  SEC_FILE_READ_ATTRIBUTE,     true,   },
     354             :         { "WD",  SEC_FILE_WRITE_ATTRIBUTE,    true,   },
     355             :         { "WD",  SEC_STD_DELETE,              true,   },
     356             :         { "WD",  SEC_STD_READ_CONTROL,                true,   },
     357             :         { "WD",  SEC_STD_WRITE_DAC,           true,   },
     358             :         { "WD",  SEC_STD_WRITE_OWNER,         true,   },
     359             :         { "WD",  SEC_STD_SYNCHRONIZE,         true,   },
     360             : 
     361             :         { "RWD",  SEC_FILE_READ_DATA,         true    },
     362             :         { "RWD",  SEC_FILE_WRITE_DATA,                true,   },
     363             :         { "RWD",  SEC_FILE_APPEND_DATA,       true,   },
     364             :         { "RWD",  SEC_FILE_READ_EA,           true    },
     365             :         { "RWD",  SEC_FILE_WRITE_EA,          true,   },
     366             :         { "RWD",  SEC_FILE_EXECUTE,           true,   },
     367             :         { "RWD",  SEC_FILE_READ_ATTRIBUTE,    true,   },
     368             :         { "RWD",  SEC_FILE_WRITE_ATTRIBUTE,   true,   },
     369             :         { "RWD",  SEC_STD_DELETE,             true,   },
     370             :         { "RWD",  SEC_STD_READ_CONTROL,       true,   },
     371             :         { "RWD",  SEC_STD_WRITE_DAC,          true,   },
     372             :         { "RWD",  SEC_STD_WRITE_OWNER,                true,   },
     373             :         { "RWD",  SEC_STD_SYNCHRONIZE,                 true,  },
     374             : 
     375             :         /*
     376             :          * Some more interesting cases. Always request READ or WRITE
     377             :          * access, as that will trigger the opening of a file
     378             :          * description in Samba. This especially useful for file
     379             :          * systems that enforce share modes on open file descriptors.
     380             :          */
     381             : 
     382             :         { "R",         SEC_FILE_READ_DATA,                            true,   },
     383             :         { "R",         SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA,        false,  },
     384             :         { "R",         SEC_FILE_READ_DATA|SEC_FILE_APPEND_DATA,       false,  },
     385             :         { "R",         SEC_FILE_READ_DATA|SEC_FILE_READ_EA,           true,   },
     386             :         { "R",         SEC_FILE_READ_DATA|SEC_FILE_WRITE_EA,          true,   },
     387             :         { "R",         SEC_FILE_READ_DATA|SEC_FILE_EXECUTE,           true,   },
     388             :         { "R",         SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE,    true,   },
     389             :         { "R",         SEC_FILE_READ_DATA|SEC_FILE_WRITE_ATTRIBUTE,   true,   },
     390             :         { "R",         SEC_FILE_READ_DATA|SEC_STD_DELETE,             false,  },
     391             :         { "R",         SEC_FILE_READ_DATA|SEC_STD_READ_CONTROL,       true,   },
     392             :         { "R",         SEC_FILE_READ_DATA|SEC_STD_WRITE_DAC,          true,   },
     393             :         { "R",         SEC_FILE_READ_DATA|SEC_STD_WRITE_OWNER,        true,   },
     394             :         { "R",         SEC_FILE_READ_DATA|SEC_STD_SYNCHRONIZE,        true,   },
     395             : 
     396             :         { "W",         SEC_FILE_WRITE_DATA|SEC_FILE_READ_DATA,        false,  },
     397             :         { "W",         SEC_FILE_WRITE_DATA,                           true,   },
     398             :         { "W",         SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA,      true,   },
     399             :         { "W",         SEC_FILE_WRITE_DATA|SEC_FILE_READ_EA,          true,   },
     400             :         { "W",         SEC_FILE_WRITE_DATA|SEC_FILE_WRITE_EA, true,   },
     401             :         { "W",         SEC_FILE_WRITE_DATA|SEC_FILE_EXECUTE,          false,  },
     402             :         { "W",         SEC_FILE_WRITE_DATA|SEC_FILE_READ_ATTRIBUTE,   true,   },
     403             :         { "W",         SEC_FILE_WRITE_DATA|SEC_FILE_WRITE_ATTRIBUTE,  true,   },
     404             :         { "W",         SEC_FILE_WRITE_DATA|SEC_STD_DELETE,            false,  },
     405             :         { "W",         SEC_FILE_WRITE_DATA|SEC_STD_READ_CONTROL,      true,   },
     406             :         { "W",         SEC_FILE_WRITE_DATA|SEC_STD_WRITE_DAC, true,   },
     407             :         { "W",         SEC_FILE_WRITE_DATA|SEC_STD_WRITE_OWNER,       true,   },
     408             :         { "W",         SEC_FILE_WRITE_DATA|SEC_STD_SYNCHRONIZE,       true,   },
     409             : 
     410             :         { "RW",  SEC_FILE_READ_DATA,                          true,   },
     411             :         { "RW",  SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA,      true,   },
     412             :         { "RW",  SEC_FILE_READ_DATA|SEC_FILE_APPEND_DATA,     true,   },
     413             :         { "RW",  SEC_FILE_READ_DATA|SEC_FILE_READ_EA,         true,   },
     414             :         { "RW",  SEC_FILE_READ_DATA|SEC_FILE_WRITE_EA,                true,   },
     415             :         { "RW",  SEC_FILE_READ_DATA|SEC_FILE_EXECUTE,         true,   },
     416             :         { "RW",  SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE,  true,   },
     417             :         { "RW",  SEC_FILE_READ_DATA|SEC_FILE_WRITE_ATTRIBUTE, true,   },
     418             :         { "RW",  SEC_FILE_READ_DATA|SEC_STD_DELETE,           false,  },
     419             :         { "RW",  SEC_FILE_READ_DATA|SEC_STD_READ_CONTROL,     true,   },
     420             :         { "RW",  SEC_FILE_READ_DATA|SEC_STD_WRITE_DAC,                true,   },
     421             :         { "RW",  SEC_FILE_READ_DATA|SEC_STD_WRITE_OWNER,      true,   },
     422             :         { "RW",  SEC_FILE_READ_DATA|SEC_STD_SYNCHRONIZE,      true,   },
     423             : 
     424             :         { "RD",  SEC_FILE_READ_DATA,                          true,   },
     425             :         { "RD",  SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA,      false,  },
     426             :         { "RD",  SEC_FILE_READ_DATA|SEC_FILE_APPEND_DATA,     false,  },
     427             :         { "RD",  SEC_FILE_READ_DATA|SEC_FILE_READ_EA,         true    },
     428             :         { "RD",  SEC_FILE_READ_DATA|SEC_FILE_WRITE_EA,                true,   },
     429             :         { "RD",  SEC_FILE_READ_DATA|SEC_FILE_EXECUTE,         true,   },
     430             :         { "RD",  SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE,  true,   },
     431             :         { "RD",  SEC_FILE_READ_DATA|SEC_FILE_WRITE_ATTRIBUTE, true,   },
     432             :         { "RD",  SEC_FILE_READ_DATA|SEC_STD_DELETE,           true,   },
     433             :         { "RD",  SEC_FILE_READ_DATA|SEC_STD_READ_CONTROL,     true,   },
     434             :         { "RD",  SEC_FILE_READ_DATA|SEC_STD_WRITE_DAC,                true,   },
     435             :         { "RD",  SEC_FILE_READ_DATA|SEC_STD_WRITE_OWNER,      true,   },
     436             :         { "RD",  SEC_FILE_READ_DATA|SEC_STD_SYNCHRONIZE,      true,   },
     437             : 
     438             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_FILE_READ_DATA,      false   },
     439             :         { "WD",  SEC_FILE_WRITE_DATA,                         true,   },
     440             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA,    true,   },
     441             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_FILE_READ_EA,                true    },
     442             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_FILE_WRITE_EA,       true,   },
     443             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_FILE_EXECUTE,                false   },
     444             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_FILE_READ_ATTRIBUTE, true,   },
     445             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_FILE_WRITE_ATTRIBUTE,        true,   },
     446             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_STD_DELETE,          true,   },
     447             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_STD_READ_CONTROL,    true,   },
     448             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_STD_WRITE_DAC,       true,   },
     449             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_STD_WRITE_OWNER,     true,   },
     450             :         { "WD",  SEC_FILE_WRITE_DATA|SEC_STD_SYNCHRONIZE,     true,   },
     451             : 
     452             :         { "RWD", SEC_FILE_READ_DATA,                          true    },
     453             :         { "RWD", SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA,      true,   },
     454             :         { "RWD", SEC_FILE_READ_DATA|SEC_FILE_APPEND_DATA,     true,   },
     455             :         { "RWD", SEC_FILE_READ_DATA|SEC_FILE_READ_EA,         true,   },
     456             :         { "RWD", SEC_FILE_READ_DATA|SEC_FILE_WRITE_EA,                true,   },
     457             :         { "RWD", SEC_FILE_READ_DATA|SEC_FILE_EXECUTE,         true,   },
     458             :         { "RWD", SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE,  true,   },
     459             :         { "RWD", SEC_FILE_READ_DATA|SEC_FILE_WRITE_ATTRIBUTE, true,   },
     460             :         { "RWD", SEC_FILE_READ_DATA|SEC_STD_DELETE,           true,   },
     461             :         { "RWD", SEC_FILE_READ_DATA|SEC_STD_READ_CONTROL,     true,   },
     462             :         { "RWD", SEC_FILE_READ_DATA|SEC_STD_WRITE_DAC,                true,   },
     463             :         { "RWD", SEC_FILE_READ_DATA|SEC_STD_WRITE_OWNER,      true,   },
     464             :         { "RWD", SEC_FILE_READ_DATA|SEC_STD_SYNCHRONIZE,      true,   },
     465             : };
     466             : 
     467             : /*
     468             :  * Test conflicting sharemodes through SMB2: First open takes a
     469             :  * sharemode, second open with potentially conflicting access.
     470             :  */
     471           5 : static bool test_smb2_sharemode_access(struct torture_context *tctx,
     472             :                                        struct smb2_tree *tree1,
     473             :                                        struct smb2_tree *tree2)
     474             : {
     475           5 :         const char *fname = "test_sharemode";
     476           0 :         NTSTATUS status;
     477           5 :         bool ret = true;
     478           0 :         int i;
     479             : 
     480         693 :         for (i = 0; i < ARRAY_SIZE(sharemode_table); i++) {
     481         689 :                 struct sharemode_info *info = &sharemode_table[i];
     482         689 :                 struct smb2_create create1 = { 0 }, create2 = { 0 };
     483           0 :                 NTSTATUS expected_status;
     484             : 
     485         689 :                 torture_comment(tctx, "index %3d, sharemode %3s, "
     486             :                                 "access mask 0x%06x\n",
     487             :                                 i, info->sharemode, info->access_mask);
     488             : 
     489         689 :                 create1.in.desired_access = SEC_RIGHTS_FILE_ALL;
     490         689 :                 create1.in.alloc_size = 0;
     491         689 :                 create1.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     492         689 :                 create1.in.share_access =
     493         689 :                         smb2_util_share_access(info->sharemode);
     494         689 :                 create1.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     495         689 :                 create1.in.create_options = 0;
     496         689 :                 create1.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     497         689 :                 create1.in.fname = fname;
     498         689 :                 create1.in.security_flags = 0;
     499         689 :                 create1.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     500         689 :                 create1.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
     501             : 
     502         689 :                 status = smb2_create(tree1, tctx, &create1);
     503             : 
     504         689 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     505             :                                                 "CREATE file failed\n");
     506             : 
     507         689 :                 create2.in.desired_access = info->access_mask;
     508         689 :                 create2.in.alloc_size = 0;
     509         689 :                 create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     510         689 :                 create2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     511             :                         NTCREATEX_SHARE_ACCESS_WRITE |
     512             :                         NTCREATEX_SHARE_ACCESS_DELETE;
     513         689 :                 create2.in.create_disposition = NTCREATEX_DISP_OPEN;
     514         689 :                 create2.in.create_options = 0;
     515         689 :                 create2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     516         689 :                 create2.in.fname = fname;
     517         689 :                 create2.in.security_flags = 0;
     518         689 :                 create2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     519         689 :                 create2.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
     520             : 
     521         689 :                 status = smb2_create(tree2, tctx, &create2);
     522         689 :                 expected_status = info->expect_ok ?
     523         169 :                         NT_STATUS_OK : NT_STATUS_SHARING_VIOLATION;
     524         689 :                 torture_assert_ntstatus_equal_goto(tctx, status,
     525             :                                                    expected_status, ret,
     526             :                                                    done, "Unexpected status on "
     527             :                                                    "second create.\n");
     528             : 
     529         688 :                 status = smb2_util_close(tree1, create1.out.file.handle);
     530         688 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     531             :                                                 "Failed to close "
     532             :                                                 "first handle.\n");
     533             : 
     534         688 :                 if (info->expect_ok) {
     535         581 :                         status = smb2_util_close(tree2, create2.out.file.handle);
     536         581 :                         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     537             :                                                         "Failed to close  "
     538             :                                                         "second handle.\n");
     539             :                 }
     540             :         }
     541             : 
     542           4 : done:
     543           5 :         smb2_util_unlink(tree1, fname);
     544           5 :         return ret;
     545             : }
     546             : 
     547             : /*
     548             :  * Test conflicting sharemodes through SMB2: First open file with
     549             :  * different access masks, second open requests potentially conflicting
     550             :  * sharemode.
     551             :  */
     552           5 : static bool test_smb2_access_sharemode(struct torture_context *tctx,
     553             :                                        struct smb2_tree *tree1,
     554             :                                        struct smb2_tree *tree2)
     555             : {
     556           5 :         const char *fname = "test_sharemode";
     557           0 :         NTSTATUS status;
     558           5 :         bool ret = true;
     559           0 :         int i;
     560             : 
     561         693 :         for (i = 0; i < ARRAY_SIZE(sharemode_table); i++) {
     562         689 :                 struct sharemode_info *info = &sharemode_table[i];
     563         689 :                 struct smb2_create create1 = { 0 }, create2 = { 0 };
     564           0 :                 NTSTATUS expected_status;
     565             : 
     566         689 :                 torture_comment(tctx, "index %3d, access mask 0x%06x, "
     567             :                                 "sharemode %3s\n",
     568             :                                 i, info->access_mask, info->sharemode);
     569             : 
     570         689 :                 create1.in.desired_access = info->access_mask;
     571         689 :                 create1.in.alloc_size = 0;
     572         689 :                 create1.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     573         689 :                 create1.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     574             :                         NTCREATEX_SHARE_ACCESS_WRITE |
     575             :                         NTCREATEX_SHARE_ACCESS_DELETE;
     576         689 :                 create1.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     577         689 :                 create1.in.create_options = 0;
     578         689 :                 create1.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     579         689 :                 create1.in.fname = fname;
     580         689 :                 create1.in.security_flags = 0;
     581         689 :                 create1.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     582         689 :                 create1.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
     583             : 
     584         689 :                 status = smb2_create(tree1, tctx, &create1);
     585             : 
     586         689 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     587             :                                                 "CREATE file failed\n");
     588             : 
     589         688 :                 create2.in.desired_access = SEC_RIGHTS_FILE_ALL;
     590         688 :                 create2.in.alloc_size = 0;
     591         688 :                 create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     592         688 :                 create2.in.share_access =
     593         688 :                         smb2_util_share_access(info->sharemode);
     594         688 :                 create2.in.create_disposition = NTCREATEX_DISP_OPEN;
     595         688 :                 create2.in.create_options = 0;
     596         688 :                 create2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     597         688 :                 create2.in.fname = fname;
     598         688 :                 create2.in.security_flags = 0;
     599         688 :                 create2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     600         688 :                 create2.in.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
     601             : 
     602         688 :                 status = smb2_create(tree2, tctx, &create2);
     603             : 
     604         688 :                 expected_status = info->expect_ok ?
     605         169 :                         NT_STATUS_OK : NT_STATUS_SHARING_VIOLATION;
     606         688 :                 torture_assert_ntstatus_equal_goto(tctx, status,
     607             :                                                    expected_status, ret,
     608             :                                                    done, "Unexpected status on "
     609             :                                                    "second create.\n");
     610             : 
     611         688 :                 status = smb2_util_close(tree1, create1.out.file.handle);
     612         688 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     613             :                                                 "Failed to close "
     614             :                                                 "first handle.\n");
     615             : 
     616         688 :                 if (info->expect_ok) {
     617         581 :                         status = smb2_util_close(tree2, create2.out.file.handle);
     618         581 :                         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     619             :                                                         "Failed to close "
     620             :                                                         "second handle.\n");
     621             :                 }
     622             :         }
     623             : 
     624           4 : done:
     625           5 :         smb2_util_unlink(tree1, fname);
     626           5 :         return ret;
     627             : }
     628             : 
     629             : /*
     630             :  * Test initial stat open with share nothing doesn't trigger SHARING_VIOLTION
     631             :  * errors.
     632             :  */
     633           5 : static bool test_smb2_bug14375(struct torture_context *tctx,
     634             :                                struct smb2_tree *tree)
     635             : {
     636           5 :         const char *fname = "test_bug14375";
     637           0 :         struct smb2_create cr1;
     638           0 :         struct smb2_create cr2;
     639           0 :         struct smb2_create cr3;
     640           0 :         NTSTATUS status;
     641           5 :         bool ret = true;
     642             : 
     643           5 :         smb2_util_unlink(tree, fname);
     644             : 
     645           5 :         cr1 = (struct smb2_create) {
     646             :                 .in.desired_access = SEC_FILE_READ_ATTRIBUTE,
     647             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
     648             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_NONE,
     649             :                 .in.create_disposition = NTCREATEX_DISP_CREATE,
     650             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
     651             :                 .in.fname = fname,
     652             :         };
     653             : 
     654           5 :         status = smb2_create(tree, tctx, &cr1);
     655           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     656             :                                         "CREATE file failed\n");
     657             : 
     658           5 :         cr2 = (struct smb2_create) {
     659             :                 .in.desired_access = SEC_FILE_READ_DATA,
     660             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
     661             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
     662             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
     663             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
     664             :                 .in.fname = fname,
     665             :         };
     666             : 
     667           5 :         status = smb2_create(tree, tctx, &cr2);
     668           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     669             :                                         "CREATE file failed\n");
     670             : 
     671           5 :         cr3 = (struct smb2_create) {
     672             :                 .in.desired_access = SEC_FILE_READ_DATA,
     673             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
     674             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
     675             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
     676             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
     677             :                 .in.fname = fname,
     678             :         };
     679             : 
     680           5 :         status = smb2_create(tree, tctx, &cr3);
     681           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     682             :                                         "CREATE file failed\n");
     683             : 
     684           5 :         status = smb2_util_close(tree, cr1.out.file.handle);
     685           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     686             :                                         "CLOSE file failed\n");
     687           5 :         status = smb2_util_close(tree, cr2.out.file.handle);
     688           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     689             :                                         "CLOSE file failed\n");
     690           5 :         status = smb2_util_close(tree, cr3.out.file.handle);
     691           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     692             :                                         "CLOSE file failed\n");
     693             : 
     694           5 :         cr1 = (struct smb2_create) {
     695             :                 .in.desired_access = SEC_FILE_READ_DATA,
     696             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
     697             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
     698             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
     699             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
     700             :                 .in.fname = fname,
     701             :         };
     702             : 
     703           5 :         status = smb2_create(tree, tctx, &cr1);
     704           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     705             :                                         "CREATE file failed\n");
     706             : 
     707           5 :         cr2 = (struct smb2_create) {
     708             :                 .in.desired_access = SEC_FILE_READ_ATTRIBUTE,
     709             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
     710             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_NONE,
     711             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
     712             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
     713             :                 .in.fname = fname,
     714             :         };
     715             : 
     716           5 :         status = smb2_create(tree, tctx, &cr2);
     717           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     718             :                                         "CREATE file failed\n");
     719             : 
     720           5 :         cr3 = (struct smb2_create) {
     721             :                 .in.desired_access = SEC_FILE_READ_DATA,
     722             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
     723             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
     724             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
     725             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
     726             :                 .in.fname = fname,
     727             :         };
     728             : 
     729           5 :         status = smb2_create(tree, tctx, &cr3);
     730           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     731             :                                         "CREATE file failed\n");
     732             : 
     733           5 : done:
     734           5 :         smb2_util_close(tree, cr1.out.file.handle);
     735           5 :         smb2_util_close(tree, cr2.out.file.handle);
     736           5 :         smb2_util_close(tree, cr3.out.file.handle);
     737           5 :         smb2_util_unlink(tree, fname);
     738           5 :         return ret;
     739             : }
     740             : 
     741        2358 : struct torture_suite *torture_smb2_sharemode_init(TALLOC_CTX *ctx)
     742             : {
     743        2358 :         struct torture_suite *suite = torture_suite_create(ctx, "sharemode");
     744             : 
     745        2358 :         torture_suite_add_2smb2_test(suite, "sharemode-access",
     746             :                                      test_smb2_sharemode_access);
     747        2358 :         torture_suite_add_2smb2_test(suite, "access-sharemode",
     748             :                                      test_smb2_access_sharemode);
     749        2358 :         torture_suite_add_1smb2_test(suite, "bug14375",
     750             :                                      test_smb2_bug14375);
     751             : 
     752        2358 :         suite->description = talloc_strdup(suite, "SMB2-SHAREMODE tests");
     753             : 
     754        2358 :         return suite;
     755             : }

Generated by: LCOV version 1.14