LCOV - code coverage report
Current view: top level - source4/torture/smb2 - getinfo.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 377 405 93.1 %
Date: 2021-08-25 13:27:56 Functions: 9 11 81.8 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    SMB2 getinfo test suite
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2005
       7             :    
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "libcli/smb2/smb2.h"
      24             : #include "libcli/smb2/smb2_calls.h"
      25             : #include "libcli/smb/smbXcli_base.h"
      26             : 
      27             : #include "torture/torture.h"
      28             : #include "torture/smb2/proto.h"
      29             : #include "torture/util.h"
      30             : 
      31             : static struct {
      32             :         const char *name;
      33             :         uint16_t level;
      34             :         NTSTATUS fstatus;
      35             :         NTSTATUS dstatus;
      36             :         union smb_fileinfo finfo;
      37             :         union smb_fileinfo dinfo;
      38             : } file_levels[] = {
      39             : #define LEVEL(x) .name = #x, .level = x
      40             :  { LEVEL(RAW_FILEINFO_BASIC_INFORMATION) },
      41             :  { LEVEL(RAW_FILEINFO_STANDARD_INFORMATION) },
      42             :  { LEVEL(RAW_FILEINFO_INTERNAL_INFORMATION) },
      43             :  { LEVEL(RAW_FILEINFO_EA_INFORMATION) },
      44             :  { LEVEL(RAW_FILEINFO_ACCESS_INFORMATION) },
      45             :  { LEVEL(RAW_FILEINFO_POSITION_INFORMATION) },
      46             :  { LEVEL(RAW_FILEINFO_MODE_INFORMATION) },
      47             :  { LEVEL(RAW_FILEINFO_ALIGNMENT_INFORMATION) },
      48             :  { LEVEL(RAW_FILEINFO_ALL_INFORMATION) },
      49             :  { LEVEL(RAW_FILEINFO_ALT_NAME_INFORMATION) },
      50             :  { LEVEL(RAW_FILEINFO_STREAM_INFORMATION) },
      51             :  { LEVEL(RAW_FILEINFO_COMPRESSION_INFORMATION) },
      52             :  { LEVEL(RAW_FILEINFO_NETWORK_OPEN_INFORMATION) },
      53             :  { LEVEL(RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION) },
      54             : 
      55             :  { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS) },
      56             : 
      57             :  { LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION) },
      58             :  { LEVEL(RAW_FILEINFO_SEC_DESC) }
      59             : };
      60             : 
      61             : static struct {
      62             :         const char *name;
      63             :         uint16_t level;
      64             :         NTSTATUS status;
      65             :         union smb_fsinfo info;
      66             : } fs_levels[] = {
      67             :  { LEVEL(RAW_QFS_VOLUME_INFORMATION) },
      68             :  { LEVEL(RAW_QFS_SIZE_INFORMATION) },
      69             :  { LEVEL(RAW_QFS_DEVICE_INFORMATION) },
      70             :  { LEVEL(RAW_QFS_ATTRIBUTE_INFORMATION) },
      71             :  { LEVEL(RAW_QFS_QUOTA_INFORMATION) },
      72             :  { LEVEL(RAW_QFS_FULL_SIZE_INFORMATION) },
      73             :  { LEVEL(RAW_QFS_OBJECTID_INFORMATION) },
      74             :  { LEVEL(RAW_QFS_SECTOR_SIZE_INFORMATION) },
      75             : };
      76             : 
      77             : #define FNAME "testsmb2_file.dat"
      78             : #define DNAME "testsmb2_dir"
      79             : 
      80             : /*
      81             :   test fileinfo levels
      82             : */
      83           0 : static bool torture_smb2_fileinfo(struct torture_context *tctx, struct smb2_tree *tree)
      84             : {
      85             :         struct smb2_handle hfile, hdir;
      86             :         NTSTATUS status;
      87             :         int i;
      88             : 
      89           0 :         status = torture_smb2_testfile(tree, FNAME, &hfile);
      90           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create test file "
      91             :                                    FNAME "\n");
      92             : 
      93           0 :         status = torture_smb2_testdir(tree, DNAME, &hdir);
      94           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create test dir "
      95             :                                    DNAME "\n");
      96             : 
      97           0 :         torture_comment(tctx, "Testing file info levels\n");
      98           0 :         torture_smb2_all_info(tctx, tree, hfile);
      99           0 :         torture_smb2_all_info(tctx, tree, hdir);
     100             : 
     101           0 :         for (i=0;i<ARRAY_SIZE(file_levels);i++) {
     102           0 :                 if (file_levels[i].level == RAW_FILEINFO_SEC_DESC) {
     103           0 :                         file_levels[i].finfo.query_secdesc.in.secinfo_flags = 0x7;
     104           0 :                         file_levels[i].dinfo.query_secdesc.in.secinfo_flags = 0x7;
     105             :                 }
     106           0 :                 if (file_levels[i].level == RAW_FILEINFO_SMB2_ALL_EAS) {
     107           0 :                         file_levels[i].finfo.all_eas.in.continue_flags =
     108             :                                 SMB2_CONTINUE_FLAG_RESTART;
     109           0 :                         file_levels[i].dinfo.all_eas.in.continue_flags =
     110             :                                 SMB2_CONTINUE_FLAG_RESTART;
     111             :                 }
     112           0 :                 file_levels[i].finfo.generic.level = file_levels[i].level;
     113           0 :                 file_levels[i].finfo.generic.in.file.handle = hfile;
     114           0 :                 file_levels[i].fstatus = smb2_getinfo_file(tree, tree, &file_levels[i].finfo);
     115           0 :                 torture_assert_ntstatus_ok(tctx, file_levels[i].fstatus,
     116             :                                            talloc_asprintf(tctx, "%s on file",
     117             :                                                            file_levels[i].name));
     118           0 :                 file_levels[i].dinfo.generic.level = file_levels[i].level;
     119           0 :                 file_levels[i].dinfo.generic.in.file.handle = hdir;
     120           0 :                 file_levels[i].dstatus = smb2_getinfo_file(tree, tree, &file_levels[i].dinfo);
     121           0 :                 torture_assert_ntstatus_ok(tctx, file_levels[i].dstatus,
     122             :                                            talloc_asprintf(tctx, "%s on dir",
     123             :                                                            file_levels[i].name));
     124             :         }
     125             : 
     126           0 :         return true;
     127             : }
     128             : 
     129             : /*
     130             :   test granted access when desired access includes
     131             :   FILE_EXECUTE and does not include FILE_READ_DATA
     132             : */
     133           5 : static bool torture_smb2_fileinfo_grant_read(struct torture_context *tctx)
     134             : {
     135             :         struct smb2_tree *tree;
     136             :         bool ret;
     137             :         struct smb2_handle hfile, hdir;
     138             :         NTSTATUS status;
     139             :         uint32_t file_granted_access, dir_granted_access;
     140             : 
     141           5 :         ret = torture_smb2_connection(tctx, &tree);
     142           5 :         torture_assert(tctx, ret, "connection failed");
     143             : 
     144           5 :         status = torture_smb2_testfile_access(
     145             :             tree, FNAME, &hfile, SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE);
     146           5 :         torture_assert_ntstatus_ok(tctx, status,
     147             :                                    "Unable to create test file " FNAME "\n");
     148           5 :         status =
     149           5 :             torture_smb2_get_allinfo_access(tree, hfile, &file_granted_access);
     150           5 :         torture_assert_ntstatus_ok(tctx, status,
     151             :                                    "Unable to query test file access ");
     152           5 :         torture_assert_int_equal(tctx, file_granted_access,
     153             :                                  SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE,
     154             :                                  "granted file access ");
     155           5 :         smb2_util_close(tree, hfile);
     156             : 
     157           5 :         status = torture_smb2_testdir_access(
     158             :             tree, DNAME, &hdir, SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE);
     159           5 :         torture_assert_ntstatus_ok(tctx, status,
     160             :                                    "Unable to create test dir " DNAME "\n");
     161           5 :         status =
     162           5 :             torture_smb2_get_allinfo_access(tree, hdir, &dir_granted_access);
     163           5 :         torture_assert_ntstatus_ok(tctx, status,
     164             :                                    "Unable to query test dir access ");
     165           5 :         torture_assert_int_equal(tctx, dir_granted_access,
     166             :                                  SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE,
     167             :                                  "granted dir access ");
     168           5 :         smb2_util_close(tree, hdir);
     169             : 
     170           5 :         return true;
     171             : }
     172             : 
     173           5 : static bool torture_smb2_fileinfo_normalized(struct torture_context *tctx)
     174             : {
     175           5 :         struct smb2_tree *tree = NULL;
     176             :         bool ret;
     177             :         struct smb2_handle hroot;
     178           5 :         const char *d1 = NULL, *d1l = NULL, *d1u = NULL;
     179             :         struct smb2_handle hd1, hd1l, hd1u;
     180           5 :         const char *d2 = NULL, *d2l = NULL, *d2u = NULL;
     181             :         struct smb2_handle hd2, hd2l, hd2u;
     182           5 :         const char *d3 = NULL, *d3l = NULL, *d3u = NULL;
     183             :         struct smb2_handle hd3, hd3l, hd3u;
     184           5 :         const char *d3s = NULL, *d3sl = NULL, *d3su = NULL, *d3sd = NULL;
     185             :         struct smb2_handle hd3s, hd3sl, hd3su, hd3sd;
     186           5 :         const char *f4 = NULL, *f4l = NULL, *f4u = NULL, *f4d = NULL;
     187             :         struct smb2_handle hf4, hf4l, hf4u, hf4d;
     188           5 :         const char *f4s = NULL, *f4sl = NULL, *f4su = NULL, *f4sd = NULL;
     189             :         struct smb2_handle hf4s, hf4sl, hf4su, hf4sd;
     190           5 :         union smb_fileinfo info = {
     191             :                 .normalized_name_info = {
     192             :                         .level = RAW_FILEINFO_NORMALIZED_NAME_INFORMATION,
     193             :                 },
     194             :         };
     195             :         NTSTATUS status;
     196             :         enum protocol_types protocol;
     197           5 :         struct smb2_tree *tree_3_0 = NULL;
     198             :         struct smbcli_options options3_0;
     199             :         struct smb2_handle hroot_3_0;
     200             : 
     201           5 :         ret = torture_smb2_connection(tctx, &tree);
     202           5 :         torture_assert(tctx, ret, "connection failed");
     203             : 
     204           5 :         protocol = smbXcli_conn_protocol(tree->session->transport->conn);
     205             : 
     206           5 :         d1 = talloc_asprintf(tctx, "torture_dIr1N");
     207           5 :         torture_assert_not_null(tctx, d1, "d1");
     208           5 :         d1l = strlower_talloc(tctx, d1);
     209           5 :         torture_assert_not_null(tctx, d1l, "d1l");
     210           5 :         d1u = strupper_talloc(tctx, d1);
     211           5 :         torture_assert_not_null(tctx, d1u, "d1u");
     212             : 
     213           5 :         d2 = talloc_asprintf(tctx, "%s\\dIr2Na", d1);
     214           5 :         torture_assert_not_null(tctx, d2, "d2");
     215           5 :         d2l = strlower_talloc(tctx, d2);
     216           5 :         torture_assert_not_null(tctx, d2l, "d2l");
     217           5 :         d2u = strupper_talloc(tctx, d2);
     218           5 :         torture_assert_not_null(tctx, d2u, "d2u");
     219             : 
     220           5 :         d3 = talloc_asprintf(tctx, "%s\\dIr3NaM", d2);
     221           5 :         torture_assert_not_null(tctx, d3, "d3");
     222           5 :         d3l = strlower_talloc(tctx, d3);
     223           5 :         torture_assert_not_null(tctx, d3l, "d3l");
     224           5 :         d3u = strupper_talloc(tctx, d3);
     225           5 :         torture_assert_not_null(tctx, d3u, "d3u");
     226             : 
     227           5 :         d3s = talloc_asprintf(tctx, "%s:sTrEaM3", d3);
     228           5 :         torture_assert_not_null(tctx, d3s, "d3s");
     229           5 :         d3sl = strlower_talloc(tctx, d3s);
     230           5 :         torture_assert_not_null(tctx, d3sl, "d3sl");
     231           5 :         d3su = strupper_talloc(tctx, d3s);
     232           5 :         torture_assert_not_null(tctx, d3su, "d3su");
     233           5 :         d3sd = talloc_asprintf(tctx, "%s:$DaTa", d3s);
     234           5 :         torture_assert_not_null(tctx, d3sd, "d3sd");
     235             : 
     236           5 :         f4 = talloc_asprintf(tctx, "%s\\fIlE4NaMe", d3);
     237           5 :         torture_assert_not_null(tctx, f4, "f4");
     238           5 :         f4l = strlower_talloc(tctx, f4);
     239           5 :         torture_assert_not_null(tctx, f4l, "f4l");
     240           5 :         f4u = strupper_talloc(tctx, f4);
     241           5 :         torture_assert_not_null(tctx, f4u, "f4u");
     242           5 :         f4d = talloc_asprintf(tctx, "%s::$dAtA", f4);
     243           5 :         torture_assert_not_null(tctx, f4d, "f4d");
     244             : 
     245           5 :         f4s = talloc_asprintf(tctx, "%s:StReAm4", f4);
     246           5 :         torture_assert_not_null(tctx, f4s, "f4s");
     247           5 :         f4sl = strlower_talloc(tctx, f4s);
     248           5 :         torture_assert_not_null(tctx, f4sl, "f4sl");
     249           5 :         f4su = strupper_talloc(tctx, f4s);
     250           5 :         torture_assert_not_null(tctx, f4su, "f4su");
     251           5 :         f4sd = talloc_asprintf(tctx, "%s:$dAtA", f4s);
     252           5 :         torture_assert_not_null(tctx, f4sd, "f4sd");
     253             : 
     254           5 :         status = smb2_util_roothandle(tree, &hroot);
     255           5 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
     256             : 
     257           5 :         info.normalized_name_info.in.file.handle = hroot;
     258           5 :         ZERO_STRUCT(info.normalized_name_info.out);
     259           5 :         status = smb2_getinfo_file(tree, tree, &info);
     260           5 :         if (protocol < PROTOCOL_SMB3_11) {
     261             :                 /*
     262             :                  * Only SMB 3.1.1 and above should offer this.
     263             :                  */
     264           1 :                 torture_assert_ntstatus_equal(tctx, status,
     265             :                                               NT_STATUS_NOT_SUPPORTED,
     266             :                                               "getinfo hroot");
     267           1 :                 torture_skip(tctx, "SMB 3.1.1 not supported");
     268             :         }
     269           4 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
     270             :                 /*
     271             :                  * Not all servers support this.
     272             :                  * (only Windows 10 1803 and higher)
     273             :                  */
     274           0 :                 torture_skip(tctx, "NORMALIZED_NAME_INFORMATION not supported");
     275             :         }
     276           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hroot");
     277           4 :         torture_assert(tctx, info.normalized_name_info.out.fname.s == NULL,
     278             :                        "getinfo hroot should be empty");
     279             : 
     280           4 :         smb2_deltree(tree, d1);
     281             : 
     282           4 :         status = torture_smb2_testdir(tree, d1, &hd1);
     283           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hd1");
     284           4 :         status = torture_smb2_open(tree, d1l, SEC_RIGHTS_FILE_ALL, &hd1l);
     285           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd1l");
     286           4 :         status = torture_smb2_open(tree, d1u, SEC_RIGHTS_FILE_ALL, &hd1u);
     287           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd1u");
     288             : 
     289           4 :         status = torture_smb2_testdir(tree, d2, &hd2);
     290           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hd2");
     291           4 :         status = torture_smb2_open(tree, d2l, SEC_RIGHTS_FILE_ALL, &hd2l);
     292           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd2l");
     293           4 :         status = torture_smb2_open(tree, d2u, SEC_RIGHTS_FILE_ALL, &hd2u);
     294           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd2u");
     295             : 
     296           4 :         status = torture_smb2_testdir(tree, d3, &hd3);
     297           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hd3");
     298           4 :         status = torture_smb2_open(tree, d3l, SEC_RIGHTS_FILE_ALL, &hd3l);
     299           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3l");
     300           4 :         status = torture_smb2_open(tree, d3u, SEC_RIGHTS_FILE_ALL, &hd3u);
     301           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3u");
     302             : 
     303           4 :         status = torture_smb2_testfile(tree, d3s, &hd3s);
     304           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hd3s");
     305           4 :         status = torture_smb2_open(tree, d3sl, SEC_RIGHTS_FILE_ALL, &hd3sl);
     306           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3sl");
     307           4 :         status = torture_smb2_open(tree, d3su, SEC_RIGHTS_FILE_ALL, &hd3su);
     308           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3su");
     309           4 :         status = torture_smb2_open(tree, d3sd, SEC_RIGHTS_FILE_ALL, &hd3sd);
     310           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3sd");
     311             : 
     312           4 :         status = torture_smb2_testfile(tree, f4, &hf4);
     313           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hf4");
     314           4 :         status = torture_smb2_open(tree, f4l, SEC_RIGHTS_FILE_ALL, &hf4l);
     315           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4l");
     316           4 :         status = torture_smb2_open(tree, f4u, SEC_RIGHTS_FILE_ALL, &hf4u);
     317           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4u");
     318           4 :         status = torture_smb2_open(tree, f4d, SEC_RIGHTS_FILE_ALL, &hf4d);
     319           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4d");
     320             : 
     321           4 :         status = torture_smb2_testfile(tree, f4s, &hf4s);
     322           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hf4s");
     323           4 :         status = torture_smb2_open(tree, f4sl, SEC_RIGHTS_FILE_ALL, &hf4sl);
     324           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4sl");
     325           4 :         status = torture_smb2_open(tree, f4su, SEC_RIGHTS_FILE_ALL, &hf4su);
     326           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4su");
     327           4 :         status = torture_smb2_open(tree, f4sd, SEC_RIGHTS_FILE_ALL, &hf4sd);
     328           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4sd");
     329             : 
     330           4 :         info.normalized_name_info.in.file.handle = hd1;
     331           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     332           4 :         status = smb2_getinfo_file(tree, tree, &info);
     333           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd1");
     334           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     335             :                                  d1, "getinfo hd1");
     336           4 :         info.normalized_name_info.in.file.handle = hd1l;
     337           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     338           4 :         status = smb2_getinfo_file(tree, tree, &info);
     339           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd1l");
     340           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     341             :                                  d1, "getinfo hd1l");
     342           4 :         info.normalized_name_info.in.file.handle = hd1u;
     343           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     344           4 :         status = smb2_getinfo_file(tree, tree, &info);
     345           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd1u");
     346           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     347             :                                  d1, "getinfo hd1u");
     348             : 
     349           4 :         info.normalized_name_info.in.file.handle = hd2;
     350           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     351           4 :         status = smb2_getinfo_file(tree, tree, &info);
     352           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd2");
     353           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     354             :                                  d2, "getinfo hd2");
     355           4 :         info.normalized_name_info.in.file.handle = hd2l;
     356           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     357           4 :         status = smb2_getinfo_file(tree, tree, &info);
     358           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd2l");
     359           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     360             :                                  d2, "getinfo hd2l");
     361           4 :         info.normalized_name_info.in.file.handle = hd2u;
     362           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     363           4 :         status = smb2_getinfo_file(tree, tree, &info);
     364           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd2u");
     365           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     366             :                                  d2, "getinfo hd2u");
     367             : 
     368           4 :         info.normalized_name_info.in.file.handle = hd3;
     369           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     370           4 :         status = smb2_getinfo_file(tree, tree, &info);
     371           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3");
     372           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     373             :                                  d3, "getinfo hd3");
     374           4 :         info.normalized_name_info.in.file.handle = hd3l;
     375           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     376           4 :         status = smb2_getinfo_file(tree, tree, &info);
     377           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3l");
     378           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     379             :                                  d3, "getinfo hd3l");
     380           4 :         info.normalized_name_info.in.file.handle = hd3u;
     381           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     382           4 :         status = smb2_getinfo_file(tree, tree, &info);
     383           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3u");
     384           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     385             :                                  d3, "getinfo hd3u");
     386             : 
     387           4 :         info.normalized_name_info.in.file.handle = hd3s;
     388           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     389           4 :         status = smb2_getinfo_file(tree, tree, &info);
     390           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3s");
     391           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     392             :                                  d3s, "getinfo hd3s");
     393           4 :         info.normalized_name_info.in.file.handle = hd3sl;
     394           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     395           4 :         status = smb2_getinfo_file(tree, tree, &info);
     396           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3sl");
     397           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     398             :                                  d3s, "getinfo hd3sl");
     399           4 :         info.normalized_name_info.in.file.handle = hd3su;
     400           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     401           4 :         status = smb2_getinfo_file(tree, tree, &info);
     402           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3su");
     403           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     404             :                                  d3s, "getinfo hd3su");
     405           4 :         info.normalized_name_info.in.file.handle = hd3sd;
     406           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     407           4 :         status = smb2_getinfo_file(tree, tree, &info);
     408           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3sd");
     409           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     410             :                                  d3s, "getinfo hd3sd");
     411             : 
     412           4 :         info.normalized_name_info.in.file.handle = hf4;
     413           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     414           4 :         status = smb2_getinfo_file(tree, tree, &info);
     415           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4");
     416           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     417             :                                  f4, "getinfo hf4");
     418           4 :         info.normalized_name_info.in.file.handle = hf4l;
     419           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     420           4 :         status = smb2_getinfo_file(tree, tree, &info);
     421           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4l");
     422           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     423             :                                  f4, "getinfo hf4l");
     424           4 :         info.normalized_name_info.in.file.handle = hf4u;
     425           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     426           4 :         status = smb2_getinfo_file(tree, tree, &info);
     427           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4u");
     428           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     429             :                                  f4, "getinfo hf4u");
     430           4 :         info.normalized_name_info.in.file.handle = hf4d;
     431           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     432           4 :         status = smb2_getinfo_file(tree, tree, &info);
     433           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4d");
     434           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     435             :                                  f4, "getinfo hf4d");
     436             : 
     437           4 :         info.normalized_name_info.in.file.handle = hf4s;
     438           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     439           4 :         status = smb2_getinfo_file(tree, tree, &info);
     440           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4s");
     441           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     442             :                                  f4s, "getinfo hf4s");
     443           4 :         info.normalized_name_info.in.file.handle = hf4sl;
     444           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     445           4 :         status = smb2_getinfo_file(tree, tree, &info);
     446           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4sl");
     447           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     448             :                                  f4s, "getinfo hf4sl");
     449           4 :         info.normalized_name_info.in.file.handle = hf4su;
     450           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     451           4 :         status = smb2_getinfo_file(tree, tree, &info);
     452           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4su");
     453           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     454             :                                  f4s, "getinfo hf4su");
     455           4 :         info.normalized_name_info.in.file.handle = hf4sd;
     456           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     457           4 :         status = smb2_getinfo_file(tree, tree, &info);
     458           4 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4sd");
     459           4 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     460             :                                  f4s, "getinfo hf4sd");
     461             : 
     462             :         /* Set max protocol to SMB 3.0.2 */
     463           4 :         options3_0 = tree->session->transport->options;
     464           4 :         options3_0.max_protocol = PROTOCOL_SMB3_02;
     465           4 :         options3_0.client_guid = GUID_zero();
     466           4 :         ret = torture_smb2_connection_ext(tctx, 0, &options3_0, &tree_3_0);
     467           4 :         torture_assert(tctx, ret, "connection with SMB < 3.1.1 failed");
     468             : 
     469           4 :         status = smb2_util_roothandle(tree_3_0, &hroot_3_0);
     470           4 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle 3_0");
     471             : 
     472           4 :         info.normalized_name_info.in.file.handle = hroot_3_0;
     473           4 :         ZERO_STRUCT(info.normalized_name_info.out);
     474           4 :         status = smb2_getinfo_file(tree_3_0, tree_3_0, &info);
     475           4 :         torture_assert_ntstatus_equal(tctx, status,
     476             :                                       NT_STATUS_NOT_SUPPORTED,
     477             :                                       "getinfo hroot");
     478             : 
     479           4 :         return true;
     480             : }
     481             : 
     482             : /*
     483             :   test fsinfo levels
     484             : */
     485           5 : static bool torture_smb2_fsinfo(struct torture_context *tctx)
     486             : {
     487             :         bool ret;
     488             :         struct smb2_tree *tree;
     489             :         int i;
     490             :         NTSTATUS status;
     491             :         struct smb2_handle handle;
     492             : 
     493           5 :         torture_comment(tctx, "Testing fsinfo levels\n");
     494             : 
     495           5 :         ret = torture_smb2_connection(tctx, &tree);
     496           5 :         torture_assert(tctx, ret, "connection failed");
     497             : 
     498           5 :         status = smb2_util_roothandle(tree, &handle);
     499           5 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
     500             : 
     501          29 :         for (i=0;i<ARRAY_SIZE(fs_levels);i++) {
     502          28 :                 fs_levels[i].info.generic.level = fs_levels[i].level;
     503          28 :                 fs_levels[i].info.generic.handle = handle;
     504          28 :                 fs_levels[i].status = smb2_getinfo_fs(tree, tree, &fs_levels[i].info);
     505          28 :                 torture_assert_ntstatus_ok(tctx, fs_levels[i].status,
     506             :                                            fs_levels[i].name);
     507             :         }
     508             : 
     509           1 :         return true;
     510             : }
     511             : 
     512          84 : static bool torture_smb2_buffercheck_err(struct torture_context *tctx,
     513             :                                          struct smb2_tree *tree,
     514             :                                          struct smb2_getinfo *b,
     515             :                                          size_t fixed,
     516             :                                          DATA_BLOB full)
     517             : {
     518             :         size_t i;
     519             : 
     520        2286 :         for (i=0; i<=full.length; i++) {
     521             :                 NTSTATUS status;
     522             : 
     523        2204 :                 b->in.output_buffer_length = i;
     524             : 
     525        2204 :                 status = smb2_getinfo(tree, tree, b);
     526             : 
     527        2204 :                 if (i < fixed) {
     528        1928 :                         torture_assert_ntstatus_equal(
     529             :                                 tctx, status, NT_STATUS_INFO_LENGTH_MISMATCH,
     530             :                                 "Wrong error code small buffer");
     531        4048 :                         continue;
     532             :                 }
     533             : 
     534         276 :                 if (i<full.length) {
     535         194 :                         torture_assert_ntstatus_equal(
     536             :                                 tctx, status, STATUS_BUFFER_OVERFLOW,
     537             :                                 "Wrong error code for large buffer");
     538             :                         /*
     539             :                          * TODO: compare the output buffer. That seems a bit
     540             :                          * difficult, because for level 5 for example the
     541             :                          * label length is adjusted to what is there. And some
     542             :                          * reserved fields seem to be not initialized to 0.
     543             :                          */
     544         192 :                         TALLOC_FREE(b->out.blob.data);
     545         192 :                         continue;
     546             :                 }
     547             : 
     548          82 :                 torture_assert_ntstatus_equal(
     549             :                         tctx, status, NT_STATUS_OK,
     550             :                         "Wrong error code for right sized buffer");
     551             :         }
     552             : 
     553          82 :         return true;
     554             : }
     555             : 
     556             : struct level_buffersize {
     557             :         int level;
     558             :         size_t fixed;
     559             : };
     560             : 
     561           5 : static bool torture_smb2_qfs_buffercheck(struct torture_context *tctx)
     562             : {
     563             :         bool ret;
     564             :         struct smb2_tree *tree;
     565             :         NTSTATUS status;
     566             :         struct smb2_handle handle;
     567             :         int i;
     568             : 
     569           5 :         struct level_buffersize levels[] = {
     570             :                 { 1, 24 },      /* We don't have proper defines here */
     571             :                 { 3, 24 },
     572             :                 { 4, 8 },
     573             :                 { 5, 16 },
     574             :                 { 6, 48 },
     575             :                 { 7, 32 },
     576             :                 { 11, 28 },
     577             :         };
     578             : 
     579           5 :         torture_comment(tctx, "Testing SMB2_GETINFO_FS buffer sizes\n");
     580             : 
     581           5 :         ret = torture_smb2_connection(tctx, &tree);
     582           5 :         torture_assert(tctx, ret, "connection failed");
     583             : 
     584           5 :         status = smb2_util_roothandle(tree, &handle);
     585           5 :         torture_assert_ntstatus_ok(
     586             :                 tctx, status, "Unable to create root handle");
     587             : 
     588          36 :         for (i=0; i<ARRAY_SIZE(levels); i++) {
     589             :                 struct smb2_getinfo b;
     590             : 
     591          60 :                 if (TARGET_IS_SAMBA3(tctx) &&
     592          52 :                     ((levels[i].level == 6) || (levels[i].level == 11))) {
     593           8 :                         continue;
     594             :                 }
     595             : 
     596          24 :                 ZERO_STRUCT(b);
     597          24 :                 b.in.info_type                  = SMB2_0_INFO_FILESYSTEM;
     598          24 :                 b.in.info_class                 = levels[i].level;
     599          24 :                 b.in.file.handle                = handle;
     600          24 :                 b.in.output_buffer_length       = 65535;
     601             : 
     602          24 :                 status = smb2_getinfo(tree, tree, &b);
     603             : 
     604          24 :                 torture_assert_ntstatus_equal(
     605             :                         tctx, status, NT_STATUS_OK,
     606             :                         "Wrong error code for large buffer");
     607             : 
     608          24 :                 ret = torture_smb2_buffercheck_err(
     609             :                         tctx, tree, &b, levels[i].fixed, b.out.blob);
     610          24 :                 if (!ret) {
     611           1 :                         return ret;
     612             :                 }
     613             :         }
     614             : 
     615           4 :         return true;
     616             : }
     617             : 
     618           5 : static bool torture_smb2_qfile_buffercheck(struct torture_context *tctx)
     619             : {
     620             :         bool ret;
     621             :         struct smb2_tree *tree;
     622             :         struct smb2_create c;
     623             :         NTSTATUS status;
     624             :         struct smb2_handle handle;
     625             :         int i;
     626             : 
     627           5 :         struct level_buffersize levels[] = {
     628             :                 { 4, 40 },
     629             :                 { 5, 24 },
     630             :                 { 6, 8 },
     631             :                 { 7, 4 },
     632             :                 { 8, 4 },
     633             :                 { 16, 4 },
     634             :                 { 17, 4 },
     635             :                 { 18, 104 },
     636             :                 { 21, 8 },
     637             :                 { 22, 32 },
     638             :                 { 28, 16 },
     639             :                 { 34, 56 },
     640             :                 { 35, 8 },
     641             :         };
     642             : 
     643           5 :         torture_comment(tctx, "Testing SMB2_GETINFO_FILE buffer sizes\n");
     644             : 
     645           5 :         ret = torture_smb2_connection(tctx, &tree);
     646           5 :         torture_assert(tctx, ret, "connection failed");
     647             : 
     648           5 :         ZERO_STRUCT(c);
     649           5 :         c.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     650           5 :         c.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
     651           5 :         c.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     652           5 :         c.in.share_access =
     653             :                 NTCREATEX_SHARE_ACCESS_DELETE|
     654             :                 NTCREATEX_SHARE_ACCESS_READ|
     655             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     656           5 :         c.in.create_options = 0;
     657           5 :         c.in.fname = "bufsize.txt";
     658             : 
     659           5 :         c.in.eas.num_eas = 2;
     660           5 :         c.in.eas.eas = talloc_array(tree, struct ea_struct, 2);
     661           5 :         c.in.eas.eas[0].flags = 0;
     662           5 :         c.in.eas.eas[0].name.s = "EAONE";
     663           5 :         c.in.eas.eas[0].value = data_blob_talloc(c.in.eas.eas, "VALUE1", 6);
     664           5 :         c.in.eas.eas[1].flags = 0;
     665           5 :         c.in.eas.eas[1].name.s = "SECONDEA";
     666           5 :         c.in.eas.eas[1].value = data_blob_talloc(c.in.eas.eas, "ValueTwo", 8);
     667             : 
     668           5 :         status = smb2_create(tree, tree, &c);
     669           5 :         torture_assert_ntstatus_ok(
     670             :                 tctx, status, "Unable to create test file");
     671             : 
     672           5 :         handle = c.out.file.handle;
     673             : 
     674          64 :         for (i=0; i<ARRAY_SIZE(levels); i++) {
     675             :                 struct smb2_getinfo b;
     676             : 
     677          60 :                 ZERO_STRUCT(b);
     678          60 :                 b.in.info_type                  = SMB2_0_INFO_FILE;
     679          60 :                 b.in.info_class                 = levels[i].level;
     680          60 :                 b.in.file.handle                = handle;
     681          60 :                 b.in.output_buffer_length       = 65535;
     682             : 
     683          60 :                 status = smb2_getinfo(tree, tree, &b);
     684          60 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
     685           0 :                         continue;
     686             :                 }
     687          60 :                 torture_assert_ntstatus_equal(
     688             :                         tctx, status, NT_STATUS_OK,
     689             :                         "Wrong error code for large buffer");
     690             : 
     691          60 :                 ret = torture_smb2_buffercheck_err(
     692             :                         tctx, tree, &b, levels[i].fixed, b.out.blob);
     693          60 :                 if (!ret) {
     694           1 :                         return ret;
     695             :                 }
     696             :         }
     697           4 :         return true;
     698             : }
     699             : 
     700           5 : static bool torture_smb2_qsec_buffercheck(struct torture_context *tctx)
     701             : {
     702             :         struct smb2_getinfo b;
     703             :         bool ret;
     704             :         struct smb2_tree *tree;
     705             :         struct smb2_create c;
     706             :         NTSTATUS status;
     707             :         struct smb2_handle handle;
     708             : 
     709           5 :         torture_comment(tctx, "Testing SMB2_GETINFO_SECURITY buffer sizes\n");
     710             : 
     711           5 :         ret = torture_smb2_connection(tctx, &tree);
     712           5 :         torture_assert(tctx, ret, "connection failed");
     713             : 
     714           5 :         ZERO_STRUCT(c);
     715           5 :         c.in.oplock_level = 0;
     716           5 :         c.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE |
     717             :                 SEC_DIR_LIST | SEC_STD_READ_CONTROL;
     718           5 :         c.in.file_attributes   = 0;
     719           5 :         c.in.create_disposition = NTCREATEX_DISP_OPEN;
     720           5 :         c.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
     721             :                 NTCREATEX_SHARE_ACCESS_DELETE;
     722           5 :         c.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT;
     723           5 :         c.in.fname = "";
     724             : 
     725           5 :         status = smb2_create(tree, tree, &c);
     726           5 :         torture_assert_ntstatus_ok(
     727             :                 tctx, status, "Unable to create root handle");
     728             : 
     729           5 :         handle = c.out.file.handle;
     730             : 
     731           5 :         ZERO_STRUCT(b);
     732           5 :         b.in.info_type                  = SMB2_0_INFO_SECURITY;
     733           5 :         b.in.info_class                 = 0;
     734           5 :         b.in.file.handle                = handle;
     735           5 :         b.in.output_buffer_length       = 0;
     736             : 
     737           5 :         status = smb2_getinfo(tree, tree, &b);
     738           5 :         torture_assert_ntstatus_equal(
     739             :                 tctx, status, NT_STATUS_BUFFER_TOO_SMALL,
     740             :                 "Wrong error code for large buffer");
     741             : 
     742           4 :         b.in.output_buffer_length       = 1;
     743           4 :         status = smb2_getinfo(tree, tree, &b);
     744           4 :         torture_assert_ntstatus_equal(
     745             :                 tctx, status, NT_STATUS_BUFFER_TOO_SMALL,
     746             :                 "Wrong error code for large buffer");
     747             : 
     748           4 :         return true;
     749             : }
     750             : 
     751             : /* basic testing of all SMB2 getinfo levels
     752             : */
     753           5 : static bool torture_smb2_getinfo(struct torture_context *tctx)
     754             : {
     755             :         struct smb2_tree *tree;
     756           5 :         bool ret = true;
     757             :         NTSTATUS status;
     758             : 
     759           5 :         ret = torture_smb2_connection(tctx, &tree);
     760           5 :         torture_assert(tctx, ret, "connection failed");
     761             : 
     762           5 :         smb2_deltree(tree, FNAME);
     763           5 :         smb2_deltree(tree, DNAME);
     764             : 
     765           5 :         status = torture_setup_complex_file(tctx, tree, FNAME);
     766           5 :         torture_assert_ntstatus_ok(tctx, status,
     767             :                                    "setup complex file " FNAME);
     768             : 
     769           1 :         status = torture_setup_complex_file(tctx, tree, FNAME ":streamtwo");
     770           1 :         torture_assert_ntstatus_ok(tctx, status,
     771             :                                    "setup complex file " FNAME ":streamtwo");
     772             : 
     773           1 :         status = torture_setup_complex_dir(tctx, tree, DNAME);
     774           1 :         torture_assert_ntstatus_ok(tctx, status,
     775             :                                    "setup complex dir " DNAME);
     776             : 
     777           1 :         status = torture_setup_complex_file(tctx, tree, DNAME ":streamtwo");
     778           1 :         torture_assert_ntstatus_ok(tctx, status,
     779             :                                    "setup complex dir " DNAME ":streamtwo");
     780             : 
     781           0 :         ret &= torture_smb2_fileinfo(tctx, tree);
     782             : 
     783           0 :         return ret;
     784             : }
     785             : 
     786        2353 : struct torture_suite *torture_smb2_getinfo_init(TALLOC_CTX *ctx)
     787             : {
     788        2353 :         struct torture_suite *suite = torture_suite_create(
     789             :                 ctx, "getinfo");
     790             : 
     791        2353 :         torture_suite_add_simple_test(suite, "complex", torture_smb2_getinfo);
     792        2353 :         torture_suite_add_simple_test(suite, "fsinfo",  torture_smb2_fsinfo);
     793        2353 :         torture_suite_add_simple_test(suite, "qfs_buffercheck",
     794             :                                       torture_smb2_qfs_buffercheck);
     795        2353 :         torture_suite_add_simple_test(suite, "qfile_buffercheck",
     796             :                                       torture_smb2_qfile_buffercheck);
     797        2353 :         torture_suite_add_simple_test(suite, "qsec_buffercheck",
     798             :                                       torture_smb2_qsec_buffercheck);
     799        2353 :         torture_suite_add_simple_test(suite, "granted",
     800             :                                       torture_smb2_fileinfo_grant_read);
     801        2353 :         torture_suite_add_simple_test(suite, "normalized",
     802             :                                       torture_smb2_fileinfo_normalized);
     803        2353 :         return suite;
     804             : }

Generated by: LCOV version 1.13