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 : }
|