LCOV - code coverage report
Current view: top level - source4/torture/smb2 - getinfo.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 215 440 48.9 %
Date: 2024-06-13 04:01:37 Functions: 10 11 90.9 %

          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           1 : 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           1 :         ret = torture_smb2_connection(tctx, &tree);
     142           1 :         torture_assert(tctx, ret, "connection failed");
     143             : 
     144           1 :         status = torture_smb2_testfile_access(
     145             :             tree, FNAME, &hfile, SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE);
     146           1 :         torture_assert_ntstatus_ok(tctx, status,
     147             :                                    "Unable to create test file " FNAME "\n");
     148           1 :         status =
     149           1 :             torture_smb2_get_allinfo_access(tree, hfile, &file_granted_access);
     150           1 :         torture_assert_ntstatus_ok(tctx, status,
     151             :                                    "Unable to query test file access ");
     152           1 :         torture_assert_int_equal(tctx, file_granted_access,
     153             :                                  SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE,
     154             :                                  "granted file access ");
     155           1 :         smb2_util_close(tree, hfile);
     156             : 
     157           1 :         status = torture_smb2_testdir_access(
     158             :             tree, DNAME, &hdir, SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE);
     159           1 :         torture_assert_ntstatus_ok(tctx, status,
     160             :                                    "Unable to create test dir " DNAME "\n");
     161           1 :         status =
     162           1 :             torture_smb2_get_allinfo_access(tree, hdir, &dir_granted_access);
     163           1 :         torture_assert_ntstatus_ok(tctx, status,
     164             :                                    "Unable to query test dir access ");
     165           1 :         torture_assert_int_equal(tctx, dir_granted_access,
     166             :                                  SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE,
     167             :                                  "granted dir access ");
     168           1 :         smb2_util_close(tree, hdir);
     169             : 
     170           1 :         return true;
     171             : }
     172             : 
     173           1 : static bool torture_smb2_fileinfo_normalized(struct torture_context *tctx)
     174             : {
     175           1 :         struct smb2_tree *tree = NULL;
     176             :         bool ret;
     177             :         struct smb2_handle hroot;
     178           1 :         const char *d1 = NULL, *d1l = NULL, *d1u = NULL;
     179             :         struct smb2_handle hd1, hd1l, hd1u;
     180           1 :         const char *d2 = NULL, *d2l = NULL, *d2u = NULL;
     181             :         struct smb2_handle hd2, hd2l, hd2u;
     182           1 :         const char *d3 = NULL, *d3l = NULL, *d3u = NULL;
     183             :         struct smb2_handle hd3, hd3l, hd3u;
     184           1 :         const char *d3s = NULL, *d3sl = NULL, *d3su = NULL, *d3sd = NULL;
     185             :         struct smb2_handle hd3s, hd3sl, hd3su, hd3sd;
     186           1 :         const char *f4 = NULL, *f4l = NULL, *f4u = NULL, *f4d = NULL;
     187             :         struct smb2_handle hf4, hf4l, hf4u, hf4d;
     188           1 :         const char *f4s = NULL, *f4sl = NULL, *f4su = NULL, *f4sd = NULL;
     189             :         struct smb2_handle hf4s, hf4sl, hf4su, hf4sd;
     190           1 :         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           1 :         struct smb2_tree *tree_3_0 = NULL;
     198             :         struct smbcli_options options3_0;
     199             :         struct smb2_handle hroot_3_0;
     200             : 
     201           1 :         ret = torture_smb2_connection(tctx, &tree);
     202           1 :         torture_assert(tctx, ret, "connection failed");
     203             : 
     204           1 :         protocol = smbXcli_conn_protocol(tree->session->transport->conn);
     205             : 
     206           1 :         d1 = talloc_asprintf(tctx, "torture_dIr1N");
     207           1 :         torture_assert_not_null(tctx, d1, "d1");
     208           1 :         d1l = strlower_talloc(tctx, d1);
     209           1 :         torture_assert_not_null(tctx, d1l, "d1l");
     210           1 :         d1u = strupper_talloc(tctx, d1);
     211           1 :         torture_assert_not_null(tctx, d1u, "d1u");
     212             : 
     213           1 :         d2 = talloc_asprintf(tctx, "%s\\dIr2Na", d1);
     214           1 :         torture_assert_not_null(tctx, d2, "d2");
     215           1 :         d2l = strlower_talloc(tctx, d2);
     216           1 :         torture_assert_not_null(tctx, d2l, "d2l");
     217           1 :         d2u = strupper_talloc(tctx, d2);
     218           1 :         torture_assert_not_null(tctx, d2u, "d2u");
     219             : 
     220           1 :         d3 = talloc_asprintf(tctx, "%s\\dIr3NaM", d2);
     221           1 :         torture_assert_not_null(tctx, d3, "d3");
     222           1 :         d3l = strlower_talloc(tctx, d3);
     223           1 :         torture_assert_not_null(tctx, d3l, "d3l");
     224           1 :         d3u = strupper_talloc(tctx, d3);
     225           1 :         torture_assert_not_null(tctx, d3u, "d3u");
     226             : 
     227           1 :         d3s = talloc_asprintf(tctx, "%s:sTrEaM3", d3);
     228           1 :         torture_assert_not_null(tctx, d3s, "d3s");
     229           1 :         d3sl = strlower_talloc(tctx, d3s);
     230           1 :         torture_assert_not_null(tctx, d3sl, "d3sl");
     231           1 :         d3su = strupper_talloc(tctx, d3s);
     232           1 :         torture_assert_not_null(tctx, d3su, "d3su");
     233           1 :         d3sd = talloc_asprintf(tctx, "%s:$DaTa", d3s);
     234           1 :         torture_assert_not_null(tctx, d3sd, "d3sd");
     235             : 
     236           1 :         f4 = talloc_asprintf(tctx, "%s\\fIlE4NaMe", d3);
     237           1 :         torture_assert_not_null(tctx, f4, "f4");
     238           1 :         f4l = strlower_talloc(tctx, f4);
     239           1 :         torture_assert_not_null(tctx, f4l, "f4l");
     240           1 :         f4u = strupper_talloc(tctx, f4);
     241           1 :         torture_assert_not_null(tctx, f4u, "f4u");
     242           1 :         f4d = talloc_asprintf(tctx, "%s::$dAtA", f4);
     243           1 :         torture_assert_not_null(tctx, f4d, "f4d");
     244             : 
     245           1 :         f4s = talloc_asprintf(tctx, "%s:StReAm4", f4);
     246           1 :         torture_assert_not_null(tctx, f4s, "f4s");
     247           1 :         f4sl = strlower_talloc(tctx, f4s);
     248           1 :         torture_assert_not_null(tctx, f4sl, "f4sl");
     249           1 :         f4su = strupper_talloc(tctx, f4s);
     250           1 :         torture_assert_not_null(tctx, f4su, "f4su");
     251           1 :         f4sd = talloc_asprintf(tctx, "%s:$dAtA", f4s);
     252           1 :         torture_assert_not_null(tctx, f4sd, "f4sd");
     253             : 
     254           1 :         status = smb2_util_roothandle(tree, &hroot);
     255           1 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
     256             : 
     257           1 :         info.normalized_name_info.in.file.handle = hroot;
     258           1 :         ZERO_STRUCT(info.normalized_name_info.out);
     259           1 :         status = smb2_getinfo_file(tree, tree, &info);
     260           1 :         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           0 :         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           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hroot");
     277           0 :         torture_assert(tctx, info.normalized_name_info.out.fname.s == NULL,
     278             :                        "getinfo hroot should be empty");
     279             : 
     280           0 :         smb2_deltree(tree, d1);
     281             : 
     282           0 :         status = torture_smb2_testdir(tree, d1, &hd1);
     283           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hd1");
     284           0 :         status = torture_smb2_open(tree, d1l, SEC_RIGHTS_FILE_ALL, &hd1l);
     285           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd1l");
     286           0 :         status = torture_smb2_open(tree, d1u, SEC_RIGHTS_FILE_ALL, &hd1u);
     287           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd1u");
     288             : 
     289           0 :         status = torture_smb2_testdir(tree, d2, &hd2);
     290           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hd2");
     291           0 :         status = torture_smb2_open(tree, d2l, SEC_RIGHTS_FILE_ALL, &hd2l);
     292           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd2l");
     293           0 :         status = torture_smb2_open(tree, d2u, SEC_RIGHTS_FILE_ALL, &hd2u);
     294           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd2u");
     295             : 
     296           0 :         status = torture_smb2_testdir(tree, d3, &hd3);
     297           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hd3");
     298           0 :         status = torture_smb2_open(tree, d3l, SEC_RIGHTS_FILE_ALL, &hd3l);
     299           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3l");
     300           0 :         status = torture_smb2_open(tree, d3u, SEC_RIGHTS_FILE_ALL, &hd3u);
     301           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3u");
     302             : 
     303           0 :         status = torture_smb2_testfile(tree, d3s, &hd3s);
     304           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hd3s");
     305           0 :         status = torture_smb2_open(tree, d3sl, SEC_RIGHTS_FILE_ALL, &hd3sl);
     306           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3sl");
     307           0 :         status = torture_smb2_open(tree, d3su, SEC_RIGHTS_FILE_ALL, &hd3su);
     308           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3su");
     309           0 :         status = torture_smb2_open(tree, d3sd, SEC_RIGHTS_FILE_ALL, &hd3sd);
     310           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3sd");
     311             : 
     312           0 :         status = torture_smb2_testfile(tree, f4, &hf4);
     313           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hf4");
     314           0 :         status = torture_smb2_open(tree, f4l, SEC_RIGHTS_FILE_ALL, &hf4l);
     315           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4l");
     316           0 :         status = torture_smb2_open(tree, f4u, SEC_RIGHTS_FILE_ALL, &hf4u);
     317           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4u");
     318           0 :         status = torture_smb2_open(tree, f4d, SEC_RIGHTS_FILE_ALL, &hf4d);
     319           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4d");
     320             : 
     321           0 :         status = torture_smb2_testfile(tree, f4s, &hf4s);
     322           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create hf4s");
     323           0 :         status = torture_smb2_open(tree, f4sl, SEC_RIGHTS_FILE_ALL, &hf4sl);
     324           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4sl");
     325           0 :         status = torture_smb2_open(tree, f4su, SEC_RIGHTS_FILE_ALL, &hf4su);
     326           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4su");
     327           0 :         status = torture_smb2_open(tree, f4sd, SEC_RIGHTS_FILE_ALL, &hf4sd);
     328           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4sd");
     329             : 
     330           0 :         info.normalized_name_info.in.file.handle = hd1;
     331           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     332           0 :         status = smb2_getinfo_file(tree, tree, &info);
     333           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd1");
     334           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     335             :                                  d1, "getinfo hd1");
     336           0 :         info.normalized_name_info.in.file.handle = hd1l;
     337           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     338           0 :         status = smb2_getinfo_file(tree, tree, &info);
     339           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd1l");
     340           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     341             :                                  d1, "getinfo hd1l");
     342           0 :         info.normalized_name_info.in.file.handle = hd1u;
     343           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     344           0 :         status = smb2_getinfo_file(tree, tree, &info);
     345           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd1u");
     346           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     347             :                                  d1, "getinfo hd1u");
     348             : 
     349           0 :         info.normalized_name_info.in.file.handle = hd2;
     350           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     351           0 :         status = smb2_getinfo_file(tree, tree, &info);
     352           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd2");
     353           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     354             :                                  d2, "getinfo hd2");
     355           0 :         info.normalized_name_info.in.file.handle = hd2l;
     356           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     357           0 :         status = smb2_getinfo_file(tree, tree, &info);
     358           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd2l");
     359           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     360             :                                  d2, "getinfo hd2l");
     361           0 :         info.normalized_name_info.in.file.handle = hd2u;
     362           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     363           0 :         status = smb2_getinfo_file(tree, tree, &info);
     364           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd2u");
     365           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     366             :                                  d2, "getinfo hd2u");
     367             : 
     368           0 :         info.normalized_name_info.in.file.handle = hd3;
     369           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     370           0 :         status = smb2_getinfo_file(tree, tree, &info);
     371           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3");
     372           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     373             :                                  d3, "getinfo hd3");
     374           0 :         info.normalized_name_info.in.file.handle = hd3l;
     375           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     376           0 :         status = smb2_getinfo_file(tree, tree, &info);
     377           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3l");
     378           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     379             :                                  d3, "getinfo hd3l");
     380           0 :         info.normalized_name_info.in.file.handle = hd3u;
     381           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     382           0 :         status = smb2_getinfo_file(tree, tree, &info);
     383           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3u");
     384           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     385             :                                  d3, "getinfo hd3u");
     386             : 
     387           0 :         info.normalized_name_info.in.file.handle = hd3s;
     388           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     389           0 :         status = smb2_getinfo_file(tree, tree, &info);
     390           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3s");
     391           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     392             :                                  d3s, "getinfo hd3s");
     393           0 :         info.normalized_name_info.in.file.handle = hd3sl;
     394           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     395           0 :         status = smb2_getinfo_file(tree, tree, &info);
     396           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3sl");
     397           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     398             :                                  d3s, "getinfo hd3sl");
     399           0 :         info.normalized_name_info.in.file.handle = hd3su;
     400           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     401           0 :         status = smb2_getinfo_file(tree, tree, &info);
     402           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3su");
     403           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     404             :                                  d3s, "getinfo hd3su");
     405           0 :         info.normalized_name_info.in.file.handle = hd3sd;
     406           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     407           0 :         status = smb2_getinfo_file(tree, tree, &info);
     408           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hd3sd");
     409           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     410             :                                  d3s, "getinfo hd3sd");
     411             : 
     412           0 :         info.normalized_name_info.in.file.handle = hf4;
     413           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     414           0 :         status = smb2_getinfo_file(tree, tree, &info);
     415           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4");
     416           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     417             :                                  f4, "getinfo hf4");
     418           0 :         info.normalized_name_info.in.file.handle = hf4l;
     419           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     420           0 :         status = smb2_getinfo_file(tree, tree, &info);
     421           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4l");
     422           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     423             :                                  f4, "getinfo hf4l");
     424           0 :         info.normalized_name_info.in.file.handle = hf4u;
     425           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     426           0 :         status = smb2_getinfo_file(tree, tree, &info);
     427           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4u");
     428           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     429             :                                  f4, "getinfo hf4u");
     430           0 :         info.normalized_name_info.in.file.handle = hf4d;
     431           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     432           0 :         status = smb2_getinfo_file(tree, tree, &info);
     433           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4d");
     434           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     435             :                                  f4, "getinfo hf4d");
     436             : 
     437           0 :         info.normalized_name_info.in.file.handle = hf4s;
     438           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     439           0 :         status = smb2_getinfo_file(tree, tree, &info);
     440           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4s");
     441           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     442             :                                  f4s, "getinfo hf4s");
     443           0 :         info.normalized_name_info.in.file.handle = hf4sl;
     444           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     445           0 :         status = smb2_getinfo_file(tree, tree, &info);
     446           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4sl");
     447           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     448             :                                  f4s, "getinfo hf4sl");
     449           0 :         info.normalized_name_info.in.file.handle = hf4su;
     450           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     451           0 :         status = smb2_getinfo_file(tree, tree, &info);
     452           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4su");
     453           0 :         torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
     454             :                                  f4s, "getinfo hf4su");
     455           0 :         info.normalized_name_info.in.file.handle = hf4sd;
     456           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     457           0 :         status = smb2_getinfo_file(tree, tree, &info);
     458           0 :         torture_assert_ntstatus_ok(tctx, status, "getinfo hf4sd");
     459           0 :         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           0 :         options3_0 = tree->session->transport->options;
     464           0 :         options3_0.max_protocol = PROTOCOL_SMB3_02;
     465           0 :         options3_0.client_guid = GUID_zero();
     466           0 :         ret = torture_smb2_connection_ext(tctx, 0, &options3_0, &tree_3_0);
     467           0 :         torture_assert(tctx, ret, "connection with SMB < 3.1.1 failed");
     468             : 
     469           0 :         status = smb2_util_roothandle(tree_3_0, &hroot_3_0);
     470           0 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle 3_0");
     471             : 
     472           0 :         info.normalized_name_info.in.file.handle = hroot_3_0;
     473           0 :         ZERO_STRUCT(info.normalized_name_info.out);
     474           0 :         status = smb2_getinfo_file(tree_3_0, tree_3_0, &info);
     475           0 :         torture_assert_ntstatus_equal(tctx, status,
     476             :                                       NT_STATUS_NOT_SUPPORTED,
     477             :                                       "getinfo hroot");
     478             : 
     479           0 :         return true;
     480             : }
     481             : 
     482             : /*
     483             :   test fsinfo levels
     484             : */
     485           1 : 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           1 :         torture_comment(tctx, "Testing fsinfo levels\n");
     494             : 
     495           1 :         ret = torture_smb2_connection(tctx, &tree);
     496           1 :         torture_assert(tctx, ret, "connection failed");
     497             : 
     498           1 :         status = smb2_util_roothandle(tree, &handle);
     499           1 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
     500             : 
     501           9 :         for (i=0;i<ARRAY_SIZE(fs_levels);i++) {
     502           8 :                 fs_levels[i].info.generic.level = fs_levels[i].level;
     503           8 :                 fs_levels[i].info.generic.handle = handle;
     504           8 :                 fs_levels[i].status = smb2_getinfo_fs(tree, tree, &fs_levels[i].info);
     505           8 :                 torture_assert_ntstatus_ok(tctx, fs_levels[i].status,
     506             :                                            fs_levels[i].name);
     507             :         }
     508             : 
     509           1 :         return true;
     510             : }
     511             : 
     512          12 : 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         286 :         for (i=0; i<=full.length; i++) {
     521             :                 NTSTATUS status;
     522             : 
     523         276 :                 b->in.output_buffer_length = i;
     524             : 
     525         276 :                 status = smb2_getinfo(tree, tree, b);
     526             : 
     527         276 :                 if (i < fixed) {
     528         264 :                         torture_assert_ntstatus_equal(
     529             :                                 tctx, status, NT_STATUS_INFO_LENGTH_MISMATCH,
     530             :                                 "Wrong error code small buffer");
     531         528 :                         continue;
     532             :                 }
     533             : 
     534          12 :                 if (i<full.length) {
     535           2 :                         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           0 :                         TALLOC_FREE(b->out.blob.data);
     545           0 :                         continue;
     546             :                 }
     547             : 
     548          10 :                 torture_assert_ntstatus_equal(
     549             :                         tctx, status, NT_STATUS_OK,
     550             :                         "Wrong error code for right sized buffer");
     551             :         }
     552             : 
     553          10 :         return true;
     554             : }
     555             : 
     556             : struct level_buffersize {
     557             :         int level;
     558             :         size_t fixed;
     559             : };
     560             : 
     561           1 : 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           1 :         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           1 :         torture_comment(tctx, "Testing SMB2_GETINFO_FS buffer sizes\n");
     580             : 
     581           1 :         ret = torture_smb2_connection(tctx, &tree);
     582           1 :         torture_assert(tctx, ret, "connection failed");
     583             : 
     584           1 :         status = smb2_util_roothandle(tree, &handle);
     585           1 :         torture_assert_ntstatus_ok(
     586             :                 tctx, status, "Unable to create root handle");
     587             : 
     588           4 :         for (i=0; i<ARRAY_SIZE(levels); i++) {
     589             :                 struct smb2_getinfo b;
     590             : 
     591           4 :                 if (TARGET_IS_SAMBA3(tctx) &&
     592           0 :                     ((levels[i].level == 6) || (levels[i].level == 11))) {
     593           0 :                         continue;
     594             :                 }
     595             : 
     596           4 :                 ZERO_STRUCT(b);
     597           4 :                 b.in.info_type                  = SMB2_0_INFO_FILESYSTEM;
     598           4 :                 b.in.info_class                 = levels[i].level;
     599           4 :                 b.in.file.handle                = handle;
     600           4 :                 b.in.output_buffer_length       = 65535;
     601             : 
     602           4 :                 status = smb2_getinfo(tree, tree, &b);
     603             : 
     604           4 :                 torture_assert_ntstatus_equal(
     605             :                         tctx, status, NT_STATUS_OK,
     606             :                         "Wrong error code for large buffer");
     607             : 
     608           4 :                 ret = torture_smb2_buffercheck_err(
     609             :                         tctx, tree, &b, levels[i].fixed, b.out.blob);
     610           4 :                 if (!ret) {
     611           1 :                         return ret;
     612             :                 }
     613             :         }
     614             : 
     615           0 :         return true;
     616             : }
     617             : 
     618           1 : 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           1 :         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           1 :         torture_comment(tctx, "Testing SMB2_GETINFO_FILE buffer sizes\n");
     644             : 
     645           1 :         ret = torture_smb2_connection(tctx, &tree);
     646           1 :         torture_assert(tctx, ret, "connection failed");
     647             : 
     648           1 :         ZERO_STRUCT(c);
     649           1 :         c.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     650           1 :         c.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
     651           1 :         c.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     652           1 :         c.in.share_access =
     653             :                 NTCREATEX_SHARE_ACCESS_DELETE|
     654             :                 NTCREATEX_SHARE_ACCESS_READ|
     655             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     656           1 :         c.in.create_options = 0;
     657           1 :         c.in.fname = "bufsize.txt";
     658             : 
     659           1 :         c.in.eas.num_eas = 2;
     660           1 :         c.in.eas.eas = talloc_array(tree, struct ea_struct, 2);
     661           1 :         c.in.eas.eas[0].flags = 0;
     662           1 :         c.in.eas.eas[0].name.s = "EAONE";
     663           1 :         c.in.eas.eas[0].value = data_blob_talloc(c.in.eas.eas, "VALUE1", 6);
     664           1 :         c.in.eas.eas[1].flags = 0;
     665           1 :         c.in.eas.eas[1].name.s = "SECONDEA";
     666           1 :         c.in.eas.eas[1].value = data_blob_talloc(c.in.eas.eas, "ValueTwo", 8);
     667             : 
     668           1 :         status = smb2_create(tree, tree, &c);
     669           1 :         torture_assert_ntstatus_ok(
     670             :                 tctx, status, "Unable to create test file");
     671             : 
     672           1 :         handle = c.out.file.handle;
     673             : 
     674           8 :         for (i=0; i<ARRAY_SIZE(levels); i++) {
     675             :                 struct smb2_getinfo b;
     676             : 
     677           8 :                 ZERO_STRUCT(b);
     678           8 :                 b.in.info_type                  = SMB2_0_INFO_FILE;
     679           8 :                 b.in.info_class                 = levels[i].level;
     680           8 :                 b.in.file.handle                = handle;
     681           8 :                 b.in.output_buffer_length       = 65535;
     682             : 
     683           8 :                 status = smb2_getinfo(tree, tree, &b);
     684           8 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
     685           0 :                         continue;
     686             :                 }
     687           8 :                 torture_assert_ntstatus_equal(
     688             :                         tctx, status, NT_STATUS_OK,
     689             :                         "Wrong error code for large buffer");
     690             : 
     691           8 :                 ret = torture_smb2_buffercheck_err(
     692             :                         tctx, tree, &b, levels[i].fixed, b.out.blob);
     693           8 :                 if (!ret) {
     694           1 :                         return ret;
     695             :                 }
     696             :         }
     697           0 :         return true;
     698             : }
     699             : 
     700           1 : 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           1 :         torture_comment(tctx, "Testing SMB2_GETINFO_SECURITY buffer sizes\n");
     710             : 
     711           1 :         ret = torture_smb2_connection(tctx, &tree);
     712           1 :         torture_assert(tctx, ret, "connection failed");
     713             : 
     714           1 :         ZERO_STRUCT(c);
     715           1 :         c.in.oplock_level = 0;
     716           1 :         c.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE |
     717             :                 SEC_DIR_LIST | SEC_STD_READ_CONTROL;
     718           1 :         c.in.file_attributes   = 0;
     719           1 :         c.in.create_disposition = NTCREATEX_DISP_OPEN;
     720           1 :         c.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
     721             :                 NTCREATEX_SHARE_ACCESS_DELETE;
     722           1 :         c.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT;
     723           1 :         c.in.fname = "";
     724             : 
     725           1 :         status = smb2_create(tree, tree, &c);
     726           1 :         torture_assert_ntstatus_ok(
     727             :                 tctx, status, "Unable to create root handle");
     728             : 
     729           1 :         handle = c.out.file.handle;
     730             : 
     731           1 :         ZERO_STRUCT(b);
     732           1 :         b.in.info_type                  = SMB2_0_INFO_SECURITY;
     733           1 :         b.in.info_class                 = 0;
     734           1 :         b.in.file.handle                = handle;
     735           1 :         b.in.output_buffer_length       = 0;
     736             : 
     737           1 :         status = smb2_getinfo(tree, tree, &b);
     738           1 :         torture_assert_ntstatus_equal(
     739             :                 tctx, status, NT_STATUS_BUFFER_TOO_SMALL,
     740             :                 "Wrong error code for large buffer");
     741             : 
     742           0 :         b.in.output_buffer_length       = 1;
     743           0 :         status = smb2_getinfo(tree, tree, &b);
     744           0 :         torture_assert_ntstatus_equal(
     745             :                 tctx, status, NT_STATUS_BUFFER_TOO_SMALL,
     746             :                 "Wrong error code for large buffer");
     747             : 
     748           0 :         return true;
     749             : }
     750             : 
     751             : /* basic testing of all SMB2 getinfo levels
     752             : */
     753           1 : static bool torture_smb2_getinfo(struct torture_context *tctx)
     754             : {
     755             :         struct smb2_tree *tree;
     756           1 :         bool ret = true;
     757             :         NTSTATUS status;
     758             : 
     759           1 :         ret = torture_smb2_connection(tctx, &tree);
     760           1 :         torture_assert(tctx, ret, "connection failed");
     761             : 
     762           1 :         smb2_deltree(tree, FNAME);
     763           1 :         smb2_deltree(tree, DNAME);
     764             : 
     765           1 :         status = torture_setup_complex_file(tctx, tree, FNAME);
     766           1 :         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             : #undef LEVEL
     787             : #define LEVEL(l, u, ua, ra) \
     788             :         .name = #l, \
     789             :         .level = l, \
     790             :         .unrestricted = u, \
     791             :         .unrestricted_access = ua, \
     792             :         .required_access = ra
     793             : 
     794             : static struct {
     795             :         const char *name;
     796             :         uint16_t level;
     797             :         bool unrestricted;
     798             :         uint32_t unrestricted_access;
     799             :         uint32_t required_access;
     800             : } file_levels_access[] = {
     801             :         /*
     802             :          * The following info levels are not checked:
     803             :          * - FileFullEaInformation and FileIdInformation:
     804             :          *   not implemented by the s4/libcli/raw
     805             :          * - all pipe infolevels: that should be tested elsewhere by RPC tests
     806             :          */
     807             : 
     808             :         /*
     809             :          * The following allow unrestricted access, so requesting
     810             :          * SEC_FILE_READ_ATTRIBUTE works, SEC_FILE_READ_ATTRIBUTE or
     811             :          * SEC_FILE_READ_EA as well of course.
     812             :          */
     813             :         { LEVEL(RAW_FILEINFO_STANDARD_INFORMATION, true, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     814             :         { LEVEL(RAW_FILEINFO_INTERNAL_INFORMATION, true, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     815             :         { LEVEL(RAW_FILEINFO_ACCESS_INFORMATION, true, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     816             :         { LEVEL(RAW_FILEINFO_POSITION_INFORMATION, true, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     817             :         { LEVEL(RAW_FILEINFO_MODE_INFORMATION, true, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     818             :         { LEVEL(RAW_FILEINFO_ALIGNMENT_INFORMATION, true, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     819             :         { LEVEL(RAW_FILEINFO_ALT_NAME_INFORMATION, true, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     820             :         { LEVEL(RAW_FILEINFO_STREAM_INFORMATION, true, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     821             :         { LEVEL(RAW_FILEINFO_COMPRESSION_INFORMATION, true, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     822             :         { LEVEL(RAW_FILEINFO_NORMALIZED_NAME_INFORMATION, true, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     823             :         { LEVEL(RAW_FILEINFO_EA_INFORMATION, true, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_EA) },
     824             : 
     825             :         /*
     826             :          * The following require either SEC_FILE_READ_ATTRIBUTE or
     827             :          * SEC_FILE_READ_EA.
     828             :          */
     829             :         { LEVEL(RAW_FILEINFO_BASIC_INFORMATION, false, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     830             :         { LEVEL(RAW_FILEINFO_ALL_INFORMATION, false, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     831             :         { LEVEL(RAW_FILEINFO_NETWORK_OPEN_INFORMATION, false, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     832             :         { LEVEL(RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, false, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     833             :         { LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION, false, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_ATTRIBUTE) },
     834             :         { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS, false, SEC_STD_SYNCHRONIZE, SEC_FILE_READ_EA) },
     835             :         /* Also try SEC_FILE_READ_ATTRIBUTE to show that it is the wrong one */
     836             :         { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS, false, SEC_FILE_READ_ATTRIBUTE, SEC_FILE_READ_EA) },
     837             :         { LEVEL(RAW_FILEINFO_SEC_DESC, false, SEC_STD_SYNCHRONIZE, SEC_STD_READ_CONTROL) },
     838             :         /* Also try SEC_FILE_READ_ATTRIBUTE to show that it is the wrong one */
     839             :         { LEVEL(RAW_FILEINFO_SEC_DESC, false, SEC_FILE_READ_ATTRIBUTE, SEC_STD_READ_CONTROL) }
     840             : };
     841             : 
     842             : 
     843             : /*
     844             :   test fileinfo levels
     845             : */
     846           1 : static bool torture_smb2_getfinfo_access(struct torture_context *tctx,
     847             :                                          struct smb2_tree *tree)
     848             : {
     849           1 :         const char *fname = "torture_smb2_getfinfo_access";
     850             :         struct smb2_handle hfile;
     851             :         NTSTATUS status;
     852           1 :         bool ret = true;
     853             :         int i;
     854             : 
     855           1 :         smb2_deltree(tree, fname);
     856             : 
     857           1 :         torture_setup_complex_file(tctx, tree, fname);
     858             : 
     859           1 :         for (i = 0; i < ARRAY_SIZE(file_levels_access); i++) {
     860             :                 union smb_fileinfo finfo;
     861             :                 NTSTATUS expected_status;
     862             : 
     863             :                 /*
     864             :                  * First open with unrestricted_access, SEC_STD_SYNCHRONIZE for
     865             :                  * most tests, info levels with unrestricted=true should allow
     866             :                  * this.
     867             :                  */
     868           1 :                 status = torture_smb2_testfile_access(
     869             :                         tree, fname, &hfile, file_levels_access[i].unrestricted_access);
     870           1 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     871             :                                            "Unable to open test file\n");
     872             : 
     873           0 :                 if (file_levels_access[i].level == RAW_FILEINFO_SEC_DESC) {
     874           0 :                         finfo.query_secdesc.in.secinfo_flags = 0x7;
     875             :                 }
     876           0 :                 if (file_levels_access[i].level == RAW_FILEINFO_SMB2_ALL_EAS) {
     877           0 :                         finfo.all_eas.in.continue_flags =
     878             :                                 SMB2_CONTINUE_FLAG_RESTART;
     879             :                 }
     880             : 
     881           0 :                 finfo.generic.level = file_levels_access[i].level;
     882           0 :                 finfo.generic.in.file.handle = hfile;
     883             : 
     884           0 :                 if (file_levels_access[i].unrestricted) {
     885           0 :                         expected_status = NT_STATUS_OK;
     886             :                 } else {
     887           0 :                         expected_status = NT_STATUS_ACCESS_DENIED;
     888             :                 }
     889             : 
     890           0 :                 status = smb2_getinfo_file(tree, tree, &finfo);
     891           0 :                 torture_assert_ntstatus_equal_goto(
     892             :                         tctx, status, expected_status, ret, done,
     893             :                         talloc_asprintf(tctx, "Level %s failed\n",
     894             :                                         file_levels_access[i].name));
     895             : 
     896           0 :                 smb2_util_close(tree, hfile);
     897             : 
     898             :                 /*
     899             :                  * Now open with expected access, getinfo should work.
     900             :                  */
     901           0 :                 status = torture_smb2_testfile_access(
     902             :                         tree, fname, &hfile, file_levels_access[i].required_access);
     903           0 :                 torture_assert_ntstatus_ok_goto(
     904             :                         tctx, status, ret, done,
     905             :                         "Unable to open test file\n");
     906             : 
     907           0 :                 if (file_levels_access[i].level == RAW_FILEINFO_SEC_DESC) {
     908           0 :                         finfo.query_secdesc.in.secinfo_flags = 0x7;
     909             :                 }
     910           0 :                 if (file_levels_access[i].level == RAW_FILEINFO_SMB2_ALL_EAS) {
     911           0 :                         finfo.all_eas.in.continue_flags =
     912             :                                 SMB2_CONTINUE_FLAG_RESTART;
     913             :                 }
     914           0 :                 finfo.generic.level = file_levels_access[i].level;
     915           0 :                 finfo.generic.in.file.handle = hfile;
     916             : 
     917           0 :                 status = smb2_getinfo_file(tree, tree, &finfo);
     918           0 :                 torture_assert_ntstatus_ok_goto(
     919             :                         tctx, status, ret, done,
     920             :                         talloc_asprintf(tctx, "%s on file",
     921             :                                         file_levels_access[i].name));
     922             : 
     923           0 :                 smb2_util_close(tree, hfile);
     924             :         }
     925             : 
     926           0 : done:
     927           1 :         smb2_deltree(tree, fname);
     928           1 :         return ret;
     929             : }
     930             : 
     931         964 : struct torture_suite *torture_smb2_getinfo_init(TALLOC_CTX *ctx)
     932             : {
     933         964 :         struct torture_suite *suite = torture_suite_create(
     934             :                 ctx, "getinfo");
     935             : 
     936         964 :         torture_suite_add_simple_test(suite, "complex", torture_smb2_getinfo);
     937         964 :         torture_suite_add_simple_test(suite, "fsinfo",  torture_smb2_fsinfo);
     938         964 :         torture_suite_add_simple_test(suite, "qfs_buffercheck",
     939             :                                       torture_smb2_qfs_buffercheck);
     940         964 :         torture_suite_add_simple_test(suite, "qfile_buffercheck",
     941             :                                       torture_smb2_qfile_buffercheck);
     942         964 :         torture_suite_add_simple_test(suite, "qsec_buffercheck",
     943             :                                       torture_smb2_qsec_buffercheck);
     944         964 :         torture_suite_add_simple_test(suite, "granted",
     945             :                                       torture_smb2_fileinfo_grant_read);
     946         964 :         torture_suite_add_simple_test(suite, "normalized",
     947             :                                       torture_smb2_fileinfo_normalized);
     948         964 :         torture_suite_add_1smb2_test(suite, "getinfo_access",
     949             :                                      torture_smb2_getfinfo_access);
     950         964 :         return suite;
     951             : }

Generated by: LCOV version 1.13