Convert libcli routines to use cli_tree instead of cli_state. Port
[samba.git] / source / torture / raw / lock.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for various lock operations
4    Copyright (C) Andrew Tridgell 2003
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 #define CHECK_STATUS(status, correct) do { \
24         if (!NT_STATUS_EQUAL(status, correct)) { \
25                 printf("(%d) Incorrect status %s - should be %s\n", \
26                        __LINE__, nt_errstr(status), nt_errstr(correct)); \
27                 ret = False; \
28                 goto done; \
29         }} while (0)
30
31 #define CHECK_VALUE(v, correct) do { \
32         if ((v) != (correct)) { \
33                 printf("(%d) Incorrect value %s=%d - should be %d\n", \
34                        __LINE__, #v, v, correct); \
35                 ret = False; \
36                 goto done; \
37         }} while (0)
38
39 #define BASEDIR "\\testlock"
40
41
42 /*
43   test SMBlock and SMBunlock ops
44 */
45 static BOOL test_lock(struct cli_state *cli, TALLOC_CTX *mem_ctx)
46 {
47         union smb_lock io;
48         NTSTATUS status;
49         BOOL ret = True;
50         int fnum;
51         const char *fname = BASEDIR "\\test.txt";
52
53         if (cli_deltree(cli->tree, BASEDIR) == -1 ||
54             !cli_mkdir(cli->tree, BASEDIR)) {
55                 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli->tree));
56                 return False;
57         }
58
59         printf("Testing RAW_LOCK_LOCK\n");
60         io.generic.level = RAW_LOCK_LOCK;
61         
62         fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
63         if (fnum == -1) {
64                 printf("Failed to create %s - %s\n", fname, cli_errstr(cli->tree));
65                 ret = False;
66                 goto done;
67         }
68
69         printf("Trying 0/0 lock\n");
70         io.lock.level = RAW_LOCK_LOCK;
71         io.lock.in.fnum = fnum;
72         io.lock.in.count = 0;
73         io.lock.in.offset = 0;
74         status = smb_raw_lock(cli->tree, &io);
75         CHECK_STATUS(status, NT_STATUS_OK);
76         cli->session->pid++;
77         status = smb_raw_lock(cli->tree, &io);
78         CHECK_STATUS(status, NT_STATUS_OK);
79         cli->session->pid--;
80         io.lock.level = RAW_LOCK_UNLOCK;
81         status = smb_raw_lock(cli->tree, &io);
82         CHECK_STATUS(status, NT_STATUS_OK);
83
84         printf("Trying 0/1 lock\n");
85         io.lock.level = RAW_LOCK_LOCK;
86         io.lock.in.fnum = fnum;
87         io.lock.in.count = 1;
88         io.lock.in.offset = 0;
89         status = smb_raw_lock(cli->tree, &io);
90         CHECK_STATUS(status, NT_STATUS_OK);
91         cli->session->pid++;
92         status = smb_raw_lock(cli->tree, &io);
93         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
94         cli->session->pid--;
95         io.lock.level = RAW_LOCK_UNLOCK;
96         status = smb_raw_lock(cli->tree, &io);
97         CHECK_STATUS(status, NT_STATUS_OK);
98         io.lock.level = RAW_LOCK_UNLOCK;
99         status = smb_raw_lock(cli->tree, &io);
100         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
101
102         printf("Trying max lock\n");
103         io.lock.level = RAW_LOCK_LOCK;
104         io.lock.in.fnum = fnum;
105         io.lock.in.count = 4000;
106         io.lock.in.offset = ~0;
107         status = smb_raw_lock(cli->tree, &io);
108         CHECK_STATUS(status, NT_STATUS_OK);
109         cli->session->pid++;
110         status = smb_raw_lock(cli->tree, &io);
111         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
112         cli->session->pid--;
113         io.lock.level = RAW_LOCK_UNLOCK;
114         status = smb_raw_lock(cli->tree, &io);
115         CHECK_STATUS(status, NT_STATUS_OK);
116         io.lock.level = RAW_LOCK_UNLOCK;
117         status = smb_raw_lock(cli->tree, &io);
118         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
119
120         printf("Trying wrong pid unlock\n");
121         io.lock.level = RAW_LOCK_LOCK;
122         io.lock.in.fnum = fnum;
123         io.lock.in.count = 4002;
124         io.lock.in.offset = 10001;
125         status = smb_raw_lock(cli->tree, &io);
126         CHECK_STATUS(status, NT_STATUS_OK);
127         cli->session->pid++;
128         io.lock.level = RAW_LOCK_UNLOCK;
129         status = smb_raw_lock(cli->tree, &io);
130         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
131         cli->session->pid--;
132         status = smb_raw_lock(cli->tree, &io);
133         CHECK_STATUS(status, NT_STATUS_OK);
134
135 done:
136         cli_close(cli->tree, fnum);
137         smb_raw_exit(cli->session);
138         cli_deltree(cli->tree, BASEDIR);
139         return ret;
140 }
141
142
143 /*
144   test locking&X ops
145 */
146 static BOOL test_lockx(struct cli_state *cli, TALLOC_CTX *mem_ctx)
147 {
148         union smb_lock io;
149         struct smb_lock_entry lock[1];
150         NTSTATUS status;
151         BOOL ret = True;
152         int fnum;
153         const char *fname = BASEDIR "\\test.txt";
154
155         if (cli_deltree(cli->tree, BASEDIR) == -1 ||
156             !cli_mkdir(cli->tree, BASEDIR)) {
157                 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli->tree));
158                 return False;
159         }
160
161         printf("Testing RAW_LOCK_LOCKX\n");
162         io.generic.level = RAW_LOCK_LOCKX;
163         
164         fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
165         if (fnum == -1) {
166                 printf("Failed to create %s - %s\n", fname, cli_errstr(cli->tree));
167                 ret = False;
168                 goto done;
169         }
170
171         io.lockx.level = RAW_LOCK_LOCKX;
172         io.lockx.in.fnum = fnum;
173         io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
174         io.lockx.in.timeout = 0;
175         io.lockx.in.ulock_cnt = 0;
176         io.lockx.in.lock_cnt = 1;
177         lock[0].pid = cli->session->pid;
178         lock[0].offset = 0;
179         lock[0].count = 0xFFFFFFFF;
180         io.lockx.in.locks = &lock[0];
181         status = smb_raw_lock(cli->tree, &io);
182         CHECK_STATUS(status, NT_STATUS_OK);
183
184 done:
185         cli_close(cli->tree, fnum);
186         smb_raw_exit(cli->session);
187         cli_deltree(cli->tree, BASEDIR);
188         return ret;
189 }
190
191
192 /*
193   test high pid
194 */
195 static BOOL test_pidhigh(struct cli_state *cli, TALLOC_CTX *mem_ctx)
196 {
197         union smb_lock io;
198         struct smb_lock_entry lock[1];
199         NTSTATUS status;
200         BOOL ret = True;
201         int fnum;
202         const char *fname = BASEDIR "\\test.txt";
203         char c = 1;
204
205         if (cli_deltree(cli->tree, BASEDIR) == -1 ||
206             !cli_mkdir(cli->tree, BASEDIR)) {
207                 printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli->tree));
208                 return False;
209         }
210
211         printf("Testing high pid\n");
212         io.generic.level = RAW_LOCK_LOCKX;
213
214         cli->session->pid = 1;
215         
216         fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
217         if (fnum == -1) {
218                 printf("Failed to create %s - %s\n", fname, cli_errstr(cli->tree));
219                 ret = False;
220                 goto done;
221         }
222
223         if (cli_write(cli->tree, fnum, 0, &c, 0, 1) != 1) {
224                 printf("Failed to write 1 byte - %s\n", cli_errstr(cli->tree));
225                 ret = False;
226                 goto done;
227         }
228
229         io.lockx.level = RAW_LOCK_LOCKX;
230         io.lockx.in.fnum = fnum;
231         io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
232         io.lockx.in.timeout = 0;
233         io.lockx.in.ulock_cnt = 0;
234         io.lockx.in.lock_cnt = 1;
235         lock[0].pid = cli->session->pid;
236         lock[0].offset = 0;
237         lock[0].count = 0xFFFFFFFF;
238         io.lockx.in.locks = &lock[0];
239         status = smb_raw_lock(cli->tree, &io);
240         CHECK_STATUS(status, NT_STATUS_OK);
241
242         if (cli_read(cli->tree, fnum, &c, 0, 1) != 1) {
243                 printf("Failed to read 1 byte - %s\n", cli_errstr(cli->tree));
244                 ret = False;
245                 goto done;
246         }
247
248         cli->session->pid |= 0x10000;
249
250         cli->session->pid = 2;
251
252         if (cli_read(cli->tree, fnum, &c, 0, 1) == 1) {
253                 printf("pid is incorrect handled for read with lock!\n");
254                 ret = False;
255                 goto done;
256         }
257
258         cli->session->pid = 0x10001;
259
260         if (cli_read(cli->tree, fnum, &c, 0, 1) != 1) {
261                 printf("High pid is used on this server!\n");
262                 ret = False;
263         } else {
264                 printf("High pid is not used on this server (correct)\n");
265         }
266
267 done:
268         cli_close(cli->tree, fnum);
269         smb_raw_exit(cli->session);
270         cli_deltree(cli->tree, BASEDIR);
271         return ret;
272 }
273
274
275 /* 
276    basic testing of lock calls
277 */
278 BOOL torture_raw_lock(int dummy)
279 {
280         struct cli_state *cli;
281         BOOL ret = True;
282         TALLOC_CTX *mem_ctx;
283
284         if (!torture_open_connection(&cli)) {
285                 return False;
286         }
287
288         mem_ctx = talloc_init("torture_raw_lock");
289
290         if (!test_lockx(cli, mem_ctx)) {
291                 ret = False;
292         }
293
294         if (!test_lock(cli, mem_ctx)) {
295                 ret = False;
296         }
297
298         if (!test_pidhigh(cli, mem_ctx)) {
299                 ret = False;
300         }
301
302         torture_close_connection(cli);
303         talloc_destroy(mem_ctx);
304         return ret;
305 }