r16951: add the year to the copyright...
[kai/samba.git] / source4 / torture / smb2 / lock.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    SMB2 lock test suite
5
6    Copyright (C) Stefan Metzmacher 2006
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 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "libcli/smb2/smb2.h"
25 #include "libcli/smb2/smb2_calls.h"
26
27 #include "torture/torture.h"
28 #include "torture/smb2/proto.h"
29
30 #define CHECK_STATUS(status, correct) do { \
31         if (!NT_STATUS_EQUAL(status, correct)) { \
32                 printf("(%s) Incorrect status %s - should be %s\n", \
33                        __location__, nt_errstr(status), nt_errstr(correct)); \
34                 ret = False; \
35                 goto done; \
36         }} while (0)
37
38 #define CHECK_VALUE(v, correct) do { \
39         if ((v) != (correct)) { \
40                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
41                        __location__, #v, v, correct); \
42                 ret = False; \
43                 goto done; \
44         }} while (0)
45
46 static BOOL test_valid_request(TALLOC_CTX *mem_ctx, struct smb2_tree *tree)
47 {
48         BOOL ret = True;
49         NTSTATUS status;
50         struct smb2_handle h;
51         uint8_t buf[200];
52         struct smb2_lock lck;
53
54         ZERO_STRUCT(buf);
55
56         status = torture_smb2_testfile(tree, "lock1.txt", &h);
57         CHECK_STATUS(status, NT_STATUS_OK);
58
59         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
60         CHECK_STATUS(status, NT_STATUS_OK);
61
62         lck.in.unknown1         = 0x0000;
63         lck.in.unknown2         = 0x00000000;
64         lck.in.file.handle      = h;
65         lck.in.offset           = 0x0000000000000000;
66         lck.in.count            = 0x0000000000000000;
67         lck.in.unknown5         = 0x0000000000000000;
68         lck.in.flags            = 0x00000000;
69         status = smb2_lock(tree, &lck);
70         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
71
72         lck.in.unknown1         = 0x0001;
73         lck.in.unknown2         = 0x00000000;
74         lck.in.file.handle      = h;
75         lck.in.offset           = 0;
76         lck.in.count            = 0;
77         lck.in.unknown5         = 0x00000000;
78         lck.in.flags            = SMB2_LOCK_FLAG_NONE;
79         status = smb2_lock(tree, &lck);
80         CHECK_STATUS(status, NT_STATUS_OK);
81         CHECK_VALUE(lck.out.unknown1, 0);
82
83         lck.in.file.handle.data[0] +=1;
84         status = smb2_lock(tree, &lck);
85         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
86         lck.in.file.handle.data[0] -=1;
87
88         lck.in.unknown1         = 0x0001;
89         lck.in.unknown2         = 0xFFFFFFFF;
90         lck.in.file.handle      = h;
91         lck.in.offset           = UINT64_MAX;
92         lck.in.count            = UINT64_MAX;
93         lck.in.unknown5         = 0x00000000;
94         lck.in.flags            = SMB2_LOCK_FLAG_EXCLUSIV;
95         status = smb2_lock(tree, &lck);
96         CHECK_STATUS(status, NT_STATUS_OK);
97         CHECK_VALUE(lck.out.unknown1, 0);
98
99         status = smb2_lock(tree, &lck);
100         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
101
102         status = smb2_lock(tree, &lck);
103         CHECK_STATUS(status, NT_STATUS_OK);
104         CHECK_VALUE(lck.out.unknown1, 0);
105
106         status = smb2_lock(tree, &lck);
107         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
108
109         status = smb2_lock(tree, &lck);
110         CHECK_STATUS(status, NT_STATUS_OK);
111         CHECK_VALUE(lck.out.unknown1, 0);
112
113         lck.in.unknown1         = 0x0001;
114         lck.in.unknown2         = 0x12345678;
115         lck.in.file.handle      = h;
116         lck.in.offset           = UINT32_MAX;
117         lck.in.count            = UINT32_MAX;
118         lck.in.unknown5         = 0x87654321;
119         lck.in.flags            = SMB2_LOCK_FLAG_EXCLUSIV;
120         status = smb2_lock(tree, &lck);
121         CHECK_STATUS(status, NT_STATUS_OK);
122         CHECK_VALUE(lck.out.unknown1, 0);
123
124         status = smb2_lock(tree, &lck);
125         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
126
127         status = smb2_lock(tree, &lck);
128         CHECK_STATUS(status, NT_STATUS_OK);
129         CHECK_VALUE(lck.out.unknown1, 0);
130
131         status = smb2_lock(tree, &lck);
132         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
133
134         status = smb2_lock(tree, &lck);
135         CHECK_STATUS(status, NT_STATUS_OK);
136         CHECK_VALUE(lck.out.unknown1, 0);
137
138         lck.in.flags            = 0x00000000;
139         status = smb2_lock(tree, &lck);
140         CHECK_STATUS(status, NT_STATUS_OK);
141         CHECK_VALUE(lck.out.unknown1, 0);
142
143         status = smb2_lock(tree, &lck);
144         CHECK_STATUS(status, NT_STATUS_OK);
145         CHECK_VALUE(lck.out.unknown1, 0);
146
147         lck.in.flags            = 0x00000001;
148         status = smb2_lock(tree, &lck);
149         CHECK_STATUS(status, NT_STATUS_OK);
150         CHECK_VALUE(lck.out.unknown1, 0);
151
152         status = smb2_lock(tree, &lck);
153         CHECK_STATUS(status, NT_STATUS_OK);
154         CHECK_VALUE(lck.out.unknown1, 0);
155
156         lck.in.unknown1         = 0x0001;
157         lck.in.unknown2         = 0x87654321;
158         lck.in.file.handle      = h;
159         lck.in.offset           = 0x00000000FFFFFFFF;
160         lck.in.count            = 0x00000000FFFFFFFF;
161         lck.in.unknown5         = 0x12345678;
162         lck.in.flags            = SMB2_LOCK_FLAG_UNLOCK;
163         status = smb2_lock(tree, &lck);
164         CHECK_STATUS(status, NT_STATUS_OK);
165         CHECK_VALUE(lck.out.unknown1, 0);
166
167         lck.in.unknown1         = 0x0001;
168         lck.in.unknown2         = 0x12345678;
169         lck.in.file.handle      = h;
170         lck.in.offset           = 0x00000000FFFFFFFF;
171         lck.in.count            = 0x00000000FFFFFFFF;
172         lck.in.unknown5         = 0x00000000;
173         lck.in.flags            = SMB2_LOCK_FLAG_UNLOCK;
174         status = smb2_lock(tree, &lck);
175         CHECK_STATUS(status, NT_STATUS_OK);
176         CHECK_VALUE(lck.out.unknown1, 0);
177
178         status = smb2_lock(tree, &lck);
179         CHECK_STATUS(status, NT_STATUS_OK);
180         CHECK_VALUE(lck.out.unknown1, 0);
181         status = smb2_lock(tree, &lck);
182         CHECK_STATUS(status, NT_STATUS_OK);
183         CHECK_VALUE(lck.out.unknown1, 0);
184         status = smb2_lock(tree, &lck);
185         CHECK_STATUS(status, NT_STATUS_OK);
186         CHECK_VALUE(lck.out.unknown1, 0);
187         status = smb2_lock(tree, &lck);
188         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
189         status = smb2_lock(tree, &lck);
190         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
191         status = smb2_lock(tree, &lck);
192         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
193
194 done:
195         return ret;
196 }
197
198 /* basic testing of SMB2 locking
199 */
200 BOOL torture_smb2_lock(struct torture_context *torture)
201 {
202         TALLOC_CTX *mem_ctx = talloc_new(NULL);
203         struct smb2_tree *tree;
204         BOOL ret = True;
205
206         if (!torture_smb2_connection(mem_ctx, &tree)) {
207                 return False;
208         }
209
210         ret &= test_valid_request(mem_ctx, tree);
211
212         talloc_free(mem_ctx);
213
214         return ret;
215 }