named_pipe_echo raw mode...
[metze/samba/wip.git] / source4 / torture / raw / named_pipe_echo.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    test suite for SMB2 oplocks
5
6    Copyright (C) Stefan Metzmacher 2008
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 "torture/torture.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "libcli/raw/raw_proto.h"
26 #include "libcli/libcli.h"
27 #include "torture/util.h"
28
29 #define CHECK_VAL(v, correct) do { \
30         if ((v) != (correct)) { \
31                 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
32                                 __location__, #v, (int)v, (int)correct); \
33                 ret = false; \
34         }} while (0)
35
36 #define CHECK_STATUS(status, correct) do { \
37         if (!NT_STATUS_EQUAL(status, correct)) { \
38                 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
39                        nt_errstr(status), nt_errstr(correct)); \
40                 ret = false; \
41                 goto done; \
42         }} while (0)
43
44 #define NP_ECHO_MESSAGE_FNAME "\\NPECHO_MESSAGE"
45
46 bool torture_raw_np_echo01(struct torture_context *tctx,
47                            struct smbcli_state *cli)
48 {
49         bool ret = true;
50         NTSTATUS status;
51         union smb_open op;
52         struct smb_trans2 tr;
53         union smb_write wr;
54         union smb_write wr_raw;
55         union smb_read rd;
56         union smb_read rd_raw;
57         union smb_close cl;
58         int fnum;
59         uint8_t cmd_buf[256*8];
60         uint16_t setup[2];
61         struct smbcli_request *reqs[5];
62         uint32_t i;
63         uint8_t raw_bytes[2+20];
64         uint8_t zero20[20];
65         ZERO_STRUCT(zero20);
66
67         torture_comment(tctx, "open message mode named pipe\n");
68         ZERO_STRUCT(op);
69         op.ntcreatex.level = RAW_OPEN_NTCREATEX;
70         op.ntcreatex.in.fname = NP_ECHO_MESSAGE_FNAME;
71         op.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
72                                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK |
73                                 NTCREATEX_FLAGS_REQUEST_OPLOCK;
74         op.ntcreatex.in.root_fid = 0;
75         op.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
76         op.ntcreatex.in.alloc_size = 0;
77         op.ntcreatex.in.file_attr = 0;
78         op.ntcreatex.in.share_access = 0;
79         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
80         op.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
81         op.ntcreatex.in.security_flags = NTCREATEX_SECURITY_ALL |
82                                          NTCREATEX_SECURITY_DYNAMIC;
83         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
84
85         status = smb_raw_open(cli->tree, tctx, &op);
86         CHECK_STATUS(status, NT_STATUS_OK);
87         fnum = op.ntcreatex.out.file.fnum;
88         CHECK_VAL(op.ntcreatex.out.attrib, FILE_ATTRIBUTE_NORMAL);
89         CHECK_VAL(op.ntcreatex.out.create_action, 1);
90         CHECK_VAL(op.ntcreatex.out.is_directory, 0);
91         CHECK_VAL(op.ntcreatex.out.size, 0);
92         //CHECK_VAL(op.ntcreatex.out.alloc_size, 0);
93         CHECK_VAL(op.ntcreatex.out.maximal_access, 0);
94         CHECK_VAL(op.ntcreatex.out.file_type, FILE_TYPE_MESSAGE_MODE_PIPE);
95         CHECK_VAL(op.ntcreatex.out.ipc_state, 0x5ff);
96
97         torture_comment(tctx, "select cmds\n");
98 #define NPECHO_CMD_SLEEP 0
99 #define NPECHO_CMD_READ 1
100 #define NPECHO_CMD_WRITE 2
101
102 #define NPECHO_BUF_CMD_SIZE 8
103
104 #define NPECHO_BUF_SETUP_CMD(buf, idx, cmd, val) do { \
105         SIVAL(buf, (idx*NPECHO_BUF_CMD_SIZE)+0, cmd); \
106         SIVAL(buf, (idx*NPECHO_BUF_CMD_SIZE)+4, val); \
107         } while (0)
108
109         NPECHO_BUF_SETUP_CMD(cmd_buf, 0, NPECHO_CMD_SLEEP, 300);
110         NPECHO_BUF_SETUP_CMD(cmd_buf, 1, NPECHO_CMD_READ, 20);
111         NPECHO_BUF_SETUP_CMD(cmd_buf, 2, NPECHO_CMD_READ, 20);
112         NPECHO_BUF_SETUP_CMD(cmd_buf, 3, NPECHO_CMD_SLEEP, 300);
113         NPECHO_BUF_SETUP_CMD(cmd_buf, 4, NPECHO_CMD_WRITE, 20);
114         NPECHO_BUF_SETUP_CMD(cmd_buf, 5, NPECHO_CMD_WRITE, 20);
115         NPECHO_BUF_SETUP_CMD(cmd_buf, 6, NPECHO_CMD_SLEEP, 300);
116         NPECHO_BUF_SETUP_CMD(cmd_buf, 7, NPECHO_CMD_READ, 20);
117         NPECHO_BUF_SETUP_CMD(cmd_buf, 8, NPECHO_CMD_READ, 20);
118         NPECHO_BUF_SETUP_CMD(cmd_buf, 9, NPECHO_CMD_SLEEP, 300);
119         NPECHO_BUF_SETUP_CMD(cmd_buf,10, NPECHO_CMD_WRITE, 20);
120         NPECHO_BUF_SETUP_CMD(cmd_buf,11, NPECHO_CMD_WRITE, 20);
121         NPECHO_BUF_SETUP_CMD(cmd_buf,12, NPECHO_CMD_SLEEP, 300);
122         NPECHO_BUF_SETUP_CMD(cmd_buf,13, NPECHO_CMD_READ, 20);
123         NPECHO_BUF_SETUP_CMD(cmd_buf,14, NPECHO_CMD_READ, 20);
124         NPECHO_BUF_SETUP_CMD(cmd_buf,15, NPECHO_CMD_SLEEP, 300);
125         NPECHO_BUF_SETUP_CMD(cmd_buf,16, NPECHO_CMD_WRITE, 20);
126         NPECHO_BUF_SETUP_CMD(cmd_buf,17, NPECHO_CMD_WRITE, 20);
127         NPECHO_BUF_SETUP_CMD(cmd_buf,18, NPECHO_CMD_SLEEP, 300);
128         NPECHO_BUF_SETUP_CMD(cmd_buf,19, NPECHO_CMD_READ, 20);
129         NPECHO_BUF_SETUP_CMD(cmd_buf,20, NPECHO_CMD_SLEEP, 300);
130         NPECHO_BUF_SETUP_CMD(cmd_buf,21, NPECHO_CMD_WRITE, 20);
131         NPECHO_BUF_SETUP_CMD(cmd_buf,22, NPECHO_CMD_WRITE, 20);
132         NPECHO_BUF_SETUP_CMD(cmd_buf,23, NPECHO_CMD_SLEEP, 300);
133         NPECHO_BUF_SETUP_CMD(cmd_buf,24, NPECHO_CMD_READ, 20);
134         NPECHO_BUF_SETUP_CMD(cmd_buf,25, NPECHO_CMD_READ, 20);
135         NPECHO_BUF_SETUP_CMD(cmd_buf,26, NPECHO_CMD_SLEEP, 300);
136         NPECHO_BUF_SETUP_CMD(cmd_buf,27, NPECHO_CMD_WRITE, 20);
137         NPECHO_BUF_SETUP_CMD(cmd_buf,28, NPECHO_CMD_SLEEP, 300);
138
139         setup[0] = TRANSACT_DCERPCCMD;
140         setup[1] = fnum;
141
142         ZERO_STRUCT(tr);
143         tr.in.flags = 0;
144         tr.in.timeout = 0;
145         tr.in.setup_count = 2;
146         tr.in.setup = setup;
147         tr.in.params = data_blob(NULL, 0);
148         tr.in.data = data_blob_const(cmd_buf, 29*NPECHO_BUF_CMD_SIZE);
149         tr.in.max_setup = 0;
150         tr.in.max_param = 0;
151         tr.in.max_data = 4;
152         status = smb_raw_trans(cli->tree, tctx, &tr);
153         CHECK_STATUS(status, NT_STATUS_OK);
154
155         /* now do operations and send them all at the same time */
156         ZERO_STRUCT(wr);
157         wr.writex.level = RAW_WRITE_WRITEX;
158         wr.writex.in.file.fnum = fnum;
159         wr.writex.in.wmode = 0;
160         wr.writex.in.remaining = 0;
161         wr.writex.in.offset = 0;
162         wr.writex.in.count = sizeof(zero20);
163         wr.writex.in.data = zero20;
164
165         ZERO_STRUCT(rd);
166         rd.readx.level = RAW_READ_READX;
167         rd.readx.in.file.fnum = fnum;
168         rd.readx.in.maxcnt = sizeof(zero20);
169         rd.readx.in.mincnt = sizeof(zero20);
170         rd.readx.in.offset = 0;
171         rd.readx.in.read_for_execute = false;
172         rd.readx.in.remaining = 0;
173         rd.readx.out.data = zero20;
174
175         tr.in.data = data_blob_const(zero20, sizeof(zero20));
176         tr.in.max_data = sizeof(zero20);
177
178         torture_comment(tctx, "do write, write, read, read\n");
179         reqs[0] = smb_raw_write_send(cli->tree, &wr);
180         reqs[1] = smb_raw_write_send(cli->tree, &wr);
181         reqs[2] = smb_raw_read_send(cli->tree, &rd);
182         reqs[3] = smb_raw_read_send(cli->tree, &rd);
183
184         status = smb_raw_write_recv(reqs[0], &wr);
185         CHECK_STATUS(status, NT_STATUS_OK);
186         status = smb_raw_write_recv(reqs[1], &wr);
187         CHECK_STATUS(status, NT_STATUS_OK);
188         status = smb_raw_read_recv(reqs[2], &rd);
189         CHECK_STATUS(status, NT_STATUS_OK);
190         status = smb_raw_read_recv(reqs[3], &rd);
191         CHECK_STATUS(status, NT_STATUS_OK);
192
193         torture_comment(tctx, "do write, trans, read\n");
194         reqs[0] = smb_raw_write_send(cli->tree, &wr);
195         reqs[1] = smb_raw_trans_send(cli->tree, &tr);
196         reqs[2] = smb_raw_read_send(cli->tree, &rd);
197
198         status = smb_raw_write_recv(reqs[0], &wr);
199         CHECK_STATUS(status, NT_STATUS_OK);
200         status = smb_raw_trans_recv(reqs[1], tctx, &tr);
201         CHECK_STATUS(status, NT_STATUS_OK);
202         status = smb_raw_read_recv(reqs[2], &rd);
203         CHECK_STATUS(status, NT_STATUS_OK);
204
205         torture_comment(tctx, "do write, trans, trans(pipe_busy), read\n");
206         reqs[0] = smb_raw_write_send(cli->tree, &wr);
207         reqs[1] = smb_raw_trans_send(cli->tree, &tr);
208         reqs[2] = smb_raw_trans_send(cli->tree, &tr);
209         reqs[3] = smb_raw_read_send(cli->tree, &rd);
210
211         status = smb_raw_write_recv(reqs[0], &wr);
212         CHECK_STATUS(status, NT_STATUS_OK);
213         status = smb_raw_trans_recv(reqs[1], tctx, &tr);
214         CHECK_STATUS(status, NT_STATUS_OK);
215         status = smb_raw_trans_recv(reqs[2], tctx, &tr);
216         CHECK_STATUS(status, NT_STATUS_PIPE_BUSY);
217         status = smb_raw_read_recv(reqs[3], &rd);
218         CHECK_STATUS(status, NT_STATUS_OK);
219
220         torture_comment(tctx, "do write, read, trans(pipe_busy), read\n");
221         reqs[0] = smb_raw_write_send(cli->tree, &wr);
222         reqs[1] = smb_raw_read_send(cli->tree, &rd);
223         reqs[2] = smb_raw_trans_send(cli->tree, &tr);
224         reqs[3] = smb_raw_read_send(cli->tree, &rd);
225
226         status = smb_raw_write_recv(reqs[0], &wr);
227         CHECK_STATUS(status, NT_STATUS_OK);
228         status = smb_raw_read_recv(reqs[1], &rd);
229         CHECK_STATUS(status, NT_STATUS_OK);
230         status = smb_raw_trans_recv(reqs[2], tctx, &tr);
231         CHECK_STATUS(status, NT_STATUS_PIPE_BUSY);
232         status = smb_raw_read_recv(reqs[3], &rd);
233         CHECK_STATUS(status, NT_STATUS_OK);
234
235 //#define PIPE_RAW_MODE 0x4
236 //#define PIPE_START_MESSAGE 0x8
237         ZERO_STRUCT(wr_raw);
238         wr_raw.writex.level = RAW_WRITE_WRITEX;
239         wr_raw.writex.in.file.fnum = fnum;
240         wr_raw.writex.in.wmode = PIPE_RAW_MODE;
241         wr_raw.writex.in.remaining = 0;
242         wr_raw.writex.in.offset = 0;
243         wr_raw.writex.in.count = sizeof(raw_bytes);
244         wr_raw.writex.in.data = raw_bytes;
245
246         SSVAL(raw_bytes, 0, 0xFFFF);
247         for (i=0; i < (sizeof(raw_bytes) - 2); i++) {
248                 raw_bytes[2+i] = i;
249         }
250
251         ZERO_STRUCT(rd);
252         rd_raw.readx.level = RAW_READ_READX;
253         rd_raw.readx.in.file.fnum = fnum;
254         rd_raw.readx.in.maxcnt = sizeof(zero20);
255         rd_raw.readx.in.mincnt = sizeof(zero20);
256         rd_raw.readx.in.offset = 0;
257         rd_raw.readx.in.read_for_execute = false;
258         rd_raw.readx.in.remaining = 20;
259         rd_raw.readx.out.data = zero20;
260
261         torture_comment(tctx, "do write(raw_mode le), read\n");
262         SSVAL(raw_bytes, 0, sizeof(raw_bytes) - 2);
263         reqs[0] = smb_raw_write_send(cli->tree, &wr_raw);
264
265         status = smb_raw_write_recv(reqs[0], &wr_raw);
266         CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRerror));
267
268         torture_comment(tctx, "do write(raw_mode be), read\n");
269         RSSVAL(raw_bytes, 0, sizeof(raw_bytes) - 2);
270         reqs[0] = smb_raw_write_send(cli->tree, &wr_raw);
271
272         status = smb_raw_write_recv(reqs[0], &wr_raw);
273         CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRerror));
274
275
276         torture_comment(tctx, "do write, write(half), write(half), read(half), read(half)\n");
277         reqs[0] = smb_raw_write_send(cli->tree, &wr);
278         SSVAL(raw_bytes, 0, 0xFFFF);
279         SSVAL(raw_bytes, 0, 0x8765);
280         //SSVAL(raw_bytes, 0, sizeof(raw_bytes) - 2 + 5);
281         wr_raw.writex.in.wmode = PIPE_START_MESSAGE | PIPE_RAW_MODE;
282         wr_raw.writex.in.remaining = 20;
283         wr_raw.writex.in.offset = 0x8765;
284         wr_raw.writex.in.count = 12;
285         wr_raw.writex.in.data = raw_bytes;
286         reqs[1] = smb_raw_write_send(cli->tree, &wr_raw);
287         wr_raw.writex.in.wmode = PIPE_RAW_MODE | 0x02;
288         wr_raw.writex.in.remaining = 0x8765;
289         wr_raw.writex.in.offset = 0x1234;
290         wr_raw.writex.in.count = 10;
291         wr_raw.writex.in.data = raw_bytes + 12;
292         reqs[2] = smb_raw_write_send(cli->tree, &wr_raw);
293         rd_raw.readx.in.maxcnt = 10;
294         rd_raw.readx.in.mincnt = 10;
295         rd_raw.readx.in.offset = 7870;
296         rd_raw.readx.in.read_for_execute = false;
297         rd_raw.readx.in.remaining = 0x8765;
298         rd_raw.readx.out.data = zero20;
299         reqs[3] = smb_raw_read_send(cli->tree, &rd_raw);
300         rd_raw.readx.in.maxcnt = 10;
301         rd_raw.readx.in.mincnt = 10;
302         rd_raw.readx.in.offset = 5560;
303         rd_raw.readx.in.read_for_execute = false;
304         rd_raw.readx.in.remaining = 0x1234;
305         rd_raw.readx.out.data = zero20;
306         reqs[4] = smb_raw_read_send(cli->tree, &rd_raw);
307
308         status = smb_raw_write_recv(reqs[0], &wr);
309         CHECK_STATUS(status, NT_STATUS_OK);
310         status = smb_raw_write_recv(reqs[1], &wr_raw);
311         CHECK_STATUS(status, NT_STATUS_OK);
312         status = smb_raw_write_recv(reqs[2], &wr_raw);
313         CHECK_STATUS(status, NT_STATUS_OK);
314         status = smb_raw_read_recv(reqs[3], &rd_raw);
315         CHECK_STATUS(status, STATUS_BUFFER_OVERFLOW);
316         status = smb_raw_read_recv(reqs[4], &rd_raw);
317         CHECK_STATUS(status, NT_STATUS_OK);
318
319         torture_comment(tctx, "close message mode named pipe\n");
320         ZERO_STRUCT(cl);
321         cl.close.level = RAW_CLOSE_CLOSE;
322         cl.close.in.file.fnum = fnum;
323         cl.close.in.write_time = 0;
324         status = smb_raw_close(cli->tree, &cl);
325         CHECK_STATUS(status, NT_STATUS_OK);
326
327 done:
328         return ret;
329 }
330