torture: expand test "vfs.fruit.resource fork IO" to check size
[amitay/samba.git] / source4 / torture / vfs / fruit.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    vfs_fruit tests
5
6    Copyright (C) Ralph Boehme 2014
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "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"
33
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"
39 #include "libcli/security/dom_sid.h"
40 #include "../librpc/gen_ndr/ndr_security.h"
41 #include "libcli/security/secace.h"
42 #include "libcli/security/security_descriptor.h"
43
44 #define BASEDIR "vfs_fruit_dir"
45 #define FNAME_CC_SRC "testfsctl.dat"
46 #define FNAME_CC_DST "testfsctl2.dat"
47
48 #define CHECK_STATUS(status, correct) do { \
49         if (!NT_STATUS_EQUAL(status, correct)) { \
50                 torture_result(tctx, TORTURE_FAIL, \
51                     "(%s) Incorrect status %s - should be %s\n", \
52                     __location__, nt_errstr(status), nt_errstr(correct)); \
53                 ret = false; \
54                 goto done; \
55         }} while (0)
56
57 #define CHECK_VALUE(v, correct) do { \
58         if ((v) != (correct)) { \
59                 torture_result(tctx, TORTURE_FAIL, \
60                                "(%s) Incorrect value %s=%u - should be %u\n", \
61                                __location__, #v, (unsigned)v, (unsigned)correct); \
62                 ret = false; \
63                 goto done; \
64         }} while (0)
65
66 static bool check_stream_list(struct smb2_tree *tree,
67                               struct torture_context *tctx,
68                               const char *fname,
69                               int num_exp,
70                               const char **exp,
71                               bool is_dir);
72
73 static int qsort_string(char * const *s1, char * const *s2)
74 {
75         return strcmp(*s1, *s2);
76 }
77
78 static int qsort_stream(const struct stream_struct * s1, const struct stream_struct *s2)
79 {
80         return strcmp(s1->stream_name.s, s2->stream_name.s);
81 }
82
83 /*
84  * REVIEW:
85  * This is hokey, but what else can we do?
86  */
87 #if defined(HAVE_ATTROPEN) || defined(FREEBSD)
88 #define AFPINFO_EA_NETATALK "org.netatalk.Metadata"
89 #define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork"
90 #else
91 #define AFPINFO_EA_NETATALK "user.org.netatalk.Metadata"
92 #define AFPRESOURCE_EA_NETATALK "user.org.netatalk.ResourceFork"
93 #endif
94
95 /*
96 The metadata xattr char buf below contains the following attributes:
97
98 -------------------------------------------------------------------------------
99 Entry ID   : 00000008 : File Dates Info
100 Offset     : 00000162 : 354
101 Length     : 00000010 : 16
102
103 -DATE------:          : (GMT)                    : (Local)
104 create     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
105 modify     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
106 backup     : 80000000 : Unknown or Initial
107 access     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
108
109 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
110 00000000   : 1B 44 21 69 1B 44 21 69 80 00 00 00 1B 44 21 69 : .D!i.D!i.....D!i
111
112 -------------------------------------------------------------------------------
113 Entry ID   : 00000009 : Finder Info
114 Offset     : 0000007A : 122
115 Length     : 00000020 : 32
116
117 -FInfo-----:
118 Type       : 42415252 : BARR
119 Creator    : 464F4F4F : FOOO
120 isAlias    : 0
121 Invisible  : 1
122 hasBundle  : 0
123 nameLocked : 0
124 Stationery : 0
125 CustomIcon : 0
126 Reserved   : 0
127 Inited     : 0
128 NoINITS    : 0
129 Shared     : 0
130 SwitchLaunc: 0
131 Hidden Ext : 0
132 color      : 000      : none
133 isOnDesk   : 0
134 Location v : 0000     : 0
135 Location h : 0000     : 0
136 Fldr       : 0000     : ..
137
138 -FXInfo----:
139 Rsvd|IconID: 0000     : 0
140 Rsvd       : 0000     : ..
141 Rsvd       : 0000     : ..
142 Rsvd       : 0000     : ..
143 AreInvalid : 0
144 unknown bit: 0
145 unknown bit: 0
146 unknown bit: 0
147 unknown bit: 0
148 unknown bit: 0
149 unknown bit: 0
150 CustomBadge: 0
151 ObjctIsBusy: 0
152 unknown bit: 0
153 unknown bit: 0
154 unknown bit: 0
155 unknown bit: 0
156 RoutingInfo: 0
157 unknown bit: 0
158 unknown bit: 0
159 Rsvd|commnt: 0000     : 0
160 PutAway    : 00000000 : 0
161
162 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
163 00000000   : 42 41 52 52 46 4F 4F 4F 40 00 00 00 00 00 00 00 : BARRFOOO@.......
164 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
165
166 -------------------------------------------------------------------------------
167 Entry ID   : 0000000E : AFP File Info
168 Offset     : 00000172 : 370
169 Length     : 00000004 : 4
170
171 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
172 00000000   : 00 00 01 A1                                     : ....
173  */
174
175 char metadata_xattr[] = {
176         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
177         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179         0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
180         0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181         0x00, 0x08, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00,
182         0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
183         0x00, 0x7a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
184         0x00, 0x0e, 0x00, 0x00, 0x01, 0x72, 0x00, 0x00,
185         0x00, 0x04, 0x80, 0x44, 0x45, 0x56, 0x00, 0x00,
186         0x01, 0x76, 0x00, 0x00, 0x00, 0x08, 0x80, 0x49,
187         0x4e, 0x4f, 0x00, 0x00, 0x01, 0x7e, 0x00, 0x00,
188         0x00, 0x08, 0x80, 0x53, 0x59, 0x4e, 0x00, 0x00,
189         0x01, 0x86, 0x00, 0x00, 0x00, 0x08, 0x80, 0x53,
190         0x56, 0x7e, 0x00, 0x00, 0x01, 0x8e, 0x00, 0x00,
191         0x00, 0x04, 0x42, 0x41, 0x52, 0x52, 0x46, 0x4f,
192         0x4f, 0x4f, 0x40, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
220         0x00, 0x00, 0x1b, 0x44, 0x21, 0x69, 0x1b, 0x44,
221         0x21, 0x69, 0x80, 0x00, 0x00, 0x00, 0x1b, 0x44,
222         0x21, 0x69, 0x00, 0x00, 0x01, 0xa1, 0x00, 0xfd,
223         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x20,
224         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xe3,
225         0x86, 0x53, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x01,
226         0x00, 0x00
227 };
228
229 /*
230 The buf below contains the following AppleDouble encoded data:
231
232 -------------------------------------------------------------------------------
233 MagicNumber: 00051607                                        : AppleDouble
234 Version    : 00020000                                        : Version 2
235 Filler     : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
236 Num. of ent: 0002                                            : 2
237
238 -------------------------------------------------------------------------------
239 Entry ID   : 00000009 : Finder Info
240 Offset     : 00000032 : 50
241 Length     : 00000EB0 : 3760
242
243 -FInfo-----:
244 Type       : 54455354 : TEST
245 Creator    : 534C4F57 : SLOW
246 isAlias    : 0
247 Invisible  : 0
248 hasBundle  : 0
249 nameLocked : 0
250 Stationery : 0
251 CustomIcon : 0
252 Reserved   : 0
253 Inited     : 0
254 NoINITS    : 0
255 Shared     : 0
256 SwitchLaunc: 0
257 Hidden Ext : 0
258 color      : 100      : blue
259 isOnDesk   : 0
260 Location v : 0000     : 0
261 Location h : 0000     : 0
262 Fldr       : 0000     : ..
263
264 -FXInfo----:
265 Rsvd|IconID: 0000     : 0
266 Rsvd       : 0000     : ..
267 Rsvd       : 0000     : ..
268 Rsvd       : 0000     : ..
269 AreInvalid : 0
270 unknown bit: 0
271 unknown bit: 0
272 unknown bit: 0
273 unknown bit: 0
274 unknown bit: 0
275 unknown bit: 0
276 CustomBadge: 0
277 ObjctIsBusy: 0
278 unknown bit: 0
279 unknown bit: 0
280 unknown bit: 0
281 unknown bit: 0
282 RoutingInfo: 0
283 unknown bit: 0
284 unknown bit: 0
285 Rsvd|commnt: 0000     : 0
286 PutAway    : 00000000 : 0
287
288 -EA--------:
289 pad        : 0000     : ..
290 magic      : 41545452 : ATTR
291 debug_tag  : 53D4580C : 1406425100
292 total_size : 00000EE2 : 3810
293 data_start : 000000BC : 188
294 data_length: 0000005E : 94
295 reserved[0]: 00000000 : ....
296 reserved[1]: 00000000 : ....
297 reserved[2]: 00000000 : ....
298 flags      : 0000     : ..
299 num_attrs  : 0002     : 2
300 -EA ENTRY--:
301 offset     : 000000BC : 188
302 length     : 0000005B : 91
303 flags      : 0000     : ..
304 namelen    : 24       : 36
305 -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
306 00000000   : 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 61 : com.apple.metada
307 00000010   : 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 54 : ta:_kMDItemUserT
308 00000020   : 61 67 73 00                                     : ags.
309 -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
310 00000000   : 62 70 6C 69 73 74 30 30 A5 01 02 03 04 05 54 74 : bplist00......Tt
311 00000010   : 65 73 74 66 00 47 00 72 00 FC 00 6E 00 0A 00 32 : estf.G.r...n...2
312 00000020   : 56 4C 69 6C 61 0A 33 56 47 65 6C 62 0A 35 56 42 : VLila.3VGelb.5VB
313 00000030   : 6C 61 75 0A 34 08 0E 13 20 27 2E 00 00 00 00 00 : lau.4... '......
314 00000040   : 00 01 01 00 00 00 00 00 00 00 06 00 00 00 00 00 : ................
315 00000050   : 00 00 00 00 00 00 00 00 00 00 35                : ..........5
316 -EA ENTRY--:
317 offset     : 00000117 : 279
318 length     : 00000003 : 3
319 flags      : 0000     : ..
320 namelen    : 08       : 8
321 -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
322 00000000   : 66 6F 6F 3A 62 61 72 00                         : foo:bar.
323 -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
324 00000000   : 62 61 7A                                        : baz
325
326 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
327 00000000   : 54 45 53 54 53 4C 4F 57 00 08 00 00 00 00 00 00 : TESTSLOW........
328 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
329 00000020   : 00 00 41 54 54 52 53 D4 58 0C 00 00 0E E2 00 00 : ..ATTRS.X.......
330 00000030   : 00 BC 00 00 00 5E 00 00 00 00 00 00 00 00 00 00 : .....^..........
331 00000040   : 00 00 00 00 00 02 00 00 00 BC 00 00 00 5B 00 00 : .............[..
332 00000050   : 24 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 : $com.apple.metad
333 00000060   : 61 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 : ata:_kMDItemUser
334 00000070   : 54 61 67 73 00 00 00 00 01 17 00 00 00 03 00 00 : Tags............
335 00000080   : 08 66 6F 6F 3A 62 61 72 00 66 62 70 6C 69 73 74 : .foo:bar.fbplist
336 00000090   : 30 30 A5 01 02 03 04 05 54 74 65 73 74 66 00 47 : 00......Ttestf.G
337 000000A0   : 00 72 00 FC 00 6E 00 0A 00 32 56 4C 69 6C 61 0A : .r...n...2VLila.
338 000000B0   : 33 56 47 65 6C 62 0A 35 56 42 6C 61 75 0A 34 08 : 3VGelb.5VBlau.4.
339 000000C0   : 0E 13 20 27 2E 00 00 00 00 00 00 01 01 00 00 00 : .. '............
340 000000D0   : 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 : ................
341 000000E0   : 00 00 00 00 35 62 61 7A 00 00 00 00 00 00 00 00 : ....5baz........
342 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
343 ... all zeroes ...
344 00000EA0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
345
346 -------------------------------------------------------------------------------
347 Entry ID   : 00000002 : Resource Fork
348 Offset     : 00000EE2 : 3810
349 Length     : 0000011E : 286
350
351 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
352 00000000   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
353 00000010   : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo
354 00000020   : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
355 00000030   : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 :  left blank   ..
356 00000040   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
357 00000050   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
358 00000060   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
359 00000070   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
360 00000080   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
361 00000090   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
362 000000A0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
363 000000B0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
364 000000C0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
365 000000D0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
366 000000E0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
367 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
368 00000100   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
369 00000110   : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF       : ..............
370
371 It was created with:
372 $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
373 */
374 static char osx_adouble_w_xattr[] = {
375         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
376         0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
377         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
378         0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
379         0x00, 0x32, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00,
380         0x00, 0x02, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00,
381         0x01, 0x1e, 0x54, 0x45, 0x53, 0x54, 0x53, 0x4c,
382         0x4f, 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
383         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385         0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
386         0x53, 0xd4, 0x58, 0x0c, 0x00, 0x00, 0x0e, 0xe2,
387         0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5e,
388         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
390         0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5b,
391         0x00, 0x00, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
392         0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x65, 0x74,
393         0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x5f, 0x6b,
394         0x4d, 0x44, 0x49, 0x74, 0x65, 0x6d, 0x55, 0x73,
395         0x65, 0x72, 0x54, 0x61, 0x67, 0x73, 0x00, 0x00,
396         0x00, 0x00, 0x01, 0x17, 0x00, 0x00, 0x00, 0x03,
397         0x00, 0x00, 0x08, 0x66, 0x6f, 0x6f, 0x3a, 0x62,
398         0x61, 0x72, 0x00, 0x66, 0x62, 0x70, 0x6c, 0x69,
399         0x73, 0x74, 0x30, 0x30, 0xa5, 0x01, 0x02, 0x03,
400         0x04, 0x05, 0x54, 0x74, 0x65, 0x73, 0x74, 0x66,
401         0x00, 0x47, 0x00, 0x72, 0x00, 0xfc, 0x00, 0x6e,
402         0x00, 0x0a, 0x00, 0x32, 0x56, 0x4c, 0x69, 0x6c,
403         0x61, 0x0a, 0x33, 0x56, 0x47, 0x65, 0x6c, 0x62,
404         0x0a, 0x35, 0x56, 0x42, 0x6c, 0x61, 0x75, 0x0a,
405         0x34, 0x08, 0x0e, 0x13, 0x20, 0x27, 0x2e, 0x00,
406         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
407         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
408         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x62,
410         0x61, 0x7a, 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, 0x00, 0x00, 0x00, 0x00,
848         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
849         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
850         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
851         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
852         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
853         0x00, 0x1e, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72,
854         0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20,
855         0x66, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
856         0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
857         0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
858         0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
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, 0x00, 0x00, 0x00, 0x00,
880         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
881         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
882         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
883         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
884         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
885         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
886         0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
887 };
888
889 /*
890  * The buf below contains the following AppleDouble encoded data:
891  *
892  * -------------------------------------------------------------------------------
893  * MagicNumber: 00051607                                        : AppleDouble
894  * Version    : 00020000                                        : Version 2
895  * Filler     : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
896  * Num. of ent: 0002                                            : 2
897  *
898  * -------------------------------------------------------------------------------
899  * Entry ID   : 00000002 : Resource Fork
900  * Offset     : 00000052 : 82
901  * Length     : 0000011E : 286
902  *
903  * -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
904  * 00000000   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
905  * 00000010   : F0 F1 F2 F3 F5 F5 F6 F7 F8 F9 FA FB FC FD FE FF : ................
906  * 00000020   : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
907  * 00000030   : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 :  left blank   ..
908  * 00000040   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
909  * 00000050   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
910  * 00000060   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
911  * 00000070   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
912  * 00000080   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
913  * 00000090   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
914  * 000000A0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
915  * 000000B0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
916  * 000000C0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
917  * 000000D0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
918  * 000000E0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
919  * 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
920  * 00000100   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
921  * 00000110   : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF       : ..............
922  *
923  * Entry ID   : 00000009 : Finder Info
924  * Offset     : 00000032 : 50
925  * Length     : 00000020 : 32
926  *
927  * -NOTE------: cannot detect whether FInfo or DInfo. assume FInfo.
928  *
929  * -FInfo-----:
930  * Type       : 57415645 : WAVE
931  * Creator    : 5054756C : PTul
932  * isAlias    : 0
933  * Invisible  : 0
934  * hasBundle  : 0
935  * nameLocked : 0
936  * Stationery : 0
937  * CustomIcon : 0
938  * Reserved   : 0
939  * Inited     : 0
940  * NoINITS    : 0
941  * Shared     : 0
942  * SwitchLaunc: 0
943  * Hidden Ext : 0
944  * color      : 000      : none
945  * isOnDesk   : 0
946  * Location v : 0000     : 0
947  * Location h : 0000     : 0
948  * Fldr       : 0000     : ..
949  *
950  * -FXInfo----:
951  * Rsvd|IconID: 0000     : 0
952  * Rsvd       : 0000     : ..
953  * Rsvd       : 0000     : ..
954  * Rsvd       : 0000     : ..
955  * AreInvalid : 0
956  * unknown bit: 0
957  * unknown bit: 0
958  * unknown bit: 0
959  * unknown bit: 0
960  * unknown bit: 0
961  * unknown bit: 0
962  * CustomBadge: 0
963  * ObjctIsBusy: 0
964  * unknown bit: 0
965  * unknown bit: 0
966  * unknown bit: 0
967  * unknown bit: 0
968  * RoutingInfo: 0
969  * unknown bit: 0
970  * unknown bit: 0
971  * Rsvd|commnt: 0000     : 0
972  * PutAway    : 00000000 : 0
973  *
974  * -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
975  * 00000000   : 57 41 56 45 50 54 75 6C 00 00 00 00 00 00 00 00 : WAVEPTul........
976  * 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
977  *  *
978  * It was created with:
979  * $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
980  */
981 static char osx_adouble_without_xattr[] = {
982         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
983         0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
984         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
985         0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
986         0x00, 0x52, 0x00, 0x00, 0x01, 0x1e, 0x00, 0x00,
987         0x00, 0x09, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00,
988         0x00, 0x20, 0x57, 0x41, 0x56, 0x45, 0x50, 0x54,
989         0x75, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
990         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
991         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
992         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
993         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
994         0x00, 0x1e, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
995         0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd,
996         0xfe, 0xff, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
997         0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
998         0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
999         0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
1000         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1001         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1002         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1003         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1004         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1005         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1006         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1007         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1008         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1009         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1010         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1011         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1012         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1013         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1014         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1015         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1016         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1017         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1018         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1019         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1020         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1021         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1022         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1023         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1024         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1025         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1026         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1027         0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
1028 };
1029
1030 /*
1031 The buf below contains the following AppleDouble encoded data:
1032
1033 -------------------------------------------------------------------------------
1034 MagicNumber: 00051607                                        : AppleDouble
1035 Version    : 00020000                                        : Version 2
1036 Filler     : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
1037 Num. of ent: 0002                                            : 2
1038
1039 -------------------------------------------------------------------------------
1040 Entry ID   : 00000009 : Finder Info
1041 Offset     : 00000032 : 50
1042 Length     : 00000EB0 : 3760
1043
1044 -FInfo-----:
1045 Type       : 54455354 : TEST
1046 Creator    : 534C4F57 : SLOW
1047 isAlias    : 0
1048 Invisible  : 0
1049 hasBundle  : 0
1050 nameLocked : 0
1051 Stationery : 0
1052 CustomIcon : 0
1053 Reserved   : 0
1054 Inited     : 0
1055 NoINITS    : 0
1056 Shared     : 0
1057 SwitchLaunc: 0
1058 Hidden Ext : 0
1059 color      : 100      : blue
1060 isOnDesk   : 0
1061 Location v : 0000     : 0
1062 Location h : 0000     : 0
1063 Fldr       : 0000     : ..
1064
1065 -FXInfo----:
1066 Rsvd|IconID: 0000     : 0
1067 Rsvd       : 0000     : ..
1068 Rsvd       : 0000     : ..
1069 Rsvd       : 0000     : ..
1070 AreInvalid : 0
1071 unknown bit: 0
1072 unknown bit: 0
1073 unknown bit: 0
1074 unknown bit: 0
1075 unknown bit: 0
1076 unknown bit: 0
1077 CustomBadge: 0
1078 ObjctIsBusy: 0
1079 unknown bit: 0
1080 unknown bit: 0
1081 unknown bit: 0
1082 unknown bit: 0
1083 RoutingInfo: 0
1084 unknown bit: 0
1085 unknown bit: 0
1086 Rsvd|commnt: 0000     : 0
1087 PutAway    : 00000000 : 0
1088
1089 -EA--------:
1090 pad        : 0000     : ..
1091 magic      : 41545452 : ATTR
1092 debug_tag  : 53D4580C : 1406425100
1093 total_size : 00000EE2 : 3810
1094 data_start : 000000BC : 188
1095 data_length: 0000005E : 94
1096 reserved[0]: 00000000 : ....
1097 reserved[1]: 00000000 : ....
1098 reserved[2]: 00000000 : ....
1099 flags      : 0000     : ..
1100 num_attrs  : 0002     : 2
1101 -EA ENTRY--:
1102 offset     : 000000BC : 188
1103 length     : 0000005B : 91
1104 flags      : 0000     : ..
1105 namelen    : 24       : 36
1106 -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
1107 00000000   : 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 61 : com.apple.metada
1108 00000010   : 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 54 : ta:_kMDItemUserT
1109 00000020   : 61 67 73 00                                     : ags.
1110 -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
1111 00000000   : 62 70 6C 69 73 74 30 30 A5 01 02 03 04 05 54 74 : bplist00......Tt
1112 00000010   : 65 73 74 66 00 47 00 72 00 FC 00 6E 00 0A 00 32 : estf.G.r...n...2
1113 00000020   : 56 4C 69 6C 61 0A 33 56 47 65 6C 62 0A 35 56 42 : VLila.3VGelb.5VB
1114 00000030   : 6C 61 75 0A 34 08 0E 13 20 27 2E 00 00 00 00 00 : lau.4... '......
1115 00000040   : 00 01 01 00 00 00 00 00 00 00 06 00 00 00 00 00 : ................
1116 00000050   : 00 00 00 00 00 00 00 00 00 00 35                : ..........5
1117 -EA ENTRY--:
1118 offset     : 00000117 : 279
1119 length     : 00000003 : 3
1120 flags      : 0000     : ..
1121 namelen    : 08       : 8
1122 -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
1123 00000000   : 66 6F 6F 3A 62 61 72 00                         : foo:bar.
1124 -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
1125 00000000   : 62 61 7A                                        : baz
1126
1127 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
1128 00000000   : 54 45 53 54 53 4C 4F 57 00 08 00 00 00 00 00 00 : TESTSLOW........
1129 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1130 00000020   : 00 00 41 54 54 52 53 D4 58 0C 00 00 0E E2 00 00 : ..ATTRS.X.......
1131 00000030   : 00 BC 00 00 00 5E 00 00 00 00 00 00 00 00 00 00 : .....^..........
1132 00000040   : 00 00 00 00 00 02 00 00 00 BC 00 00 00 5B 00 00 : .............[..
1133 00000050   : 24 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 : $com.apple.metad
1134 00000060   : 61 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 : ata:_kMDItemUser
1135 00000070   : 54 61 67 73 00 00 00 00 01 17 00 00 00 03 00 00 : Tags............
1136 00000080   : 08 66 6F 6F 3A 62 61 72 00 66 62 70 6C 69 73 74 : .foo:bar.fbplist
1137 00000090   : 30 30 A5 01 02 03 04 05 54 74 65 73 74 66 00 47 : 00......Ttestf.G
1138 000000A0   : 00 72 00 FC 00 6E 00 0A 00 32 56 4C 69 6C 61 0A : .r...n...2VLila.
1139 000000B0   : 33 56 47 65 6C 62 0A 35 56 42 6C 61 75 0A 34 08 : 3VGelb.5VBlau.4.
1140 000000C0   : 0E 13 20 27 2E 00 00 00 00 00 00 01 01 00 00 00 : .. '............
1141 000000D0   : 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 : ................
1142 000000E0   : 00 00 00 00 35 62 61 7A 00 00 00 00 00 00 00 00 : ....5baz........
1143 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1144 ... all zeroes ...
1145 00000EA0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1146
1147 -------------------------------------------------------------------------------
1148 Entry ID   : 00000002 : Resource Fork
1149 Offset     : 00000EE2 : 3810
1150 Length     : 0000011E : 286
1151
1152 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
1153 00000000   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
1154 00000010   : F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF : This resource fo
1155 00000020   : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
1156 00000030   : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 :  left blank   ..
1157 00000040   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1158 00000050   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1159 00000060   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1160 00000070   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1161 00000080   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1162 00000090   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1163 000000A0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1164 000000B0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1165 000000C0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1166 000000D0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1167 000000E0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1168 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
1169 00000100   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
1170 00000110   : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF       : ..............
1171
1172 It was created with:
1173 $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
1174 */
1175 static char osx_adouble_non_empty_rfork_w_xattr[] = {
1176         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
1177         0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
1178         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1179         0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
1180         0x00, 0x32, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00,
1181         0x00, 0x02, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00,
1182         0x01, 0x1e, 0x54, 0x45, 0x53, 0x54, 0x53, 0x4c,
1183         0x4f, 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
1184         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1185         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1186         0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
1187         0x53, 0xd4, 0x58, 0x0c, 0x00, 0x00, 0x0e, 0xe2,
1188         0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5e,
1189         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1190         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1191         0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5b,
1192         0x00, 0x00, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
1193         0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x65, 0x74,
1194         0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x5f, 0x6b,
1195         0x4d, 0x44, 0x49, 0x74, 0x65, 0x6d, 0x55, 0x73,
1196         0x65, 0x72, 0x54, 0x61, 0x67, 0x73, 0x00, 0x00,
1197         0x00, 0x00, 0x01, 0x17, 0x00, 0x00, 0x00, 0x03,
1198         0x00, 0x00, 0x08, 0x66, 0x6f, 0x6f, 0x3a, 0x62,
1199         0x61, 0x72, 0x00, 0x66, 0x62, 0x70, 0x6c, 0x69,
1200         0x73, 0x74, 0x30, 0x30, 0xa5, 0x01, 0x02, 0x03,
1201         0x04, 0x05, 0x54, 0x74, 0x65, 0x73, 0x74, 0x66,
1202         0x00, 0x47, 0x00, 0x72, 0x00, 0xfc, 0x00, 0x6e,
1203         0x00, 0x0a, 0x00, 0x32, 0x56, 0x4c, 0x69, 0x6c,
1204         0x61, 0x0a, 0x33, 0x56, 0x47, 0x65, 0x6c, 0x62,
1205         0x0a, 0x35, 0x56, 0x42, 0x6c, 0x61, 0x75, 0x0a,
1206         0x34, 0x08, 0x0e, 0x13, 0x20, 0x27, 0x2e, 0x00,
1207         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
1208         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
1209         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1210         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x62,
1211         0x61, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1212         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1213         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1214         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1215         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1216         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1217         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1218         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1219         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1220         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1221         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1222         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1223         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1224         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1225         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1226         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1227         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1228         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1229         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1230         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1231         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1232         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1233         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1234         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1235         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1236         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1237         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1238         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1239         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1240         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1241         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1242         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1243         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1244         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1245         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1246         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1247         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1248         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1249         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1250         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1251         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1252         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1253         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1254         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1255         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1256         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1257         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1258         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1259         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1260         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1261         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1262         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1263         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1264         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1265         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1266         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1267         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1268         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1269         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1270         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1271         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1272         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1273         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1274         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1275         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1276         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1277         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1278         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1279         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1280         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1281         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1282         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1283         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1284         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1285         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1286         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1287         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1288         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1289         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1290         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1291         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1292         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1293         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1294         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1295         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1296         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1297         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1298         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1299         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1300         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1301         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1302         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1303         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1304         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1305         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1306         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1307         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1308         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1309         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1310         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1311         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1312         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1313         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1314         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1315         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1316         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1317         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1318         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1319         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1320         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1321         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1322         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1323         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1324         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1325         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1326         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1327         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1328         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1329         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1330         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1331         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1332         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1333         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1334         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1335         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1336         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1337         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1338         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1339         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1340         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1341         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1342         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1343         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1344         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1345         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1346         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1347         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1348         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1349         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1350         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1351         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1352         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1353         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1354         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1355         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1356         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1357         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1358         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1359         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1361         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1362         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1363         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1365         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1366         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1367         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1368         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1369         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1370         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1371         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1372         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1373         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1374         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1375         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1376         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1377         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1378         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1379         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1380         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1381         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1382         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1383         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1384         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1385         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1386         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1387         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1388         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1389         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1390         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1391         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1392         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1393         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1394         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1395         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1396         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1397         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1398         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1399         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1400         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1401         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1402         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1403         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1404         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1405         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1406         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1407         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1408         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1409         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1410         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1411         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1412         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1413         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1414         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1415         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1416         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1417         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1418         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1419         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1420         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1421         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1422         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1423         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1424         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1425         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1426         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1427         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1428         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1429         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1430         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1431         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1432         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1433         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1434         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1435         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1436         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1437         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1438         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1439         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1440         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1441         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1442         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1443         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1444         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1445         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1446         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1447         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1448         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1449         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1450         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1451         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1452         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1453         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1454         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1455         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1456         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1457         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1458         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1459         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1460         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1461         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1462         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1463         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1464         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1465         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1466         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1467         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1468         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1469         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1470         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1471         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1472         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1473         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1474         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1475         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1476         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1477         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1478         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1479         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1480         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1481         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1482         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1483         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1484         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1485         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1486         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1487         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1488         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1489         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1490         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1491         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1492         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1493         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1494         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1495         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1496         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1497         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1498         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1499         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1500         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1501         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1502         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1503         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1504         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1505         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1506         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1507         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1508         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1509         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1510         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1511         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1512         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1513         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1514         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1515         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1516         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1517         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1518         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1519         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1520         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1521         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1522         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1523         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1524         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1525         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1526         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1527         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1528         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1529         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1530         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1531         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1532         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1533         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1534         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1535         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1536         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1537         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1538         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1539         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1540         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1541         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1542         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1543         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1544         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1545         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1546         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1547         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1548         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1549         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1550         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1551         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1552         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1553         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1554         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1555         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1556         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1557         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1558         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1559         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1560         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1561         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1562         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1563         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1564         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1565         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1566         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1567         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1568         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1569         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1570         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1571         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1572         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1573         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1574         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1575         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1576         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1577         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1578         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1579         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1580         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1581         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1582         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1583         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1584         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1585         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1586         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1587         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1588         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1589         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1590         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1591         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1592         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1593         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1594         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1595         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1596         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1597         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1598         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1599         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1600         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1601         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1602         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1603         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1604         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1605         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1606         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1607         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1608         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1609         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1610         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1611         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1612         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1613         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1614         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1615         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1616         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1617         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1618         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1619         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1620         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1621         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1622         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1623         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1624         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1625         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1626         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1627         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1628         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1629         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1630         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1631         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1632         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1633         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1634         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1635         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1636         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1637         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1638         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1639         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1640         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1641         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1642         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1643         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1644         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1645         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1646         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1647         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1648         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1649         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1650         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1651         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1652         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1653         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1654         0x00, 0x1e, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
1655         0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd,
1656         0xfe, 0xff, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
1657         0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
1658         0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
1659         0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
1660         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1661         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1662         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1663         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1664         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1665         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1666         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1667         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1668         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1669         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1670         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1671         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1672         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1673         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1674         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1675         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1676         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1677         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1678         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1679         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1680         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1681         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1682         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1683         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1684         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1685         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1686         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1687         0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
1688 };
1689
1690 /**
1691  * talloc and intialize an AfpInfo
1692  **/
1693 static AfpInfo *torture_afpinfo_new(TALLOC_CTX *mem_ctx)
1694 {
1695         AfpInfo *info;
1696
1697         info = talloc_zero(mem_ctx, AfpInfo);
1698         if (info == NULL) {
1699                 return NULL;
1700         }
1701
1702         info->afpi_Signature = AFP_Signature;
1703         info->afpi_Version = AFP_Version;
1704         info->afpi_BackupTime = AFP_BackupTime;
1705
1706         return info;
1707 }
1708
1709 /**
1710  * Pack AfpInfo into a talloced buffer
1711  **/
1712 static char *torture_afpinfo_pack(TALLOC_CTX *mem_ctx,
1713                                   AfpInfo *info)
1714 {
1715         char *buf;
1716
1717         buf = talloc_zero_array(mem_ctx, char, AFP_INFO_SIZE);
1718         if (buf == NULL) {
1719                 return NULL;
1720         }
1721
1722         RSIVAL(buf, 0, info->afpi_Signature);
1723         RSIVAL(buf, 4, info->afpi_Version);
1724         RSIVAL(buf, 12, info->afpi_BackupTime);
1725         memcpy(buf + 16, info->afpi_FinderInfo, sizeof(info->afpi_FinderInfo));
1726
1727         return buf;
1728 }
1729
1730 /**
1731  * Unpack AfpInfo
1732  **/
1733 #if 0
1734 static void torture_afpinfo_unpack(AfpInfo *info, char *data)
1735 {
1736         info->afpi_Signature = RIVAL(data, 0);
1737         info->afpi_Version = RIVAL(data, 4);
1738         info->afpi_BackupTime = RIVAL(data, 12);
1739         memcpy(info->afpi_FinderInfo, (const char *)data + 16,
1740                sizeof(info->afpi_FinderInfo));
1741 }
1742 #endif
1743
1744 static bool torture_write_afpinfo(struct smb2_tree *tree,
1745                                   struct torture_context *tctx,
1746                                   TALLOC_CTX *mem_ctx,
1747                                   const char *fname,
1748                                   AfpInfo *info)
1749 {
1750         struct smb2_handle handle;
1751         struct smb2_create io;
1752         NTSTATUS status;
1753         const char *full_name;
1754         char *infobuf;
1755         bool ret = true;
1756
1757         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, AFPINFO_STREAM_NAME);
1758         if (full_name == NULL) {
1759             torture_comment(tctx, "talloc_asprintf error\n");
1760             return false;
1761         }
1762         ZERO_STRUCT(io);
1763         io.in.desired_access = SEC_FILE_WRITE_DATA;
1764         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1765         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1766         io.in.create_options = 0;
1767         io.in.fname = full_name;
1768
1769         status = smb2_create(tree, mem_ctx, &io);
1770         CHECK_STATUS(status, NT_STATUS_OK);
1771
1772         handle = io.out.file.handle;
1773
1774         infobuf = torture_afpinfo_pack(mem_ctx, info);
1775         if (infobuf == NULL) {
1776                 return false;
1777         }
1778
1779         status = smb2_util_write(tree, handle, infobuf, 0, AFP_INFO_SIZE);
1780         CHECK_STATUS(status, NT_STATUS_OK);
1781
1782         smb2_util_close(tree, handle);
1783
1784 done:
1785         return ret;
1786 }
1787
1788 /**
1789  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1790  * compare against buffer 'value'
1791  **/
1792 static bool check_stream(struct smb2_tree *tree,
1793                          const char *location,
1794                          struct torture_context *tctx,
1795                          TALLOC_CTX *mem_ctx,
1796                          const char *fname,
1797                          const char *sname,
1798                          off_t read_offset,
1799                          size_t read_count,
1800                          off_t comp_offset,
1801                          size_t comp_count,
1802                          const char *value)
1803 {
1804         struct smb2_handle handle;
1805         struct smb2_create create;
1806         struct smb2_read r;
1807         NTSTATUS status;
1808         char *full_name;
1809         bool ret = true;
1810
1811         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1812         if (full_name == NULL) {
1813             torture_comment(tctx, "talloc_asprintf error\n");
1814             return false;
1815         }
1816         ZERO_STRUCT(create);
1817         create.in.desired_access = SEC_FILE_READ_DATA;
1818         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1819         create.in.create_disposition = NTCREATEX_DISP_OPEN;
1820         create.in.fname = full_name;
1821
1822         torture_comment(tctx, "Open stream %s\n", full_name);
1823
1824         status = smb2_create(tree, mem_ctx, &create);
1825         if (!NT_STATUS_IS_OK(status)) {
1826                 if (value == NULL) {
1827                         return true;
1828                 }
1829                 torture_comment(tctx, "Unable to open stream %s\n", full_name);
1830                 TALLOC_FREE(full_name);
1831                 return false;
1832         }
1833
1834         handle = create.out.file.handle;
1835         if (value == NULL) {
1836                 TALLOC_FREE(full_name);
1837                 smb2_util_close(tree, handle);
1838                 return true;
1839         }
1840
1841         ZERO_STRUCT(r);
1842         r.in.file.handle = handle;
1843         r.in.length      = read_count;
1844         r.in.offset      = read_offset;
1845
1846         status = smb2_read(tree, tree, &r);
1847
1848         torture_assert_ntstatus_ok_goto(
1849                 tctx, status, ret, done,
1850                 talloc_asprintf(tctx, "(%s) Failed to read %lu bytes from stream '%s'\n",
1851                                 location, (long)strlen(value), full_name));
1852
1853         torture_assert_goto(tctx, r.out.data.length == read_count, ret, done,
1854                             talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected %jd\n",
1855                                             (intmax_t)r.out.data.length, (intmax_t)read_count));
1856
1857         torture_assert_goto(
1858                 tctx, memcmp(r.out.data.data + comp_offset, value, comp_count) == 0,
1859                 ret, done,
1860                 talloc_asprintf(tctx, "(%s) Bad data in stream\n", location));
1861
1862 done:
1863         TALLOC_FREE(full_name);
1864         smb2_util_close(tree, handle);
1865         return ret;
1866 }
1867
1868 /**
1869  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1870  * compare against buffer 'value'
1871  **/
1872 static ssize_t read_stream(struct smb2_tree *tree,
1873                            const char *location,
1874                            struct torture_context *tctx,
1875                            TALLOC_CTX *mem_ctx,
1876                            const char *fname,
1877                            const char *sname,
1878                            off_t read_offset,
1879                            size_t read_count)
1880 {
1881         struct smb2_handle handle;
1882         struct smb2_create create;
1883         struct smb2_read r;
1884         NTSTATUS status;
1885         const char *full_name;
1886         bool ret = true;
1887
1888         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1889         if (full_name == NULL) {
1890             torture_comment(tctx, "talloc_asprintf error\n");
1891             return -1;
1892         }
1893         ZERO_STRUCT(create);
1894         create.in.desired_access = SEC_FILE_READ_DATA;
1895         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1896         create.in.create_disposition = NTCREATEX_DISP_OPEN;
1897         create.in.fname = full_name;
1898
1899         torture_comment(tctx, "Open stream %s\n", full_name);
1900
1901         status = smb2_create(tree, mem_ctx, &create);
1902         if (!NT_STATUS_IS_OK(status)) {
1903                 torture_comment(tctx, "Unable to open stream %s\n",
1904                                 full_name);
1905                 return -1;
1906         }
1907
1908         handle = create.out.file.handle;
1909
1910         ZERO_STRUCT(r);
1911         r.in.file.handle = handle;
1912         r.in.length      = read_count;
1913         r.in.offset      = read_offset;
1914
1915         status = smb2_read(tree, tree, &r);
1916         if (!NT_STATUS_IS_OK(status)) {
1917                 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
1918         }
1919
1920         smb2_util_close(tree, handle);
1921
1922 done:
1923         if (ret == false) {
1924                 return -1;
1925         }
1926         return r.out.data.length;
1927 }
1928
1929 /**
1930  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1931  * compare against buffer 'value'
1932  **/
1933 static bool write_stream(struct smb2_tree *tree,
1934                          const char *location,
1935                          struct torture_context *tctx,
1936                          TALLOC_CTX *mem_ctx,
1937                          const char *fname,
1938                          const char *sname,
1939                          off_t offset,
1940                          size_t size,
1941                          const char *value)
1942 {
1943         struct smb2_handle handle;
1944         struct smb2_create create;
1945         NTSTATUS status;
1946         const char *full_name;
1947
1948         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname ? sname : "");
1949         if (full_name == NULL) {
1950             torture_comment(tctx, "talloc_asprintf error\n");
1951             return false;
1952         }
1953         ZERO_STRUCT(create);
1954         create.in.desired_access = SEC_FILE_WRITE_DATA;
1955         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1956         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1957         create.in.fname = full_name;
1958
1959         status = smb2_create(tree, mem_ctx, &create);
1960         if (!NT_STATUS_IS_OK(status)) {
1961                 if (value == NULL) {
1962                         return true;
1963                 } else {
1964                         torture_comment(tctx, "Unable to open stream %s\n",
1965                             full_name);
1966                         sleep(10000000);
1967                         return false;
1968                 }
1969         }
1970
1971         handle = create.out.file.handle;
1972         if (value == NULL) {
1973                 return true;
1974         }
1975
1976         status = smb2_util_write(tree, handle, value, offset, size);
1977
1978         if (!NT_STATUS_IS_OK(status)) {
1979                 torture_comment(tctx, "(%s) Failed to write %lu bytes to "
1980                     "stream '%s'\n", location, (long)size, full_name);
1981                 return false;
1982         }
1983
1984         smb2_util_close(tree, handle);
1985         return true;
1986 }
1987
1988 static bool torture_setup_local_xattr(struct torture_context *tctx,
1989                                       const char *path_option,
1990                                       const char *name,
1991                                       const char *xattr,
1992                                       const char *metadata,
1993                                       size_t size)
1994 {
1995         int ret = true;
1996         int result;
1997         const char *spath;
1998         char *path;
1999
2000         spath = torture_setting_string(tctx, path_option, NULL);
2001         if (spath == NULL) {
2002                 printf("No sharepath for option %s\n", path_option);
2003                 return false;
2004         }
2005
2006         path = talloc_asprintf(tctx, "%s/%s", spath, name);
2007
2008         result = setxattr(path, xattr, metadata, size, 0);
2009         if (result != 0) {
2010                 ret = false;
2011         }
2012
2013         TALLOC_FREE(path);
2014
2015         return ret;
2016 }
2017
2018 /**
2019  * Create a file or directory
2020  **/
2021 static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree,
2022                                const char *name, bool dir)
2023 {
2024         struct smb2_create io;
2025         NTSTATUS status;
2026
2027         smb2_util_unlink(tree, name);
2028         ZERO_STRUCT(io);
2029         io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2030         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
2031         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2032         io.in.share_access =
2033                 NTCREATEX_SHARE_ACCESS_DELETE|
2034                 NTCREATEX_SHARE_ACCESS_READ|
2035                 NTCREATEX_SHARE_ACCESS_WRITE;
2036         io.in.create_options = 0;
2037         io.in.fname = name;
2038         if (dir) {
2039                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2040                 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
2041                 io.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
2042                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
2043         }
2044
2045         status = smb2_create(tree, mem_ctx, &io);
2046         if (!NT_STATUS_IS_OK(status)) {
2047                 return false;
2048         }
2049
2050         status = smb2_util_close(tree, io.out.file.handle);
2051         if (!NT_STATUS_IS_OK(status)) {
2052                 return false;
2053         }
2054
2055         return true;
2056 }
2057
2058 static bool enable_aapl(struct torture_context *tctx,
2059                         struct smb2_tree *tree)
2060 {
2061         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2062         NTSTATUS status;
2063         bool ret = true;
2064         struct smb2_create io;
2065         DATA_BLOB data;
2066         struct smb2_create_blob *aapl = NULL;
2067         uint32_t aapl_server_caps;
2068         uint32_t expected_scaps = (SMB2_CRTCTX_AAPL_UNIX_BASED |
2069                                    SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2070                                    SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
2071                                    SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2072         bool is_osx_server = torture_setting_bool(tctx, "osx", false);
2073
2074         ZERO_STRUCT(io);
2075         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
2076         io.in.file_attributes    = FILE_ATTRIBUTE_DIRECTORY;
2077         io.in.create_disposition = NTCREATEX_DISP_OPEN;
2078         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2079                               NTCREATEX_SHARE_ACCESS_READ |
2080                               NTCREATEX_SHARE_ACCESS_WRITE);
2081         io.in.fname = "";
2082
2083         /*
2084          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
2085          * controls behaviour of Apple's SMB2 extensions for the whole
2086          * session!
2087          */
2088
2089         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2090         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2091         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2092                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2093                              SMB2_CRTCTX_AAPL_MODEL_INFO));
2094         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2095                               SMB2_CRTCTX_AAPL_UNIX_BASED |
2096                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
2097
2098         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2099         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_blob_add");
2100
2101         status = smb2_create(tree, tctx, &io);
2102         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2103
2104         status = smb2_util_close(tree, io.out.file.handle);
2105         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close");
2106
2107         /*
2108          * Now check returned AAPL context
2109          */
2110         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
2111
2112         aapl = smb2_create_blob_find(&io.out.blobs,
2113                                      SMB2_CREATE_TAG_AAPL);
2114         torture_assert_goto(tctx, aapl != NULL, ret, done, "missing AAPL context");
2115
2116         if (!is_osx_server) {
2117                 size_t expected_aapl_ctx_size;
2118
2119                 expected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
2120
2121                 torture_assert_goto(
2122                         tctx, aapl->data.length == expected_aapl_ctx_size,
2123                         ret, done, "bad AAPL size");
2124         }
2125
2126         aapl_server_caps = BVAL(aapl->data.data, 16);
2127         torture_assert_goto(tctx, aapl_server_caps == expected_scaps,
2128                             ret, done, "bad AAPL caps");
2129
2130 done:
2131         talloc_free(mem_ctx);
2132         return ret;
2133 }
2134
2135 static bool test_read_netatalk_metadata(struct torture_context *tctx,
2136                                         struct smb2_tree *tree)
2137 {
2138         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2139         const char *fname = BASEDIR "\\torture_read_metadata";
2140         NTSTATUS status;
2141         struct smb2_handle testdirh;
2142         bool ret = true;
2143         ssize_t len;
2144         const char *localdir = NULL;
2145
2146         torture_comment(tctx, "Checking metadata access\n");
2147
2148         localdir = torture_setting_string(tctx, "localdir", NULL);
2149         if (localdir == NULL) {
2150                 torture_skip(tctx, "Need localdir for test");
2151         }
2152
2153         smb2_util_unlink(tree, fname);
2154
2155         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2156         CHECK_STATUS(status, NT_STATUS_OK);
2157         smb2_util_close(tree, testdirh);
2158
2159         ret = torture_setup_file(mem_ctx, tree, fname, false);
2160         if (ret == false) {
2161                 goto done;
2162         }
2163
2164         ret = torture_setup_local_xattr(tctx, "localdir",
2165                                         BASEDIR "/torture_read_metadata",
2166                                         AFPINFO_EA_NETATALK,
2167                                         metadata_xattr, sizeof(metadata_xattr));
2168         if (ret == false) {
2169                 goto done;
2170         }
2171
2172         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
2173                            0, 60, 0, 4, "AFP");
2174         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
2175
2176         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
2177                            0, 60, 16, 8, "BARRFOOO");
2178         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
2179
2180         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
2181                            16, 8, 0, 3, "AFP");
2182         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
2183
2184         /* Check reading offset and read size > sizeof(AFPINFO_STREAM) */
2185
2186         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
2187                           AFPINFO_STREAM, 0, 61);
2188         CHECK_VALUE(len, 60);
2189
2190         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
2191                           AFPINFO_STREAM, 59, 2);
2192         CHECK_VALUE(len, 2);
2193
2194         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
2195                           AFPINFO_STREAM, 60, 1);
2196         CHECK_VALUE(len, 1);
2197
2198         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
2199                           AFPINFO_STREAM, 61, 1);
2200         CHECK_VALUE(len, 0);
2201
2202 done:
2203         smb2_deltree(tree, BASEDIR);
2204         talloc_free(mem_ctx);
2205         return ret;
2206 }
2207
2208 static bool test_read_afpinfo(struct torture_context *tctx,
2209                               struct smb2_tree *tree)
2210 {
2211         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2212         const char *fname = BASEDIR "\\torture_read_metadata";
2213         NTSTATUS status;
2214         struct smb2_handle testdirh;
2215         bool ret = true;
2216         ssize_t len;
2217         AfpInfo *info;
2218         const char *type_creator = "SMB,OLE!";
2219
2220         torture_comment(tctx, "Checking metadata access\n");
2221
2222         smb2_util_unlink(tree, fname);
2223
2224         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2225         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
2226         smb2_util_close(tree, testdirh);
2227
2228         ret = torture_setup_file(mem_ctx, tree, fname, false);
2229         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
2230
2231         info = torture_afpinfo_new(mem_ctx);
2232         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
2233
2234         memcpy(info->afpi_FinderInfo, type_creator, 8);
2235         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2236         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
2237
2238         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
2239                            0, 60, 0, 4, "AFP");
2240         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
2241
2242         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
2243                            0, 60, 16, 8, type_creator);
2244         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
2245
2246         /*
2247          * OS X ignores offset <= 60 and treats the as
2248          * offset=0. Reading from offsets > 60 returns EOF=0.
2249          */
2250
2251         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
2252                            16, 8, 0, 8, "AFP\0\0\0\001\0");
2253         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
2254
2255         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
2256                           AFPINFO_STREAM, 0, 61);
2257         torture_assert_goto(tctx, len == 60, ret, done, "read_stream failed");
2258
2259         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
2260                           AFPINFO_STREAM, 59, 2);
2261         torture_assert_goto(tctx, len == 2, ret, done, "read_stream failed");
2262
2263         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
2264                            59, 2, 0, 2, "AF");
2265         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
2266
2267         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
2268                           AFPINFO_STREAM, 60, 1);
2269         torture_assert_goto(tctx, len == 1, ret, done, "read_stream failed");
2270
2271         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
2272                            60, 1, 0, 1, "A");
2273         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
2274
2275         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
2276                           AFPINFO_STREAM, 61, 1);
2277         torture_assert_goto(tctx, len == 0, ret, done, "read_stream failed");
2278
2279 done:
2280         smb2_util_unlink(tree, fname);
2281         smb2_deltree(tree, BASEDIR);
2282         talloc_free(mem_ctx);
2283         return ret;
2284 }
2285
2286 static bool test_write_atalk_metadata(struct torture_context *tctx,
2287                                       struct smb2_tree *tree)
2288 {
2289         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2290         const char *fname = BASEDIR "\\torture_write_metadata";
2291         const char *type_creator = "SMB,OLE!";
2292         NTSTATUS status;
2293         struct smb2_handle testdirh;
2294         bool ret = true;
2295         AfpInfo *info;
2296
2297         smb2_deltree(tree, BASEDIR);
2298         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2299         CHECK_STATUS(status, NT_STATUS_OK);
2300         smb2_util_close(tree, testdirh);
2301
2302         ret = torture_setup_file(mem_ctx, tree, fname, false);
2303         if (ret == false) {
2304                 goto done;
2305         }
2306
2307         info = torture_afpinfo_new(mem_ctx);
2308         if (info == NULL) {
2309                 goto done;
2310         }
2311
2312         memcpy(info->afpi_FinderInfo, type_creator, 8);
2313         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2314         ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
2315                             0, 60, 16, 8, type_creator);
2316
2317 done:
2318         smb2_util_unlink(tree, fname);
2319         smb2_deltree(tree, BASEDIR);
2320         talloc_free(mem_ctx);
2321         return ret;
2322 }
2323
2324 static bool test_write_atalk_rfork_io(struct torture_context *tctx,
2325                                       struct smb2_tree *tree)
2326 {
2327         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2328         const char *fname = BASEDIR "\\torture_write_rfork_io";
2329         const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
2330         const char *rfork_content = "1234567890";
2331         NTSTATUS status;
2332         struct smb2_handle testdirh;
2333         bool ret = true;
2334
2335         union smb_open io;
2336         struct smb2_handle filehandle;
2337         union smb_fileinfo finfo;
2338         union smb_setfileinfo sinfo;
2339
2340         smb2_util_unlink(tree, fname);
2341
2342         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2343         CHECK_STATUS(status, NT_STATUS_OK);
2344         smb2_util_close(tree, testdirh);
2345
2346         ret = torture_setup_file(mem_ctx, tree, fname, false);
2347         if (ret == false) {
2348                 goto done;
2349         }
2350
2351         torture_comment(tctx, "(%s) writing to resource fork\n",
2352             __location__);
2353
2354         ret &= write_stream(tree, __location__, tctx, mem_ctx,
2355                             fname, AFPRESOURCE_STREAM_NAME,
2356                             10, 10, rfork_content);
2357
2358         ret &= check_stream(tree, __location__, tctx, mem_ctx,
2359                             fname, AFPRESOURCE_STREAM_NAME,
2360                             0, 20, 10, 10, rfork_content);
2361
2362         /* Check size after write */
2363
2364         ZERO_STRUCT(io);
2365         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
2366         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
2367                 SEC_FILE_WRITE_ATTRIBUTE;
2368         io.smb2.in.fname = rfork;
2369         status = smb2_create(tree, mem_ctx, &(io.smb2));
2370         CHECK_STATUS(status, NT_STATUS_OK);
2371         filehandle = io.smb2.out.file.handle;
2372
2373         torture_comment(tctx, "(%s) check resource fork size after write\n",
2374             __location__);
2375
2376         ZERO_STRUCT(finfo);
2377         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2378         finfo.generic.in.file.handle = filehandle;
2379         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
2380         CHECK_STATUS(status, NT_STATUS_OK);
2381         if (finfo.all_info.out.size != 20) {
2382                 torture_result(tctx, TORTURE_FAIL,
2383                                "(%s) Incorrect resource fork size\n",
2384                                __location__);
2385                 ret = false;
2386                 smb2_util_close(tree, filehandle);
2387                 goto done;
2388         }
2389         smb2_util_close(tree, filehandle);
2390
2391         /* Write at large offset */
2392
2393         torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
2394                         __location__);
2395
2396         ret &= write_stream(tree, __location__, tctx, mem_ctx,
2397                             fname, AFPRESOURCE_STREAM_NAME,
2398                             (off_t)64*1024*1024, 10, rfork_content);
2399
2400         /* Check size after write */
2401
2402         ZERO_STRUCT(io);
2403         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
2404         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
2405                 SEC_FILE_WRITE_ATTRIBUTE;
2406         io.smb2.in.fname = rfork;
2407         status = smb2_create(tree, mem_ctx, &(io.smb2));
2408         CHECK_STATUS(status, NT_STATUS_OK);
2409         filehandle = io.smb2.out.file.handle;
2410
2411         torture_comment(tctx, "(%s) check resource fork size after write\n",
2412             __location__);
2413
2414         ZERO_STRUCT(finfo);
2415         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2416         finfo.generic.in.file.handle = filehandle;
2417         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
2418         CHECK_STATUS(status, NT_STATUS_OK);
2419         if (finfo.all_info.out.size != 64*1024*1024 + 10) {
2420                 torture_result(tctx, TORTURE_FAIL,
2421                                "(%s) Incorrect resource fork size\n",
2422                                __location__);
2423                 ret = false;
2424                 smb2_util_close(tree, filehandle);
2425                 goto done;
2426         }
2427         smb2_util_close(tree, filehandle);
2428
2429         ret &= check_stream(tree, __location__, tctx, mem_ctx,
2430                             fname, AFPRESOURCE_STREAM_NAME,
2431                             (off_t)64*1024*1024, 10, 0, 10, rfork_content);
2432
2433         /* Truncate back to size of 1 byte */
2434
2435         torture_comment(tctx, "(%s) truncate resource fork and check size\n",
2436                         __location__);
2437
2438         ZERO_STRUCT(io);
2439         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
2440         io.smb2.in.desired_access = SEC_FILE_ALL;
2441         io.smb2.in.fname = rfork;
2442         status = smb2_create(tree, mem_ctx, &(io.smb2));
2443         CHECK_STATUS(status, NT_STATUS_OK);
2444         filehandle = io.smb2.out.file.handle;
2445
2446         ZERO_STRUCT(sinfo);
2447         sinfo.end_of_file_info.level =
2448                 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
2449         sinfo.end_of_file_info.in.file.handle = filehandle;
2450         sinfo.end_of_file_info.in.size = 1;
2451         status = smb2_setinfo_file(tree, &sinfo);
2452         CHECK_STATUS(status, NT_STATUS_OK);
2453
2454         smb2_util_close(tree, filehandle);
2455
2456         /* Now check size */
2457         ZERO_STRUCT(io);
2458         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
2459         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
2460                 SEC_FILE_WRITE_ATTRIBUTE;
2461         io.smb2.in.fname = rfork;
2462         status = smb2_create(tree, mem_ctx, &(io.smb2));
2463         CHECK_STATUS(status, NT_STATUS_OK);
2464         filehandle = io.smb2.out.file.handle;
2465
2466         ZERO_STRUCT(finfo);
2467         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2468         finfo.generic.in.file.handle = filehandle;
2469         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
2470         CHECK_STATUS(status, NT_STATUS_OK);
2471         if (finfo.all_info.out.size != 1) {
2472                 torture_result(tctx, TORTURE_FAIL,
2473                                "(%s) Incorrect resource fork size\n",
2474                                __location__);
2475                 ret = false;
2476                 smb2_util_close(tree, filehandle);
2477                 goto done;
2478         }
2479         smb2_util_close(tree, filehandle);
2480
2481 done:
2482         smb2_util_unlink(tree, fname);
2483         smb2_deltree(tree, BASEDIR);
2484         talloc_free(mem_ctx);
2485         return ret;
2486 }
2487
2488 static bool test_rfork_truncate(struct torture_context *tctx,
2489                                 struct smb2_tree *tree)
2490 {
2491         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2492         const char *fname = BASEDIR "\\torture_rfork_truncate";
2493         const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
2494         const char *rfork_content = "1234567890";
2495         NTSTATUS status;
2496         struct smb2_handle testdirh;
2497         bool ret = true;
2498         struct smb2_create create;
2499         struct smb2_handle fh1, fh2, fh3;
2500         union smb_setfileinfo sinfo;
2501
2502         ret = enable_aapl(tctx, tree);
2503         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
2504
2505         smb2_util_unlink(tree, fname);
2506
2507         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2508         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
2509         smb2_util_close(tree, testdirh);
2510
2511         ret = torture_setup_file(mem_ctx, tree, fname, false);
2512         if (ret == false) {
2513                 goto done;
2514         }
2515
2516         ret &= write_stream(tree, __location__, tctx, mem_ctx,
2517                             fname, AFPRESOURCE_STREAM,
2518                             10, 10, rfork_content);
2519
2520         /* Truncate back to size 0, further access MUST return ENOENT */
2521
2522         torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
2523                         __location__);
2524
2525         ZERO_STRUCT(create);
2526         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
2527         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
2528         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
2529         create.in.fname               = fname;
2530         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
2531                 NTCREATEX_SHARE_ACCESS_READ |
2532                 NTCREATEX_SHARE_ACCESS_WRITE;
2533         status = smb2_create(tree, mem_ctx, &create);
2534         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2535         fh1 = create.out.file.handle;
2536
2537         ZERO_STRUCT(create);
2538         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
2539         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
2540         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
2541         create.in.fname               = rfork;
2542         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
2543                 NTCREATEX_SHARE_ACCESS_READ |
2544                 NTCREATEX_SHARE_ACCESS_WRITE;
2545         status = smb2_create(tree, mem_ctx, &create);
2546         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2547         fh2 = create.out.file.handle;
2548
2549         ZERO_STRUCT(sinfo);
2550         sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
2551         sinfo.end_of_file_info.in.file.handle = fh2;
2552         sinfo.end_of_file_info.in.size = 0;
2553         status = smb2_setinfo_file(tree, &sinfo);
2554         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
2555
2556         /*
2557          * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
2558          */
2559         ZERO_STRUCT(create);
2560         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
2561         create.in.desired_access      = SEC_FILE_ALL;
2562         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
2563         create.in.fname               = rfork;
2564         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
2565                 NTCREATEX_SHARE_ACCESS_READ |
2566                 NTCREATEX_SHARE_ACCESS_WRITE;
2567         status = smb2_create(tree, mem_ctx, &create);
2568         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
2569
2570         /*
2571          * Do another open on the rfork and write to the new handle. A
2572          * naive server might unlink the AppleDouble resource fork
2573          * file when its truncated to 0 bytes above, so in case both
2574          * open handles share the same underlying fd, the unlink would
2575          * cause the below write to be lost.
2576          */
2577         ZERO_STRUCT(create);
2578         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
2579         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
2580         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
2581         create.in.fname               = rfork;
2582         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
2583                 NTCREATEX_SHARE_ACCESS_READ |
2584                 NTCREATEX_SHARE_ACCESS_WRITE;
2585         status = smb2_create(tree, mem_ctx, &create);
2586         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2587         fh3 = create.out.file.handle;
2588
2589         status = smb2_util_write(tree, fh3, "foo", 0, 3);
2590         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
2591
2592         smb2_util_close(tree, fh3);
2593         smb2_util_close(tree, fh2);
2594         smb2_util_close(tree, fh1);
2595
2596         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
2597                            0, 3, 0, 3, "foo");
2598         torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
2599
2600 done:
2601         smb2_util_unlink(tree, fname);
2602         smb2_deltree(tree, BASEDIR);
2603         talloc_free(mem_ctx);
2604         return ret;
2605 }
2606
2607 static bool test_rfork_create(struct torture_context *tctx,
2608                               struct smb2_tree *tree)
2609 {
2610         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2611         const char *fname = BASEDIR "\\torture_rfork_create";
2612         const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
2613         NTSTATUS status;
2614         struct smb2_handle testdirh;
2615         bool ret = true;
2616         struct smb2_create create;
2617         struct smb2_handle fh1;
2618         const char *streams[] = {
2619                 "::$DATA"
2620         };
2621         union smb_fileinfo finfo;
2622
2623         ret = enable_aapl(tctx, tree);
2624         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
2625
2626         smb2_util_unlink(tree, fname);
2627
2628         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2629         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
2630         smb2_util_close(tree, testdirh);
2631
2632         ret = torture_setup_file(mem_ctx, tree, fname, false);
2633         if (ret == false) {
2634                 goto done;
2635         }
2636
2637         torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
2638                         __location__);
2639
2640         ZERO_STRUCT(create);
2641         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
2642         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
2643         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
2644         create.in.fname               = rfork;
2645         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
2646                 NTCREATEX_SHARE_ACCESS_READ |
2647                 NTCREATEX_SHARE_ACCESS_WRITE;
2648         status = smb2_create(tree, mem_ctx, &create);
2649         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
2650
2651         torture_comment(tctx, "(%s) create resource fork\n", __location__);
2652
2653         ZERO_STRUCT(create);
2654         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
2655         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
2656         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
2657         create.in.fname               = rfork;
2658         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
2659                 NTCREATEX_SHARE_ACCESS_READ |
2660                 NTCREATEX_SHARE_ACCESS_WRITE;
2661         status = smb2_create(tree, mem_ctx, &create);
2662         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2663         fh1 = create.out.file.handle;
2664
2665         torture_comment(tctx, "(%s) getinfo on create handle\n",
2666                         __location__);
2667
2668         ZERO_STRUCT(finfo);
2669         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2670         finfo.generic.in.file.handle = fh1;
2671         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
2672         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
2673         if (finfo.all_info.out.size != 0) {
2674                 torture_result(tctx, TORTURE_FAIL,
2675                                "(%s) Incorrect resource fork size\n",
2676                                __location__);
2677                 ret = false;
2678                 smb2_util_close(tree, fh1);
2679                 goto done;
2680         }
2681
2682         torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
2683                         __location__);
2684
2685         ZERO_STRUCT(create);
2686         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
2687         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
2688         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
2689         create.in.fname               = rfork;
2690         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
2691                 NTCREATEX_SHARE_ACCESS_READ |
2692                 NTCREATEX_SHARE_ACCESS_WRITE;
2693         status = smb2_create(tree, mem_ctx, &create);
2694         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
2695
2696         ret = check_stream_list(tree, tctx, fname, 1, streams, false);
2697         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2698
2699         torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
2700                         __location__);
2701
2702         ZERO_STRUCT(create);
2703         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
2704         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
2705         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
2706         create.in.fname               = rfork;
2707         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
2708                 NTCREATEX_SHARE_ACCESS_READ |
2709                 NTCREATEX_SHARE_ACCESS_WRITE;
2710         status = smb2_create(tree, mem_ctx, &create);
2711         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
2712
2713 done:
2714         smb2_util_unlink(tree, fname);
2715         smb2_deltree(tree, BASEDIR);
2716         talloc_free(mem_ctx);
2717         return ret;
2718 }
2719
2720 static bool test_rfork_create_ro(struct torture_context *tctx,
2721                                  struct smb2_tree *tree)
2722 {
2723         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2724         const char *fname = BASEDIR "\\torture_rfork_create";
2725         const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
2726         NTSTATUS status;
2727         struct smb2_handle testdirh;
2728         bool ret = true;
2729         struct smb2_create create;
2730
2731         smb2_util_unlink(tree, fname);
2732         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2733         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2734                 "torture_smb2_testdir\n");
2735         smb2_util_close(tree, testdirh);
2736
2737         ret = torture_setup_file(mem_ctx, tree, fname, false);
2738         if (ret == false) {
2739                 goto done;
2740         }
2741
2742         torture_comment(tctx, "(%s) Try opening read-only with "
2743                         "open_if create disposition, should work\n",
2744                         __location__);
2745
2746         ZERO_STRUCT(create);
2747         create.in.fname = rfork;
2748         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2749         create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
2750         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2751         create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
2752         status = smb2_create(tree, mem_ctx, &(create));
2753         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2754                 "smb2_create failed\n");
2755
2756         smb2_util_close(tree, create.out.file.handle);
2757
2758 done:
2759         smb2_util_unlink(tree, fname);
2760         smb2_deltree(tree, BASEDIR);
2761         talloc_free(mem_ctx);
2762         return ret;
2763 }
2764
2765 static bool test_adouble_conversion(struct torture_context *tctx,
2766                                     struct smb2_tree *tree)
2767 {
2768         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2769         const char *fname = BASEDIR "\\test_adouble_conversion";
2770         const char *adname = BASEDIR "/._test_adouble_conversion";
2771         NTSTATUS status;
2772         struct smb2_handle testdirh;
2773         bool ret = true;
2774         const char data[] = {
2775                 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
2776                 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
2777         };
2778         size_t datalen = sizeof(data);
2779         const char *streams[] = {
2780                 "::$DATA",
2781                 AFPINFO_STREAM,
2782                 AFPRESOURCE_STREAM,
2783                 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
2784                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2785         };
2786         bool is_osx = torture_setting_bool(tctx, "osx", false);
2787
2788         if (is_osx) {
2789                 torture_skip(tctx, "Test only works with Samba\n");
2790         }
2791
2792         smb2_deltree(tree, BASEDIR);
2793
2794         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2795         CHECK_STATUS(status, NT_STATUS_OK);
2796         smb2_util_close(tree, testdirh);
2797
2798         ret = torture_setup_file(tctx, tree, fname, false);
2799         torture_assert_goto(tctx, ret == true, ret, done,
2800                             "torture_setup_file failed\n");
2801
2802         ret = torture_setup_file(tctx, tree, adname, false);
2803         torture_assert_goto(tctx, ret == true, ret, done,
2804                             "torture_setup_file failed\n");
2805
2806         ret = write_stream(tree, __location__, tctx, mem_ctx,
2807                            adname, NULL,
2808                            0,
2809                            sizeof(osx_adouble_non_empty_rfork_w_xattr),
2810                            osx_adouble_non_empty_rfork_w_xattr);
2811         torture_assert_goto(tctx, ret == true, ret, done,
2812                             "write_stream failed\n");
2813
2814         torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
2815             __location__);
2816
2817         ret = check_stream(tree, __location__, tctx, mem_ctx,
2818                            fname, AFPRESOURCE_STREAM,
2819                            16, datalen, 0, datalen, data);
2820         torture_assert_goto(tctx, ret == true, ret, done,
2821                             "check AFPRESOURCE_STREAM failed\n");
2822
2823         ret = check_stream(tree, __location__, tctx, mem_ctx,
2824                            fname, AFPINFO_STREAM,
2825                            0, 60, 16, 8, "TESTSLOW");
2826         torture_assert_goto(tctx, ret == true, ret, done,
2827                             "check AFPINFO_STREAM failed\n");
2828
2829         ret = check_stream(tree, __location__, tctx, mem_ctx, fname,
2830                            ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2831                            0, 3, 0, 3, "baz");
2832         torture_assert_goto(tctx, ret == true, ret, done,
2833                             "check foo:bar stream failed\n");
2834
2835         ret = check_stream_list(tree, tctx, fname, 5, streams, false);
2836         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2837
2838 done:
2839         smb2_deltree(tree, BASEDIR);
2840         talloc_free(mem_ctx);
2841         return ret;
2842 }
2843
2844 /*
2845  * Test conversion of AppleDouble file without embedded xattr data
2846  */
2847 static bool test_adouble_conversion_wo_xattr(struct torture_context *tctx,
2848                                              struct smb2_tree *tree)
2849 {
2850         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2851         const char *fname = BASEDIR "\\test_adouble_conversion";
2852         const char *adname = BASEDIR "/._test_adouble_conversion";
2853         NTSTATUS status;
2854         struct smb2_handle testdirh;
2855         bool ret = true;
2856         const char *streams[] = {
2857                 "::$DATA",
2858                 AFPINFO_STREAM,
2859                 AFPRESOURCE_STREAM
2860         };
2861         struct smb2_create create;
2862         struct smb2_find find;
2863         unsigned int count;
2864         union smb_search_data *d;
2865         const char data[] = {
2866                 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
2867                 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
2868         };
2869         size_t datalen = sizeof(data);
2870         bool is_osx = torture_setting_bool(tctx, "osx", false);
2871
2872         if (is_osx) {
2873                 torture_skip(tctx, "Test only works with Samba\n");
2874         }
2875
2876         smb2_deltree(tree, BASEDIR);
2877
2878         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2879         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2880                                         "torture_smb2_testdir failed\n");
2881         smb2_util_close(tree, testdirh);
2882
2883         ret = torture_setup_file(tctx, tree, fname, false);
2884         torture_assert_goto(tctx, ret == true, ret, done,
2885                             "torture_setup_file failed\n");
2886
2887         ret = torture_setup_file(tctx, tree, adname, false);
2888         torture_assert_goto(tctx, ret == true, ret, done,
2889                             "torture_setup_file failed\n");
2890
2891         ret = write_stream(tree, __location__, tctx, mem_ctx,
2892                            adname, NULL, 0,
2893                            sizeof(osx_adouble_without_xattr),
2894                            osx_adouble_without_xattr);
2895         torture_assert_goto(tctx, ret == true, ret, done,
2896                             "write_stream failed\n");
2897
2898         ret = enable_aapl(tctx, tree);
2899         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
2900
2901         /*
2902          * Issue a smb2_find(), this triggers the server-side conversion
2903          */
2904
2905         create = (struct smb2_create) {
2906                 .in.desired_access = SEC_RIGHTS_DIR_READ,
2907                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
2908                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
2909                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
2910                 .in.create_disposition = NTCREATEX_DISP_OPEN,
2911                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
2912                 .in.fname = BASEDIR,
2913         };
2914
2915         status = smb2_create(tree, tctx, &create);
2916         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2917                                         "smb2_create failed\n");
2918
2919         find = (struct smb2_find) {
2920                 .in.file.handle = create.out.file.handle,
2921                 .in.pattern = "*",
2922                 .in.max_response_size = 0x1000,
2923                 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
2924         };
2925
2926         status = smb2_find_level(tree, tree, &find, &count, &d);
2927         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2928                                         "smb2_find_level failed\n");
2929
2930         status = smb2_util_close(tree, create.out.file.handle);
2931         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2932                                         "smb2_util_close failed");
2933
2934         /*
2935          * Check number of streams
2936          */
2937
2938         ret = check_stream_list(tree, tctx, fname, 3, streams, false);
2939         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2940
2941
2942         /*
2943          * Check Resourcefork data can be read.
2944          */
2945
2946         ret = check_stream(tree, __location__, tctx, mem_ctx,
2947                            fname, AFPRESOURCE_STREAM,
2948                            16, datalen, 0, datalen, data);
2949         torture_assert_goto(tctx, ret == true, ret, done,
2950                             "check AFPRESOURCE_STREAM failed\n");
2951
2952         /*
2953          * Check FinderInfo data has been migrated to stream.
2954          */
2955
2956         ret = check_stream(tree, __location__, tctx, mem_ctx,
2957                            fname, AFPINFO_STREAM,
2958                            0, 60, 16, 8, "WAVEPTul");
2959         torture_assert_goto(tctx, ret == true, ret, done,
2960                             "check AFPINFO_STREAM failed\n");
2961
2962 done:
2963         smb2_deltree(tree, BASEDIR);
2964         talloc_free(mem_ctx);
2965         return ret;
2966 }
2967
2968 static bool test_aapl(struct torture_context *tctx,
2969                       struct smb2_tree *tree)
2970 {
2971         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2972         const char *fname = BASEDIR "\\test_aapl";
2973         NTSTATUS status;
2974         struct smb2_handle testdirh;
2975         bool ret = true;
2976         struct smb2_create io;
2977         DATA_BLOB data;
2978         struct smb2_create_blob *aapl = NULL;
2979         AfpInfo *info;
2980         const char *type_creator = "SMB,OLE!";
2981         char type_creator_buf[9];
2982         uint32_t aapl_cmd;
2983         uint32_t aapl_reply_bitmap;
2984         uint32_t aapl_server_caps;
2985         uint32_t aapl_vol_caps;
2986         uint32_t expected_vol_caps = 0;
2987         char *model;
2988         struct smb2_find f;
2989         unsigned int count;
2990         union smb_search_data *d;
2991         uint64_t rfork_len;
2992         bool is_osx_server = torture_setting_bool(tctx, "osx", false);
2993
2994         smb2_deltree(tree, BASEDIR);
2995
2996         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2997         CHECK_STATUS(status, NT_STATUS_OK);
2998         smb2_util_close(tree, testdirh);
2999
3000         ZERO_STRUCT(io);
3001         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
3002         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
3003         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
3004         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
3005                               NTCREATEX_SHARE_ACCESS_READ |
3006                               NTCREATEX_SHARE_ACCESS_WRITE);
3007         io.in.fname = fname;
3008
3009         /*
3010          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
3011          * controls behaviour of Apple's SMB2 extensions for the whole
3012          * session!
3013          */
3014
3015         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
3016         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
3017         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
3018                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
3019                              SMB2_CRTCTX_AAPL_MODEL_INFO));
3020         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
3021                               SMB2_CRTCTX_AAPL_UNIX_BASED |
3022                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
3023
3024         torture_comment(tctx, "Testing SMB2 create context AAPL\n");
3025         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
3026         CHECK_STATUS(status, NT_STATUS_OK);
3027
3028         status = smb2_create(tree, tctx, &io);
3029         CHECK_STATUS(status, NT_STATUS_OK);
3030         status = smb2_util_close(tree, io.out.file.handle);
3031         CHECK_STATUS(status, NT_STATUS_OK);
3032
3033         /*
3034          * Now check returned AAPL context
3035          */
3036         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
3037
3038         aapl = smb2_create_blob_find(&io.out.blobs,
3039                                      SMB2_CREATE_TAG_AAPL);
3040
3041         if (aapl == NULL) {
3042                 torture_result(tctx, TORTURE_FAIL,
3043                                "(%s) unexpectedly no AAPL capabilities were returned.",
3044                                __location__);
3045                 ret = false;
3046                 goto done;
3047         }
3048
3049         if (!is_osx_server) {
3050                 size_t expected_aapl_ctx_size;
3051                 bool size_ok;
3052
3053                 /*
3054                  * uint32_t CommandCode = kAAPL_SERVER_QUERY
3055                  * uint32_t Reserved = 0;
3056                  * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
3057                  *                        kAAPL_VOLUME_CAPS |
3058                  *                        kAAPL_MODEL_INFO;
3059                  * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
3060                  *                       kAAPL_SUPPORTS_OSX_COPYFILE;
3061                  * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
3062                  *                       kAAPL_CASE_SENSITIVE;
3063                  * uint32_t Pad2 = 0;
3064                  * uint32_t ModelStringLen = 10;
3065                  * ucs2_t ModelString[5] = "MacSamba";
3066                  */
3067                 expected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
3068
3069                 size_ok = aapl->data.length == expected_aapl_ctx_size;
3070                 torture_assert_goto(tctx, size_ok, ret, done, "bad AAPL size");
3071         }
3072
3073         aapl_cmd = IVAL(aapl->data.data, 0);
3074         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
3075                 torture_result(tctx, TORTURE_FAIL,
3076                                "(%s) unexpected cmd: %d",
3077                                __location__, (int)aapl_cmd);
3078                 ret = false;
3079                 goto done;
3080         }
3081
3082         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
3083         if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
3084                                   SMB2_CRTCTX_AAPL_VOLUME_CAPS |
3085                                   SMB2_CRTCTX_AAPL_MODEL_INFO)) {
3086                 torture_result(tctx, TORTURE_FAIL,
3087                                "(%s) unexpected reply_bitmap: %d",
3088                                __location__, (int)aapl_reply_bitmap);
3089                 ret = false;
3090                 goto done;
3091         }
3092
3093         aapl_server_caps = BVAL(aapl->data.data, 16);
3094         if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
3095                                  SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
3096                                  SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
3097                                  SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
3098                 torture_result(tctx, TORTURE_FAIL,
3099                                "(%s) unexpected server_caps: %d",
3100                                __location__, (int)aapl_server_caps);
3101                 ret = false;
3102                 goto done;
3103         }
3104
3105         if (is_osx_server) {
3106                 expected_vol_caps = 5;
3107         }
3108         aapl_vol_caps = BVAL(aapl->data.data, 24);
3109         if (aapl_vol_caps != expected_vol_caps) {
3110                 /* this will fail on a case insensitive fs ... */
3111                 torture_result(tctx, TORTURE_FAIL,
3112                                 "(%s) unexpected vol_caps: %d",
3113                                 __location__, (int)aapl_vol_caps);
3114         }
3115
3116         ret = convert_string_talloc(mem_ctx,
3117                                     CH_UTF16LE, CH_UNIX,
3118                                     aapl->data.data + 40, 10,
3119                                     &model, NULL);
3120         if (ret == false) {
3121                 torture_result(tctx, TORTURE_FAIL,
3122                                "(%s) convert_string_talloc() failed",
3123                                __location__);
3124                 goto done;
3125         }
3126         torture_comment(tctx, "Got server model: \"%s\"\n", model);
3127
3128         /*
3129          * Now that Requested AAPL extensions are enabled, setup some
3130          * Mac files with metadata and resource fork
3131          */
3132         ret = torture_setup_file(mem_ctx, tree, fname, false);
3133         if (ret == false) {
3134                 torture_result(tctx, TORTURE_FAIL,
3135                                "(%s) torture_setup_file() failed",
3136                                __location__);
3137                 goto done;
3138         }
3139
3140         info = torture_afpinfo_new(mem_ctx);
3141         if (info == NULL) {
3142                 torture_result(tctx, TORTURE_FAIL,
3143                                "(%s) torture_afpinfo_new() failed",
3144                                __location__);
3145                 ret = false;
3146                 goto done;
3147         }
3148
3149         memcpy(info->afpi_FinderInfo, type_creator, 8);
3150         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3151         if (ret == false) {
3152                 torture_result(tctx, TORTURE_FAIL,
3153                                "(%s) torture_write_afpinfo() failed",
3154                                __location__);
3155                 goto done;
3156         }
3157
3158         ret = write_stream(tree, __location__, tctx, mem_ctx,
3159                            fname, AFPRESOURCE_STREAM_NAME,
3160                            0, 3, "foo");
3161         if (ret == false) {
3162                 torture_result(tctx, TORTURE_FAIL,
3163                                "(%s) write_stream() failed",
3164                                __location__);
3165                 goto done;
3166         }
3167
3168         /*
3169          * Ok, file is prepared, now call smb2/find
3170          */
3171
3172         ZERO_STRUCT(io);
3173         io.in.desired_access = SEC_RIGHTS_DIR_READ;
3174         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
3175         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3176         io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
3177                               NTCREATEX_SHARE_ACCESS_WRITE |
3178                               NTCREATEX_SHARE_ACCESS_DELETE);
3179         io.in.create_disposition = NTCREATEX_DISP_OPEN;
3180         io.in.fname = BASEDIR;
3181         status = smb2_create(tree, tctx, &io);
3182         CHECK_STATUS(status, NT_STATUS_OK);
3183
3184         ZERO_STRUCT(f);
3185         f.in.file.handle        = io.out.file.handle;
3186         f.in.pattern            = "test_aapl";
3187         f.in.continue_flags     = SMB2_CONTINUE_FLAG_SINGLE;
3188         f.in.max_response_size  = 0x1000;
3189         f.in.level              = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
3190
3191         status = smb2_find_level(tree, tree, &f, &count, &d);
3192         CHECK_STATUS(status, NT_STATUS_OK);
3193
3194         status = smb2_util_close(tree, io.out.file.handle);
3195         CHECK_STATUS(status, NT_STATUS_OK);
3196
3197         if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
3198                 torture_result(tctx, TORTURE_FAIL,
3199                                "(%s) write_stream() failed",
3200                                __location__);
3201                 ret = false;
3202                 goto done;
3203         }
3204
3205         if (d[0].id_both_directory_info.short_name.private_length != 24) {
3206                 torture_result(tctx, TORTURE_FAIL,
3207                                "(%s) bad short_name length %" PRIu32 ", expected 24",
3208                                __location__, d[0].id_both_directory_info.short_name.private_length);
3209                 ret = false;
3210                 goto done;
3211         }
3212
3213         torture_comment(tctx, "short_name buffer:\n");
3214         dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
3215
3216         /*
3217          * Extract data as specified by the AAPL extension:
3218          * - ea_size contains max_access
3219          * - short_name contains resource fork length + FinderInfo
3220          * - reserved2 contains the unix mode
3221          */
3222         torture_comment(tctx, "mac_access: %" PRIx32 "\n",
3223                         d[0].id_both_directory_info.ea_size);
3224
3225         rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
3226         if (rfork_len != 3) {
3227                 torture_result(tctx, TORTURE_FAIL,
3228                                "(%s) expected resource fork length 3, got: %" PRIu64,
3229                                __location__, rfork_len);
3230                 ret = false;
3231                 goto done;
3232         }
3233
3234         memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
3235         type_creator_buf[8] = 0;
3236         if (strcmp(type_creator, type_creator_buf) != 0) {
3237                 torture_result(tctx, TORTURE_FAIL,
3238                                "(%s) expected type/creator \"%s\" , got: %s",
3239                                __location__, type_creator, type_creator_buf);
3240                 ret = false;
3241                 goto done;
3242         }
3243
3244 done:
3245         smb2_util_unlink(tree, fname);
3246         smb2_deltree(tree, BASEDIR);
3247         talloc_free(mem_ctx);
3248         return ret;
3249 }
3250
3251 static uint64_t patt_hash(uint64_t off)
3252 {
3253         return off;
3254 }
3255
3256 static bool write_pattern(struct torture_context *torture,
3257                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
3258                           struct smb2_handle h, uint64_t off, uint64_t len,
3259                           uint64_t patt_off)
3260 {
3261         NTSTATUS status;
3262         uint64_t i;
3263         uint8_t *buf;
3264         uint64_t io_sz = MIN(1024 * 64, len);
3265
3266         if (len == 0) {
3267                 return true;
3268         }
3269
3270         torture_assert(torture, (len % 8) == 0, "invalid write len");
3271
3272         buf = talloc_zero_size(mem_ctx, io_sz);
3273         torture_assert(torture, (buf != NULL), "no memory for file data buf");
3274
3275         while (len > 0) {
3276                 for (i = 0; i <= io_sz - 8; i += 8) {
3277                         SBVAL(buf, i, patt_hash(patt_off));
3278                         patt_off += 8;
3279                 }
3280
3281                 status = smb2_util_write(tree, h,
3282                                          buf, off, io_sz);
3283                 torture_assert_ntstatus_ok(torture, status, "file write");
3284
3285                 len -= io_sz;
3286                 off += io_sz;
3287         }
3288
3289         talloc_free(buf);
3290
3291         return true;
3292 }
3293
3294 static bool check_pattern(struct torture_context *torture,
3295                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
3296                           struct smb2_handle h, uint64_t off, uint64_t len,
3297                           uint64_t patt_off)
3298 {
3299         if (len == 0) {
3300                 return true;
3301         }
3302
3303         torture_assert(torture, (len % 8) == 0, "invalid read len");
3304
3305         while (len > 0) {
3306                 uint64_t i;
3307                 struct smb2_read r;
3308                 NTSTATUS status;
3309                 uint64_t io_sz = MIN(1024 * 64, len);
3310
3311                 ZERO_STRUCT(r);
3312                 r.in.file.handle = h;
3313                 r.in.length      = io_sz;
3314                 r.in.offset      = off;
3315                 status = smb2_read(tree, mem_ctx, &r);
3316                 torture_assert_ntstatus_ok(torture, status, "read");
3317
3318                 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
3319                                          "read data len mismatch");
3320
3321                 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
3322                         uint64_t data = BVAL(r.out.data.data, i);
3323                         torture_assert_u64_equal(torture, data, patt_hash(patt_off),
3324                                                  talloc_asprintf(torture, "read data "
3325                                                                  "pattern bad at %llu\n",
3326                                                                  (unsigned long long)off + i));
3327                 }
3328                 talloc_free(r.out.data.data);
3329                 len -= io_sz;
3330                 off += io_sz;
3331         }
3332
3333         return true;
3334 }
3335
3336 static bool test_setup_open(struct torture_context *torture,
3337                             struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
3338                             const char *fname,
3339                             struct smb2_handle *fh,
3340                             uint32_t desired_access,
3341                             uint32_t file_attributes)
3342 {
3343         struct smb2_create io;
3344         NTSTATUS status;
3345
3346         ZERO_STRUCT(io);
3347         io.in.desired_access = desired_access;
3348         io.in.file_attributes = file_attributes;
3349         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
3350         io.in.share_access =
3351                 NTCREATEX_SHARE_ACCESS_DELETE|
3352                 NTCREATEX_SHARE_ACCESS_READ|
3353                 NTCREATEX_SHARE_ACCESS_WRITE;
3354         if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
3355                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
3356         }
3357         io.in.fname = fname;
3358
3359         status = smb2_create(tree, mem_ctx, &io);
3360         torture_assert_ntstatus_ok(torture, status, "file create");
3361
3362         *fh = io.out.file.handle;
3363
3364         return true;
3365 }
3366
3367 static bool test_setup_create_fill(struct torture_context *torture,
3368                                    struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
3369                                    const char *fname,
3370                                    struct smb2_handle *fh,
3371                                    uint64_t size,
3372                                    uint32_t desired_access,
3373                                    uint32_t file_attributes)
3374 {
3375         bool ok;
3376
3377         ok = test_setup_open(torture, tree, mem_ctx,
3378                              fname,
3379                              fh,
3380                              desired_access,
3381                              file_attributes);
3382         torture_assert(torture, ok, "file open");
3383
3384         if (size > 0) {
3385                 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
3386                 torture_assert(torture, ok, "write pattern");
3387         }
3388         return true;
3389 }
3390
3391 static bool test_setup_copy_chunk(struct torture_context *torture,
3392                                   struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
3393                                   uint32_t nchunks,
3394                                   const char *src_name,
3395                                   struct smb2_handle *src_h,
3396                                   uint64_t src_size,
3397                                   uint32_t src_desired_access,
3398                                   const char *dst_name,
3399                                   struct smb2_handle *dest_h,
3400                                   uint64_t dest_size,
3401                                   uint32_t dest_desired_access,
3402                                   struct srv_copychunk_copy *cc_copy,
3403                                   union smb_ioctl *io)
3404 {
3405         struct req_resume_key_rsp res_key;
3406         bool ok;
3407         NTSTATUS status;
3408         enum ndr_err_code ndr_ret;
3409
3410         ok = test_setup_create_fill(torture, tree, mem_ctx, src_name,
3411                                     src_h, src_size, src_desired_access,
3412                                     FILE_ATTRIBUTE_NORMAL);
3413         torture_assert(torture, ok, "src file create fill");
3414
3415         ok = test_setup_create_fill(torture, tree, mem_ctx, dst_name,
3416                                     dest_h, dest_size, dest_desired_access,
3417                                     FILE_ATTRIBUTE_NORMAL);
3418         torture_assert(torture, ok, "dest file create fill");
3419
3420         ZERO_STRUCTPN(io);
3421         io->smb2.level = RAW_IOCTL_SMB2;
3422         io->smb2.in.file.handle = *src_h;
3423         io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
3424         /* Allow for Key + ContextLength + Context */
3425         io->smb2.in.max_output_response = 32;
3426         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
3427
3428         status = smb2_ioctl(tree, mem_ctx, &io->smb2);
3429         torture_assert_ntstatus_ok(torture, status,
3430                                    "FSCTL_SRV_REQUEST_RESUME_KEY");
3431
3432         ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
3433                         (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
3434
3435         torture_assert_ndr_success(torture, ndr_ret,
3436                                    "ndr_pull_req_resume_key_rsp");
3437
3438         ZERO_STRUCTPN(io);
3439         io->smb2.level = RAW_IOCTL_SMB2;
3440         io->smb2.in.file.handle = *dest_h;
3441         io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
3442         io->smb2.in.max_output_response = sizeof(struct srv_copychunk_rsp);
3443         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
3444
3445         ZERO_STRUCTPN(cc_copy);
3446         memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
3447         cc_copy->chunk_count = nchunks;
3448         cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
3449         torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
3450
3451         return true;
3452 }
3453
3454
3455 static bool check_copy_chunk_rsp(struct torture_context *torture,
3456                                  struct srv_copychunk_rsp *cc_rsp,
3457                                  uint32_t ex_chunks_written,
3458                                  uint32_t ex_chunk_bytes_written,
3459                                  uint32_t ex_total_bytes_written)
3460 {
3461         torture_assert_int_equal(torture, cc_rsp->chunks_written,
3462                                  ex_chunks_written, "num chunks");
3463         torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
3464                                  ex_chunk_bytes_written, "chunk bytes written");
3465         torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
3466                                  ex_total_bytes_written, "chunk total bytes");
3467         return true;
3468 }
3469
3470 static bool neg_aapl_copyfile(struct torture_context *tctx,
3471                               struct smb2_tree *tree,
3472                               uint64_t flags)
3473 {
3474         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3475         const char *fname = "aapl";
3476         NTSTATUS status;
3477         struct smb2_create io;
3478         DATA_BLOB data;
3479         struct smb2_create_blob *aapl = NULL;
3480         uint32_t aapl_cmd;
3481         uint32_t aapl_reply_bitmap;
3482         uint32_t aapl_server_caps;
3483         bool ret = true;
3484
3485         ZERO_STRUCT(io);
3486         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
3487         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
3488         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
3489         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
3490                               NTCREATEX_SHARE_ACCESS_READ |
3491                               NTCREATEX_SHARE_ACCESS_WRITE);
3492         io.in.fname = fname;
3493
3494         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
3495         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
3496         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
3497         SBVAL(data.data, 16, flags);
3498
3499         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
3500         CHECK_STATUS(status, NT_STATUS_OK);
3501
3502         status = smb2_create(tree, tctx, &io);
3503         CHECK_STATUS(status, NT_STATUS_OK);
3504
3505         aapl = smb2_create_blob_find(&io.out.blobs,
3506                                      SMB2_CREATE_TAG_AAPL);
3507         if (aapl == NULL) {
3508                 ret = false;
3509                 goto done;
3510
3511         }
3512         if (aapl->data.length < 24) {
3513                 ret = false;
3514                 goto done;
3515         }
3516
3517         aapl_cmd = IVAL(aapl->data.data, 0);
3518         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
3519                 torture_result(tctx, TORTURE_FAIL,
3520                                "(%s) unexpected cmd: %d",
3521                                __location__, (int)aapl_cmd);
3522                 ret = false;
3523                 goto done;
3524         }
3525
3526         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
3527         if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
3528                 torture_result(tctx, TORTURE_FAIL,
3529                                "(%s) unexpected reply_bitmap: %d",
3530                                __location__, (int)aapl_reply_bitmap);
3531                 ret = false;
3532                 goto done;
3533         }
3534
3535         aapl_server_caps = BVAL(aapl->data.data, 16);
3536         if (!(aapl_server_caps & flags)) {
3537                 torture_result(tctx, TORTURE_FAIL,
3538                                "(%s) unexpected server_caps: %d",
3539                                __location__, (int)aapl_server_caps);
3540                 ret = false;
3541                 goto done;
3542         }
3543
3544 done:
3545         status = smb2_util_close(tree, io.out.file.handle);
3546         CHECK_STATUS(status, NT_STATUS_OK);
3547
3548         smb2_util_unlink(tree, "aapl");
3549         talloc_free(mem_ctx);
3550         return ret;
3551 }
3552
3553 static bool test_copyfile(struct torture_context *torture,
3554                           struct smb2_tree *tree)
3555 {
3556         struct smb2_handle src_h;
3557         struct smb2_handle dest_h;
3558         NTSTATUS status;
3559         union smb_ioctl io;
3560         TALLOC_CTX *tmp_ctx = talloc_new(tree);
3561         struct srv_copychunk_copy cc_copy;
3562         struct srv_copychunk_rsp cc_rsp;
3563         enum ndr_err_code ndr_ret;
3564         bool ok;
3565         const char *sname = ":foo" "\xef\x80\xa2" "bar:$DATA";
3566
3567         /*
3568          * First test a copy_chunk with a 0 chunk count without having
3569          * enabled this via AAPL. The request must not fail and the
3570          * copied length in the response must be 0. This is verified
3571          * against Windows 2008r2.
3572          */
3573
3574         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
3575                                    0, /* 0 chunks, copyfile semantics */
3576                                    FNAME_CC_SRC,
3577                                    &src_h, 4096, /* fill 4096 byte src file */
3578                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
3579                                    FNAME_CC_DST,
3580                                    &dest_h, 0,  /* 0 byte dest file */
3581                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
3582                                    &cc_copy,
3583                                    &io);
3584         if (!ok) {
3585                 torture_fail_goto(torture, done, "setup copy chunk error");
3586         }
3587
3588         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
3589                                        &cc_copy,
3590                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
3591         torture_assert_ndr_success(torture, ndr_ret,
3592                                    "ndr_push_srv_copychunk_copy");
3593
3594         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
3595         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
3596
3597         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
3598                                        &cc_rsp,
3599                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
3600         torture_assert_ndr_success(torture, ndr_ret,
3601                                    "ndr_pull_srv_copychunk_rsp");
3602
3603         ok = check_copy_chunk_rsp(torture, &cc_rsp,
3604                                   0,    /* chunks written */
3605                                   0,    /* chunk bytes unsuccessfully written */
3606                                   0); /* total bytes written */
3607         if (!ok) {
3608                 torture_fail_goto(torture, done, "bad copy chunk response data");
3609         }
3610
3611         /*
3612          * Now enable AAPL copyfile and test again, the file and the
3613          * stream must be copied by the server.
3614          */
3615         ok = neg_aapl_copyfile(torture, tree,
3616                                SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
3617         if (!ok) {
3618                 torture_skip_goto(torture, done, "missing AAPL copyfile");
3619                 goto done;
3620         }
3621
3622         smb2_util_close(tree, src_h);
3623         smb2_util_close(tree, dest_h);
3624         smb2_util_unlink(tree, FNAME_CC_SRC);
3625         smb2_util_unlink(tree, FNAME_CC_DST);
3626
3627         ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
3628         if (!ok) {
3629                 torture_fail(torture, "setup file error");
3630         }
3631         ok = write_stream(tree, __location__, torture, tmp_ctx,
3632                             FNAME_CC_SRC, AFPRESOURCE_STREAM,
3633                             10, 10, "1234567890");
3634         if (!ok) {
3635                 torture_fail(torture, "setup stream error");
3636         }
3637
3638         ok = write_stream(tree, __location__, torture, tmp_ctx,
3639                             FNAME_CC_SRC, sname,
3640                             10, 10, "abcdefghij");
3641         torture_assert_goto(torture, ok == true, ok, done, "write_stream failed\n");
3642
3643         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
3644                                    0, /* 0 chunks, copyfile semantics */
3645                                    FNAME_CC_SRC,
3646                                    &src_h, 4096, /* fill 4096 byte src file */
3647                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
3648                                    FNAME_CC_DST,
3649                                    &dest_h, 0,  /* 0 byte dest file */
3650                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
3651                                    &cc_copy,
3652                                    &io);
3653         if (!ok) {
3654                 torture_fail_goto(torture, done, "setup copy chunk error");
3655         }
3656
3657         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
3658                                        &cc_copy,
3659                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
3660         torture_assert_ndr_success(torture, ndr_ret,
3661                                    "ndr_push_srv_copychunk_copy");
3662
3663         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
3664         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
3665
3666         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
3667                                        &cc_rsp,
3668                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
3669         torture_assert_ndr_success(torture, ndr_ret,
3670                                    "ndr_pull_srv_copychunk_rsp");
3671
3672         ok = check_copy_chunk_rsp(torture, &cc_rsp,
3673                                   0,    /* chunks written */
3674                                   0,    /* chunk bytes unsuccessfully written */
3675                                   4096); /* total bytes written */
3676         if (!ok) {
3677                 torture_fail_goto(torture, done, "bad copy chunk response data");
3678         }
3679
3680         ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
3681                              SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
3682         if (!ok) {
3683                 torture_fail_goto(torture, done,"open failed");
3684         }
3685         ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
3686         if (!ok) {
3687                 torture_fail_goto(torture, done, "inconsistent file data");
3688         }
3689
3690         ok = check_stream(tree, __location__, torture, tmp_ctx,
3691                             FNAME_CC_DST, AFPRESOURCE_STREAM,
3692                             0, 20, 10, 10, "1234567890");
3693         if (!ok) {
3694                 torture_fail_goto(torture, done, "inconsistent stream data");
3695         }
3696
3697         ok = check_stream(tree, __location__, torture, tmp_ctx,
3698                             FNAME_CC_DST, sname,
3699                             0, 20, 10, 10, "abcdefghij");
3700         torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
3701
3702 done:
3703         smb2_util_close(tree, src_h);
3704         smb2_util_close(tree, dest_h);
3705         smb2_util_unlink(tree, FNAME_CC_SRC);
3706         smb2_util_unlink(tree, FNAME_CC_DST);
3707         talloc_free(tmp_ctx);
3708         return true;
3709 }
3710
3711 static bool check_stream_list(struct smb2_tree *tree,
3712                               struct torture_context *tctx,
3713                               const char *fname,
3714                               int num_exp,
3715                               const char **exp,
3716                               bool is_dir)
3717 {
3718         bool ret = true;
3719         union smb_fileinfo finfo;
3720         NTSTATUS status;
3721         int i;
3722         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
3723         char **exp_sort;
3724         struct stream_struct *stream_sort;
3725         struct smb2_create create;
3726         struct smb2_handle h;
3727
3728         ZERO_STRUCT(h);
3729         torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
3730
3731         ZERO_STRUCT(create);
3732         create.in.fname = fname;
3733         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3734         create.in.desired_access = SEC_FILE_ALL;
3735         create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
3736         create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
3737         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3738         status = smb2_create(tree, tmp_ctx, &create);
3739         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
3740         h = create.out.file.handle;
3741
3742         finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
3743         finfo.generic.in.file.handle = h;
3744
3745         status = smb2_getinfo_file(tree, tctx, &finfo);
3746         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
3747
3748         smb2_util_close(tree, h);
3749
3750         torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
3751                                       ret, done, "stream count");
3752
3753         if (num_exp == 0) {
3754                 TALLOC_FREE(tmp_ctx);
3755                 goto done;
3756         }
3757
3758         exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
3759         torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
3760
3761         TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
3762
3763         stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
3764                                     finfo.stream_info.out.num_streams *
3765                                     sizeof(*stream_sort));
3766         torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
3767
3768         TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
3769
3770         for (i=0; i<num_exp; i++) {
3771                 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
3772                                 i, exp_sort[i], stream_sort[i].stream_name.s);
3773                 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
3774                                               ret, done, "stream name");
3775         }
3776
3777 done:
3778         TALLOC_FREE(tmp_ctx);
3779         return ret;
3780 }
3781
3782 static bool check_stream_list_handle(struct smb2_tree *tree,
3783                                      struct torture_context *tctx,
3784                                      struct smb2_handle h,
3785                                      int num_exp,
3786                                      const char **exp,
3787                                      bool is_dir)
3788 {
3789         bool ret = true;
3790         union smb_fileinfo finfo;
3791         NTSTATUS status;
3792         int i;
3793         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
3794         char **exp_sort;
3795         struct stream_struct *stream_sort;
3796
3797         torture_assert_goto(tctx, tmp_ctx != NULL, ret, done,
3798                             "talloc_new failed\n");
3799
3800         finfo = (union smb_fileinfo) {
3801                 .stream_info.level = RAW_FILEINFO_STREAM_INFORMATION,
3802                 .stream_info.in.file.handle = h,
3803         };
3804
3805         status = smb2_getinfo_file(tree, tctx, &finfo);
3806         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3807                                         "get stream info\n");
3808
3809         torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams,
3810                                       num_exp, ret, done, "stream count\n");
3811
3812         if (num_exp == 0) {
3813                 TALLOC_FREE(tmp_ctx);
3814                 goto done;
3815         }
3816
3817         exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
3818         torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
3819
3820         TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
3821
3822         stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
3823                                     finfo.stream_info.out.num_streams *
3824                                     sizeof(*stream_sort));
3825         torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
3826
3827         TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
3828
3829         for (i=0; i<num_exp; i++) {
3830                 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
3831                                 i, exp_sort[i], stream_sort[i].stream_name.s);
3832                 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s,
3833                                               exp_sort[i], ret, done,
3834                                               "stream name\n");
3835         }
3836
3837 done:
3838         TALLOC_FREE(tmp_ctx);
3839         return ret;
3840 }
3841
3842 /*
3843   test stream names
3844 */
3845 static bool test_stream_names(struct torture_context *tctx,
3846                               struct smb2_tree *tree)
3847 {
3848         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3849         NTSTATUS status;
3850         struct smb2_create create;
3851         struct smb2_handle h;
3852         const char *fname = BASEDIR "\\stream_names.txt";
3853         const char *sname1;
3854         bool ret;
3855         /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
3856         const char *streams[] = {
3857                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
3858                 "::$DATA"
3859         };
3860
3861         sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
3862
3863         /* clean slate ...*/
3864         smb2_util_unlink(tree, fname);
3865         smb2_deltree(tree, fname);
3866         smb2_deltree(tree, BASEDIR);
3867
3868         status = torture_smb2_testdir(tree, BASEDIR, &h);
3869         CHECK_STATUS(status, NT_STATUS_OK);
3870         smb2_util_close(tree, h);
3871
3872         ret = torture_setup_file(mem_ctx, tree, fname, false);
3873         torture_assert_goto(tctx, ret, ret, done, "torture_setup_file");
3874
3875         torture_comment(tctx, "(%s) testing stream names\n", __location__);
3876         ZERO_STRUCT(create);
3877         create.in.desired_access = SEC_FILE_WRITE_DATA;
3878         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3879         create.in.share_access =
3880                 NTCREATEX_SHARE_ACCESS_DELETE|
3881                 NTCREATEX_SHARE_ACCESS_READ|
3882                 NTCREATEX_SHARE_ACCESS_WRITE;
3883         create.in.create_disposition = NTCREATEX_DISP_CREATE;
3884         create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3885         create.in.fname = sname1;
3886
3887         status = smb2_create(tree, mem_ctx, &create);
3888         CHECK_STATUS(status, NT_STATUS_OK);
3889
3890         status = smb2_util_write(tree, create.out.file.handle, "foo", 0, 3);
3891         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3892                                         "smb2_util_write failed\n");
3893
3894         smb2_util_close(tree, create.out.file.handle);
3895
3896         ret = check_stream_list(tree, tctx, fname, 2, streams, false);
3897         CHECK_VALUE(ret, true);
3898
3899 done:
3900         status = smb2_util_unlink(tree, fname);
3901         smb2_deltree(tree, BASEDIR);
3902         talloc_free(mem_ctx);
3903
3904         return ret;
3905 }
3906
3907 /* Renaming a directory with open file, should work for OS X AAPL clients */
3908 static bool test_rename_dir_openfile(struct torture_context *torture,
3909                                      struct smb2_tree *tree)
3910 {
3911         bool ret = true;
3912         NTSTATUS status;
3913         union smb_open io;
3914         union smb_close cl;
3915         union smb_setfileinfo sinfo;
3916         struct smb2_handle d1, h1;
3917         const char *renamedir = BASEDIR "-new";
3918         bool server_is_osx = torture_setting_bool(torture, "osx", false);
3919
3920         smb2_deltree(tree, BASEDIR);
3921         smb2_util_rmdir(tree, BASEDIR);
3922         smb2_deltree(tree, renamedir);
3923
3924         ZERO_STRUCT(io.smb2);
3925         io.generic.level = RAW_OPEN_SMB2;
3926         io.smb2.in.create_flags = 0;
3927         io.smb2.in.desired_access = 0x0017019f;
3928         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
3929         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3930         io.smb2.in.share_access = 0;
3931         io.smb2.in.alloc_size = 0;
3932         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
3933         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3934         io.smb2.in.security_flags = 0;
3935         io.smb2.in.fname = BASEDIR;
3936
3937         status = smb2_create(tree, torture, &(io.smb2));
3938         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3939         d1 = io.smb2.out.file.handle;
3940
3941         ZERO_STRUCT(io.smb2);
3942         io.generic.level = RAW_OPEN_SMB2;
3943         io.smb2.in.create_flags = 0;
3944         io.smb2.in.desired_access = 0x0017019f;
3945         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
3946         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3947         io.smb2.in.share_access = 0;
3948         io.smb2.in.alloc_size = 0;
3949         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
3950         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3951         io.smb2.in.security_flags = 0;
3952         io.smb2.in.fname = BASEDIR "\\file.txt";
3953
3954         status = smb2_create(tree, torture, &(io.smb2));
3955         torture_assert_ntstatus_ok(torture, status, "smb2_create file");
3956         h1 = io.smb2.out.file.handle;
3957
3958         if (!server_is_osx) {
3959                 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
3960
3961                 ZERO_STRUCT(sinfo);
3962                 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3963                 sinfo.rename_information.in.file.handle = d1;
3964                 sinfo.rename_information.in.overwrite = 0;
3965                 sinfo.rename_information.in.root_fid = 0;
3966                 sinfo.rename_information.in.new_name = renamedir;
3967                 status = smb2_setinfo_file(tree, &sinfo);
3968
3969                 torture_assert_ntstatus_equal(torture, status,
3970                                               NT_STATUS_ACCESS_DENIED,
3971                                               "smb2_setinfo_file");
3972         }
3973
3974         status = smb2_util_close(tree, d1);
3975         torture_assert_ntstatus_ok(torture, status, "smb2_util_close\n");
3976         ZERO_STRUCT(d1);
3977
3978         torture_comment(torture, "Enabling AAPL\n");
3979
3980         ret = enable_aapl(torture, tree);
3981         torture_assert(torture, ret == true, "enable_aapl failed");
3982
3983         torture_comment(torture, "Renaming directory with AAPL\n");
3984
3985         ZERO_STRUCT(io.smb2);
3986         io.generic.level = RAW_OPEN_SMB2;
3987         io.smb2.in.desired_access = 0x0017019f;
3988         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3989         io.smb2.in.share_access = 0;
3990         io.smb2.in.alloc_size = 0;
3991         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
3992         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3993         io.smb2.in.security_flags = 0;
3994         io.smb2.in.fname = BASEDIR;
3995
3996         status = smb2_create(tree, torture, &(io.smb2));
3997         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3998         d1 = io.smb2.out.file.handle;
3999
4000         ZERO_STRUCT(sinfo);
4001         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
4002         sinfo.rename_information.in.file.handle = d1;
4003         sinfo.rename_information.in.overwrite = 0;
4004         sinfo.rename_information.in.root_fid = 0;
4005         sinfo.rename_information.in.new_name = renamedir;
4006
4007         status = smb2_setinfo_file(tree, &sinfo);
4008         torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
4009
4010         ZERO_STRUCT(cl.smb2);
4011         cl.smb2.level = RAW_CLOSE_SMB2;
4012         cl.smb2.in.file.handle = d1;
4013         status = smb2_close(tree, &(cl.smb2));
4014         torture_assert_ntstatus_ok(torture, status, "smb2_close");
4015         ZERO_STRUCT(d1);
4016
4017         cl.smb2.in.file.handle = h1;
4018         status = smb2_close(tree, &(cl.smb2));
4019         torture_assert_ntstatus_ok(torture, status, "smb2_close");
4020         ZERO_STRUCT(h1);
4021
4022         torture_comment(torture, "Cleaning up\n");
4023
4024         if (h1.data[0] || h1.data[1]) {
4025                 ZERO_STRUCT(cl.smb2);
4026                 cl.smb2.level = RAW_CLOSE_SMB2;
4027                 cl.smb2.in.file.handle = h1;
4028                 status = smb2_close(tree, &(cl.smb2));
4029         }
4030
4031         smb2_util_unlink(tree, BASEDIR "\\file.txt");
4032         smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
4033         smb2_deltree(tree, renamedir);
4034         smb2_deltree(tree, BASEDIR);
4035         return ret;
4036 }
4037
4038 static bool test_afpinfo_enoent(struct torture_context *tctx,
4039                                 struct smb2_tree *tree)
4040 {
4041         bool ret = true;
4042         NTSTATUS status;
4043         struct smb2_create create;
4044         struct smb2_handle h1;
4045         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4046         const char *fname = BASEDIR "\\file";
4047         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
4048
4049         torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
4050
4051         smb2_deltree(tree, BASEDIR);
4052         status = torture_smb2_testdir(tree, BASEDIR, &h1);
4053         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
4054         smb2_util_close(tree, h1);
4055         ret = torture_setup_file(mem_ctx, tree, fname, false);
4056         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4057
4058         torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
4059
4060         ZERO_STRUCT(create);
4061         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4062         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
4063         create.in.fname = sname;
4064
4065         status = smb2_create(tree, mem_ctx, &create);
4066         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4067                                            ret, done, "Got unexpected AFP_AfpInfo stream");
4068
4069 done:
4070         smb2_util_unlink(tree, fname);
4071         smb2_util_rmdir(tree, BASEDIR);
4072         return ret;
4073 }
4074
4075 static bool test_create_delete_on_close(struct torture_context *tctx,
4076                                         struct smb2_tree *tree)
4077 {
4078         bool ret = true;
4079         NTSTATUS status;
4080         struct smb2_create create;
4081         struct smb2_handle h1;
4082         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4083         const char *fname = BASEDIR "\\file";
4084         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
4085         const char *type_creator = "SMB,OLE!";
4086         AfpInfo *info = NULL;
4087         const char *streams_basic[] = {
4088                 "::$DATA"
4089         };
4090         const char *streams_afpinfo[] = {
4091                 "::$DATA",
4092                 AFPINFO_STREAM
4093         };
4094
4095         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
4096
4097         torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
4098
4099         smb2_deltree(tree, BASEDIR);
4100         status = torture_smb2_testdir(tree, BASEDIR, &h1);
4101         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
4102         smb2_util_close(tree, h1);
4103         ret = torture_setup_file(mem_ctx, tree, fname, false);
4104         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4105
4106         torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
4107
4108         ZERO_STRUCT(create);
4109         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4110         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
4111         create.in.fname = sname;
4112
4113         status = smb2_create(tree, mem_ctx, &create);
4114         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4115                                            ret, done, "Got unexpected AFP_AfpInfo stream");
4116
4117         ZERO_STRUCT(create);
4118         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4119         create.in.desired_access = SEC_FILE_ALL;
4120         create.in.fname = sname;
4121
4122         status = smb2_create(tree, mem_ctx, &create);
4123         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4124                                            ret, done, "Got unexpected AFP_AfpInfo stream");
4125
4126         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
4127         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4128
4129         torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
4130
4131         info = torture_afpinfo_new(mem_ctx);
4132         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
4133
4134         memcpy(info->afpi_FinderInfo, type_creator, 8);
4135         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
4136         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
4137
4138         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
4139                            0, 60, 16, 8, type_creator);
4140         torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
4141
4142         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
4143         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4144
4145         ZERO_STRUCT(create);
4146         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4147         create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
4148         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
4149         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4150         create.in.fname = sname;
4151         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4152
4153         status = smb2_create(tree, mem_ctx, &create);
4154         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4155
4156         h1 = create.out.file.handle;
4157         smb2_util_close(tree, h1);
4158
4159         ZERO_STRUCT(create);
4160         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4161         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4162         create.in.fname = sname;
4163         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4164         status = smb2_create(tree, mem_ctx, &create);
4165         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4166                                            ret, done, "Got unexpected AFP_AfpInfo stream");
4167
4168         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
4169         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4170
4171 done:
4172         smb2_util_unlink(tree, fname);
4173         smb2_util_rmdir(tree, BASEDIR);
4174         return ret;
4175 }
4176
4177 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
4178                                          struct smb2_tree *tree)
4179 {
4180         bool ret = true;
4181         NTSTATUS status;
4182         struct smb2_create create;
4183         union smb_setfileinfo sfinfo;
4184         struct smb2_handle h1;
4185         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4186         const char *fname = BASEDIR "\\file";
4187         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
4188         const char *type_creator = "SMB,OLE!";
4189         AfpInfo *info = NULL;
4190         const char *streams[] = {
4191                 AFPINFO_STREAM,
4192                 "::$DATA"
4193         };
4194         const char *streams_basic[] = {
4195                 "::$DATA"
4196         };
4197
4198         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
4199
4200         torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
4201
4202         smb2_deltree(tree, BASEDIR);
4203         status = torture_smb2_testdir(tree, BASEDIR, &h1);
4204         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
4205         smb2_util_close(tree, h1);
4206         ret = torture_setup_file(mem_ctx, tree, fname, false);
4207         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4208
4209         info = torture_afpinfo_new(mem_ctx);
4210         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
4211         memcpy(info->afpi_FinderInfo, type_creator, 8);
4212         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
4213         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
4214
4215         ZERO_STRUCT(create);
4216         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4217         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
4218         create.in.fname = sname;
4219         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4220         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4221
4222         status = smb2_create(tree, mem_ctx, &create);
4223         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4224
4225         h1 = create.out.file.handle;
4226
4227         /* Delete stream via setinfo delete-on-close */
4228         ZERO_STRUCT(sfinfo);
4229         sfinfo.disposition_info.in.delete_on_close = 1;
4230         sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
4231         sfinfo.generic.in.file.handle = h1;
4232         status = smb2_setinfo_file(tree, &sfinfo);
4233         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
4234
4235         ret = check_stream_list(tree, tctx, fname, 2, streams, false);
4236         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4237
4238         ZERO_STRUCT(create);
4239         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4240         create.in.desired_access = SEC_FILE_ALL;
4241         create.in.fname = sname;
4242         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4243         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4244         status = smb2_create(tree, mem_ctx, &create);
4245         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_DELETE_PENDING,
4246                                            ret, done, "Got unexpected AFP_AfpInfo stream");
4247
4248         smb2_util_close(tree, h1);
4249
4250         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
4251         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4252
4253         ZERO_STRUCT(create);
4254         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4255         create.in.desired_access = SEC_FILE_ALL;
4256         create.in.fname = sname;
4257         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4258         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4259         status = smb2_create(tree, mem_ctx, &create);
4260         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4261                                            ret, done, "Got unexpected AFP_AfpInfo stream");
4262
4263 done:
4264         smb2_util_unlink(tree, fname);
4265         smb2_util_rmdir(tree, BASEDIR);
4266         return ret;
4267 }
4268
4269 static bool test_setinfo_eof(struct torture_context *tctx,
4270                              struct smb2_tree *tree)
4271 {
4272         bool ret = true;
4273         NTSTATUS status;
4274         struct smb2_create create;
4275         union smb_setfileinfo sfinfo;
4276         struct smb2_handle h1;
4277         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4278         const char *fname = BASEDIR "\\file";
4279         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
4280         const char *type_creator = "SMB,OLE!";
4281         AfpInfo *info = NULL;
4282         const char *streams_afpinfo[] = {
4283                 "::$DATA",
4284                 AFPINFO_STREAM
4285         };
4286
4287         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
4288
4289         torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
4290
4291         smb2_deltree(tree, BASEDIR);
4292         status = torture_smb2_testdir(tree, BASEDIR, &h1);
4293         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
4294         smb2_util_close(tree, h1);
4295         ret = torture_setup_file(mem_ctx, tree, fname, false);
4296         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4297
4298         info = torture_afpinfo_new(mem_ctx);
4299         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
4300         memcpy(info->afpi_FinderInfo, type_creator, 8);
4301         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
4302         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
4303
4304         ZERO_STRUCT(create);
4305         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4306         create.in.desired_access = SEC_FILE_ALL;
4307         create.in.fname = sname;
4308         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4309         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4310
4311         status = smb2_create(tree, mem_ctx, &create);
4312         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4313
4314         h1 = create.out.file.handle;
4315
4316         torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
4317
4318         /* Test setinfo end-of-file info */
4319         ZERO_STRUCT(sfinfo);
4320         sfinfo.generic.in.file.handle = h1;
4321         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4322         sfinfo.position_information.in.position = 61;
4323         status = smb2_setinfo_file(tree, &sfinfo);
4324         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
4325                                            ret, done, "set eof 61 failed");
4326
4327         torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
4328
4329         /* Truncation returns success, but has no effect */
4330         ZERO_STRUCT(sfinfo);
4331         sfinfo.generic.in.file.handle = h1;
4332         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4333         sfinfo.position_information.in.position = 1;
4334         status = smb2_setinfo_file(tree, &sfinfo);
4335         torture_assert_ntstatus_ok_goto(tctx, status,
4336                                         ret, done, "set eof 1 failed");
4337         smb2_util_close(tree, h1);
4338
4339         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
4340         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4341
4342         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
4343                            0, 60, 16, 8, type_creator);
4344         torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
4345
4346         ZERO_STRUCT(create);
4347         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4348         create.in.desired_access = SEC_FILE_ALL;
4349         create.in.fname = sname;
4350         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4351         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4352
4353         status = smb2_create(tree, mem_ctx, &create);
4354         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4355
4356         h1 = create.out.file.handle;
4357
4358         /*
4359          * Delete stream via setinfo end-of-file info to 0, should
4360          * return success but stream MUST NOT deleted
4361          */
4362         ZERO_STRUCT(sfinfo);
4363         sfinfo.generic.in.file.handle = h1;
4364         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4365         sfinfo.position_information.in.position = 0;
4366         status = smb2_setinfo_file(tree, &sfinfo);
4367         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
4368
4369         smb2_util_close(tree, h1);
4370
4371         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
4372         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4373
4374         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
4375                            0, 60, 16, 8, type_creator);
4376         torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
4377
4378 done:
4379         smb2_util_unlink(tree, fname);
4380         smb2_util_rmdir(tree, BASEDIR);
4381         return ret;
4382 }
4383
4384 static bool test_afpinfo_all0(struct torture_context *tctx,
4385                               struct smb2_tree *tree)
4386 {
4387         bool ret = true;
4388         NTSTATUS status;
4389         struct smb2_create create;
4390         struct smb2_handle h1 = {{0}};
4391         struct smb2_handle baseh = {{0}};
4392         union smb_setfileinfo setfinfo;
4393         union smb_fileinfo getfinfo;
4394         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4395         const char *fname = BASEDIR "\\file";
4396         const char *sname = BASEDIR "\\file" AFPINFO_STREAM;
4397         const char *type_creator = "SMB,OLE!";
4398         AfpInfo *info = NULL;
4399         char *infobuf = NULL;
4400         const char *streams_basic[] = {
4401                 "::$DATA"
4402         };
4403         const char *streams_afpinfo[] = {
4404                 "::$DATA",
4405                 AFPINFO_STREAM
4406         };
4407
4408         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
4409
4410         torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
4411
4412         smb2_deltree(tree, BASEDIR);
4413         status = torture_smb2_testdir(tree, BASEDIR, &h1);
4414         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
4415         smb2_util_close(tree, h1);
4416         ret = torture_setup_file(mem_ctx, tree, fname, false);
4417         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4418
4419         info = torture_afpinfo_new(mem_ctx);
4420         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
4421         memcpy(info->afpi_FinderInfo, type_creator, 8);
4422         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
4423         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
4424
4425         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
4426         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4427
4428         /* Write all 0 to AFP_AfpInfo */
4429         memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
4430         infobuf = torture_afpinfo_pack(mem_ctx, info);
4431         torture_assert_not_null_goto(tctx, infobuf, ret, done,
4432                                      "torture_afpinfo_pack failed\n");
4433
4434         ZERO_STRUCT(create);
4435         create.in.desired_access = SEC_FILE_ALL;
4436         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4437         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4438         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4439         create.in.fname = fname;
4440
4441         status = smb2_create(tree, mem_ctx, &create);
4442         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4443                                         "smb2_create failed\n");
4444         baseh = create.out.file.handle;
4445
4446         ZERO_STRUCT(create);
4447         create.in.desired_access = SEC_FILE_ALL;
4448         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4449         create.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
4450         create.in.fname = sname;
4451
4452         status = smb2_create(tree, mem_ctx, &create);
4453         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4454                                         "smb2_create failed\n");
4455         h1 = create.out.file.handle;
4456
4457         status = smb2_util_write(tree, h1, infobuf, 0, AFP_INFO_SIZE);
4458         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4459                                         "smb2_util_write failed\n");
4460
4461         /*
4462          * Get stream information on open handle, must return only default
4463          * stream, the AFP_AfpInfo stream must not be returned.
4464          */
4465
4466         ZERO_STRUCT(getfinfo);
4467         getfinfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
4468         getfinfo.generic.in.file.handle = baseh;
4469
4470         status = smb2_getinfo_file(tree, tctx, &getfinfo);
4471         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4472                                         "get stream info\n");
4473
4474         torture_assert_int_equal_goto(tctx, getfinfo.stream_info.out.num_streams,
4475                                       1, ret, done, "stream count");
4476
4477         smb2_util_close(tree, baseh);
4478         ZERO_STRUCT(baseh);
4479
4480         /*
4481          * Try to set some file-basic-info (time) on the stream. This catches
4482          * naive implementation mistakes that simply deleted the backing store
4483          * from the filesystem in the zero-out step.
4484          */
4485
4486         ZERO_STRUCT(setfinfo);
4487         unix_to_nt_time(&setfinfo.basic_info.in.write_time, time(NULL));
4488         setfinfo.basic_info.in.attrib = 0x20;
4489         setfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
4490         setfinfo.generic.in.file.handle = h1;
4491
4492         status = smb2_setinfo_file(tree, &setfinfo);
4493         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4494                                         "smb2_getinfo_file failed\n");
4495
4496         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
4497         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
4498
4499         smb2_util_close(tree, h1);
4500         ZERO_STRUCT(h1);
4501
4502         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
4503         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4504
4505 done:
4506         if (!smb2_util_handle_empty(h1)) {
4507                 smb2_util_close(tree, h1);
4508         }
4509         if (!smb2_util_handle_empty(baseh)) {
4510                 smb2_util_close(tree, baseh);
4511         }
4512         smb2_util_unlink(tree, fname);
4513         smb2_util_rmdir(tree, BASEDIR);
4514         return ret;
4515 }
4516
4517 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
4518                                                  struct smb2_tree *tree)
4519 {
4520         bool ret = true;
4521         NTSTATUS status;
4522         struct smb2_create create;
4523         struct smb2_handle h1;
4524         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4525         const char *fname = BASEDIR "\\file";
4526         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
4527         const char *streams_basic[] = {
4528                 "::$DATA"
4529         };
4530         const char *streams_afpresource[] = {
4531                 "::$DATA",
4532                 AFPRESOURCE_STREAM
4533         };
4534
4535         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
4536
4537         torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
4538
4539         smb2_deltree(tree, BASEDIR);
4540         status = torture_smb2_testdir(tree, BASEDIR, &h1);
4541         torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
4542         smb2_util_close(tree, h1);
4543         ret = torture_setup_file(mem_ctx, tree, fname, false);
4544         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4545
4546         torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
4547
4548         ZERO_STRUCT(create);
4549         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4550         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
4551         create.in.fname = sname;
4552
4553         status = smb2_create(tree, mem_ctx, &create);
4554         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4555                                            ret, done, "Got unexpected AFP_AfpResource stream");
4556
4557         ZERO_STRUCT(create);
4558         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4559         create.in.desired_access = SEC_FILE_ALL;
4560         create.in.fname = sname;
4561
4562         status = smb2_create(tree, mem_ctx, &create);
4563         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4564                                            ret, done, "Got unexpected AFP_AfpResource stream");
4565
4566         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
4567         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4568
4569         torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
4570
4571         ret = write_stream(tree, __location__, tctx, mem_ctx,
4572                            fname, AFPRESOURCE_STREAM_NAME,
4573                            0, 10, "1234567890");
4574         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
4575
4576         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
4577                            0, 10, 0, 10, "1234567890");
4578         torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
4579
4580         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
4581         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4582
4583         ZERO_STRUCT(create);
4584         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4585         create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
4586         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
4587         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4588         create.in.fname = sname;
4589         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4590
4591         status = smb2_create(tree, mem_ctx, &create);
4592         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4593
4594         h1 = create.out.file.handle;
4595         smb2_util_close(tree, h1);
4596
4597         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
4598         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4599
4600         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
4601                            0, 10, 0, 10, "1234567890");
4602         torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
4603
4604 done:
4605         smb2_util_unlink(tree, fname);
4606         smb2_util_rmdir(tree, BASEDIR);
4607         return ret;
4608 }
4609
4610 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
4611                                                   struct smb2_tree *tree)
4612 {
4613         bool ret = true;
4614         NTSTATUS status;
4615         struct smb2_create create;
4616         union smb_setfileinfo sfinfo;
4617         struct smb2_handle h1;
4618         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4619         const char *fname = BASEDIR "\\file";
4620         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
4621         const char *streams_afpresource[] = {
4622                 "::$DATA",
4623                 AFPRESOURCE_STREAM
4624         };
4625
4626         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
4627
4628         torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
4629
4630         smb2_deltree(tree, BASEDIR);
4631         status = torture_smb2_testdir(tree, BASEDIR, &h1);
4632         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
4633         smb2_util_close(tree, h1);
4634         ret = torture_setup_file(mem_ctx, tree, fname, false);
4635         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4636
4637         ret = write_stream(tree, __location__, tctx, mem_ctx,
4638                            fname, AFPRESOURCE_STREAM_NAME,
4639                            10, 10, "1234567890");
4640         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
4641
4642         ZERO_STRUCT(create);
4643         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4644         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
4645         create.in.fname = sname;
4646         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4647         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4648
4649         status = smb2_create(tree, mem_ctx, &create);
4650         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4651
4652         h1 = create.out.file.handle;
4653
4654         /* Try to delete stream via setinfo delete-on-close */
4655         ZERO_STRUCT(sfinfo);
4656         sfinfo.disposition_info.in.delete_on_close = 1;
4657         sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
4658         sfinfo.generic.in.file.handle = h1;
4659         status = smb2_setinfo_file(tree, &sfinfo);
4660         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
4661
4662         smb2_util_close(tree, h1);
4663
4664         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
4665         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4666
4667         ZERO_STRUCT(create);
4668         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4669         create.in.desired_access = SEC_FILE_ALL;
4670         create.in.fname = sname;
4671         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4672         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4673         status = smb2_create(tree, mem_ctx, &create);
4674         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4675                                         "Got unexpected AFP_AfpResource stream");
4676
4677 done:
4678         smb2_util_unlink(tree, fname);
4679         smb2_util_rmdir(tree, BASEDIR);
4680         return ret;
4681 }
4682
4683 static bool test_setinfo_eof_resource(struct torture_context *tctx,
4684                                       struct smb2_tree *tree)
4685 {
4686         bool ret = true;
4687         NTSTATUS status;
4688         struct smb2_create create;
4689         union smb_setfileinfo sfinfo;
4690         union smb_fileinfo finfo;
4691         struct smb2_handle h1;
4692         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4693         const char *fname = BASEDIR "\\file";
4694         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
4695         const char *streams_basic[] = {
4696                 "::$DATA"
4697         };
4698
4699         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
4700
4701         ret = enable_aapl(tctx, tree);
4702         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
4703
4704         torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
4705
4706         smb2_deltree(tree, BASEDIR);
4707         status = torture_smb2_testdir(tree, BASEDIR, &h1);
4708         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
4709         smb2_util_close(tree, h1);
4710         ret = torture_setup_file(mem_ctx, tree, fname, false);
4711         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4712
4713         ret = write_stream(tree, __location__, tctx, mem_ctx,
4714                            fname, AFPRESOURCE_STREAM_NAME,
4715                            10, 10, "1234567890");
4716         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
4717
4718         ZERO_STRUCT(create);
4719         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4720         create.in.desired_access = SEC_FILE_ALL;
4721         create.in.fname = sname;
4722         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4723         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4724
4725         status = smb2_create(tree, mem_ctx, &create);
4726         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4727
4728         h1 = create.out.file.handle;
4729
4730         torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
4731
4732         /* Test setinfo end-of-file info */
4733         ZERO_STRUCT(sfinfo);
4734         sfinfo.generic.in.file.handle = h1;
4735         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4736         sfinfo.position_information.in.position = 1;
4737         status = smb2_setinfo_file(tree, &sfinfo);
4738         torture_assert_ntstatus_ok_goto(tctx, status,
4739                                         ret, done, "set eof 1 failed");
4740
4741         smb2_util_close(tree, h1);
4742
4743         /* Check size == 1 */
4744         ZERO_STRUCT(create);
4745         create.in.fname = sname;
4746         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4747         create.in.desired_access = SEC_FILE_ALL;
4748         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4749         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4750         status = smb2_create(tree, mem_ctx, &create);
4751         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4752
4753         h1 = create.out.file.handle;
4754
4755         ZERO_STRUCT(finfo);
4756         finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
4757         finfo.generic.in.file.handle = h1;
4758         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
4759         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
4760
4761         smb2_util_close(tree, h1);
4762
4763         torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
4764
4765         ZERO_STRUCT(create);
4766         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4767         create.in.desired_access = SEC_FILE_ALL;
4768         create.in.fname = sname;
4769         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4770         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4771
4772         status = smb2_create(tree, mem_ctx, &create);
4773         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4774
4775         h1 = create.out.file.handle;
4776
4777         /*
4778          * Delete stream via setinfo end-of-file info to 0, this
4779          * should delete the stream.
4780          */
4781         ZERO_STRUCT(sfinfo);
4782         sfinfo.generic.in.file.handle = h1;
4783         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4784         sfinfo.position_information.in.position = 0;
4785         status = smb2_setinfo_file(tree, &sfinfo);
4786         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
4787
4788         smb2_util_close(tree, h1);
4789
4790         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
4791         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4792
4793         ZERO_STRUCT(create);
4794         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4795         create.in.desired_access = SEC_FILE_ALL;
4796         create.in.fname = sname;
4797         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4798         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4799
4800         status = smb2_create(tree, mem_ctx, &create);
4801         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4802                                            ret, done, "smb2_create failed");
4803
4804 done:
4805         smb2_util_unlink(tree, fname);
4806         smb2_util_rmdir(tree, BASEDIR);
4807         return ret;
4808 }
4809
4810 /*
4811  * This tests that right after creating the AFP_AfpInfo stream,
4812  * reading from the stream returns an empty, default metadata blob of
4813  * 60 bytes.
4814  *
4815  * NOTE: against OS X SMB server this only works if the read request
4816  * is compounded with the create that created the stream, is fails
4817  * otherwise. We don't care...
4818  */
4819 static bool test_null_afpinfo(struct torture_context *tctx,
4820                               struct smb2_tree *tree)
4821 {
4822         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4823         const char *fname = "test_null_afpinfo";
4824         const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
4825         NTSTATUS status;
4826         bool ret = true;
4827         struct smb2_request *req[3];
4828         struct smb2_handle handle;
4829         struct smb2_create create;
4830         struct smb2_read read;
4831         AfpInfo *afpinfo = NULL;
4832         char *afpinfo_buf = NULL;
4833         const char *type_creator = "SMB,OLE!";
4834         struct smb2_handle handle2;
4835         struct smb2_read r;
4836
4837         torture_comment(tctx, "Checking create of AfpInfo stream\n");
4838
4839         smb2_util_unlink(tree, fname);
4840
4841         ret = torture_setup_file(mem_ctx, tree, fname, false);
4842         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
4843
4844         ZERO_STRUCT(create);
4845         create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
4846         create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
4847         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4848         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4849         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
4850         create.in.fname = sname;
4851
4852         smb2_transport_compound_start(tree->session->transport, 2);
4853
4854         req[0] = smb2_create_send(tree, &create);
4855
4856         handle.data[0] = UINT64_MAX;
4857         handle.data[1] = UINT64_MAX;
4858
4859         smb2_transport_compound_set_related(tree->session->transport, true);
4860
4861         ZERO_STRUCT(read);
4862         read.in.file.handle = handle;
4863         read.in.length = AFP_INFO_SIZE;
4864         req[1] = smb2_read_send(tree, &read);
4865
4866         status = smb2_create_recv(req[0], tree, &create);
4867         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
4868
4869         handle = create.out.file.handle;
4870
4871         status = smb2_read_recv(req[1], tree, &read);
4872         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
4873
4874         status = torture_smb2_testfile_access(tree, sname, &handle2,
4875                                               SEC_FILE_READ_DATA);
4876         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4877                                         "torture_smb2_testfile failed\n");
4878         r = (struct smb2_read) {
4879                 .in.file.handle = handle2,
4880                 .in.length      = AFP_INFO_SIZE,
4881         };
4882
4883         status = smb2_read(tree, tree, &r);
4884         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4885                                         "torture_smb2_testfile failed\n");
4886         smb2_util_close(tree, handle2);
4887
4888         afpinfo = torture_afpinfo_new(mem_ctx);
4889         torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
4890
4891         memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
4892
4893         afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
4894         torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
4895
4896         status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
4897         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
4898
4899         smb2_util_close(tree, handle);
4900
4901         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
4902                            0, 60, 16, 8, type_creator);
4903         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
4904
4905 done:
4906         smb2_util_unlink(tree, fname);
4907         talloc_free(mem_ctx);
4908         return ret;
4909 }
4910
4911 static bool test_delete_file_with_rfork(struct torture_context *tctx,
4912                                         struct smb2_tree *tree)
4913 {
4914         const char *fname = "torture_write_rfork_io";
4915         const char *rfork_content = "1234567890";
4916         NTSTATUS status;
4917         bool ret = true;
4918
4919         smb2_util_unlink(tree, fname);
4920
4921         torture_comment(tctx, "Test deleting file with resource fork\n");
4922
4923         ret = torture_setup_file(tctx, tree, fname, false);
4924         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
4925
4926         ret = write_stream(tree, __location__, tctx, tctx,
4927                            fname, AFPRESOURCE_STREAM_NAME,
4928                            10, 10, rfork_content);
4929         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
4930
4931         ret = check_stream(tree, __location__, tctx, tctx,
4932                            fname, AFPRESOURCE_STREAM_NAME,
4933                            0, 20, 10, 10, rfork_content);
4934         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
4935
4936         status = smb2_util_unlink(tree, fname);
4937         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
4938
4939 done:
4940         return ret;
4941 }
4942
4943 static bool test_rename_and_read_rsrc(struct torture_context *tctx,
4944                                       struct smb2_tree *tree)
4945 {
4946         bool ret = true;
4947         NTSTATUS status;
4948         struct smb2_create create, create2;
4949         struct smb2_handle h1, h2;
4950         const char *fname = "test_rename_openfile";
4951         const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
4952         const char *fname_renamed = "test_rename_openfile_renamed";
4953         const char *data = "1234567890";
4954         union smb_setfileinfo sinfo;
4955         bool server_is_macos = torture_setting_bool(tctx, "osx", false);
4956         NTSTATUS expected_status;
4957
4958         ret = enable_aapl(tctx, tree);
4959         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
4960
4961         torture_comment(tctx, "Create file with resource fork\n");
4962
4963         ret = torture_setup_file(tctx, tree, fname, false);
4964         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4965
4966         ret = write_stream(tree, __location__, tctx, tctx,
4967                            fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
4968         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4969
4970         torture_comment(tctx, "Open resource fork\n");
4971
4972         ZERO_STRUCT(create);
4973         create.in.desired_access = SEC_FILE_ALL;
4974         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4975         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4976         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4977         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4978         create.in.fname = sname;
4979
4980         status = smb2_create(tree, tctx, &create);
4981         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4982
4983         h1 = create.out.file.handle;
4984
4985         torture_comment(tctx, "Rename base file\n");
4986
4987         ZERO_STRUCT(create2);
4988         create2.in.desired_access = SEC_FILE_ALL;
4989         create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4990         create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4991         create2.in.create_disposition = NTCREATEX_DISP_OPEN;
4992         create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4993         create2.in.fname = fname;
4994
4995         status = smb2_create(tree, tctx, &create2);
4996         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4997
4998         h2 = create2.out.file.handle;
4999
5000         ZERO_STRUCT(sinfo);
5001         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
5002         sinfo.rename_information.in.file.handle = h2;
5003         sinfo.rename_information.in.overwrite = 0;
5004         sinfo.rename_information.in.root_fid = 0;
5005         sinfo.rename_information.in.new_name = fname_renamed;
5006
5007         if (server_is_macos) {
5008                 expected_status = NT_STATUS_SHARING_VIOLATION;
5009         } else {
5010                 expected_status = NT_STATUS_ACCESS_DENIED;
5011         }
5012
5013         status = smb2_setinfo_file(tree, &sinfo);
5014         torture_assert_ntstatus_equal_goto(
5015                 tctx, status, expected_status, ret, done,
5016                 "smb2_setinfo_file failed");
5017
5018         smb2_util_close(tree, h2);
5019
5020         status = smb2_util_write(tree, h1, "foo", 0, 3);
5021         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5022                                         "write failed\n");
5023
5024         smb2_util_close(tree, h1);
5025
5026 done:
5027         smb2_util_unlink(tree, fname);
5028         smb2_util_unlink(tree, fname_renamed);
5029
5030         return ret;
5031 }
5032
5033 static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
5034                                            struct smb2_tree *tree)
5035 {
5036         TALLOC_CTX *mem_ctx = talloc_new(tctx);
5037         const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
5038         const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
5039         NTSTATUS status;
5040         struct smb2_handle testdirh;
5041         bool ret = true;
5042         struct smb2_create io;
5043         AfpInfo *info;
5044         const char *type_creator = "SMB,OLE!";
5045         struct smb2_find f;
5046         unsigned int count;
5047         union smb_search_data *d;
5048         uint64_t rfork_len;
5049         int i;
5050
5051         smb2_deltree(tree, BASEDIR);
5052
5053         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
5054         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
5055         smb2_util_close(tree, testdirh);
5056
5057         torture_comment(tctx, "Enabling AAPL\n");
5058
5059         ret = enable_aapl(tctx, tree);
5060         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
5061
5062         /*
5063          * Now that Requested AAPL extensions are enabled, setup some
5064          * Mac files with metadata and resource fork
5065          */
5066
5067         torture_comment(tctx, "Preparing file\n");
5068
5069         ret = torture_setup_file(mem_ctx, tree, fname, false);
5070         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
5071
5072         info = torture_afpinfo_new(mem_ctx);
5073         torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
5074
5075         memcpy(info->afpi_FinderInfo, type_creator, 8);
5076         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
5077         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
5078
5079         ret = write_stream(tree, __location__, tctx, mem_ctx,
5080                            fname, AFPRESOURCE_STREAM_NAME,
5081                            0, 3, "foo");
5082         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
5083
5084         /*
5085          * Ok, file is prepared, now call smb2/find
5086          */
5087
5088         torture_comment(tctx, "Issue find\n");
5089
5090         ZERO_STRUCT(io);
5091         io.in.desired_access = SEC_RIGHTS_DIR_READ;
5092         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
5093         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
5094         io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
5095                               NTCREATEX_SHARE_ACCESS_WRITE |
5096                               NTCREATEX_SHARE_ACCESS_DELETE);
5097         io.in.create_disposition = NTCREATEX_DISP_OPEN;
5098         io.in.fname = BASEDIR;
5099         status = smb2_create(tree, tctx, &io);
5100         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
5101
5102         ZERO_STRUCT(f);
5103         f.in.file.handle        = io.out.file.handle;
5104         f.in.pattern            = "*";
5105         f.in.max_response_size  = 0x1000;
5106         f.in.level              = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
5107
5108         status = smb2_find_level(tree, tree, &f, &count, &d);
5109         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
5110
5111         status = smb2_util_close(tree, io.out.file.handle);
5112         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
5113
5114         torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
5115
5116         for (i = 0; i < count; i++) {
5117                 const char *found = d[i].id_both_directory_info.name.s;
5118
5119                 if (!strcmp(found, ".") || !strcmp(found, ".."))
5120                         continue;
5121                 if (strncmp(found, "._", 2) == 0) {
5122                         continue;
5123                 }
5124                 break;
5125         }
5126
5127         torture_assert_str_equal_goto(tctx,
5128                                       d[i].id_both_directory_info.name.s, name,
5129                                       ret, done, "bad name");
5130
5131         rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
5132         torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
5133
5134         torture_assert_mem_equal_goto(tctx, type_creator,
5135                                       d[i].id_both_directory_info.short_name_buf + 8,
5136                                       8, ret, done, "Bad FinderInfo");
5137 done:
5138         smb2_util_unlink(tree, fname);
5139         smb2_deltree(tree, BASEDIR);
5140         talloc_free(mem_ctx);
5141         return ret;
5142 }
5143
5144 static bool test_invalid_afpinfo(struct torture_context *tctx,
5145                                  struct smb2_tree *tree1,
5146                                  struct smb2_tree *tree2)
5147 {
5148         const char *fname = "filtest_invalid_afpinfo";
5149         const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
5150         struct smb2_create create;
5151         const char *streams_basic[] = {
5152                 "::$DATA"
5153         };
5154         const char *streams_afpinfo[] = {
5155                 "::$DATA",
5156                 AFPINFO_STREAM
5157         };
5158         NTSTATUS status;
5159         bool ret = true;
5160
5161         if (tree2 == NULL) {
5162                 torture_skip_goto(tctx, done, "need second share without fruit\n");
5163         }
5164
5165         torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
5166
5167         ret = torture_setup_file(tctx, tree2, fname, false);
5168         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
5169
5170         ret = write_stream(tree2, __location__, tctx, tctx,
5171                            fname, AFPINFO_STREAM_NAME,
5172                            0, 3, "foo");
5173         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
5174
5175         ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
5176         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
5177
5178         torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
5179
5180         ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
5181         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
5182
5183         torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
5184
5185         ZERO_STRUCT(create);
5186         create.in.desired_access = SEC_FILE_ALL;
5187         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5188         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5189         create.in.create_disposition = NTCREATEX_DISP_OPEN;
5190         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
5191         create.in.fname = sname;
5192
5193         status = smb2_create(tree1, tctx, &create);
5194         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
5195                                            ret, done, "Stream still around?");
5196
5197 done:
5198         smb2_util_unlink(tree1, fname);
5199         return ret;
5200 }
5201
5202 static bool test_writing_afpinfo(struct torture_context *tctx,
5203                                  struct smb2_tree *tree)
5204 {
5205         const char *fname = "filtest_invalid_afpinfo";
5206         const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM;
5207         const char *streams_afpinfo[] = {
5208                 "::$DATA",
5209                 AFPINFO_STREAM
5210         };
5211         bool ret = true;
5212         static AfpInfo *afpi = NULL;
5213         char *buf = NULL;
5214         char *afpi_buf = NULL;
5215         char *zero_buf = NULL;
5216         bool broken_osx = torture_setting_bool(tctx, "broken_osx_45759458", false);
5217         off_t min_offset_for_2streams = 16;
5218         int i;
5219         NTSTATUS status;
5220         struct test_sizes {
5221                 off_t offset;
5222                 size_t size;
5223                 bool expected_result;
5224         } test_sizes[] = {
5225                 { 0, 1, false},
5226                 { 0, 2, false},
5227                 { 0, 3, true},
5228                 { 0, 4, true},
5229                 { 0, 14, true},
5230                 { 0, 15, true},
5231                 { 0, 16, true},
5232                 { 0, 24, true},
5233                 { 0, 34, true},
5234                 { 0, 44, true},
5235                 { 0, 54, true},
5236                 { 0, 55, true},
5237                 { 0, 56, true},
5238                 { 0, 57, true},
5239                 { 0, 58, true},
5240                 { 0, 59, true},
5241                 { 0, 60, true},
5242                 { 0, 61, true},
5243                 { 0, 64, true},
5244                 { 0, 1024, true},
5245                 { 0, 10064, true},
5246
5247                 { 1, 1, false},
5248                 { 1, 2, false},
5249                 { 1, 3, false},
5250                 { 1, 4, false},
5251                 { 1, 14, false},
5252                 { 1, 15, false},
5253                 { 1, 16, false},
5254                 { 1, 24, false},
5255                 { 1, 34, false},
5256                 { 1, 44, false},
5257                 { 1, 54, false},
5258                 { 1, 55, false},
5259                 { 1, 56, false},
5260                 { 1, 57, false},
5261                 { 1, 58, false},
5262                 { 1, 59, false},
5263                 { 1, 60, true},
5264                 { 1, 61, true},
5265                 { 1, 1024, true},
5266                 { 1, 10064, true},
5267
5268                 { 30, 1, false},
5269                 { 30, 2, false},
5270                 { 30, 3, false},
5271                 { 30, 4, false},
5272                 { 30, 14, false},
5273                 { 30, 15, false},
5274                 { 30, 16, false},
5275                 { 30, 24, false},
5276                 { 30, 34, false},
5277                 { 30, 44, false},
5278                 { 30, 54, false},
5279                 { 30, 55, false},
5280                 { 30, 56, false},
5281                 { 30, 57, false},
5282                 { 30, 58, false},
5283                 { 30, 59, false},
5284                 { 30, 60, true},
5285                 { 30, 61, true},
5286                 { 30, 1024, true},
5287                 { 30, 10064, true},
5288
5289                 { 58, 1, false},
5290                 { 58, 2, false},
5291                 { 58, 3, false},
5292                 { 58, 4, false},
5293                 { 58, 14, false},
5294                 { 58, 15, false},
5295                 { 58, 16, false},
5296                 { 58, 24, false},
5297                 { 58, 34, false},
5298                 { 58, 44, false},
5299                 { 58, 54, false},
5300                 { 58, 55, false},
5301                 { 58, 56, false},
5302                 { 58, 57, false},
5303                 { 58, 58, false},
5304                 { 58, 59, false},
5305                 { 58, 60, true},
5306                 { 58, 61, true},
5307                 { 58, 1024, true},
5308                 { 58, 10064, true},
5309
5310                 { 59, 1, false},
5311                 { 59, 2, false},
5312                 { 59, 3, false},
5313                 { 59, 4, false},
5314                 { 59, 14, false},
5315                 { 59, 15, false},
5316                 { 59, 16, false},
5317                 { 59, 24, false},
5318                 { 59, 34, false},
5319                 { 59, 44, false},
5320                 { 59, 54, false},
5321                 { 59, 55, false},
5322                 { 59, 56, false},
5323                 { 59, 57, false},
5324                 { 59, 58, false},
5325                 { 59, 59, false},
5326                 { 59, 60, true},
5327                 { 59, 61, true},
5328                 { 59, 1024, true},
5329                 { 59, 10064, true},
5330
5331                 { 60, 1, false},
5332                 { 60, 2, false},
5333                 { 60, 3, false},
5334                 { 60, 4, false},
5335                 { 60, 14, false},
5336                 { 60, 15, false},
5337                 { 60, 16, false},
5338                 { 60, 24, false},
5339                 { 60, 34, false},
5340                 { 60, 44, false},
5341                 { 60, 54, false},
5342                 { 60, 55, false},
5343                 { 60, 56, false},
5344                 { 60, 57, false},
5345                 { 60, 58, false},
5346                 { 60, 59, false},
5347                 { 60, 60, true},
5348                 { 60, 61, true},
5349                 { 60, 1024, true},
5350                 { 60, 10064, true},
5351
5352                 { 61, 1, false},
5353                 { 61, 2, false},
5354                 { 61, 3, false},
5355                 { 61, 4, false},
5356                 { 61, 14, false},
5357                 { 61, 15, false},
5358                 { 61, 16, false},
5359                 { 61, 24, false},
5360                 { 61, 34, false},
5361                 { 61, 44, false},
5362                 { 61, 54, false},
5363                 { 61, 55, false},
5364                 { 61, 56, false},
5365                 { 61, 57, false},
5366                 { 61, 58, false},
5367                 { 61, 59, false},
5368                 { 61, 60, true},
5369                 { 61, 61, true},
5370                 { 61, 1024, true},
5371                 { 61, 10064, true},
5372
5373                 { 10000, 1, false},
5374                 { 10000, 2, false},
5375                 { 10000, 3, false},
5376                 { 10000, 4, false},
5377                 { 10000, 14, false},
5378                 { 10000, 15, false},
5379                 { 10000, 16, false},
5380                 { 10000, 24, false},
5381                 { 10000, 34, false},
5382                 { 10000, 44, false},
5383                 { 10000, 54, false},
5384                 { 10000, 55, false},
5385                 { 10000, 56, false},
5386                 { 10000, 57, false},
5387                 { 10000, 58, false},
5388                 { 10000, 59, false},
5389                 { 10000, 60, true},
5390                 { 10000, 61, true},
5391                 { 10000, 1024, true},
5392                 { 10000, 10064, true},
5393
5394                 { -1, 0, false},
5395         };
5396
5397         afpi = torture_afpinfo_new(tctx);
5398         torture_assert_not_null_goto(tctx, afpi, ret, done,
5399                                      "torture_afpinfo_new failed\n");
5400
5401         memcpy(afpi->afpi_FinderInfo, "FOO BAR ", 8);
5402
5403         buf = torture_afpinfo_pack(afpi, afpi);
5404         torture_assert_not_null_goto(tctx, buf, ret, done,
5405                                      "torture_afpinfo_pack failed\n");
5406
5407         afpi_buf = talloc_zero_array(tctx, char, 10064);
5408         torture_assert_not_null_goto(tctx, afpi_buf, ret, done,
5409                                      "talloc_zero_array failed\n");
5410         memcpy(afpi_buf, buf, 60);
5411
5412         zero_buf = talloc_zero_array(tctx, char, 10064);
5413         torture_assert_not_null_goto(tctx, zero_buf, ret, done,
5414                                      "talloc_zero_array failed\n");
5415
5416         ret = torture_setup_file(tctx, tree, fname, false);
5417         torture_assert_goto(tctx, ret == true, ret, done,
5418                             "torture_setup_file\n");
5419
5420         for (i = 0; test_sizes[i].offset != -1; i++) {
5421                 struct smb2_handle h;
5422                 struct smb2_create c;
5423                 int expected_num_streams;
5424                 size_t fi_check_size;
5425
5426                 torture_comment(tctx,
5427                                 "Test %d: offset=%jd size=%zu result=%s\n",
5428                                 i,
5429                                 (intmax_t)test_sizes[i].offset,
5430                                 test_sizes[i].size,
5431                                 test_sizes[i].expected_result ? "true":"false");
5432
5433
5434                 c = (struct smb2_create) {
5435                         .in.desired_access = SEC_FILE_WRITE_DATA,
5436                         .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5437                         .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
5438                         .in.fname = sname,
5439                 };
5440
5441                 status = smb2_create(tree, tree, &c);
5442                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5443                                                 "smb2_create\n");
5444                 h = c.out.file.handle;
5445
5446                 status = smb2_util_write(tree,
5447                                          h,
5448                                          zero_buf,
5449                                          test_sizes[i].offset,
5450                                          test_sizes[i].size);
5451                 torture_assert_ntstatus_equal_goto(
5452                         tctx, status, NT_STATUS_INVALID_PARAMETER,
5453                         ret, done, "smb2_util_write\n");
5454
5455                 status = smb2_util_write(tree,
5456                                          h,
5457                                          afpi_buf,
5458                                          test_sizes[i].offset,
5459                                          test_sizes[i].size);
5460                 smb2_util_close(tree, h);
5461                 if (test_sizes[i].expected_result == true) {
5462                         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5463                                                         "smb2_util_write\n");
5464                 } else {
5465                         torture_assert_ntstatus_equal_goto(
5466                                 tctx, status, NT_STATUS_INVALID_PARAMETER,
5467                                 ret, done, "smb2_util_write\n");
5468                 }
5469
5470                 if (broken_osx) {
5471                         /*
5472                          * Currently macOS has a bug (Radar #45759458) where it
5473                          * writes more bytes then requested from uninitialized
5474                          * memory to the filesystem. That means it will likely
5475                          * write data to FinderInfo so the stream is not empty
5476                          * and thus listed when the number of streams is
5477                          * queried.
5478                          */
5479                         min_offset_for_2streams = 2;
5480                 }
5481
5482                 if ((test_sizes[i].expected_result == true) &&
5483                     (test_sizes[i].size > min_offset_for_2streams))
5484                 {
5485                         expected_num_streams = 2;
5486                 } else {
5487                         expected_num_streams = 1;
5488                 }
5489
5490                 ret = check_stream_list(tree, tctx, fname,
5491                                         expected_num_streams,
5492                                         streams_afpinfo, false);
5493                 torture_assert_goto(tctx, ret == true, ret, done,
5494                                     "Bad streams\n");
5495
5496                 if (test_sizes[i].expected_result == false) {
5497                         continue;
5498                 }
5499
5500                 if (test_sizes[i].size <= 16) {
5501                         /*
5502                          * FinderInfo with the "FOO BAR " string we wrote above
5503                          * would start at offset 16. Check whether this test
5504                          * wrote 1 byte or more.
5505                          */
5506                         goto next;
5507                 }
5508
5509                 fi_check_size = test_sizes[i].size - 16;
5510                 fi_check_size = MIN(fi_check_size, 8);
5511
5512                 ret = check_stream(tree, __location__,
5513                                    tctx, tctx,
5514                                    fname, AFPINFO_STREAM,
5515                                    0, 60, 16, fi_check_size, "FOO BAR ");
5516                 torture_assert_goto(tctx, ret == true, ret, done,
5517                                     "Bad streams\n");
5518
5519 next:
5520                 status = smb2_util_unlink(tree, sname);
5521                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5522                         bool missing_ok;
5523
5524                         missing_ok = test_sizes[i].expected_result == false;
5525                         missing_ok |= test_sizes[i].size <= 16;
5526
5527                         torture_assert_goto(tctx, missing_ok,
5528                                             ret, done, "smb2_util_unlink\n");
5529                 }
5530         }
5531
5532 done:
5533         smb2_util_unlink(tree, fname);
5534         return ret;
5535 }
5536
5537 static bool test_zero_file_id(struct torture_context *tctx,
5538                               struct smb2_tree *tree)
5539 {
5540         const char *fname = "filtest_file_id";
5541         struct smb2_create create = {0};
5542         NTSTATUS status;
5543         bool ret = true;
5544         uint8_t zero_file_id[8] = {0};
5545
5546         torture_comment(tctx, "Testing zero file id\n");
5547
5548         ret = torture_setup_file(tctx, tree, fname, false);
5549         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
5550
5551         ZERO_STRUCT(create);
5552         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5553         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5554         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5555         create.in.create_disposition = NTCREATEX_DISP_OPEN;
5556         create.in.fname = fname;
5557         create.in.query_on_disk_id = true;
5558
5559         status = smb2_create(tree, tctx, &create);
5560         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
5561                                            done,
5562                                            "test file could not be opened");
5563         torture_assert_mem_not_equal_goto(tctx, create.out.on_disk_id,
5564                                           zero_file_id, 8, ret, done,
5565                                           "unexpected zero file id");
5566
5567         smb2_util_close(tree, create.out.file.handle);
5568
5569         ret = enable_aapl(tctx, tree);
5570         torture_assert(tctx, ret == true, "enable_aapl failed");
5571
5572         ZERO_STRUCT(create);
5573         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5574         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5575         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5576         create.in.create_disposition = NTCREATEX_DISP_OPEN;
5577         create.in.fname = fname;
5578         create.in.query_on_disk_id = true;
5579
5580         status = smb2_create(tree, tctx, &create);
5581         torture_assert_ntstatus_equal_goto(
5582             tctx, status, NT_STATUS_OK, ret, done,
5583             "test file could not be opened with AAPL");
5584         torture_assert_mem_equal_goto(tctx, create.out.on_disk_id, zero_file_id,
5585                                       8, ret, done, "non-zero file id");
5586
5587         smb2_util_close(tree, create.out.file.handle);
5588
5589 done:
5590         smb2_util_unlink(tree, fname);
5591         return ret;
5592 }
5593
5594 static bool copy_one_stream(struct torture_context *torture,
5595                             struct smb2_tree *tree,
5596                             TALLOC_CTX *tmp_ctx,
5597                             const char *src_sname,
5598                             const char *dst_sname)
5599 {
5600         struct smb2_handle src_h = {{0}};
5601         struct smb2_handle dest_h = {{0}};
5602         NTSTATUS status;
5603         union smb_ioctl io;
5604         struct srv_copychunk_copy cc_copy;
5605         struct srv_copychunk_rsp cc_rsp;
5606         enum ndr_err_code ndr_ret;
5607         bool ok = false;
5608
5609         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
5610                                    1, /* 1 chunk */
5611                                    src_sname,
5612                                    &src_h, 256, /* fill 256 byte src file */
5613                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
5614                                    dst_sname,
5615                                    &dest_h, 0,  /* 0 byte dest file */
5616                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
5617                                    &cc_copy,
5618                                    &io);
5619         torture_assert_goto(torture, ok == true, ok, done,
5620                             "setup copy chunk error\n");
5621
5622         /* copy all src file data (via a single chunk desc) */
5623         cc_copy.chunks[0].source_off = 0;
5624         cc_copy.chunks[0].target_off = 0;
5625         cc_copy.chunks[0].length = 256;
5626
5627         ndr_ret = ndr_push_struct_blob(
5628                 &io.smb2.in.out, tmp_ctx, &cc_copy,
5629                 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
5630
5631         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
5632                                    "ndr_push_srv_copychunk_copy\n");
5633
5634         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
5635         torture_assert_ntstatus_ok_goto(torture, status, ok, done,
5636                                         "FSCTL_SRV_COPYCHUNK\n");
5637
5638         ndr_ret = ndr_pull_struct_blob(
5639                 &io.smb2.out.out, tmp_ctx, &cc_rsp,
5640                 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
5641
5642         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
5643                                    "ndr_pull_srv_copychunk_rsp\n");
5644
5645         ok = check_copy_chunk_rsp(torture, &cc_rsp,
5646                                   1,    /* chunks written */
5647                                   0,    /* chunk bytes unsuccessfully written */
5648                                   256); /* total bytes written */
5649         torture_assert_goto(torture, ok == true, ok, done,
5650                             "bad copy chunk response data\n");
5651
5652         ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
5653         if (!ok) {
5654                 torture_fail(torture, "inconsistent file data\n");
5655         }
5656
5657 done:
5658         if (!smb2_util_handle_empty(src_h)) {
5659                 smb2_util_close(tree, src_h);
5660         }
5661         if (!smb2_util_handle_empty(dest_h)) {
5662                 smb2_util_close(tree, dest_h);
5663         }
5664
5665         return ok;
5666 }
5667
5668 static bool copy_finderinfo_stream(struct torture_context *torture,
5669                                    struct smb2_tree *tree,
5670                                    TALLOC_CTX *tmp_ctx,
5671                                    const char *src_name,
5672                                    const char *dst_name)
5673 {
5674         struct smb2_handle src_h = {{0}};
5675         struct smb2_handle dest_h = {{0}};
5676         NTSTATUS status;
5677         union smb_ioctl io;
5678         struct srv_copychunk_copy cc_copy;
5679         struct srv_copychunk_rsp cc_rsp;
5680         enum ndr_err_code ndr_ret;
5681         const char *type_creator = "SMB,OLE!";
5682         AfpInfo *info = NULL;
5683         const char *src_name_afpinfo = NULL;
5684         const char *dst_name_afpinfo = NULL;
5685         bool ok = false;
5686
5687         src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
5688                                            AFPINFO_STREAM);
5689         torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
5690                                      "talloc_asprintf failed\n");
5691
5692         dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
5693                                            AFPINFO_STREAM);
5694         torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
5695                                      "talloc_asprintf failed\n");
5696
5697         info = torture_afpinfo_new(tmp_ctx);
5698         torture_assert_not_null_goto(torture, info, ok, done,
5699                                      "torture_afpinfo_new failed\n");
5700
5701         memcpy(info->afpi_FinderInfo, type_creator, 8);
5702         ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
5703         torture_assert_goto(torture, ok == true, ok, done,
5704                             "torture_write_afpinfo failed\n");
5705
5706         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
5707                                    1, /* 1 chunk */
5708                                    src_name_afpinfo,
5709                                    &src_h, 0,
5710                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
5711                                    dst_name_afpinfo,
5712                                    &dest_h, 0,
5713                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
5714                                    &cc_copy,
5715                                    &io);
5716         torture_assert_goto(torture, ok == true, ok, done,
5717                             "setup copy chunk error\n");
5718
5719         /* copy all src file data (via a single chunk desc) */
5720         cc_copy.chunks[0].source_off = 0;
5721         cc_copy.chunks[0].target_off = 0;
5722         cc_copy.chunks[0].length = 60;
5723
5724         ndr_ret = ndr_push_struct_blob(
5725                 &io.smb2.in.out, tmp_ctx, &cc_copy,
5726                 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
5727
5728         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
5729                                    "ndr_push_srv_copychunk_copy\n");
5730
5731         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
5732         torture_assert_ntstatus_ok_goto(torture, status, ok, done,
5733                                         "FSCTL_SRV_COPYCHUNK\n");
5734
5735         ndr_ret = ndr_pull_struct_blob(
5736                 &io.smb2.out.out, tmp_ctx, &cc_rsp,
5737                 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
5738
5739         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
5740                                    "ndr_pull_srv_copychunk_rsp\n");
5741
5742         smb2_util_close(tree, src_h);
5743         ZERO_STRUCT(src_h);
5744         smb2_util_close(tree, dest_h);
5745         ZERO_STRUCT(dest_h);
5746
5747         ok = check_copy_chunk_rsp(torture, &cc_rsp,
5748                                   1,    /* chunks written */
5749                                   0,    /* chunk bytes unsuccessfully written */
5750                                   60); /* total bytes written */
5751         torture_assert_goto(torture, ok == true, ok, done,
5752                             "bad copy chunk response data\n");
5753
5754         ok = check_stream(tree, __location__, torture, tmp_ctx,
5755                           dst_name, AFPINFO_STREAM,
5756                           0, 60, 16, 8, type_creator);
5757         torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
5758
5759 done:
5760         if (!smb2_util_handle_empty(src_h)) {
5761                 smb2_util_close(tree, src_h);
5762         }
5763         if (!smb2_util_handle_empty(dest_h)) {
5764                 smb2_util_close(tree, dest_h);
5765         }
5766
5767         return ok;
5768 }
5769
5770 static bool test_copy_chunk_streams(struct torture_context *torture,
5771                                     struct smb2_tree *tree)
5772 {
5773         const char *src_name = "src";
5774         const char *dst_name = "dst";
5775         struct names {
5776                 const char *src_sname;
5777                 const char *dst_sname;
5778         } names[] = {
5779                 { "src:foo", "dst:foo" },
5780                 { "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
5781         };
5782         int i;
5783         TALLOC_CTX *tmp_ctx = NULL;
5784         bool ok = false;
5785
5786         tmp_ctx = talloc_new(tree);
5787         torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
5788                                      "torture_setup_file\n");
5789
5790         smb2_util_unlink(tree, src_name);
5791         smb2_util_unlink(tree, dst_name);
5792
5793         ok = torture_setup_file(torture, tree, src_name, false);
5794         torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
5795         ok = torture_setup_file(torture, tree, dst_name, false);
5796         torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
5797
5798         for (i = 0; i < ARRAY_SIZE(names); i++) {
5799                 ok = copy_one_stream(torture, tree, tmp_ctx,
5800                                      names[i].src_sname,
5801                                      names[i].dst_sname);
5802                 torture_assert_goto(torture, ok == true, ok, done,
5803                                     "copy_one_stream failed\n");
5804         }
5805
5806         ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
5807                                     src_name, dst_name);
5808         torture_assert_goto(torture, ok == true, ok, done,
5809                             "copy_finderinfo_stream failed\n");
5810
5811 done:
5812         smb2_util_unlink(tree, src_name);
5813         smb2_util_unlink(tree, dst_name);
5814         talloc_free(tmp_ctx);
5815         return ok;
5816 }
5817
5818 /*
5819  * Ensure this security descriptor has exactly one mode, uid
5820  * and gid.
5821  */
5822
5823 static NTSTATUS check_nfs_sd(const struct security_descriptor *psd)
5824 {
5825         uint32_t i;
5826         bool got_one_mode = false;
5827         bool got_one_uid = false;
5828         bool got_one_gid = false;
5829
5830         if (psd->dacl == NULL) {
5831                 return NT_STATUS_INVALID_SECURITY_DESCR;
5832         }
5833
5834         for (i = 0; i < psd->dacl->num_aces; i++) {
5835                 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Mode,
5836                                            &psd->dacl->aces[i].trustee) == 0) {
5837                         if (got_one_mode == true) {
5838                                 /* Can't have more than one. */
5839                                 return NT_STATUS_INVALID_SECURITY_DESCR;
5840                         }
5841                         got_one_mode = true;
5842                 }
5843         }
5844         for (i = 0; i < psd->dacl->num_aces; i++) {
5845                 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Users,
5846                                            &psd->dacl->aces[i].trustee) == 0) {
5847                         if (got_one_uid == true) {
5848                                 /* Can't have more than one. */
5849                                 return NT_STATUS_INVALID_SECURITY_DESCR;
5850                         }
5851                         got_one_uid = true;
5852                 }
5853         }
5854         for (i = 0; i < psd->dacl->num_aces; i++) {
5855                 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Groups,
5856                                            &psd->dacl->aces[i].trustee) == 0) {
5857                         if (got_one_gid == true) {
5858                                 /* Can't have more than one. */
5859                                 return NT_STATUS_INVALID_SECURITY_DESCR;
5860                         }
5861                         got_one_gid = true;
5862                 }
5863         }
5864         /* Must have at least one of each. */
5865         if (got_one_mode == false ||
5866                         got_one_uid == false ||
5867                         got_one_gid == false) {
5868                 return NT_STATUS_INVALID_SECURITY_DESCR;
5869         }
5870         return NT_STATUS_OK;
5871 }
5872
5873 static bool test_nfs_aces(struct torture_context *tctx,
5874                           struct smb2_tree *tree)
5875 {
5876         TALLOC_CTX *mem_ctx = talloc_new(tctx);
5877         struct security_ace ace;
5878         struct dom_sid sid;
5879         const char *fname = BASEDIR "\\nfs_aces.txt";
5880         struct smb2_handle h = {{0}};
5881         union smb_fileinfo finfo2;
5882         union smb_setfileinfo set;
5883         struct security_descriptor *psd = NULL;
5884         NTSTATUS status;
5885         bool ret = true;
5886         bool is_osx = torture_setting_bool(tctx, "osx", false);
5887
5888         if (is_osx) {
5889                 torture_skip(tctx, "Test only works with Samba\n");
5890         }
5891
5892         ret = enable_aapl(tctx, tree);
5893         torture_assert(tctx, ret == true, "enable_aapl failed");
5894
5895         /* clean slate ...*/
5896         smb2_util_unlink(tree, fname);
5897         smb2_deltree(tree, fname);
5898         smb2_deltree(tree, BASEDIR);
5899
5900         status = torture_smb2_testdir(tree, BASEDIR, &h);
5901         CHECK_STATUS(status, NT_STATUS_OK);
5902         smb2_util_close(tree, h);
5903
5904         /* Create a test file. */
5905         status = torture_smb2_testfile_access(tree,
5906                                 fname,
5907                                 &h,
5908                                 SEC_STD_READ_CONTROL |
5909                                 SEC_STD_WRITE_DAC |
5910                                 SEC_RIGHTS_FILE_ALL);
5911         CHECK_STATUS(status, NT_STATUS_OK);
5912
5913         /* Get the ACL. */
5914         finfo2.query_secdesc.in.secinfo_flags =
5915                 SECINFO_OWNER |
5916                 SECINFO_GROUP |
5917                 SECINFO_DACL;
5918         finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
5919         finfo2.generic.in.file.handle = h;
5920         status = smb2_getinfo_file(tree, tctx, &finfo2);
5921         CHECK_STATUS(status, NT_STATUS_OK);
5922
5923         psd = finfo2.query_secdesc.out.sd;
5924
5925         /* Ensure we have only single mode/uid/gid NFS entries. */
5926         status = check_nfs_sd(psd);
5927         if (!NT_STATUS_IS_OK(status)) {
5928                 NDR_PRINT_DEBUG(
5929                         security_descriptor,
5930                         discard_const_p(struct security_descriptor, psd));
5931         }
5932         CHECK_STATUS(status, NT_STATUS_OK);
5933
5934         /* Add a couple of extra NFS uids and gids. */
5935         sid_compose(&sid, &global_sid_Unix_NFS_Users, 27);
5936         init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
5937         status = security_descriptor_dacl_add(psd, &ace);
5938         CHECK_STATUS(status, NT_STATUS_OK);
5939         status = security_descriptor_dacl_add(psd, &ace);
5940         CHECK_STATUS(status, NT_STATUS_OK);
5941
5942         sid_compose(&sid, &global_sid_Unix_NFS_Groups, 300);
5943         init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
5944         status = security_descriptor_dacl_add(psd, &ace);
5945         CHECK_STATUS(status, NT_STATUS_OK);
5946         status = security_descriptor_dacl_add(psd, &ace);
5947         CHECK_STATUS(status, NT_STATUS_OK);
5948
5949         /* Now set on the file handle. */
5950         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
5951         set.set_secdesc.in.file.handle = h;
5952         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
5953         set.set_secdesc.in.sd = psd;
5954         status = smb2_setinfo_file(tree, &set);
5955         CHECK_STATUS(status, NT_STATUS_OK);
5956
5957         /* Get the ACL again. */
5958         finfo2.query_secdesc.in.secinfo_flags =
5959                 SECINFO_OWNER |
5960                 SECINFO_GROUP |
5961                 SECINFO_DACL;
5962         finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
5963         finfo2.generic.in.file.handle = h;
5964         status = smb2_getinfo_file(tree, tctx, &finfo2);
5965         CHECK_STATUS(status, NT_STATUS_OK);
5966
5967         psd = finfo2.query_secdesc.out.sd;
5968
5969         /* Ensure we have only single mode/uid/gid NFS entries. */
5970         status = check_nfs_sd(psd);
5971         if (!NT_STATUS_IS_OK(status)) {
5972                 NDR_PRINT_DEBUG(
5973                         security_descriptor,
5974                         discard_const_p(struct security_descriptor, psd));
5975         }
5976         CHECK_STATUS(status, NT_STATUS_OK);
5977
5978 done:
5979         if (!smb2_util_handle_empty(h)) {
5980                 smb2_util_close(tree, h);
5981         }
5982         smb2_util_unlink(tree, fname);
5983         smb2_deltree(tree, fname);
5984         smb2_deltree(tree, BASEDIR);
5985         talloc_free(mem_ctx);
5986         return ret;
5987 }
5988
5989 static bool test_setinfo_stream_eof(struct torture_context *tctx,
5990                                     struct smb2_tree *tree)
5991 {
5992         bool ret = true;
5993         NTSTATUS status;
5994         struct smb2_create create;
5995         union smb_setfileinfo sfinfo;
5996         union smb_fileinfo finfo;
5997         struct smb2_handle h1;
5998         TALLOC_CTX *mem_ctx = talloc_new(tctx);
5999         const char *fname = BASEDIR "\\file";
6000         const char *sname = BASEDIR "\\file:foo";
6001
6002         torture_assert_goto(tctx, mem_ctx != NULL, ret, done,
6003                             "talloc_new failed\n");
6004
6005         ret = enable_aapl(tctx, tree);
6006         torture_assert(tctx, ret == true, "enable_aapl failed");
6007
6008         torture_comment(tctx, "Test setting EOF on a stream\n");
6009
6010         smb2_deltree(tree, BASEDIR);
6011         status = torture_smb2_testdir(tree, BASEDIR, &h1);
6012         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6013                                         "torture_smb2_testdir\n");
6014         smb2_util_close(tree, h1);
6015
6016         status = torture_smb2_testfile(tree, fname, &h1);
6017         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6018                                         "torture_smb2_testfile failed\n");
6019         smb2_util_close(tree, h1);
6020
6021         status = torture_smb2_testfile_access(tree, sname, &h1,
6022                                               SEC_FILE_WRITE_DATA);
6023         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6024                                         "torture_smb2_testfile failed\n");
6025
6026         status = smb2_util_write(tree, h1, "1234567890", 0, 10);
6027         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6028                                         "smb2_util_write failed\n");
6029         smb2_util_close(tree, h1);
6030
6031         /*
6032          * Test setting EOF to 21
6033          */
6034
6035         torture_comment(tctx, "Setting stream EOF to 21\n");
6036
6037         status = torture_smb2_testfile_access(tree, sname, &h1,
6038                                               SEC_FILE_WRITE_DATA);
6039         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6040                                         "torture_smb2_testfile failed\n");
6041
6042         ZERO_STRUCT(sfinfo);
6043         sfinfo.generic.in.file.handle = h1;
6044         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
6045         sfinfo.position_information.in.position = 21;
6046         status = smb2_setinfo_file(tree, &sfinfo);
6047         torture_assert_ntstatus_ok_goto(tctx, status,
6048                                         ret, done, "set EOF 21 failed\n");
6049
6050         smb2_util_close(tree, h1);
6051
6052         status = torture_smb2_testfile_access(tree, sname, &h1,
6053                                               SEC_FILE_WRITE_DATA);
6054         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6055                                         "torture_smb2_testfile failed\n");
6056
6057         ZERO_STRUCT(finfo);
6058         finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
6059         finfo.generic.in.file.handle = h1;
6060         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
6061         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6062                                         "smb2_getinfo_file failed");
6063
6064         smb2_util_close(tree, h1);
6065
6066         torture_assert_goto(tctx, finfo.standard_info.out.size == 21,
6067                             ret, done, "size != 21\n");
6068
6069         /*
6070          * Test setting EOF to 0
6071          */
6072
6073         torture_comment(tctx, "Setting stream EOF to 0\n");
6074
6075         status = torture_smb2_testfile_access(tree, sname, &h1,
6076                                               SEC_FILE_WRITE_DATA);
6077         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6078                                         "torture_smb2_testfile failed\n");
6079
6080         ZERO_STRUCT(sfinfo);
6081         sfinfo.generic.in.file.handle = h1;
6082         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
6083         sfinfo.position_information.in.position = 0;
6084         status = smb2_setinfo_file(tree, &sfinfo);
6085         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6086                                         "set eof 0 failed\n");
6087
6088         ZERO_STRUCT(create);
6089         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
6090         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
6091         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
6092         create.in.create_disposition = NTCREATEX_DISP_OPEN;
6093         create.in.fname = sname;
6094
6095         status = smb2_create(tree, tctx, &create);
6096         torture_assert_ntstatus_equal_goto(
6097                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
6098                 "Unexpected status\n");
6099
6100         smb2_util_close(tree, h1);
6101
6102         ZERO_STRUCT(create);
6103         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
6104         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
6105         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
6106         create.in.create_disposition = NTCREATEX_DISP_OPEN;
6107         create.in.fname = sname;
6108
6109         status = smb2_create(tree, tctx, &create);
6110         torture_assert_ntstatus_equal_goto(
6111                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
6112                 "Unexpected status\n");
6113
6114         status = torture_smb2_testfile_access(tree, sname, &h1,
6115                                               SEC_FILE_WRITE_DATA);
6116         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6117                                         "torture_smb2_testfile failed\n");
6118
6119         ZERO_STRUCT(finfo);
6120         finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
6121         finfo.generic.in.file.handle = h1;
6122         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
6123         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6124                                         "smb2_getinfo_file failed\n");
6125
6126         smb2_util_close(tree, h1);
6127
6128         torture_assert_goto(tctx, finfo.standard_info.out.size == 0,
6129                             ret, done, "size != 0\n");
6130
6131         /*
6132          * Test setinfo end-of-file info to 1
6133          */
6134
6135         torture_comment(tctx, "Setting stream EOF to 1\n");
6136
6137         status = torture_smb2_testfile_access(tree, sname, &h1,
6138                                               SEC_FILE_WRITE_DATA);
6139         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6140                                         "torture_smb2_testfile failed\n");
6141
6142         ZERO_STRUCT(sfinfo);
6143         sfinfo.generic.in.file.handle = h1;
6144         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
6145         sfinfo.position_information.in.position = 1;
6146         status = smb2_setinfo_file(tree, &sfinfo);
6147         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6148                                         "set EOF 1 failed\n");
6149
6150         smb2_util_close(tree, h1);
6151
6152         status = torture_smb2_testfile_access(tree, sname, &h1,
6153                                               SEC_FILE_WRITE_DATA);
6154         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6155                                         "torture_smb2_testfile failed\n");
6156
6157         ZERO_STRUCT(finfo);
6158         finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
6159         finfo.generic.in.file.handle = h1;
6160         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
6161         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6162                                         "smb2_getinfo_file failed\n");
6163
6164         smb2_util_close(tree, h1);
6165
6166         torture_assert_goto(tctx, finfo.standard_info.out.size == 1,
6167                             ret, done, "size != 1\n");
6168
6169         /*
6170          * Test setting EOF to 0 with AAPL enabled, should delete stream
6171          */
6172
6173         torture_comment(tctx, "Enabling AAPL extensions\n");
6174
6175         ret = enable_aapl(tctx, tree);
6176         torture_assert(tctx, ret == true, "enable_aapl failed\n");
6177
6178         torture_comment(tctx, "Setting stream EOF to 0\n");
6179         status = torture_smb2_testfile_access(tree, sname, &h1,
6180                                               SEC_FILE_WRITE_DATA);
6181         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6182                                         "torture_smb2_testfile failed\n");
6183
6184         ZERO_STRUCT(sfinfo);
6185         sfinfo.generic.in.file.handle = h1;
6186         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
6187         sfinfo.position_information.in.position = 0;
6188         status = smb2_setinfo_file(tree, &sfinfo);
6189         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6190                                         "set eof 0 failed\n");
6191
6192         ZERO_STRUCT(create);
6193         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
6194         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
6195         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
6196         create.in.create_disposition = NTCREATEX_DISP_OPEN;
6197         create.in.fname = sname;
6198
6199         status = smb2_create(tree, tctx, &create);
6200         torture_assert_ntstatus_equal_goto(
6201                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
6202                 "Unexpected status\n");
6203
6204         smb2_util_close(tree, h1);
6205
6206         ZERO_STRUCT(create);
6207         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
6208         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
6209         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
6210         create.in.create_disposition = NTCREATEX_DISP_OPEN;
6211         create.in.fname = sname;
6212
6213         status = smb2_create(tree, tctx, &create);
6214         torture_assert_ntstatus_equal_goto(
6215                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
6216                 "Unexpected status\n");
6217
6218         torture_comment(
6219                 tctx, "Setting main file EOF to 1 to force 0-truncate\n");
6220
6221         status = torture_smb2_testfile_access(
6222                 tree,
6223                 fname,
6224                 &h1,
6225                 SEC_FILE_WRITE_DATA);
6226         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6227                                         "torture_smb2_testfile failed\n");
6228
6229         ZERO_STRUCT(sfinfo);
6230         sfinfo.generic.in.file.handle = h1;
6231         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
6232         sfinfo.position_information.in.position = 1;
6233         status = smb2_setinfo_file(tree, &sfinfo);
6234         torture_assert_ntstatus_ok_goto(
6235                 tctx,
6236                 status,
6237                 ret,
6238                 done,
6239                 "set eof 1 failed\n");
6240
6241         sfinfo.position_information.in.position = 0;
6242         status = smb2_setinfo_file(tree, &sfinfo);
6243         torture_assert_ntstatus_ok_goto(
6244                 tctx,
6245                 status,
6246                 ret,
6247                 done,
6248                 "set eof 0 failed\n");
6249
6250         smb2_util_close(tree, h1);
6251
6252         ZERO_STRUCT(create);
6253         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
6254         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
6255         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
6256         create.in.create_disposition = NTCREATEX_DISP_OPEN;
6257         create.in.fname = fname;
6258
6259         status = smb2_create(tree, tctx, &create);
6260         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6261                                         "torture_smb2_testfile failed\n");
6262         smb2_util_close(tree, h1);
6263
6264         torture_comment(tctx, "Writing to stream after setting EOF to 0\n");
6265         status = torture_smb2_testfile_access(tree, sname, &h1,
6266                                               SEC_FILE_WRITE_DATA);
6267         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6268                                         "torture_smb2_testfile failed\n");
6269
6270         status = smb2_util_write(tree, h1, "1234567890", 0, 10);
6271         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6272                                         "smb2_util_write failed\n");
6273
6274         ZERO_STRUCT(sfinfo);
6275         sfinfo.generic.in.file.handle = h1;
6276         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
6277         sfinfo.position_information.in.position = 0;
6278         status = smb2_setinfo_file(tree, &sfinfo);
6279         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6280                                         "set eof 0 failed\n");
6281
6282         status = smb2_util_write(tree, h1, "1234567890", 0, 10);
6283         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6284                                         "smb2_util_write failed\n");
6285
6286         smb2_util_close(tree, h1);
6287
6288 done:
6289         smb2_util_unlink(tree, fname);
6290         smb2_util_rmdir(tree, BASEDIR);
6291         return ret;
6292 }
6293
6294 #define MAX_STREAMS 16
6295
6296 struct tcase {
6297         const char *name;
6298         uint32_t access;
6299         const char *write_data;
6300         size_t write_size;
6301         struct tcase_results {
6302                 size_t size;
6303                 NTSTATUS initial_status;
6304                 NTSTATUS final_status;
6305                 int num_streams_open_handle;
6306                 const char *streams_open_handle[MAX_STREAMS];
6307                 int num_streams_closed_handle;
6308                 const char *streams_closed_handle[MAX_STREAMS];
6309         } create, write, overwrite, eof, doc;
6310 };
6311
6312 typedef enum {T_CREATE, T_WRITE, T_OVERWRITE, T_EOF, T_DOC} subtcase_t;
6313
6314 static bool test_empty_stream_do_checks(
6315         struct torture_context *tctx,
6316         struct smb2_tree *tree,
6317         struct smb2_tree *tree2,
6318         struct tcase *tcase,
6319         TALLOC_CTX *mem_ctx,
6320         struct smb2_handle baseh,
6321         struct smb2_handle streamh,
6322         subtcase_t subcase)
6323 {
6324         bool ret = false;
6325         NTSTATUS status;
6326         struct smb2_handle h1;
6327         union smb_fileinfo finfo;
6328         struct tcase_results *tcase_results = NULL;
6329
6330         switch (subcase) {
6331         case T_CREATE:
6332                 tcase_results = &tcase->create;
6333                 break;
6334         case T_OVERWRITE:
6335                 tcase_results = &tcase->overwrite;
6336                 break;
6337         case T_WRITE:
6338                 tcase_results = &tcase->write;
6339                 break;
6340         case T_EOF:
6341                 tcase_results = &tcase->eof;
6342                 break;
6343         case T_DOC:
6344                 tcase_results = &tcase->doc;
6345                 break;
6346         }
6347
6348         finfo = (union smb_fileinfo) {
6349                 .generic.level = RAW_FILEINFO_STANDARD_INFORMATION,
6350                 .generic.in.file.handle = streamh,
6351         };
6352
6353         /*
6354          * Test: check size, same client
6355          */
6356
6357         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
6358         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6359                                         "torture_smb2_testfile failed\n");
6360
6361         torture_assert_int_equal_goto(tctx, finfo.standard_info.out.size,
6362                                       tcase_results->size,
6363                                       ret, done, "Wrong size\n");
6364
6365         /*
6366          * Test: open, same client
6367          */
6368
6369         status = torture_smb2_open(tree, tcase->name,
6370                                    SEC_FILE_READ_ATTRIBUTE, &h1);
6371         torture_assert_ntstatus_equal_goto(tctx, status,
6372                                            tcase_results->initial_status,
6373                                            ret, done,
6374                                            "smb2_create failed\n");
6375         if (NT_STATUS_IS_OK(status)) {
6376                 status = smb2_util_close(tree, h1);
6377                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6378                                                 "smb2_util_close failed\n");
6379         }
6380
6381         /*
6382          * Test: check streams, same client
6383          */
6384
6385         ret = check_stream_list_handle(tree, tctx, baseh,
6386                                        tcase_results->num_streams_open_handle,
6387                                        tcase_results->streams_open_handle,
6388                                        false);
6389         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
6390
6391         /*
6392          * Test: open, different client
6393          */
6394
6395         status = torture_smb2_open(tree2, tcase->name,
6396                                    SEC_FILE_READ_ATTRIBUTE, &h1);
6397         torture_assert_ntstatus_equal_goto(tctx, status,
6398                                            tcase_results->initial_status,
6399                                            ret, done,
6400                                            "smb2_create failed\n");
6401         if (NT_STATUS_IS_OK(status)) {
6402                 finfo = (union smb_fileinfo) {
6403                         .generic.level = RAW_FILEINFO_STANDARD_INFORMATION,
6404                         .generic.in.file.handle = h1,
6405                 };
6406
6407                 /*
6408                  * Test: check size, different client
6409                  */
6410
6411                 status = smb2_getinfo_file(tree2, mem_ctx, &finfo);
6412                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6413                                                 "smb2_getinfo_file failed\n");
6414
6415                 torture_assert_int_equal_goto(tctx, finfo.standard_info.out.size,
6416                                               tcase_results->size,
6417                                               ret, done, "Wrong size\n");
6418
6419                 /*
6420                  * Test: check streams, different client
6421                  */
6422
6423                 ret = check_stream_list(tree2, tctx, BASEDIR "\\file",
6424                                         tcase_results->num_streams_open_handle,
6425                                         tcase_results->streams_open_handle,
6426                                         false);
6427                 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
6428
6429                 status = smb2_util_close(tree2, h1);
6430                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6431                                                 "smb2_util_close failed\n");
6432         }
6433
6434         status = smb2_util_close(tree, streamh);
6435         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6436                                         "smb2_util_close failed\n");
6437
6438         /*
6439          * Test: open after close, same client
6440          */
6441
6442         status = torture_smb2_open(tree, tcase->name,
6443                                    SEC_FILE_READ_DATA, &h1);
6444         torture_assert_ntstatus_equal_goto(tctx, status,
6445                                            tcase_results->final_status,
6446                                            ret, done,
6447                                            "smb2_create failed\n");
6448         if (NT_STATUS_IS_OK(status)) {
6449                 status = smb2_util_close(tree, h1);
6450                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6451                                                 "smb2_util_close failed\n");
6452         }
6453
6454         /*
6455          * Test: open after close, different client
6456          */
6457
6458         status = torture_smb2_open(tree2, tcase->name,
6459                                    SEC_FILE_READ_DATA, &h1);
6460         torture_assert_ntstatus_equal_goto(tctx, status,
6461                                            tcase_results->final_status,
6462                                            ret, done,
6463                                            "smb2_create failed\n");
6464         if (NT_STATUS_IS_OK(status)) {
6465                 status = smb2_util_close(tree2, h1);
6466                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6467                                                 "smb2_util_close failed\n");
6468         }
6469
6470         /*
6471          * Test: check streams after close, same client
6472          */
6473
6474         ret = check_stream_list_handle(tree, tctx, baseh,
6475                                        tcase_results->num_streams_closed_handle,
6476                                        tcase_results->streams_closed_handle,
6477                                        false);
6478         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
6479
6480         ret = true;
6481
6482 done:
6483         smb2_util_close(tree, streamh);
6484         smb2_util_close(tree, baseh);
6485         return ret;
6486 }
6487
6488 static bool test_empty_stream_do_one(
6489         struct torture_context *tctx,
6490         struct smb2_tree *tree,
6491         struct smb2_tree *tree2,
6492         struct tcase *tcase)
6493 {
6494         bool ret = false;
6495         NTSTATUS status;
6496         struct smb2_handle baseh = {{0}};
6497         struct smb2_handle streamh;
6498         struct smb2_create create;
6499         union smb_setfileinfo sfinfo;
6500         TALLOC_CTX *mem_ctx = talloc_new(tctx);
6501
6502         torture_comment(tctx, "Testing stream [%s]\n", tcase->name);
6503
6504         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new\n");
6505
6506         /*
6507          * Subtest: create
6508          */
6509         torture_comment(tctx, "Subtest: T_CREATE\n");
6510
6511         status = smb2_util_unlink(tree, BASEDIR "\\file");
6512         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6513                                         "smb2_util_unlink failed\n");
6514
6515         status = torture_smb2_testfile_access(tree, BASEDIR "\\file",
6516                                               &baseh, SEC_FILE_ALL);
6517         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6518                                         "torture_smb2_testfile_access failed\n");
6519
6520         status = torture_smb2_testfile_access(tree, tcase->name, &streamh,
6521                                               tcase->access);
6522         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6523                                         "torture_smb2_testfile_access failed\n");
6524
6525         ret = test_empty_stream_do_checks(tctx, tree, tree2, tcase,
6526                                           mem_ctx, baseh, streamh, T_CREATE);
6527         torture_assert_goto(tctx, ret, ret, done, "test failed\n");
6528
6529         if (!(tcase->access & SEC_FILE_WRITE_DATA)) {
6530                 /*
6531                  * All subsequent tests require write access
6532                  */
6533                 ret = true;
6534                 goto done;
6535         }
6536
6537         /*
6538          * Subtest: create and write
6539          */
6540         torture_comment(tctx, "Subtest: T_WRITE\n");
6541
6542         status = smb2_util_unlink(tree, BASEDIR "\\file");
6543         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6544                                         "smb2_util_unlink failed\n");
6545
6546         status = torture_smb2_testfile_access(tree, BASEDIR "\\file",
6547                                               &baseh, SEC_FILE_ALL);
6548         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6549                                         "torture_smb2_testfile_access failed\n");
6550
6551         status = torture_smb2_testfile_access(tree, tcase->name, &streamh,
6552                                               tcase->access);
6553         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6554                                         "torture_smb2_testfile_access failed\n");
6555
6556         status = smb2_util_write(tree, streamh, tcase->write_data, 0,
6557                                  tcase->write_size);
6558         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6559                                         "torture_smb2_open failed\n");
6560
6561         ret = test_empty_stream_do_checks(tctx, tree, tree2, tcase,
6562                                           mem_ctx, baseh, streamh, T_WRITE);
6563         torture_assert_goto(tctx, ret, ret, done, "test failed\n");
6564
6565         /*
6566          * Subtest: overwrite
6567          */
6568         torture_comment(tctx, "Subtest: T_OVERWRITE\n");
6569
6570         status = smb2_util_unlink(tree, BASEDIR "\\file");
6571         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6572                                         "smb2_util_unlink failed\n");
6573
6574         status = torture_smb2_testfile_access(tree, BASEDIR "\\file",
6575                                               &baseh, SEC_FILE_ALL);
6576         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6577                                         "torture_smb2_testfile_access failed\n");
6578
6579         create = (struct smb2_create) {
6580                 .in.desired_access = SEC_FILE_ALL,
6581                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
6582                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
6583                 .in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF,
6584                 .in.fname = tcase->name,
6585         };
6586
6587         status = smb2_create(tree, tctx, &create);
6588         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6589                                         "torture_smb2_testfile failed\n");
6590         streamh = create.out.file.handle;
6591
6592         ret = test_empty_stream_do_checks(tctx, tree, tree2, tcase,
6593                                           mem_ctx, baseh, streamh, T_OVERWRITE);
6594         torture_assert_goto(tctx, ret, ret, done, "test failed\n");
6595
6596         /*
6597          * Subtest: setinfo EOF 0
6598          */
6599         torture_comment(tctx, "Subtest: T_EOF\n");
6600
6601         status = smb2_util_unlink(tree, BASEDIR "\\file");
6602         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6603                                         "smb2_util_unlink failed\n");
6604
6605         status = torture_smb2_testfile_access(tree, BASEDIR "\\file",
6606                                               &baseh, SEC_FILE_ALL);
6607         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6608                                         "torture_smb2_testfile_access failed\n");
6609
6610         status = torture_smb2_testfile_access(tree, tcase->name, &streamh,
6611                                               tcase->access);
6612         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6613                                         "torture_smb2_testfile_access failed\n");
6614
6615         status = smb2_util_write(tree, streamh, tcase->write_data, 0,
6616                                  tcase->write_size);
6617         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6618                                         "torture_smb2_open failed\n");
6619
6620         sfinfo = (union smb_setfileinfo) {
6621                 .end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION,
6622                 .end_of_file_info.in.file.handle = streamh,
6623                 .end_of_file_info.in.size = 0,
6624         };
6625         status = smb2_setinfo_file(tree, &sfinfo);
6626         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6627                                         "set eof 0 failed\n");
6628
6629         ret = test_empty_stream_do_checks(tctx, tree, tree2, tcase,
6630                                           mem_ctx, baseh, streamh, T_EOF);
6631         torture_assert_goto(tctx, ret, ret, done, "test failed\n");
6632
6633         /*
6634          * Subtest: delete-on-close
6635          */
6636         torture_comment(tctx, "Subtest: T_DOC\n");
6637
6638         status = smb2_util_unlink(tree, BASEDIR "\\file");
6639         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6640                                         "smb2_util_unlink failed\n");
6641
6642         status = torture_smb2_testfile_access(tree, BASEDIR "\\file",
6643                                               &baseh, SEC_FILE_ALL);
6644         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6645                                         "torture_smb2_testfile_access failed\n");
6646
6647         status = torture_smb2_testfile_access(tree, tcase->name, &streamh,
6648                                               tcase->access);
6649         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6650                                         "torture_smb2_testfile_access failed\n");
6651
6652         status = smb2_util_write(tree, streamh, tcase->write_data, 0,
6653                                  tcase->write_size);
6654         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6655                                         "torture_smb2_open failed\n");
6656
6657         sfinfo = (union smb_setfileinfo) {
6658                 .disposition_info.level = RAW_SFILEINFO_DISPOSITION_INFORMATION,
6659                 .disposition_info.in.file.handle = streamh,
6660                 .disposition_info.in.delete_on_close = true,
6661         };
6662         status = smb2_setinfo_file(tree, &sfinfo);
6663         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6664                                         "set eof 0 failed\n");
6665
6666         ret = test_empty_stream_do_checks(tctx, tree, tree2, tcase,
6667                                           mem_ctx, baseh, streamh,
6668                                           T_DOC);
6669         torture_assert_goto(tctx, ret, ret, done, "test failed\n");
6670
6671         ret = true;
6672
6673 done:
6674         smb2_util_close(tree, baseh);
6675         TALLOC_FREE(mem_ctx);
6676         return ret;
6677 }
6678
6679 static bool test_empty_stream(struct torture_context *tctx,
6680                               struct smb2_tree *tree)
6681 {
6682         struct smb2_tree *tree2 = NULL;
6683         struct tcase *tcase = NULL;
6684         const char *fname = BASEDIR "\\file";
6685         struct smb2_handle h1;
6686         bool ret = true;
6687         NTSTATUS status;
6688         AfpInfo ai = (AfpInfo) {
6689                 .afpi_Signature = AFP_Signature,
6690                 .afpi_Version = AFP_Version,
6691                 .afpi_BackupTime = AFP_BackupTime,
6692                 .afpi_FinderInfo = "FOO BAR ",
6693         };
6694         char *ai_blob = torture_afpinfo_pack(tctx, &ai);
6695         struct tcase tcase_afpinfo_ro = (struct tcase) {
6696                 .name = BASEDIR "\\file" AFPINFO_STREAM,
6697                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE,
6698                 .create = {
6699                         .size = 60,
6700                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6701                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6702                         .num_streams_open_handle = 1,
6703                         .num_streams_closed_handle = 1,
6704                         .streams_open_handle = {"::$DATA"},
6705                         .streams_closed_handle = {"::$DATA"},
6706                 },
6707         };
6708         struct tcase tcase_afpinfo_rw = (struct tcase) {
6709                 .name = BASEDIR "\\file" AFPINFO_STREAM,
6710                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_DATA|SEC_STD_DELETE,
6711                 .write_data = ai_blob,
6712                 .write_size = AFP_INFO_SIZE,
6713                 .create = {
6714                         .size = 60,
6715                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6716                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6717                         .num_streams_open_handle = 1,
6718                         .num_streams_closed_handle = 1,
6719                         .streams_open_handle = {"::$DATA"},
6720                         .streams_closed_handle = {"::$DATA"},
6721                 },
6722                 .write = {
6723                         .size = 60,
6724                         .initial_status = NT_STATUS_OK,
6725                         .final_status = NT_STATUS_OK,
6726                         .num_streams_open_handle = 2,
6727                         .num_streams_closed_handle = 2,
6728                         .streams_open_handle = {"::$DATA", AFPINFO_STREAM},
6729                         .streams_closed_handle = {"::$DATA", AFPINFO_STREAM},
6730                 },
6731                 .overwrite = {
6732                         .size = 60,
6733                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6734                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6735                         .num_streams_open_handle = 1,
6736                         .num_streams_closed_handle = 1,
6737                         .streams_open_handle = {"::$DATA"},
6738                         .streams_closed_handle = {"::$DATA"},
6739                 },
6740                 .eof = {
6741                         .size = 60,
6742                         .initial_status = NT_STATUS_OK,
6743                         .final_status = NT_STATUS_OK,
6744                         .num_streams_open_handle = 2,
6745                         .num_streams_closed_handle = 2,
6746                         .streams_open_handle = {"::$DATA", AFPINFO_STREAM},
6747                         .streams_closed_handle = {"::$DATA", AFPINFO_STREAM},
6748                 },
6749                 .doc = {
6750                         .size = 60,
6751                         .initial_status = NT_STATUS_DELETE_PENDING,
6752                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6753                         .num_streams_open_handle = 2,
6754                         .num_streams_closed_handle = 1,
6755                         .streams_open_handle = {"::$DATA", AFPINFO_STREAM},
6756                         .streams_closed_handle = {"::$DATA"},
6757                 },
6758         };
6759
6760         struct tcase tcase_afpresource_ro = (struct tcase) {
6761                 .name = BASEDIR "\\file" AFPRESOURCE_STREAM,
6762                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE,
6763                 .create = {
6764                         .size = 0,
6765                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6766                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6767                         .num_streams_open_handle = 1,
6768                         .num_streams_closed_handle = 1,
6769                         .streams_open_handle = {"::$DATA"},
6770                         .streams_closed_handle = {"::$DATA"},
6771                 },
6772         };
6773         struct tcase tcase_afpresource_rw = (struct tcase) {
6774                 .name = BASEDIR "\\file" AFPRESOURCE_STREAM,
6775                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_DATA|SEC_STD_DELETE,
6776                 .write_data = "foo",
6777                 .write_size = 3,
6778                 .create = {
6779                         .size = 0,
6780                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6781                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6782                         .num_streams_open_handle = 1,
6783                         .num_streams_closed_handle = 1,
6784                         .streams_open_handle = {"::$DATA"},
6785                         .streams_closed_handle = {"::$DATA"},
6786                 },
6787                 .write = {
6788                         .size = 3,
6789                         .initial_status = NT_STATUS_OK,
6790                         .final_status = NT_STATUS_OK,
6791                         .num_streams_open_handle = 2,
6792                         .num_streams_closed_handle = 2,
6793                         .streams_open_handle = {"::$DATA", AFPRESOURCE_STREAM},
6794                         .streams_closed_handle = {"::$DATA", AFPRESOURCE_STREAM},
6795                 },
6796                 .overwrite = {
6797                         .size = 0,
6798                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6799                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6800                         .num_streams_open_handle = 1,
6801                         .num_streams_closed_handle = 1,
6802                         .streams_open_handle = {"::$DATA"},
6803                         .streams_closed_handle = {"::$DATA"},
6804                 },
6805                 .eof = {
6806                         .size = 0,
6807                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6808                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6809                         .num_streams_open_handle = 1,
6810                         .num_streams_closed_handle = 1,
6811                         .streams_open_handle = {"::$DATA"},
6812                         .streams_closed_handle = {"::$DATA"},
6813                 },
6814                 .doc = {
6815                         .size = 3,
6816                         .initial_status = NT_STATUS_DELETE_PENDING,
6817                         .final_status = NT_STATUS_OK,
6818                         .num_streams_open_handle = 2,
6819                         .num_streams_closed_handle = 2,
6820                         .streams_open_handle = {"::$DATA", AFPRESOURCE_STREAM},
6821                         .streams_closed_handle = {"::$DATA", AFPRESOURCE_STREAM},
6822                 },
6823         };
6824
6825         struct tcase tcase_foo_ro = (struct tcase) {
6826                 .name = BASEDIR "\\file:foo",
6827                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE,
6828                 .write_data = "foo",
6829                 .write_size = 3,
6830                 .create = {
6831                         .size = 0,
6832                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6833                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6834                         .num_streams_open_handle = 1,
6835                         .num_streams_closed_handle = 1,
6836                         .streams_open_handle = {"::$DATA"},
6837                         .streams_closed_handle = {"::$DATA"},
6838                 },
6839         };
6840
6841         struct tcase tcase_foo_rw = (struct tcase) {
6842                 .name = BASEDIR "\\file:foo",
6843                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_DATA|SEC_STD_DELETE,
6844                 .write_data = "foo",
6845                 .write_size = 3,
6846                 .create = {
6847                         .size = 0,
6848                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6849                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6850                         .num_streams_open_handle = 1,
6851                         .num_streams_closed_handle = 1,
6852                         .streams_open_handle = {"::$DATA"},
6853                         .streams_closed_handle = {"::$DATA"},
6854                 },
6855                 .write = {
6856                         .size = 3,
6857                         .initial_status = NT_STATUS_OK,
6858                         .final_status = NT_STATUS_OK,
6859                         .num_streams_open_handle = 2,
6860                         .num_streams_closed_handle = 2,
6861                         .streams_open_handle = {"::$DATA", ":foo:$DATA"},
6862                         .streams_closed_handle = {"::$DATA", ":foo:$DATA"},
6863                 },
6864                 .overwrite = {
6865                         .size = 0,
6866                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6867                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6868                         .num_streams_open_handle = 1,
6869                         .num_streams_closed_handle = 1,
6870                         .streams_open_handle = {"::$DATA"},
6871                         .streams_closed_handle = {"::$DATA"},
6872                 },
6873                 .eof = {
6874                         .size = 0,
6875                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6876                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6877                         .num_streams_open_handle = 1,
6878                         .num_streams_closed_handle = 1,
6879                         .streams_open_handle = {"::$DATA"},
6880                         .streams_closed_handle = {"::$DATA"},
6881                 },
6882                 .doc = {
6883                         .size = 3,
6884                         .initial_status = NT_STATUS_DELETE_PENDING,
6885                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
6886                         .num_streams_open_handle = 2,
6887                         .num_streams_closed_handle = 1,
6888                         .streams_open_handle = {"::$DATA", ":foo:$DATA"},
6889                         .streams_closed_handle = {"::$DATA"},
6890                 },
6891         };
6892
6893         struct tcase tcases[] = {
6894                 tcase_afpinfo_ro,
6895                 tcase_afpinfo_rw,
6896                 tcase_afpresource_ro,
6897                 tcase_afpresource_rw,
6898                 tcase_foo_ro,
6899                 tcase_foo_rw,
6900                 {NULL}
6901         };
6902
6903         ret = torture_smb2_connection(tctx, &tree2);
6904         torture_assert_goto(tctx, ret == true, ret, done,
6905                             "torture_smb2_connection failed\n");
6906
6907         ret = enable_aapl(tctx, tree);
6908         torture_assert(tctx, ret == true, "enable_aapl failed\n");
6909
6910         ret = enable_aapl(tctx, tree2);
6911         torture_assert(tctx, ret == true, "enable_aapl failed\n");
6912
6913         smb2_deltree(tree, BASEDIR);
6914
6915         status = torture_smb2_testdir(tree, BASEDIR, &h1);
6916         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6917                                         "torture_smb2_testdir\n");
6918         smb2_util_close(tree, h1);
6919
6920         for (tcase = &tcases[0]; tcase->name != NULL; tcase++) {
6921                 ret = torture_setup_file(tctx, tree, fname, false);
6922                 torture_assert_goto(tctx, ret == true, ret, done,
6923                                     "torture_setup_file failed\n");
6924
6925                 ret = test_empty_stream_do_one(tctx, tree, tree2, tcase);
6926                 torture_assert_goto(tctx, ret == true, ret, done,
6927                                     "subtest failed\n");
6928
6929                 status = smb2_util_unlink(tree, fname);
6930                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
6931                                                 "smb2_util_unlink failed\n");
6932         }
6933
6934 done:
6935         smb2_deltree(tree, BASEDIR);
6936         TALLOC_FREE(tree2);
6937         return ret;
6938 }
6939
6940 /*
6941  * Note: This test depends on "vfs objects = catia fruit streams_xattr".  For
6942  * some tests torture must be run on the host it tests and takes an additional
6943  * argument with the local path to the share:
6944  * "--option=torture:localdir=<SHAREPATH>".
6945  *
6946  * When running against an OS X SMB server add "--option=torture:osx=true"
6947  */
6948 struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
6949 {
6950         struct torture_suite *suite = torture_suite_create(
6951                 ctx, "fruit");
6952
6953         suite->description = talloc_strdup(suite, "vfs_fruit tests");
6954
6955         torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
6956         torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
6957         torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
6958         torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
6959         torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
6960         torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
6961         torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
6962         torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
6963         torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
6964         torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
6965         torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
6966         torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
6967         torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
6968         torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
6969         torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
6970         torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
6971         torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
6972         torture_suite_add_1smb2_test(suite, "setinfo eof stream", test_setinfo_stream_eof);
6973         torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
6974         torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
6975         torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
6976         torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
6977         torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
6978         torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
6979         torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
6980         torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
6981         torture_suite_add_1smb2_test(suite, "NFS ACE entries", test_nfs_aces);
6982         torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion without embedded xattr", test_adouble_conversion_wo_xattr);
6983         torture_suite_add_1smb2_test(suite, "empty_stream", test_empty_stream);
6984         torture_suite_add_1smb2_test(suite, "writing_afpinfo", test_writing_afpinfo);
6985
6986         return suite;
6987 }
6988
6989 static bool test_stream_names_local(struct torture_context *tctx,
6990                                     struct smb2_tree *tree)
6991 {
6992         TALLOC_CTX *mem_ctx = talloc_new(tctx);
6993         NTSTATUS status;
6994         struct smb2_create create;
6995         struct smb2_handle h;
6996         const char *fname = BASEDIR "\\stream_names.txt";
6997         const char *sname1;
6998         bool ret;
6999         /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
7000         const char *streams[] = {
7001                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
7002                 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
7003                 "::$DATA"
7004         };
7005         const char *localdir = NULL;
7006
7007         localdir = torture_setting_string(tctx, "localdir", NULL);
7008         if (localdir == NULL) {
7009                 torture_skip(tctx, "Need localdir for test");
7010         }
7011
7012         sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
7013
7014         /* clean slate ...*/
7015         smb2_util_unlink(tree, fname);
7016         smb2_deltree(tree, fname);
7017         smb2_deltree(tree, BASEDIR);
7018
7019         status = torture_smb2_testdir(tree, BASEDIR, &h);
7020         CHECK_STATUS(status, NT_STATUS_OK);
7021         smb2_util_close(tree, h);
7022
7023         torture_comment(tctx, "(%s) testing stream names\n", __location__);
7024         ZERO_STRUCT(create);
7025         create.in.desired_access = SEC_FILE_WRITE_DATA;
7026         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
7027         create.in.share_access =
7028                 NTCREATEX_SHARE_ACCESS_DELETE|
7029                 NTCREATEX_SHARE_ACCESS_READ|
7030                 NTCREATEX_SHARE_ACCESS_WRITE;
7031         create.in.create_disposition = NTCREATEX_DISP_CREATE;
7032         create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
7033         create.in.fname = sname1;
7034
7035         status = smb2_create(tree, mem_ctx, &create);
7036         CHECK_STATUS(status, NT_STATUS_OK);
7037
7038         status = smb2_util_write(tree, create.out.file.handle, "foo", 0, 3);
7039         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
7040                                         "smb2_util_write failed\n");
7041
7042         smb2_util_close(tree, create.out.file.handle);
7043
7044         ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
7045                                         "user.DosStream.bar:baz:$DATA",
7046                                         "data", strlen("data"));
7047         CHECK_VALUE(ret, true);
7048
7049         ret = check_stream_list(tree, tctx, fname, 3, streams, false);
7050         CHECK_VALUE(ret, true);
7051
7052 done:
7053         status = smb2_util_unlink(tree, fname);
7054         smb2_deltree(tree, BASEDIR);
7055         talloc_free(mem_ctx);
7056
7057         return ret;
7058 }
7059
7060 static bool test_fruit_locking_conflict(struct torture_context *tctx,
7061                                         struct smb2_tree *tree,
7062                                         struct smb2_tree *tree2)
7063 {
7064         TALLOC_CTX *mem_ctx;
7065         struct smb2_create create;
7066         struct smb2_handle h;
7067         struct smb2_lock lck;
7068         struct smb2_lock_element el;
7069         const char *fname = BASEDIR "\\locking_conflict.txt";
7070         NTSTATUS status;
7071         bool ret = false;
7072
7073         mem_ctx = talloc_new(tctx);
7074         torture_assert_not_null(tctx, mem_ctx, "talloc_new failed");
7075
7076         /* clean slate ...*/
7077         smb2_util_unlink(tree, fname);
7078         smb2_deltree(tree, fname);
7079         smb2_deltree(tree, BASEDIR);
7080
7081         status = torture_smb2_testdir(tree, BASEDIR, &h);
7082         CHECK_STATUS(status, NT_STATUS_OK);
7083         smb2_util_close(tree, h);
7084
7085         create = (struct smb2_create) {
7086                 .in.desired_access = SEC_RIGHTS_FILE_READ,
7087                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
7088                 .in.share_access =
7089                 NTCREATEX_SHARE_ACCESS_READ|
7090                 NTCREATEX_SHARE_ACCESS_WRITE,
7091                 .in.create_disposition = NTCREATEX_DISP_CREATE,
7092                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
7093                 .in.fname = fname,
7094         };
7095
7096         status = smb2_create(tree, mem_ctx, &create);
7097         CHECK_STATUS(status, NT_STATUS_OK);
7098         h = create.out.file.handle;
7099
7100         /* Add AD_FILELOCK_RSRC_DENY_WR lock. */
7101         el = (struct smb2_lock_element) {
7102                 .offset = 0xfffffffffffffffc,
7103                 .length = 1,
7104                 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
7105         };
7106         lck = (struct smb2_lock) {
7107                 .in.lock_count = 1,
7108                 .in.file.handle = h,
7109                 .in.locks = &el,
7110         };
7111
7112         /*
7113          * Lock up to and including:
7114          * AD_FILELOCK_OPEN_WR
7115          * AD_FILELOCK_OPEN_RD
7116          * This is designed to cause a NetAtalk
7117          * locking conflict on the next open,
7118          * even though the share modes are
7119          * compatible.
7120          */
7121         status = smb2_lock(tree, &lck);
7122         CHECK_STATUS(status, NT_STATUS_OK);
7123
7124         el = (struct smb2_lock_element) {
7125                 .offset = 0,
7126                 .length = 0x7ffffffffffffff7,
7127                 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
7128         };
7129         status = smb2_lock(tree, &lck);
7130         CHECK_STATUS(status, NT_STATUS_OK);
7131
7132         create = (struct smb2_create) {
7133                 .in.desired_access =
7134                 SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
7135                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
7136                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
7137                 .in.create_disposition = NTCREATEX_DISP_OPEN,
7138                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
7139                 .in.fname = fname,
7140         };
7141
7142         /*
7143          * Open on the second tree - ensure we are
7144          * emulating trying to access with a NetATalk
7145          * process with an existing open/deny mode.
7146          */
7147         status = smb2_create(tree2, mem_ctx, &create);
7148         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
7149
7150         {
7151                 struct smb2_close cl = {
7152                         .level = RAW_CLOSE_SMB2,
7153                         .in.file.handle = h,
7154                 };
7155                 smb2_close(tree, &cl);
7156         }
7157
7158         ret = true;
7159 done:
7160         return ret;
7161 }
7162
7163 struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
7164 {
7165         struct torture_suite *suite = torture_suite_create(
7166                 ctx, "fruit_netatalk");
7167
7168         suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
7169
7170         torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
7171         torture_suite_add_1smb2_test(suite, "stream names with locally created xattr", test_stream_names_local);
7172         torture_suite_add_2smb2_test(
7173                 suite, "locking conflict", test_fruit_locking_conflict);
7174
7175         return suite;
7176 }
7177
7178 struct torture_suite *torture_vfs_fruit_file_id(TALLOC_CTX *ctx)
7179 {
7180         struct torture_suite *suite =
7181             torture_suite_create(ctx, "fruit_file_id");
7182
7183         suite->description =
7184             talloc_strdup(suite, "vfs_fruit tests for on-disk file ID that "
7185                                  "require fruit:zero_file_id=yes");
7186
7187         torture_suite_add_1smb2_test(suite, "zero file id if AAPL negotiated",
7188                                      test_zero_file_id);
7189
7190         return suite;
7191 }
7192
7193 static bool test_timemachine_volsize(struct torture_context *tctx,
7194                                      struct smb2_tree *tree)
7195 {
7196         TALLOC_CTX *mem_ctx = talloc_new(tctx);
7197         struct smb2_handle h = {{0}};
7198         union smb_fsinfo fsinfo;
7199         NTSTATUS status;
7200         bool ok = true;
7201         const char *info_plist =
7202                 "<dict>\n"
7203                 "        <key>band-size</key>\n"
7204                 "        <integer>8192</integer>\n"
7205                 "</dict>\n";
7206
7207         smb2_deltree(tree, "test.sparsebundle");
7208
7209         ok = enable_aapl(tctx, tree);
7210         torture_assert_goto(tctx, ok, ok, done, "enable_aapl failed");
7211
7212         status = smb2_util_mkdir(tree, "test.sparsebundle");
7213         torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
7214                                         "smb2_util_mkdir\n");
7215
7216         ok = write_stream(tree, __location__, tctx, mem_ctx,
7217                           "test.sparsebundle/Info.plist", NULL,
7218                            0, strlen(info_plist), info_plist);
7219         torture_assert_goto(tctx, ok, ok, done, "write_stream failed\n");
7220
7221         status = smb2_util_mkdir(tree, "test.sparsebundle/bands");
7222         torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
7223                                         "smb2_util_mkdir\n");
7224
7225         ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/1", false);
7226         torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
7227
7228         ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/2", false);
7229         torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
7230
7231         status = smb2_util_roothandle(tree, &h);
7232         torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
7233
7234         ZERO_STRUCT(fsinfo);
7235         fsinfo.generic.level = RAW_QFS_SIZE_INFORMATION;
7236         fsinfo.generic.handle = h;
7237
7238         status = smb2_getinfo_fs(tree, tree, &fsinfo);
7239         torture_assert_ntstatus_ok(tctx, status, "smb2_getinfo_fs failed");
7240
7241         torture_comment(tctx, "sectors_per_unit: %" PRIu32"\n"
7242                         "bytes_per_sector: %" PRIu32"\n"
7243                         "total_alloc_units: %" PRIu64"\n"
7244                         "avail_alloc_units: %" PRIu64"\n",
7245                         fsinfo.size_info.out.sectors_per_unit,
7246                         fsinfo.size_info.out.bytes_per_sector,
7247                         fsinfo.size_info.out.total_alloc_units,
7248                         fsinfo.size_info.out.avail_alloc_units);
7249
7250         /*
7251          * Let me explain the numbers:
7252          *
7253          * - the share is set to "fruit:time machine max size = 32K"
7254          * - we've faked a bandsize of 8 K in the Info.plist file
7255          * - we've created two bands files
7256          * - one allocation unit is made of two sectors with 512 B each
7257          * => we've consumed 16 allocation units, there should be 16 free
7258          */
7259
7260         torture_assert_goto(tctx, fsinfo.size_info.out.sectors_per_unit == 2,
7261                             ok, done, "Bad sectors_per_unit");
7262
7263         torture_assert_goto(tctx, fsinfo.size_info.out.bytes_per_sector == 512,
7264                             ok, done, "Bad bytes_per_sector");
7265
7266         torture_assert_goto(tctx, fsinfo.size_info.out.total_alloc_units == 32,
7267                             ok, done, "Bad total_alloc_units");
7268
7269         torture_assert_goto(tctx, fsinfo.size_info.out.avail_alloc_units == 16,
7270                             ok, done, "Bad avail_alloc_units");
7271
7272 done:
7273         if (!smb2_util_handle_empty(h)) {
7274                 smb2_util_close(tree, h);
7275         }
7276         smb2_deltree(tree, "test.sparsebundle");
7277         talloc_free(mem_ctx);
7278         return ok;
7279 }
7280
7281 struct torture_suite *torture_vfs_fruit_timemachine(TALLOC_CTX *ctx)
7282 {
7283         struct torture_suite *suite = torture_suite_create(
7284                 ctx, "fruit_timemachine");
7285
7286         suite->description = talloc_strdup(
7287                 suite, "vfs_fruit tests for TimeMachine");
7288
7289         torture_suite_add_1smb2_test(suite, "Timemachine-volsize",
7290                                      test_timemachine_volsize);
7291
7292         return suite;
7293 }
7294
7295 static bool test_convert_xattr_and_empty_rfork_then_delete(
7296         struct torture_context *tctx,
7297         struct smb2_tree *tree1,
7298         struct smb2_tree *tree2)
7299 {
7300         TALLOC_CTX *mem_ctx = talloc_new(tctx);
7301         const char *fname = BASEDIR "\\test_adouble_conversion";
7302         const char *adname = BASEDIR "/._test_adouble_conversion";
7303         const char *rfork = BASEDIR "\\test_adouble_conversion" AFPRESOURCE_STREAM_NAME;
7304         NTSTATUS status;
7305         struct smb2_handle testdirh;
7306         bool ret = true;
7307         const char *streams[] = {
7308                 "::$DATA",
7309                 AFPINFO_STREAM,
7310                 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
7311                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
7312         };
7313         struct smb2_create create;
7314         struct smb2_find find;
7315         unsigned int count;
7316         union smb_search_data *d;
7317         bool delete_empty_adfiles;
7318         int expected_num_files;
7319
7320         delete_empty_adfiles = torture_setting_bool(tctx,
7321                                                     "delete_empty_adfiles",
7322                                                     false);
7323
7324         smb2_deltree(tree1, BASEDIR);
7325
7326         status = torture_smb2_testdir(tree1, BASEDIR, &testdirh);
7327         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
7328                                         "torture_smb2_testdir failed\n");
7329         smb2_util_close(tree1, testdirh);
7330
7331         ret = torture_setup_file(tctx, tree1, fname, false);
7332         torture_assert_goto(tctx, ret == true, ret, done,
7333                             "torture_setup_file failed\n");
7334
7335         ret = torture_setup_file(tctx, tree1, adname, false);
7336         torture_assert_goto(tctx, ret == true, ret, done,
7337                             "torture_setup_file failed\n");
7338
7339         ret = write_stream(tree1, __location__, tctx, mem_ctx,
7340                            adname, NULL,
7341                            0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
7342         torture_assert_goto(tctx, ret == true, ret, done,
7343                             "write_stream failed\n");
7344
7345         ret = enable_aapl(tctx, tree2);
7346         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
7347
7348         /*
7349          * Issue a smb2_find(), this triggers the server-side conversion
7350          */
7351
7352         create = (struct smb2_create) {
7353                 .in.desired_access = SEC_RIGHTS_DIR_READ,
7354                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
7355                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
7356                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
7357                 .in.create_disposition = NTCREATEX_DISP_OPEN,
7358                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
7359                 .in.fname = BASEDIR,
7360         };
7361
7362         status = smb2_create(tree2, tctx, &create);
7363         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
7364                                         "smb2_create failed\n");
7365
7366         find = (struct smb2_find) {
7367                 .in.file.handle = create.out.file.handle,
7368                 .in.pattern = "*",
7369                 .in.max_response_size = 0x1000,
7370                 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
7371         };
7372
7373         status = smb2_find_level(tree2, tree2, &find, &count, &d);
7374         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
7375                                         "smb2_find_level failed\n");
7376
7377         status = smb2_util_close(tree2, create.out.file.handle);
7378         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
7379                                         "smb2_util_close failed");
7380
7381         /*
7382          * Check number of streams
7383          */
7384
7385         ret = check_stream_list(tree2, tctx, fname, 4, streams, false);
7386         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
7387
7388         /*
7389          * Check Resource Fork is gone
7390          */
7391
7392         create = (struct smb2_create) {
7393                 .in.desired_access = SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
7394                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
7395                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
7396                 .in.create_disposition = NTCREATEX_DISP_OPEN,
7397                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
7398                 .in.fname = rfork,
7399         };
7400
7401         status = smb2_create(tree2, mem_ctx, &create);
7402         torture_assert_ntstatus_equal_goto(
7403                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
7404                 ret, done, "Bad smb2_create return\n");
7405
7406         /*
7407          * Check xattr data has been migrated from the AppleDouble file to
7408          * streams.
7409          */
7410
7411         ret = check_stream(tree2, __location__, tctx, mem_ctx,
7412                            fname, AFPINFO_STREAM,
7413                            0, 60, 16, 8, "TESTSLOW");
7414         torture_assert_goto(tctx, ret == true, ret, done,
7415                             "check AFPINFO_STREAM failed\n");
7416
7417         ret = check_stream(tree2, __location__, tctx, mem_ctx,
7418                            fname, ":foo" "\xef\x80\xa2" "bar", /* foo:bar */
7419                            0, 3, 0, 3, "baz");
7420         torture_assert_goto(tctx, ret == true, ret, done,
7421                             "check foo stream failed\n");
7422
7423         /*
7424          * Now check number of files. If delete_empty_adfiles is set, the
7425          * AppleDouble files should have been deleted.
7426          */
7427
7428         create = (struct smb2_create) {
7429                 .in.desired_access = SEC_RIGHTS_DIR_READ,
7430                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
7431                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
7432                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
7433                 .in.create_disposition = NTCREATEX_DISP_OPEN,
7434                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
7435                 .in.fname = BASEDIR,
7436         };
7437
7438         status = smb2_create(tree2, tctx, &create);
7439         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
7440                                         "smb2_create failed\n");
7441
7442         find = (struct smb2_find) {
7443                 .in.file.handle = create.out.file.handle,
7444                 .in.pattern = "*",
7445                 .in.max_response_size = 0x1000,
7446                 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
7447         };
7448
7449         status = smb2_find_level(tree2, tree2, &find, &count, &d);
7450         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
7451                                         "smb2_find_level failed\n");
7452
7453         status = smb2_util_close(tree2, create.out.file.handle);
7454         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
7455                                         "smb2_util_close failed");
7456
7457         if (delete_empty_adfiles) {
7458                 expected_num_files = 3;
7459         } else {
7460                 expected_num_files = 4;
7461         }
7462         torture_assert_int_equal_goto(tctx, count, expected_num_files, ret, done,
7463                                       "Wrong number of files\n");
7464
7465 done:
7466         smb2_deltree(tree1, BASEDIR);
7467         talloc_free(mem_ctx);
7468         return ret;
7469 }
7470
7471 struct torture_suite *torture_vfs_fruit_conversion(TALLOC_CTX *ctx)
7472 {
7473         struct torture_suite *suite = torture_suite_create(
7474                 ctx, "fruit_conversion");
7475
7476         suite->description = talloc_strdup(
7477                 suite, "vfs_fruit conversion tests");
7478
7479         torture_suite_add_2ns_smb2_test(
7480                 suite, "convert_xattr_and_empty_rfork_then_delete",
7481                 test_convert_xattr_and_empty_rfork_then_delete);
7482
7483         return suite;
7484 }
7485
7486 /*
7487  * The buf below contains the following AppleDouble encoded data:
7488  *
7489  * -----------------------------------------------------------------------------
7490  * MagicNumber: 00051607                                        : AppleDouble
7491  * Version    : 00020000                                        : Version 2
7492  * Filler     : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
7493  * Num. of ent: 0002                                            : 2
7494  *
7495  * -----------------------------------------------------------------------------
7496  * Entry ID   : 00000002 : Resource Fork
7497  * Offset     : 0000009A : 154
7498  * Length     : 00000004 : 4
7499  *
7500  * -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
7501  * 00000000   : 62 61 72 00                                     : bar.
7502  *
7503  * -----------------------------------------------------------------------------
7504  * Entry ID   : 00000009 : Finder Info
7505  * Offset     : 00000032 : 50
7506  * Length     : 00000068 : 104
7507  *
7508  * -FInfo-----:
7509  * Type       : 464F4F20 : FOO
7510  * Creator    : 42415220 : BAR
7511  * isAlias    : 0
7512  * Invisible  : 0
7513  * hasBundle  : 0
7514  * nameLocked : 0
7515  * Stationery : 0
7516  * CustomIcon : 0
7517  * Reserved   : 0
7518  * Inited     : 0
7519  * NoINITS    : 0
7520  * Shared     : 0
7521  * SwitchLaunc: 0
7522  * Hidden Ext : 0
7523  * color      : 000      : none
7524  * isOnDesk   : 0
7525  * Location v : 0000     : 0
7526  * Location h : 0000     : 0
7527  * Fldr       : 0000     : ..
7528  *
7529  * -FXInfo----:
7530  * Rsvd|IconID: 0000     : 0
7531  * Rsvd       : 0000     : ..
7532  * Rsvd       : 0000     : ..
7533  * Rsvd       : 0000     : ..
7534  * AreInvalid : 0
7535  * unknown bit: 0
7536  * unknown bit: 0
7537  * unknown bit: 0
7538  * unknown bit: 0
7539  * unknown bit: 0
7540  * unknown bit: 0
7541  * CustomBadge: 0
7542  * ObjctIsBusy: 0
7543  * unknown bit: 0
7544  * unknown bit: 0
7545  * unknown bit: 0
7546  * unknown bit: 0
7547  * RoutingInfo: 0
7548  * unknown bit: 0
7549  * unknown bit: 0
7550  * Rsvd|commnt: 0000     : 0
7551  * PutAway    : 00000000 : 0
7552  *
7553  * -EA--------:
7554  * pad        : 0000     :
7555  * magic      : 41545452 : ATTR
7556  * debug_tag  : 00000000 : 0
7557  * total_size : 0000009A : 154
7558  * data_start : 00000096 : 150
7559  * data_length: 00000004 : 4
7560  * reserved[0]: 00000000 : ....
7561  * reserved[1]: 00000000 : ....
7562  * reserved[2]: 00000000 : ....
7563  * flags      : 0000     : ..
7564  * num_attrs  : 0001     : 1
7565  * -EA ENTRY--:
7566  * offset     : 00000096 : 150
7567  * length     : 00000004 : 4
7568  * flags      : 0000     : ..
7569  * namelen    : 13       : 19
7570  * -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
7571  * 00000000   : 6F 72 67 2E 73 61 6D 62 61 EF 80 A2 77 6F 6F 68 : org.samba...wooh
7572  * 00000010   : 6F 6F 00                                        : oo.
7573  * -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
7574  * 00000000   : 62 61 72 00                                     : bar.
7575  *
7576  * -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
7577  * 00000000   : 46 4F 4F 20 42 41 52 20 00 00 00 00 00 00 00 00 : FOO BAR ........
7578  * 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
7579  * 00000020   : 00 00 41 54 54 52 00 00 00 00 00 00 00 9A 00 00 : baATTR..........
7580  * 00000030   : 00 96 00 00 00 04 00 00 00 00 00 00 00 00 00 00 : ................
7581  * 00000040   : 00 00 00 00 00 01 00 00 00 96 00 00 00 04 00 00 : ................
7582  * 00000050   : 13 6F 72 67 2E 73 61 6D 62 61 EF 80 A2 77 6F 6F : .org.samba...woo
7583  * 00000060   : 68 6F 6F 00 62 61 72 00                         : hoo.bar.
7584  *
7585  * It was created with:
7586  *
7587  * $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
7588  */
7589 static char unconvert_adfile_data[] = {
7590         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
7591         0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
7592         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
7593         0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
7594         0x00, 0x98, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
7595         0x00, 0x09, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00,
7596         0x00, 0x66, 0x46, 0x4f, 0x4f, 0x20, 0x42, 0x41,
7597         0x52, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7598         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7599         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7600         0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
7601         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
7602         0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x04,
7603         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7604         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
7605         0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x04,
7606         0x00, 0x00, 0x11, 0x6f, 0x72, 0x67, 0x2e, 0x73,
7607         0x61, 0x6d, 0x62, 0x61, 0x3a, 0x77, 0x6f, 0x6f,
7608         0x68, 0x6f, 0x6f, 0x00, 0x62, 0x61, 0x72, 0x00,
7609         0x62, 0x61, 0x72, 0x00
7610 };
7611
7612 static bool test_unconvert(struct torture_context *tctx,
7613                            struct smb2_tree *tree1,
7614                            struct smb2_tree *tree2)
7615 {
7616         const char *fname = BASEDIR "\\unconvert";
7617         const char *adname = BASEDIR "\\._unconvert";
7618         const char *net = NULL;
7619         const char *share = NULL;
7620         AfpInfo *afpi = NULL;
7621         char *cmd = NULL;
7622         struct smb2_handle h1;
7623         union smb_fileinfo finfo;
7624         size_t adsize;
7625         NTSTATUS status;
7626         int result;
7627         bool ret = true;
7628
7629         torture_assert_not_null_goto(tctx, tree2, ret, done,
7630                                      "Need a second share without fruit\n");
7631
7632         net = torture_setting_string(tctx, "net", NULL);
7633         torture_assert_not_null_goto(tctx, net, ret, done,
7634                                      "Need path to 'net'");
7635
7636         share = torture_setting_string(tctx, "sharename", NULL);
7637         torture_assert_not_null_goto(tctx, share, ret, done,
7638                                      "Need sharename");
7639
7640         torture_comment(tctx, "Testing unconvert\n");
7641
7642         smb2_deltree(tree1, BASEDIR);
7643
7644         status = torture_smb2_testdir(tree1, BASEDIR, &h1);
7645         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
7646                                         "torture_smb2_testdir\n");
7647         smb2_util_close(tree1, h1);
7648
7649         ret = torture_setup_file(tctx, tree1, fname, false);
7650         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
7651
7652         afpi = torture_afpinfo_new(tctx);
7653         torture_assert_not_null_goto(tctx, afpi, ret, done,
7654                                      "torture_afpinfo_new failed\n");
7655
7656         memcpy(afpi->afpi_FinderInfo, "FOO BAR ", 8);
7657
7658         ret = torture_write_afpinfo(tree1, tctx, tctx, fname, afpi);
7659         torture_assert_goto(tctx, ret == true, ret, done,
7660                             "torture_write_afpinfo failed\n");
7661
7662         ret = write_stream(tree1, __location__, tctx, tctx,
7663                            fname,
7664                            /*
7665                             * \xef\x80\xa2 is ':' mapped to Unicoe private range
7666                             */
7667                            ":org.samba" "\xef\x80\xa2" "woohoo",
7668                            0, 4, "bar");
7669         torture_assert_goto(tctx, ret == true, ret, done,
7670                             "write_stream failed\n");
7671
7672         ret = write_stream(tree1, __location__, tctx, tctx,
7673                            fname, AFPRESOURCE_STREAM_NAME,
7674                            0, 4, "bar");
7675         torture_assert_goto(tctx, ret == true, ret, done,
7676                             "write_stream failed\n");
7677
7678         cmd = talloc_asprintf(tctx,
7679                               "%s --recursive vfs stream2adouble %s %s/",
7680                               net,
7681                               share,
7682                               BASEDIR);
7683         torture_assert_not_null_goto(tctx, cmd, ret, done,
7684                                      "talloc_asprintf failed\n");
7685
7686         torture_comment(tctx, "cmd: %s\n", cmd);
7687
7688         result = system(cmd);
7689         torture_assert_int_equal_goto(tctx, result, 0, ret, done,
7690                             "command failed\n");
7691
7692         status = torture_smb2_testfile(tree2, adname, &h1);
7693         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
7694                                         "torture_smb2_testfile failed\n");
7695
7696         finfo = (union smb_fileinfo) {
7697                 .generic.level = RAW_FILEINFO_ALL_INFORMATION,
7698                 .generic.in.file.handle = h1,
7699         };
7700
7701         status = smb2_getinfo_file(tree2, tctx, &finfo);
7702         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
7703                                         "torture_smb2_testdir\n");
7704         smb2_util_close(tree2, h1);
7705
7706         adsize = finfo.all_info.out.size;
7707         torture_assert_int_equal_goto(tctx, adsize,
7708                                       sizeof(unconvert_adfile_data),
7709                                       ret, done, "wrong size\n");
7710
7711         ret = check_stream(tree2, __location__, tctx, tctx,
7712                            adname, "", 0, adsize, 0, adsize,
7713                            unconvert_adfile_data);
7714         torture_assert_goto(tctx, ret == true, ret, done,
7715                             "check_stream failed\n");
7716
7717 done:
7718 //      smb2_deltree(tree1, BASEDIR);
7719         return ret;
7720 }
7721
7722 struct torture_suite *torture_vfs_fruit_unfruit(TALLOC_CTX *ctx)
7723 {
7724         struct torture_suite *suite = torture_suite_create(
7725                 ctx, "unfruit");
7726
7727         suite->description = talloc_strdup(
7728                 suite, "test converting back to AppleDouble");
7729
7730         torture_suite_add_2ns_smb2_test(suite,
7731                                         "unconvert",
7732                                         test_unconvert);
7733
7734         return suite;
7735 }