torture: Fix uninitialized variables
[Samba.git] / source4 / torture / vfs / fruit.c
blobd5de9d5c805f1b6567455fe02712a0c93a573983
1 /*
2 Unix SMB/CIFS implementation.
4 vfs_fruit tests
6 Copyright (C) Ralph Boehme 2014
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.
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.
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/>.
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "libcli/libcli.h"
25 #include "libcli/smb2/smb2.h"
26 #include "libcli/smb2/smb2_calls.h"
27 #include "libcli/smb/smb2_create_ctx.h"
28 #include "lib/cmdline/popt_common.h"
29 #include "param/param.h"
30 #include "libcli/resolve/resolve.h"
31 #include "MacExtensions.h"
32 #include "lib/util/tsort.h"
34 #include "torture/torture.h"
35 #include "torture/util.h"
36 #include "torture/smb2/proto.h"
37 #include "torture/vfs/proto.h"
38 #include "librpc/gen_ndr/ndr_ioctl.h"
40 #define BASEDIR "vfs_fruit_dir"
41 #define FNAME_CC_SRC "testfsctl.dat"
42 #define FNAME_CC_DST "testfsctl2.dat"
44 #define CHECK_STATUS(status, correct) do { \
45 if (!NT_STATUS_EQUAL(status, correct)) { \
46 torture_result(tctx, TORTURE_FAIL, \
47 "(%s) Incorrect status %s - should be %s\n", \
48 __location__, nt_errstr(status), nt_errstr(correct)); \
49 ret = false; \
50 goto done; \
51 }} while (0)
53 #define CHECK_VALUE(v, correct) do { \
54 if ((v) != (correct)) { \
55 torture_result(tctx, TORTURE_FAIL, \
56 "(%s) Incorrect value %s=%u - should be %u\n", \
57 __location__, #v, (unsigned)v, (unsigned)correct); \
58 ret = false; \
59 goto done; \
60 }} while (0)
62 static bool check_stream_list(struct smb2_tree *tree,
63 struct torture_context *tctx,
64 const char *fname,
65 int num_exp,
66 const char **exp,
67 bool is_dir);
69 static int qsort_string(char * const *s1, char * const *s2)
71 return strcmp(*s1, *s2);
74 static int qsort_stream(const struct stream_struct * s1, const struct stream_struct *s2)
76 return strcmp(s1->stream_name.s, s2->stream_name.s);
80 * REVIEW:
81 * This is hokey, but what else can we do?
83 #if defined(HAVE_ATTROPEN) || defined(FREEBSD)
84 #define AFPINFO_EA_NETATALK "org.netatalk.Metadata"
85 #define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork"
86 #else
87 #define AFPINFO_EA_NETATALK "user.org.netatalk.Metadata"
88 #define AFPRESOURCE_EA_NETATALK "user.org.netatalk.ResourceFork"
89 #endif
92 The metadata xattr char buf below contains the following attributes:
94 -------------------------------------------------------------------------------
95 Entry ID : 00000008 : File Dates Info
96 Offset : 00000162 : 354
97 Length : 00000010 : 16
99 -DATE------: : (GMT) : (Local)
100 create : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
101 modify : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
102 backup : 80000000 : Unknown or Initial
103 access : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
105 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
106 00000000 : 1B 44 21 69 1B 44 21 69 80 00 00 00 1B 44 21 69 : .D!i.D!i.....D!i
108 -------------------------------------------------------------------------------
109 Entry ID : 00000009 : Finder Info
110 Offset : 0000007A : 122
111 Length : 00000020 : 32
113 -FInfo-----:
114 Type : 42415252 : BARR
115 Creator : 464F4F4F : FOOO
116 isAlias : 0
117 Invisible : 1
118 hasBundle : 0
119 nameLocked : 0
120 Stationery : 0
121 CustomIcon : 0
122 Reserved : 0
123 Inited : 0
124 NoINITS : 0
125 Shared : 0
126 SwitchLaunc: 0
127 Hidden Ext : 0
128 color : 000 : none
129 isOnDesk : 0
130 Location v : 0000 : 0
131 Location h : 0000 : 0
132 Fldr : 0000 : ..
134 -FXInfo----:
135 Rsvd|IconID: 0000 : 0
136 Rsvd : 0000 : ..
137 Rsvd : 0000 : ..
138 Rsvd : 0000 : ..
139 AreInvalid : 0
140 unknown bit: 0
141 unknown bit: 0
142 unknown bit: 0
143 unknown bit: 0
144 unknown bit: 0
145 unknown bit: 0
146 CustomBadge: 0
147 ObjctIsBusy: 0
148 unknown bit: 0
149 unknown bit: 0
150 unknown bit: 0
151 unknown bit: 0
152 RoutingInfo: 0
153 unknown bit: 0
154 unknown bit: 0
155 Rsvd|commnt: 0000 : 0
156 PutAway : 00000000 : 0
158 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
159 00000000 : 42 41 52 52 46 4F 4F 4F 40 00 00 00 00 00 00 00 : BARRFOOO@.......
160 00000010 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
162 -------------------------------------------------------------------------------
163 Entry ID : 0000000E : AFP File Info
164 Offset : 00000172 : 370
165 Length : 00000004 : 4
167 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
168 00000000 : 00 00 01 A1 : ....
171 char metadata_xattr[] = {
172 0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
176 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x08, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00,
178 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
179 0x00, 0x7a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
180 0x00, 0x0e, 0x00, 0x00, 0x01, 0x72, 0x00, 0x00,
181 0x00, 0x04, 0x80, 0x44, 0x45, 0x56, 0x00, 0x00,
182 0x01, 0x76, 0x00, 0x00, 0x00, 0x08, 0x80, 0x49,
183 0x4e, 0x4f, 0x00, 0x00, 0x01, 0x7e, 0x00, 0x00,
184 0x00, 0x08, 0x80, 0x53, 0x59, 0x4e, 0x00, 0x00,
185 0x01, 0x86, 0x00, 0x00, 0x00, 0x08, 0x80, 0x53,
186 0x56, 0x7e, 0x00, 0x00, 0x01, 0x8e, 0x00, 0x00,
187 0x00, 0x04, 0x42, 0x41, 0x52, 0x52, 0x46, 0x4f,
188 0x4f, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x00, 0x00, 0x1b, 0x44, 0x21, 0x69, 0x1b, 0x44,
217 0x21, 0x69, 0x80, 0x00, 0x00, 0x00, 0x1b, 0x44,
218 0x21, 0x69, 0x00, 0x00, 0x01, 0xa1, 0x00, 0xfd,
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x20,
220 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xe3,
221 0x86, 0x53, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x01,
222 0x00, 0x00
226 The buf below contains the following AppleDouble encoded data:
228 -------------------------------------------------------------------------------
229 MagicNumber: 00051607 : AppleDouble
230 Version : 00020000 : Version 2
231 Filler : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
232 Num. of ent: 0002 : 2
234 -------------------------------------------------------------------------------
235 Entry ID : 00000009 : Finder Info
236 Offset : 00000032 : 50
237 Length : 00000EB0 : 3760
239 -FInfo-----:
240 Type : 54455854 : TEXT
241 Creator : 21526368 : !Rch
244 -EA--------:
245 pad : 0000 : ..
246 magic : 41545452 : ATTR
247 debug_tag : 0007F98E : 522638
248 total_size : 00000EE2 : 3810
249 data_start : 00000078 : 120
250 data_length: 00000000 : 0
251 reserved[0]: 00000000 : ....
252 reserved[1]: 00000000 : ....
253 reserved[2]: 00000000 : ....
254 flags : 0000 : ..
255 num_attrs : 0000 : 0
257 -------------------------------------------------------------------------------
258 Entry ID : 00000002 : Resource Fork
259 Offset : 00000EE2 : 3810
260 Length : 0000011E : 286
262 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
263 00000000 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
264 00000010 : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo
265 00000020 : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
266 00000030 : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 : left blank ..
268 00000110 : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF : ..............
270 static char osx_adouble_w_xattr[] = {
271 0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
272 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
273 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
274 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
275 0x00, 0x32, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00,
276 0x00, 0x02, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00,
277 0x01, 0x1e, 0x54, 0x45, 0x58, 0x54, 0x21, 0x52,
278 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
281 0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
282 0x00, 0x07, 0xf9, 0x8e, 0x00, 0x00, 0x0e, 0xe2,
283 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
284 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
418 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
431 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
445 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
457 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
487 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
493 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
509 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
514 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
523 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
524 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
525 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
530 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
549 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
614 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
679 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
721 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
733 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
734 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
736 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
737 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
744 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
745 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
746 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
747 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
748 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
749 0x00, 0x1e, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72,
750 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20,
751 0x66, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
752 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
753 0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
754 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
757 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
759 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
760 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
761 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
762 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
763 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
764 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
769 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
771 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
779 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
780 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
782 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
786 * talloc and intialize an AfpInfo
788 static AfpInfo *torture_afpinfo_new(TALLOC_CTX *mem_ctx)
790 AfpInfo *info;
792 info = talloc_zero(mem_ctx, AfpInfo);
793 if (info == NULL) {
794 return NULL;
797 info->afpi_Signature = AFP_Signature;
798 info->afpi_Version = AFP_Version;
799 info->afpi_BackupTime = AFP_BackupTime;
801 return info;
805 * Pack AfpInfo into a talloced buffer
807 static char *torture_afpinfo_pack(TALLOC_CTX *mem_ctx,
808 AfpInfo *info)
810 char *buf;
812 buf = talloc_array(mem_ctx, char, AFP_INFO_SIZE);
813 if (buf == NULL) {
814 return NULL;
817 RSIVAL(buf, 0, info->afpi_Signature);
818 RSIVAL(buf, 4, info->afpi_Version);
819 RSIVAL(buf, 12, info->afpi_BackupTime);
820 memcpy(buf + 16, info->afpi_FinderInfo, sizeof(info->afpi_FinderInfo));
822 return buf;
826 * Unpack AfpInfo
828 #if 0
829 static void torture_afpinfo_unpack(AfpInfo *info, char *data)
831 info->afpi_Signature = RIVAL(data, 0);
832 info->afpi_Version = RIVAL(data, 4);
833 info->afpi_BackupTime = RIVAL(data, 12);
834 memcpy(info->afpi_FinderInfo, (const char *)data + 16,
835 sizeof(info->afpi_FinderInfo));
837 #endif
839 static bool torture_write_afpinfo(struct smb2_tree *tree,
840 struct torture_context *tctx,
841 TALLOC_CTX *mem_ctx,
842 const char *fname,
843 AfpInfo *info)
845 struct smb2_handle handle;
846 struct smb2_create io;
847 NTSTATUS status;
848 const char *full_name;
849 char *infobuf;
850 bool ret = true;
852 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, AFPINFO_STREAM_NAME);
853 if (full_name == NULL) {
854 torture_comment(tctx, "talloc_asprintf error\n");
855 return false;
857 ZERO_STRUCT(io);
858 io.in.desired_access = SEC_FILE_WRITE_DATA;
859 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
860 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
861 io.in.create_options = 0;
862 io.in.fname = full_name;
864 status = smb2_create(tree, mem_ctx, &io);
865 CHECK_STATUS(status, NT_STATUS_OK);
867 handle = io.out.file.handle;
869 infobuf = torture_afpinfo_pack(mem_ctx, info);
870 if (infobuf == NULL) {
871 return false;
874 status = smb2_util_write(tree, handle, infobuf, 0, AFP_INFO_SIZE);
875 CHECK_STATUS(status, NT_STATUS_OK);
877 smb2_util_close(tree, handle);
879 done:
880 return ret;
884 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
885 * compare against buffer 'value'
887 static bool check_stream(struct smb2_tree *tree,
888 const char *location,
889 struct torture_context *tctx,
890 TALLOC_CTX *mem_ctx,
891 const char *fname,
892 const char *sname,
893 off_t read_offset,
894 size_t read_count,
895 off_t comp_offset,
896 size_t comp_count,
897 const char *value)
899 struct smb2_handle handle;
900 struct smb2_create create;
901 struct smb2_read r;
902 NTSTATUS status;
903 char *full_name;
904 bool ret = true;
906 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
907 if (full_name == NULL) {
908 torture_comment(tctx, "talloc_asprintf error\n");
909 return false;
911 ZERO_STRUCT(create);
912 create.in.desired_access = SEC_FILE_READ_DATA;
913 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
914 create.in.create_disposition = NTCREATEX_DISP_OPEN;
915 create.in.fname = full_name;
917 torture_comment(tctx, "Open stream %s\n", full_name);
919 status = smb2_create(tree, mem_ctx, &create);
920 if (!NT_STATUS_IS_OK(status)) {
921 TALLOC_FREE(full_name);
922 if (value == NULL) {
923 return true;
925 torture_comment(tctx, "Unable to open stream %s\n", full_name);
926 return false;
929 handle = create.out.file.handle;
930 if (value == NULL) {
931 TALLOC_FREE(full_name);
932 smb2_util_close(tree, handle);
933 return true;
936 ZERO_STRUCT(r);
937 r.in.file.handle = handle;
938 r.in.length = read_count;
939 r.in.offset = read_offset;
941 status = smb2_read(tree, tree, &r);
943 torture_assert_ntstatus_ok_goto(
944 tctx, status, ret, done,
945 talloc_asprintf(tctx, "(%s) Failed to read %lu bytes from stream '%s'\n",
946 location, (long)strlen(value), full_name));
948 torture_assert_goto(tctx, r.out.data.length == read_count, ret, done,
949 talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected %jd\n",
950 (intmax_t)r.out.data.length, (intmax_t)read_count));
952 torture_assert_goto(
953 tctx, memcmp(r.out.data.data + comp_offset, value, comp_count) == 0,
954 ret, done,
955 talloc_asprintf(tctx, "(%s) Bad data in stream\n", location));
957 done:
958 TALLOC_FREE(full_name);
959 smb2_util_close(tree, handle);
960 return ret;
964 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
965 * compare against buffer 'value'
967 static ssize_t read_stream(struct smb2_tree *tree,
968 const char *location,
969 struct torture_context *tctx,
970 TALLOC_CTX *mem_ctx,
971 const char *fname,
972 const char *sname,
973 off_t read_offset,
974 size_t read_count)
976 struct smb2_handle handle;
977 struct smb2_create create;
978 struct smb2_read r;
979 NTSTATUS status;
980 const char *full_name;
981 bool ret = true;
983 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
984 if (full_name == NULL) {
985 torture_comment(tctx, "talloc_asprintf error\n");
986 return -1;
988 ZERO_STRUCT(create);
989 create.in.desired_access = SEC_FILE_READ_DATA;
990 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
991 create.in.create_disposition = NTCREATEX_DISP_OPEN;
992 create.in.fname = full_name;
994 torture_comment(tctx, "Open stream %s\n", full_name);
996 status = smb2_create(tree, mem_ctx, &create);
997 if (!NT_STATUS_IS_OK(status)) {
998 torture_comment(tctx, "Unable to open stream %s\n",
999 full_name);
1000 return -1;
1003 handle = create.out.file.handle;
1005 ZERO_STRUCT(r);
1006 r.in.file.handle = handle;
1007 r.in.length = read_count;
1008 r.in.offset = read_offset;
1010 status = smb2_read(tree, tree, &r);
1011 if (!NT_STATUS_IS_OK(status)) {
1012 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
1015 smb2_util_close(tree, handle);
1017 done:
1018 if (ret == false) {
1019 return -1;
1021 return r.out.data.length;
1025 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1026 * compare against buffer 'value'
1028 static bool write_stream(struct smb2_tree *tree,
1029 const char *location,
1030 struct torture_context *tctx,
1031 TALLOC_CTX *mem_ctx,
1032 const char *fname,
1033 const char *sname,
1034 off_t offset,
1035 size_t size,
1036 const char *value)
1038 struct smb2_handle handle;
1039 struct smb2_create create;
1040 NTSTATUS status;
1041 const char *full_name;
1043 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1044 if (full_name == NULL) {
1045 torture_comment(tctx, "talloc_asprintf error\n");
1046 return false;
1048 ZERO_STRUCT(create);
1049 create.in.desired_access = SEC_FILE_WRITE_DATA;
1050 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1051 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1052 create.in.fname = full_name;
1054 status = smb2_create(tree, mem_ctx, &create);
1055 if (!NT_STATUS_IS_OK(status)) {
1056 if (value == NULL) {
1057 return true;
1058 } else {
1059 torture_comment(tctx, "Unable to open stream %s\n",
1060 full_name);
1061 sleep(10000000);
1062 return false;
1066 handle = create.out.file.handle;
1067 if (value == NULL) {
1068 return true;
1071 status = smb2_util_write(tree, handle, value, offset, size);
1073 if (!NT_STATUS_IS_OK(status)) {
1074 torture_comment(tctx, "(%s) Failed to write %lu bytes to "
1075 "stream '%s'\n", location, (long)size, full_name);
1076 return false;
1079 smb2_util_close(tree, handle);
1080 return true;
1083 static bool torture_setup_local_xattr(struct torture_context *tctx,
1084 const char *path_option,
1085 const char *name,
1086 const char *xattr,
1087 const char *metadata,
1088 size_t size)
1090 int ret = true;
1091 int result;
1092 const char *spath;
1093 char *path;
1095 spath = torture_setting_string(tctx, path_option, NULL);
1096 if (spath == NULL) {
1097 printf("No sharepath for option %s\n", path_option);
1098 return false;
1101 path = talloc_asprintf(tctx, "%s/%s", spath, name);
1103 result = setxattr(path, xattr, metadata, size, 0);
1104 if (result != 0) {
1105 ret = false;
1108 TALLOC_FREE(path);
1110 return ret;
1113 static bool torture_setup_local_file(struct torture_context *tctx,
1114 const char *path_option,
1115 const char *name,
1116 const char *buf,
1117 size_t size)
1119 int fd;
1120 const char *spath;
1121 char *path;
1122 ssize_t rsize;
1124 spath = torture_setting_string(tctx, path_option, NULL);
1125 if (spath == NULL) {
1126 printf("No sharepath for option %s\n", path_option);
1127 return false;
1130 path = talloc_asprintf(tctx, "%s/%s", spath, name);
1131 if (path == NULL) {
1132 return false;
1135 fd = creat(path, S_IRWXU);
1136 TALLOC_FREE(path);
1137 if (fd == -1) {
1138 return false;
1141 if ((buf == NULL) || (size == 0)) {
1142 close(fd);
1143 return true;
1146 rsize = write(fd, buf, size);
1147 if (rsize != size) {
1148 return false;
1151 close(fd);
1153 return true;
1157 * Create a file or directory
1159 static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree,
1160 const char *name, bool dir)
1162 struct smb2_create io;
1163 NTSTATUS status;
1165 smb2_util_unlink(tree, name);
1166 ZERO_STRUCT(io);
1167 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1168 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1169 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1170 io.in.share_access =
1171 NTCREATEX_SHARE_ACCESS_DELETE|
1172 NTCREATEX_SHARE_ACCESS_READ|
1173 NTCREATEX_SHARE_ACCESS_WRITE;
1174 io.in.create_options = 0;
1175 io.in.fname = name;
1176 if (dir) {
1177 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1178 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
1179 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1180 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1183 status = smb2_create(tree, mem_ctx, &io);
1184 if (!NT_STATUS_IS_OK(status)) {
1185 return false;
1188 status = smb2_util_close(tree, io.out.file.handle);
1189 if (!NT_STATUS_IS_OK(status)) {
1190 return false;
1193 return true;
1196 static bool enable_aapl(struct torture_context *tctx,
1197 struct smb2_tree *tree)
1199 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1200 NTSTATUS status;
1201 bool ret = true;
1202 struct smb2_create io;
1203 DATA_BLOB data;
1204 struct smb2_create_blob *aapl = NULL;
1205 uint32_t aapl_server_caps;
1206 uint32_t expexted_scaps = (SMB2_CRTCTX_AAPL_UNIX_BASED |
1207 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1208 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1209 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
1210 bool is_osx_server = torture_setting_bool(tctx, "osx", false);
1212 ZERO_STRUCT(io);
1213 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1214 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1215 io.in.create_disposition = NTCREATEX_DISP_OPEN;
1216 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1217 NTCREATEX_SHARE_ACCESS_READ |
1218 NTCREATEX_SHARE_ACCESS_WRITE);
1219 io.in.fname = "";
1222 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1223 * controls behaviour of Apple's SMB2 extensions for the whole
1224 * session!
1227 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1228 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1229 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1230 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1231 SMB2_CRTCTX_AAPL_MODEL_INFO));
1232 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1233 SMB2_CRTCTX_AAPL_UNIX_BASED |
1234 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1236 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1237 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_blob_add");
1239 status = smb2_create(tree, tctx, &io);
1240 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1242 status = smb2_util_close(tree, io.out.file.handle);
1243 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close");
1246 * Now check returned AAPL context
1248 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1250 aapl = smb2_create_blob_find(&io.out.blobs,
1251 SMB2_CREATE_TAG_AAPL);
1252 torture_assert_goto(tctx, aapl != NULL, ret, done, "missing AAPL context");
1254 if (!is_osx_server) {
1255 torture_assert_goto(tctx, aapl->data.length == 50, ret, done, "bad AAPL size");
1258 aapl_server_caps = BVAL(aapl->data.data, 16);
1259 torture_assert_goto(tctx, aapl_server_caps == expexted_scaps,
1260 ret, done, "bad AAPL caps");
1262 done:
1263 talloc_free(mem_ctx);
1264 return ret;
1267 static bool test_read_netatalk_metadata(struct torture_context *tctx,
1268 struct smb2_tree *tree)
1270 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1271 const char *fname = BASEDIR "\\torture_read_metadata";
1272 NTSTATUS status;
1273 struct smb2_handle testdirh;
1274 bool ret = true;
1275 ssize_t len;
1276 const char *localdir = NULL;
1278 torture_comment(tctx, "Checking metadata access\n");
1280 localdir = torture_setting_string(tctx, "localdir", NULL);
1281 if (localdir == NULL) {
1282 torture_skip(tctx, "Need localdir for test");
1285 smb2_util_unlink(tree, fname);
1287 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1288 CHECK_STATUS(status, NT_STATUS_OK);
1289 smb2_util_close(tree, testdirh);
1291 ret = torture_setup_file(mem_ctx, tree, fname, false);
1292 if (ret == false) {
1293 goto done;
1296 ret = torture_setup_local_xattr(tctx, "localdir",
1297 BASEDIR "/torture_read_metadata",
1298 AFPINFO_EA_NETATALK,
1299 metadata_xattr, sizeof(metadata_xattr));
1300 if (ret == false) {
1301 goto done;
1304 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1305 0, 60, 0, 4, "AFP");
1306 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1308 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1309 0, 60, 16, 8, "BARRFOOO");
1310 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1312 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1313 16, 8, 0, 3, "AFP");
1314 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1316 /* Check reading offset and read size > sizeof(AFPINFO_STREAM) */
1318 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1319 AFPINFO_STREAM, 0, 61);
1320 CHECK_VALUE(len, 60);
1322 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1323 AFPINFO_STREAM, 59, 2);
1324 CHECK_VALUE(len, 2);
1326 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1327 AFPINFO_STREAM, 60, 1);
1328 CHECK_VALUE(len, 1);
1330 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1331 AFPINFO_STREAM, 61, 1);
1332 CHECK_VALUE(len, 0);
1334 done:
1335 smb2_deltree(tree, BASEDIR);
1336 talloc_free(mem_ctx);
1337 return ret;
1340 static bool test_read_afpinfo(struct torture_context *tctx,
1341 struct smb2_tree *tree)
1343 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1344 const char *fname = BASEDIR "\\torture_read_metadata";
1345 NTSTATUS status;
1346 struct smb2_handle testdirh;
1347 bool ret = true;
1348 ssize_t len;
1349 AfpInfo *info;
1350 const char *type_creator = "SMB,OLE!";
1352 torture_comment(tctx, "Checking metadata access\n");
1354 smb2_util_unlink(tree, fname);
1356 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1357 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
1358 smb2_util_close(tree, testdirh);
1360 ret = torture_setup_file(mem_ctx, tree, fname, false);
1361 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
1363 info = torture_afpinfo_new(mem_ctx);
1364 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
1366 memcpy(info->afpi_FinderInfo, type_creator, 8);
1367 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1368 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
1370 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1371 0, 60, 0, 4, "AFP");
1372 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1374 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1375 0, 60, 16, 8, type_creator);
1376 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1379 * OS X ignores offset <= 60 and treats the as
1380 * offset=0. Reading from offsets > 60 returns EOF=0.
1383 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1384 16, 8, 0, 8, "AFP\0\0\0\001\0");
1385 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1387 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1388 AFPINFO_STREAM, 0, 61);
1389 torture_assert_goto(tctx, len == 60, ret, done, "read_stream failed");
1391 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1392 AFPINFO_STREAM, 59, 2);
1393 torture_assert_goto(tctx, len == 2, ret, done, "read_stream failed");
1395 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1396 59, 2, 0, 2, "AF");
1397 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1399 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1400 AFPINFO_STREAM, 60, 1);
1401 torture_assert_goto(tctx, len == 1, ret, done, "read_stream failed");
1403 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1404 60, 1, 0, 1, "A");
1405 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1407 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1408 AFPINFO_STREAM, 61, 1);
1409 torture_assert_goto(tctx, len == 0, ret, done, "read_stream failed");
1411 done:
1412 smb2_util_unlink(tree, fname);
1413 smb2_deltree(tree, BASEDIR);
1414 talloc_free(mem_ctx);
1415 return ret;
1418 static bool test_write_atalk_metadata(struct torture_context *tctx,
1419 struct smb2_tree *tree)
1421 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1422 const char *fname = BASEDIR "\\torture_write_metadata";
1423 const char *type_creator = "SMB,OLE!";
1424 NTSTATUS status;
1425 struct smb2_handle testdirh;
1426 bool ret = true;
1427 AfpInfo *info;
1429 smb2_deltree(tree, BASEDIR);
1430 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1431 CHECK_STATUS(status, NT_STATUS_OK);
1432 smb2_util_close(tree, testdirh);
1434 ret = torture_setup_file(mem_ctx, tree, fname, false);
1435 if (ret == false) {
1436 goto done;
1439 info = torture_afpinfo_new(mem_ctx);
1440 if (info == NULL) {
1441 goto done;
1444 memcpy(info->afpi_FinderInfo, type_creator, 8);
1445 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1446 ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1447 0, 60, 16, 8, type_creator);
1449 done:
1450 smb2_util_unlink(tree, fname);
1451 smb2_deltree(tree, BASEDIR);
1452 talloc_free(mem_ctx);
1453 return ret;
1456 static bool test_write_atalk_rfork_io(struct torture_context *tctx,
1457 struct smb2_tree *tree)
1459 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1460 const char *fname = BASEDIR "\\torture_write_rfork_io";
1461 const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
1462 const char *rfork_content = "1234567890";
1463 NTSTATUS status;
1464 struct smb2_handle testdirh;
1465 bool ret = true;
1467 union smb_open io;
1468 struct smb2_handle filehandle;
1469 union smb_fileinfo finfo;
1470 union smb_setfileinfo sinfo;
1472 smb2_util_unlink(tree, fname);
1474 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1475 CHECK_STATUS(status, NT_STATUS_OK);
1476 smb2_util_close(tree, testdirh);
1478 ret = torture_setup_file(mem_ctx, tree, fname, false);
1479 if (ret == false) {
1480 goto done;
1483 torture_comment(tctx, "(%s) writing to resource fork\n",
1484 __location__);
1486 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1487 fname, AFPRESOURCE_STREAM_NAME,
1488 10, 10, rfork_content);
1490 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1491 fname, AFPRESOURCE_STREAM_NAME,
1492 0, 20, 10, 10, rfork_content);
1494 /* Check size after write */
1496 ZERO_STRUCT(io);
1497 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1498 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1499 SEC_FILE_WRITE_ATTRIBUTE;
1500 io.smb2.in.fname = rfork;
1501 status = smb2_create(tree, mem_ctx, &(io.smb2));
1502 CHECK_STATUS(status, NT_STATUS_OK);
1503 filehandle = io.smb2.out.file.handle;
1505 torture_comment(tctx, "(%s) check resource fork size after write\n",
1506 __location__);
1508 ZERO_STRUCT(finfo);
1509 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1510 finfo.generic.in.file.handle = filehandle;
1511 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1512 CHECK_STATUS(status, NT_STATUS_OK);
1513 if (finfo.all_info.out.size != 20) {
1514 torture_result(tctx, TORTURE_FAIL,
1515 "(%s) Incorrect resource fork size\n",
1516 __location__);
1517 ret = false;
1518 smb2_util_close(tree, filehandle);
1519 goto done;
1521 smb2_util_close(tree, filehandle);
1523 /* Write at large offset */
1525 torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
1526 __location__);
1528 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1529 fname, AFPRESOURCE_STREAM_NAME,
1530 (off_t)1<<32, 10, rfork_content);
1532 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1533 fname, AFPRESOURCE_STREAM_NAME,
1534 (off_t)1<<32, 10, 0, 10, rfork_content);
1536 /* Truncate back to size of 1 byte */
1538 torture_comment(tctx, "(%s) truncate resource fork and check size\n",
1539 __location__);
1541 ZERO_STRUCT(io);
1542 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1543 io.smb2.in.desired_access = SEC_FILE_ALL;
1544 io.smb2.in.fname = rfork;
1545 status = smb2_create(tree, mem_ctx, &(io.smb2));
1546 CHECK_STATUS(status, NT_STATUS_OK);
1547 filehandle = io.smb2.out.file.handle;
1549 ZERO_STRUCT(sinfo);
1550 sinfo.end_of_file_info.level =
1551 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1552 sinfo.end_of_file_info.in.file.handle = filehandle;
1553 sinfo.end_of_file_info.in.size = 1;
1554 status = smb2_setinfo_file(tree, &sinfo);
1555 CHECK_STATUS(status, NT_STATUS_OK);
1557 smb2_util_close(tree, filehandle);
1559 /* Now check size */
1560 ZERO_STRUCT(io);
1561 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1562 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1563 SEC_FILE_WRITE_ATTRIBUTE;
1564 io.smb2.in.fname = rfork;
1565 status = smb2_create(tree, mem_ctx, &(io.smb2));
1566 CHECK_STATUS(status, NT_STATUS_OK);
1567 filehandle = io.smb2.out.file.handle;
1569 ZERO_STRUCT(finfo);
1570 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1571 finfo.generic.in.file.handle = filehandle;
1572 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1573 CHECK_STATUS(status, NT_STATUS_OK);
1574 if (finfo.all_info.out.size != 1) {
1575 torture_result(tctx, TORTURE_FAIL,
1576 "(%s) Incorrect resource fork size\n",
1577 __location__);
1578 ret = false;
1579 smb2_util_close(tree, filehandle);
1580 goto done;
1582 smb2_util_close(tree, filehandle);
1584 done:
1585 smb2_util_unlink(tree, fname);
1586 smb2_deltree(tree, BASEDIR);
1587 talloc_free(mem_ctx);
1588 return ret;
1591 static bool test_rfork_truncate(struct torture_context *tctx,
1592 struct smb2_tree *tree)
1594 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1595 const char *fname = BASEDIR "\\torture_rfork_truncate";
1596 const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
1597 const char *rfork_content = "1234567890";
1598 NTSTATUS status;
1599 struct smb2_handle testdirh;
1600 bool ret = true;
1601 struct smb2_create create;
1602 struct smb2_handle fh1, fh2, fh3;
1603 union smb_setfileinfo sinfo;
1605 smb2_util_unlink(tree, fname);
1607 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1608 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1609 smb2_util_close(tree, testdirh);
1611 ret = torture_setup_file(mem_ctx, tree, fname, false);
1612 if (ret == false) {
1613 goto done;
1616 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1617 fname, AFPRESOURCE_STREAM,
1618 10, 10, rfork_content);
1620 /* Truncate back to size 0, further access MUST return ENOENT */
1622 torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
1623 __location__);
1625 ZERO_STRUCT(create);
1626 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1627 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1628 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1629 create.in.fname = fname;
1630 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1631 NTCREATEX_SHARE_ACCESS_READ |
1632 NTCREATEX_SHARE_ACCESS_WRITE;
1633 status = smb2_create(tree, mem_ctx, &create);
1634 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1635 fh1 = create.out.file.handle;
1637 ZERO_STRUCT(create);
1638 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1639 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1640 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1641 create.in.fname = rfork;
1642 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1643 NTCREATEX_SHARE_ACCESS_READ |
1644 NTCREATEX_SHARE_ACCESS_WRITE;
1645 status = smb2_create(tree, mem_ctx, &create);
1646 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1647 fh2 = create.out.file.handle;
1649 ZERO_STRUCT(sinfo);
1650 sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1651 sinfo.end_of_file_info.in.file.handle = fh2;
1652 sinfo.end_of_file_info.in.size = 0;
1653 status = smb2_setinfo_file(tree, &sinfo);
1654 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
1657 * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
1659 ZERO_STRUCT(create);
1660 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1661 create.in.desired_access = SEC_FILE_ALL;
1662 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1663 create.in.fname = rfork;
1664 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1665 NTCREATEX_SHARE_ACCESS_READ |
1666 NTCREATEX_SHARE_ACCESS_WRITE;
1667 status = smb2_create(tree, mem_ctx, &create);
1668 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1671 * Do another open on the rfork and write to the new handle. A
1672 * naive server might unlink the AppleDouble resource fork
1673 * file when its truncated to 0 bytes above, so in case both
1674 * open handles share the same underlying fd, the unlink would
1675 * cause the below write to be lost.
1677 ZERO_STRUCT(create);
1678 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1679 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1680 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1681 create.in.fname = rfork;
1682 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1683 NTCREATEX_SHARE_ACCESS_READ |
1684 NTCREATEX_SHARE_ACCESS_WRITE;
1685 status = smb2_create(tree, mem_ctx, &create);
1686 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1687 fh3 = create.out.file.handle;
1689 status = smb2_util_write(tree, fh3, "foo", 0, 3);
1690 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
1692 smb2_util_close(tree, fh3);
1693 smb2_util_close(tree, fh2);
1694 smb2_util_close(tree, fh1);
1696 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
1697 0, 3, 0, 3, "foo");
1698 torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1700 done:
1701 smb2_util_unlink(tree, fname);
1702 smb2_deltree(tree, BASEDIR);
1703 talloc_free(mem_ctx);
1704 return ret;
1707 static bool test_rfork_create(struct torture_context *tctx,
1708 struct smb2_tree *tree)
1710 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1711 const char *fname = BASEDIR "\\torture_rfork_create";
1712 const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1713 NTSTATUS status;
1714 struct smb2_handle testdirh;
1715 bool ret = true;
1716 struct smb2_create create;
1717 struct smb2_handle fh1;
1718 const char *streams[] = {
1719 "::$DATA"
1721 union smb_fileinfo finfo;
1723 smb2_util_unlink(tree, fname);
1725 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1726 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1727 smb2_util_close(tree, testdirh);
1729 ret = torture_setup_file(mem_ctx, tree, fname, false);
1730 if (ret == false) {
1731 goto done;
1734 torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
1735 __location__);
1737 ZERO_STRUCT(create);
1738 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1739 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1740 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1741 create.in.fname = rfork;
1742 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1743 NTCREATEX_SHARE_ACCESS_READ |
1744 NTCREATEX_SHARE_ACCESS_WRITE;
1745 status = smb2_create(tree, mem_ctx, &create);
1746 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1748 torture_comment(tctx, "(%s) create resource fork\n", __location__);
1750 ZERO_STRUCT(create);
1751 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1752 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1753 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1754 create.in.fname = rfork;
1755 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1756 NTCREATEX_SHARE_ACCESS_READ |
1757 NTCREATEX_SHARE_ACCESS_WRITE;
1758 status = smb2_create(tree, mem_ctx, &create);
1759 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1760 fh1 = create.out.file.handle;
1762 torture_comment(tctx, "(%s) getinfo on create handle\n",
1763 __location__);
1765 ZERO_STRUCT(finfo);
1766 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1767 finfo.generic.in.file.handle = fh1;
1768 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1769 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
1770 if (finfo.all_info.out.size != 0) {
1771 torture_result(tctx, TORTURE_FAIL,
1772 "(%s) Incorrect resource fork size\n",
1773 __location__);
1774 ret = false;
1775 smb2_util_close(tree, fh1);
1776 goto done;
1779 torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
1780 __location__);
1782 ZERO_STRUCT(create);
1783 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1784 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1785 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1786 create.in.fname = rfork;
1787 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1788 NTCREATEX_SHARE_ACCESS_READ |
1789 NTCREATEX_SHARE_ACCESS_WRITE;
1790 status = smb2_create(tree, mem_ctx, &create);
1791 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1793 ret = check_stream_list(tree, tctx, fname, 1, streams, false);
1794 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
1796 torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
1797 __location__);
1799 ZERO_STRUCT(create);
1800 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1801 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1802 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1803 create.in.fname = rfork;
1804 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1805 NTCREATEX_SHARE_ACCESS_READ |
1806 NTCREATEX_SHARE_ACCESS_WRITE;
1807 status = smb2_create(tree, mem_ctx, &create);
1808 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1810 done:
1811 smb2_util_unlink(tree, fname);
1812 smb2_deltree(tree, BASEDIR);
1813 talloc_free(mem_ctx);
1814 return ret;
1817 static bool test_adouble_conversion(struct torture_context *tctx,
1818 struct smb2_tree *tree)
1820 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1821 const char *fname = BASEDIR "\\test_adouble_conversion";
1822 const char *fname_local = BASEDIR "/test_adouble_conversion";
1823 const char *adname_local = BASEDIR "/._test_adouble_conversion";
1824 NTSTATUS status;
1825 struct smb2_handle testdirh;
1826 bool ret = true;
1827 const char *data = "This resource fork intentionally left blank";
1828 size_t datalen = strlen(data);
1829 const char *localdir = NULL;
1831 localdir = torture_setting_string(tctx, "localdir", NULL);
1832 if (localdir == NULL) {
1833 torture_skip(tctx, "Need localdir for test");
1836 smb2_util_unlink(tree, fname);
1838 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1839 CHECK_STATUS(status, NT_STATUS_OK);
1840 smb2_util_close(tree, testdirh);
1842 ret = torture_setup_local_file(tctx, "localdir", fname_local,
1843 NULL, 0);
1844 if (ret == false) {
1845 goto done;
1848 ret = torture_setup_local_file(tctx, "localdir", adname_local,
1849 osx_adouble_w_xattr,
1850 sizeof(osx_adouble_w_xattr));
1851 if (ret == false) {
1852 goto done;
1855 torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
1856 __location__);
1858 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1859 fname, AFPRESOURCE_STREAM,
1860 16, datalen, 0, datalen, data);
1862 done:
1863 smb2_deltree(tree, BASEDIR);
1864 talloc_free(mem_ctx);
1865 return ret;
1868 static bool test_aapl(struct torture_context *tctx,
1869 struct smb2_tree *tree)
1871 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1872 const char *fname = BASEDIR "\\test_aapl";
1873 NTSTATUS status;
1874 struct smb2_handle testdirh;
1875 bool ret = true;
1876 struct smb2_create io;
1877 DATA_BLOB data;
1878 struct smb2_create_blob *aapl = NULL;
1879 AfpInfo *info;
1880 const char *type_creator = "SMB,OLE!";
1881 char type_creator_buf[9];
1882 uint32_t aapl_cmd;
1883 uint32_t aapl_reply_bitmap;
1884 uint32_t aapl_server_caps;
1885 uint32_t aapl_vol_caps;
1886 char *model;
1887 struct smb2_find f;
1888 unsigned int count;
1889 union smb_search_data *d;
1890 uint64_t rfork_len;
1892 smb2_deltree(tree, BASEDIR);
1894 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1895 CHECK_STATUS(status, NT_STATUS_OK);
1896 smb2_util_close(tree, testdirh);
1898 ZERO_STRUCT(io);
1899 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1900 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1901 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1902 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1903 NTCREATEX_SHARE_ACCESS_READ |
1904 NTCREATEX_SHARE_ACCESS_WRITE);
1905 io.in.fname = fname;
1908 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1909 * controls behaviour of Apple's SMB2 extensions for the whole
1910 * session!
1913 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1914 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1915 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1916 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1917 SMB2_CRTCTX_AAPL_MODEL_INFO));
1918 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1919 SMB2_CRTCTX_AAPL_UNIX_BASED |
1920 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1922 torture_comment(tctx, "Testing SMB2 create context AAPL\n");
1923 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1924 CHECK_STATUS(status, NT_STATUS_OK);
1926 status = smb2_create(tree, tctx, &io);
1927 CHECK_STATUS(status, NT_STATUS_OK);
1928 status = smb2_util_close(tree, io.out.file.handle);
1929 CHECK_STATUS(status, NT_STATUS_OK);
1932 * Now check returned AAPL context
1934 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1936 aapl = smb2_create_blob_find(&io.out.blobs,
1937 SMB2_CREATE_TAG_AAPL);
1939 if (aapl == NULL) {
1940 torture_result(tctx, TORTURE_FAIL,
1941 "(%s) unexpectedly no AAPL capabilities were returned.",
1942 __location__);
1943 ret = false;
1944 goto done;
1947 if (aapl->data.length != 50) {
1949 * uint32_t CommandCode = kAAPL_SERVER_QUERY
1950 * uint32_t Reserved = 0;
1951 * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
1952 * kAAPL_VOLUME_CAPS |
1953 * kAAPL_MODEL_INFO;
1954 * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
1955 * kAAPL_SUPPORTS_OSX_COPYFILE;
1956 * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
1957 * kAAPL_CASE_SENSITIVE;
1958 * uint32_t Pad2 = 0;
1959 * uint32_t ModelStringLen = 10;
1960 * ucs2_t ModelString[5] = "Samba";
1962 torture_warning(tctx,
1963 "(%s) unexpected AAPL context length: %zd, expected 50",
1964 __location__, aapl->data.length);
1967 aapl_cmd = IVAL(aapl->data.data, 0);
1968 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
1969 torture_result(tctx, TORTURE_FAIL,
1970 "(%s) unexpected cmd: %d",
1971 __location__, (int)aapl_cmd);
1972 ret = false;
1973 goto done;
1976 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
1977 if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1978 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1979 SMB2_CRTCTX_AAPL_MODEL_INFO)) {
1980 torture_result(tctx, TORTURE_FAIL,
1981 "(%s) unexpected reply_bitmap: %d",
1982 __location__, (int)aapl_reply_bitmap);
1983 ret = false;
1984 goto done;
1987 aapl_server_caps = BVAL(aapl->data.data, 16);
1988 if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
1989 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1990 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1991 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
1992 torture_result(tctx, TORTURE_FAIL,
1993 "(%s) unexpected server_caps: %d",
1994 __location__, (int)aapl_server_caps);
1995 ret = false;
1996 goto done;
1999 aapl_vol_caps = BVAL(aapl->data.data, 24);
2000 if (aapl_vol_caps != SMB2_CRTCTX_AAPL_CASE_SENSITIVE) {
2001 /* this will fail on a case insensitive fs ... */
2002 torture_warning(tctx,
2003 "(%s) unexpected vol_caps: %d",
2004 __location__, (int)aapl_vol_caps);
2007 ret = convert_string_talloc(mem_ctx,
2008 CH_UTF16LE, CH_UNIX,
2009 aapl->data.data + 40, 10,
2010 &model, NULL);
2011 if (ret == false) {
2012 torture_result(tctx, TORTURE_FAIL,
2013 "(%s) convert_string_talloc() failed",
2014 __location__);
2015 goto done;
2017 torture_comment(tctx, "Got server model: \"%s\"\n", model);
2020 * Now that Requested AAPL extensions are enabled, setup some
2021 * Mac files with metadata and resource fork
2023 ret = torture_setup_file(mem_ctx, tree, fname, false);
2024 if (ret == false) {
2025 torture_result(tctx, TORTURE_FAIL,
2026 "(%s) torture_setup_file() failed",
2027 __location__);
2028 goto done;
2031 info = torture_afpinfo_new(mem_ctx);
2032 if (info == NULL) {
2033 torture_result(tctx, TORTURE_FAIL,
2034 "(%s) torture_afpinfo_new() failed",
2035 __location__);
2036 ret = false;
2037 goto done;
2040 memcpy(info->afpi_FinderInfo, type_creator, 8);
2041 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2042 if (ret == false) {
2043 torture_result(tctx, TORTURE_FAIL,
2044 "(%s) torture_write_afpinfo() failed",
2045 __location__);
2046 goto done;
2049 ret = write_stream(tree, __location__, tctx, mem_ctx,
2050 fname, AFPRESOURCE_STREAM_NAME,
2051 0, 3, "foo");
2052 if (ret == false) {
2053 torture_result(tctx, TORTURE_FAIL,
2054 "(%s) write_stream() failed",
2055 __location__);
2056 goto done;
2060 * Ok, file is prepared, now call smb2/find
2063 ZERO_STRUCT(io);
2064 io.in.desired_access = SEC_RIGHTS_DIR_READ;
2065 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2066 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2067 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
2068 NTCREATEX_SHARE_ACCESS_WRITE |
2069 NTCREATEX_SHARE_ACCESS_DELETE);
2070 io.in.create_disposition = NTCREATEX_DISP_OPEN;
2071 io.in.fname = BASEDIR;
2072 status = smb2_create(tree, tctx, &io);
2073 CHECK_STATUS(status, NT_STATUS_OK);
2075 ZERO_STRUCT(f);
2076 f.in.file.handle = io.out.file.handle;
2077 f.in.pattern = "test_aapl";
2078 f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
2079 f.in.max_response_size = 0x1000;
2080 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
2082 status = smb2_find_level(tree, tree, &f, &count, &d);
2083 CHECK_STATUS(status, NT_STATUS_OK);
2085 status = smb2_util_close(tree, io.out.file.handle);
2086 CHECK_STATUS(status, NT_STATUS_OK);
2088 if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2089 torture_result(tctx, TORTURE_FAIL,
2090 "(%s) write_stream() failed",
2091 __location__);
2092 ret = false;
2093 goto done;
2096 if (d[0].id_both_directory_info.short_name.private_length != 24) {
2097 torture_result(tctx, TORTURE_FAIL,
2098 "(%s) bad short_name length %" PRIu32 ", expected 24",
2099 __location__, d[0].id_both_directory_info.short_name.private_length);
2100 ret = false;
2101 goto done;
2104 torture_comment(tctx, "short_name buffer:\n");
2105 dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2108 * Extract data as specified by the AAPL extension:
2109 * - ea_size contains max_access
2110 * - short_name contains resource fork length + FinderInfo
2111 * - reserved2 contains the unix mode
2113 torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2114 d[0].id_both_directory_info.ea_size);
2116 rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2117 if (rfork_len != 3) {
2118 torture_result(tctx, TORTURE_FAIL,
2119 "(%s) expected resource fork length 3, got: %" PRIu64,
2120 __location__, rfork_len);
2121 ret = false;
2122 goto done;
2125 memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2126 type_creator_buf[8] = 0;
2127 if (strcmp(type_creator, type_creator_buf) != 0) {
2128 torture_result(tctx, TORTURE_FAIL,
2129 "(%s) expected type/creator \"%s\" , got: %s",
2130 __location__, type_creator, type_creator_buf);
2131 ret = false;
2132 goto done;
2135 done:
2136 smb2_util_unlink(tree, fname);
2137 smb2_deltree(tree, BASEDIR);
2138 talloc_free(mem_ctx);
2139 return ret;
2142 static uint64_t patt_hash(uint64_t off)
2144 return off;
2147 static bool write_pattern(struct torture_context *torture,
2148 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2149 struct smb2_handle h, uint64_t off, uint64_t len,
2150 uint64_t patt_off)
2152 NTSTATUS status;
2153 uint64_t i;
2154 uint8_t *buf;
2155 uint64_t io_sz = MIN(1024 * 64, len);
2157 if (len == 0) {
2158 return true;
2161 torture_assert(torture, (len % 8) == 0, "invalid write len");
2163 buf = talloc_zero_size(mem_ctx, io_sz);
2164 torture_assert(torture, (buf != NULL), "no memory for file data buf");
2166 while (len > 0) {
2167 for (i = 0; i <= io_sz - 8; i += 8) {
2168 SBVAL(buf, i, patt_hash(patt_off));
2169 patt_off += 8;
2172 status = smb2_util_write(tree, h,
2173 buf, off, io_sz);
2174 torture_assert_ntstatus_ok(torture, status, "file write");
2176 len -= io_sz;
2177 off += io_sz;
2180 talloc_free(buf);
2182 return true;
2185 static bool check_pattern(struct torture_context *torture,
2186 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2187 struct smb2_handle h, uint64_t off, uint64_t len,
2188 uint64_t patt_off)
2190 if (len == 0) {
2191 return true;
2194 torture_assert(torture, (len % 8) == 0, "invalid read len");
2196 while (len > 0) {
2197 uint64_t i;
2198 struct smb2_read r;
2199 NTSTATUS status;
2200 uint64_t io_sz = MIN(1024 * 64, len);
2202 ZERO_STRUCT(r);
2203 r.in.file.handle = h;
2204 r.in.length = io_sz;
2205 r.in.offset = off;
2206 status = smb2_read(tree, mem_ctx, &r);
2207 torture_assert_ntstatus_ok(torture, status, "read");
2209 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2210 "read data len mismatch");
2212 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2213 uint64_t data = BVAL(r.out.data.data, i);
2214 torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2215 talloc_asprintf(torture, "read data "
2216 "pattern bad at %llu\n",
2217 (unsigned long long)off + i));
2219 talloc_free(r.out.data.data);
2220 len -= io_sz;
2221 off += io_sz;
2224 return true;
2227 static bool test_setup_open(struct torture_context *torture,
2228 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2229 const char *fname,
2230 struct smb2_handle *fh,
2231 uint32_t desired_access,
2232 uint32_t file_attributes)
2234 struct smb2_create io;
2235 NTSTATUS status;
2237 ZERO_STRUCT(io);
2238 io.in.desired_access = desired_access;
2239 io.in.file_attributes = file_attributes;
2240 io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2241 io.in.share_access =
2242 NTCREATEX_SHARE_ACCESS_DELETE|
2243 NTCREATEX_SHARE_ACCESS_READ|
2244 NTCREATEX_SHARE_ACCESS_WRITE;
2245 if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2246 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2248 io.in.fname = fname;
2250 status = smb2_create(tree, mem_ctx, &io);
2251 torture_assert_ntstatus_ok(torture, status, "file create");
2253 *fh = io.out.file.handle;
2255 return true;
2258 static bool test_setup_create_fill(struct torture_context *torture,
2259 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2260 const char *fname,
2261 struct smb2_handle *fh,
2262 uint64_t size,
2263 uint32_t desired_access,
2264 uint32_t file_attributes)
2266 bool ok;
2268 ok = test_setup_open(torture, tree, mem_ctx,
2269 fname,
2271 desired_access,
2272 file_attributes);
2273 torture_assert(torture, ok, "file open");
2275 if (size > 0) {
2276 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2277 torture_assert(torture, ok, "write pattern");
2279 return true;
2282 static bool test_setup_copy_chunk(struct torture_context *torture,
2283 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2284 uint32_t nchunks,
2285 struct smb2_handle *src_h,
2286 uint64_t src_size,
2287 uint32_t src_desired_access,
2288 struct smb2_handle *dest_h,
2289 uint64_t dest_size,
2290 uint32_t dest_desired_access,
2291 struct srv_copychunk_copy *cc_copy,
2292 union smb_ioctl *io)
2294 struct req_resume_key_rsp res_key;
2295 bool ok;
2296 NTSTATUS status;
2297 enum ndr_err_code ndr_ret;
2299 ok = test_setup_create_fill(torture, tree, mem_ctx, FNAME_CC_SRC,
2300 src_h, src_size, src_desired_access,
2301 FILE_ATTRIBUTE_NORMAL);
2302 torture_assert(torture, ok, "src file create fill");
2304 ok = test_setup_create_fill(torture, tree, mem_ctx, FNAME_CC_DST,
2305 dest_h, dest_size, dest_desired_access,
2306 FILE_ATTRIBUTE_NORMAL);
2307 torture_assert(torture, ok, "dest file create fill");
2309 ZERO_STRUCTPN(io);
2310 io->smb2.level = RAW_IOCTL_SMB2;
2311 io->smb2.in.file.handle = *src_h;
2312 io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2313 /* Allow for Key + ContextLength + Context */
2314 io->smb2.in.max_response_size = 32;
2315 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2317 status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2318 torture_assert_ntstatus_ok(torture, status,
2319 "FSCTL_SRV_REQUEST_RESUME_KEY");
2321 ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2322 (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2324 torture_assert_ndr_success(torture, ndr_ret,
2325 "ndr_pull_req_resume_key_rsp");
2327 ZERO_STRUCTPN(io);
2328 io->smb2.level = RAW_IOCTL_SMB2;
2329 io->smb2.in.file.handle = *dest_h;
2330 io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2331 io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2332 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2334 ZERO_STRUCTPN(cc_copy);
2335 memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2336 cc_copy->chunk_count = nchunks;
2337 cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2338 torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2340 return true;
2344 static bool check_copy_chunk_rsp(struct torture_context *torture,
2345 struct srv_copychunk_rsp *cc_rsp,
2346 uint32_t ex_chunks_written,
2347 uint32_t ex_chunk_bytes_written,
2348 uint32_t ex_total_bytes_written)
2350 torture_assert_int_equal(torture, cc_rsp->chunks_written,
2351 ex_chunks_written, "num chunks");
2352 torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2353 ex_chunk_bytes_written, "chunk bytes written");
2354 torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2355 ex_total_bytes_written, "chunk total bytes");
2356 return true;
2359 static bool neg_aapl_copyfile(struct torture_context *tctx,
2360 struct smb2_tree *tree,
2361 uint64_t flags)
2363 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2364 const char *fname = "aapl";
2365 NTSTATUS status;
2366 struct smb2_create io;
2367 DATA_BLOB data;
2368 struct smb2_create_blob *aapl = NULL;
2369 uint32_t aapl_cmd;
2370 uint32_t aapl_reply_bitmap;
2371 uint32_t aapl_server_caps;
2372 bool ret = true;
2374 ZERO_STRUCT(io);
2375 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2376 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2377 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2378 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2379 NTCREATEX_SHARE_ACCESS_READ |
2380 NTCREATEX_SHARE_ACCESS_WRITE);
2381 io.in.fname = fname;
2383 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2384 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2385 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2386 SBVAL(data.data, 16, flags);
2388 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2389 CHECK_STATUS(status, NT_STATUS_OK);
2391 status = smb2_create(tree, tctx, &io);
2392 CHECK_STATUS(status, NT_STATUS_OK);
2394 aapl = smb2_create_blob_find(&io.out.blobs,
2395 SMB2_CREATE_TAG_AAPL);
2396 if (aapl == NULL) {
2397 ret = false;
2398 goto done;
2401 if (aapl->data.length < 24) {
2402 ret = false;
2403 goto done;
2406 aapl_cmd = IVAL(aapl->data.data, 0);
2407 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2408 torture_result(tctx, TORTURE_FAIL,
2409 "(%s) unexpected cmd: %d",
2410 __location__, (int)aapl_cmd);
2411 ret = false;
2412 goto done;
2415 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2416 if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2417 torture_result(tctx, TORTURE_FAIL,
2418 "(%s) unexpected reply_bitmap: %d",
2419 __location__, (int)aapl_reply_bitmap);
2420 ret = false;
2421 goto done;
2424 aapl_server_caps = BVAL(aapl->data.data, 16);
2425 if (!(aapl_server_caps & flags)) {
2426 torture_result(tctx, TORTURE_FAIL,
2427 "(%s) unexpected server_caps: %d",
2428 __location__, (int)aapl_server_caps);
2429 ret = false;
2430 goto done;
2433 done:
2434 status = smb2_util_close(tree, io.out.file.handle);
2435 CHECK_STATUS(status, NT_STATUS_OK);
2437 smb2_util_unlink(tree, "aapl");
2438 talloc_free(mem_ctx);
2439 return ret;
2442 static bool test_copyfile(struct torture_context *torture,
2443 struct smb2_tree *tree)
2445 struct smb2_handle src_h;
2446 struct smb2_handle dest_h;
2447 NTSTATUS status;
2448 union smb_ioctl io;
2449 TALLOC_CTX *tmp_ctx = talloc_new(tree);
2450 struct srv_copychunk_copy cc_copy;
2451 struct srv_copychunk_rsp cc_rsp;
2452 enum ndr_err_code ndr_ret;
2453 bool ok;
2456 * First test a copy_chunk with a 0 chunk count without having
2457 * enabled this via AAPL. The request must not fail and the
2458 * copied length in the response must be 0. This is verified
2459 * against Windows 2008r2.
2462 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2463 0, /* 0 chunks, copyfile semantics */
2464 &src_h, 4096, /* fill 4096 byte src file */
2465 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2466 &dest_h, 0, /* 0 byte dest file */
2467 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2468 &cc_copy,
2469 &io);
2470 if (!ok) {
2471 torture_fail_goto(torture, done, "setup copy chunk error");
2474 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2475 &cc_copy,
2476 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2477 torture_assert_ndr_success(torture, ndr_ret,
2478 "ndr_push_srv_copychunk_copy");
2480 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2481 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2483 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2484 &cc_rsp,
2485 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2486 torture_assert_ndr_success(torture, ndr_ret,
2487 "ndr_pull_srv_copychunk_rsp");
2489 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2490 0, /* chunks written */
2491 0, /* chunk bytes unsuccessfully written */
2492 0); /* total bytes written */
2493 if (!ok) {
2494 torture_fail_goto(torture, done, "bad copy chunk response data");
2498 * Now enable AAPL copyfile and test again, the file and the
2499 * stream must be copied by the server.
2501 ok = neg_aapl_copyfile(torture, tree,
2502 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2503 if (!ok) {
2504 torture_skip_goto(torture, done, "missing AAPL copyfile");
2505 goto done;
2508 smb2_util_close(tree, src_h);
2509 smb2_util_close(tree, dest_h);
2510 smb2_util_unlink(tree, FNAME_CC_SRC);
2511 smb2_util_unlink(tree, FNAME_CC_DST);
2513 ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2514 if (!ok) {
2515 torture_fail(torture, "setup file error");
2517 ok = write_stream(tree, __location__, torture, tmp_ctx,
2518 FNAME_CC_SRC, AFPRESOURCE_STREAM,
2519 10, 10, "1234567890");
2520 if (!ok) {
2521 torture_fail(torture, "setup stream error");
2524 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2525 0, /* 0 chunks, copyfile semantics */
2526 &src_h, 4096, /* fill 4096 byte src file */
2527 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2528 &dest_h, 0, /* 0 byte dest file */
2529 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2530 &cc_copy,
2531 &io);
2532 if (!ok) {
2533 torture_fail_goto(torture, done, "setup copy chunk error");
2536 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2537 &cc_copy,
2538 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2539 torture_assert_ndr_success(torture, ndr_ret,
2540 "ndr_push_srv_copychunk_copy");
2542 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2543 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2545 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2546 &cc_rsp,
2547 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2548 torture_assert_ndr_success(torture, ndr_ret,
2549 "ndr_pull_srv_copychunk_rsp");
2551 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2552 0, /* chunks written */
2553 0, /* chunk bytes unsuccessfully written */
2554 4096); /* total bytes written */
2555 if (!ok) {
2556 torture_fail_goto(torture, done, "bad copy chunk response data");
2559 ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
2560 SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
2561 if (!ok) {
2562 torture_fail_goto(torture, done,"open failed");
2564 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
2565 if (!ok) {
2566 torture_fail_goto(torture, done, "inconsistent file data");
2569 ok = check_stream(tree, __location__, torture, tmp_ctx,
2570 FNAME_CC_DST, AFPRESOURCE_STREAM,
2571 0, 20, 10, 10, "1234567890");
2572 if (!ok) {
2573 torture_fail_goto(torture, done, "inconsistent stream data");
2576 done:
2577 smb2_util_close(tree, src_h);
2578 smb2_util_close(tree, dest_h);
2579 smb2_util_unlink(tree, FNAME_CC_SRC);
2580 smb2_util_unlink(tree, FNAME_CC_DST);
2581 talloc_free(tmp_ctx);
2582 return true;
2585 static bool check_stream_list(struct smb2_tree *tree,
2586 struct torture_context *tctx,
2587 const char *fname,
2588 int num_exp,
2589 const char **exp,
2590 bool is_dir)
2592 bool ret = true;
2593 union smb_fileinfo finfo;
2594 NTSTATUS status;
2595 int i;
2596 TALLOC_CTX *tmp_ctx = talloc_new(tctx);
2597 char **exp_sort;
2598 struct stream_struct *stream_sort;
2599 struct smb2_create create;
2600 struct smb2_handle h;
2602 ZERO_STRUCT(h);
2603 torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
2605 ZERO_STRUCT(create);
2606 create.in.fname = fname;
2607 create.in.create_disposition = NTCREATEX_DISP_OPEN;
2608 create.in.desired_access = SEC_FILE_ALL;
2609 create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
2610 create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
2611 status = smb2_create(tree, tmp_ctx, &create);
2612 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2613 h = create.out.file.handle;
2615 finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
2616 finfo.generic.in.file.handle = h;
2618 status = smb2_getinfo_file(tree, tctx, &finfo);
2619 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
2621 smb2_util_close(tree, h);
2623 torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
2624 ret, done, "stream count");
2626 if (num_exp == 0) {
2627 TALLOC_FREE(tmp_ctx);
2628 goto done;
2631 exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
2632 torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
2634 TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
2636 stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
2637 finfo.stream_info.out.num_streams *
2638 sizeof(*stream_sort));
2639 torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
2641 TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
2643 for (i=0; i<num_exp; i++) {
2644 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
2645 i, exp_sort[i], stream_sort[i].stream_name.s);
2646 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
2647 ret, done, "stream name");
2650 done:
2651 TALLOC_FREE(tmp_ctx);
2652 return ret;
2656 test stream names
2658 static bool test_stream_names(struct torture_context *tctx,
2659 struct smb2_tree *tree)
2661 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2662 NTSTATUS status;
2663 struct smb2_create create;
2664 struct smb2_handle h;
2665 const char *fname = BASEDIR "\\stream_names.txt";
2666 const char *sname1;
2667 bool ret;
2668 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
2669 const char *streams[] = {
2670 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2671 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
2672 "::$DATA"
2674 const char *localdir = NULL;
2676 localdir = torture_setting_string(tctx, "localdir", NULL);
2677 if (localdir == NULL) {
2678 torture_skip(tctx, "Need localdir for test");
2681 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
2683 /* clean slate ...*/
2684 smb2_util_unlink(tree, fname);
2685 smb2_deltree(tree, fname);
2686 smb2_deltree(tree, BASEDIR);
2688 status = torture_smb2_testdir(tree, BASEDIR, &h);
2689 CHECK_STATUS(status, NT_STATUS_OK);
2690 smb2_util_close(tree, h);
2692 torture_comment(tctx, "(%s) testing stream names\n", __location__);
2693 ZERO_STRUCT(create);
2694 create.in.desired_access = SEC_FILE_WRITE_DATA;
2695 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2696 create.in.share_access =
2697 NTCREATEX_SHARE_ACCESS_DELETE|
2698 NTCREATEX_SHARE_ACCESS_READ|
2699 NTCREATEX_SHARE_ACCESS_WRITE;
2700 create.in.create_disposition = NTCREATEX_DISP_CREATE;
2701 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2702 create.in.fname = sname1;
2704 status = smb2_create(tree, mem_ctx, &create);
2705 CHECK_STATUS(status, NT_STATUS_OK);
2706 smb2_util_close(tree, create.out.file.handle);
2708 ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
2709 "user.DosStream.bar:baz:$DATA",
2710 "data", strlen("data"));
2711 CHECK_VALUE(ret, true);
2713 ret = check_stream_list(tree, tctx, fname, 3, streams, false);
2714 CHECK_VALUE(ret, true);
2716 done:
2717 status = smb2_util_unlink(tree, fname);
2718 smb2_deltree(tree, BASEDIR);
2719 talloc_free(mem_ctx);
2721 return ret;
2724 /* Renaming a directory with open file, should work for OS X AAPL clients */
2725 static bool test_rename_dir_openfile(struct torture_context *torture,
2726 struct smb2_tree *tree)
2728 bool ret = true;
2729 NTSTATUS status;
2730 union smb_open io;
2731 union smb_close cl;
2732 union smb_setfileinfo sinfo;
2733 struct smb2_handle d1, h1;
2734 const char *renamedir = BASEDIR "-new";
2735 bool server_is_osx = torture_setting_bool(torture, "osx", false);
2737 smb2_deltree(tree, BASEDIR);
2738 smb2_util_rmdir(tree, BASEDIR);
2739 smb2_deltree(tree, renamedir);
2741 ZERO_STRUCT(io.smb2);
2742 io.generic.level = RAW_OPEN_SMB2;
2743 io.smb2.in.create_flags = 0;
2744 io.smb2.in.desired_access = 0x0017019f;
2745 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2746 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2747 io.smb2.in.share_access = 0;
2748 io.smb2.in.alloc_size = 0;
2749 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2750 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2751 io.smb2.in.security_flags = 0;
2752 io.smb2.in.fname = BASEDIR;
2754 status = smb2_create(tree, torture, &(io.smb2));
2755 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2756 d1 = io.smb2.out.file.handle;
2758 ZERO_STRUCT(io.smb2);
2759 io.generic.level = RAW_OPEN_SMB2;
2760 io.smb2.in.create_flags = 0;
2761 io.smb2.in.desired_access = 0x0017019f;
2762 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2763 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2764 io.smb2.in.share_access = 0;
2765 io.smb2.in.alloc_size = 0;
2766 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2767 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2768 io.smb2.in.security_flags = 0;
2769 io.smb2.in.fname = BASEDIR "\\file.txt";
2771 status = smb2_create(tree, torture, &(io.smb2));
2772 torture_assert_ntstatus_ok(torture, status, "smb2_create file");
2773 h1 = io.smb2.out.file.handle;
2775 if (!server_is_osx) {
2776 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
2778 ZERO_STRUCT(sinfo);
2779 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2780 sinfo.rename_information.in.file.handle = d1;
2781 sinfo.rename_information.in.overwrite = 0;
2782 sinfo.rename_information.in.root_fid = 0;
2783 sinfo.rename_information.in.new_name = renamedir;
2784 status = smb2_setinfo_file(tree, &sinfo);
2786 torture_assert_ntstatus_equal(torture, status,
2787 NT_STATUS_ACCESS_DENIED,
2788 "smb2_setinfo_file");
2790 ZERO_STRUCT(cl.smb2);
2791 cl.smb2.level = RAW_CLOSE_SMB2;
2792 cl.smb2.in.file.handle = d1;
2793 status = smb2_close(tree, &(cl.smb2));
2794 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2795 ZERO_STRUCT(d1);
2798 torture_comment(torture, "Enabling AAPL\n");
2800 ret = enable_aapl(torture, tree);
2801 torture_assert(torture, ret == true, "enable_aapl failed");
2803 torture_comment(torture, "Renaming directory with AAPL\n");
2805 ZERO_STRUCT(io.smb2);
2806 io.generic.level = RAW_OPEN_SMB2;
2807 io.smb2.in.desired_access = 0x0017019f;
2808 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2809 io.smb2.in.share_access = 0;
2810 io.smb2.in.alloc_size = 0;
2811 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
2812 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2813 io.smb2.in.security_flags = 0;
2814 io.smb2.in.fname = BASEDIR;
2816 status = smb2_create(tree, torture, &(io.smb2));
2817 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2818 d1 = io.smb2.out.file.handle;
2820 ZERO_STRUCT(sinfo);
2821 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2822 sinfo.rename_information.in.file.handle = d1;
2823 sinfo.rename_information.in.overwrite = 0;
2824 sinfo.rename_information.in.root_fid = 0;
2825 sinfo.rename_information.in.new_name = renamedir;
2827 status = smb2_setinfo_file(tree, &sinfo);
2828 torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
2830 ZERO_STRUCT(cl.smb2);
2831 cl.smb2.level = RAW_CLOSE_SMB2;
2832 cl.smb2.in.file.handle = d1;
2833 status = smb2_close(tree, &(cl.smb2));
2834 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2835 ZERO_STRUCT(d1);
2837 cl.smb2.in.file.handle = h1;
2838 status = smb2_close(tree, &(cl.smb2));
2839 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2840 ZERO_STRUCT(h1);
2842 torture_comment(torture, "Cleaning up\n");
2844 if (h1.data[0] || h1.data[1]) {
2845 ZERO_STRUCT(cl.smb2);
2846 cl.smb2.level = RAW_CLOSE_SMB2;
2847 cl.smb2.in.file.handle = h1;
2848 status = smb2_close(tree, &(cl.smb2));
2851 smb2_util_unlink(tree, BASEDIR "\\file.txt");
2852 smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
2853 smb2_deltree(tree, renamedir);
2854 smb2_deltree(tree, BASEDIR);
2855 return ret;
2858 static bool test_afpinfo_enoent(struct torture_context *tctx,
2859 struct smb2_tree *tree)
2861 bool ret = true;
2862 NTSTATUS status;
2863 struct smb2_create create;
2864 struct smb2_handle h1;
2865 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2866 const char *fname = BASEDIR "\\file";
2867 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
2869 torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
2871 smb2_deltree(tree, BASEDIR);
2872 status = torture_smb2_testdir(tree, BASEDIR, &h1);
2873 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
2874 smb2_util_close(tree, h1);
2875 ret = torture_setup_file(mem_ctx, tree, fname, false);
2876 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
2878 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
2880 ZERO_STRUCT(create);
2881 create.in.create_disposition = NTCREATEX_DISP_OPEN;
2882 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
2883 create.in.fname = sname;
2885 status = smb2_create(tree, mem_ctx, &create);
2886 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
2887 ret, done, "Got unexpected AFP_AfpInfo stream");
2889 done:
2890 smb2_util_unlink(tree, fname);
2891 smb2_util_rmdir(tree, BASEDIR);
2892 return ret;
2895 static bool test_create_delete_on_close(struct torture_context *tctx,
2896 struct smb2_tree *tree)
2898 bool ret = true;
2899 NTSTATUS status;
2900 struct smb2_create create;
2901 struct smb2_handle h1;
2902 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2903 const char *fname = BASEDIR "\\file";
2904 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
2905 const char *type_creator = "SMB,OLE!";
2906 AfpInfo *info = NULL;
2907 const char *streams_basic[] = {
2908 "::$DATA"
2910 const char *streams_afpinfo[] = {
2911 "::$DATA",
2912 AFPINFO_STREAM
2915 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
2917 torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
2919 smb2_deltree(tree, BASEDIR);
2920 status = torture_smb2_testdir(tree, BASEDIR, &h1);
2921 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
2922 smb2_util_close(tree, h1);
2923 ret = torture_setup_file(mem_ctx, tree, fname, false);
2924 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
2926 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
2928 ZERO_STRUCT(create);
2929 create.in.create_disposition = NTCREATEX_DISP_OPEN;
2930 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
2931 create.in.fname = sname;
2933 status = smb2_create(tree, mem_ctx, &create);
2934 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
2935 ret, done, "Got unexpected AFP_AfpInfo stream");
2937 ZERO_STRUCT(create);
2938 create.in.create_disposition = NTCREATEX_DISP_OPEN;
2939 create.in.desired_access = SEC_FILE_ALL;
2940 create.in.fname = sname;
2942 status = smb2_create(tree, mem_ctx, &create);
2943 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
2944 ret, done, "Got unexpected AFP_AfpInfo stream");
2946 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
2947 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
2949 torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
2951 info = torture_afpinfo_new(mem_ctx);
2952 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
2954 memcpy(info->afpi_FinderInfo, type_creator, 8);
2955 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2956 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
2958 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
2959 0, 60, 16, 8, type_creator);
2960 torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
2962 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
2963 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
2965 ZERO_STRUCT(create);
2966 create.in.create_disposition = NTCREATEX_DISP_OPEN;
2967 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
2968 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
2969 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
2970 create.in.fname = sname;
2971 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2973 status = smb2_create(tree, mem_ctx, &create);
2974 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
2976 h1 = create.out.file.handle;
2977 smb2_util_close(tree, h1);
2979 ZERO_STRUCT(create);
2980 create.in.create_disposition = NTCREATEX_DISP_OPEN;
2981 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
2982 create.in.fname = sname;
2983 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2984 status = smb2_create(tree, mem_ctx, &create);
2985 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
2986 ret, done, "Got unexpected AFP_AfpInfo stream");
2988 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
2989 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
2991 done:
2992 smb2_util_unlink(tree, fname);
2993 smb2_util_rmdir(tree, BASEDIR);
2994 return ret;
2997 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
2998 struct smb2_tree *tree)
3000 bool ret = true;
3001 NTSTATUS status;
3002 struct smb2_create create;
3003 union smb_setfileinfo sfinfo;
3004 struct smb2_handle h1;
3005 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3006 const char *fname = BASEDIR "\\file";
3007 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3008 const char *type_creator = "SMB,OLE!";
3009 AfpInfo *info = NULL;
3010 const char *streams_basic[] = {
3011 "::$DATA"
3014 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3016 torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
3018 smb2_deltree(tree, BASEDIR);
3019 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3020 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3021 smb2_util_close(tree, h1);
3022 ret = torture_setup_file(mem_ctx, tree, fname, false);
3023 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3025 info = torture_afpinfo_new(mem_ctx);
3026 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3027 memcpy(info->afpi_FinderInfo, type_creator, 8);
3028 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3029 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3031 ZERO_STRUCT(create);
3032 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3033 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3034 create.in.fname = sname;
3035 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3036 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3038 status = smb2_create(tree, mem_ctx, &create);
3039 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3041 h1 = create.out.file.handle;
3043 /* Delete stream via setinfo delete-on-close */
3044 ZERO_STRUCT(sfinfo);
3045 sfinfo.disposition_info.in.delete_on_close = 1;
3046 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3047 sfinfo.generic.in.file.handle = h1;
3048 status = smb2_setinfo_file(tree, &sfinfo);
3049 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3051 smb2_util_close(tree, h1);
3053 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3054 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3056 ZERO_STRUCT(create);
3057 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3058 create.in.desired_access = SEC_FILE_ALL;
3059 create.in.fname = sname;
3060 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3061 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3062 status = smb2_create(tree, mem_ctx, &create);
3063 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3064 ret, done, "Got unexpected AFP_AfpInfo stream");
3066 done:
3067 smb2_util_unlink(tree, fname);
3068 smb2_util_rmdir(tree, BASEDIR);
3069 return ret;
3072 static bool test_setinfo_eof(struct torture_context *tctx,
3073 struct smb2_tree *tree)
3075 bool ret = true;
3076 NTSTATUS status;
3077 struct smb2_create create;
3078 union smb_setfileinfo sfinfo;
3079 struct smb2_handle h1;
3080 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3081 const char *fname = BASEDIR "\\file";
3082 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3083 const char *type_creator = "SMB,OLE!";
3084 AfpInfo *info = NULL;
3085 const char *streams_afpinfo[] = {
3086 "::$DATA",
3087 AFPINFO_STREAM
3090 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3092 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
3094 smb2_deltree(tree, BASEDIR);
3095 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3096 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3097 smb2_util_close(tree, h1);
3098 ret = torture_setup_file(mem_ctx, tree, fname, false);
3099 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3101 info = torture_afpinfo_new(mem_ctx);
3102 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3103 memcpy(info->afpi_FinderInfo, type_creator, 8);
3104 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3105 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3107 ZERO_STRUCT(create);
3108 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3109 create.in.desired_access = SEC_FILE_ALL;
3110 create.in.fname = sname;
3111 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3112 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3114 status = smb2_create(tree, mem_ctx, &create);
3115 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3117 h1 = create.out.file.handle;
3119 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
3121 /* Test setinfo end-of-file info */
3122 ZERO_STRUCT(sfinfo);
3123 sfinfo.generic.in.file.handle = h1;
3124 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3125 sfinfo.position_information.in.position = 61;
3126 status = smb2_setinfo_file(tree, &sfinfo);
3127 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
3128 ret, done, "set eof 61 failed");
3130 torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
3132 /* Truncation returns success, but has no effect */
3133 ZERO_STRUCT(sfinfo);
3134 sfinfo.generic.in.file.handle = h1;
3135 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3136 sfinfo.position_information.in.position = 1;
3137 status = smb2_setinfo_file(tree, &sfinfo);
3138 torture_assert_ntstatus_ok_goto(tctx, status,
3139 ret, done, "set eof 1 failed");
3140 smb2_util_close(tree, h1);
3142 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3143 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3145 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3146 0, 60, 16, 8, type_creator);
3147 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3149 ZERO_STRUCT(create);
3150 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3151 create.in.desired_access = SEC_FILE_ALL;
3152 create.in.fname = sname;
3153 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3154 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3156 status = smb2_create(tree, mem_ctx, &create);
3157 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3159 h1 = create.out.file.handle;
3162 * Delete stream via setinfo end-of-file info to 0, should
3163 * return success but stream MUST NOT deleted
3165 ZERO_STRUCT(sfinfo);
3166 sfinfo.generic.in.file.handle = h1;
3167 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3168 sfinfo.position_information.in.position = 0;
3169 status = smb2_setinfo_file(tree, &sfinfo);
3170 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3172 smb2_util_close(tree, h1);
3174 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3175 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3177 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3178 0, 60, 16, 8, type_creator);
3179 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3181 done:
3182 smb2_util_unlink(tree, fname);
3183 smb2_util_rmdir(tree, BASEDIR);
3184 return ret;
3187 static bool test_afpinfo_all0(struct torture_context *tctx,
3188 struct smb2_tree *tree)
3190 bool ret = true;
3191 NTSTATUS status;
3192 struct smb2_handle h1;
3193 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3194 const char *fname = BASEDIR "\\file";
3195 const char *type_creator = "SMB,OLE!";
3196 AfpInfo *info = NULL;
3197 const char *streams_basic[] = {
3198 "::$DATA"
3200 const char *streams_afpinfo[] = {
3201 "::$DATA",
3202 AFPINFO_STREAM
3205 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3207 torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
3209 smb2_deltree(tree, BASEDIR);
3210 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3211 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3212 smb2_util_close(tree, h1);
3213 ret = torture_setup_file(mem_ctx, tree, fname, false);
3214 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3216 info = torture_afpinfo_new(mem_ctx);
3217 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3218 memcpy(info->afpi_FinderInfo, type_creator, 8);
3219 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3220 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3222 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3223 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3225 /* Write all 0 to AFP_AfpInfo */
3226 memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
3227 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3228 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3230 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3231 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3233 done:
3234 smb2_util_unlink(tree, fname);
3235 smb2_util_rmdir(tree, BASEDIR);
3236 return ret;
3239 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
3240 struct smb2_tree *tree)
3242 bool ret = true;
3243 NTSTATUS status;
3244 struct smb2_create create;
3245 struct smb2_handle h1;
3246 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3247 const char *fname = BASEDIR "\\file";
3248 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3249 const char *streams_basic[] = {
3250 "::$DATA"
3252 const char *streams_afpresource[] = {
3253 "::$DATA",
3254 AFPRESOURCE_STREAM
3257 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3259 torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
3261 smb2_deltree(tree, BASEDIR);
3262 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3263 torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
3264 smb2_util_close(tree, h1);
3265 ret = torture_setup_file(mem_ctx, tree, fname, false);
3266 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3268 torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
3270 ZERO_STRUCT(create);
3271 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3272 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3273 create.in.fname = sname;
3275 status = smb2_create(tree, mem_ctx, &create);
3276 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3277 ret, done, "Got unexpected AFP_AfpResource stream");
3279 ZERO_STRUCT(create);
3280 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3281 create.in.desired_access = SEC_FILE_ALL;
3282 create.in.fname = sname;
3284 status = smb2_create(tree, mem_ctx, &create);
3285 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3286 ret, done, "Got unexpected AFP_AfpResource stream");
3288 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3289 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3291 torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
3293 ret = write_stream(tree, __location__, tctx, mem_ctx,
3294 fname, AFPRESOURCE_STREAM_NAME,
3295 0, 10, "1234567890");
3296 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3298 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3299 0, 10, 0, 10, "1234567890");
3300 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3302 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3303 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3305 ZERO_STRUCT(create);
3306 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3307 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3308 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3309 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3310 create.in.fname = sname;
3311 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3313 status = smb2_create(tree, mem_ctx, &create);
3314 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3316 h1 = create.out.file.handle;
3317 smb2_util_close(tree, h1);
3319 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3320 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3322 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3323 0, 10, 0, 10, "1234567890");
3324 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3326 done:
3327 smb2_util_unlink(tree, fname);
3328 smb2_util_rmdir(tree, BASEDIR);
3329 return ret;
3332 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
3333 struct smb2_tree *tree)
3335 bool ret = true;
3336 NTSTATUS status;
3337 struct smb2_create create;
3338 union smb_setfileinfo sfinfo;
3339 struct smb2_handle h1;
3340 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3341 const char *fname = BASEDIR "\\file";
3342 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3343 const char *streams_afpresource[] = {
3344 "::$DATA",
3345 AFPRESOURCE_STREAM
3348 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3350 torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
3352 smb2_deltree(tree, BASEDIR);
3353 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3354 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3355 smb2_util_close(tree, h1);
3356 ret = torture_setup_file(mem_ctx, tree, fname, false);
3357 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3359 ret = write_stream(tree, __location__, tctx, mem_ctx,
3360 fname, AFPRESOURCE_STREAM_NAME,
3361 10, 10, "1234567890");
3362 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3364 ZERO_STRUCT(create);
3365 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3366 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3367 create.in.fname = sname;
3368 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3369 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3371 status = smb2_create(tree, mem_ctx, &create);
3372 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3374 h1 = create.out.file.handle;
3376 /* Try to delete stream via setinfo delete-on-close */
3377 ZERO_STRUCT(sfinfo);
3378 sfinfo.disposition_info.in.delete_on_close = 1;
3379 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3380 sfinfo.generic.in.file.handle = h1;
3381 status = smb2_setinfo_file(tree, &sfinfo);
3382 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3384 smb2_util_close(tree, h1);
3386 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3387 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3389 ZERO_STRUCT(create);
3390 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3391 create.in.desired_access = SEC_FILE_ALL;
3392 create.in.fname = sname;
3393 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3394 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3395 status = smb2_create(tree, mem_ctx, &create);
3396 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3397 "Got unexpected AFP_AfpResource stream");
3399 done:
3400 smb2_util_unlink(tree, fname);
3401 smb2_util_rmdir(tree, BASEDIR);
3402 return ret;
3405 static bool test_setinfo_eof_resource(struct torture_context *tctx,
3406 struct smb2_tree *tree)
3408 bool ret = true;
3409 NTSTATUS status;
3410 struct smb2_create create;
3411 union smb_setfileinfo sfinfo;
3412 union smb_fileinfo finfo;
3413 struct smb2_handle h1;
3414 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3415 const char *fname = BASEDIR "\\file";
3416 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3417 const char *streams_basic[] = {
3418 "::$DATA"
3421 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3423 torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
3425 smb2_deltree(tree, BASEDIR);
3426 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3427 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3428 smb2_util_close(tree, h1);
3429 ret = torture_setup_file(mem_ctx, tree, fname, false);
3430 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3432 ret = write_stream(tree, __location__, tctx, mem_ctx,
3433 fname, AFPRESOURCE_STREAM_NAME,
3434 10, 10, "1234567890");
3435 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3437 ZERO_STRUCT(create);
3438 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3439 create.in.desired_access = SEC_FILE_ALL;
3440 create.in.fname = sname;
3441 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3442 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3444 status = smb2_create(tree, mem_ctx, &create);
3445 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3447 h1 = create.out.file.handle;
3449 torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
3451 /* Test setinfo end-of-file info */
3452 ZERO_STRUCT(sfinfo);
3453 sfinfo.generic.in.file.handle = h1;
3454 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3455 sfinfo.position_information.in.position = 1;
3456 status = smb2_setinfo_file(tree, &sfinfo);
3457 torture_assert_ntstatus_ok_goto(tctx, status,
3458 ret, done, "set eof 1 failed");
3460 smb2_util_close(tree, h1);
3462 /* Check size == 1 */
3463 ZERO_STRUCT(create);
3464 create.in.fname = sname;
3465 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3466 create.in.desired_access = SEC_FILE_ALL;
3467 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3468 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3469 status = smb2_create(tree, mem_ctx, &create);
3470 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3472 h1 = create.out.file.handle;
3474 ZERO_STRUCT(finfo);
3475 finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
3476 finfo.generic.in.file.handle = h1;
3477 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
3478 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
3480 smb2_util_close(tree, h1);
3482 torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
3484 ZERO_STRUCT(create);
3485 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3486 create.in.desired_access = SEC_FILE_ALL;
3487 create.in.fname = sname;
3488 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3489 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3491 status = smb2_create(tree, mem_ctx, &create);
3492 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3494 h1 = create.out.file.handle;
3497 * Delete stream via setinfo end-of-file info to 0, this
3498 * should delete the stream.
3500 ZERO_STRUCT(sfinfo);
3501 sfinfo.generic.in.file.handle = h1;
3502 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3503 sfinfo.position_information.in.position = 0;
3504 status = smb2_setinfo_file(tree, &sfinfo);
3505 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3507 smb2_util_close(tree, h1);
3509 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3510 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3512 ZERO_STRUCT(create);
3513 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3514 create.in.desired_access = SEC_FILE_ALL;
3515 create.in.fname = sname;
3516 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3517 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3519 status = smb2_create(tree, mem_ctx, &create);
3520 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3521 ret, done, "smb2_create failed");
3523 done:
3524 smb2_util_unlink(tree, fname);
3525 smb2_util_rmdir(tree, BASEDIR);
3526 return ret;
3530 * Note: This test depends on "vfs objects = catia fruit streams_xattr". For
3531 * some tests torture must be run on the host it tests and takes an additional
3532 * argument with the local path to the share:
3533 * "--option=torture:localdir=<SHAREPATH>".
3535 * When running against an OS X SMB server add "--option=torture:osx=true"
3537 struct torture_suite *torture_vfs_fruit(void)
3539 struct torture_suite *suite = torture_suite_create(
3540 talloc_autofree_context(), "fruit");
3542 suite->description = talloc_strdup(suite, "vfs_fruit tests");
3544 torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
3545 torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
3546 torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
3547 torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
3548 torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
3549 torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
3550 torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
3551 torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
3552 torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
3553 torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
3554 torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
3555 torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
3556 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
3557 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
3558 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
3559 torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
3560 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
3561 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
3562 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
3564 return suite;