LCOV - code coverage report
Current view: top level - source4/torture/smb2 - attr.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 255 297 85.9 %
Date: 2024-04-21 15:09:00 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    openattr tester
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003
       7             :    Copyright (C) David Mulder 2019
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "libcli/smb2/smb2.h"
      25             : #include "libcli/smb2/smb2_calls.h"
      26             : #include "torture/torture.h"
      27             : #include "libcli/security/security_descriptor.h"
      28             : #include "torture/smb2/proto.h"
      29             : 
      30             : static const uint32_t open_attrs_table[] = {
      31             :                 FILE_ATTRIBUTE_NORMAL,
      32             :                 FILE_ATTRIBUTE_ARCHIVE,
      33             :                 FILE_ATTRIBUTE_READONLY,
      34             :                 FILE_ATTRIBUTE_HIDDEN,
      35             :                 FILE_ATTRIBUTE_SYSTEM,
      36             : 
      37             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
      38             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
      39             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
      40             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
      41             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
      42             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
      43             : 
      44             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
      45             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
      46             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
      47             :                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
      48             : };
      49             : 
      50             : struct trunc_open_results {
      51             :         unsigned int num;
      52             :         uint32_t init_attr;
      53             :         uint32_t trunc_attr;
      54             :         uint32_t result_attr;
      55             : };
      56             : 
      57             : static const struct trunc_open_results attr_results[] = {
      58             :         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
      59             :         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
      60             :         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
      61             :         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
      62             :         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
      63             :         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
      64             :         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
      65             :         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
      66             :         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
      67             :         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
      68             :         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
      69             :         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
      70             :         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
      71             :         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
      72             :         { 104, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
      73             :         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
      74             :         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
      75             :         { 121, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
      76             :         { 170, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN },
      77             :         { 173, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM },
      78             :         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
      79             :         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
      80             :         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
      81             :         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
      82             :         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
      83             :         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
      84             : };
      85             : 
      86         249 : static NTSTATUS smb2_setatr(struct smb2_tree *tree, const char *name,
      87             :                             uint32_t attrib)
      88             : {
      89           0 :         NTSTATUS status;
      90         249 :         struct smb2_create create_io = {0};
      91           0 :         union smb_setfileinfo io;
      92             : 
      93         249 :         create_io.in.desired_access = SEC_FILE_READ_DATA |
      94             :                                       SEC_FILE_WRITE_ATTRIBUTE;
      95         249 :         create_io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
      96         249 :         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
      97         249 :         create_io.in.create_disposition = NTCREATEX_DISP_OPEN;
      98         249 :         create_io.in.fname = name;
      99         249 :         status = smb2_create(tree, tree, &create_io);
     100         249 :         if (!NT_STATUS_IS_OK(status)) {
     101           5 :                 return status;
     102             :         }
     103             : 
     104         244 :         ZERO_STRUCT(io);
     105         244 :         io.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION;
     106         244 :         io.basic_info.in.file.handle = create_io.out.file.handle;
     107         244 :         io.basic_info.in.attrib = attrib;
     108         244 :         status = smb2_setinfo_file(tree, &io);
     109         244 :         if (!NT_STATUS_IS_OK(status)) {
     110           0 :                 return status;
     111             :         }
     112             : 
     113         244 :         status = smb2_util_close(tree, create_io.out.file.handle);
     114         244 :         if (!NT_STATUS_IS_OK(status)) {
     115           0 :                 return status;
     116             :         }
     117             : 
     118         244 :         return status;
     119             : }
     120             : 
     121           5 : bool torture_smb2_openattrtest(struct torture_context *tctx,
     122             :                                struct smb2_tree *tree)
     123             : {
     124           0 :         NTSTATUS status;
     125           5 :         const char *fname = "openattr.file";
     126           0 :         uint16_t attr;
     127           0 :         unsigned int i, j, k, l;
     128           5 :         int ret = true;
     129             : 
     130          85 :         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
     131          80 :                 struct smb2_create create_io = {0};
     132          80 :                 smb2_setatr(tree, fname, FILE_ATTRIBUTE_NORMAL);
     133          80 :                 smb2_util_unlink(tree, fname);
     134          80 :                 create_io.in.create_flags = 0;
     135          80 :                 create_io.in.desired_access = SEC_FILE_WRITE_DATA;
     136          80 :                 create_io.in.file_attributes = open_attrs_table[i];
     137          80 :                 create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     138          80 :                 create_io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     139          80 :                 create_io.in.create_options = 0;
     140          80 :                 create_io.in.security_flags = 0;
     141          80 :                 create_io.in.fname = fname;
     142          80 :                 status = smb2_create(tree, tctx, &create_io);
     143          80 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     144             :                         talloc_asprintf(tctx, "open %d (1) of %s failed (%s)",
     145             :                         i, fname, nt_errstr(status)));
     146             : 
     147          80 :                 status = smb2_util_close(tree, create_io.out.file.handle);
     148          80 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     149             :                         talloc_asprintf(tctx, "close %d (1) of %s failed (%s)",
     150             :                         i, fname, nt_errstr(status)));
     151             : 
     152        1360 :                 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
     153        1280 :                         create_io = (struct smb2_create){0};
     154        1280 :                         create_io.in.create_flags = 0;
     155        1280 :                         create_io.in.desired_access = SEC_FILE_READ_DATA|
     156             :                                                       SEC_FILE_WRITE_DATA;
     157        1280 :                         create_io.in.file_attributes = open_attrs_table[j];
     158        1280 :                         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     159        1280 :                         create_io.in.create_disposition = NTCREATEX_DISP_OVERWRITE;
     160        1280 :                         create_io.in.create_options = 0;
     161        1280 :                         create_io.in.security_flags = 0;
     162        1280 :                         create_io.in.fname = fname;
     163        1280 :                         status = smb2_create(tree, tctx, &create_io);
     164             : 
     165        1280 :                         if (!NT_STATUS_IS_OK(status)) {
     166       24840 :                                 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
     167       23920 :                                         torture_assert_goto(tctx,
     168             :                                                 attr_results[l].num != k,
     169             :                                                 ret, error_exit,
     170             :                                                 talloc_asprintf(tctx,
     171             :                                                         "[%d] trunc open 0x%x "
     172             :                                                         "-> 0x%x of %s failed "
     173             :                                                         "- should have "
     174             :                                                         "succeeded !(%s)",
     175             :                                                         k, open_attrs_table[i],
     176             :                                                         open_attrs_table[j],
     177             :                                                         fname,
     178             :                                                         nt_errstr(status)));
     179             :                                 }
     180         920 :                                 torture_assert_ntstatus_equal_goto(tctx,
     181             :                                         status, NT_STATUS_ACCESS_DENIED,
     182             :                                         ret, error_exit,
     183             :                                         talloc_asprintf(tctx,
     184             :                                                         "[%d] trunc open 0x%x "
     185             :                                                         "-> 0x%x failed with "
     186             :                                                         "wrong error code %s",
     187             :                                                         k, open_attrs_table[i],
     188             :                                                         open_attrs_table[j],
     189             :                                                         nt_errstr(status)));
     190         920 :                                 k++;
     191         920 :                                 continue;
     192             :                         }
     193             : 
     194         360 :                         status = smb2_util_close(tree, create_io.out.file.handle);
     195         360 :                         torture_assert_ntstatus_ok_goto(tctx, status, ret,
     196             :                                 error_exit, talloc_asprintf(tctx,
     197             :                                         "close %d (2) of %s failed (%s)", j,
     198             :                                         fname, nt_errstr(status)));
     199             : 
     200         360 :                         status = smb2_util_getatr(tree, fname, &attr, NULL, NULL);
     201         360 :                         torture_assert_ntstatus_ok_goto(tctx, status, ret,
     202             :                                 error_exit, talloc_asprintf(tctx,
     203             :                                         "getatr(2) failed (%s)",
     204             :                                         nt_errstr(status)));
     205             : 
     206        7965 :                         for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
     207        7735 :                                 if (attr_results[l].num == k) {
     208         130 :                                         if (attr != attr_results[l].result_attr ||
     209         130 :                                             open_attrs_table[i] != attr_results[l].init_attr ||
     210         130 :                                             open_attrs_table[j] != attr_results[l].trunc_attr) {
     211           0 :                                                 ret = false;
     212           0 :                                                 torture_fail_goto(tctx, error_exit,
     213             :                                                         talloc_asprintf(tctx,
     214             :                                                         "[%d] getatr check "
     215             :                                                         "failed. [0x%x] trunc "
     216             :                                                         "[0x%x] got attr 0x%x,"
     217             :                                                         " should be 0x%x",
     218             :                                                         k, open_attrs_table[i],
     219             :                                                         open_attrs_table[j],
     220             :                                                         (unsigned int)attr,
     221             :                                                         attr_results[l].result_attr));
     222             :                                         }
     223         130 :                                         break;
     224             :                                 }
     225             :                         }
     226         360 :                         k++;
     227             :                 }
     228             :         }
     229           5 : error_exit:
     230           5 :         smb2_setatr(tree, fname, FILE_ATTRIBUTE_NORMAL);
     231           5 :         smb2_util_unlink(tree, fname);
     232             : 
     233             : 
     234           5 :         return ret;
     235             : }
     236             : 
     237           5 : bool torture_smb2_winattrtest(struct torture_context *tctx,
     238             :                               struct smb2_tree *tree)
     239             : {
     240           5 :         const char *fname = "winattr1.file";
     241           5 :         const char *dname = "winattr1.dir";
     242           0 :         uint16_t attr;
     243           0 :         uint16_t j;
     244           0 :         uint32_t aceno;
     245           5 :         bool ret = true;
     246           0 :         union smb_fileinfo query, query_org;
     247           0 :         NTSTATUS status;
     248           5 :         struct security_descriptor *sd1 = NULL, *sd2 = NULL;
     249           5 :         struct smb2_create create_io = {0};
     250           5 :         ZERO_STRUCT(query);
     251           5 :         ZERO_STRUCT(query_org);
     252             : 
     253             :         /* Test winattrs for file */
     254           5 :         smb2_util_unlink(tree, fname);
     255             : 
     256             :         /* Open a file*/
     257           5 :         create_io.in.create_flags = 0;
     258           5 :         create_io.in.desired_access = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA |
     259             :                                 SEC_STD_READ_CONTROL;
     260           5 :         create_io.in.file_attributes = 0;
     261           5 :         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     262           5 :         create_io.in.create_disposition = FILE_SUPERSEDE;
     263           5 :         create_io.in.create_options = 0;
     264           5 :         create_io.in.security_flags = 0;
     265           5 :         create_io.in.fname = fname;
     266           5 :         status = smb2_create(tree, tctx, &create_io);
     267           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     268             :                 talloc_asprintf(tctx, "open(1) of %s failed (%s)\n",
     269             :                 fname, nt_errstr(status)));
     270             : 
     271             :         /* Get security descriptor and store it*/
     272           5 :         query_org.generic.level = RAW_FILEINFO_SEC_DESC;
     273           5 :         query_org.generic.in.file.handle = create_io.out.file.handle;
     274           5 :         query_org.query_secdesc.in.secinfo_flags = SECINFO_OWNER|
     275             :                                                 SECINFO_GROUP|
     276             :                                                 SECINFO_DACL;
     277           5 :         status = smb2_getinfo_file(tree, tctx, &query_org);
     278           5 :         if(!NT_STATUS_IS_OK(status)){
     279           0 :                 NTSTATUS s = smb2_util_close(tree, create_io.out.file.handle);
     280           0 :                 torture_assert_ntstatus_ok_goto(tctx, s, ret, error_exit,
     281             :                                 talloc_asprintf(tctx,
     282             :                                         "close(1) of %s failed (%s)\n",
     283             :                                         fname, nt_errstr(s)));
     284           0 :                 ret = false;
     285           0 :                 torture_fail_goto(tctx, error_exit, talloc_asprintf(tctx,
     286             :                         "smb2_getinfo_file(1) of %s failed (%s)\n",
     287             :                         fname, nt_errstr(status)));
     288             :         }
     289           5 :         sd1 = query_org.query_secdesc.out.sd;
     290             : 
     291           5 :         status = smb2_util_close(tree, create_io.out.file.handle);
     292           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     293             :                        talloc_asprintf(tctx, "close(1) of %s failed (%s)\n",
     294             :                                        fname, nt_errstr(status)));
     295             : 
     296             :         /*Set and get attributes*/
     297          85 :         for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
     298          80 :                 status = smb2_setatr(tree, fname, open_attrs_table[j]);
     299          80 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret,
     300             :                         error_exit,
     301             :                         talloc_asprintf(tctx, "setatr(2) failed (%s)",
     302             :                                 nt_errstr(status)));
     303             : 
     304          80 :                 status = smb2_util_getatr(tree, fname, &attr, NULL, NULL);
     305          80 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret,
     306             :                         error_exit,
     307             :                         talloc_asprintf(tctx, "getatr(2) failed (%s)",
     308             :                         nt_errstr(status)));
     309             : 
     310             :                 /* Check the result */
     311          80 :                 torture_assert_goto(tctx, attr == open_attrs_table[j], ret,
     312             :                         error_exit, talloc_asprintf(tctx,
     313             :                                 "getatr check failed. \
     314             :                                 Attr applied [0x%x],got attr 0x%x, \
     315             :                                 should be 0x%x ", open_attrs_table[j],
     316             :                                 (uint16_t)attr, open_attrs_table[j]));
     317             : 
     318          80 :                 create_io = (struct smb2_create){0};
     319          80 :                 create_io.in.create_flags = 0;
     320          80 :                 create_io.in.desired_access = SEC_FILE_READ_ATTRIBUTE|
     321             :                                                 SEC_STD_READ_CONTROL;
     322          80 :                 create_io.in.file_attributes = 0;
     323          80 :                 create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     324          80 :                 create_io.in.create_disposition = FILE_OPEN_IF;
     325          80 :                 create_io.in.create_options = 0;
     326          80 :                 create_io.in.security_flags = 0;
     327          80 :                 create_io.in.fname = fname;
     328          80 :                 status = smb2_create(tree, tctx, &create_io);
     329          80 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret,
     330             :                         error_exit,
     331             :                         talloc_asprintf(tctx, "open(2) of %s failed (%s)\n",
     332             :                         fname, nt_errstr(status)));
     333             :                 /*Get security descriptor */
     334          80 :                 query.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     335          80 :                 query.query_secdesc.in.file.handle = create_io.out.file.handle;
     336          80 :                 query.query_secdesc.in.secinfo_flags = SECINFO_OWNER|
     337             :                                                 SECINFO_GROUP|
     338             :                                                 SECINFO_DACL;
     339          80 :                 status = smb2_getinfo_file(tree, tctx, &query);
     340          80 :                 if(!NT_STATUS_IS_OK(status)){
     341           0 :                         NTSTATUS s = smb2_util_close(tree, create_io.out.file.handle);
     342           0 :                         torture_assert_ntstatus_ok_goto(tctx, s, ret,
     343             :                                 error_exit,
     344             :                                 talloc_asprintf(tctx,
     345             :                                         "close(2) of %s failed (%s)\n",
     346             :                                         fname, nt_errstr(s)));
     347           0 :                         ret = false;
     348           0 :                         torture_fail_goto(tctx, error_exit,
     349             :                                 talloc_asprintf(tctx,
     350             :                                 "smb2_getinfo_file(2) of %s failed (%s)\n",
     351             :                                 fname, nt_errstr(status)));
     352             :                 }
     353          80 :                 sd2 = query.query_secdesc.out.sd;
     354             : 
     355          80 :                 status = smb2_util_close(tree, create_io.out.file.handle);
     356          80 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     357             :                        talloc_asprintf(tctx, "close(2) of %s failed (%s)\n",
     358             :                                        fname, nt_errstr(status)));
     359             : 
     360             :                 /*Compare security descriptors -- Must be same*/
     361         336 :                 for (aceno=0;(sd1->dacl&&aceno < sd1->dacl->num_aces);aceno++){
     362         256 :                         struct security_ace *ace1 = &sd1->dacl->aces[aceno];
     363         256 :                         struct security_ace *ace2 = &sd2->dacl->aces[aceno];
     364             : 
     365         256 :                         torture_assert_goto(tctx, security_ace_equal(ace1, ace2),
     366             :                                 ret, error_exit,
     367             :                                 "ACLs changed! Not expected!\n");
     368             :                 }
     369             : 
     370          80 :                 torture_comment(tctx, "[%d] setattr = [0x%x] got attr 0x%x\n",
     371          80 :                         j,  open_attrs_table[j], attr );
     372             : 
     373             :         }
     374             : 
     375             : 
     376             : /* Check for Directory. */
     377             : 
     378           5 :         smb2_deltree(tree, dname);
     379           5 :         smb2_util_rmdir(tree, dname);
     380             : 
     381             :         /* Open a directory */
     382           5 :         create_io = (struct smb2_create){0};
     383           5 :         create_io.in.create_flags = 0;
     384           5 :         create_io.in.desired_access = SEC_RIGHTS_DIR_ALL;
     385           5 :         create_io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     386           5 :         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     387           5 :         create_io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     388           5 :         create_io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     389           5 :         create_io.in.security_flags = 0;
     390           5 :         create_io.in.fname = dname;
     391           5 :         status = smb2_create(tree, tctx, &create_io);
     392             : 
     393           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     394             :                         talloc_asprintf(tctx,
     395             :                         "open (1) of %s failed (%s)",
     396             :                         dname, nt_errstr(status)));
     397             : 
     398             : 
     399             :         /* Get Security Descriptor */
     400           5 :         query_org.generic.level = RAW_FILEINFO_SEC_DESC;
     401           5 :         query_org.generic.in.file.handle = create_io.out.file.handle;
     402           5 :         status = smb2_getinfo_file(tree, tctx, &query_org);
     403           5 :         if(!NT_STATUS_IS_OK(status)){
     404           0 :                 NTSTATUS s = smb2_util_close(tree, create_io.out.file.handle);
     405           0 :                 torture_assert_ntstatus_ok_goto(tctx, s, ret, error_exit,
     406             :                                 talloc_asprintf(tctx,
     407             :                                         "close(1) of %s failed (%s)\n",
     408             :                                         dname, nt_errstr(s)));
     409           0 :                 ret = false;
     410           0 :                 torture_fail_goto(tctx, error_exit, talloc_asprintf(tctx,
     411             :                         "smb2_getinfo_file(1) of %s failed (%s)\n", dname,
     412             :                         nt_errstr(status)));
     413             :         }
     414           5 :         sd1 = query_org.query_secdesc.out.sd;
     415             : 
     416           5 :         status = smb2_util_close(tree, create_io.out.file.handle);
     417           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     418             :                                 talloc_asprintf(tctx,
     419             :                                 "close (1) of %s failed (%s)", dname,
     420             :                                 nt_errstr(status)));
     421             : 
     422             :         /* Set and get win attributes*/
     423          80 :         for (j = 1; j < ARRAY_SIZE(open_attrs_table); j++) {
     424             : 
     425          75 :                 status = smb2_setatr(tree, dname, open_attrs_table[j]);
     426          75 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     427             :                         talloc_asprintf(tctx, "setatr(2) failed (%s)",
     428             :                                 nt_errstr(status)));
     429             : 
     430          75 :                 status = smb2_util_getatr(tree, dname, &attr, NULL, NULL);
     431          75 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     432             :                         talloc_asprintf(tctx, "getatr(2) failed (%s)",
     433             :                                 nt_errstr(status)));
     434             : 
     435          75 :                 torture_comment(tctx, "[%d] setatt = [0x%x] got attr 0x%x\n",
     436          75 :                         j,  open_attrs_table[j], attr );
     437             : 
     438             :                 /* Check the result */
     439          75 :                 torture_assert_goto(tctx,
     440             :                         attr == (open_attrs_table[j]|FILE_ATTRIBUTE_DIRECTORY),
     441             :                         ret, error_exit, talloc_asprintf(tctx,
     442             :                         "getatr check failed. set attr "
     443             :                         "[0x%x], got attr 0x%x, should be 0x%x\n",
     444             :                         open_attrs_table[j], (uint16_t)attr,
     445             :                         (unsigned int)(open_attrs_table[j]|FILE_ATTRIBUTE_DIRECTORY)));
     446             : 
     447          75 :                 create_io = (struct smb2_create){0};
     448          75 :                 create_io.in.create_flags = 0;
     449          75 :                 create_io.in.desired_access = SEC_RIGHTS_DIR_READ;
     450          75 :                 create_io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     451          75 :                 create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     452          75 :                 create_io.in.create_disposition = NTCREATEX_DISP_OPEN;
     453          75 :                 create_io.in.create_options = 0;
     454          75 :                 create_io.in.security_flags = 0;
     455          75 :                 create_io.in.fname = dname;
     456          75 :                 status = smb2_create(tree, tctx, &create_io);
     457             : 
     458          75 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     459             :                         talloc_asprintf(tctx,
     460             :                         "open (2) of %s failed (%s)",
     461             :                         dname, nt_errstr(status)));
     462             :                 /* Get security descriptor */
     463          75 :                 query.generic.level = RAW_FILEINFO_SEC_DESC;
     464          75 :                 query.generic.in.file.handle = create_io.out.file.handle;
     465          75 :                 status = smb2_getinfo_file(tree, tctx, &query);
     466          75 :                 if(!NT_STATUS_IS_OK(status)){
     467           0 :                         NTSTATUS s = smb2_util_close(tree, create_io.out.file.handle);
     468           0 :                         torture_assert_ntstatus_ok_goto(tctx, s, ret, error_exit,
     469             :                                         talloc_asprintf(tctx,
     470             :                                         "close (2) of %s failed (%s)", dname,
     471             :                                         nt_errstr(s)));
     472           0 :                         ret = false;
     473           0 :                         torture_fail_goto(tctx, error_exit,
     474             :                                 talloc_asprintf(tctx,
     475             :                                 "smb2_getinfo_file(2) of %s failed(%s)\n",
     476             :                                 dname, nt_errstr(status)));
     477             :                 }
     478          75 :                 sd2 = query.query_secdesc.out.sd;
     479          75 :                 status = smb2_util_close(tree, create_io.out.file.handle);
     480          75 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     481             :                                 talloc_asprintf(tctx,
     482             :                                 "close (2) of %s failed (%s)", dname,
     483             :                                 nt_errstr(status)));
     484             : 
     485             :                 /* Security descriptor must be same*/
     486         435 :                 for (aceno=0;(sd1->dacl&&aceno < sd1->dacl->num_aces);aceno++){
     487         360 :                         struct security_ace *ace1 = &sd1->dacl->aces[aceno];
     488         360 :                         struct security_ace *ace2 = &sd2->dacl->aces[aceno];
     489             : 
     490         360 :                         torture_assert_goto(tctx, security_ace_equal(ace1, ace2),
     491             :                                 ret, error_exit,
     492             :                                 "ACLs changed! Not expected!\n");
     493             :                 }
     494             : 
     495             :         }
     496             : 
     497           5 : error_exit:
     498           5 :         smb2_setatr(tree, fname, FILE_ATTRIBUTE_NORMAL);
     499           5 :         smb2_util_unlink(tree, fname);
     500           5 :         smb2_deltree(tree, dname);
     501           5 :         smb2_util_rmdir(tree, dname);
     502             : 
     503           5 :         return ret;
     504             : }
     505             : 
     506           5 : bool torture_smb2_winattr2(struct torture_context *tctx,
     507             :                            struct smb2_tree *tree)
     508             : {
     509           5 :         const char *fname = "winattr2.file";
     510           5 :         struct smb2_create c = {0};
     511           0 :         NTSTATUS status;
     512           5 :         bool ret = true;
     513             : 
     514           5 :         smb2_util_unlink(tree, fname);
     515             : 
     516             :         /* Create a file with FILE_ATTRIBUTE_ARCHIVE */
     517           5 :         c = (struct smb2_create) {
     518             :                 .in.desired_access = SEC_FILE_READ_DATA,
     519             :                 .in.file_attributes = FILE_ATTRIBUTE_ARCHIVE,
     520             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_NONE,
     521             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
     522             :                 .in.fname = fname,
     523             :         };
     524             : 
     525           5 :         status = smb2_create(tree, tctx, &c);
     526           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     527             :                                         "smb2_create failed\n");
     528             : 
     529           5 :         status = smb2_util_close(tree, c.out.file.handle);
     530           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     531             :                                         "smb2_util_close failed\n");
     532             : 
     533             :         /* Reopen file with different attributes */
     534           5 :         c = (struct smb2_create) {
     535             :                 .in.desired_access = SEC_FILE_READ_DATA,
     536             :                 .in.file_attributes = FILE_ATTRIBUTE_ARCHIVE |
     537             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN |
     538             :                         FILE_ATTRIBUTE_READONLY,
     539             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_NONE,
     540             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
     541             :                 .in.fname = fname,
     542             :         };
     543             : 
     544           5 :         status = smb2_create(tree, tctx, &c);
     545           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     546             :                                         "smb2_create failed\n");
     547             : 
     548           5 :         status = smb2_util_close(tree, c.out.file.handle);
     549           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     550             :                                         "smb2_util_close failed\n");
     551             : 
     552           5 :         torture_assert_int_equal_goto(tctx,
     553             :                                       c.out.file_attr,
     554             :                                       FILE_ATTRIBUTE_ARCHIVE,
     555             :                                       ret, done,
     556             :                                       "Wrong attributes\n");
     557             : 
     558           5 : done:
     559           5 :         smb2_util_unlink(tree, fname);
     560           5 :         return ret;
     561             : }
     562             : 
     563           4 : bool torture_smb2_sdreadtest(struct torture_context *tctx,
     564             :                               struct smb2_tree *tree)
     565             : {
     566           4 :         const char *fname = "sdread.file";
     567           4 :         bool ret = true;
     568           0 :         union smb_fileinfo query;
     569           0 :         NTSTATUS status;
     570           4 :         struct security_descriptor *sd = NULL;
     571           4 :         struct smb2_create create_io = {0};
     572           4 :         uint32_t sd_bits[] = { SECINFO_OWNER,
     573             :                                 SECINFO_GROUP,
     574             :                                 SECINFO_DACL };
     575           0 :         size_t i;
     576             : 
     577           4 :         ZERO_STRUCT(query);
     578             : 
     579           4 :         smb2_util_unlink(tree, fname);
     580             : 
     581             :         /* Create then close a file*/
     582           4 :         create_io.in.create_flags = 0;
     583           4 :         create_io.in.desired_access = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
     584           4 :         create_io.in.file_attributes = 0;
     585           4 :         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     586           4 :         create_io.in.create_disposition = FILE_SUPERSEDE;
     587           4 :         create_io.in.create_options = 0;
     588           4 :         create_io.in.security_flags = 0;
     589           4 :         create_io.in.fname = fname;
     590           4 :         status = smb2_create(tree, tctx, &create_io);
     591           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     592             :                 talloc_asprintf(tctx, "open(1) of %s failed (%s)\n",
     593             :                 fname, nt_errstr(status)));
     594           4 :         status = smb2_util_close(tree, create_io.out.file.handle);
     595           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     596             :                        talloc_asprintf(tctx, "close(1) of %s failed (%s)\n",
     597             :                                        fname, nt_errstr(status)));
     598             : 
     599             :         /*
     600             :          * Open the file with READ_ATTRIBUTES *only*,
     601             :          * no READ_CONTROL.
     602             :          *
     603             :          * This should deny access for any attempt to
     604             :          * get a security descriptor if we ask for
     605             :          * any of OWNER|GROUP|DACL, but if
     606             :          * we ask for *NO* info but still ask for
     607             :          * the security descriptor, then Windows
     608             :          * returns an ACL but with zero entries
     609             :          * for OWNER|GROUP|DACL.
     610             :          */
     611             : 
     612           4 :         create_io = (struct smb2_create){0};
     613           4 :         create_io.in.create_flags = 0;
     614           4 :         create_io.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
     615           4 :         create_io.in.file_attributes = 0;
     616           4 :         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     617           4 :         create_io.in.create_disposition = FILE_OPEN;
     618           4 :         create_io.in.create_options = 0;
     619           4 :         create_io.in.security_flags = 0;
     620           4 :         create_io.in.fname = fname;
     621           4 :         status = smb2_create(tree, tctx, &create_io);
     622           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret,
     623             :                         error_exit,
     624             :                         talloc_asprintf(tctx, "open(2) of %s failed (%s)\n",
     625             :                         fname, nt_errstr(status)));
     626             : 
     627             :         /* Check asking for SD fails ACCESS_DENIED with actual bits set. */
     628          16 :         for (i = 0; i < ARRAY_SIZE(sd_bits); i++) {
     629          12 :                 query.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     630          12 :                 query.query_secdesc.in.file.handle = create_io.out.file.handle;
     631          12 :                 query.query_secdesc.in.secinfo_flags = sd_bits[i];
     632             : 
     633          12 :                 status = smb2_getinfo_file(tree, tctx, &query);
     634             : 
     635             :                 /* Must return ACESS_DENIED. */
     636          12 :                 if(!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)){
     637           0 :                         NTSTATUS s = smb2_util_close(tree,
     638             :                                         create_io.out.file.handle);
     639           0 :                         torture_assert_ntstatus_ok_goto(tctx, s, ret,
     640             :                                 error_exit,
     641             :                                 talloc_asprintf(tctx,
     642             :                                         "close(2) of %s failed (%s)\n",
     643             :                                         fname, nt_errstr(s)));
     644           0 :                         ret = false;
     645           0 :                         torture_fail_goto(tctx, error_exit,
     646             :                                 talloc_asprintf(tctx,
     647             :                                 "smb2_getinfo_file(2) of %s failed (%s)\n",
     648             :                                 fname, nt_errstr(status)));
     649             :                 }
     650             :         }
     651             : 
     652             :         /*
     653             :          * Get security descriptor whilst asking for *NO* bits.
     654             :          * This succeeds even though we don't have READ_CONTROL
     655             :          * access but returns an SD with zero data.
     656             :          */
     657           4 :         query.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     658           4 :         query.query_secdesc.in.file.handle = create_io.out.file.handle;
     659           4 :         query.query_secdesc.in.secinfo_flags = 0;
     660             : 
     661           4 :         status = smb2_getinfo_file(tree, tctx, &query);
     662           4 :         if(!NT_STATUS_IS_OK(status)){
     663           0 :                 NTSTATUS s = smb2_util_close(tree, create_io.out.file.handle);
     664           0 :                 torture_assert_ntstatus_ok_goto(tctx, s, ret, error_exit,
     665             :                                 talloc_asprintf(tctx,
     666             :                                         "close(3) of %s failed (%s)\n",
     667             :                                         fname, nt_errstr(s)));
     668           0 :                 ret = false;
     669           0 :                 torture_fail_goto(tctx, error_exit, talloc_asprintf(tctx,
     670             :                         "smb2_getinfo_file(3) of %s failed (%s)\n",
     671             :                         fname, nt_errstr(status)));
     672             :         }
     673             : 
     674           4 :         sd = query.query_secdesc.out.sd;
     675             : 
     676             :         /* Check it's empty. */
     677           4 :         torture_assert_goto(tctx,
     678             :                         (sd->owner_sid == NULL),
     679             :                         ret,
     680             :                         error_exit,
     681             :                         "sd->owner_sid != NULL\n");
     682             : 
     683           4 :         torture_assert_goto(tctx,
     684             :                         (sd->group_sid == NULL),
     685             :                         ret,
     686             :                         error_exit,
     687             :                         "sd->group_sid != NULL\n");
     688             : 
     689           4 :         torture_assert_goto(tctx,
     690             :                         (sd->dacl == NULL),
     691             :                         ret,
     692             :                         error_exit,
     693             :                         "sd->dacl != NULL\n");
     694             : 
     695           4 :         status = smb2_util_close(tree, create_io.out.file.handle);
     696           4 :         torture_assert_ntstatus_ok_goto(tctx,
     697             :                         status,
     698             :                         ret,
     699             :                         error_exit,
     700             :                         talloc_asprintf(tctx, "close(4) of %s failed (%s)\n",
     701             :                                 fname,
     702             :                         nt_errstr(status)));
     703             : 
     704           4 : error_exit:
     705             : 
     706           4 :         smb2_setatr(tree, fname, FILE_ATTRIBUTE_NORMAL);
     707           4 :         smb2_util_unlink(tree, fname);
     708             : 
     709           4 :         return ret;
     710             : }

Generated by: LCOV version 1.14