s4/torture: let write_stream() deal with stream=NULL
[Samba.git] / source4 / torture / vfs / fruit.c
blob471a755a40d3f75f7509224be869c3060812aacf
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 : 54455354 : TEST
241 Creator : 534C4F57 : SLOW
242 isAlias : 0
243 Invisible : 0
244 hasBundle : 0
245 nameLocked : 0
246 Stationery : 0
247 CustomIcon : 0
248 Reserved : 0
249 Inited : 0
250 NoINITS : 0
251 Shared : 0
252 SwitchLaunc: 0
253 Hidden Ext : 0
254 color : 100 : blue
255 isOnDesk : 0
256 Location v : 0000 : 0
257 Location h : 0000 : 0
258 Fldr : 0000 : ..
260 -FXInfo----:
261 Rsvd|IconID: 0000 : 0
262 Rsvd : 0000 : ..
263 Rsvd : 0000 : ..
264 Rsvd : 0000 : ..
265 AreInvalid : 0
266 unknown bit: 0
267 unknown bit: 0
268 unknown bit: 0
269 unknown bit: 0
270 unknown bit: 0
271 unknown bit: 0
272 CustomBadge: 0
273 ObjctIsBusy: 0
274 unknown bit: 0
275 unknown bit: 0
276 unknown bit: 0
277 unknown bit: 0
278 RoutingInfo: 0
279 unknown bit: 0
280 unknown bit: 0
281 Rsvd|commnt: 0000 : 0
282 PutAway : 00000000 : 0
284 -EA--------:
285 pad : 0000 : ..
286 magic : 41545452 : ATTR
287 debug_tag : 53D4580C : 1406425100
288 total_size : 00000EE2 : 3810
289 data_start : 000000BC : 188
290 data_length: 0000005E : 94
291 reserved[0]: 00000000 : ....
292 reserved[1]: 00000000 : ....
293 reserved[2]: 00000000 : ....
294 flags : 0000 : ..
295 num_attrs : 0002 : 2
296 -EA ENTRY--:
297 offset : 000000BC : 188
298 length : 0000005B : 91
299 flags : 0000 : ..
300 namelen : 24 : 36
301 -EA NAME---: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
302 00000000 : 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 61 : com.apple.metada
303 00000010 : 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 54 : ta:_kMDItemUserT
304 00000020 : 61 67 73 00 : ags.
305 -EA VALUE--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
306 00000000 : 62 70 6C 69 73 74 30 30 A5 01 02 03 04 05 54 74 : bplist00......Tt
307 00000010 : 65 73 74 66 00 47 00 72 00 FC 00 6E 00 0A 00 32 : estf.G.r...n...2
308 00000020 : 56 4C 69 6C 61 0A 33 56 47 65 6C 62 0A 35 56 42 : VLila.3VGelb.5VB
309 00000030 : 6C 61 75 0A 34 08 0E 13 20 27 2E 00 00 00 00 00 : lau.4... '......
310 00000040 : 00 01 01 00 00 00 00 00 00 00 06 00 00 00 00 00 : ................
311 00000050 : 00 00 00 00 00 00 00 00 00 00 35 : ..........5
312 -EA ENTRY--:
313 offset : 00000117 : 279
314 length : 00000003 : 3
315 flags : 0000 : ..
316 namelen : 08 : 8
317 -EA NAME---: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
318 00000000 : 66 6F 6F 3A 62 61 72 00 : foo:bar.
319 -EA VALUE--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
320 00000000 : 62 61 7A : baz
322 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
323 00000000 : 54 45 53 54 53 4C 4F 57 00 08 00 00 00 00 00 00 : TESTSLOW........
324 00000010 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
325 00000020 : 00 00 41 54 54 52 53 D4 58 0C 00 00 0E E2 00 00 : ..ATTRS.X.......
326 00000030 : 00 BC 00 00 00 5E 00 00 00 00 00 00 00 00 00 00 : .....^..........
327 00000040 : 00 00 00 00 00 02 00 00 00 BC 00 00 00 5B 00 00 : .............[..
328 00000050 : 24 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 : $com.apple.metad
329 00000060 : 61 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 : ata:_kMDItemUser
330 00000070 : 54 61 67 73 00 00 00 00 01 17 00 00 00 03 00 00 : Tags............
331 00000080 : 08 66 6F 6F 3A 62 61 72 00 66 62 70 6C 69 73 74 : .foo:bar.fbplist
332 00000090 : 30 30 A5 01 02 03 04 05 54 74 65 73 74 66 00 47 : 00......Ttestf.G
333 000000A0 : 00 72 00 FC 00 6E 00 0A 00 32 56 4C 69 6C 61 0A : .r...n...2VLila.
334 000000B0 : 33 56 47 65 6C 62 0A 35 56 42 6C 61 75 0A 34 08 : 3VGelb.5VBlau.4.
335 000000C0 : 0E 13 20 27 2E 00 00 00 00 00 00 01 01 00 00 00 : .. '............
336 000000D0 : 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 : ................
337 000000E0 : 00 00 00 00 35 62 61 7A 00 00 00 00 00 00 00 00 : ....5baz........
338 000000F0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
339 ... all zeroes ...
340 00000EA0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
342 -------------------------------------------------------------------------------
343 Entry ID : 00000002 : Resource Fork
344 Offset : 00000EE2 : 3810
345 Length : 0000011E : 286
347 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
348 00000000 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
349 00000010 : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo
350 00000020 : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
351 00000030 : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 : left blank ..
352 00000040 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
353 00000050 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
354 00000060 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
355 00000070 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
356 00000080 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
357 00000090 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
358 000000A0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
359 000000B0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
360 000000C0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
361 000000D0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
362 000000E0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
363 000000F0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
364 00000100 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
365 00000110 : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF : ..............
367 It was created with:
368 $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
370 static char osx_adouble_w_xattr[] = {
371 0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
372 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
373 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
374 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
375 0x00, 0x32, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00,
376 0x00, 0x02, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00,
377 0x01, 0x1e, 0x54, 0x45, 0x53, 0x54, 0x53, 0x4c,
378 0x4f, 0x57, 0x00, 0x08, 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, 0x41, 0x54, 0x54, 0x52,
382 0x53, 0xd4, 0x58, 0x0c, 0x00, 0x00, 0x0e, 0xe2,
383 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5e,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
386 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5b,
387 0x00, 0x00, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
388 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x65, 0x74,
389 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x5f, 0x6b,
390 0x4d, 0x44, 0x49, 0x74, 0x65, 0x6d, 0x55, 0x73,
391 0x65, 0x72, 0x54, 0x61, 0x67, 0x73, 0x00, 0x00,
392 0x00, 0x00, 0x01, 0x17, 0x00, 0x00, 0x00, 0x03,
393 0x00, 0x00, 0x08, 0x66, 0x6f, 0x6f, 0x3a, 0x62,
394 0x61, 0x72, 0x00, 0x66, 0x62, 0x70, 0x6c, 0x69,
395 0x73, 0x74, 0x30, 0x30, 0xa5, 0x01, 0x02, 0x03,
396 0x04, 0x05, 0x54, 0x74, 0x65, 0x73, 0x74, 0x66,
397 0x00, 0x47, 0x00, 0x72, 0x00, 0xfc, 0x00, 0x6e,
398 0x00, 0x0a, 0x00, 0x32, 0x56, 0x4c, 0x69, 0x6c,
399 0x61, 0x0a, 0x33, 0x56, 0x47, 0x65, 0x6c, 0x62,
400 0x0a, 0x35, 0x56, 0x42, 0x6c, 0x61, 0x75, 0x0a,
401 0x34, 0x08, 0x0e, 0x13, 0x20, 0x27, 0x2e, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x62,
406 0x61, 0x7a, 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, 0x00, 0x00, 0x00, 0x00,
748 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
750 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
751 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
752 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x00, 0x00, 0x00, 0x00,
780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
783 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
784 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
785 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
789 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
792 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
795 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
797 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
798 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
799 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
800 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
801 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
802 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
803 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
804 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
805 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
817 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
818 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
819 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
820 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
821 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
822 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
823 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
824 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
825 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
826 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
827 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
829 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
830 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
831 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
832 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
833 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
834 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
847 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
848 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
849 0x00, 0x1e, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72,
850 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20,
851 0x66, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
852 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
853 0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
854 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
855 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
856 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
860 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
861 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
862 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
863 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
864 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
865 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
868 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
870 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
871 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
872 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
873 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
874 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
875 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
876 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
877 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
878 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
879 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
880 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
881 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
882 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
886 * talloc and intialize an AfpInfo
888 static AfpInfo *torture_afpinfo_new(TALLOC_CTX *mem_ctx)
890 AfpInfo *info;
892 info = talloc_zero(mem_ctx, AfpInfo);
893 if (info == NULL) {
894 return NULL;
897 info->afpi_Signature = AFP_Signature;
898 info->afpi_Version = AFP_Version;
899 info->afpi_BackupTime = AFP_BackupTime;
901 return info;
905 * Pack AfpInfo into a talloced buffer
907 static char *torture_afpinfo_pack(TALLOC_CTX *mem_ctx,
908 AfpInfo *info)
910 char *buf;
912 buf = talloc_array(mem_ctx, char, AFP_INFO_SIZE);
913 if (buf == NULL) {
914 return NULL;
917 RSIVAL(buf, 0, info->afpi_Signature);
918 RSIVAL(buf, 4, info->afpi_Version);
919 RSIVAL(buf, 12, info->afpi_BackupTime);
920 memcpy(buf + 16, info->afpi_FinderInfo, sizeof(info->afpi_FinderInfo));
922 return buf;
926 * Unpack AfpInfo
928 #if 0
929 static void torture_afpinfo_unpack(AfpInfo *info, char *data)
931 info->afpi_Signature = RIVAL(data, 0);
932 info->afpi_Version = RIVAL(data, 4);
933 info->afpi_BackupTime = RIVAL(data, 12);
934 memcpy(info->afpi_FinderInfo, (const char *)data + 16,
935 sizeof(info->afpi_FinderInfo));
937 #endif
939 static bool torture_write_afpinfo(struct smb2_tree *tree,
940 struct torture_context *tctx,
941 TALLOC_CTX *mem_ctx,
942 const char *fname,
943 AfpInfo *info)
945 struct smb2_handle handle;
946 struct smb2_create io;
947 NTSTATUS status;
948 const char *full_name;
949 char *infobuf;
950 bool ret = true;
952 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, AFPINFO_STREAM_NAME);
953 if (full_name == NULL) {
954 torture_comment(tctx, "talloc_asprintf error\n");
955 return false;
957 ZERO_STRUCT(io);
958 io.in.desired_access = SEC_FILE_WRITE_DATA;
959 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
960 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
961 io.in.create_options = 0;
962 io.in.fname = full_name;
964 status = smb2_create(tree, mem_ctx, &io);
965 CHECK_STATUS(status, NT_STATUS_OK);
967 handle = io.out.file.handle;
969 infobuf = torture_afpinfo_pack(mem_ctx, info);
970 if (infobuf == NULL) {
971 return false;
974 status = smb2_util_write(tree, handle, infobuf, 0, AFP_INFO_SIZE);
975 CHECK_STATUS(status, NT_STATUS_OK);
977 smb2_util_close(tree, handle);
979 done:
980 return ret;
984 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
985 * compare against buffer 'value'
987 static bool check_stream(struct smb2_tree *tree,
988 const char *location,
989 struct torture_context *tctx,
990 TALLOC_CTX *mem_ctx,
991 const char *fname,
992 const char *sname,
993 off_t read_offset,
994 size_t read_count,
995 off_t comp_offset,
996 size_t comp_count,
997 const char *value)
999 struct smb2_handle handle;
1000 struct smb2_create create;
1001 struct smb2_read r;
1002 NTSTATUS status;
1003 char *full_name;
1004 bool ret = true;
1006 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1007 if (full_name == NULL) {
1008 torture_comment(tctx, "talloc_asprintf error\n");
1009 return false;
1011 ZERO_STRUCT(create);
1012 create.in.desired_access = SEC_FILE_READ_DATA;
1013 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1014 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1015 create.in.fname = full_name;
1017 torture_comment(tctx, "Open stream %s\n", full_name);
1019 status = smb2_create(tree, mem_ctx, &create);
1020 if (!NT_STATUS_IS_OK(status)) {
1021 TALLOC_FREE(full_name);
1022 if (value == NULL) {
1023 return true;
1025 torture_comment(tctx, "Unable to open stream %s\n", full_name);
1026 return false;
1029 handle = create.out.file.handle;
1030 if (value == NULL) {
1031 TALLOC_FREE(full_name);
1032 smb2_util_close(tree, handle);
1033 return true;
1036 ZERO_STRUCT(r);
1037 r.in.file.handle = handle;
1038 r.in.length = read_count;
1039 r.in.offset = read_offset;
1041 status = smb2_read(tree, tree, &r);
1043 torture_assert_ntstatus_ok_goto(
1044 tctx, status, ret, done,
1045 talloc_asprintf(tctx, "(%s) Failed to read %lu bytes from stream '%s'\n",
1046 location, (long)strlen(value), full_name));
1048 torture_assert_goto(tctx, r.out.data.length == read_count, ret, done,
1049 talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected %jd\n",
1050 (intmax_t)r.out.data.length, (intmax_t)read_count));
1052 torture_assert_goto(
1053 tctx, memcmp(r.out.data.data + comp_offset, value, comp_count) == 0,
1054 ret, done,
1055 talloc_asprintf(tctx, "(%s) Bad data in stream\n", location));
1057 done:
1058 TALLOC_FREE(full_name);
1059 smb2_util_close(tree, handle);
1060 return ret;
1064 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1065 * compare against buffer 'value'
1067 static ssize_t read_stream(struct smb2_tree *tree,
1068 const char *location,
1069 struct torture_context *tctx,
1070 TALLOC_CTX *mem_ctx,
1071 const char *fname,
1072 const char *sname,
1073 off_t read_offset,
1074 size_t read_count)
1076 struct smb2_handle handle;
1077 struct smb2_create create;
1078 struct smb2_read r;
1079 NTSTATUS status;
1080 const char *full_name;
1081 bool ret = true;
1083 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1084 if (full_name == NULL) {
1085 torture_comment(tctx, "talloc_asprintf error\n");
1086 return -1;
1088 ZERO_STRUCT(create);
1089 create.in.desired_access = SEC_FILE_READ_DATA;
1090 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1091 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1092 create.in.fname = full_name;
1094 torture_comment(tctx, "Open stream %s\n", full_name);
1096 status = smb2_create(tree, mem_ctx, &create);
1097 if (!NT_STATUS_IS_OK(status)) {
1098 torture_comment(tctx, "Unable to open stream %s\n",
1099 full_name);
1100 return -1;
1103 handle = create.out.file.handle;
1105 ZERO_STRUCT(r);
1106 r.in.file.handle = handle;
1107 r.in.length = read_count;
1108 r.in.offset = read_offset;
1110 status = smb2_read(tree, tree, &r);
1111 if (!NT_STATUS_IS_OK(status)) {
1112 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
1115 smb2_util_close(tree, handle);
1117 done:
1118 if (ret == false) {
1119 return -1;
1121 return r.out.data.length;
1125 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1126 * compare against buffer 'value'
1128 static bool write_stream(struct smb2_tree *tree,
1129 const char *location,
1130 struct torture_context *tctx,
1131 TALLOC_CTX *mem_ctx,
1132 const char *fname,
1133 const char *sname,
1134 off_t offset,
1135 size_t size,
1136 const char *value)
1138 struct smb2_handle handle;
1139 struct smb2_create create;
1140 NTSTATUS status;
1141 const char *full_name;
1143 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname ? sname : "");
1144 if (full_name == NULL) {
1145 torture_comment(tctx, "talloc_asprintf error\n");
1146 return false;
1148 ZERO_STRUCT(create);
1149 create.in.desired_access = SEC_FILE_WRITE_DATA;
1150 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1151 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1152 create.in.fname = full_name;
1154 status = smb2_create(tree, mem_ctx, &create);
1155 if (!NT_STATUS_IS_OK(status)) {
1156 if (value == NULL) {
1157 return true;
1158 } else {
1159 torture_comment(tctx, "Unable to open stream %s\n",
1160 full_name);
1161 sleep(10000000);
1162 return false;
1166 handle = create.out.file.handle;
1167 if (value == NULL) {
1168 return true;
1171 status = smb2_util_write(tree, handle, value, offset, size);
1173 if (!NT_STATUS_IS_OK(status)) {
1174 torture_comment(tctx, "(%s) Failed to write %lu bytes to "
1175 "stream '%s'\n", location, (long)size, full_name);
1176 return false;
1179 smb2_util_close(tree, handle);
1180 return true;
1183 static bool torture_setup_local_xattr(struct torture_context *tctx,
1184 const char *path_option,
1185 const char *name,
1186 const char *xattr,
1187 const char *metadata,
1188 size_t size)
1190 int ret = true;
1191 int result;
1192 const char *spath;
1193 char *path;
1195 spath = torture_setting_string(tctx, path_option, NULL);
1196 if (spath == NULL) {
1197 printf("No sharepath for option %s\n", path_option);
1198 return false;
1201 path = talloc_asprintf(tctx, "%s/%s", spath, name);
1203 result = setxattr(path, xattr, metadata, size, 0);
1204 if (result != 0) {
1205 ret = false;
1208 TALLOC_FREE(path);
1210 return ret;
1213 static bool torture_setup_local_file(struct torture_context *tctx,
1214 const char *path_option,
1215 const char *name,
1216 const char *buf,
1217 size_t size)
1219 int fd;
1220 const char *spath;
1221 char *path;
1222 ssize_t rsize;
1224 spath = torture_setting_string(tctx, path_option, NULL);
1225 if (spath == NULL) {
1226 printf("No sharepath for option %s\n", path_option);
1227 return false;
1230 path = talloc_asprintf(tctx, "%s/%s", spath, name);
1231 if (path == NULL) {
1232 return false;
1235 fd = creat(path, S_IRWXU);
1236 TALLOC_FREE(path);
1237 if (fd == -1) {
1238 return false;
1241 if ((buf == NULL) || (size == 0)) {
1242 close(fd);
1243 return true;
1246 rsize = write(fd, buf, size);
1247 if (rsize != size) {
1248 return false;
1251 close(fd);
1253 return true;
1257 * Create a file or directory
1259 static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree,
1260 const char *name, bool dir)
1262 struct smb2_create io;
1263 NTSTATUS status;
1265 smb2_util_unlink(tree, name);
1266 ZERO_STRUCT(io);
1267 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1268 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1269 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1270 io.in.share_access =
1271 NTCREATEX_SHARE_ACCESS_DELETE|
1272 NTCREATEX_SHARE_ACCESS_READ|
1273 NTCREATEX_SHARE_ACCESS_WRITE;
1274 io.in.create_options = 0;
1275 io.in.fname = name;
1276 if (dir) {
1277 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1278 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
1279 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1280 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1283 status = smb2_create(tree, mem_ctx, &io);
1284 if (!NT_STATUS_IS_OK(status)) {
1285 return false;
1288 status = smb2_util_close(tree, io.out.file.handle);
1289 if (!NT_STATUS_IS_OK(status)) {
1290 return false;
1293 return true;
1296 static bool enable_aapl(struct torture_context *tctx,
1297 struct smb2_tree *tree)
1299 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1300 NTSTATUS status;
1301 bool ret = true;
1302 struct smb2_create io;
1303 DATA_BLOB data;
1304 struct smb2_create_blob *aapl = NULL;
1305 uint32_t aapl_server_caps;
1306 uint32_t expexted_scaps = (SMB2_CRTCTX_AAPL_UNIX_BASED |
1307 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1308 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1309 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
1310 bool is_osx_server = torture_setting_bool(tctx, "osx", false);
1312 ZERO_STRUCT(io);
1313 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1314 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1315 io.in.create_disposition = NTCREATEX_DISP_OPEN;
1316 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1317 NTCREATEX_SHARE_ACCESS_READ |
1318 NTCREATEX_SHARE_ACCESS_WRITE);
1319 io.in.fname = "";
1322 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1323 * controls behaviour of Apple's SMB2 extensions for the whole
1324 * session!
1327 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1328 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1329 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1330 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1331 SMB2_CRTCTX_AAPL_MODEL_INFO));
1332 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1333 SMB2_CRTCTX_AAPL_UNIX_BASED |
1334 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1336 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1337 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_blob_add");
1339 status = smb2_create(tree, tctx, &io);
1340 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1342 status = smb2_util_close(tree, io.out.file.handle);
1343 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close");
1346 * Now check returned AAPL context
1348 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1350 aapl = smb2_create_blob_find(&io.out.blobs,
1351 SMB2_CREATE_TAG_AAPL);
1352 torture_assert_goto(tctx, aapl != NULL, ret, done, "missing AAPL context");
1354 if (!is_osx_server) {
1355 size_t exptected_aapl_ctx_size;
1357 exptected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
1359 torture_assert_goto(
1360 tctx, aapl->data.length == exptected_aapl_ctx_size,
1361 ret, done, "bad AAPL size");
1364 aapl_server_caps = BVAL(aapl->data.data, 16);
1365 torture_assert_goto(tctx, aapl_server_caps == expexted_scaps,
1366 ret, done, "bad AAPL caps");
1368 done:
1369 talloc_free(mem_ctx);
1370 return ret;
1373 static bool test_read_netatalk_metadata(struct torture_context *tctx,
1374 struct smb2_tree *tree)
1376 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1377 const char *fname = BASEDIR "\\torture_read_metadata";
1378 NTSTATUS status;
1379 struct smb2_handle testdirh;
1380 bool ret = true;
1381 ssize_t len;
1382 const char *localdir = NULL;
1384 torture_comment(tctx, "Checking metadata access\n");
1386 localdir = torture_setting_string(tctx, "localdir", NULL);
1387 if (localdir == NULL) {
1388 torture_skip(tctx, "Need localdir for test");
1391 smb2_util_unlink(tree, fname);
1393 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1394 CHECK_STATUS(status, NT_STATUS_OK);
1395 smb2_util_close(tree, testdirh);
1397 ret = torture_setup_file(mem_ctx, tree, fname, false);
1398 if (ret == false) {
1399 goto done;
1402 ret = torture_setup_local_xattr(tctx, "localdir",
1403 BASEDIR "/torture_read_metadata",
1404 AFPINFO_EA_NETATALK,
1405 metadata_xattr, sizeof(metadata_xattr));
1406 if (ret == false) {
1407 goto done;
1410 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1411 0, 60, 0, 4, "AFP");
1412 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1414 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1415 0, 60, 16, 8, "BARRFOOO");
1416 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1418 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1419 16, 8, 0, 3, "AFP");
1420 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1422 /* Check reading offset and read size > sizeof(AFPINFO_STREAM) */
1424 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1425 AFPINFO_STREAM, 0, 61);
1426 CHECK_VALUE(len, 60);
1428 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1429 AFPINFO_STREAM, 59, 2);
1430 CHECK_VALUE(len, 2);
1432 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1433 AFPINFO_STREAM, 60, 1);
1434 CHECK_VALUE(len, 1);
1436 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1437 AFPINFO_STREAM, 61, 1);
1438 CHECK_VALUE(len, 0);
1440 done:
1441 smb2_deltree(tree, BASEDIR);
1442 talloc_free(mem_ctx);
1443 return ret;
1446 static bool test_read_afpinfo(struct torture_context *tctx,
1447 struct smb2_tree *tree)
1449 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1450 const char *fname = BASEDIR "\\torture_read_metadata";
1451 NTSTATUS status;
1452 struct smb2_handle testdirh;
1453 bool ret = true;
1454 ssize_t len;
1455 AfpInfo *info;
1456 const char *type_creator = "SMB,OLE!";
1458 torture_comment(tctx, "Checking metadata access\n");
1460 smb2_util_unlink(tree, fname);
1462 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1463 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
1464 smb2_util_close(tree, testdirh);
1466 ret = torture_setup_file(mem_ctx, tree, fname, false);
1467 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
1469 info = torture_afpinfo_new(mem_ctx);
1470 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
1472 memcpy(info->afpi_FinderInfo, type_creator, 8);
1473 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1474 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
1476 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1477 0, 60, 0, 4, "AFP");
1478 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1480 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1481 0, 60, 16, 8, type_creator);
1482 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1485 * OS X ignores offset <= 60 and treats the as
1486 * offset=0. Reading from offsets > 60 returns EOF=0.
1489 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1490 16, 8, 0, 8, "AFP\0\0\0\001\0");
1491 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1493 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1494 AFPINFO_STREAM, 0, 61);
1495 torture_assert_goto(tctx, len == 60, ret, done, "read_stream failed");
1497 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1498 AFPINFO_STREAM, 59, 2);
1499 torture_assert_goto(tctx, len == 2, ret, done, "read_stream failed");
1501 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1502 59, 2, 0, 2, "AF");
1503 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1505 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1506 AFPINFO_STREAM, 60, 1);
1507 torture_assert_goto(tctx, len == 1, ret, done, "read_stream failed");
1509 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1510 60, 1, 0, 1, "A");
1511 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1513 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1514 AFPINFO_STREAM, 61, 1);
1515 torture_assert_goto(tctx, len == 0, ret, done, "read_stream failed");
1517 done:
1518 smb2_util_unlink(tree, fname);
1519 smb2_deltree(tree, BASEDIR);
1520 talloc_free(mem_ctx);
1521 return ret;
1524 static bool test_write_atalk_metadata(struct torture_context *tctx,
1525 struct smb2_tree *tree)
1527 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1528 const char *fname = BASEDIR "\\torture_write_metadata";
1529 const char *type_creator = "SMB,OLE!";
1530 NTSTATUS status;
1531 struct smb2_handle testdirh;
1532 bool ret = true;
1533 AfpInfo *info;
1535 smb2_deltree(tree, BASEDIR);
1536 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1537 CHECK_STATUS(status, NT_STATUS_OK);
1538 smb2_util_close(tree, testdirh);
1540 ret = torture_setup_file(mem_ctx, tree, fname, false);
1541 if (ret == false) {
1542 goto done;
1545 info = torture_afpinfo_new(mem_ctx);
1546 if (info == NULL) {
1547 goto done;
1550 memcpy(info->afpi_FinderInfo, type_creator, 8);
1551 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1552 ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1553 0, 60, 16, 8, type_creator);
1555 done:
1556 smb2_util_unlink(tree, fname);
1557 smb2_deltree(tree, BASEDIR);
1558 talloc_free(mem_ctx);
1559 return ret;
1562 static bool test_write_atalk_rfork_io(struct torture_context *tctx,
1563 struct smb2_tree *tree)
1565 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1566 const char *fname = BASEDIR "\\torture_write_rfork_io";
1567 const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
1568 const char *rfork_content = "1234567890";
1569 NTSTATUS status;
1570 struct smb2_handle testdirh;
1571 bool ret = true;
1573 union smb_open io;
1574 struct smb2_handle filehandle;
1575 union smb_fileinfo finfo;
1576 union smb_setfileinfo sinfo;
1578 smb2_util_unlink(tree, fname);
1580 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1581 CHECK_STATUS(status, NT_STATUS_OK);
1582 smb2_util_close(tree, testdirh);
1584 ret = torture_setup_file(mem_ctx, tree, fname, false);
1585 if (ret == false) {
1586 goto done;
1589 torture_comment(tctx, "(%s) writing to resource fork\n",
1590 __location__);
1592 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1593 fname, AFPRESOURCE_STREAM_NAME,
1594 10, 10, rfork_content);
1596 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1597 fname, AFPRESOURCE_STREAM_NAME,
1598 0, 20, 10, 10, rfork_content);
1600 /* Check size after write */
1602 ZERO_STRUCT(io);
1603 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1604 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1605 SEC_FILE_WRITE_ATTRIBUTE;
1606 io.smb2.in.fname = rfork;
1607 status = smb2_create(tree, mem_ctx, &(io.smb2));
1608 CHECK_STATUS(status, NT_STATUS_OK);
1609 filehandle = io.smb2.out.file.handle;
1611 torture_comment(tctx, "(%s) check resource fork size after write\n",
1612 __location__);
1614 ZERO_STRUCT(finfo);
1615 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1616 finfo.generic.in.file.handle = filehandle;
1617 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1618 CHECK_STATUS(status, NT_STATUS_OK);
1619 if (finfo.all_info.out.size != 20) {
1620 torture_result(tctx, TORTURE_FAIL,
1621 "(%s) Incorrect resource fork size\n",
1622 __location__);
1623 ret = false;
1624 smb2_util_close(tree, filehandle);
1625 goto done;
1627 smb2_util_close(tree, filehandle);
1629 /* Write at large offset */
1631 torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
1632 __location__);
1634 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1635 fname, AFPRESOURCE_STREAM_NAME,
1636 (off_t)1<<32, 10, rfork_content);
1638 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1639 fname, AFPRESOURCE_STREAM_NAME,
1640 (off_t)1<<32, 10, 0, 10, rfork_content);
1642 /* Truncate back to size of 1 byte */
1644 torture_comment(tctx, "(%s) truncate resource fork and check size\n",
1645 __location__);
1647 ZERO_STRUCT(io);
1648 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1649 io.smb2.in.desired_access = SEC_FILE_ALL;
1650 io.smb2.in.fname = rfork;
1651 status = smb2_create(tree, mem_ctx, &(io.smb2));
1652 CHECK_STATUS(status, NT_STATUS_OK);
1653 filehandle = io.smb2.out.file.handle;
1655 ZERO_STRUCT(sinfo);
1656 sinfo.end_of_file_info.level =
1657 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1658 sinfo.end_of_file_info.in.file.handle = filehandle;
1659 sinfo.end_of_file_info.in.size = 1;
1660 status = smb2_setinfo_file(tree, &sinfo);
1661 CHECK_STATUS(status, NT_STATUS_OK);
1663 smb2_util_close(tree, filehandle);
1665 /* Now check size */
1666 ZERO_STRUCT(io);
1667 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1668 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1669 SEC_FILE_WRITE_ATTRIBUTE;
1670 io.smb2.in.fname = rfork;
1671 status = smb2_create(tree, mem_ctx, &(io.smb2));
1672 CHECK_STATUS(status, NT_STATUS_OK);
1673 filehandle = io.smb2.out.file.handle;
1675 ZERO_STRUCT(finfo);
1676 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1677 finfo.generic.in.file.handle = filehandle;
1678 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1679 CHECK_STATUS(status, NT_STATUS_OK);
1680 if (finfo.all_info.out.size != 1) {
1681 torture_result(tctx, TORTURE_FAIL,
1682 "(%s) Incorrect resource fork size\n",
1683 __location__);
1684 ret = false;
1685 smb2_util_close(tree, filehandle);
1686 goto done;
1688 smb2_util_close(tree, filehandle);
1690 done:
1691 smb2_util_unlink(tree, fname);
1692 smb2_deltree(tree, BASEDIR);
1693 talloc_free(mem_ctx);
1694 return ret;
1697 static bool test_rfork_truncate(struct torture_context *tctx,
1698 struct smb2_tree *tree)
1700 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1701 const char *fname = BASEDIR "\\torture_rfork_truncate";
1702 const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
1703 const char *rfork_content = "1234567890";
1704 NTSTATUS status;
1705 struct smb2_handle testdirh;
1706 bool ret = true;
1707 struct smb2_create create;
1708 struct smb2_handle fh1, fh2, fh3;
1709 union smb_setfileinfo sinfo;
1711 smb2_util_unlink(tree, fname);
1713 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1714 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1715 smb2_util_close(tree, testdirh);
1717 ret = torture_setup_file(mem_ctx, tree, fname, false);
1718 if (ret == false) {
1719 goto done;
1722 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1723 fname, AFPRESOURCE_STREAM,
1724 10, 10, rfork_content);
1726 /* Truncate back to size 0, further access MUST return ENOENT */
1728 torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
1729 __location__);
1731 ZERO_STRUCT(create);
1732 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1733 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1734 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1735 create.in.fname = fname;
1736 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1737 NTCREATEX_SHARE_ACCESS_READ |
1738 NTCREATEX_SHARE_ACCESS_WRITE;
1739 status = smb2_create(tree, mem_ctx, &create);
1740 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1741 fh1 = create.out.file.handle;
1743 ZERO_STRUCT(create);
1744 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1745 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1746 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1747 create.in.fname = rfork;
1748 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1749 NTCREATEX_SHARE_ACCESS_READ |
1750 NTCREATEX_SHARE_ACCESS_WRITE;
1751 status = smb2_create(tree, mem_ctx, &create);
1752 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1753 fh2 = create.out.file.handle;
1755 ZERO_STRUCT(sinfo);
1756 sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1757 sinfo.end_of_file_info.in.file.handle = fh2;
1758 sinfo.end_of_file_info.in.size = 0;
1759 status = smb2_setinfo_file(tree, &sinfo);
1760 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
1763 * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
1765 ZERO_STRUCT(create);
1766 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1767 create.in.desired_access = SEC_FILE_ALL;
1768 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1769 create.in.fname = rfork;
1770 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1771 NTCREATEX_SHARE_ACCESS_READ |
1772 NTCREATEX_SHARE_ACCESS_WRITE;
1773 status = smb2_create(tree, mem_ctx, &create);
1774 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1777 * Do another open on the rfork and write to the new handle. A
1778 * naive server might unlink the AppleDouble resource fork
1779 * file when its truncated to 0 bytes above, so in case both
1780 * open handles share the same underlying fd, the unlink would
1781 * cause the below write to be lost.
1783 ZERO_STRUCT(create);
1784 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1785 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1786 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1787 create.in.fname = rfork;
1788 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1789 NTCREATEX_SHARE_ACCESS_READ |
1790 NTCREATEX_SHARE_ACCESS_WRITE;
1791 status = smb2_create(tree, mem_ctx, &create);
1792 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1793 fh3 = create.out.file.handle;
1795 status = smb2_util_write(tree, fh3, "foo", 0, 3);
1796 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
1798 smb2_util_close(tree, fh3);
1799 smb2_util_close(tree, fh2);
1800 smb2_util_close(tree, fh1);
1802 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
1803 0, 3, 0, 3, "foo");
1804 torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1806 done:
1807 smb2_util_unlink(tree, fname);
1808 smb2_deltree(tree, BASEDIR);
1809 talloc_free(mem_ctx);
1810 return ret;
1813 static bool test_rfork_create(struct torture_context *tctx,
1814 struct smb2_tree *tree)
1816 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1817 const char *fname = BASEDIR "\\torture_rfork_create";
1818 const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1819 NTSTATUS status;
1820 struct smb2_handle testdirh;
1821 bool ret = true;
1822 struct smb2_create create;
1823 struct smb2_handle fh1;
1824 const char *streams[] = {
1825 "::$DATA"
1827 union smb_fileinfo finfo;
1829 smb2_util_unlink(tree, fname);
1831 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1832 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1833 smb2_util_close(tree, testdirh);
1835 ret = torture_setup_file(mem_ctx, tree, fname, false);
1836 if (ret == false) {
1837 goto done;
1840 torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
1841 __location__);
1843 ZERO_STRUCT(create);
1844 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1845 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1846 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1847 create.in.fname = rfork;
1848 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1849 NTCREATEX_SHARE_ACCESS_READ |
1850 NTCREATEX_SHARE_ACCESS_WRITE;
1851 status = smb2_create(tree, mem_ctx, &create);
1852 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1854 torture_comment(tctx, "(%s) create resource fork\n", __location__);
1856 ZERO_STRUCT(create);
1857 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1858 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1859 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1860 create.in.fname = rfork;
1861 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1862 NTCREATEX_SHARE_ACCESS_READ |
1863 NTCREATEX_SHARE_ACCESS_WRITE;
1864 status = smb2_create(tree, mem_ctx, &create);
1865 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1866 fh1 = create.out.file.handle;
1868 torture_comment(tctx, "(%s) getinfo on create handle\n",
1869 __location__);
1871 ZERO_STRUCT(finfo);
1872 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1873 finfo.generic.in.file.handle = fh1;
1874 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1875 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
1876 if (finfo.all_info.out.size != 0) {
1877 torture_result(tctx, TORTURE_FAIL,
1878 "(%s) Incorrect resource fork size\n",
1879 __location__);
1880 ret = false;
1881 smb2_util_close(tree, fh1);
1882 goto done;
1885 torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
1886 __location__);
1888 ZERO_STRUCT(create);
1889 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1890 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1891 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1892 create.in.fname = rfork;
1893 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1894 NTCREATEX_SHARE_ACCESS_READ |
1895 NTCREATEX_SHARE_ACCESS_WRITE;
1896 status = smb2_create(tree, mem_ctx, &create);
1897 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1899 ret = check_stream_list(tree, tctx, fname, 1, streams, false);
1900 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
1902 torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
1903 __location__);
1905 ZERO_STRUCT(create);
1906 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1907 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1908 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1909 create.in.fname = rfork;
1910 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1911 NTCREATEX_SHARE_ACCESS_READ |
1912 NTCREATEX_SHARE_ACCESS_WRITE;
1913 status = smb2_create(tree, mem_ctx, &create);
1914 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1916 done:
1917 smb2_util_unlink(tree, fname);
1918 smb2_deltree(tree, BASEDIR);
1919 talloc_free(mem_ctx);
1920 return ret;
1923 static bool test_rfork_create_ro(struct torture_context *tctx,
1924 struct smb2_tree *tree)
1926 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1927 const char *fname = BASEDIR "\\torture_rfork_create";
1928 const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1929 NTSTATUS status;
1930 struct smb2_handle testdirh;
1931 bool ret = true;
1932 struct smb2_create create;
1934 smb2_util_unlink(tree, fname);
1935 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1936 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1937 "torture_smb2_testdir\n");
1938 smb2_util_close(tree, testdirh);
1940 ret = torture_setup_file(mem_ctx, tree, fname, false);
1941 if (ret == false) {
1942 goto done;
1945 torture_comment(tctx, "(%s) Try opening read-only with "
1946 "open_if create disposition, should return ENOENT\n",
1947 __location__);
1949 ZERO_STRUCT(create);
1950 create.in.fname = rfork;
1951 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1952 create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
1953 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1954 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
1955 status = smb2_create(tree, mem_ctx, &(create));
1956 torture_assert_ntstatus_equal_goto(tctx, status,
1957 NT_STATUS_OBJECT_NAME_NOT_FOUND,
1958 ret, done, "smb2_create failed\n");
1960 torture_comment(tctx, "(%s) Now write something to the "
1961 "rsrc stream, then the same open should succeed\n",
1962 __location__);
1964 ret = write_stream(tree, __location__, tctx, mem_ctx,
1965 fname, AFPRESOURCE_STREAM_NAME,
1966 0, 3, "foo");
1967 torture_assert_goto(tctx, ret == true, ret, done,
1968 "write_stream failed\n");
1970 ret = check_stream(tree, __location__, tctx, mem_ctx,
1971 fname, AFPRESOURCE_STREAM,
1972 0, 3, 0, 3, "foo");
1973 torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1975 ZERO_STRUCT(create);
1976 create.in.fname = rfork;
1977 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1978 create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
1979 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1980 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
1981 status = smb2_create(tree, mem_ctx, &(create));
1982 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1983 "smb2_create failed\n");
1985 smb2_util_close(tree, create.out.file.handle);
1987 done:
1988 smb2_util_unlink(tree, fname);
1989 smb2_deltree(tree, BASEDIR);
1990 talloc_free(mem_ctx);
1991 return ret;
1994 static bool test_adouble_conversion(struct torture_context *tctx,
1995 struct smb2_tree *tree)
1997 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1998 const char *fname = BASEDIR "\\test_adouble_conversion";
1999 const char *fname_local = BASEDIR "/test_adouble_conversion";
2000 const char *adname_local = BASEDIR "/._test_adouble_conversion";
2001 NTSTATUS status;
2002 struct smb2_handle testdirh;
2003 bool ret = true;
2004 const char *data = "This resource fork intentionally left blank";
2005 size_t datalen = strlen(data);
2006 const char *localdir = NULL;
2008 localdir = torture_setting_string(tctx, "localdir", NULL);
2009 if (localdir == NULL) {
2010 torture_skip(tctx, "Need localdir for test");
2013 smb2_util_unlink(tree, fname);
2015 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2016 CHECK_STATUS(status, NT_STATUS_OK);
2017 smb2_util_close(tree, testdirh);
2019 ret = torture_setup_local_file(tctx, "localdir", fname_local,
2020 NULL, 0);
2021 if (ret == false) {
2022 goto done;
2025 ret = torture_setup_local_file(tctx, "localdir", adname_local,
2026 osx_adouble_w_xattr,
2027 sizeof(osx_adouble_w_xattr));
2028 if (ret == false) {
2029 goto done;
2032 torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
2033 __location__);
2035 ret = check_stream(tree, __location__, tctx, mem_ctx,
2036 fname, AFPRESOURCE_STREAM,
2037 16, datalen, 0, datalen, data);
2038 torture_assert_goto(tctx, ret == true, ret, done,
2039 "check AFPRESOURCE_STREAM failed\n");
2041 ret = check_stream(tree, __location__, tctx, mem_ctx, fname,
2042 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2043 0, 3, 0, 3, "baz");
2044 torture_assert_goto(tctx, ret == true, ret, done,
2045 "check foo:bar stream failed\n");
2047 done:
2048 smb2_deltree(tree, BASEDIR);
2049 talloc_free(mem_ctx);
2050 return ret;
2053 static bool test_aapl(struct torture_context *tctx,
2054 struct smb2_tree *tree)
2056 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2057 const char *fname = BASEDIR "\\test_aapl";
2058 NTSTATUS status;
2059 struct smb2_handle testdirh;
2060 bool ret = true;
2061 struct smb2_create io;
2062 DATA_BLOB data;
2063 struct smb2_create_blob *aapl = NULL;
2064 AfpInfo *info;
2065 const char *type_creator = "SMB,OLE!";
2066 char type_creator_buf[9];
2067 uint32_t aapl_cmd;
2068 uint32_t aapl_reply_bitmap;
2069 uint32_t aapl_server_caps;
2070 uint32_t aapl_vol_caps;
2071 char *model;
2072 struct smb2_find f;
2073 unsigned int count;
2074 union smb_search_data *d;
2075 uint64_t rfork_len;
2077 smb2_deltree(tree, BASEDIR);
2079 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2080 CHECK_STATUS(status, NT_STATUS_OK);
2081 smb2_util_close(tree, testdirh);
2083 ZERO_STRUCT(io);
2084 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2085 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2086 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2087 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2088 NTCREATEX_SHARE_ACCESS_READ |
2089 NTCREATEX_SHARE_ACCESS_WRITE);
2090 io.in.fname = fname;
2093 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
2094 * controls behaviour of Apple's SMB2 extensions for the whole
2095 * session!
2098 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2099 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2100 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2101 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2102 SMB2_CRTCTX_AAPL_MODEL_INFO));
2103 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2104 SMB2_CRTCTX_AAPL_UNIX_BASED |
2105 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
2107 torture_comment(tctx, "Testing SMB2 create context AAPL\n");
2108 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2109 CHECK_STATUS(status, NT_STATUS_OK);
2111 status = smb2_create(tree, tctx, &io);
2112 CHECK_STATUS(status, NT_STATUS_OK);
2113 status = smb2_util_close(tree, io.out.file.handle);
2114 CHECK_STATUS(status, NT_STATUS_OK);
2117 * Now check returned AAPL context
2119 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
2121 aapl = smb2_create_blob_find(&io.out.blobs,
2122 SMB2_CREATE_TAG_AAPL);
2124 if (aapl == NULL) {
2125 torture_result(tctx, TORTURE_FAIL,
2126 "(%s) unexpectedly no AAPL capabilities were returned.",
2127 __location__);
2128 ret = false;
2129 goto done;
2132 if (aapl->data.length != 50) {
2134 * uint32_t CommandCode = kAAPL_SERVER_QUERY
2135 * uint32_t Reserved = 0;
2136 * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
2137 * kAAPL_VOLUME_CAPS |
2138 * kAAPL_MODEL_INFO;
2139 * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
2140 * kAAPL_SUPPORTS_OSX_COPYFILE;
2141 * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
2142 * kAAPL_CASE_SENSITIVE;
2143 * uint32_t Pad2 = 0;
2144 * uint32_t ModelStringLen = 10;
2145 * ucs2_t ModelString[5] = "Samba";
2147 torture_warning(tctx,
2148 "(%s) unexpected AAPL context length: %zd, expected 50",
2149 __location__, aapl->data.length);
2152 aapl_cmd = IVAL(aapl->data.data, 0);
2153 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2154 torture_result(tctx, TORTURE_FAIL,
2155 "(%s) unexpected cmd: %d",
2156 __location__, (int)aapl_cmd);
2157 ret = false;
2158 goto done;
2161 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2162 if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2163 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2164 SMB2_CRTCTX_AAPL_MODEL_INFO)) {
2165 torture_result(tctx, TORTURE_FAIL,
2166 "(%s) unexpected reply_bitmap: %d",
2167 __location__, (int)aapl_reply_bitmap);
2168 ret = false;
2169 goto done;
2172 aapl_server_caps = BVAL(aapl->data.data, 16);
2173 if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
2174 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2175 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
2176 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
2177 torture_result(tctx, TORTURE_FAIL,
2178 "(%s) unexpected server_caps: %d",
2179 __location__, (int)aapl_server_caps);
2180 ret = false;
2181 goto done;
2184 aapl_vol_caps = BVAL(aapl->data.data, 24);
2185 if (aapl_vol_caps != 0) {
2186 /* this will fail on a case insensitive fs ... */
2187 torture_result(tctx, TORTURE_FAIL,
2188 "(%s) unexpected vol_caps: %d",
2189 __location__, (int)aapl_vol_caps);
2192 ret = convert_string_talloc(mem_ctx,
2193 CH_UTF16LE, CH_UNIX,
2194 aapl->data.data + 40, 10,
2195 &model, NULL);
2196 if (ret == false) {
2197 torture_result(tctx, TORTURE_FAIL,
2198 "(%s) convert_string_talloc() failed",
2199 __location__);
2200 goto done;
2202 torture_comment(tctx, "Got server model: \"%s\"\n", model);
2205 * Now that Requested AAPL extensions are enabled, setup some
2206 * Mac files with metadata and resource fork
2208 ret = torture_setup_file(mem_ctx, tree, fname, false);
2209 if (ret == false) {
2210 torture_result(tctx, TORTURE_FAIL,
2211 "(%s) torture_setup_file() failed",
2212 __location__);
2213 goto done;
2216 info = torture_afpinfo_new(mem_ctx);
2217 if (info == NULL) {
2218 torture_result(tctx, TORTURE_FAIL,
2219 "(%s) torture_afpinfo_new() failed",
2220 __location__);
2221 ret = false;
2222 goto done;
2225 memcpy(info->afpi_FinderInfo, type_creator, 8);
2226 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2227 if (ret == false) {
2228 torture_result(tctx, TORTURE_FAIL,
2229 "(%s) torture_write_afpinfo() failed",
2230 __location__);
2231 goto done;
2234 ret = write_stream(tree, __location__, tctx, mem_ctx,
2235 fname, AFPRESOURCE_STREAM_NAME,
2236 0, 3, "foo");
2237 if (ret == false) {
2238 torture_result(tctx, TORTURE_FAIL,
2239 "(%s) write_stream() failed",
2240 __location__);
2241 goto done;
2245 * Ok, file is prepared, now call smb2/find
2248 ZERO_STRUCT(io);
2249 io.in.desired_access = SEC_RIGHTS_DIR_READ;
2250 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2251 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2252 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
2253 NTCREATEX_SHARE_ACCESS_WRITE |
2254 NTCREATEX_SHARE_ACCESS_DELETE);
2255 io.in.create_disposition = NTCREATEX_DISP_OPEN;
2256 io.in.fname = BASEDIR;
2257 status = smb2_create(tree, tctx, &io);
2258 CHECK_STATUS(status, NT_STATUS_OK);
2260 ZERO_STRUCT(f);
2261 f.in.file.handle = io.out.file.handle;
2262 f.in.pattern = "test_aapl";
2263 f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
2264 f.in.max_response_size = 0x1000;
2265 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
2267 status = smb2_find_level(tree, tree, &f, &count, &d);
2268 CHECK_STATUS(status, NT_STATUS_OK);
2270 status = smb2_util_close(tree, io.out.file.handle);
2271 CHECK_STATUS(status, NT_STATUS_OK);
2273 if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2274 torture_result(tctx, TORTURE_FAIL,
2275 "(%s) write_stream() failed",
2276 __location__);
2277 ret = false;
2278 goto done;
2281 if (d[0].id_both_directory_info.short_name.private_length != 24) {
2282 torture_result(tctx, TORTURE_FAIL,
2283 "(%s) bad short_name length %" PRIu32 ", expected 24",
2284 __location__, d[0].id_both_directory_info.short_name.private_length);
2285 ret = false;
2286 goto done;
2289 torture_comment(tctx, "short_name buffer:\n");
2290 dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2293 * Extract data as specified by the AAPL extension:
2294 * - ea_size contains max_access
2295 * - short_name contains resource fork length + FinderInfo
2296 * - reserved2 contains the unix mode
2298 torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2299 d[0].id_both_directory_info.ea_size);
2301 rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2302 if (rfork_len != 3) {
2303 torture_result(tctx, TORTURE_FAIL,
2304 "(%s) expected resource fork length 3, got: %" PRIu64,
2305 __location__, rfork_len);
2306 ret = false;
2307 goto done;
2310 memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2311 type_creator_buf[8] = 0;
2312 if (strcmp(type_creator, type_creator_buf) != 0) {
2313 torture_result(tctx, TORTURE_FAIL,
2314 "(%s) expected type/creator \"%s\" , got: %s",
2315 __location__, type_creator, type_creator_buf);
2316 ret = false;
2317 goto done;
2320 done:
2321 smb2_util_unlink(tree, fname);
2322 smb2_deltree(tree, BASEDIR);
2323 talloc_free(mem_ctx);
2324 return ret;
2327 static uint64_t patt_hash(uint64_t off)
2329 return off;
2332 static bool write_pattern(struct torture_context *torture,
2333 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2334 struct smb2_handle h, uint64_t off, uint64_t len,
2335 uint64_t patt_off)
2337 NTSTATUS status;
2338 uint64_t i;
2339 uint8_t *buf;
2340 uint64_t io_sz = MIN(1024 * 64, len);
2342 if (len == 0) {
2343 return true;
2346 torture_assert(torture, (len % 8) == 0, "invalid write len");
2348 buf = talloc_zero_size(mem_ctx, io_sz);
2349 torture_assert(torture, (buf != NULL), "no memory for file data buf");
2351 while (len > 0) {
2352 for (i = 0; i <= io_sz - 8; i += 8) {
2353 SBVAL(buf, i, patt_hash(patt_off));
2354 patt_off += 8;
2357 status = smb2_util_write(tree, h,
2358 buf, off, io_sz);
2359 torture_assert_ntstatus_ok(torture, status, "file write");
2361 len -= io_sz;
2362 off += io_sz;
2365 talloc_free(buf);
2367 return true;
2370 static bool check_pattern(struct torture_context *torture,
2371 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2372 struct smb2_handle h, uint64_t off, uint64_t len,
2373 uint64_t patt_off)
2375 if (len == 0) {
2376 return true;
2379 torture_assert(torture, (len % 8) == 0, "invalid read len");
2381 while (len > 0) {
2382 uint64_t i;
2383 struct smb2_read r;
2384 NTSTATUS status;
2385 uint64_t io_sz = MIN(1024 * 64, len);
2387 ZERO_STRUCT(r);
2388 r.in.file.handle = h;
2389 r.in.length = io_sz;
2390 r.in.offset = off;
2391 status = smb2_read(tree, mem_ctx, &r);
2392 torture_assert_ntstatus_ok(torture, status, "read");
2394 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2395 "read data len mismatch");
2397 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2398 uint64_t data = BVAL(r.out.data.data, i);
2399 torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2400 talloc_asprintf(torture, "read data "
2401 "pattern bad at %llu\n",
2402 (unsigned long long)off + i));
2404 talloc_free(r.out.data.data);
2405 len -= io_sz;
2406 off += io_sz;
2409 return true;
2412 static bool test_setup_open(struct torture_context *torture,
2413 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2414 const char *fname,
2415 struct smb2_handle *fh,
2416 uint32_t desired_access,
2417 uint32_t file_attributes)
2419 struct smb2_create io;
2420 NTSTATUS status;
2422 ZERO_STRUCT(io);
2423 io.in.desired_access = desired_access;
2424 io.in.file_attributes = file_attributes;
2425 io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2426 io.in.share_access =
2427 NTCREATEX_SHARE_ACCESS_DELETE|
2428 NTCREATEX_SHARE_ACCESS_READ|
2429 NTCREATEX_SHARE_ACCESS_WRITE;
2430 if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2431 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2433 io.in.fname = fname;
2435 status = smb2_create(tree, mem_ctx, &io);
2436 torture_assert_ntstatus_ok(torture, status, "file create");
2438 *fh = io.out.file.handle;
2440 return true;
2443 static bool test_setup_create_fill(struct torture_context *torture,
2444 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2445 const char *fname,
2446 struct smb2_handle *fh,
2447 uint64_t size,
2448 uint32_t desired_access,
2449 uint32_t file_attributes)
2451 bool ok;
2453 ok = test_setup_open(torture, tree, mem_ctx,
2454 fname,
2456 desired_access,
2457 file_attributes);
2458 torture_assert(torture, ok, "file open");
2460 if (size > 0) {
2461 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2462 torture_assert(torture, ok, "write pattern");
2464 return true;
2467 static bool test_setup_copy_chunk(struct torture_context *torture,
2468 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2469 uint32_t nchunks,
2470 const char *src_name,
2471 struct smb2_handle *src_h,
2472 uint64_t src_size,
2473 uint32_t src_desired_access,
2474 const char *dst_name,
2475 struct smb2_handle *dest_h,
2476 uint64_t dest_size,
2477 uint32_t dest_desired_access,
2478 struct srv_copychunk_copy *cc_copy,
2479 union smb_ioctl *io)
2481 struct req_resume_key_rsp res_key;
2482 bool ok;
2483 NTSTATUS status;
2484 enum ndr_err_code ndr_ret;
2486 ok = test_setup_create_fill(torture, tree, mem_ctx, src_name,
2487 src_h, src_size, src_desired_access,
2488 FILE_ATTRIBUTE_NORMAL);
2489 torture_assert(torture, ok, "src file create fill");
2491 ok = test_setup_create_fill(torture, tree, mem_ctx, dst_name,
2492 dest_h, dest_size, dest_desired_access,
2493 FILE_ATTRIBUTE_NORMAL);
2494 torture_assert(torture, ok, "dest file create fill");
2496 ZERO_STRUCTPN(io);
2497 io->smb2.level = RAW_IOCTL_SMB2;
2498 io->smb2.in.file.handle = *src_h;
2499 io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2500 /* Allow for Key + ContextLength + Context */
2501 io->smb2.in.max_response_size = 32;
2502 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2504 status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2505 torture_assert_ntstatus_ok(torture, status,
2506 "FSCTL_SRV_REQUEST_RESUME_KEY");
2508 ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2509 (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2511 torture_assert_ndr_success(torture, ndr_ret,
2512 "ndr_pull_req_resume_key_rsp");
2514 ZERO_STRUCTPN(io);
2515 io->smb2.level = RAW_IOCTL_SMB2;
2516 io->smb2.in.file.handle = *dest_h;
2517 io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2518 io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2519 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2521 ZERO_STRUCTPN(cc_copy);
2522 memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2523 cc_copy->chunk_count = nchunks;
2524 cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2525 torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2527 return true;
2531 static bool check_copy_chunk_rsp(struct torture_context *torture,
2532 struct srv_copychunk_rsp *cc_rsp,
2533 uint32_t ex_chunks_written,
2534 uint32_t ex_chunk_bytes_written,
2535 uint32_t ex_total_bytes_written)
2537 torture_assert_int_equal(torture, cc_rsp->chunks_written,
2538 ex_chunks_written, "num chunks");
2539 torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2540 ex_chunk_bytes_written, "chunk bytes written");
2541 torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2542 ex_total_bytes_written, "chunk total bytes");
2543 return true;
2546 static bool neg_aapl_copyfile(struct torture_context *tctx,
2547 struct smb2_tree *tree,
2548 uint64_t flags)
2550 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2551 const char *fname = "aapl";
2552 NTSTATUS status;
2553 struct smb2_create io;
2554 DATA_BLOB data;
2555 struct smb2_create_blob *aapl = NULL;
2556 uint32_t aapl_cmd;
2557 uint32_t aapl_reply_bitmap;
2558 uint32_t aapl_server_caps;
2559 bool ret = true;
2561 ZERO_STRUCT(io);
2562 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2563 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2564 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2565 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2566 NTCREATEX_SHARE_ACCESS_READ |
2567 NTCREATEX_SHARE_ACCESS_WRITE);
2568 io.in.fname = fname;
2570 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2571 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2572 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2573 SBVAL(data.data, 16, flags);
2575 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2576 CHECK_STATUS(status, NT_STATUS_OK);
2578 status = smb2_create(tree, tctx, &io);
2579 CHECK_STATUS(status, NT_STATUS_OK);
2581 aapl = smb2_create_blob_find(&io.out.blobs,
2582 SMB2_CREATE_TAG_AAPL);
2583 if (aapl == NULL) {
2584 ret = false;
2585 goto done;
2588 if (aapl->data.length < 24) {
2589 ret = false;
2590 goto done;
2593 aapl_cmd = IVAL(aapl->data.data, 0);
2594 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2595 torture_result(tctx, TORTURE_FAIL,
2596 "(%s) unexpected cmd: %d",
2597 __location__, (int)aapl_cmd);
2598 ret = false;
2599 goto done;
2602 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2603 if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2604 torture_result(tctx, TORTURE_FAIL,
2605 "(%s) unexpected reply_bitmap: %d",
2606 __location__, (int)aapl_reply_bitmap);
2607 ret = false;
2608 goto done;
2611 aapl_server_caps = BVAL(aapl->data.data, 16);
2612 if (!(aapl_server_caps & flags)) {
2613 torture_result(tctx, TORTURE_FAIL,
2614 "(%s) unexpected server_caps: %d",
2615 __location__, (int)aapl_server_caps);
2616 ret = false;
2617 goto done;
2620 done:
2621 status = smb2_util_close(tree, io.out.file.handle);
2622 CHECK_STATUS(status, NT_STATUS_OK);
2624 smb2_util_unlink(tree, "aapl");
2625 talloc_free(mem_ctx);
2626 return ret;
2629 static bool test_copyfile(struct torture_context *torture,
2630 struct smb2_tree *tree)
2632 struct smb2_handle src_h;
2633 struct smb2_handle dest_h;
2634 NTSTATUS status;
2635 union smb_ioctl io;
2636 TALLOC_CTX *tmp_ctx = talloc_new(tree);
2637 struct srv_copychunk_copy cc_copy;
2638 struct srv_copychunk_rsp cc_rsp;
2639 enum ndr_err_code ndr_ret;
2640 bool ok;
2641 const char *sname = ":foo" "\xef\x80\xa2" "bar:$DATA";
2644 * First test a copy_chunk with a 0 chunk count without having
2645 * enabled this via AAPL. The request must not fail and the
2646 * copied length in the response must be 0. This is verified
2647 * against Windows 2008r2.
2650 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2651 0, /* 0 chunks, copyfile semantics */
2652 FNAME_CC_SRC,
2653 &src_h, 4096, /* fill 4096 byte src file */
2654 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2655 FNAME_CC_DST,
2656 &dest_h, 0, /* 0 byte dest file */
2657 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2658 &cc_copy,
2659 &io);
2660 if (!ok) {
2661 torture_fail_goto(torture, done, "setup copy chunk error");
2664 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2665 &cc_copy,
2666 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2667 torture_assert_ndr_success(torture, ndr_ret,
2668 "ndr_push_srv_copychunk_copy");
2670 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2671 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2673 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2674 &cc_rsp,
2675 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2676 torture_assert_ndr_success(torture, ndr_ret,
2677 "ndr_pull_srv_copychunk_rsp");
2679 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2680 0, /* chunks written */
2681 0, /* chunk bytes unsuccessfully written */
2682 0); /* total bytes written */
2683 if (!ok) {
2684 torture_fail_goto(torture, done, "bad copy chunk response data");
2688 * Now enable AAPL copyfile and test again, the file and the
2689 * stream must be copied by the server.
2691 ok = neg_aapl_copyfile(torture, tree,
2692 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2693 if (!ok) {
2694 torture_skip_goto(torture, done, "missing AAPL copyfile");
2695 goto done;
2698 smb2_util_close(tree, src_h);
2699 smb2_util_close(tree, dest_h);
2700 smb2_util_unlink(tree, FNAME_CC_SRC);
2701 smb2_util_unlink(tree, FNAME_CC_DST);
2703 ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2704 if (!ok) {
2705 torture_fail(torture, "setup file error");
2707 ok = write_stream(tree, __location__, torture, tmp_ctx,
2708 FNAME_CC_SRC, AFPRESOURCE_STREAM,
2709 10, 10, "1234567890");
2710 if (!ok) {
2711 torture_fail(torture, "setup stream error");
2714 ok = write_stream(tree, __location__, torture, tmp_ctx,
2715 FNAME_CC_SRC, sname,
2716 10, 10, "abcdefghij");
2717 torture_assert_goto(torture, ok == true, ok, done, "write_stream failed\n");
2719 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2720 0, /* 0 chunks, copyfile semantics */
2721 FNAME_CC_SRC,
2722 &src_h, 4096, /* fill 4096 byte src file */
2723 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2724 FNAME_CC_DST,
2725 &dest_h, 0, /* 0 byte dest file */
2726 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2727 &cc_copy,
2728 &io);
2729 if (!ok) {
2730 torture_fail_goto(torture, done, "setup copy chunk error");
2733 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2734 &cc_copy,
2735 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2736 torture_assert_ndr_success(torture, ndr_ret,
2737 "ndr_push_srv_copychunk_copy");
2739 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2740 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2742 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2743 &cc_rsp,
2744 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2745 torture_assert_ndr_success(torture, ndr_ret,
2746 "ndr_pull_srv_copychunk_rsp");
2748 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2749 0, /* chunks written */
2750 0, /* chunk bytes unsuccessfully written */
2751 4096); /* total bytes written */
2752 if (!ok) {
2753 torture_fail_goto(torture, done, "bad copy chunk response data");
2756 ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
2757 SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
2758 if (!ok) {
2759 torture_fail_goto(torture, done,"open failed");
2761 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
2762 if (!ok) {
2763 torture_fail_goto(torture, done, "inconsistent file data");
2766 ok = check_stream(tree, __location__, torture, tmp_ctx,
2767 FNAME_CC_DST, AFPRESOURCE_STREAM,
2768 0, 20, 10, 10, "1234567890");
2769 if (!ok) {
2770 torture_fail_goto(torture, done, "inconsistent stream data");
2773 ok = check_stream(tree, __location__, torture, tmp_ctx,
2774 FNAME_CC_DST, sname,
2775 0, 20, 10, 10, "abcdefghij");
2776 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
2778 done:
2779 smb2_util_close(tree, src_h);
2780 smb2_util_close(tree, dest_h);
2781 smb2_util_unlink(tree, FNAME_CC_SRC);
2782 smb2_util_unlink(tree, FNAME_CC_DST);
2783 talloc_free(tmp_ctx);
2784 return true;
2787 static bool check_stream_list(struct smb2_tree *tree,
2788 struct torture_context *tctx,
2789 const char *fname,
2790 int num_exp,
2791 const char **exp,
2792 bool is_dir)
2794 bool ret = true;
2795 union smb_fileinfo finfo;
2796 NTSTATUS status;
2797 int i;
2798 TALLOC_CTX *tmp_ctx = talloc_new(tctx);
2799 char **exp_sort;
2800 struct stream_struct *stream_sort;
2801 struct smb2_create create;
2802 struct smb2_handle h;
2804 ZERO_STRUCT(h);
2805 torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
2807 ZERO_STRUCT(create);
2808 create.in.fname = fname;
2809 create.in.create_disposition = NTCREATEX_DISP_OPEN;
2810 create.in.desired_access = SEC_FILE_ALL;
2811 create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
2812 create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
2813 status = smb2_create(tree, tmp_ctx, &create);
2814 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2815 h = create.out.file.handle;
2817 finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
2818 finfo.generic.in.file.handle = h;
2820 status = smb2_getinfo_file(tree, tctx, &finfo);
2821 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
2823 smb2_util_close(tree, h);
2825 torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
2826 ret, done, "stream count");
2828 if (num_exp == 0) {
2829 TALLOC_FREE(tmp_ctx);
2830 goto done;
2833 exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
2834 torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
2836 TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
2838 stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
2839 finfo.stream_info.out.num_streams *
2840 sizeof(*stream_sort));
2841 torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
2843 TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
2845 for (i=0; i<num_exp; i++) {
2846 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
2847 i, exp_sort[i], stream_sort[i].stream_name.s);
2848 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
2849 ret, done, "stream name");
2852 done:
2853 TALLOC_FREE(tmp_ctx);
2854 return ret;
2858 test stream names
2860 static bool test_stream_names(struct torture_context *tctx,
2861 struct smb2_tree *tree)
2863 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2864 NTSTATUS status;
2865 struct smb2_create create;
2866 struct smb2_handle h;
2867 const char *fname = BASEDIR "\\stream_names.txt";
2868 const char *sname1;
2869 bool ret;
2870 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
2871 const char *streams[] = {
2872 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2873 "::$DATA"
2876 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
2878 /* clean slate ...*/
2879 smb2_util_unlink(tree, fname);
2880 smb2_deltree(tree, fname);
2881 smb2_deltree(tree, BASEDIR);
2883 status = torture_smb2_testdir(tree, BASEDIR, &h);
2884 CHECK_STATUS(status, NT_STATUS_OK);
2885 smb2_util_close(tree, h);
2887 torture_comment(tctx, "(%s) testing stream names\n", __location__);
2888 ZERO_STRUCT(create);
2889 create.in.desired_access = SEC_FILE_WRITE_DATA;
2890 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2891 create.in.share_access =
2892 NTCREATEX_SHARE_ACCESS_DELETE|
2893 NTCREATEX_SHARE_ACCESS_READ|
2894 NTCREATEX_SHARE_ACCESS_WRITE;
2895 create.in.create_disposition = NTCREATEX_DISP_CREATE;
2896 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2897 create.in.fname = sname1;
2899 status = smb2_create(tree, mem_ctx, &create);
2900 CHECK_STATUS(status, NT_STATUS_OK);
2901 smb2_util_close(tree, create.out.file.handle);
2903 ret = check_stream_list(tree, tctx, fname, 2, streams, false);
2904 CHECK_VALUE(ret, true);
2906 done:
2907 status = smb2_util_unlink(tree, fname);
2908 smb2_deltree(tree, BASEDIR);
2909 talloc_free(mem_ctx);
2911 return ret;
2914 /* Renaming a directory with open file, should work for OS X AAPL clients */
2915 static bool test_rename_dir_openfile(struct torture_context *torture,
2916 struct smb2_tree *tree)
2918 bool ret = true;
2919 NTSTATUS status;
2920 union smb_open io;
2921 union smb_close cl;
2922 union smb_setfileinfo sinfo;
2923 struct smb2_handle d1, h1;
2924 const char *renamedir = BASEDIR "-new";
2925 bool server_is_osx = torture_setting_bool(torture, "osx", false);
2927 smb2_deltree(tree, BASEDIR);
2928 smb2_util_rmdir(tree, BASEDIR);
2929 smb2_deltree(tree, renamedir);
2931 ZERO_STRUCT(io.smb2);
2932 io.generic.level = RAW_OPEN_SMB2;
2933 io.smb2.in.create_flags = 0;
2934 io.smb2.in.desired_access = 0x0017019f;
2935 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2936 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2937 io.smb2.in.share_access = 0;
2938 io.smb2.in.alloc_size = 0;
2939 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2940 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2941 io.smb2.in.security_flags = 0;
2942 io.smb2.in.fname = BASEDIR;
2944 status = smb2_create(tree, torture, &(io.smb2));
2945 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2946 d1 = io.smb2.out.file.handle;
2948 ZERO_STRUCT(io.smb2);
2949 io.generic.level = RAW_OPEN_SMB2;
2950 io.smb2.in.create_flags = 0;
2951 io.smb2.in.desired_access = 0x0017019f;
2952 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2953 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2954 io.smb2.in.share_access = 0;
2955 io.smb2.in.alloc_size = 0;
2956 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2957 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2958 io.smb2.in.security_flags = 0;
2959 io.smb2.in.fname = BASEDIR "\\file.txt";
2961 status = smb2_create(tree, torture, &(io.smb2));
2962 torture_assert_ntstatus_ok(torture, status, "smb2_create file");
2963 h1 = io.smb2.out.file.handle;
2965 if (!server_is_osx) {
2966 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
2968 ZERO_STRUCT(sinfo);
2969 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2970 sinfo.rename_information.in.file.handle = d1;
2971 sinfo.rename_information.in.overwrite = 0;
2972 sinfo.rename_information.in.root_fid = 0;
2973 sinfo.rename_information.in.new_name = renamedir;
2974 status = smb2_setinfo_file(tree, &sinfo);
2976 torture_assert_ntstatus_equal(torture, status,
2977 NT_STATUS_ACCESS_DENIED,
2978 "smb2_setinfo_file");
2980 ZERO_STRUCT(cl.smb2);
2981 cl.smb2.level = RAW_CLOSE_SMB2;
2982 cl.smb2.in.file.handle = d1;
2983 status = smb2_close(tree, &(cl.smb2));
2984 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2985 ZERO_STRUCT(d1);
2988 torture_comment(torture, "Enabling AAPL\n");
2990 ret = enable_aapl(torture, tree);
2991 torture_assert(torture, ret == true, "enable_aapl failed");
2993 torture_comment(torture, "Renaming directory with AAPL\n");
2995 ZERO_STRUCT(io.smb2);
2996 io.generic.level = RAW_OPEN_SMB2;
2997 io.smb2.in.desired_access = 0x0017019f;
2998 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2999 io.smb2.in.share_access = 0;
3000 io.smb2.in.alloc_size = 0;
3001 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
3002 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3003 io.smb2.in.security_flags = 0;
3004 io.smb2.in.fname = BASEDIR;
3006 status = smb2_create(tree, torture, &(io.smb2));
3007 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3008 d1 = io.smb2.out.file.handle;
3010 ZERO_STRUCT(sinfo);
3011 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3012 sinfo.rename_information.in.file.handle = d1;
3013 sinfo.rename_information.in.overwrite = 0;
3014 sinfo.rename_information.in.root_fid = 0;
3015 sinfo.rename_information.in.new_name = renamedir;
3017 status = smb2_setinfo_file(tree, &sinfo);
3018 torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
3020 ZERO_STRUCT(cl.smb2);
3021 cl.smb2.level = RAW_CLOSE_SMB2;
3022 cl.smb2.in.file.handle = d1;
3023 status = smb2_close(tree, &(cl.smb2));
3024 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3025 ZERO_STRUCT(d1);
3027 cl.smb2.in.file.handle = h1;
3028 status = smb2_close(tree, &(cl.smb2));
3029 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3030 ZERO_STRUCT(h1);
3032 torture_comment(torture, "Cleaning up\n");
3034 if (h1.data[0] || h1.data[1]) {
3035 ZERO_STRUCT(cl.smb2);
3036 cl.smb2.level = RAW_CLOSE_SMB2;
3037 cl.smb2.in.file.handle = h1;
3038 status = smb2_close(tree, &(cl.smb2));
3041 smb2_util_unlink(tree, BASEDIR "\\file.txt");
3042 smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
3043 smb2_deltree(tree, renamedir);
3044 smb2_deltree(tree, BASEDIR);
3045 return ret;
3048 static bool test_afpinfo_enoent(struct torture_context *tctx,
3049 struct smb2_tree *tree)
3051 bool ret = true;
3052 NTSTATUS status;
3053 struct smb2_create create;
3054 struct smb2_handle h1;
3055 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3056 const char *fname = BASEDIR "\\file";
3057 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3059 torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
3061 smb2_deltree(tree, BASEDIR);
3062 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3063 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3064 smb2_util_close(tree, h1);
3065 ret = torture_setup_file(mem_ctx, tree, fname, false);
3066 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3068 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3070 ZERO_STRUCT(create);
3071 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3072 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3073 create.in.fname = sname;
3075 status = smb2_create(tree, mem_ctx, &create);
3076 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3077 ret, done, "Got unexpected AFP_AfpInfo stream");
3079 done:
3080 smb2_util_unlink(tree, fname);
3081 smb2_util_rmdir(tree, BASEDIR);
3082 return ret;
3085 static bool test_create_delete_on_close(struct torture_context *tctx,
3086 struct smb2_tree *tree)
3088 bool ret = true;
3089 NTSTATUS status;
3090 struct smb2_create create;
3091 struct smb2_handle h1;
3092 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3093 const char *fname = BASEDIR "\\file";
3094 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3095 const char *type_creator = "SMB,OLE!";
3096 AfpInfo *info = NULL;
3097 const char *streams_basic[] = {
3098 "::$DATA"
3100 const char *streams_afpinfo[] = {
3101 "::$DATA",
3102 AFPINFO_STREAM
3105 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3107 torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
3109 smb2_deltree(tree, BASEDIR);
3110 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3111 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3112 smb2_util_close(tree, h1);
3113 ret = torture_setup_file(mem_ctx, tree, fname, false);
3114 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3116 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3118 ZERO_STRUCT(create);
3119 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3120 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3121 create.in.fname = sname;
3123 status = smb2_create(tree, mem_ctx, &create);
3124 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3125 ret, done, "Got unexpected AFP_AfpInfo stream");
3127 ZERO_STRUCT(create);
3128 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3129 create.in.desired_access = SEC_FILE_ALL;
3130 create.in.fname = sname;
3132 status = smb2_create(tree, mem_ctx, &create);
3133 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3134 ret, done, "Got unexpected AFP_AfpInfo stream");
3136 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3137 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3139 torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
3141 info = torture_afpinfo_new(mem_ctx);
3142 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3144 memcpy(info->afpi_FinderInfo, type_creator, 8);
3145 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3146 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3148 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3149 0, 60, 16, 8, type_creator);
3150 torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
3152 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3153 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3155 ZERO_STRUCT(create);
3156 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3157 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3158 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3159 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3160 create.in.fname = sname;
3161 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3163 status = smb2_create(tree, mem_ctx, &create);
3164 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3166 h1 = create.out.file.handle;
3167 smb2_util_close(tree, h1);
3169 ZERO_STRUCT(create);
3170 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3171 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
3172 create.in.fname = sname;
3173 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3174 status = smb2_create(tree, mem_ctx, &create);
3175 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3176 ret, done, "Got unexpected AFP_AfpInfo stream");
3178 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3179 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3181 done:
3182 smb2_util_unlink(tree, fname);
3183 smb2_util_rmdir(tree, BASEDIR);
3184 return ret;
3187 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
3188 struct smb2_tree *tree)
3190 bool ret = true;
3191 NTSTATUS status;
3192 struct smb2_create create;
3193 union smb_setfileinfo sfinfo;
3194 struct smb2_handle h1;
3195 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3196 const char *fname = BASEDIR "\\file";
3197 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3198 const char *type_creator = "SMB,OLE!";
3199 AfpInfo *info = NULL;
3200 const char *streams_basic[] = {
3201 "::$DATA"
3204 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3206 torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
3208 smb2_deltree(tree, BASEDIR);
3209 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3210 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3211 smb2_util_close(tree, h1);
3212 ret = torture_setup_file(mem_ctx, tree, fname, false);
3213 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3215 info = torture_afpinfo_new(mem_ctx);
3216 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3217 memcpy(info->afpi_FinderInfo, type_creator, 8);
3218 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3219 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3221 ZERO_STRUCT(create);
3222 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3223 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3224 create.in.fname = sname;
3225 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3226 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3228 status = smb2_create(tree, mem_ctx, &create);
3229 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3231 h1 = create.out.file.handle;
3233 /* Delete stream via setinfo delete-on-close */
3234 ZERO_STRUCT(sfinfo);
3235 sfinfo.disposition_info.in.delete_on_close = 1;
3236 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3237 sfinfo.generic.in.file.handle = h1;
3238 status = smb2_setinfo_file(tree, &sfinfo);
3239 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3241 smb2_util_close(tree, h1);
3243 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3244 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3246 ZERO_STRUCT(create);
3247 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3248 create.in.desired_access = SEC_FILE_ALL;
3249 create.in.fname = sname;
3250 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3251 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3252 status = smb2_create(tree, mem_ctx, &create);
3253 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3254 ret, done, "Got unexpected AFP_AfpInfo stream");
3256 done:
3257 smb2_util_unlink(tree, fname);
3258 smb2_util_rmdir(tree, BASEDIR);
3259 return ret;
3262 static bool test_setinfo_eof(struct torture_context *tctx,
3263 struct smb2_tree *tree)
3265 bool ret = true;
3266 NTSTATUS status;
3267 struct smb2_create create;
3268 union smb_setfileinfo sfinfo;
3269 struct smb2_handle h1;
3270 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3271 const char *fname = BASEDIR "\\file";
3272 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3273 const char *type_creator = "SMB,OLE!";
3274 AfpInfo *info = NULL;
3275 const char *streams_afpinfo[] = {
3276 "::$DATA",
3277 AFPINFO_STREAM
3280 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3282 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
3284 smb2_deltree(tree, BASEDIR);
3285 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3286 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3287 smb2_util_close(tree, h1);
3288 ret = torture_setup_file(mem_ctx, tree, fname, false);
3289 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3291 info = torture_afpinfo_new(mem_ctx);
3292 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3293 memcpy(info->afpi_FinderInfo, type_creator, 8);
3294 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3295 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3297 ZERO_STRUCT(create);
3298 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3299 create.in.desired_access = SEC_FILE_ALL;
3300 create.in.fname = sname;
3301 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3302 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3304 status = smb2_create(tree, mem_ctx, &create);
3305 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3307 h1 = create.out.file.handle;
3309 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
3311 /* Test setinfo end-of-file info */
3312 ZERO_STRUCT(sfinfo);
3313 sfinfo.generic.in.file.handle = h1;
3314 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3315 sfinfo.position_information.in.position = 61;
3316 status = smb2_setinfo_file(tree, &sfinfo);
3317 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
3318 ret, done, "set eof 61 failed");
3320 torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
3322 /* Truncation returns success, but has no effect */
3323 ZERO_STRUCT(sfinfo);
3324 sfinfo.generic.in.file.handle = h1;
3325 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3326 sfinfo.position_information.in.position = 1;
3327 status = smb2_setinfo_file(tree, &sfinfo);
3328 torture_assert_ntstatus_ok_goto(tctx, status,
3329 ret, done, "set eof 1 failed");
3330 smb2_util_close(tree, h1);
3332 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3333 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3335 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3336 0, 60, 16, 8, type_creator);
3337 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3339 ZERO_STRUCT(create);
3340 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3341 create.in.desired_access = SEC_FILE_ALL;
3342 create.in.fname = sname;
3343 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3344 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3346 status = smb2_create(tree, mem_ctx, &create);
3347 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3349 h1 = create.out.file.handle;
3352 * Delete stream via setinfo end-of-file info to 0, should
3353 * return success but stream MUST NOT deleted
3355 ZERO_STRUCT(sfinfo);
3356 sfinfo.generic.in.file.handle = h1;
3357 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3358 sfinfo.position_information.in.position = 0;
3359 status = smb2_setinfo_file(tree, &sfinfo);
3360 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3362 smb2_util_close(tree, h1);
3364 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3365 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3367 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3368 0, 60, 16, 8, type_creator);
3369 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3371 done:
3372 smb2_util_unlink(tree, fname);
3373 smb2_util_rmdir(tree, BASEDIR);
3374 return ret;
3377 static bool test_afpinfo_all0(struct torture_context *tctx,
3378 struct smb2_tree *tree)
3380 bool ret = true;
3381 NTSTATUS status;
3382 struct smb2_handle h1;
3383 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3384 const char *fname = BASEDIR "\\file";
3385 const char *type_creator = "SMB,OLE!";
3386 AfpInfo *info = NULL;
3387 const char *streams_basic[] = {
3388 "::$DATA"
3390 const char *streams_afpinfo[] = {
3391 "::$DATA",
3392 AFPINFO_STREAM
3395 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3397 torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
3399 smb2_deltree(tree, BASEDIR);
3400 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3401 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3402 smb2_util_close(tree, h1);
3403 ret = torture_setup_file(mem_ctx, tree, fname, false);
3404 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3406 info = torture_afpinfo_new(mem_ctx);
3407 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3408 memcpy(info->afpi_FinderInfo, type_creator, 8);
3409 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3410 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3412 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3413 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3415 /* Write all 0 to AFP_AfpInfo */
3416 memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
3417 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3418 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3420 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3421 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3423 done:
3424 smb2_util_unlink(tree, fname);
3425 smb2_util_rmdir(tree, BASEDIR);
3426 return ret;
3429 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
3430 struct smb2_tree *tree)
3432 bool ret = true;
3433 NTSTATUS status;
3434 struct smb2_create create;
3435 struct smb2_handle h1;
3436 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3437 const char *fname = BASEDIR "\\file";
3438 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3439 const char *streams_basic[] = {
3440 "::$DATA"
3442 const char *streams_afpresource[] = {
3443 "::$DATA",
3444 AFPRESOURCE_STREAM
3447 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3449 torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
3451 smb2_deltree(tree, BASEDIR);
3452 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3453 torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
3454 smb2_util_close(tree, h1);
3455 ret = torture_setup_file(mem_ctx, tree, fname, false);
3456 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3458 torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
3460 ZERO_STRUCT(create);
3461 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3462 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3463 create.in.fname = sname;
3465 status = smb2_create(tree, mem_ctx, &create);
3466 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3467 ret, done, "Got unexpected AFP_AfpResource stream");
3469 ZERO_STRUCT(create);
3470 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3471 create.in.desired_access = SEC_FILE_ALL;
3472 create.in.fname = sname;
3474 status = smb2_create(tree, mem_ctx, &create);
3475 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3476 ret, done, "Got unexpected AFP_AfpResource stream");
3478 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3479 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3481 torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
3483 ret = write_stream(tree, __location__, tctx, mem_ctx,
3484 fname, AFPRESOURCE_STREAM_NAME,
3485 0, 10, "1234567890");
3486 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3488 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3489 0, 10, 0, 10, "1234567890");
3490 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3492 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3493 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3495 ZERO_STRUCT(create);
3496 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3497 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3498 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3499 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3500 create.in.fname = sname;
3501 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3503 status = smb2_create(tree, mem_ctx, &create);
3504 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3506 h1 = create.out.file.handle;
3507 smb2_util_close(tree, h1);
3509 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3510 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3512 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3513 0, 10, 0, 10, "1234567890");
3514 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3516 done:
3517 smb2_util_unlink(tree, fname);
3518 smb2_util_rmdir(tree, BASEDIR);
3519 return ret;
3522 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
3523 struct smb2_tree *tree)
3525 bool ret = true;
3526 NTSTATUS status;
3527 struct smb2_create create;
3528 union smb_setfileinfo sfinfo;
3529 struct smb2_handle h1;
3530 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3531 const char *fname = BASEDIR "\\file";
3532 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3533 const char *streams_afpresource[] = {
3534 "::$DATA",
3535 AFPRESOURCE_STREAM
3538 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3540 torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
3542 smb2_deltree(tree, BASEDIR);
3543 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3544 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3545 smb2_util_close(tree, h1);
3546 ret = torture_setup_file(mem_ctx, tree, fname, false);
3547 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3549 ret = write_stream(tree, __location__, tctx, mem_ctx,
3550 fname, AFPRESOURCE_STREAM_NAME,
3551 10, 10, "1234567890");
3552 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3554 ZERO_STRUCT(create);
3555 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3556 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3557 create.in.fname = sname;
3558 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3559 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3561 status = smb2_create(tree, mem_ctx, &create);
3562 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3564 h1 = create.out.file.handle;
3566 /* Try to delete stream via setinfo delete-on-close */
3567 ZERO_STRUCT(sfinfo);
3568 sfinfo.disposition_info.in.delete_on_close = 1;
3569 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3570 sfinfo.generic.in.file.handle = h1;
3571 status = smb2_setinfo_file(tree, &sfinfo);
3572 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3574 smb2_util_close(tree, h1);
3576 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3577 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3579 ZERO_STRUCT(create);
3580 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3581 create.in.desired_access = SEC_FILE_ALL;
3582 create.in.fname = sname;
3583 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3584 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3585 status = smb2_create(tree, mem_ctx, &create);
3586 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3587 "Got unexpected AFP_AfpResource stream");
3589 done:
3590 smb2_util_unlink(tree, fname);
3591 smb2_util_rmdir(tree, BASEDIR);
3592 return ret;
3595 static bool test_setinfo_eof_resource(struct torture_context *tctx,
3596 struct smb2_tree *tree)
3598 bool ret = true;
3599 NTSTATUS status;
3600 struct smb2_create create;
3601 union smb_setfileinfo sfinfo;
3602 union smb_fileinfo finfo;
3603 struct smb2_handle h1;
3604 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3605 const char *fname = BASEDIR "\\file";
3606 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3607 const char *streams_basic[] = {
3608 "::$DATA"
3611 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3613 torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
3615 smb2_deltree(tree, BASEDIR);
3616 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3617 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3618 smb2_util_close(tree, h1);
3619 ret = torture_setup_file(mem_ctx, tree, fname, false);
3620 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3622 ret = write_stream(tree, __location__, tctx, mem_ctx,
3623 fname, AFPRESOURCE_STREAM_NAME,
3624 10, 10, "1234567890");
3625 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3627 ZERO_STRUCT(create);
3628 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3629 create.in.desired_access = SEC_FILE_ALL;
3630 create.in.fname = sname;
3631 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3632 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3634 status = smb2_create(tree, mem_ctx, &create);
3635 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3637 h1 = create.out.file.handle;
3639 torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
3641 /* Test setinfo end-of-file info */
3642 ZERO_STRUCT(sfinfo);
3643 sfinfo.generic.in.file.handle = h1;
3644 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3645 sfinfo.position_information.in.position = 1;
3646 status = smb2_setinfo_file(tree, &sfinfo);
3647 torture_assert_ntstatus_ok_goto(tctx, status,
3648 ret, done, "set eof 1 failed");
3650 smb2_util_close(tree, h1);
3652 /* Check size == 1 */
3653 ZERO_STRUCT(create);
3654 create.in.fname = sname;
3655 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3656 create.in.desired_access = SEC_FILE_ALL;
3657 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3658 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3659 status = smb2_create(tree, mem_ctx, &create);
3660 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3662 h1 = create.out.file.handle;
3664 ZERO_STRUCT(finfo);
3665 finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
3666 finfo.generic.in.file.handle = h1;
3667 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
3668 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
3670 smb2_util_close(tree, h1);
3672 torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
3674 ZERO_STRUCT(create);
3675 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3676 create.in.desired_access = SEC_FILE_ALL;
3677 create.in.fname = sname;
3678 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3679 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3681 status = smb2_create(tree, mem_ctx, &create);
3682 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3684 h1 = create.out.file.handle;
3687 * Delete stream via setinfo end-of-file info to 0, this
3688 * should delete the stream.
3690 ZERO_STRUCT(sfinfo);
3691 sfinfo.generic.in.file.handle = h1;
3692 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3693 sfinfo.position_information.in.position = 0;
3694 status = smb2_setinfo_file(tree, &sfinfo);
3695 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3697 smb2_util_close(tree, h1);
3699 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3700 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3702 ZERO_STRUCT(create);
3703 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3704 create.in.desired_access = SEC_FILE_ALL;
3705 create.in.fname = sname;
3706 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3707 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3709 status = smb2_create(tree, mem_ctx, &create);
3710 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3711 ret, done, "smb2_create failed");
3713 done:
3714 smb2_util_unlink(tree, fname);
3715 smb2_util_rmdir(tree, BASEDIR);
3716 return ret;
3720 * This tests that right after creating the AFP_AfpInfo stream,
3721 * reading from the stream returns an empty, default metadata blob of
3722 * 60 bytes.
3724 * NOTE: against OS X SMB server this only works if the read request
3725 * is compounded with the create that created the stream, is fails
3726 * otherwise. We don't care...
3728 static bool test_null_afpinfo(struct torture_context *tctx,
3729 struct smb2_tree *tree)
3731 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3732 const char *fname = "test_null_afpinfo";
3733 const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
3734 NTSTATUS status;
3735 bool ret = true;
3736 struct smb2_request *req[3];
3737 struct smb2_handle handle;
3738 struct smb2_create create;
3739 struct smb2_read read;
3740 AfpInfo *afpinfo = NULL;
3741 char *afpinfo_buf = NULL;
3742 const char *type_creator = "SMB,OLE!";
3744 torture_comment(tctx, "Checking create of AfpInfo stream\n");
3746 smb2_util_unlink(tree, fname);
3748 ret = torture_setup_file(mem_ctx, tree, fname, false);
3749 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
3751 ZERO_STRUCT(create);
3752 create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
3753 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
3754 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3755 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3756 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
3757 create.in.fname = sname;
3759 smb2_transport_compound_start(tree->session->transport, 2);
3761 req[0] = smb2_create_send(tree, &create);
3763 handle.data[0] = UINT64_MAX;
3764 handle.data[1] = UINT64_MAX;
3766 smb2_transport_compound_set_related(tree->session->transport, true);
3768 ZERO_STRUCT(read);
3769 read.in.file.handle = handle;
3770 read.in.length = AFP_INFO_SIZE;
3771 req[1] = smb2_read_send(tree, &read);
3773 status = smb2_create_recv(req[0], tree, &create);
3774 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
3776 handle = create.out.file.handle;
3778 status = smb2_read_recv(req[1], tree, &read);
3779 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
3781 afpinfo = torture_afpinfo_new(mem_ctx);
3782 torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
3784 memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
3786 afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
3787 torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
3789 status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
3790 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
3792 smb2_util_close(tree, handle);
3794 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3795 0, 60, 16, 8, type_creator);
3796 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
3798 done:
3799 smb2_util_unlink(tree, fname);
3800 talloc_free(mem_ctx);
3801 return ret;
3804 static bool test_delete_file_with_rfork(struct torture_context *tctx,
3805 struct smb2_tree *tree)
3807 const char *fname = "torture_write_rfork_io";
3808 const char *rfork_content = "1234567890";
3809 NTSTATUS status;
3810 bool ret = true;
3812 smb2_util_unlink(tree, fname);
3814 torture_comment(tctx, "Test deleting file with resource fork\n");
3816 ret = torture_setup_file(tctx, tree, fname, false);
3817 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
3819 ret = write_stream(tree, __location__, tctx, tctx,
3820 fname, AFPRESOURCE_STREAM_NAME,
3821 10, 10, rfork_content);
3822 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
3824 ret = check_stream(tree, __location__, tctx, tctx,
3825 fname, AFPRESOURCE_STREAM_NAME,
3826 0, 20, 10, 10, rfork_content);
3827 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
3829 status = smb2_util_unlink(tree, fname);
3830 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
3832 done:
3833 return ret;
3836 static bool test_rename_and_read_rsrc(struct torture_context *tctx,
3837 struct smb2_tree *tree)
3839 bool ret = true;
3840 NTSTATUS status;
3841 struct smb2_create create, create2;
3842 struct smb2_handle h1, h2;
3843 const char *fname = "test_rename_openfile";
3844 const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
3845 const char *fname_renamed = "test_rename_openfile_renamed";
3846 const char *data = "1234567890";
3847 union smb_setfileinfo sinfo;
3848 struct smb2_read r;
3850 ret = enable_aapl(tctx, tree);
3851 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
3853 torture_comment(tctx, "Create file with resource fork\n");
3855 ret = torture_setup_file(tctx, tree, fname, false);
3856 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3858 ret = write_stream(tree, __location__, tctx, tctx,
3859 fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
3860 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
3862 torture_comment(tctx, "Open resource fork\n");
3864 ZERO_STRUCT(create);
3865 create.in.desired_access = SEC_FILE_ALL;
3866 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3867 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3868 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3869 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3870 create.in.fname = sname;
3872 status = smb2_create(tree, tctx, &create);
3873 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3875 h1 = create.out.file.handle;
3877 torture_comment(tctx, "Rename base file\n");
3879 ZERO_STRUCT(create2);
3880 create2.in.desired_access = SEC_FILE_ALL;
3881 create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3882 create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3883 create2.in.create_disposition = NTCREATEX_DISP_OPEN;
3884 create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3885 create2.in.fname = fname;
3887 status = smb2_create(tree, tctx, &create2);
3888 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3890 h2 = create2.out.file.handle;
3892 ZERO_STRUCT(sinfo);
3893 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3894 sinfo.rename_information.in.file.handle = h2;
3895 sinfo.rename_information.in.overwrite = 0;
3896 sinfo.rename_information.in.root_fid = 0;
3897 sinfo.rename_information.in.new_name = fname_renamed;
3899 status = smb2_setinfo_file(tree, &sinfo);
3900 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file failed");
3902 smb2_util_close(tree, h2);
3904 ZERO_STRUCT(r);
3905 r.in.file.handle = h1;
3906 r.in.length = 10;
3907 r.in.offset = 0;
3909 torture_comment(tctx, "Read resource fork of renamed file\n");
3911 status = smb2_read(tree, tree, &r);
3912 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read failed");
3914 smb2_util_close(tree, h1);
3916 torture_assert_goto(tctx, r.out.data.length == 10, ret, done,
3917 talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected 10\n",
3918 (intmax_t)r.out.data.length));
3920 torture_assert_goto(tctx, memcmp(r.out.data.data, data, 10) == 0, ret, done,
3921 talloc_asprintf(tctx, "Bad data in stream\n"));
3923 done:
3924 smb2_util_unlink(tree, fname);
3925 smb2_util_unlink(tree, fname_renamed);
3927 return ret;
3930 static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
3931 struct smb2_tree *tree)
3933 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3934 const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
3935 const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
3936 NTSTATUS status;
3937 struct smb2_handle testdirh;
3938 bool ret = true;
3939 struct smb2_create io;
3940 AfpInfo *info;
3941 const char *type_creator = "SMB,OLE!";
3942 struct smb2_find f;
3943 unsigned int count;
3944 union smb_search_data *d;
3945 uint64_t rfork_len;
3946 int i;
3948 smb2_deltree(tree, BASEDIR);
3950 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
3951 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
3952 smb2_util_close(tree, testdirh);
3954 torture_comment(tctx, "Enabling AAPL\n");
3956 ret = enable_aapl(tctx, tree);
3957 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
3960 * Now that Requested AAPL extensions are enabled, setup some
3961 * Mac files with metadata and resource fork
3964 torture_comment(tctx, "Preparing file\n");
3966 ret = torture_setup_file(mem_ctx, tree, fname, false);
3967 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
3969 info = torture_afpinfo_new(mem_ctx);
3970 torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
3972 memcpy(info->afpi_FinderInfo, type_creator, 8);
3973 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3974 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3976 ret = write_stream(tree, __location__, tctx, mem_ctx,
3977 fname, AFPRESOURCE_STREAM_NAME,
3978 0, 3, "foo");
3979 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
3982 * Ok, file is prepared, now call smb2/find
3985 torture_comment(tctx, "Issue find\n");
3987 ZERO_STRUCT(io);
3988 io.in.desired_access = SEC_RIGHTS_DIR_READ;
3989 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
3990 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3991 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
3992 NTCREATEX_SHARE_ACCESS_WRITE |
3993 NTCREATEX_SHARE_ACCESS_DELETE);
3994 io.in.create_disposition = NTCREATEX_DISP_OPEN;
3995 io.in.fname = BASEDIR;
3996 status = smb2_create(tree, tctx, &io);
3997 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3999 ZERO_STRUCT(f);
4000 f.in.file.handle = io.out.file.handle;
4001 f.in.pattern = "*";
4002 f.in.max_response_size = 0x1000;
4003 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
4005 status = smb2_find_level(tree, tree, &f, &count, &d);
4006 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
4008 status = smb2_util_close(tree, io.out.file.handle);
4009 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
4011 torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
4013 for (i = 0; i < count; i++) {
4014 const char *found = d[i].id_both_directory_info.name.s;
4016 if (!strcmp(found, ".") || !strcmp(found, ".."))
4017 continue;
4018 break;
4021 torture_assert_str_equal_goto(tctx,
4022 d[i].id_both_directory_info.name.s, name,
4023 ret, done, "bad name");
4025 rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
4026 torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
4028 torture_assert_mem_equal_goto(tctx, type_creator,
4029 d[i].id_both_directory_info.short_name_buf + 8,
4030 8, ret, done, "Bad FinderInfo");
4031 done:
4032 smb2_util_unlink(tree, fname);
4033 smb2_deltree(tree, BASEDIR);
4034 talloc_free(mem_ctx);
4035 return ret;
4038 static bool test_invalid_afpinfo(struct torture_context *tctx,
4039 struct smb2_tree *tree1,
4040 struct smb2_tree *tree2)
4042 const char *fname = "filtest_invalid_afpinfo";
4043 const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
4044 struct smb2_create create;
4045 const char *streams_basic[] = {
4046 "::$DATA"
4048 const char *streams_afpinfo[] = {
4049 "::$DATA",
4050 AFPINFO_STREAM
4052 NTSTATUS status;
4053 bool ret = true;
4055 if (tree2 == NULL) {
4056 torture_skip_goto(tctx, done, "need second share without fruit\n");
4059 torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
4061 ret = torture_setup_file(tctx, tree2, fname, false);
4062 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4064 ret = write_stream(tree2, __location__, tctx, tctx,
4065 fname, AFPINFO_STREAM_NAME,
4066 0, 3, "foo");
4067 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4069 ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
4070 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4072 torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
4074 ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
4075 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4077 torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
4079 ZERO_STRUCT(create);
4080 create.in.desired_access = SEC_FILE_ALL;
4081 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4082 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4083 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4084 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4085 create.in.fname = sname;
4087 status = smb2_create(tree1, tctx, &create);
4088 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4089 ret, done, "Stream still around?");
4091 done:
4092 smb2_util_unlink(tree1, fname);
4093 return ret;
4096 static bool test_zero_file_id(struct torture_context *tctx,
4097 struct smb2_tree *tree)
4099 const char *fname = "filtest_file_id";
4100 struct smb2_create create = {0};
4101 NTSTATUS status;
4102 bool ret = true;
4103 uint8_t zero_file_id[8] = {0};
4105 torture_comment(tctx, "Testing zero file id\n");
4107 ret = torture_setup_file(tctx, tree, fname, false);
4108 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4110 ZERO_STRUCT(create);
4111 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4112 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4113 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4114 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4115 create.in.fname = fname;
4116 create.in.query_on_disk_id = true;
4118 status = smb2_create(tree, tctx, &create);
4119 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
4120 done,
4121 "test file could not be opened");
4122 torture_assert_mem_not_equal_goto(tctx, create.out.on_disk_id,
4123 zero_file_id, 8, ret, done,
4124 "unexpected zero file id");
4126 smb2_util_close(tree, create.out.file.handle);
4128 ret = enable_aapl(tctx, tree);
4129 torture_assert(tctx, ret == true, "enable_aapl failed");
4131 ZERO_STRUCT(create);
4132 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4133 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4134 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4135 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4136 create.in.fname = fname;
4137 create.in.query_on_disk_id = true;
4139 status = smb2_create(tree, tctx, &create);
4140 torture_assert_ntstatus_equal_goto(
4141 tctx, status, NT_STATUS_OK, ret, done,
4142 "test file could not be opened with AAPL");
4143 torture_assert_mem_equal_goto(tctx, create.out.on_disk_id, zero_file_id,
4144 8, ret, done, "non-zero file id");
4146 smb2_util_close(tree, create.out.file.handle);
4148 done:
4149 smb2_util_unlink(tree, fname);
4150 return ret;
4153 static bool copy_one_stream(struct torture_context *torture,
4154 struct smb2_tree *tree,
4155 TALLOC_CTX *tmp_ctx,
4156 const char *src_sname,
4157 const char *dst_sname)
4159 struct smb2_handle src_h = {{0}};
4160 struct smb2_handle dest_h = {{0}};
4161 NTSTATUS status;
4162 union smb_ioctl io;
4163 struct srv_copychunk_copy cc_copy;
4164 struct srv_copychunk_rsp cc_rsp;
4165 enum ndr_err_code ndr_ret;
4166 bool ok = false;
4168 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4169 1, /* 1 chunk */
4170 src_sname,
4171 &src_h, 256, /* fill 256 byte src file */
4172 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4173 dst_sname,
4174 &dest_h, 0, /* 0 byte dest file */
4175 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4176 &cc_copy,
4177 &io);
4178 torture_assert_goto(torture, ok == true, ok, done,
4179 "setup copy chunk error\n");
4181 /* copy all src file data (via a single chunk desc) */
4182 cc_copy.chunks[0].source_off = 0;
4183 cc_copy.chunks[0].target_off = 0;
4184 cc_copy.chunks[0].length = 256;
4186 ndr_ret = ndr_push_struct_blob(
4187 &io.smb2.in.out, tmp_ctx, &cc_copy,
4188 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4190 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4191 "ndr_push_srv_copychunk_copy\n");
4193 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4194 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4195 "FSCTL_SRV_COPYCHUNK\n");
4197 ndr_ret = ndr_pull_struct_blob(
4198 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4199 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4201 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4202 "ndr_pull_srv_copychunk_rsp\n");
4204 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4205 1, /* chunks written */
4206 0, /* chunk bytes unsuccessfully written */
4207 256); /* total bytes written */
4208 torture_assert_goto(torture, ok == true, ok, done,
4209 "bad copy chunk response data\n");
4211 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
4212 if (!ok) {
4213 torture_fail(torture, "inconsistent file data\n");
4216 done:
4217 if (!smb2_util_handle_empty(src_h)) {
4218 smb2_util_close(tree, src_h);
4220 if (!smb2_util_handle_empty(dest_h)) {
4221 smb2_util_close(tree, dest_h);
4224 return ok;
4227 static bool copy_finderinfo_stream(struct torture_context *torture,
4228 struct smb2_tree *tree,
4229 TALLOC_CTX *tmp_ctx,
4230 const char *src_name,
4231 const char *dst_name)
4233 struct smb2_handle src_h = {{0}};
4234 struct smb2_handle dest_h = {{0}};
4235 NTSTATUS status;
4236 union smb_ioctl io;
4237 struct srv_copychunk_copy cc_copy;
4238 struct srv_copychunk_rsp cc_rsp;
4239 enum ndr_err_code ndr_ret;
4240 const char *type_creator = "SMB,OLE!";
4241 AfpInfo *info = NULL;
4242 const char *src_name_afpinfo = NULL;
4243 const char *dst_name_afpinfo = NULL;
4244 bool ok = false;
4246 src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
4247 AFPINFO_STREAM);
4248 torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
4249 "talloc_asprintf failed\n");
4251 dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
4252 AFPINFO_STREAM);
4253 torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
4254 "talloc_asprintf failed\n");
4256 info = torture_afpinfo_new(tmp_ctx);
4257 torture_assert_not_null_goto(torture, info, ok, done,
4258 "torture_afpinfo_new failed\n");
4260 memcpy(info->afpi_FinderInfo, type_creator, 8);
4261 ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
4262 torture_assert_goto(torture, ok == true, ok, done,
4263 "torture_write_afpinfo failed\n");
4265 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4266 1, /* 1 chunk */
4267 src_name_afpinfo,
4268 &src_h, 0,
4269 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4270 dst_name_afpinfo,
4271 &dest_h, 0,
4272 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4273 &cc_copy,
4274 &io);
4275 torture_assert_goto(torture, ok == true, ok, done,
4276 "setup copy chunk error\n");
4278 /* copy all src file data (via a single chunk desc) */
4279 cc_copy.chunks[0].source_off = 0;
4280 cc_copy.chunks[0].target_off = 0;
4281 cc_copy.chunks[0].length = 60;
4283 ndr_ret = ndr_push_struct_blob(
4284 &io.smb2.in.out, tmp_ctx, &cc_copy,
4285 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4287 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4288 "ndr_push_srv_copychunk_copy\n");
4290 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4291 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4292 "FSCTL_SRV_COPYCHUNK\n");
4294 ndr_ret = ndr_pull_struct_blob(
4295 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4296 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4298 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4299 "ndr_pull_srv_copychunk_rsp\n");
4301 smb2_util_close(tree, src_h);
4302 ZERO_STRUCT(src_h);
4303 smb2_util_close(tree, dest_h);
4304 ZERO_STRUCT(dest_h);
4306 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4307 1, /* chunks written */
4308 0, /* chunk bytes unsuccessfully written */
4309 60); /* total bytes written */
4310 torture_assert_goto(torture, ok == true, ok, done,
4311 "bad copy chunk response data\n");
4313 ok = check_stream(tree, __location__, torture, tmp_ctx,
4314 dst_name, AFPINFO_STREAM,
4315 0, 60, 16, 8, type_creator);
4316 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
4318 done:
4319 if (!smb2_util_handle_empty(src_h)) {
4320 smb2_util_close(tree, src_h);
4322 if (!smb2_util_handle_empty(dest_h)) {
4323 smb2_util_close(tree, dest_h);
4326 return ok;
4329 static bool test_copy_chunk_streams(struct torture_context *torture,
4330 struct smb2_tree *tree)
4332 const char *src_name = "src";
4333 const char *dst_name = "dst";
4334 struct names {
4335 const char *src_sname;
4336 const char *dst_sname;
4337 } names[] = {
4338 { "src:foo", "dst:foo" },
4339 { "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
4341 int i;
4342 TALLOC_CTX *tmp_ctx = NULL;
4343 bool ok = false;
4345 tmp_ctx = talloc_new(tree);
4346 torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
4347 "torture_setup_file\n");
4349 smb2_util_unlink(tree, src_name);
4350 smb2_util_unlink(tree, dst_name);
4352 ok = torture_setup_file(torture, tree, src_name, false);
4353 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4354 ok = torture_setup_file(torture, tree, dst_name, false);
4355 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4357 for (i = 0; i < ARRAY_SIZE(names); i++) {
4358 ok = copy_one_stream(torture, tree, tmp_ctx,
4359 names[i].src_sname,
4360 names[i].dst_sname);
4361 torture_assert_goto(torture, ok == true, ok, done,
4362 "copy_one_stream failed\n");
4365 ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
4366 src_name, dst_name);
4367 torture_assert_goto(torture, ok == true, ok, done,
4368 "copy_finderinfo_stream failed\n");
4370 done:
4371 smb2_util_unlink(tree, src_name);
4372 smb2_util_unlink(tree, dst_name);
4373 talloc_free(tmp_ctx);
4374 return ok;
4378 * Note: This test depends on "vfs objects = catia fruit streams_xattr". For
4379 * some tests torture must be run on the host it tests and takes an additional
4380 * argument with the local path to the share:
4381 * "--option=torture:localdir=<SHAREPATH>".
4383 * When running against an OS X SMB server add "--option=torture:osx=true"
4385 struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
4387 struct torture_suite *suite = torture_suite_create(
4388 ctx, "fruit");
4390 suite->description = talloc_strdup(suite, "vfs_fruit tests");
4392 torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
4393 torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
4394 torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
4395 torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
4396 torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
4397 torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
4398 torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
4399 torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
4400 torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
4401 torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
4402 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
4403 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
4404 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
4405 torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
4406 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
4407 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
4408 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
4409 torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
4410 torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
4411 torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
4412 torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
4413 torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
4414 torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
4415 torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
4416 torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
4418 return suite;
4421 static bool test_stream_names_local(struct torture_context *tctx,
4422 struct smb2_tree *tree)
4424 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4425 NTSTATUS status;
4426 struct smb2_create create;
4427 struct smb2_handle h;
4428 const char *fname = BASEDIR "\\stream_names.txt";
4429 const char *sname1;
4430 bool ret;
4431 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
4432 const char *streams[] = {
4433 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
4434 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
4435 "::$DATA"
4437 const char *localdir = NULL;
4439 localdir = torture_setting_string(tctx, "localdir", NULL);
4440 if (localdir == NULL) {
4441 torture_skip(tctx, "Need localdir for test");
4444 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
4446 /* clean slate ...*/
4447 smb2_util_unlink(tree, fname);
4448 smb2_deltree(tree, fname);
4449 smb2_deltree(tree, BASEDIR);
4451 status = torture_smb2_testdir(tree, BASEDIR, &h);
4452 CHECK_STATUS(status, NT_STATUS_OK);
4453 smb2_util_close(tree, h);
4455 torture_comment(tctx, "(%s) testing stream names\n", __location__);
4456 ZERO_STRUCT(create);
4457 create.in.desired_access = SEC_FILE_WRITE_DATA;
4458 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4459 create.in.share_access =
4460 NTCREATEX_SHARE_ACCESS_DELETE|
4461 NTCREATEX_SHARE_ACCESS_READ|
4462 NTCREATEX_SHARE_ACCESS_WRITE;
4463 create.in.create_disposition = NTCREATEX_DISP_CREATE;
4464 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
4465 create.in.fname = sname1;
4467 status = smb2_create(tree, mem_ctx, &create);
4468 CHECK_STATUS(status, NT_STATUS_OK);
4469 smb2_util_close(tree, create.out.file.handle);
4471 ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
4472 "user.DosStream.bar:baz:$DATA",
4473 "data", strlen("data"));
4474 CHECK_VALUE(ret, true);
4476 ret = check_stream_list(tree, tctx, fname, 3, streams, false);
4477 CHECK_VALUE(ret, true);
4479 done:
4480 status = smb2_util_unlink(tree, fname);
4481 smb2_deltree(tree, BASEDIR);
4482 talloc_free(mem_ctx);
4484 return ret;
4487 struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
4489 struct torture_suite *suite = torture_suite_create(
4490 ctx, "fruit_netatalk");
4492 suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
4494 torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
4495 torture_suite_add_1smb2_test(suite, "stream names with locally created xattr", test_stream_names_local);
4497 return suite;
4500 struct torture_suite *torture_vfs_fruit_file_id(TALLOC_CTX *ctx)
4502 struct torture_suite *suite =
4503 torture_suite_create(ctx, "fruit_file_id");
4505 suite->description =
4506 talloc_strdup(suite, "vfs_fruit tests for on-disk file ID that "
4507 "require fruit:zero_file_id=yes");
4509 torture_suite_add_1smb2_test(suite, "zero file id if AAPL negotiated",
4510 test_zero_file_id);
4512 return suite;