LCOV - code coverage report
Current view: top level - source4/torture/smb2 - attr.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 177 264 67.0 %
Date: 2024-06-13 04:01:37 Functions: 3 4 75.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          49 : static NTSTATUS smb2_setatr(struct smb2_tree *tree, const char *name,
      87             :                             uint32_t attrib)
      88             : {
      89             :         NTSTATUS status;
      90          49 :         struct smb2_create create_io = {0};
      91             :         union smb_setfileinfo io;
      92             : 
      93          49 :         create_io.in.desired_access = SEC_FILE_READ_DATA |
      94             :                                       SEC_FILE_WRITE_ATTRIBUTE;
      95          49 :         create_io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
      96          49 :         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
      97          49 :         create_io.in.create_disposition = NTCREATEX_DISP_OPEN;
      98          49 :         create_io.in.fname = name;
      99          49 :         status = smb2_create(tree, tree, &create_io);
     100          49 :         if (!NT_STATUS_IS_OK(status)) {
     101           1 :                 return status;
     102             :         }
     103             : 
     104          48 :         ZERO_STRUCT(io);
     105          48 :         io.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION;
     106          48 :         io.basic_info.in.file.handle = create_io.out.file.handle;
     107          48 :         io.basic_info.in.attrib = attrib;
     108          48 :         status = smb2_setinfo_file(tree, &io);
     109          48 :         if (!NT_STATUS_IS_OK(status)) {
     110           0 :                 return status;
     111             :         }
     112             : 
     113          48 :         status = smb2_util_close(tree, create_io.out.file.handle);
     114          48 :         if (!NT_STATUS_IS_OK(status)) {
     115           0 :                 return status;
     116             :         }
     117             : 
     118          48 :         return status;
     119             : }
     120             : 
     121           1 : bool torture_smb2_openattrtest(struct torture_context *tctx,
     122             :                                struct smb2_tree *tree)
     123             : {
     124             :         NTSTATUS status;
     125           1 :         const char *fname = "openattr.file";
     126             :         uint16_t attr;
     127             :         unsigned int i, j, k, l;
     128           1 :         int ret = true;
     129             : 
     130          17 :         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
     131          16 :                 struct smb2_create create_io = {0};
     132          16 :                 smb2_setatr(tree, fname, FILE_ATTRIBUTE_NORMAL);
     133          16 :                 smb2_util_unlink(tree, fname);
     134          16 :                 create_io.in.create_flags = 0;
     135          16 :                 create_io.in.desired_access = SEC_FILE_WRITE_DATA;
     136          16 :                 create_io.in.file_attributes = open_attrs_table[i];
     137          16 :                 create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     138          16 :                 create_io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     139          16 :                 create_io.in.create_options = 0;
     140          16 :                 create_io.in.security_flags = 0;
     141          16 :                 create_io.in.fname = fname;
     142          16 :                 status = smb2_create(tree, tctx, &create_io);
     143          16 :                 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          16 :                 status = smb2_util_close(tree, create_io.out.file.handle);
     148          16 :                 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         272 :                 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
     153         256 :                         create_io = (struct smb2_create){0};
     154         256 :                         create_io.in.create_flags = 0;
     155         256 :                         create_io.in.desired_access = SEC_FILE_READ_DATA|
     156             :                                                       SEC_FILE_WRITE_DATA;
     157         256 :                         create_io.in.file_attributes = open_attrs_table[j];
     158         256 :                         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     159         256 :                         create_io.in.create_disposition = NTCREATEX_DISP_OVERWRITE;
     160         256 :                         create_io.in.create_options = 0;
     161         256 :                         create_io.in.security_flags = 0;
     162         256 :                         create_io.in.fname = fname;
     163         256 :                         status = smb2_create(tree, tctx, &create_io);
     164             : 
     165         256 :                         if (!NT_STATUS_IS_OK(status)) {
     166           0 :                                 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
     167           0 :                                         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           0 :                                 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           0 :                                 k++;
     191           0 :                                 continue;
     192             :                         }
     193             : 
     194         256 :                         status = smb2_util_close(tree, create_io.out.file.handle);
     195         256 :                         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         256 :                         status = smb2_util_getatr(tree, fname, &attr, NULL, NULL);
     201         256 :                         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        6561 :                         for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
     207        6331 :                                 if (attr_results[l].num == k) {
     208          52 :                                         if (attr != attr_results[l].result_attr ||
     209          52 :                                             open_attrs_table[i] != attr_results[l].init_attr ||
     210          26 :                                             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          26 :                                         break;
     224             :                                 }
     225             :                         }
     226         256 :                         k++;
     227             :                 }
     228             :         }
     229           1 : error_exit:
     230           1 :         smb2_setatr(tree, fname, FILE_ATTRIBUTE_NORMAL);
     231           1 :         smb2_util_unlink(tree, fname);
     232             : 
     233             : 
     234           1 :         return ret;
     235             : }
     236             : 
     237           1 : bool torture_smb2_winattrtest(struct torture_context *tctx,
     238             :                               struct smb2_tree *tree)
     239             : {
     240           1 :         const char *fname = "winattr1.file";
     241           1 :         const char *dname = "winattr1.dir";
     242             :         uint16_t attr;
     243             :         uint16_t j;
     244             :         uint32_t aceno;
     245           1 :         bool ret = true;
     246             :         union smb_fileinfo query, query_org;
     247             :         NTSTATUS status;
     248           1 :         struct security_descriptor *sd1 = NULL, *sd2 = NULL;
     249           1 :         struct smb2_create create_io = {0};
     250           1 :         ZERO_STRUCT(query);
     251           1 :         ZERO_STRUCT(query_org);
     252             : 
     253             :         /* Test winattrs for file */
     254           1 :         smb2_util_unlink(tree, fname);
     255             : 
     256             :         /* Open a file*/
     257           1 :         create_io.in.create_flags = 0;
     258           1 :         create_io.in.desired_access = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA |
     259             :                                 SEC_STD_READ_CONTROL;
     260           1 :         create_io.in.file_attributes = 0;
     261           1 :         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     262           1 :         create_io.in.create_disposition = FILE_SUPERSEDE;
     263           1 :         create_io.in.create_options = 0;
     264           1 :         create_io.in.security_flags = 0;
     265           1 :         create_io.in.fname = fname;
     266           1 :         status = smb2_create(tree, tctx, &create_io);
     267           1 :         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           1 :         query_org.generic.level = RAW_FILEINFO_SEC_DESC;
     273           1 :         query_org.generic.in.file.handle = create_io.out.file.handle;
     274           1 :         query_org.query_secdesc.in.secinfo_flags = SECINFO_OWNER|
     275             :                                                 SECINFO_GROUP|
     276             :                                                 SECINFO_DACL;
     277           1 :         status = smb2_getinfo_file(tree, tctx, &query_org);
     278           1 :         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           1 :         sd1 = query_org.query_secdesc.out.sd;
     290             : 
     291           1 :         status = smb2_util_close(tree, create_io.out.file.handle);
     292           1 :         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          17 :         for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
     298          16 :                 status = smb2_setatr(tree, fname, open_attrs_table[j]);
     299          16 :                 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          16 :                 status = smb2_util_getatr(tree, fname, &attr, NULL, NULL);
     305          16 :                 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          16 :                 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          16 :                 create_io = (struct smb2_create){0};
     319          16 :                 create_io.in.create_flags = 0;
     320          16 :                 create_io.in.desired_access = SEC_FILE_READ_ATTRIBUTE|
     321             :                                                 SEC_STD_READ_CONTROL;
     322          16 :                 create_io.in.file_attributes = 0;
     323          16 :                 create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     324          16 :                 create_io.in.create_disposition = FILE_OPEN_IF;
     325          16 :                 create_io.in.create_options = 0;
     326          16 :                 create_io.in.security_flags = 0;
     327          16 :                 create_io.in.fname = fname;
     328          16 :                 status = smb2_create(tree, tctx, &create_io);
     329          16 :                 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          16 :                 query.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     335          16 :                 query.query_secdesc.in.file.handle = create_io.out.file.handle;
     336          16 :                 query.query_secdesc.in.secinfo_flags = SECINFO_OWNER|
     337             :                                                 SECINFO_GROUP|
     338             :                                                 SECINFO_DACL;
     339          16 :                 status = smb2_getinfo_file(tree, tctx, &query);
     340          16 :                 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          16 :                 sd2 = query.query_secdesc.out.sd;
     354             : 
     355          16 :                 status = smb2_util_close(tree, create_io.out.file.handle);
     356          16 :                 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          80 :                 for (aceno=0;(sd1->dacl&&aceno < sd1->dacl->num_aces);aceno++){
     362          64 :                         struct security_ace *ace1 = &sd1->dacl->aces[aceno];
     363          64 :                         struct security_ace *ace2 = &sd2->dacl->aces[aceno];
     364             : 
     365          64 :                         torture_assert_goto(tctx, security_ace_equal(ace1, ace2),
     366             :                                 ret, error_exit,
     367             :                                 "ACLs changed! Not expected!\n");
     368             :                 }
     369             : 
     370          16 :                 torture_comment(tctx, "[%d] setattr = [0x%x] got attr 0x%x\n",
     371           0 :                         j,  open_attrs_table[j], attr );
     372             : 
     373             :         }
     374             : 
     375             : 
     376             : /* Check for Directory. */
     377             : 
     378           1 :         smb2_deltree(tree, dname);
     379           1 :         smb2_util_rmdir(tree, dname);
     380             : 
     381             :         /* Open a directory */
     382           1 :         create_io = (struct smb2_create){0};
     383           1 :         create_io.in.create_flags = 0;
     384           1 :         create_io.in.desired_access = SEC_RIGHTS_DIR_ALL;
     385           1 :         create_io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     386           1 :         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     387           1 :         create_io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     388           1 :         create_io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     389           1 :         create_io.in.security_flags = 0;
     390           1 :         create_io.in.fname = dname;
     391           1 :         status = smb2_create(tree, tctx, &create_io);
     392             : 
     393           1 :         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           1 :         query_org.generic.level = RAW_FILEINFO_SEC_DESC;
     401           1 :         query_org.generic.in.file.handle = create_io.out.file.handle;
     402           1 :         status = smb2_getinfo_file(tree, tctx, &query_org);
     403           1 :         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           1 :         sd1 = query_org.query_secdesc.out.sd;
     415             : 
     416           1 :         status = smb2_util_close(tree, create_io.out.file.handle);
     417           1 :         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          16 :         for (j = 1; j < ARRAY_SIZE(open_attrs_table); j++) {
     424             : 
     425          15 :                 status = smb2_setatr(tree, dname, open_attrs_table[j]);
     426          15 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     427             :                         talloc_asprintf(tctx, "setatr(2) failed (%s)",
     428             :                                 nt_errstr(status)));
     429             : 
     430          15 :                 status = smb2_util_getatr(tree, dname, &attr, NULL, NULL);
     431          15 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     432             :                         talloc_asprintf(tctx, "getatr(2) failed (%s)",
     433             :                                 nt_errstr(status)));
     434             : 
     435          15 :                 torture_comment(tctx, "[%d] setatt = [0x%x] got attr 0x%x\n",
     436           0 :                         j,  open_attrs_table[j], attr );
     437             : 
     438             :                 /* Check the result */
     439          15 :                 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          15 :                 create_io = (struct smb2_create){0};
     448          15 :                 create_io.in.create_flags = 0;
     449          15 :                 create_io.in.desired_access = SEC_RIGHTS_DIR_READ;
     450          15 :                 create_io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     451          15 :                 create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     452          15 :                 create_io.in.create_disposition = NTCREATEX_DISP_OPEN;
     453          15 :                 create_io.in.create_options = 0;
     454          15 :                 create_io.in.security_flags = 0;
     455          15 :                 create_io.in.fname = dname;
     456          15 :                 status = smb2_create(tree, tctx, &create_io);
     457             : 
     458          15 :                 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          15 :                 query.generic.level = RAW_FILEINFO_SEC_DESC;
     464          15 :                 query.generic.in.file.handle = create_io.out.file.handle;
     465          15 :                 status = smb2_getinfo_file(tree, tctx, &query);
     466          15 :                 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          15 :                 sd2 = query.query_secdesc.out.sd;
     479          15 :                 status = smb2_util_close(tree, create_io.out.file.handle);
     480          15 :                 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          75 :                 for (aceno=0;(sd1->dacl&&aceno < sd1->dacl->num_aces);aceno++){
     487          60 :                         struct security_ace *ace1 = &sd1->dacl->aces[aceno];
     488          60 :                         struct security_ace *ace2 = &sd2->dacl->aces[aceno];
     489             : 
     490          60 :                         torture_assert_goto(tctx, security_ace_equal(ace1, ace2),
     491             :                                 ret, error_exit,
     492             :                                 "ACLs changed! Not expected!\n");
     493             :                 }
     494             : 
     495             :         }
     496             : 
     497           1 : error_exit:
     498           1 :         smb2_setatr(tree, fname, FILE_ATTRIBUTE_NORMAL);
     499           1 :         smb2_util_unlink(tree, fname);
     500           1 :         smb2_deltree(tree, dname);
     501           1 :         smb2_util_rmdir(tree, dname);
     502             : 
     503           1 :         return ret;
     504             : }
     505             : 
     506           0 : bool torture_smb2_sdreadtest(struct torture_context *tctx,
     507             :                               struct smb2_tree *tree)
     508             : {
     509           0 :         const char *fname = "sdread.file";
     510           0 :         bool ret = true;
     511             :         union smb_fileinfo query;
     512             :         NTSTATUS status;
     513           0 :         struct security_descriptor *sd = NULL;
     514           0 :         struct smb2_create create_io = {0};
     515           0 :         uint32_t sd_bits[] = { SECINFO_OWNER,
     516             :                                 SECINFO_GROUP,
     517             :                                 SECINFO_DACL };
     518             :         size_t i;
     519             : 
     520           0 :         ZERO_STRUCT(query);
     521             : 
     522           0 :         smb2_util_unlink(tree, fname);
     523             : 
     524             :         /* Create then close a file*/
     525           0 :         create_io.in.create_flags = 0;
     526           0 :         create_io.in.desired_access = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
     527           0 :         create_io.in.file_attributes = 0;
     528           0 :         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     529           0 :         create_io.in.create_disposition = FILE_SUPERSEDE;
     530           0 :         create_io.in.create_options = 0;
     531           0 :         create_io.in.security_flags = 0;
     532           0 :         create_io.in.fname = fname;
     533           0 :         status = smb2_create(tree, tctx, &create_io);
     534           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     535             :                 talloc_asprintf(tctx, "open(1) of %s failed (%s)\n",
     536             :                 fname, nt_errstr(status)));
     537           0 :         status = smb2_util_close(tree, create_io.out.file.handle);
     538           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, error_exit,
     539             :                        talloc_asprintf(tctx, "close(1) of %s failed (%s)\n",
     540             :                                        fname, nt_errstr(status)));
     541             : 
     542             :         /*
     543             :          * Open the file with READ_ATTRIBUTES *only*,
     544             :          * no READ_CONTROL.
     545             :          *
     546             :          * This should deny access for any attempt to
     547             :          * get a security descriptor if we ask for
     548             :          * any of OWNER|GROUP|DACL, but if
     549             :          * we ask for *NO* info but still ask for
     550             :          * the security descriptor, then Windows
     551             :          * returns an ACL but with zero entries
     552             :          * for OWNER|GROUP|DACL.
     553             :          */
     554             : 
     555           0 :         create_io = (struct smb2_create){0};
     556           0 :         create_io.in.create_flags = 0;
     557           0 :         create_io.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
     558           0 :         create_io.in.file_attributes = 0;
     559           0 :         create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     560           0 :         create_io.in.create_disposition = FILE_OPEN;
     561           0 :         create_io.in.create_options = 0;
     562           0 :         create_io.in.security_flags = 0;
     563           0 :         create_io.in.fname = fname;
     564           0 :         status = smb2_create(tree, tctx, &create_io);
     565           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret,
     566             :                         error_exit,
     567             :                         talloc_asprintf(tctx, "open(2) of %s failed (%s)\n",
     568             :                         fname, nt_errstr(status)));
     569             : 
     570             :         /* Check asking for SD fails ACCESS_DENIED with actual bits set. */
     571           0 :         for (i = 0; i < ARRAY_SIZE(sd_bits); i++) {
     572           0 :                 query.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     573           0 :                 query.query_secdesc.in.file.handle = create_io.out.file.handle;
     574           0 :                 query.query_secdesc.in.secinfo_flags = sd_bits[i];
     575             : 
     576           0 :                 status = smb2_getinfo_file(tree, tctx, &query);
     577             : 
     578             :                 /* Must return ACESS_DENIED. */
     579           0 :                 if(!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)){
     580           0 :                         NTSTATUS s = smb2_util_close(tree,
     581             :                                         create_io.out.file.handle);
     582           0 :                         torture_assert_ntstatus_ok_goto(tctx, s, ret,
     583             :                                 error_exit,
     584             :                                 talloc_asprintf(tctx,
     585             :                                         "close(2) of %s failed (%s)\n",
     586             :                                         fname, nt_errstr(s)));
     587           0 :                         ret = false;
     588           0 :                         torture_fail_goto(tctx, error_exit,
     589             :                                 talloc_asprintf(tctx,
     590             :                                 "smb2_getinfo_file(2) of %s failed (%s)\n",
     591             :                                 fname, nt_errstr(status)));
     592             :                 }
     593             :         }
     594             : 
     595             :         /*
     596             :          * Get security descriptor whilst asking for *NO* bits.
     597             :          * This succeeds even though we don't have READ_CONTROL
     598             :          * access but returns an SD with zero data.
     599             :          */
     600           0 :         query.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     601           0 :         query.query_secdesc.in.file.handle = create_io.out.file.handle;
     602           0 :         query.query_secdesc.in.secinfo_flags = 0;
     603             : 
     604           0 :         status = smb2_getinfo_file(tree, tctx, &query);
     605           0 :         if(!NT_STATUS_IS_OK(status)){
     606           0 :                 NTSTATUS s = smb2_util_close(tree, create_io.out.file.handle);
     607           0 :                 torture_assert_ntstatus_ok_goto(tctx, s, ret, error_exit,
     608             :                                 talloc_asprintf(tctx,
     609             :                                         "close(3) of %s failed (%s)\n",
     610             :                                         fname, nt_errstr(s)));
     611           0 :                 ret = false;
     612           0 :                 torture_fail_goto(tctx, error_exit, talloc_asprintf(tctx,
     613             :                         "smb2_getinfo_file(3) of %s failed (%s)\n",
     614             :                         fname, nt_errstr(status)));
     615             :         }
     616             : 
     617           0 :         sd = query.query_secdesc.out.sd;
     618             : 
     619             :         /* Check it's empty. */
     620           0 :         torture_assert_goto(tctx,
     621             :                         (sd->owner_sid == NULL),
     622             :                         ret,
     623             :                         error_exit,
     624             :                         "sd->owner_sid != NULL\n");
     625             : 
     626           0 :         torture_assert_goto(tctx,
     627             :                         (sd->group_sid == NULL),
     628             :                         ret,
     629             :                         error_exit,
     630             :                         "sd->group_sid != NULL\n");
     631             : 
     632           0 :         torture_assert_goto(tctx,
     633             :                         (sd->dacl == NULL),
     634             :                         ret,
     635             :                         error_exit,
     636             :                         "sd->dacl != NULL\n");
     637             : 
     638           0 :         status = smb2_util_close(tree, create_io.out.file.handle);
     639           0 :         torture_assert_ntstatus_ok_goto(tctx,
     640             :                         status,
     641             :                         ret,
     642             :                         error_exit,
     643             :                         talloc_asprintf(tctx, "close(4) of %s failed (%s)\n",
     644             :                                 fname,
     645             :                         nt_errstr(status)));
     646             : 
     647           0 : error_exit:
     648             : 
     649           0 :         smb2_setatr(tree, fname, FILE_ATTRIBUTE_NORMAL);
     650           0 :         smb2_util_unlink(tree, fname);
     651             : 
     652           0 :         return ret;
     653             : }

Generated by: LCOV version 1.13