LCOV - code coverage report
Current view: top level - source4/torture/raw - ioctl.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 81 97 83.5 %
Date: 2024-04-21 15:09:00 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    ioctl individual test suite
       4             :    Copyright (C) Andrew Tridgell 2003
       5             :    Copyright (C) James J Myers 2003 <myersjj@samba.org>
       6             :    
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             :    
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             :    
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "../libcli/smb/smb_constants.h"
      23             : #include "libcli/raw/libcliraw.h"
      24             : #include "libcli/raw/raw_proto.h"
      25             : #include "libcli/libcli.h"
      26             : #include "torture/util.h"
      27             : #include "torture/raw/proto.h"
      28             : 
      29             : #define BASEDIR "\\rawioctl"
      30             : 
      31             : #define CHECK_STATUS(status, correct) do { \
      32             :         if (!NT_STATUS_EQUAL(status, correct)) { \
      33             :                 printf("(%d) Incorrect status %s - should be %s\n", \
      34             :                        __LINE__, nt_errstr(status), nt_errstr(correct)); \
      35             :                 ret = false; \
      36             :                 goto done; \
      37             :         }} while (0)
      38             : 
      39             : 
      40             : /* test some ioctls */
      41           1 : static bool test_ioctl(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
      42             : {
      43           0 :         union smb_ioctl ctl;
      44           0 :         int fnum;
      45           0 :         NTSTATUS status;
      46           1 :         bool ret = true;
      47           1 :         const char *fname = BASEDIR "\\test.dat";
      48             : 
      49           1 :         printf("TESTING IOCTL FUNCTIONS\n");
      50             : 
      51           1 :         fnum = create_complex_file(cli, mem_ctx, fname);
      52           1 :         if (fnum == -1) {
      53           0 :                 printf("Failed to create test.dat - %s\n", smbcli_errstr(cli->tree));
      54           0 :                 ret = false;
      55           0 :                 goto done;
      56             :         }
      57             : 
      58           1 :         printf("Trying 0xFFFF\n");
      59           1 :         ctl.ioctl.level = RAW_IOCTL_IOCTL;
      60           1 :         ctl.ioctl.in.file.fnum = fnum;
      61           1 :         ctl.ioctl.in.request = 0xFFFF;
      62             : 
      63           1 :         status = smb_raw_ioctl(cli->tree, mem_ctx, &ctl);
      64           1 :         CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRerror));
      65             : 
      66           1 :         printf("Trying QUERY_JOB_INFO\n");
      67           1 :         ctl.ioctl.level = RAW_IOCTL_IOCTL;
      68           1 :         ctl.ioctl.in.file.fnum = fnum;
      69           1 :         ctl.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
      70             : 
      71           1 :         status = smb_raw_ioctl(cli->tree, mem_ctx, &ctl);
      72           1 :         CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRerror));
      73             : 
      74           1 :         printf("Trying bad handle\n");
      75           1 :         ctl.ioctl.in.file.fnum = fnum+1;
      76           1 :         status = smb_raw_ioctl(cli->tree, mem_ctx, &ctl);
      77           1 :         CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRerror));
      78             : 
      79           1 : done:
      80           1 :         smbcli_close(cli->tree, fnum);
      81           1 :         return ret;
      82             : }
      83             : 
      84             : /* test some filesystem control functions */
      85           1 : static bool test_fsctl(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
      86             : {
      87           0 :         int fnum;
      88           0 :         NTSTATUS status;
      89           1 :         bool ret = true;
      90           1 :         const char *fname = BASEDIR "\\test.dat";
      91           0 :         union smb_ioctl nt;
      92             : 
      93           1 :         printf("\nTESTING FSCTL FUNCTIONS\n");
      94             : 
      95           1 :         fnum = create_complex_file(cli, mem_ctx, fname);
      96           1 :         if (fnum == -1) {
      97           0 :                 printf("Failed to create test.dat - %s\n", smbcli_errstr(cli->tree));
      98           0 :                 ret = false;
      99           0 :                 goto done;
     100             :         }
     101             : 
     102           1 :         printf("Trying FSCTL_FIND_FILES_BY_SID\n");
     103           1 :         nt.ioctl.level = RAW_IOCTL_NTIOCTL;
     104           1 :         nt.ntioctl.in.function = FSCTL_FIND_FILES_BY_SID;
     105           1 :         nt.ntioctl.in.file.fnum = fnum;
     106           1 :         nt.ntioctl.in.fsctl = true;
     107           1 :         nt.ntioctl.in.filter = 0;
     108           1 :         nt.ntioctl.in.max_data = 0;
     109           1 :         nt.ntioctl.in.blob = data_blob(NULL, 1024);
     110             :         /* definitely not a sid... */
     111           1 :         generate_random_buffer(nt.ntioctl.in.blob.data,
     112             :                                nt.ntioctl.in.blob.length);
     113           1 :         nt.ntioctl.in.blob.data[1] = 15+1;
     114           1 :         status = smb_raw_ioctl(cli->tree, mem_ctx, &nt);
     115           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
     116           1 :             !NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED) &&
     117           1 :             !NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
     118           0 :                 printf("Got unexpected error code: %s\n",
     119             :                         nt_errstr(status));
     120           0 :                 ret = false;
     121           0 :                 goto done;
     122             :         }
     123             : 
     124           1 :         printf("trying sparse file\n");
     125           1 :         nt.ioctl.level = RAW_IOCTL_NTIOCTL;
     126           1 :         nt.ntioctl.in.function = FSCTL_SET_SPARSE;
     127           1 :         nt.ntioctl.in.file.fnum = fnum;
     128           1 :         nt.ntioctl.in.fsctl = true;
     129           1 :         nt.ntioctl.in.filter = 0;
     130           1 :         nt.ntioctl.in.max_data = 0;
     131           1 :         nt.ntioctl.in.blob = data_blob(NULL, 0);
     132             : 
     133           1 :         status = smb_raw_ioctl(cli->tree, mem_ctx, &nt);
     134           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     135             : 
     136           1 :         printf("trying batch oplock\n");
     137           1 :         nt.ioctl.level = RAW_IOCTL_NTIOCTL;
     138           1 :         nt.ntioctl.in.function = FSCTL_REQUEST_BATCH_OPLOCK;
     139           1 :         nt.ntioctl.in.file.fnum = fnum;
     140           1 :         nt.ntioctl.in.fsctl = true;
     141           1 :         nt.ntioctl.in.filter = 0;
     142           1 :         nt.ntioctl.in.max_data = 0;
     143           1 :         nt.ntioctl.in.blob = data_blob(NULL, 0);
     144             : 
     145           1 :         status = smb_raw_ioctl(cli->tree, mem_ctx, &nt);
     146           1 :         if (NT_STATUS_IS_OK(status)) {
     147           0 :                 printf("Server supports batch oplock upgrades on open files\n");
     148             :         } else {
     149           1 :                 printf("Server does not support batch oplock upgrades on open files\n");
     150             :         }
     151             : 
     152           1 :         printf("Trying bad handle\n");
     153           1 :         nt.ntioctl.in.file.fnum = fnum+1;
     154           1 :         status = smb_raw_ioctl(cli->tree, mem_ctx, &nt);
     155           1 :         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
     156             : 
     157             : #if 0
     158             :         nt.ntioctl.in.file.fnum = fnum;
     159             :         for (i=0;i<100;i++) {
     160             :                 nt.ntioctl.in.function = FSCTL_FILESYSTEM + (i<<2);
     161             :                 status = smb_raw_ioctl(cli->tree, mem_ctx, &nt);
     162             :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
     163             :                         printf("filesystem fsctl 0x%x - %s\n",
     164             :                                i, nt_errstr(status));
     165             :                 }
     166             :         }
     167             : #endif
     168             : 
     169           1 : done:
     170           1 :         smbcli_close(cli->tree, fnum);
     171           1 :         return ret;
     172             : }
     173             : 
     174             : /* 
     175             :    basic testing of some ioctl calls 
     176             : */
     177           1 : bool torture_raw_ioctl(struct torture_context *torture, 
     178             :                        struct smbcli_state *cli)
     179             : {
     180           1 :         bool ret = true;
     181             : 
     182           1 :         torture_assert(torture, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     183             : 
     184           1 :         ret &= test_ioctl(cli, torture);
     185           1 :         ret &= test_fsctl(cli, torture);
     186             : 
     187           1 :         smb_raw_exit(cli->session);
     188           1 :         smbcli_deltree(cli->tree, BASEDIR);
     189             : 
     190           1 :         return ret;
     191             : }

Generated by: LCOV version 1.14