s4:torture/vfs/fruit: write some data to a just created teststream
[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   : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo
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, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72,
995         0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20,
996         0x66, 0x6f, 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  * talloc and intialize an AfpInfo
1032  **/
1033 static AfpInfo *torture_afpinfo_new(TALLOC_CTX *mem_ctx)
1034 {
1035         AfpInfo *info;
1036
1037         info = talloc_zero(mem_ctx, AfpInfo);
1038         if (info == NULL) {
1039                 return NULL;
1040         }
1041
1042         info->afpi_Signature = AFP_Signature;
1043         info->afpi_Version = AFP_Version;
1044         info->afpi_BackupTime = AFP_BackupTime;
1045
1046         return info;
1047 }
1048
1049 /**
1050  * Pack AfpInfo into a talloced buffer
1051  **/
1052 static char *torture_afpinfo_pack(TALLOC_CTX *mem_ctx,
1053                                   AfpInfo *info)
1054 {
1055         char *buf;
1056
1057         buf = talloc_zero_array(mem_ctx, char, AFP_INFO_SIZE);
1058         if (buf == NULL) {
1059                 return NULL;
1060         }
1061
1062         RSIVAL(buf, 0, info->afpi_Signature);
1063         RSIVAL(buf, 4, info->afpi_Version);
1064         RSIVAL(buf, 12, info->afpi_BackupTime);
1065         memcpy(buf + 16, info->afpi_FinderInfo, sizeof(info->afpi_FinderInfo));
1066
1067         return buf;
1068 }
1069
1070 /**
1071  * Unpack AfpInfo
1072  **/
1073 #if 0
1074 static void torture_afpinfo_unpack(AfpInfo *info, char *data)
1075 {
1076         info->afpi_Signature = RIVAL(data, 0);
1077         info->afpi_Version = RIVAL(data, 4);
1078         info->afpi_BackupTime = RIVAL(data, 12);
1079         memcpy(info->afpi_FinderInfo, (const char *)data + 16,
1080                sizeof(info->afpi_FinderInfo));
1081 }
1082 #endif
1083
1084 static bool torture_write_afpinfo(struct smb2_tree *tree,
1085                                   struct torture_context *tctx,
1086                                   TALLOC_CTX *mem_ctx,
1087                                   const char *fname,
1088                                   AfpInfo *info)
1089 {
1090         struct smb2_handle handle;
1091         struct smb2_create io;
1092         NTSTATUS status;
1093         const char *full_name;
1094         char *infobuf;
1095         bool ret = true;
1096
1097         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, AFPINFO_STREAM_NAME);
1098         if (full_name == NULL) {
1099             torture_comment(tctx, "talloc_asprintf error\n");
1100             return false;
1101         }
1102         ZERO_STRUCT(io);
1103         io.in.desired_access = SEC_FILE_WRITE_DATA;
1104         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1105         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1106         io.in.create_options = 0;
1107         io.in.fname = full_name;
1108
1109         status = smb2_create(tree, mem_ctx, &io);
1110         CHECK_STATUS(status, NT_STATUS_OK);
1111
1112         handle = io.out.file.handle;
1113
1114         infobuf = torture_afpinfo_pack(mem_ctx, info);
1115         if (infobuf == NULL) {
1116                 return false;
1117         }
1118
1119         status = smb2_util_write(tree, handle, infobuf, 0, AFP_INFO_SIZE);
1120         CHECK_STATUS(status, NT_STATUS_OK);
1121
1122         smb2_util_close(tree, handle);
1123
1124 done:
1125         return ret;
1126 }
1127
1128 /**
1129  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1130  * compare against buffer 'value'
1131  **/
1132 static bool check_stream(struct smb2_tree *tree,
1133                          const char *location,
1134                          struct torture_context *tctx,
1135                          TALLOC_CTX *mem_ctx,
1136                          const char *fname,
1137                          const char *sname,
1138                          off_t read_offset,
1139                          size_t read_count,
1140                          off_t comp_offset,
1141                          size_t comp_count,
1142                          const char *value)
1143 {
1144         struct smb2_handle handle;
1145         struct smb2_create create;
1146         struct smb2_read r;
1147         NTSTATUS status;
1148         char *full_name;
1149         bool ret = true;
1150
1151         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1152         if (full_name == NULL) {
1153             torture_comment(tctx, "talloc_asprintf error\n");
1154             return false;
1155         }
1156         ZERO_STRUCT(create);
1157         create.in.desired_access = SEC_FILE_READ_DATA;
1158         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1159         create.in.create_disposition = NTCREATEX_DISP_OPEN;
1160         create.in.fname = full_name;
1161
1162         torture_comment(tctx, "Open stream %s\n", full_name);
1163
1164         status = smb2_create(tree, mem_ctx, &create);
1165         if (!NT_STATUS_IS_OK(status)) {
1166                 TALLOC_FREE(full_name);
1167                 if (value == NULL) {
1168                         return true;
1169                 }
1170                 torture_comment(tctx, "Unable to open stream %s\n", full_name);
1171                 return false;
1172         }
1173
1174         handle = create.out.file.handle;
1175         if (value == NULL) {
1176                 TALLOC_FREE(full_name);
1177                 smb2_util_close(tree, handle);
1178                 return true;
1179         }
1180
1181         ZERO_STRUCT(r);
1182         r.in.file.handle = handle;
1183         r.in.length      = read_count;
1184         r.in.offset      = read_offset;
1185
1186         status = smb2_read(tree, tree, &r);
1187
1188         torture_assert_ntstatus_ok_goto(
1189                 tctx, status, ret, done,
1190                 talloc_asprintf(tctx, "(%s) Failed to read %lu bytes from stream '%s'\n",
1191                                 location, (long)strlen(value), full_name));
1192
1193         torture_assert_goto(tctx, r.out.data.length == read_count, ret, done,
1194                             talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected %jd\n",
1195                                             (intmax_t)r.out.data.length, (intmax_t)read_count));
1196
1197         torture_assert_goto(
1198                 tctx, memcmp(r.out.data.data + comp_offset, value, comp_count) == 0,
1199                 ret, done,
1200                 talloc_asprintf(tctx, "(%s) Bad data in stream\n", location));
1201
1202 done:
1203         TALLOC_FREE(full_name);
1204         smb2_util_close(tree, handle);
1205         return ret;
1206 }
1207
1208 /**
1209  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1210  * compare against buffer 'value'
1211  **/
1212 static ssize_t read_stream(struct smb2_tree *tree,
1213                            const char *location,
1214                            struct torture_context *tctx,
1215                            TALLOC_CTX *mem_ctx,
1216                            const char *fname,
1217                            const char *sname,
1218                            off_t read_offset,
1219                            size_t read_count)
1220 {
1221         struct smb2_handle handle;
1222         struct smb2_create create;
1223         struct smb2_read r;
1224         NTSTATUS status;
1225         const char *full_name;
1226         bool ret = true;
1227
1228         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1229         if (full_name == NULL) {
1230             torture_comment(tctx, "talloc_asprintf error\n");
1231             return -1;
1232         }
1233         ZERO_STRUCT(create);
1234         create.in.desired_access = SEC_FILE_READ_DATA;
1235         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1236         create.in.create_disposition = NTCREATEX_DISP_OPEN;
1237         create.in.fname = full_name;
1238
1239         torture_comment(tctx, "Open stream %s\n", full_name);
1240
1241         status = smb2_create(tree, mem_ctx, &create);
1242         if (!NT_STATUS_IS_OK(status)) {
1243                 torture_comment(tctx, "Unable to open stream %s\n",
1244                                 full_name);
1245                 return -1;
1246         }
1247
1248         handle = create.out.file.handle;
1249
1250         ZERO_STRUCT(r);
1251         r.in.file.handle = handle;
1252         r.in.length      = read_count;
1253         r.in.offset      = read_offset;
1254
1255         status = smb2_read(tree, tree, &r);
1256         if (!NT_STATUS_IS_OK(status)) {
1257                 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
1258         }
1259
1260         smb2_util_close(tree, handle);
1261
1262 done:
1263         if (ret == false) {
1264                 return -1;
1265         }
1266         return r.out.data.length;
1267 }
1268
1269 /**
1270  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1271  * compare against buffer 'value'
1272  **/
1273 static bool write_stream(struct smb2_tree *tree,
1274                          const char *location,
1275                          struct torture_context *tctx,
1276                          TALLOC_CTX *mem_ctx,
1277                          const char *fname,
1278                          const char *sname,
1279                          off_t offset,
1280                          size_t size,
1281                          const char *value)
1282 {
1283         struct smb2_handle handle;
1284         struct smb2_create create;
1285         NTSTATUS status;
1286         const char *full_name;
1287
1288         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname ? sname : "");
1289         if (full_name == NULL) {
1290             torture_comment(tctx, "talloc_asprintf error\n");
1291             return false;
1292         }
1293         ZERO_STRUCT(create);
1294         create.in.desired_access = SEC_FILE_WRITE_DATA;
1295         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1296         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1297         create.in.fname = full_name;
1298
1299         status = smb2_create(tree, mem_ctx, &create);
1300         if (!NT_STATUS_IS_OK(status)) {
1301                 if (value == NULL) {
1302                         return true;
1303                 } else {
1304                         torture_comment(tctx, "Unable to open stream %s\n",
1305                             full_name);
1306                         sleep(10000000);
1307                         return false;
1308                 }
1309         }
1310
1311         handle = create.out.file.handle;
1312         if (value == NULL) {
1313                 return true;
1314         }
1315
1316         status = smb2_util_write(tree, handle, value, offset, size);
1317
1318         if (!NT_STATUS_IS_OK(status)) {
1319                 torture_comment(tctx, "(%s) Failed to write %lu bytes to "
1320                     "stream '%s'\n", location, (long)size, full_name);
1321                 return false;
1322         }
1323
1324         smb2_util_close(tree, handle);
1325         return true;
1326 }
1327
1328 static bool torture_setup_local_xattr(struct torture_context *tctx,
1329                                       const char *path_option,
1330                                       const char *name,
1331                                       const char *xattr,
1332                                       const char *metadata,
1333                                       size_t size)
1334 {
1335         int ret = true;
1336         int result;
1337         const char *spath;
1338         char *path;
1339
1340         spath = torture_setting_string(tctx, path_option, NULL);
1341         if (spath == NULL) {
1342                 printf("No sharepath for option %s\n", path_option);
1343                 return false;
1344         }
1345
1346         path = talloc_asprintf(tctx, "%s/%s", spath, name);
1347
1348         result = setxattr(path, xattr, metadata, size, 0);
1349         if (result != 0) {
1350                 ret = false;
1351         }
1352
1353         TALLOC_FREE(path);
1354
1355         return ret;
1356 }
1357
1358 /**
1359  * Create a file or directory
1360  **/
1361 static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree,
1362                                const char *name, bool dir)
1363 {
1364         struct smb2_create io;
1365         NTSTATUS status;
1366
1367         smb2_util_unlink(tree, name);
1368         ZERO_STRUCT(io);
1369         io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1370         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
1371         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1372         io.in.share_access =
1373                 NTCREATEX_SHARE_ACCESS_DELETE|
1374                 NTCREATEX_SHARE_ACCESS_READ|
1375                 NTCREATEX_SHARE_ACCESS_WRITE;
1376         io.in.create_options = 0;
1377         io.in.fname = name;
1378         if (dir) {
1379                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1380                 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
1381                 io.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
1382                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1383         }
1384
1385         status = smb2_create(tree, mem_ctx, &io);
1386         if (!NT_STATUS_IS_OK(status)) {
1387                 return false;
1388         }
1389
1390         status = smb2_util_close(tree, io.out.file.handle);
1391         if (!NT_STATUS_IS_OK(status)) {
1392                 return false;
1393         }
1394
1395         return true;
1396 }
1397
1398 static bool enable_aapl(struct torture_context *tctx,
1399                         struct smb2_tree *tree)
1400 {
1401         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1402         NTSTATUS status;
1403         bool ret = true;
1404         struct smb2_create io;
1405         DATA_BLOB data;
1406         struct smb2_create_blob *aapl = NULL;
1407         uint32_t aapl_server_caps;
1408         uint32_t expected_scaps = (SMB2_CRTCTX_AAPL_UNIX_BASED |
1409                                    SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1410                                    SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1411                                    SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
1412         bool is_osx_server = torture_setting_bool(tctx, "osx", false);
1413
1414         ZERO_STRUCT(io);
1415         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
1416         io.in.file_attributes    = FILE_ATTRIBUTE_DIRECTORY;
1417         io.in.create_disposition = NTCREATEX_DISP_OPEN;
1418         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1419                               NTCREATEX_SHARE_ACCESS_READ |
1420                               NTCREATEX_SHARE_ACCESS_WRITE);
1421         io.in.fname = "";
1422
1423         /*
1424          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1425          * controls behaviour of Apple's SMB2 extensions for the whole
1426          * session!
1427          */
1428
1429         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1430         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1431         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1432                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1433                              SMB2_CRTCTX_AAPL_MODEL_INFO));
1434         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1435                               SMB2_CRTCTX_AAPL_UNIX_BASED |
1436                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1437
1438         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1439         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_blob_add");
1440
1441         status = smb2_create(tree, tctx, &io);
1442         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1443
1444         status = smb2_util_close(tree, io.out.file.handle);
1445         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close");
1446
1447         /*
1448          * Now check returned AAPL context
1449          */
1450         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1451
1452         aapl = smb2_create_blob_find(&io.out.blobs,
1453                                      SMB2_CREATE_TAG_AAPL);
1454         torture_assert_goto(tctx, aapl != NULL, ret, done, "missing AAPL context");
1455
1456         if (!is_osx_server) {
1457                 size_t expected_aapl_ctx_size;
1458
1459                 expected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
1460
1461                 torture_assert_goto(
1462                         tctx, aapl->data.length == expected_aapl_ctx_size,
1463                         ret, done, "bad AAPL size");
1464         }
1465
1466         aapl_server_caps = BVAL(aapl->data.data, 16);
1467         torture_assert_goto(tctx, aapl_server_caps == expected_scaps,
1468                             ret, done, "bad AAPL caps");
1469
1470 done:
1471         talloc_free(mem_ctx);
1472         return ret;
1473 }
1474
1475 static bool test_read_netatalk_metadata(struct torture_context *tctx,
1476                                         struct smb2_tree *tree)
1477 {
1478         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1479         const char *fname = BASEDIR "\\torture_read_metadata";
1480         NTSTATUS status;
1481         struct smb2_handle testdirh;
1482         bool ret = true;
1483         ssize_t len;
1484         const char *localdir = NULL;
1485
1486         torture_comment(tctx, "Checking metadata access\n");
1487
1488         localdir = torture_setting_string(tctx, "localdir", NULL);
1489         if (localdir == NULL) {
1490                 torture_skip(tctx, "Need localdir for test");
1491         }
1492
1493         smb2_util_unlink(tree, fname);
1494
1495         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1496         CHECK_STATUS(status, NT_STATUS_OK);
1497         smb2_util_close(tree, testdirh);
1498
1499         ret = torture_setup_file(mem_ctx, tree, fname, false);
1500         if (ret == false) {
1501                 goto done;
1502         }
1503
1504         ret = torture_setup_local_xattr(tctx, "localdir",
1505                                         BASEDIR "/torture_read_metadata",
1506                                         AFPINFO_EA_NETATALK,
1507                                         metadata_xattr, sizeof(metadata_xattr));
1508         if (ret == false) {
1509                 goto done;
1510         }
1511
1512         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1513                            0, 60, 0, 4, "AFP");
1514         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1515
1516         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1517                            0, 60, 16, 8, "BARRFOOO");
1518         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1519
1520         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1521                            16, 8, 0, 3, "AFP");
1522         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1523
1524         /* Check reading offset and read size > sizeof(AFPINFO_STREAM) */
1525
1526         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1527                           AFPINFO_STREAM, 0, 61);
1528         CHECK_VALUE(len, 60);
1529
1530         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1531                           AFPINFO_STREAM, 59, 2);
1532         CHECK_VALUE(len, 2);
1533
1534         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1535                           AFPINFO_STREAM, 60, 1);
1536         CHECK_VALUE(len, 1);
1537
1538         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1539                           AFPINFO_STREAM, 61, 1);
1540         CHECK_VALUE(len, 0);
1541
1542 done:
1543         smb2_deltree(tree, BASEDIR);
1544         talloc_free(mem_ctx);
1545         return ret;
1546 }
1547
1548 static bool test_read_afpinfo(struct torture_context *tctx,
1549                               struct smb2_tree *tree)
1550 {
1551         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1552         const char *fname = BASEDIR "\\torture_read_metadata";
1553         NTSTATUS status;
1554         struct smb2_handle testdirh;
1555         bool ret = true;
1556         ssize_t len;
1557         AfpInfo *info;
1558         const char *type_creator = "SMB,OLE!";
1559
1560         torture_comment(tctx, "Checking metadata access\n");
1561
1562         smb2_util_unlink(tree, fname);
1563
1564         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1565         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
1566         smb2_util_close(tree, testdirh);
1567
1568         ret = torture_setup_file(mem_ctx, tree, fname, false);
1569         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
1570
1571         info = torture_afpinfo_new(mem_ctx);
1572         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
1573
1574         memcpy(info->afpi_FinderInfo, type_creator, 8);
1575         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1576         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
1577
1578         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1579                            0, 60, 0, 4, "AFP");
1580         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1581
1582         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1583                            0, 60, 16, 8, type_creator);
1584         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1585
1586         /*
1587          * OS X ignores offset <= 60 and treats the as
1588          * offset=0. Reading from offsets > 60 returns EOF=0.
1589          */
1590
1591         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1592                            16, 8, 0, 8, "AFP\0\0\0\001\0");
1593         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1594
1595         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1596                           AFPINFO_STREAM, 0, 61);
1597         torture_assert_goto(tctx, len == 60, ret, done, "read_stream failed");
1598
1599         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1600                           AFPINFO_STREAM, 59, 2);
1601         torture_assert_goto(tctx, len == 2, ret, done, "read_stream failed");
1602
1603         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1604                            59, 2, 0, 2, "AF");
1605         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1606
1607         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1608                           AFPINFO_STREAM, 60, 1);
1609         torture_assert_goto(tctx, len == 1, ret, done, "read_stream failed");
1610
1611         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1612                            60, 1, 0, 1, "A");
1613         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1614
1615         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1616                           AFPINFO_STREAM, 61, 1);
1617         torture_assert_goto(tctx, len == 0, ret, done, "read_stream failed");
1618
1619 done:
1620         smb2_util_unlink(tree, fname);
1621         smb2_deltree(tree, BASEDIR);
1622         talloc_free(mem_ctx);
1623         return ret;
1624 }
1625
1626 static bool test_write_atalk_metadata(struct torture_context *tctx,
1627                                       struct smb2_tree *tree)
1628 {
1629         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1630         const char *fname = BASEDIR "\\torture_write_metadata";
1631         const char *type_creator = "SMB,OLE!";
1632         NTSTATUS status;
1633         struct smb2_handle testdirh;
1634         bool ret = true;
1635         AfpInfo *info;
1636
1637         smb2_deltree(tree, BASEDIR);
1638         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1639         CHECK_STATUS(status, NT_STATUS_OK);
1640         smb2_util_close(tree, testdirh);
1641
1642         ret = torture_setup_file(mem_ctx, tree, fname, false);
1643         if (ret == false) {
1644                 goto done;
1645         }
1646
1647         info = torture_afpinfo_new(mem_ctx);
1648         if (info == NULL) {
1649                 goto done;
1650         }
1651
1652         memcpy(info->afpi_FinderInfo, type_creator, 8);
1653         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1654         ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1655                             0, 60, 16, 8, type_creator);
1656
1657 done:
1658         smb2_util_unlink(tree, fname);
1659         smb2_deltree(tree, BASEDIR);
1660         talloc_free(mem_ctx);
1661         return ret;
1662 }
1663
1664 static bool test_write_atalk_rfork_io(struct torture_context *tctx,
1665                                       struct smb2_tree *tree)
1666 {
1667         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1668         const char *fname = BASEDIR "\\torture_write_rfork_io";
1669         const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
1670         const char *rfork_content = "1234567890";
1671         NTSTATUS status;
1672         struct smb2_handle testdirh;
1673         bool ret = true;
1674
1675         union smb_open io;
1676         struct smb2_handle filehandle;
1677         union smb_fileinfo finfo;
1678         union smb_setfileinfo sinfo;
1679
1680         smb2_util_unlink(tree, fname);
1681
1682         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1683         CHECK_STATUS(status, NT_STATUS_OK);
1684         smb2_util_close(tree, testdirh);
1685
1686         ret = torture_setup_file(mem_ctx, tree, fname, false);
1687         if (ret == false) {
1688                 goto done;
1689         }
1690
1691         torture_comment(tctx, "(%s) writing to resource fork\n",
1692             __location__);
1693
1694         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1695                             fname, AFPRESOURCE_STREAM_NAME,
1696                             10, 10, rfork_content);
1697
1698         ret &= check_stream(tree, __location__, tctx, mem_ctx,
1699                             fname, AFPRESOURCE_STREAM_NAME,
1700                             0, 20, 10, 10, rfork_content);
1701
1702         /* Check size after write */
1703
1704         ZERO_STRUCT(io);
1705         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1706         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1707                 SEC_FILE_WRITE_ATTRIBUTE;
1708         io.smb2.in.fname = rfork;
1709         status = smb2_create(tree, mem_ctx, &(io.smb2));
1710         CHECK_STATUS(status, NT_STATUS_OK);
1711         filehandle = io.smb2.out.file.handle;
1712
1713         torture_comment(tctx, "(%s) check resource fork size after write\n",
1714             __location__);
1715
1716         ZERO_STRUCT(finfo);
1717         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1718         finfo.generic.in.file.handle = filehandle;
1719         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1720         CHECK_STATUS(status, NT_STATUS_OK);
1721         if (finfo.all_info.out.size != 20) {
1722                 torture_result(tctx, TORTURE_FAIL,
1723                                "(%s) Incorrect resource fork size\n",
1724                                __location__);
1725                 ret = false;
1726                 smb2_util_close(tree, filehandle);
1727                 goto done;
1728         }
1729         smb2_util_close(tree, filehandle);
1730
1731         /* Write at large offset */
1732
1733         torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
1734                         __location__);
1735
1736         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1737                             fname, AFPRESOURCE_STREAM_NAME,
1738                             (off_t)64*1024*1024, 10, rfork_content);
1739
1740         ret &= check_stream(tree, __location__, tctx, mem_ctx,
1741                             fname, AFPRESOURCE_STREAM_NAME,
1742                             (off_t)64*1024*1024, 10, 0, 10, rfork_content);
1743
1744         /* Truncate back to size of 1 byte */
1745
1746         torture_comment(tctx, "(%s) truncate resource fork and check size\n",
1747                         __location__);
1748
1749         ZERO_STRUCT(io);
1750         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1751         io.smb2.in.desired_access = SEC_FILE_ALL;
1752         io.smb2.in.fname = rfork;
1753         status = smb2_create(tree, mem_ctx, &(io.smb2));
1754         CHECK_STATUS(status, NT_STATUS_OK);
1755         filehandle = io.smb2.out.file.handle;
1756
1757         ZERO_STRUCT(sinfo);
1758         sinfo.end_of_file_info.level =
1759                 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1760         sinfo.end_of_file_info.in.file.handle = filehandle;
1761         sinfo.end_of_file_info.in.size = 1;
1762         status = smb2_setinfo_file(tree, &sinfo);
1763         CHECK_STATUS(status, NT_STATUS_OK);
1764
1765         smb2_util_close(tree, filehandle);
1766
1767         /* Now check size */
1768         ZERO_STRUCT(io);
1769         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1770         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1771                 SEC_FILE_WRITE_ATTRIBUTE;
1772         io.smb2.in.fname = rfork;
1773         status = smb2_create(tree, mem_ctx, &(io.smb2));
1774         CHECK_STATUS(status, NT_STATUS_OK);
1775         filehandle = io.smb2.out.file.handle;
1776
1777         ZERO_STRUCT(finfo);
1778         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1779         finfo.generic.in.file.handle = filehandle;
1780         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1781         CHECK_STATUS(status, NT_STATUS_OK);
1782         if (finfo.all_info.out.size != 1) {
1783                 torture_result(tctx, TORTURE_FAIL,
1784                                "(%s) Incorrect resource fork size\n",
1785                                __location__);
1786                 ret = false;
1787                 smb2_util_close(tree, filehandle);
1788                 goto done;
1789         }
1790         smb2_util_close(tree, filehandle);
1791
1792 done:
1793         smb2_util_unlink(tree, fname);
1794         smb2_deltree(tree, BASEDIR);
1795         talloc_free(mem_ctx);
1796         return ret;
1797 }
1798
1799 static bool test_rfork_truncate(struct torture_context *tctx,
1800                                 struct smb2_tree *tree)
1801 {
1802         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1803         const char *fname = BASEDIR "\\torture_rfork_truncate";
1804         const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
1805         const char *rfork_content = "1234567890";
1806         NTSTATUS status;
1807         struct smb2_handle testdirh;
1808         bool ret = true;
1809         struct smb2_create create;
1810         struct smb2_handle fh1, fh2, fh3;
1811         union smb_setfileinfo sinfo;
1812
1813         smb2_util_unlink(tree, fname);
1814
1815         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1816         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1817         smb2_util_close(tree, testdirh);
1818
1819         ret = torture_setup_file(mem_ctx, tree, fname, false);
1820         if (ret == false) {
1821                 goto done;
1822         }
1823
1824         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1825                             fname, AFPRESOURCE_STREAM,
1826                             10, 10, rfork_content);
1827
1828         /* Truncate back to size 0, further access MUST return ENOENT */
1829
1830         torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
1831                         __location__);
1832
1833         ZERO_STRUCT(create);
1834         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1835         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1836         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1837         create.in.fname               = fname;
1838         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1839                 NTCREATEX_SHARE_ACCESS_READ |
1840                 NTCREATEX_SHARE_ACCESS_WRITE;
1841         status = smb2_create(tree, mem_ctx, &create);
1842         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1843         fh1 = create.out.file.handle;
1844
1845         ZERO_STRUCT(create);
1846         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1847         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1848         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1849         create.in.fname               = rfork;
1850         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1851                 NTCREATEX_SHARE_ACCESS_READ |
1852                 NTCREATEX_SHARE_ACCESS_WRITE;
1853         status = smb2_create(tree, mem_ctx, &create);
1854         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1855         fh2 = create.out.file.handle;
1856
1857         ZERO_STRUCT(sinfo);
1858         sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1859         sinfo.end_of_file_info.in.file.handle = fh2;
1860         sinfo.end_of_file_info.in.size = 0;
1861         status = smb2_setinfo_file(tree, &sinfo);
1862         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
1863
1864         /*
1865          * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
1866          */
1867         ZERO_STRUCT(create);
1868         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1869         create.in.desired_access      = SEC_FILE_ALL;
1870         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1871         create.in.fname               = rfork;
1872         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1873                 NTCREATEX_SHARE_ACCESS_READ |
1874                 NTCREATEX_SHARE_ACCESS_WRITE;
1875         status = smb2_create(tree, mem_ctx, &create);
1876         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1877
1878         /*
1879          * Do another open on the rfork and write to the new handle. A
1880          * naive server might unlink the AppleDouble resource fork
1881          * file when its truncated to 0 bytes above, so in case both
1882          * open handles share the same underlying fd, the unlink would
1883          * cause the below write to be lost.
1884          */
1885         ZERO_STRUCT(create);
1886         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1887         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1888         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1889         create.in.fname               = rfork;
1890         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1891                 NTCREATEX_SHARE_ACCESS_READ |
1892                 NTCREATEX_SHARE_ACCESS_WRITE;
1893         status = smb2_create(tree, mem_ctx, &create);
1894         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1895         fh3 = create.out.file.handle;
1896
1897         status = smb2_util_write(tree, fh3, "foo", 0, 3);
1898         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
1899
1900         smb2_util_close(tree, fh3);
1901         smb2_util_close(tree, fh2);
1902         smb2_util_close(tree, fh1);
1903
1904         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
1905                            0, 3, 0, 3, "foo");
1906         torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1907
1908 done:
1909         smb2_util_unlink(tree, fname);
1910         smb2_deltree(tree, BASEDIR);
1911         talloc_free(mem_ctx);
1912         return ret;
1913 }
1914
1915 static bool test_rfork_create(struct torture_context *tctx,
1916                               struct smb2_tree *tree)
1917 {
1918         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1919         const char *fname = BASEDIR "\\torture_rfork_create";
1920         const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1921         NTSTATUS status;
1922         struct smb2_handle testdirh;
1923         bool ret = true;
1924         struct smb2_create create;
1925         struct smb2_handle fh1;
1926         const char *streams[] = {
1927                 "::$DATA"
1928         };
1929         union smb_fileinfo finfo;
1930
1931         smb2_util_unlink(tree, fname);
1932
1933         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1934         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1935         smb2_util_close(tree, testdirh);
1936
1937         ret = torture_setup_file(mem_ctx, tree, fname, false);
1938         if (ret == false) {
1939                 goto done;
1940         }
1941
1942         torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
1943                         __location__);
1944
1945         ZERO_STRUCT(create);
1946         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1947         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1948         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1949         create.in.fname               = rfork;
1950         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1951                 NTCREATEX_SHARE_ACCESS_READ |
1952                 NTCREATEX_SHARE_ACCESS_WRITE;
1953         status = smb2_create(tree, mem_ctx, &create);
1954         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1955
1956         torture_comment(tctx, "(%s) create resource fork\n", __location__);
1957
1958         ZERO_STRUCT(create);
1959         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1960         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1961         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1962         create.in.fname               = rfork;
1963         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1964                 NTCREATEX_SHARE_ACCESS_READ |
1965                 NTCREATEX_SHARE_ACCESS_WRITE;
1966         status = smb2_create(tree, mem_ctx, &create);
1967         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1968         fh1 = create.out.file.handle;
1969
1970         torture_comment(tctx, "(%s) getinfo on create handle\n",
1971                         __location__);
1972
1973         ZERO_STRUCT(finfo);
1974         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1975         finfo.generic.in.file.handle = fh1;
1976         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1977         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
1978         if (finfo.all_info.out.size != 0) {
1979                 torture_result(tctx, TORTURE_FAIL,
1980                                "(%s) Incorrect resource fork size\n",
1981                                __location__);
1982                 ret = false;
1983                 smb2_util_close(tree, fh1);
1984                 goto done;
1985         }
1986
1987         torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
1988                         __location__);
1989
1990         ZERO_STRUCT(create);
1991         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1992         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1993         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1994         create.in.fname               = rfork;
1995         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1996                 NTCREATEX_SHARE_ACCESS_READ |
1997                 NTCREATEX_SHARE_ACCESS_WRITE;
1998         status = smb2_create(tree, mem_ctx, &create);
1999         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
2000
2001         ret = check_stream_list(tree, tctx, fname, 1, streams, false);
2002         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2003
2004         torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
2005                         __location__);
2006
2007         ZERO_STRUCT(create);
2008         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
2009         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
2010         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
2011         create.in.fname               = rfork;
2012         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
2013                 NTCREATEX_SHARE_ACCESS_READ |
2014                 NTCREATEX_SHARE_ACCESS_WRITE;
2015         status = smb2_create(tree, mem_ctx, &create);
2016         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
2017
2018 done:
2019         smb2_util_unlink(tree, fname);
2020         smb2_deltree(tree, BASEDIR);
2021         talloc_free(mem_ctx);
2022         return ret;
2023 }
2024
2025 static bool test_rfork_create_ro(struct torture_context *tctx,
2026                                  struct smb2_tree *tree)
2027 {
2028         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2029         const char *fname = BASEDIR "\\torture_rfork_create";
2030         const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
2031         NTSTATUS status;
2032         struct smb2_handle testdirh;
2033         bool ret = true;
2034         struct smb2_create create;
2035
2036         smb2_util_unlink(tree, fname);
2037         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2038         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2039                 "torture_smb2_testdir\n");
2040         smb2_util_close(tree, testdirh);
2041
2042         ret = torture_setup_file(mem_ctx, tree, fname, false);
2043         if (ret == false) {
2044                 goto done;
2045         }
2046
2047         torture_comment(tctx, "(%s) Try opening read-only with "
2048                         "open_if create disposition, should work\n",
2049                         __location__);
2050
2051         ZERO_STRUCT(create);
2052         create.in.fname = rfork;
2053         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2054         create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
2055         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2056         create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
2057         status = smb2_create(tree, mem_ctx, &(create));
2058         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2059                 "smb2_create failed\n");
2060
2061         smb2_util_close(tree, create.out.file.handle);
2062
2063 done:
2064         smb2_util_unlink(tree, fname);
2065         smb2_deltree(tree, BASEDIR);
2066         talloc_free(mem_ctx);
2067         return ret;
2068 }
2069
2070 static bool test_adouble_conversion(struct torture_context *tctx,
2071                                     struct smb2_tree *tree)
2072 {
2073         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2074         const char *fname = BASEDIR "\\test_adouble_conversion";
2075         const char *adname = BASEDIR "/._test_adouble_conversion";
2076         NTSTATUS status;
2077         struct smb2_handle testdirh;
2078         bool ret = true;
2079         const char *data = "This resource fork intentionally left blank";
2080         size_t datalen = strlen(data);
2081         const char *streams[] = {
2082                 "::$DATA",
2083                 AFPINFO_STREAM,
2084                 AFPRESOURCE_STREAM,
2085                 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
2086                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2087         };
2088         bool is_osx = torture_setting_bool(tctx, "osx", false);
2089
2090         if (is_osx) {
2091                 torture_skip(tctx, "Test only works with Samba\n");
2092         }
2093
2094         smb2_deltree(tree, BASEDIR);
2095
2096         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2097         CHECK_STATUS(status, NT_STATUS_OK);
2098         smb2_util_close(tree, testdirh);
2099
2100         ret = torture_setup_file(tctx, tree, fname, false);
2101         torture_assert_goto(tctx, ret == true, ret, done,
2102                             "torture_setup_file failed\n");
2103
2104         ret = torture_setup_file(tctx, tree, adname, false);
2105         torture_assert_goto(tctx, ret == true, ret, done,
2106                             "torture_setup_file failed\n");
2107
2108         ret = write_stream(tree, __location__, tctx, mem_ctx,
2109                            adname, NULL,
2110                            0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
2111         torture_assert_goto(tctx, ret == true, ret, done,
2112                             "write_stream failed\n");
2113
2114         torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
2115             __location__);
2116
2117         ret = check_stream(tree, __location__, tctx, mem_ctx,
2118                            fname, AFPRESOURCE_STREAM,
2119                            16, datalen, 0, datalen, data);
2120         torture_assert_goto(tctx, ret == true, ret, done,
2121                             "check AFPRESOURCE_STREAM failed\n");
2122
2123         ret = check_stream(tree, __location__, tctx, mem_ctx,
2124                            fname, AFPINFO_STREAM,
2125                            0, 60, 16, 8, "TESTSLOW");
2126         torture_assert_goto(tctx, ret == true, ret, done,
2127                             "check AFPINFO_STREAM failed\n");
2128
2129         ret = check_stream(tree, __location__, tctx, mem_ctx, fname,
2130                            ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2131                            0, 3, 0, 3, "baz");
2132         torture_assert_goto(tctx, ret == true, ret, done,
2133                             "check foo:bar stream failed\n");
2134
2135         ret = check_stream_list(tree, tctx, fname, 5, streams, false);
2136         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2137
2138 done:
2139         smb2_deltree(tree, BASEDIR);
2140         talloc_free(mem_ctx);
2141         return ret;
2142 }
2143
2144 /*
2145  * Test conversion of AppleDouble file without embedded xattr data
2146  */
2147 static bool test_adouble_conversion_wo_xattr(struct torture_context *tctx,
2148                                              struct smb2_tree *tree)
2149 {
2150         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2151         const char *fname = BASEDIR "\\test_adouble_conversion";
2152         const char *adname = BASEDIR "/._test_adouble_conversion";
2153         NTSTATUS status;
2154         struct smb2_handle testdirh;
2155         bool ret = true;
2156         const char *streams[] = {
2157                 "::$DATA",
2158                 AFPINFO_STREAM,
2159                 AFPRESOURCE_STREAM
2160         };
2161         struct smb2_create create;
2162         struct smb2_find find;
2163         unsigned int count;
2164         union smb_search_data *d;
2165         const char *data = "This resource fork intentionally left blank";
2166         size_t datalen = strlen(data);
2167         bool is_osx = torture_setting_bool(tctx, "osx", false);
2168
2169         if (is_osx) {
2170                 torture_skip(tctx, "Test only works with Samba\n");
2171         }
2172
2173         smb2_deltree(tree, BASEDIR);
2174
2175         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2176         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2177                                         "torture_smb2_testdir failed\n");
2178         smb2_util_close(tree, testdirh);
2179
2180         ret = torture_setup_file(tctx, tree, fname, false);
2181         torture_assert_goto(tctx, ret == true, ret, done,
2182                             "torture_setup_file failed\n");
2183
2184         ret = torture_setup_file(tctx, tree, adname, false);
2185         torture_assert_goto(tctx, ret == true, ret, done,
2186                             "torture_setup_file failed\n");
2187
2188         ret = write_stream(tree, __location__, tctx, mem_ctx,
2189                            adname, NULL, 0,
2190                            sizeof(osx_adouble_without_xattr),
2191                            osx_adouble_without_xattr);
2192         torture_assert_goto(tctx, ret == true, ret, done,
2193                             "write_stream failed\n");
2194
2195         ret = enable_aapl(tctx, tree);
2196         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
2197
2198         /*
2199          * Issue a smb2_find(), this triggers the server-side conversion
2200          */
2201
2202         create = (struct smb2_create) {
2203                 .in.desired_access = SEC_RIGHTS_DIR_READ,
2204                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
2205                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
2206                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
2207                 .in.create_disposition = NTCREATEX_DISP_OPEN,
2208                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
2209                 .in.fname = BASEDIR,
2210         };
2211
2212         status = smb2_create(tree, tctx, &create);
2213         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2214                                         "smb2_create failed\n");
2215
2216         find = (struct smb2_find) {
2217                 .in.file.handle = create.out.file.handle,
2218                 .in.pattern = "*",
2219                 .in.max_response_size = 0x1000,
2220                 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
2221         };
2222
2223         status = smb2_find_level(tree, tree, &find, &count, &d);
2224         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2225                                         "smb2_find_level failed\n");
2226
2227         status = smb2_util_close(tree, create.out.file.handle);
2228         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2229                                         "smb2_util_close failed");
2230
2231         /*
2232          * Check number of streams
2233          */
2234
2235         ret = check_stream_list(tree, tctx, fname, 3, streams, false);
2236         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2237
2238
2239         /*
2240          * Check Resourcefork data can be read.
2241          */
2242
2243         ret = check_stream(tree, __location__, tctx, mem_ctx,
2244                            fname, AFPRESOURCE_STREAM,
2245                            16, datalen, 0, datalen, data);
2246         torture_assert_goto(tctx, ret == true, ret, done,
2247                             "check AFPRESOURCE_STREAM failed\n");
2248
2249         /*
2250          * Check FinderInfo data has been migrated to stream.
2251          */
2252
2253         ret = check_stream(tree, __location__, tctx, mem_ctx,
2254                            fname, AFPINFO_STREAM,
2255                            0, 60, 16, 8, "WAVEPTul");
2256         torture_assert_goto(tctx, ret == true, ret, done,
2257                             "check AFPINFO_STREAM failed\n");
2258
2259 done:
2260         smb2_deltree(tree, BASEDIR);
2261         talloc_free(mem_ctx);
2262         return ret;
2263 }
2264
2265 static bool test_aapl(struct torture_context *tctx,
2266                       struct smb2_tree *tree)
2267 {
2268         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2269         const char *fname = BASEDIR "\\test_aapl";
2270         NTSTATUS status;
2271         struct smb2_handle testdirh;
2272         bool ret = true;
2273         struct smb2_create io;
2274         DATA_BLOB data;
2275         struct smb2_create_blob *aapl = NULL;
2276         AfpInfo *info;
2277         const char *type_creator = "SMB,OLE!";
2278         char type_creator_buf[9];
2279         uint32_t aapl_cmd;
2280         uint32_t aapl_reply_bitmap;
2281         uint32_t aapl_server_caps;
2282         uint32_t aapl_vol_caps;
2283         uint32_t expected_vol_caps = 0;
2284         char *model;
2285         struct smb2_find f;
2286         unsigned int count;
2287         union smb_search_data *d;
2288         uint64_t rfork_len;
2289         bool is_osx_server = torture_setting_bool(tctx, "osx", false);
2290
2291         smb2_deltree(tree, BASEDIR);
2292
2293         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2294         CHECK_STATUS(status, NT_STATUS_OK);
2295         smb2_util_close(tree, testdirh);
2296
2297         ZERO_STRUCT(io);
2298         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
2299         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
2300         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2301         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2302                               NTCREATEX_SHARE_ACCESS_READ |
2303                               NTCREATEX_SHARE_ACCESS_WRITE);
2304         io.in.fname = fname;
2305
2306         /*
2307          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
2308          * controls behaviour of Apple's SMB2 extensions for the whole
2309          * session!
2310          */
2311
2312         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2313         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2314         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2315                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2316                              SMB2_CRTCTX_AAPL_MODEL_INFO));
2317         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2318                               SMB2_CRTCTX_AAPL_UNIX_BASED |
2319                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
2320
2321         torture_comment(tctx, "Testing SMB2 create context AAPL\n");
2322         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2323         CHECK_STATUS(status, NT_STATUS_OK);
2324
2325         status = smb2_create(tree, tctx, &io);
2326         CHECK_STATUS(status, NT_STATUS_OK);
2327         status = smb2_util_close(tree, io.out.file.handle);
2328         CHECK_STATUS(status, NT_STATUS_OK);
2329
2330         /*
2331          * Now check returned AAPL context
2332          */
2333         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
2334
2335         aapl = smb2_create_blob_find(&io.out.blobs,
2336                                      SMB2_CREATE_TAG_AAPL);
2337
2338         if (aapl == NULL) {
2339                 torture_result(tctx, TORTURE_FAIL,
2340                                "(%s) unexpectedly no AAPL capabilities were returned.",
2341                                __location__);
2342                 ret = false;
2343                 goto done;
2344         }
2345
2346         if (!is_osx_server) {
2347                 size_t expected_aapl_ctx_size;
2348                 bool size_ok;
2349
2350                 /*
2351                  * uint32_t CommandCode = kAAPL_SERVER_QUERY
2352                  * uint32_t Reserved = 0;
2353                  * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
2354                  *                        kAAPL_VOLUME_CAPS |
2355                  *                        kAAPL_MODEL_INFO;
2356                  * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
2357                  *                       kAAPL_SUPPORTS_OSX_COPYFILE;
2358                  * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
2359                  *                       kAAPL_CASE_SENSITIVE;
2360                  * uint32_t Pad2 = 0;
2361                  * uint32_t ModelStringLen = 10;
2362                  * ucs2_t ModelString[5] = "MacSamba";
2363                  */
2364                 expected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
2365
2366                 size_ok = aapl->data.length == expected_aapl_ctx_size;
2367                 torture_assert_goto(tctx, size_ok, ret, done, "bad AAPL size");
2368         }
2369
2370         aapl_cmd = IVAL(aapl->data.data, 0);
2371         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2372                 torture_result(tctx, TORTURE_FAIL,
2373                                "(%s) unexpected cmd: %d",
2374                                __location__, (int)aapl_cmd);
2375                 ret = false;
2376                 goto done;
2377         }
2378
2379         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2380         if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2381                                   SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2382                                   SMB2_CRTCTX_AAPL_MODEL_INFO)) {
2383                 torture_result(tctx, TORTURE_FAIL,
2384                                "(%s) unexpected reply_bitmap: %d",
2385                                __location__, (int)aapl_reply_bitmap);
2386                 ret = false;
2387                 goto done;
2388         }
2389
2390         aapl_server_caps = BVAL(aapl->data.data, 16);
2391         if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
2392                                  SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2393                                  SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
2394                                  SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
2395                 torture_result(tctx, TORTURE_FAIL,
2396                                "(%s) unexpected server_caps: %d",
2397                                __location__, (int)aapl_server_caps);
2398                 ret = false;
2399                 goto done;
2400         }
2401
2402         if (is_osx_server) {
2403                 expected_vol_caps = 5;
2404         }
2405         aapl_vol_caps = BVAL(aapl->data.data, 24);
2406         if (aapl_vol_caps != expected_vol_caps) {
2407                 /* this will fail on a case insensitive fs ... */
2408                 torture_result(tctx, TORTURE_FAIL,
2409                                 "(%s) unexpected vol_caps: %d",
2410                                 __location__, (int)aapl_vol_caps);
2411         }
2412
2413         ret = convert_string_talloc(mem_ctx,
2414                                     CH_UTF16LE, CH_UNIX,
2415                                     aapl->data.data + 40, 10,
2416                                     &model, NULL);
2417         if (ret == false) {
2418                 torture_result(tctx, TORTURE_FAIL,
2419                                "(%s) convert_string_talloc() failed",
2420                                __location__);
2421                 goto done;
2422         }
2423         torture_comment(tctx, "Got server model: \"%s\"\n", model);
2424
2425         /*
2426          * Now that Requested AAPL extensions are enabled, setup some
2427          * Mac files with metadata and resource fork
2428          */
2429         ret = torture_setup_file(mem_ctx, tree, fname, false);
2430         if (ret == false) {
2431                 torture_result(tctx, TORTURE_FAIL,
2432                                "(%s) torture_setup_file() failed",
2433                                __location__);
2434                 goto done;
2435         }
2436
2437         info = torture_afpinfo_new(mem_ctx);
2438         if (info == NULL) {
2439                 torture_result(tctx, TORTURE_FAIL,
2440                                "(%s) torture_afpinfo_new() failed",
2441                                __location__);
2442                 ret = false;
2443                 goto done;
2444         }
2445
2446         memcpy(info->afpi_FinderInfo, type_creator, 8);
2447         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2448         if (ret == false) {
2449                 torture_result(tctx, TORTURE_FAIL,
2450                                "(%s) torture_write_afpinfo() failed",
2451                                __location__);
2452                 goto done;
2453         }
2454
2455         ret = write_stream(tree, __location__, tctx, mem_ctx,
2456                            fname, AFPRESOURCE_STREAM_NAME,
2457                            0, 3, "foo");
2458         if (ret == false) {
2459                 torture_result(tctx, TORTURE_FAIL,
2460                                "(%s) write_stream() failed",
2461                                __location__);
2462                 goto done;
2463         }
2464
2465         /*
2466          * Ok, file is prepared, now call smb2/find
2467          */
2468
2469         ZERO_STRUCT(io);
2470         io.in.desired_access = SEC_RIGHTS_DIR_READ;
2471         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2472         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2473         io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
2474                               NTCREATEX_SHARE_ACCESS_WRITE |
2475                               NTCREATEX_SHARE_ACCESS_DELETE);
2476         io.in.create_disposition = NTCREATEX_DISP_OPEN;
2477         io.in.fname = BASEDIR;
2478         status = smb2_create(tree, tctx, &io);
2479         CHECK_STATUS(status, NT_STATUS_OK);
2480
2481         ZERO_STRUCT(f);
2482         f.in.file.handle        = io.out.file.handle;
2483         f.in.pattern            = "test_aapl";
2484         f.in.continue_flags     = SMB2_CONTINUE_FLAG_SINGLE;
2485         f.in.max_response_size  = 0x1000;
2486         f.in.level              = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
2487
2488         status = smb2_find_level(tree, tree, &f, &count, &d);
2489         CHECK_STATUS(status, NT_STATUS_OK);
2490
2491         status = smb2_util_close(tree, io.out.file.handle);
2492         CHECK_STATUS(status, NT_STATUS_OK);
2493
2494         if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2495                 torture_result(tctx, TORTURE_FAIL,
2496                                "(%s) write_stream() failed",
2497                                __location__);
2498                 ret = false;
2499                 goto done;
2500         }
2501
2502         if (d[0].id_both_directory_info.short_name.private_length != 24) {
2503                 torture_result(tctx, TORTURE_FAIL,
2504                                "(%s) bad short_name length %" PRIu32 ", expected 24",
2505                                __location__, d[0].id_both_directory_info.short_name.private_length);
2506                 ret = false;
2507                 goto done;
2508         }
2509
2510         torture_comment(tctx, "short_name buffer:\n");
2511         dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2512
2513         /*
2514          * Extract data as specified by the AAPL extension:
2515          * - ea_size contains max_access
2516          * - short_name contains resource fork length + FinderInfo
2517          * - reserved2 contains the unix mode
2518          */
2519         torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2520                         d[0].id_both_directory_info.ea_size);
2521
2522         rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2523         if (rfork_len != 3) {
2524                 torture_result(tctx, TORTURE_FAIL,
2525                                "(%s) expected resource fork length 3, got: %" PRIu64,
2526                                __location__, rfork_len);
2527                 ret = false;
2528                 goto done;
2529         }
2530
2531         memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2532         type_creator_buf[8] = 0;
2533         if (strcmp(type_creator, type_creator_buf) != 0) {
2534                 torture_result(tctx, TORTURE_FAIL,
2535                                "(%s) expected type/creator \"%s\" , got: %s",
2536                                __location__, type_creator, type_creator_buf);
2537                 ret = false;
2538                 goto done;
2539         }
2540
2541 done:
2542         smb2_util_unlink(tree, fname);
2543         smb2_deltree(tree, BASEDIR);
2544         talloc_free(mem_ctx);
2545         return ret;
2546 }
2547
2548 static uint64_t patt_hash(uint64_t off)
2549 {
2550         return off;
2551 }
2552
2553 static bool write_pattern(struct torture_context *torture,
2554                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2555                           struct smb2_handle h, uint64_t off, uint64_t len,
2556                           uint64_t patt_off)
2557 {
2558         NTSTATUS status;
2559         uint64_t i;
2560         uint8_t *buf;
2561         uint64_t io_sz = MIN(1024 * 64, len);
2562
2563         if (len == 0) {
2564                 return true;
2565         }
2566
2567         torture_assert(torture, (len % 8) == 0, "invalid write len");
2568
2569         buf = talloc_zero_size(mem_ctx, io_sz);
2570         torture_assert(torture, (buf != NULL), "no memory for file data buf");
2571
2572         while (len > 0) {
2573                 for (i = 0; i <= io_sz - 8; i += 8) {
2574                         SBVAL(buf, i, patt_hash(patt_off));
2575                         patt_off += 8;
2576                 }
2577
2578                 status = smb2_util_write(tree, h,
2579                                          buf, off, io_sz);
2580                 torture_assert_ntstatus_ok(torture, status, "file write");
2581
2582                 len -= io_sz;
2583                 off += io_sz;
2584         }
2585
2586         talloc_free(buf);
2587
2588         return true;
2589 }
2590
2591 static bool check_pattern(struct torture_context *torture,
2592                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2593                           struct smb2_handle h, uint64_t off, uint64_t len,
2594                           uint64_t patt_off)
2595 {
2596         if (len == 0) {
2597                 return true;
2598         }
2599
2600         torture_assert(torture, (len % 8) == 0, "invalid read len");
2601
2602         while (len > 0) {
2603                 uint64_t i;
2604                 struct smb2_read r;
2605                 NTSTATUS status;
2606                 uint64_t io_sz = MIN(1024 * 64, len);
2607
2608                 ZERO_STRUCT(r);
2609                 r.in.file.handle = h;
2610                 r.in.length      = io_sz;
2611                 r.in.offset      = off;
2612                 status = smb2_read(tree, mem_ctx, &r);
2613                 torture_assert_ntstatus_ok(torture, status, "read");
2614
2615                 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2616                                          "read data len mismatch");
2617
2618                 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2619                         uint64_t data = BVAL(r.out.data.data, i);
2620                         torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2621                                                  talloc_asprintf(torture, "read data "
2622                                                                  "pattern bad at %llu\n",
2623                                                                  (unsigned long long)off + i));
2624                 }
2625                 talloc_free(r.out.data.data);
2626                 len -= io_sz;
2627                 off += io_sz;
2628         }
2629
2630         return true;
2631 }
2632
2633 static bool test_setup_open(struct torture_context *torture,
2634                             struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2635                             const char *fname,
2636                             struct smb2_handle *fh,
2637                             uint32_t desired_access,
2638                             uint32_t file_attributes)
2639 {
2640         struct smb2_create io;
2641         NTSTATUS status;
2642
2643         ZERO_STRUCT(io);
2644         io.in.desired_access = desired_access;
2645         io.in.file_attributes = file_attributes;
2646         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2647         io.in.share_access =
2648                 NTCREATEX_SHARE_ACCESS_DELETE|
2649                 NTCREATEX_SHARE_ACCESS_READ|
2650                 NTCREATEX_SHARE_ACCESS_WRITE;
2651         if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2652                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2653         }
2654         io.in.fname = fname;
2655
2656         status = smb2_create(tree, mem_ctx, &io);
2657         torture_assert_ntstatus_ok(torture, status, "file create");
2658
2659         *fh = io.out.file.handle;
2660
2661         return true;
2662 }
2663
2664 static bool test_setup_create_fill(struct torture_context *torture,
2665                                    struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2666                                    const char *fname,
2667                                    struct smb2_handle *fh,
2668                                    uint64_t size,
2669                                    uint32_t desired_access,
2670                                    uint32_t file_attributes)
2671 {
2672         bool ok;
2673
2674         ok = test_setup_open(torture, tree, mem_ctx,
2675                              fname,
2676                              fh,
2677                              desired_access,
2678                              file_attributes);
2679         torture_assert(torture, ok, "file open");
2680
2681         if (size > 0) {
2682                 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2683                 torture_assert(torture, ok, "write pattern");
2684         }
2685         return true;
2686 }
2687
2688 static bool test_setup_copy_chunk(struct torture_context *torture,
2689                                   struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2690                                   uint32_t nchunks,
2691                                   const char *src_name,
2692                                   struct smb2_handle *src_h,
2693                                   uint64_t src_size,
2694                                   uint32_t src_desired_access,
2695                                   const char *dst_name,
2696                                   struct smb2_handle *dest_h,
2697                                   uint64_t dest_size,
2698                                   uint32_t dest_desired_access,
2699                                   struct srv_copychunk_copy *cc_copy,
2700                                   union smb_ioctl *io)
2701 {
2702         struct req_resume_key_rsp res_key;
2703         bool ok;
2704         NTSTATUS status;
2705         enum ndr_err_code ndr_ret;
2706
2707         ok = test_setup_create_fill(torture, tree, mem_ctx, src_name,
2708                                     src_h, src_size, src_desired_access,
2709                                     FILE_ATTRIBUTE_NORMAL);
2710         torture_assert(torture, ok, "src file create fill");
2711
2712         ok = test_setup_create_fill(torture, tree, mem_ctx, dst_name,
2713                                     dest_h, dest_size, dest_desired_access,
2714                                     FILE_ATTRIBUTE_NORMAL);
2715         torture_assert(torture, ok, "dest file create fill");
2716
2717         ZERO_STRUCTPN(io);
2718         io->smb2.level = RAW_IOCTL_SMB2;
2719         io->smb2.in.file.handle = *src_h;
2720         io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2721         /* Allow for Key + ContextLength + Context */
2722         io->smb2.in.max_response_size = 32;
2723         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2724
2725         status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2726         torture_assert_ntstatus_ok(torture, status,
2727                                    "FSCTL_SRV_REQUEST_RESUME_KEY");
2728
2729         ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2730                         (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2731
2732         torture_assert_ndr_success(torture, ndr_ret,
2733                                    "ndr_pull_req_resume_key_rsp");
2734
2735         ZERO_STRUCTPN(io);
2736         io->smb2.level = RAW_IOCTL_SMB2;
2737         io->smb2.in.file.handle = *dest_h;
2738         io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2739         io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2740         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2741
2742         ZERO_STRUCTPN(cc_copy);
2743         memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2744         cc_copy->chunk_count = nchunks;
2745         cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2746         torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2747
2748         return true;
2749 }
2750
2751
2752 static bool check_copy_chunk_rsp(struct torture_context *torture,
2753                                  struct srv_copychunk_rsp *cc_rsp,
2754                                  uint32_t ex_chunks_written,
2755                                  uint32_t ex_chunk_bytes_written,
2756                                  uint32_t ex_total_bytes_written)
2757 {
2758         torture_assert_int_equal(torture, cc_rsp->chunks_written,
2759                                  ex_chunks_written, "num chunks");
2760         torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2761                                  ex_chunk_bytes_written, "chunk bytes written");
2762         torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2763                                  ex_total_bytes_written, "chunk total bytes");
2764         return true;
2765 }
2766
2767 static bool neg_aapl_copyfile(struct torture_context *tctx,
2768                               struct smb2_tree *tree,
2769                               uint64_t flags)
2770 {
2771         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2772         const char *fname = "aapl";
2773         NTSTATUS status;
2774         struct smb2_create io;
2775         DATA_BLOB data;
2776         struct smb2_create_blob *aapl = NULL;
2777         uint32_t aapl_cmd;
2778         uint32_t aapl_reply_bitmap;
2779         uint32_t aapl_server_caps;
2780         bool ret = true;
2781
2782         ZERO_STRUCT(io);
2783         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
2784         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
2785         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2786         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2787                               NTCREATEX_SHARE_ACCESS_READ |
2788                               NTCREATEX_SHARE_ACCESS_WRITE);
2789         io.in.fname = fname;
2790
2791         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2792         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2793         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2794         SBVAL(data.data, 16, flags);
2795
2796         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2797         CHECK_STATUS(status, NT_STATUS_OK);
2798
2799         status = smb2_create(tree, tctx, &io);
2800         CHECK_STATUS(status, NT_STATUS_OK);
2801
2802         aapl = smb2_create_blob_find(&io.out.blobs,
2803                                      SMB2_CREATE_TAG_AAPL);
2804         if (aapl == NULL) {
2805                 ret = false;
2806                 goto done;
2807
2808         }
2809         if (aapl->data.length < 24) {
2810                 ret = false;
2811                 goto done;
2812         }
2813
2814         aapl_cmd = IVAL(aapl->data.data, 0);
2815         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2816                 torture_result(tctx, TORTURE_FAIL,
2817                                "(%s) unexpected cmd: %d",
2818                                __location__, (int)aapl_cmd);
2819                 ret = false;
2820                 goto done;
2821         }
2822
2823         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2824         if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2825                 torture_result(tctx, TORTURE_FAIL,
2826                                "(%s) unexpected reply_bitmap: %d",
2827                                __location__, (int)aapl_reply_bitmap);
2828                 ret = false;
2829                 goto done;
2830         }
2831
2832         aapl_server_caps = BVAL(aapl->data.data, 16);
2833         if (!(aapl_server_caps & flags)) {
2834                 torture_result(tctx, TORTURE_FAIL,
2835                                "(%s) unexpected server_caps: %d",
2836                                __location__, (int)aapl_server_caps);
2837                 ret = false;
2838                 goto done;
2839         }
2840
2841 done:
2842         status = smb2_util_close(tree, io.out.file.handle);
2843         CHECK_STATUS(status, NT_STATUS_OK);
2844
2845         smb2_util_unlink(tree, "aapl");
2846         talloc_free(mem_ctx);
2847         return ret;
2848 }
2849
2850 static bool test_copyfile(struct torture_context *torture,
2851                           struct smb2_tree *tree)
2852 {
2853         struct smb2_handle src_h;
2854         struct smb2_handle dest_h;
2855         NTSTATUS status;
2856         union smb_ioctl io;
2857         TALLOC_CTX *tmp_ctx = talloc_new(tree);
2858         struct srv_copychunk_copy cc_copy;
2859         struct srv_copychunk_rsp cc_rsp;
2860         enum ndr_err_code ndr_ret;
2861         bool ok;
2862         const char *sname = ":foo" "\xef\x80\xa2" "bar:$DATA";
2863
2864         /*
2865          * First test a copy_chunk with a 0 chunk count without having
2866          * enabled this via AAPL. The request must not fail and the
2867          * copied length in the response must be 0. This is verified
2868          * against Windows 2008r2.
2869          */
2870
2871         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2872                                    0, /* 0 chunks, copyfile semantics */
2873                                    FNAME_CC_SRC,
2874                                    &src_h, 4096, /* fill 4096 byte src file */
2875                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2876                                    FNAME_CC_DST,
2877                                    &dest_h, 0,  /* 0 byte dest file */
2878                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2879                                    &cc_copy,
2880                                    &io);
2881         if (!ok) {
2882                 torture_fail_goto(torture, done, "setup copy chunk error");
2883         }
2884
2885         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2886                                        &cc_copy,
2887                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2888         torture_assert_ndr_success(torture, ndr_ret,
2889                                    "ndr_push_srv_copychunk_copy");
2890
2891         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2892         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2893
2894         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2895                                        &cc_rsp,
2896                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2897         torture_assert_ndr_success(torture, ndr_ret,
2898                                    "ndr_pull_srv_copychunk_rsp");
2899
2900         ok = check_copy_chunk_rsp(torture, &cc_rsp,
2901                                   0,    /* chunks written */
2902                                   0,    /* chunk bytes unsuccessfully written */
2903                                   0); /* total bytes written */
2904         if (!ok) {
2905                 torture_fail_goto(torture, done, "bad copy chunk response data");
2906         }
2907
2908         /*
2909          * Now enable AAPL copyfile and test again, the file and the
2910          * stream must be copied by the server.
2911          */
2912         ok = neg_aapl_copyfile(torture, tree,
2913                                SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2914         if (!ok) {
2915                 torture_skip_goto(torture, done, "missing AAPL copyfile");
2916                 goto done;
2917         }
2918
2919         smb2_util_close(tree, src_h);
2920         smb2_util_close(tree, dest_h);
2921         smb2_util_unlink(tree, FNAME_CC_SRC);
2922         smb2_util_unlink(tree, FNAME_CC_DST);
2923
2924         ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2925         if (!ok) {
2926                 torture_fail(torture, "setup file error");
2927         }
2928         ok = write_stream(tree, __location__, torture, tmp_ctx,
2929                             FNAME_CC_SRC, AFPRESOURCE_STREAM,
2930                             10, 10, "1234567890");
2931         if (!ok) {
2932                 torture_fail(torture, "setup stream error");
2933         }
2934
2935         ok = write_stream(tree, __location__, torture, tmp_ctx,
2936                             FNAME_CC_SRC, sname,
2937                             10, 10, "abcdefghij");
2938         torture_assert_goto(torture, ok == true, ok, done, "write_stream failed\n");
2939
2940         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2941                                    0, /* 0 chunks, copyfile semantics */
2942                                    FNAME_CC_SRC,
2943                                    &src_h, 4096, /* fill 4096 byte src file */
2944                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2945                                    FNAME_CC_DST,
2946                                    &dest_h, 0,  /* 0 byte dest file */
2947                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2948                                    &cc_copy,
2949                                    &io);
2950         if (!ok) {
2951                 torture_fail_goto(torture, done, "setup copy chunk error");
2952         }
2953
2954         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2955                                        &cc_copy,
2956                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2957         torture_assert_ndr_success(torture, ndr_ret,
2958                                    "ndr_push_srv_copychunk_copy");
2959
2960         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2961         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2962
2963         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2964                                        &cc_rsp,
2965                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2966         torture_assert_ndr_success(torture, ndr_ret,
2967                                    "ndr_pull_srv_copychunk_rsp");
2968
2969         ok = check_copy_chunk_rsp(torture, &cc_rsp,
2970                                   0,    /* chunks written */
2971                                   0,    /* chunk bytes unsuccessfully written */
2972                                   4096); /* total bytes written */
2973         if (!ok) {
2974                 torture_fail_goto(torture, done, "bad copy chunk response data");
2975         }
2976
2977         ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
2978                              SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
2979         if (!ok) {
2980                 torture_fail_goto(torture, done,"open failed");
2981         }
2982         ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
2983         if (!ok) {
2984                 torture_fail_goto(torture, done, "inconsistent file data");
2985         }
2986
2987         ok = check_stream(tree, __location__, torture, tmp_ctx,
2988                             FNAME_CC_DST, AFPRESOURCE_STREAM,
2989                             0, 20, 10, 10, "1234567890");
2990         if (!ok) {
2991                 torture_fail_goto(torture, done, "inconsistent stream data");
2992         }
2993
2994         ok = check_stream(tree, __location__, torture, tmp_ctx,
2995                             FNAME_CC_DST, sname,
2996                             0, 20, 10, 10, "abcdefghij");
2997         torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
2998
2999 done:
3000         smb2_util_close(tree, src_h);
3001         smb2_util_close(tree, dest_h);
3002         smb2_util_unlink(tree, FNAME_CC_SRC);
3003         smb2_util_unlink(tree, FNAME_CC_DST);
3004         talloc_free(tmp_ctx);
3005         return true;
3006 }
3007
3008 static bool check_stream_list(struct smb2_tree *tree,
3009                               struct torture_context *tctx,
3010                               const char *fname,
3011                               int num_exp,
3012                               const char **exp,
3013                               bool is_dir)
3014 {
3015         bool ret = true;
3016         union smb_fileinfo finfo;
3017         NTSTATUS status;
3018         int i;
3019         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
3020         char **exp_sort;
3021         struct stream_struct *stream_sort;
3022         struct smb2_create create;
3023         struct smb2_handle h;
3024
3025         ZERO_STRUCT(h);
3026         torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
3027
3028         ZERO_STRUCT(create);
3029         create.in.fname = fname;
3030         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3031         create.in.desired_access = SEC_FILE_ALL;
3032         create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
3033         create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
3034         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3035         status = smb2_create(tree, tmp_ctx, &create);
3036         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
3037         h = create.out.file.handle;
3038
3039         finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
3040         finfo.generic.in.file.handle = h;
3041
3042         status = smb2_getinfo_file(tree, tctx, &finfo);
3043         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
3044
3045         smb2_util_close(tree, h);
3046
3047         torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
3048                                       ret, done, "stream count");
3049
3050         if (num_exp == 0) {
3051                 TALLOC_FREE(tmp_ctx);
3052                 goto done;
3053         }
3054
3055         exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
3056         torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
3057
3058         TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
3059
3060         stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
3061                                     finfo.stream_info.out.num_streams *
3062                                     sizeof(*stream_sort));
3063         torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
3064
3065         TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
3066
3067         for (i=0; i<num_exp; i++) {
3068                 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
3069                                 i, exp_sort[i], stream_sort[i].stream_name.s);
3070                 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
3071                                               ret, done, "stream name");
3072         }
3073
3074 done:
3075         TALLOC_FREE(tmp_ctx);
3076         return ret;
3077 }
3078
3079 /*
3080   test stream names
3081 */
3082 static bool test_stream_names(struct torture_context *tctx,
3083                               struct smb2_tree *tree)
3084 {
3085         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3086         NTSTATUS status;
3087         struct smb2_create create;
3088         struct smb2_handle h;
3089         const char *fname = BASEDIR "\\stream_names.txt";
3090         const char *sname1;
3091         bool ret;
3092         /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
3093         const char *streams[] = {
3094                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
3095                 "::$DATA"
3096         };
3097
3098         sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
3099
3100         /* clean slate ...*/
3101         smb2_util_unlink(tree, fname);
3102         smb2_deltree(tree, fname);
3103         smb2_deltree(tree, BASEDIR);
3104
3105         status = torture_smb2_testdir(tree, BASEDIR, &h);
3106         CHECK_STATUS(status, NT_STATUS_OK);
3107         smb2_util_close(tree, h);
3108
3109         ret = torture_setup_file(mem_ctx, tree, fname, false);
3110         torture_assert_goto(tctx, ret, ret, done, "torture_setup_file");
3111
3112         torture_comment(tctx, "(%s) testing stream names\n", __location__);
3113         ZERO_STRUCT(create);
3114         create.in.desired_access = SEC_FILE_WRITE_DATA;
3115         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3116         create.in.share_access =
3117                 NTCREATEX_SHARE_ACCESS_DELETE|
3118                 NTCREATEX_SHARE_ACCESS_READ|
3119                 NTCREATEX_SHARE_ACCESS_WRITE;
3120         create.in.create_disposition = NTCREATEX_DISP_CREATE;
3121         create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3122         create.in.fname = sname1;
3123
3124         status = smb2_create(tree, mem_ctx, &create);
3125         CHECK_STATUS(status, NT_STATUS_OK);
3126
3127         status = smb2_util_write(tree, create.out.file.handle, "foo", 0, 3);
3128         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3129                                         "smb2_util_write failed\n");
3130
3131         smb2_util_close(tree, create.out.file.handle);
3132
3133         ret = check_stream_list(tree, tctx, fname, 2, streams, false);
3134         CHECK_VALUE(ret, true);
3135
3136 done:
3137         status = smb2_util_unlink(tree, fname);
3138         smb2_deltree(tree, BASEDIR);
3139         talloc_free(mem_ctx);
3140
3141         return ret;
3142 }
3143
3144 /* Renaming a directory with open file, should work for OS X AAPL clients */
3145 static bool test_rename_dir_openfile(struct torture_context *torture,
3146                                      struct smb2_tree *tree)
3147 {
3148         bool ret = true;
3149         NTSTATUS status;
3150         union smb_open io;
3151         union smb_close cl;
3152         union smb_setfileinfo sinfo;
3153         struct smb2_handle d1, h1;
3154         const char *renamedir = BASEDIR "-new";
3155         bool server_is_osx = torture_setting_bool(torture, "osx", false);
3156
3157         smb2_deltree(tree, BASEDIR);
3158         smb2_util_rmdir(tree, BASEDIR);
3159         smb2_deltree(tree, renamedir);
3160
3161         ZERO_STRUCT(io.smb2);
3162         io.generic.level = RAW_OPEN_SMB2;
3163         io.smb2.in.create_flags = 0;
3164         io.smb2.in.desired_access = 0x0017019f;
3165         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
3166         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3167         io.smb2.in.share_access = 0;
3168         io.smb2.in.alloc_size = 0;
3169         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
3170         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3171         io.smb2.in.security_flags = 0;
3172         io.smb2.in.fname = BASEDIR;
3173
3174         status = smb2_create(tree, torture, &(io.smb2));
3175         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3176         d1 = io.smb2.out.file.handle;
3177
3178         ZERO_STRUCT(io.smb2);
3179         io.generic.level = RAW_OPEN_SMB2;
3180         io.smb2.in.create_flags = 0;
3181         io.smb2.in.desired_access = 0x0017019f;
3182         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
3183         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3184         io.smb2.in.share_access = 0;
3185         io.smb2.in.alloc_size = 0;
3186         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
3187         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3188         io.smb2.in.security_flags = 0;
3189         io.smb2.in.fname = BASEDIR "\\file.txt";
3190
3191         status = smb2_create(tree, torture, &(io.smb2));
3192         torture_assert_ntstatus_ok(torture, status, "smb2_create file");
3193         h1 = io.smb2.out.file.handle;
3194
3195         if (!server_is_osx) {
3196                 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
3197
3198                 ZERO_STRUCT(sinfo);
3199                 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3200                 sinfo.rename_information.in.file.handle = d1;
3201                 sinfo.rename_information.in.overwrite = 0;
3202                 sinfo.rename_information.in.root_fid = 0;
3203                 sinfo.rename_information.in.new_name = renamedir;
3204                 status = smb2_setinfo_file(tree, &sinfo);
3205
3206                 torture_assert_ntstatus_equal(torture, status,
3207                                               NT_STATUS_ACCESS_DENIED,
3208                                               "smb2_setinfo_file");
3209         }
3210
3211         status = smb2_util_close(tree, d1);
3212         torture_assert_ntstatus_ok(torture, status, "smb2_util_close\n");
3213         ZERO_STRUCT(d1);
3214
3215         torture_comment(torture, "Enabling AAPL\n");
3216
3217         ret = enable_aapl(torture, tree);
3218         torture_assert(torture, ret == true, "enable_aapl failed");
3219
3220         torture_comment(torture, "Renaming directory with AAPL\n");
3221
3222         ZERO_STRUCT(io.smb2);
3223         io.generic.level = RAW_OPEN_SMB2;
3224         io.smb2.in.desired_access = 0x0017019f;
3225         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3226         io.smb2.in.share_access = 0;
3227         io.smb2.in.alloc_size = 0;
3228         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
3229         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3230         io.smb2.in.security_flags = 0;
3231         io.smb2.in.fname = BASEDIR;
3232
3233         status = smb2_create(tree, torture, &(io.smb2));
3234         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3235         d1 = io.smb2.out.file.handle;
3236
3237         ZERO_STRUCT(sinfo);
3238         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3239         sinfo.rename_information.in.file.handle = d1;
3240         sinfo.rename_information.in.overwrite = 0;
3241         sinfo.rename_information.in.root_fid = 0;
3242         sinfo.rename_information.in.new_name = renamedir;
3243
3244         status = smb2_setinfo_file(tree, &sinfo);
3245         torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
3246
3247         ZERO_STRUCT(cl.smb2);
3248         cl.smb2.level = RAW_CLOSE_SMB2;
3249         cl.smb2.in.file.handle = d1;
3250         status = smb2_close(tree, &(cl.smb2));
3251         torture_assert_ntstatus_ok(torture, status, "smb2_close");
3252         ZERO_STRUCT(d1);
3253
3254         cl.smb2.in.file.handle = h1;
3255         status = smb2_close(tree, &(cl.smb2));
3256         torture_assert_ntstatus_ok(torture, status, "smb2_close");
3257         ZERO_STRUCT(h1);
3258
3259         torture_comment(torture, "Cleaning up\n");
3260
3261         if (h1.data[0] || h1.data[1]) {
3262                 ZERO_STRUCT(cl.smb2);
3263                 cl.smb2.level = RAW_CLOSE_SMB2;
3264                 cl.smb2.in.file.handle = h1;
3265                 status = smb2_close(tree, &(cl.smb2));
3266         }
3267
3268         smb2_util_unlink(tree, BASEDIR "\\file.txt");
3269         smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
3270         smb2_deltree(tree, renamedir);
3271         smb2_deltree(tree, BASEDIR);
3272         return ret;
3273 }
3274
3275 static bool test_afpinfo_enoent(struct torture_context *tctx,
3276                                 struct smb2_tree *tree)
3277 {
3278         bool ret = true;
3279         NTSTATUS status;
3280         struct smb2_create create;
3281         struct smb2_handle h1;
3282         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3283         const char *fname = BASEDIR "\\file";
3284         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3285
3286         torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
3287
3288         smb2_deltree(tree, BASEDIR);
3289         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3290         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3291         smb2_util_close(tree, h1);
3292         ret = torture_setup_file(mem_ctx, tree, fname, false);
3293         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3294
3295         torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3296
3297         ZERO_STRUCT(create);
3298         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3299         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3300         create.in.fname = sname;
3301
3302         status = smb2_create(tree, mem_ctx, &create);
3303         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3304                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3305
3306 done:
3307         smb2_util_unlink(tree, fname);
3308         smb2_util_rmdir(tree, BASEDIR);
3309         return ret;
3310 }
3311
3312 static bool test_create_delete_on_close(struct torture_context *tctx,
3313                                         struct smb2_tree *tree)
3314 {
3315         bool ret = true;
3316         NTSTATUS status;
3317         struct smb2_create create;
3318         struct smb2_handle h1;
3319         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3320         const char *fname = BASEDIR "\\file";
3321         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3322         const char *type_creator = "SMB,OLE!";
3323         AfpInfo *info = NULL;
3324         const char *streams_basic[] = {
3325                 "::$DATA"
3326         };
3327         const char *streams_afpinfo[] = {
3328                 "::$DATA",
3329                 AFPINFO_STREAM
3330         };
3331
3332         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3333
3334         torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
3335
3336         smb2_deltree(tree, BASEDIR);
3337         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3338         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3339         smb2_util_close(tree, h1);
3340         ret = torture_setup_file(mem_ctx, tree, fname, false);
3341         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3342
3343         torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3344
3345         ZERO_STRUCT(create);
3346         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3347         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3348         create.in.fname = sname;
3349
3350         status = smb2_create(tree, mem_ctx, &create);
3351         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3352                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3353
3354         ZERO_STRUCT(create);
3355         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3356         create.in.desired_access = SEC_FILE_ALL;
3357         create.in.fname = sname;
3358
3359         status = smb2_create(tree, mem_ctx, &create);
3360         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3361                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3362
3363         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3364         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3365
3366         torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
3367
3368         info = torture_afpinfo_new(mem_ctx);
3369         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3370
3371         memcpy(info->afpi_FinderInfo, type_creator, 8);
3372         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3373         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3374
3375         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3376                            0, 60, 16, 8, type_creator);
3377         torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
3378
3379         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3380         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3381
3382         ZERO_STRUCT(create);
3383         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3384         create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3385         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3386         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3387         create.in.fname = sname;
3388         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3389
3390         status = smb2_create(tree, mem_ctx, &create);
3391         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3392
3393         h1 = create.out.file.handle;
3394         smb2_util_close(tree, h1);
3395
3396         ZERO_STRUCT(create);
3397         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3398         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
3399         create.in.fname = sname;
3400         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3401         status = smb2_create(tree, mem_ctx, &create);
3402         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3403                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3404
3405         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3406         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3407
3408 done:
3409         smb2_util_unlink(tree, fname);
3410         smb2_util_rmdir(tree, BASEDIR);
3411         return ret;
3412 }
3413
3414 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
3415                                          struct smb2_tree *tree)
3416 {
3417         bool ret = true;
3418         NTSTATUS status;
3419         struct smb2_create create;
3420         union smb_setfileinfo sfinfo;
3421         struct smb2_handle h1;
3422         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3423         const char *fname = BASEDIR "\\file";
3424         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3425         const char *type_creator = "SMB,OLE!";
3426         AfpInfo *info = NULL;
3427         const char *streams[] = {
3428                 AFPINFO_STREAM,
3429                 "::$DATA"
3430         };
3431         const char *streams_basic[] = {
3432                 "::$DATA"
3433         };
3434
3435         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3436
3437         torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
3438
3439         smb2_deltree(tree, BASEDIR);
3440         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3441         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3442         smb2_util_close(tree, h1);
3443         ret = torture_setup_file(mem_ctx, tree, fname, false);
3444         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3445
3446         info = torture_afpinfo_new(mem_ctx);
3447         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3448         memcpy(info->afpi_FinderInfo, type_creator, 8);
3449         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3450         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3451
3452         ZERO_STRUCT(create);
3453         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3454         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3455         create.in.fname = sname;
3456         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3457         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3458
3459         status = smb2_create(tree, mem_ctx, &create);
3460         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3461
3462         h1 = create.out.file.handle;
3463
3464         /* Delete stream via setinfo delete-on-close */
3465         ZERO_STRUCT(sfinfo);
3466         sfinfo.disposition_info.in.delete_on_close = 1;
3467         sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3468         sfinfo.generic.in.file.handle = h1;
3469         status = smb2_setinfo_file(tree, &sfinfo);
3470         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3471
3472         ret = check_stream_list(tree, tctx, fname, 2, streams, false);
3473         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3474
3475         ZERO_STRUCT(create);
3476         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3477         create.in.desired_access = SEC_FILE_ALL;
3478         create.in.fname = sname;
3479         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3480         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3481         status = smb2_create(tree, mem_ctx, &create);
3482         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_DELETE_PENDING,
3483                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3484
3485         smb2_util_close(tree, h1);
3486
3487         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3488         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3489
3490         ZERO_STRUCT(create);
3491         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3492         create.in.desired_access = SEC_FILE_ALL;
3493         create.in.fname = sname;
3494         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3495         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3496         status = smb2_create(tree, mem_ctx, &create);
3497         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3498                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3499
3500 done:
3501         smb2_util_unlink(tree, fname);
3502         smb2_util_rmdir(tree, BASEDIR);
3503         return ret;
3504 }
3505
3506 static bool test_setinfo_eof(struct torture_context *tctx,
3507                              struct smb2_tree *tree)
3508 {
3509         bool ret = true;
3510         NTSTATUS status;
3511         struct smb2_create create;
3512         union smb_setfileinfo sfinfo;
3513         struct smb2_handle h1;
3514         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3515         const char *fname = BASEDIR "\\file";
3516         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3517         const char *type_creator = "SMB,OLE!";
3518         AfpInfo *info = NULL;
3519         const char *streams_afpinfo[] = {
3520                 "::$DATA",
3521                 AFPINFO_STREAM
3522         };
3523
3524         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3525
3526         torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
3527
3528         smb2_deltree(tree, BASEDIR);
3529         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3530         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3531         smb2_util_close(tree, h1);
3532         ret = torture_setup_file(mem_ctx, tree, fname, false);
3533         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3534
3535         info = torture_afpinfo_new(mem_ctx);
3536         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3537         memcpy(info->afpi_FinderInfo, type_creator, 8);
3538         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3539         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3540
3541         ZERO_STRUCT(create);
3542         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3543         create.in.desired_access = SEC_FILE_ALL;
3544         create.in.fname = sname;
3545         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3546         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3547
3548         status = smb2_create(tree, mem_ctx, &create);
3549         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3550
3551         h1 = create.out.file.handle;
3552
3553         torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
3554
3555         /* Test setinfo end-of-file info */
3556         ZERO_STRUCT(sfinfo);
3557         sfinfo.generic.in.file.handle = h1;
3558         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3559         sfinfo.position_information.in.position = 61;
3560         status = smb2_setinfo_file(tree, &sfinfo);
3561         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
3562                                            ret, done, "set eof 61 failed");
3563
3564         torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
3565
3566         /* Truncation returns success, but has no effect */
3567         ZERO_STRUCT(sfinfo);
3568         sfinfo.generic.in.file.handle = h1;
3569         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3570         sfinfo.position_information.in.position = 1;
3571         status = smb2_setinfo_file(tree, &sfinfo);
3572         torture_assert_ntstatus_ok_goto(tctx, status,
3573                                         ret, done, "set eof 1 failed");
3574         smb2_util_close(tree, h1);
3575
3576         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3577         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3578
3579         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3580                            0, 60, 16, 8, type_creator);
3581         torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3582
3583         ZERO_STRUCT(create);
3584         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3585         create.in.desired_access = SEC_FILE_ALL;
3586         create.in.fname = sname;
3587         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3588         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3589
3590         status = smb2_create(tree, mem_ctx, &create);
3591         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3592
3593         h1 = create.out.file.handle;
3594
3595         /*
3596          * Delete stream via setinfo end-of-file info to 0, should
3597          * return success but stream MUST NOT deleted
3598          */
3599         ZERO_STRUCT(sfinfo);
3600         sfinfo.generic.in.file.handle = h1;
3601         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3602         sfinfo.position_information.in.position = 0;
3603         status = smb2_setinfo_file(tree, &sfinfo);
3604         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3605
3606         smb2_util_close(tree, h1);
3607
3608         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3609         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3610
3611         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3612                            0, 60, 16, 8, type_creator);
3613         torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3614
3615 done:
3616         smb2_util_unlink(tree, fname);
3617         smb2_util_rmdir(tree, BASEDIR);
3618         return ret;
3619 }
3620
3621 static bool test_afpinfo_all0(struct torture_context *tctx,
3622                               struct smb2_tree *tree)
3623 {
3624         bool ret = true;
3625         NTSTATUS status;
3626         struct smb2_create create;
3627         struct smb2_handle h1 = {{0}};
3628         struct smb2_handle baseh = {{0}};
3629         union smb_setfileinfo setfinfo;
3630         union smb_fileinfo getfinfo;
3631         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3632         const char *fname = BASEDIR "\\file";
3633         const char *sname = BASEDIR "\\file" AFPINFO_STREAM;
3634         const char *type_creator = "SMB,OLE!";
3635         AfpInfo *info = NULL;
3636         char *infobuf = NULL;
3637         const char *streams_basic[] = {
3638                 "::$DATA"
3639         };
3640         const char *streams_afpinfo[] = {
3641                 "::$DATA",
3642                 AFPINFO_STREAM
3643         };
3644
3645         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3646
3647         torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
3648
3649         smb2_deltree(tree, BASEDIR);
3650         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3651         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3652         smb2_util_close(tree, h1);
3653         ret = torture_setup_file(mem_ctx, tree, fname, false);
3654         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3655
3656         info = torture_afpinfo_new(mem_ctx);
3657         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3658         memcpy(info->afpi_FinderInfo, type_creator, 8);
3659         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3660         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3661
3662         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3663         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3664
3665         /* Write all 0 to AFP_AfpInfo */
3666         memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
3667         infobuf = torture_afpinfo_pack(mem_ctx, info);
3668         torture_assert_not_null_goto(tctx, infobuf, ret, done,
3669                                      "torture_afpinfo_pack failed\n");
3670
3671         ZERO_STRUCT(create);
3672         create.in.desired_access = SEC_FILE_ALL;
3673         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3674         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3675         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3676         create.in.fname = fname;
3677
3678         status = smb2_create(tree, mem_ctx, &create);
3679         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3680                                         "smb2_create failed\n");
3681         baseh = create.out.file.handle;
3682
3683         ZERO_STRUCT(create);
3684         create.in.desired_access = SEC_FILE_ALL;
3685         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3686         create.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
3687         create.in.fname = sname;
3688
3689         status = smb2_create(tree, mem_ctx, &create);
3690         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3691                                         "smb2_create failed\n");
3692         h1 = create.out.file.handle;
3693
3694         status = smb2_util_write(tree, h1, infobuf, 0, AFP_INFO_SIZE);
3695         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3696                                         "smb2_util_write failed\n");
3697
3698         /*
3699          * Get stream information on open handle, must return only default
3700          * stream, the AFP_AfpInfo stream must not be returned.
3701          */
3702
3703         ZERO_STRUCT(getfinfo);
3704         getfinfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
3705         getfinfo.generic.in.file.handle = baseh;
3706
3707         status = smb2_getinfo_file(tree, tctx, &getfinfo);
3708         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3709                                         "get stream info\n");
3710
3711         torture_assert_int_equal_goto(tctx, getfinfo.stream_info.out.num_streams,
3712                                       1, ret, done, "stream count");
3713
3714         smb2_util_close(tree, baseh);
3715         ZERO_STRUCT(baseh);
3716
3717         /*
3718          * Try to set some file-basic-info (time) on the stream. This catches
3719          * naive implementation mistakes that simply deleted the backing store
3720          * from the filesystem in the zero-out step.
3721          */
3722
3723         ZERO_STRUCT(setfinfo);
3724         unix_to_nt_time(&setfinfo.basic_info.in.write_time, time(NULL));
3725         setfinfo.basic_info.in.attrib = 0x20;
3726         setfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
3727         setfinfo.generic.in.file.handle = h1;
3728
3729         status = smb2_setinfo_file(tree, &setfinfo);
3730         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3731                                         "smb2_getinfo_file failed\n");
3732
3733         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3734         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
3735
3736         smb2_util_close(tree, h1);
3737         ZERO_STRUCT(h1);
3738
3739         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3740         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3741
3742 done:
3743         if (!smb2_util_handle_empty(h1)) {
3744                 smb2_util_close(tree, h1);
3745         }
3746         if (!smb2_util_handle_empty(baseh)) {
3747                 smb2_util_close(tree, baseh);
3748         }
3749         smb2_util_unlink(tree, fname);
3750         smb2_util_rmdir(tree, BASEDIR);
3751         return ret;
3752 }
3753
3754 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
3755                                                  struct smb2_tree *tree)
3756 {
3757         bool ret = true;
3758         NTSTATUS status;
3759         struct smb2_create create;
3760         struct smb2_handle h1;
3761         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3762         const char *fname = BASEDIR "\\file";
3763         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3764         const char *streams_basic[] = {
3765                 "::$DATA"
3766         };
3767         const char *streams_afpresource[] = {
3768                 "::$DATA",
3769                 AFPRESOURCE_STREAM
3770         };
3771
3772         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3773
3774         torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
3775
3776         smb2_deltree(tree, BASEDIR);
3777         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3778         torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
3779         smb2_util_close(tree, h1);
3780         ret = torture_setup_file(mem_ctx, tree, fname, false);
3781         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3782
3783         torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
3784
3785         ZERO_STRUCT(create);
3786         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3787         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3788         create.in.fname = sname;
3789
3790         status = smb2_create(tree, mem_ctx, &create);
3791         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3792                                            ret, done, "Got unexpected AFP_AfpResource stream");
3793
3794         ZERO_STRUCT(create);
3795         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3796         create.in.desired_access = SEC_FILE_ALL;
3797         create.in.fname = sname;
3798
3799         status = smb2_create(tree, mem_ctx, &create);
3800         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3801                                            ret, done, "Got unexpected AFP_AfpResource stream");
3802
3803         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3804         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3805
3806         torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
3807
3808         ret = write_stream(tree, __location__, tctx, mem_ctx,
3809                            fname, AFPRESOURCE_STREAM_NAME,
3810                            0, 10, "1234567890");
3811         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3812
3813         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3814                            0, 10, 0, 10, "1234567890");
3815         torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3816
3817         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3818         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3819
3820         ZERO_STRUCT(create);
3821         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3822         create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3823         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3824         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3825         create.in.fname = sname;
3826         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3827
3828         status = smb2_create(tree, mem_ctx, &create);
3829         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3830
3831         h1 = create.out.file.handle;
3832         smb2_util_close(tree, h1);
3833
3834         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3835         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3836
3837         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3838                            0, 10, 0, 10, "1234567890");
3839         torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3840
3841 done:
3842         smb2_util_unlink(tree, fname);
3843         smb2_util_rmdir(tree, BASEDIR);
3844         return ret;
3845 }
3846
3847 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
3848                                                   struct smb2_tree *tree)
3849 {
3850         bool ret = true;
3851         NTSTATUS status;
3852         struct smb2_create create;
3853         union smb_setfileinfo sfinfo;
3854         struct smb2_handle h1;
3855         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3856         const char *fname = BASEDIR "\\file";
3857         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3858         const char *streams_afpresource[] = {
3859                 "::$DATA",
3860                 AFPRESOURCE_STREAM
3861         };
3862
3863         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3864
3865         torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
3866
3867         smb2_deltree(tree, BASEDIR);
3868         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3869         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3870         smb2_util_close(tree, h1);
3871         ret = torture_setup_file(mem_ctx, tree, fname, false);
3872         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3873
3874         ret = write_stream(tree, __location__, tctx, mem_ctx,
3875                            fname, AFPRESOURCE_STREAM_NAME,
3876                            10, 10, "1234567890");
3877         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3878
3879         ZERO_STRUCT(create);
3880         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3881         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3882         create.in.fname = sname;
3883         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3884         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3885
3886         status = smb2_create(tree, mem_ctx, &create);
3887         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3888
3889         h1 = create.out.file.handle;
3890
3891         /* Try to delete stream via setinfo delete-on-close */
3892         ZERO_STRUCT(sfinfo);
3893         sfinfo.disposition_info.in.delete_on_close = 1;
3894         sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3895         sfinfo.generic.in.file.handle = h1;
3896         status = smb2_setinfo_file(tree, &sfinfo);
3897         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3898
3899         smb2_util_close(tree, h1);
3900
3901         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3902         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3903
3904         ZERO_STRUCT(create);
3905         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3906         create.in.desired_access = SEC_FILE_ALL;
3907         create.in.fname = sname;
3908         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3909         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3910         status = smb2_create(tree, mem_ctx, &create);
3911         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3912                                         "Got unexpected AFP_AfpResource stream");
3913
3914 done:
3915         smb2_util_unlink(tree, fname);
3916         smb2_util_rmdir(tree, BASEDIR);
3917         return ret;
3918 }
3919
3920 static bool test_setinfo_eof_resource(struct torture_context *tctx,
3921                                       struct smb2_tree *tree)
3922 {
3923         bool ret = true;
3924         NTSTATUS status;
3925         struct smb2_create create;
3926         union smb_setfileinfo sfinfo;
3927         union smb_fileinfo finfo;
3928         struct smb2_handle h1;
3929         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3930         const char *fname = BASEDIR "\\file";
3931         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3932         const char *streams_basic[] = {
3933                 "::$DATA"
3934         };
3935
3936         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3937
3938         torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
3939
3940         smb2_deltree(tree, BASEDIR);
3941         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3942         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3943         smb2_util_close(tree, h1);
3944         ret = torture_setup_file(mem_ctx, tree, fname, false);
3945         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3946
3947         ret = write_stream(tree, __location__, tctx, mem_ctx,
3948                            fname, AFPRESOURCE_STREAM_NAME,
3949                            10, 10, "1234567890");
3950         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3951
3952         ZERO_STRUCT(create);
3953         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3954         create.in.desired_access = SEC_FILE_ALL;
3955         create.in.fname = sname;
3956         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3957         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3958
3959         status = smb2_create(tree, mem_ctx, &create);
3960         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3961
3962         h1 = create.out.file.handle;
3963
3964         torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
3965
3966         /* Test setinfo end-of-file info */
3967         ZERO_STRUCT(sfinfo);
3968         sfinfo.generic.in.file.handle = h1;
3969         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3970         sfinfo.position_information.in.position = 1;
3971         status = smb2_setinfo_file(tree, &sfinfo);
3972         torture_assert_ntstatus_ok_goto(tctx, status,
3973                                         ret, done, "set eof 1 failed");
3974
3975         smb2_util_close(tree, h1);
3976
3977         /* Check size == 1 */
3978         ZERO_STRUCT(create);
3979         create.in.fname = sname;
3980         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3981         create.in.desired_access = SEC_FILE_ALL;
3982         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3983         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3984         status = smb2_create(tree, mem_ctx, &create);
3985         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3986
3987         h1 = create.out.file.handle;
3988
3989         ZERO_STRUCT(finfo);
3990         finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
3991         finfo.generic.in.file.handle = h1;
3992         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
3993         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
3994
3995         smb2_util_close(tree, h1);
3996
3997         torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
3998
3999         ZERO_STRUCT(create);
4000         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4001         create.in.desired_access = SEC_FILE_ALL;
4002         create.in.fname = sname;
4003         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4004         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4005
4006         status = smb2_create(tree, mem_ctx, &create);
4007         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4008
4009         h1 = create.out.file.handle;
4010
4011         /*
4012          * Delete stream via setinfo end-of-file info to 0, this
4013          * should delete the stream.
4014          */
4015         ZERO_STRUCT(sfinfo);
4016         sfinfo.generic.in.file.handle = h1;
4017         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4018         sfinfo.position_information.in.position = 0;
4019         status = smb2_setinfo_file(tree, &sfinfo);
4020         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
4021
4022         smb2_util_close(tree, h1);
4023
4024         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
4025         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4026
4027         ZERO_STRUCT(create);
4028         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4029         create.in.desired_access = SEC_FILE_ALL;
4030         create.in.fname = sname;
4031         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4032         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4033
4034         status = smb2_create(tree, mem_ctx, &create);
4035         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4036                                            ret, done, "smb2_create failed");
4037
4038 done:
4039         smb2_util_unlink(tree, fname);
4040         smb2_util_rmdir(tree, BASEDIR);
4041         return ret;
4042 }
4043
4044 /*
4045  * This tests that right after creating the AFP_AfpInfo stream,
4046  * reading from the stream returns an empty, default metadata blob of
4047  * 60 bytes.
4048  *
4049  * NOTE: against OS X SMB server this only works if the read request
4050  * is compounded with the create that created the stream, is fails
4051  * otherwise. We don't care...
4052  */
4053 static bool test_null_afpinfo(struct torture_context *tctx,
4054                               struct smb2_tree *tree)
4055 {
4056         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4057         const char *fname = "test_null_afpinfo";
4058         const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
4059         NTSTATUS status;
4060         bool ret = true;
4061         struct smb2_request *req[3];
4062         struct smb2_handle handle;
4063         struct smb2_create create;
4064         struct smb2_read read;
4065         AfpInfo *afpinfo = NULL;
4066         char *afpinfo_buf = NULL;
4067         const char *type_creator = "SMB,OLE!";
4068         struct smb2_handle handle2;
4069         struct smb2_read r;
4070
4071         torture_comment(tctx, "Checking create of AfpInfo stream\n");
4072
4073         smb2_util_unlink(tree, fname);
4074
4075         ret = torture_setup_file(mem_ctx, tree, fname, false);
4076         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
4077
4078         ZERO_STRUCT(create);
4079         create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
4080         create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
4081         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4082         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4083         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
4084         create.in.fname = sname;
4085
4086         smb2_transport_compound_start(tree->session->transport, 2);
4087
4088         req[0] = smb2_create_send(tree, &create);
4089
4090         handle.data[0] = UINT64_MAX;
4091         handle.data[1] = UINT64_MAX;
4092
4093         smb2_transport_compound_set_related(tree->session->transport, true);
4094
4095         ZERO_STRUCT(read);
4096         read.in.file.handle = handle;
4097         read.in.length = AFP_INFO_SIZE;
4098         req[1] = smb2_read_send(tree, &read);
4099
4100         status = smb2_create_recv(req[0], tree, &create);
4101         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
4102
4103         handle = create.out.file.handle;
4104
4105         status = smb2_read_recv(req[1], tree, &read);
4106         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
4107
4108         status = torture_smb2_testfile_access(tree, sname, &handle2,
4109                                               SEC_FILE_READ_DATA);
4110         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4111                                         "torture_smb2_testfile failed\n");
4112         r = (struct smb2_read) {
4113                 .in.file.handle = handle2,
4114                 .in.length      = AFP_INFO_SIZE,
4115         };
4116
4117         status = smb2_read(tree, tree, &r);
4118         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4119                                         "torture_smb2_testfile failed\n");
4120         smb2_util_close(tree, handle2);
4121
4122         afpinfo = torture_afpinfo_new(mem_ctx);
4123         torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
4124
4125         memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
4126
4127         afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
4128         torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
4129
4130         status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
4131         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
4132
4133         smb2_util_close(tree, handle);
4134
4135         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
4136                            0, 60, 16, 8, type_creator);
4137         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
4138
4139 done:
4140         smb2_util_unlink(tree, fname);
4141         talloc_free(mem_ctx);
4142         return ret;
4143 }
4144
4145 static bool test_delete_file_with_rfork(struct torture_context *tctx,
4146                                         struct smb2_tree *tree)
4147 {
4148         const char *fname = "torture_write_rfork_io";
4149         const char *rfork_content = "1234567890";
4150         NTSTATUS status;
4151         bool ret = true;
4152
4153         smb2_util_unlink(tree, fname);
4154
4155         torture_comment(tctx, "Test deleting file with resource fork\n");
4156
4157         ret = torture_setup_file(tctx, tree, fname, false);
4158         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
4159
4160         ret = write_stream(tree, __location__, tctx, tctx,
4161                            fname, AFPRESOURCE_STREAM_NAME,
4162                            10, 10, rfork_content);
4163         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
4164
4165         ret = check_stream(tree, __location__, tctx, tctx,
4166                            fname, AFPRESOURCE_STREAM_NAME,
4167                            0, 20, 10, 10, rfork_content);
4168         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
4169
4170         status = smb2_util_unlink(tree, fname);
4171         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
4172
4173 done:
4174         return ret;
4175 }
4176
4177 static bool test_rename_and_read_rsrc(struct torture_context *tctx,
4178                                       struct smb2_tree *tree)
4179 {
4180         bool ret = true;
4181         NTSTATUS status;
4182         struct smb2_create create, create2;
4183         struct smb2_handle h1, h2;
4184         const char *fname = "test_rename_openfile";
4185         const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
4186         const char *fname_renamed = "test_rename_openfile_renamed";
4187         const char *data = "1234567890";
4188         union smb_setfileinfo sinfo;
4189         bool server_is_macos = torture_setting_bool(tctx, "osx", false);
4190         NTSTATUS expected_status;
4191
4192         ret = enable_aapl(tctx, tree);
4193         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
4194
4195         torture_comment(tctx, "Create file with resource fork\n");
4196
4197         ret = torture_setup_file(tctx, tree, fname, false);
4198         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4199
4200         ret = write_stream(tree, __location__, tctx, tctx,
4201                            fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
4202         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4203
4204         torture_comment(tctx, "Open resource fork\n");
4205
4206         ZERO_STRUCT(create);
4207         create.in.desired_access = SEC_FILE_ALL;
4208         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4209         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4210         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4211         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4212         create.in.fname = sname;
4213
4214         status = smb2_create(tree, tctx, &create);
4215         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4216
4217         h1 = create.out.file.handle;
4218
4219         torture_comment(tctx, "Rename base file\n");
4220
4221         ZERO_STRUCT(create2);
4222         create2.in.desired_access = SEC_FILE_ALL;
4223         create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4224         create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4225         create2.in.create_disposition = NTCREATEX_DISP_OPEN;
4226         create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4227         create2.in.fname = fname;
4228
4229         status = smb2_create(tree, tctx, &create2);
4230         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4231
4232         h2 = create2.out.file.handle;
4233
4234         ZERO_STRUCT(sinfo);
4235         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
4236         sinfo.rename_information.in.file.handle = h2;
4237         sinfo.rename_information.in.overwrite = 0;
4238         sinfo.rename_information.in.root_fid = 0;
4239         sinfo.rename_information.in.new_name = fname_renamed;
4240
4241         if (server_is_macos) {
4242                 expected_status = NT_STATUS_SHARING_VIOLATION;
4243         } else {
4244                 expected_status = NT_STATUS_ACCESS_DENIED;
4245         }
4246
4247         status = smb2_setinfo_file(tree, &sinfo);
4248         torture_assert_ntstatus_equal_goto(
4249                 tctx, status, expected_status, ret, done,
4250                 "smb2_setinfo_file failed");
4251
4252         smb2_util_close(tree, h2);
4253
4254         status = smb2_util_write(tree, h1, "foo", 0, 3);
4255         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4256                                         "write failed\n");
4257
4258         smb2_util_close(tree, h1);
4259
4260 done:
4261         smb2_util_unlink(tree, fname);
4262         smb2_util_unlink(tree, fname_renamed);
4263
4264         return ret;
4265 }
4266
4267 static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
4268                                            struct smb2_tree *tree)
4269 {
4270         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4271         const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
4272         const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
4273         NTSTATUS status;
4274         struct smb2_handle testdirh;
4275         bool ret = true;
4276         struct smb2_create io;
4277         AfpInfo *info;
4278         const char *type_creator = "SMB,OLE!";
4279         struct smb2_find f;
4280         unsigned int count;
4281         union smb_search_data *d;
4282         uint64_t rfork_len;
4283         int i;
4284
4285         smb2_deltree(tree, BASEDIR);
4286
4287         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
4288         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
4289         smb2_util_close(tree, testdirh);
4290
4291         torture_comment(tctx, "Enabling AAPL\n");
4292
4293         ret = enable_aapl(tctx, tree);
4294         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
4295
4296         /*
4297          * Now that Requested AAPL extensions are enabled, setup some
4298          * Mac files with metadata and resource fork
4299          */
4300
4301         torture_comment(tctx, "Preparing file\n");
4302
4303         ret = torture_setup_file(mem_ctx, tree, fname, false);
4304         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
4305
4306         info = torture_afpinfo_new(mem_ctx);
4307         torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
4308
4309         memcpy(info->afpi_FinderInfo, type_creator, 8);
4310         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
4311         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
4312
4313         ret = write_stream(tree, __location__, tctx, mem_ctx,
4314                            fname, AFPRESOURCE_STREAM_NAME,
4315                            0, 3, "foo");
4316         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4317
4318         /*
4319          * Ok, file is prepared, now call smb2/find
4320          */
4321
4322         torture_comment(tctx, "Issue find\n");
4323
4324         ZERO_STRUCT(io);
4325         io.in.desired_access = SEC_RIGHTS_DIR_READ;
4326         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
4327         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
4328         io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
4329                               NTCREATEX_SHARE_ACCESS_WRITE |
4330                               NTCREATEX_SHARE_ACCESS_DELETE);
4331         io.in.create_disposition = NTCREATEX_DISP_OPEN;
4332         io.in.fname = BASEDIR;
4333         status = smb2_create(tree, tctx, &io);
4334         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4335
4336         ZERO_STRUCT(f);
4337         f.in.file.handle        = io.out.file.handle;
4338         f.in.pattern            = "*";
4339         f.in.max_response_size  = 0x1000;
4340         f.in.level              = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
4341
4342         status = smb2_find_level(tree, tree, &f, &count, &d);
4343         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
4344
4345         status = smb2_util_close(tree, io.out.file.handle);
4346         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
4347
4348         torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
4349
4350         for (i = 0; i < count; i++) {
4351                 const char *found = d[i].id_both_directory_info.name.s;
4352
4353                 if (!strcmp(found, ".") || !strcmp(found, ".."))
4354                         continue;
4355                 if (strncmp(found, "._", 2) == 0) {
4356                         continue;
4357                 }
4358                 break;
4359         }
4360
4361         torture_assert_str_equal_goto(tctx,
4362                                       d[i].id_both_directory_info.name.s, name,
4363                                       ret, done, "bad name");
4364
4365         rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
4366         torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
4367
4368         torture_assert_mem_equal_goto(tctx, type_creator,
4369                                       d[i].id_both_directory_info.short_name_buf + 8,
4370                                       8, ret, done, "Bad FinderInfo");
4371 done:
4372         smb2_util_unlink(tree, fname);
4373         smb2_deltree(tree, BASEDIR);
4374         talloc_free(mem_ctx);
4375         return ret;
4376 }
4377
4378 static bool test_invalid_afpinfo(struct torture_context *tctx,
4379                                  struct smb2_tree *tree1,
4380                                  struct smb2_tree *tree2)
4381 {
4382         const char *fname = "filtest_invalid_afpinfo";
4383         const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
4384         struct smb2_create create;
4385         const char *streams_basic[] = {
4386                 "::$DATA"
4387         };
4388         const char *streams_afpinfo[] = {
4389                 "::$DATA",
4390                 AFPINFO_STREAM
4391         };
4392         NTSTATUS status;
4393         bool ret = true;
4394
4395         if (tree2 == NULL) {
4396                 torture_skip_goto(tctx, done, "need second share without fruit\n");
4397         }
4398
4399         torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
4400
4401         ret = torture_setup_file(tctx, tree2, fname, false);
4402         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4403
4404         ret = write_stream(tree2, __location__, tctx, tctx,
4405                            fname, AFPINFO_STREAM_NAME,
4406                            0, 3, "foo");
4407         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4408
4409         ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
4410         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4411
4412         torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
4413
4414         ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
4415         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4416
4417         torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
4418
4419         ZERO_STRUCT(create);
4420         create.in.desired_access = SEC_FILE_ALL;
4421         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4422         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4423         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4424         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4425         create.in.fname = sname;
4426
4427         status = smb2_create(tree1, tctx, &create);
4428         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4429                                            ret, done, "Stream still around?");
4430
4431 done:
4432         smb2_util_unlink(tree1, fname);
4433         return ret;
4434 }
4435
4436 static bool test_zero_file_id(struct torture_context *tctx,
4437                               struct smb2_tree *tree)
4438 {
4439         const char *fname = "filtest_file_id";
4440         struct smb2_create create = {0};
4441         NTSTATUS status;
4442         bool ret = true;
4443         uint8_t zero_file_id[8] = {0};
4444
4445         torture_comment(tctx, "Testing zero file id\n");
4446
4447         ret = torture_setup_file(tctx, tree, fname, false);
4448         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4449
4450         ZERO_STRUCT(create);
4451         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4452         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4453         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4454         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4455         create.in.fname = fname;
4456         create.in.query_on_disk_id = true;
4457
4458         status = smb2_create(tree, tctx, &create);
4459         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
4460                                            done,
4461                                            "test file could not be opened");
4462         torture_assert_mem_not_equal_goto(tctx, create.out.on_disk_id,
4463                                           zero_file_id, 8, ret, done,
4464                                           "unexpected zero file id");
4465
4466         smb2_util_close(tree, create.out.file.handle);
4467
4468         ret = enable_aapl(tctx, tree);
4469         torture_assert(tctx, ret == true, "enable_aapl failed");
4470
4471         ZERO_STRUCT(create);
4472         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4473         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4474         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4475         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4476         create.in.fname = fname;
4477         create.in.query_on_disk_id = true;
4478
4479         status = smb2_create(tree, tctx, &create);
4480         torture_assert_ntstatus_equal_goto(
4481             tctx, status, NT_STATUS_OK, ret, done,
4482             "test file could not be opened with AAPL");
4483         torture_assert_mem_equal_goto(tctx, create.out.on_disk_id, zero_file_id,
4484                                       8, ret, done, "non-zero file id");
4485
4486         smb2_util_close(tree, create.out.file.handle);
4487
4488 done:
4489         smb2_util_unlink(tree, fname);
4490         return ret;
4491 }
4492
4493 static bool copy_one_stream(struct torture_context *torture,
4494                             struct smb2_tree *tree,
4495                             TALLOC_CTX *tmp_ctx,
4496                             const char *src_sname,
4497                             const char *dst_sname)
4498 {
4499         struct smb2_handle src_h = {{0}};
4500         struct smb2_handle dest_h = {{0}};
4501         NTSTATUS status;
4502         union smb_ioctl io;
4503         struct srv_copychunk_copy cc_copy;
4504         struct srv_copychunk_rsp cc_rsp;
4505         enum ndr_err_code ndr_ret;
4506         bool ok = false;
4507
4508         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4509                                    1, /* 1 chunk */
4510                                    src_sname,
4511                                    &src_h, 256, /* fill 256 byte src file */
4512                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4513                                    dst_sname,
4514                                    &dest_h, 0,  /* 0 byte dest file */
4515                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4516                                    &cc_copy,
4517                                    &io);
4518         torture_assert_goto(torture, ok == true, ok, done,
4519                             "setup copy chunk error\n");
4520
4521         /* copy all src file data (via a single chunk desc) */
4522         cc_copy.chunks[0].source_off = 0;
4523         cc_copy.chunks[0].target_off = 0;
4524         cc_copy.chunks[0].length = 256;
4525
4526         ndr_ret = ndr_push_struct_blob(
4527                 &io.smb2.in.out, tmp_ctx, &cc_copy,
4528                 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4529
4530         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4531                                    "ndr_push_srv_copychunk_copy\n");
4532
4533         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4534         torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4535                                         "FSCTL_SRV_COPYCHUNK\n");
4536
4537         ndr_ret = ndr_pull_struct_blob(
4538                 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4539                 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4540
4541         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4542                                    "ndr_pull_srv_copychunk_rsp\n");
4543
4544         ok = check_copy_chunk_rsp(torture, &cc_rsp,
4545                                   1,    /* chunks written */
4546                                   0,    /* chunk bytes unsuccessfully written */
4547                                   256); /* total bytes written */
4548         torture_assert_goto(torture, ok == true, ok, done,
4549                             "bad copy chunk response data\n");
4550
4551         ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
4552         if (!ok) {
4553                 torture_fail(torture, "inconsistent file data\n");
4554         }
4555
4556 done:
4557         if (!smb2_util_handle_empty(src_h)) {
4558                 smb2_util_close(tree, src_h);
4559         }
4560         if (!smb2_util_handle_empty(dest_h)) {
4561                 smb2_util_close(tree, dest_h);
4562         }
4563
4564         return ok;
4565 }
4566
4567 static bool copy_finderinfo_stream(struct torture_context *torture,
4568                                    struct smb2_tree *tree,
4569                                    TALLOC_CTX *tmp_ctx,
4570                                    const char *src_name,
4571                                    const char *dst_name)
4572 {
4573         struct smb2_handle src_h = {{0}};
4574         struct smb2_handle dest_h = {{0}};
4575         NTSTATUS status;
4576         union smb_ioctl io;
4577         struct srv_copychunk_copy cc_copy;
4578         struct srv_copychunk_rsp cc_rsp;
4579         enum ndr_err_code ndr_ret;
4580         const char *type_creator = "SMB,OLE!";
4581         AfpInfo *info = NULL;
4582         const char *src_name_afpinfo = NULL;
4583         const char *dst_name_afpinfo = NULL;
4584         bool ok = false;
4585
4586         src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
4587                                            AFPINFO_STREAM);
4588         torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
4589                                      "talloc_asprintf failed\n");
4590
4591         dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
4592                                            AFPINFO_STREAM);
4593         torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
4594                                      "talloc_asprintf failed\n");
4595
4596         info = torture_afpinfo_new(tmp_ctx);
4597         torture_assert_not_null_goto(torture, info, ok, done,
4598                                      "torture_afpinfo_new failed\n");
4599
4600         memcpy(info->afpi_FinderInfo, type_creator, 8);
4601         ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
4602         torture_assert_goto(torture, ok == true, ok, done,
4603                             "torture_write_afpinfo failed\n");
4604
4605         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4606                                    1, /* 1 chunk */
4607                                    src_name_afpinfo,
4608                                    &src_h, 0,
4609                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4610                                    dst_name_afpinfo,
4611                                    &dest_h, 0,
4612                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4613                                    &cc_copy,
4614                                    &io);
4615         torture_assert_goto(torture, ok == true, ok, done,
4616                             "setup copy chunk error\n");
4617
4618         /* copy all src file data (via a single chunk desc) */
4619         cc_copy.chunks[0].source_off = 0;
4620         cc_copy.chunks[0].target_off = 0;
4621         cc_copy.chunks[0].length = 60;
4622
4623         ndr_ret = ndr_push_struct_blob(
4624                 &io.smb2.in.out, tmp_ctx, &cc_copy,
4625                 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4626
4627         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4628                                    "ndr_push_srv_copychunk_copy\n");
4629
4630         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4631         torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4632                                         "FSCTL_SRV_COPYCHUNK\n");
4633
4634         ndr_ret = ndr_pull_struct_blob(
4635                 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4636                 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4637
4638         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4639                                    "ndr_pull_srv_copychunk_rsp\n");
4640
4641         smb2_util_close(tree, src_h);
4642         ZERO_STRUCT(src_h);
4643         smb2_util_close(tree, dest_h);
4644         ZERO_STRUCT(dest_h);
4645
4646         ok = check_copy_chunk_rsp(torture, &cc_rsp,
4647                                   1,    /* chunks written */
4648                                   0,    /* chunk bytes unsuccessfully written */
4649                                   60); /* total bytes written */
4650         torture_assert_goto(torture, ok == true, ok, done,
4651                             "bad copy chunk response data\n");
4652
4653         ok = check_stream(tree, __location__, torture, tmp_ctx,
4654                           dst_name, AFPINFO_STREAM,
4655                           0, 60, 16, 8, type_creator);
4656         torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
4657
4658 done:
4659         if (!smb2_util_handle_empty(src_h)) {
4660                 smb2_util_close(tree, src_h);
4661         }
4662         if (!smb2_util_handle_empty(dest_h)) {
4663                 smb2_util_close(tree, dest_h);
4664         }
4665
4666         return ok;
4667 }
4668
4669 static bool test_copy_chunk_streams(struct torture_context *torture,
4670                                     struct smb2_tree *tree)
4671 {
4672         const char *src_name = "src";
4673         const char *dst_name = "dst";
4674         struct names {
4675                 const char *src_sname;
4676                 const char *dst_sname;
4677         } names[] = {
4678                 { "src:foo", "dst:foo" },
4679                 { "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
4680         };
4681         int i;
4682         TALLOC_CTX *tmp_ctx = NULL;
4683         bool ok = false;
4684
4685         tmp_ctx = talloc_new(tree);
4686         torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
4687                                      "torture_setup_file\n");
4688
4689         smb2_util_unlink(tree, src_name);
4690         smb2_util_unlink(tree, dst_name);
4691
4692         ok = torture_setup_file(torture, tree, src_name, false);
4693         torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4694         ok = torture_setup_file(torture, tree, dst_name, false);
4695         torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4696
4697         for (i = 0; i < ARRAY_SIZE(names); i++) {
4698                 ok = copy_one_stream(torture, tree, tmp_ctx,
4699                                      names[i].src_sname,
4700                                      names[i].dst_sname);
4701                 torture_assert_goto(torture, ok == true, ok, done,
4702                                     "copy_one_stream failed\n");
4703         }
4704
4705         ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
4706                                     src_name, dst_name);
4707         torture_assert_goto(torture, ok == true, ok, done,
4708                             "copy_finderinfo_stream failed\n");
4709
4710 done:
4711         smb2_util_unlink(tree, src_name);
4712         smb2_util_unlink(tree, dst_name);
4713         talloc_free(tmp_ctx);
4714         return ok;
4715 }
4716
4717 /*
4718  * Ensure this security descriptor has exactly one mode, uid
4719  * and gid.
4720  */
4721
4722 static NTSTATUS check_nfs_sd(const struct security_descriptor *psd)
4723 {
4724         uint32_t i;
4725         bool got_one_mode = false;
4726         bool got_one_uid = false;
4727         bool got_one_gid = false;
4728
4729         if (psd->dacl == NULL) {
4730                 return NT_STATUS_INVALID_SECURITY_DESCR;
4731         }
4732
4733         for (i = 0; i < psd->dacl->num_aces; i++) {
4734                 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Mode,
4735                                            &psd->dacl->aces[i].trustee) == 0) {
4736                         if (got_one_mode == true) {
4737                                 /* Can't have more than one. */
4738                                 return NT_STATUS_INVALID_SECURITY_DESCR;
4739                         }
4740                         got_one_mode = true;
4741                 }
4742         }
4743         for (i = 0; i < psd->dacl->num_aces; i++) {
4744                 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Users,
4745                                            &psd->dacl->aces[i].trustee) == 0) {
4746                         if (got_one_uid == true) {
4747                                 /* Can't have more than one. */
4748                                 return NT_STATUS_INVALID_SECURITY_DESCR;
4749                         }
4750                         got_one_uid = true;
4751                 }
4752         }
4753         for (i = 0; i < psd->dacl->num_aces; i++) {
4754                 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Groups,
4755                                            &psd->dacl->aces[i].trustee) == 0) {
4756                         if (got_one_gid == true) {
4757                                 /* Can't have more than one. */
4758                                 return NT_STATUS_INVALID_SECURITY_DESCR;
4759                         }
4760                         got_one_gid = true;
4761                 }
4762         }
4763         /* Must have at least one of each. */
4764         if (got_one_mode == false ||
4765                         got_one_uid == false ||
4766                         got_one_gid == false) {
4767                 return NT_STATUS_INVALID_SECURITY_DESCR;
4768         }
4769         return NT_STATUS_OK;
4770 }
4771
4772 static bool test_nfs_aces(struct torture_context *tctx,
4773                           struct smb2_tree *tree)
4774 {
4775         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4776         struct security_ace ace;
4777         struct dom_sid sid;
4778         const char *fname = BASEDIR "\\nfs_aces.txt";
4779         struct smb2_handle h = {{0}};
4780         union smb_fileinfo finfo2;
4781         union smb_setfileinfo set;
4782         struct security_descriptor *psd = NULL;
4783         NTSTATUS status;
4784         bool ret = true;
4785         bool is_osx = torture_setting_bool(tctx, "osx", false);
4786
4787         if (is_osx) {
4788                 torture_skip(tctx, "Test only works with Samba\n");
4789         }
4790
4791         ret = enable_aapl(tctx, tree);
4792         torture_assert(tctx, ret == true, "enable_aapl failed");
4793
4794         /* clean slate ...*/
4795         smb2_util_unlink(tree, fname);
4796         smb2_deltree(tree, fname);
4797         smb2_deltree(tree, BASEDIR);
4798
4799         status = torture_smb2_testdir(tree, BASEDIR, &h);
4800         CHECK_STATUS(status, NT_STATUS_OK);
4801         smb2_util_close(tree, h);
4802
4803         /* Create a test file. */
4804         status = torture_smb2_testfile_access(tree,
4805                                 fname,
4806                                 &h,
4807                                 SEC_STD_READ_CONTROL |
4808                                 SEC_STD_WRITE_DAC |
4809                                 SEC_RIGHTS_FILE_ALL);
4810         CHECK_STATUS(status, NT_STATUS_OK);
4811
4812         /* Get the ACL. */
4813         finfo2.query_secdesc.in.secinfo_flags =
4814                 SECINFO_OWNER |
4815                 SECINFO_GROUP |
4816                 SECINFO_DACL;
4817         finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
4818         finfo2.generic.in.file.handle = h;
4819         status = smb2_getinfo_file(tree, tctx, &finfo2);
4820         CHECK_STATUS(status, NT_STATUS_OK);
4821
4822         psd = finfo2.query_secdesc.out.sd;
4823
4824         /* Ensure we have only single mode/uid/gid NFS entries. */
4825         status = check_nfs_sd(psd);
4826         if (!NT_STATUS_IS_OK(status)) {
4827                 NDR_PRINT_DEBUG(
4828                         security_descriptor,
4829                         discard_const_p(struct security_descriptor, psd));
4830         }
4831         CHECK_STATUS(status, NT_STATUS_OK);
4832
4833         /* Add a couple of extra NFS uids and gids. */
4834         sid_compose(&sid, &global_sid_Unix_NFS_Users, 27);
4835         init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
4836         status = security_descriptor_dacl_add(psd, &ace);
4837         CHECK_STATUS(status, NT_STATUS_OK);
4838         status = security_descriptor_dacl_add(psd, &ace);
4839         CHECK_STATUS(status, NT_STATUS_OK);
4840
4841         sid_compose(&sid, &global_sid_Unix_NFS_Groups, 300);
4842         init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
4843         status = security_descriptor_dacl_add(psd, &ace);
4844         CHECK_STATUS(status, NT_STATUS_OK);
4845         status = security_descriptor_dacl_add(psd, &ace);
4846         CHECK_STATUS(status, NT_STATUS_OK);
4847
4848         /* Now set on the file handle. */
4849         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
4850         set.set_secdesc.in.file.handle = h;
4851         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
4852         set.set_secdesc.in.sd = psd;
4853         status = smb2_setinfo_file(tree, &set);
4854         CHECK_STATUS(status, NT_STATUS_OK);
4855
4856         /* Get the ACL again. */
4857         finfo2.query_secdesc.in.secinfo_flags =
4858                 SECINFO_OWNER |
4859                 SECINFO_GROUP |
4860                 SECINFO_DACL;
4861         finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
4862         finfo2.generic.in.file.handle = h;
4863         status = smb2_getinfo_file(tree, tctx, &finfo2);
4864         CHECK_STATUS(status, NT_STATUS_OK);
4865
4866         psd = finfo2.query_secdesc.out.sd;
4867
4868         /* Ensure we have only single mode/uid/gid NFS entries. */
4869         status = check_nfs_sd(psd);
4870         if (!NT_STATUS_IS_OK(status)) {
4871                 NDR_PRINT_DEBUG(
4872                         security_descriptor,
4873                         discard_const_p(struct security_descriptor, psd));
4874         }
4875         CHECK_STATUS(status, NT_STATUS_OK);
4876
4877 done:
4878         if (!smb2_util_handle_empty(h)) {
4879                 smb2_util_close(tree, h);
4880         }
4881         smb2_util_unlink(tree, fname);
4882         smb2_deltree(tree, fname);
4883         smb2_deltree(tree, BASEDIR);
4884         talloc_free(mem_ctx);
4885         return ret;
4886 }
4887
4888 static bool test_setinfo_stream_eof(struct torture_context *tctx,
4889                                     struct smb2_tree *tree)
4890 {
4891         bool ret = true;
4892         NTSTATUS status;
4893         struct smb2_create create;
4894         union smb_setfileinfo sfinfo;
4895         union smb_fileinfo finfo;
4896         struct smb2_handle h1;
4897         TALLOC_CTX *mem_ctx = talloc_new(tctx);
4898         const char *fname = BASEDIR "\\file";
4899         const char *sname = BASEDIR "\\file:foo";
4900
4901         torture_assert_goto(tctx, mem_ctx != NULL, ret, done,
4902                             "talloc_new failed\n");
4903
4904         torture_comment(tctx, "Test setting EOF on a stream\n");
4905
4906         smb2_deltree(tree, BASEDIR);
4907         status = torture_smb2_testdir(tree, BASEDIR, &h1);
4908         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4909                                         "torture_smb2_testdir\n");
4910         smb2_util_close(tree, h1);
4911
4912         status = torture_smb2_testfile(tree, fname, &h1);
4913         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4914                                         "torture_smb2_testfile failed\n");
4915         smb2_util_close(tree, h1);
4916
4917         status = torture_smb2_testfile_access(tree, sname, &h1,
4918                                               SEC_FILE_WRITE_DATA);
4919         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4920                                         "torture_smb2_testfile failed\n");
4921
4922         status = smb2_util_write(tree, h1, "1234567890", 0, 10);
4923         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4924                                         "smb2_util_write failed\n");
4925         smb2_util_close(tree, h1);
4926
4927         /*
4928          * Test setting EOF to 21
4929          */
4930
4931         torture_comment(tctx, "Setting stream EOF to 21\n");
4932
4933         status = torture_smb2_testfile_access(tree, sname, &h1,
4934                                               SEC_FILE_WRITE_DATA);
4935         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4936                                         "torture_smb2_testfile failed\n");
4937
4938         ZERO_STRUCT(sfinfo);
4939         sfinfo.generic.in.file.handle = h1;
4940         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4941         sfinfo.position_information.in.position = 21;
4942         status = smb2_setinfo_file(tree, &sfinfo);
4943         torture_assert_ntstatus_ok_goto(tctx, status,
4944                                         ret, done, "set EOF 21 failed\n");
4945
4946         smb2_util_close(tree, h1);
4947
4948         status = torture_smb2_testfile_access(tree, sname, &h1,
4949                                               SEC_FILE_WRITE_DATA);
4950         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4951                                         "torture_smb2_testfile failed\n");
4952
4953         ZERO_STRUCT(finfo);
4954         finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
4955         finfo.generic.in.file.handle = h1;
4956         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
4957         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4958                                         "smb2_getinfo_file failed");
4959
4960         smb2_util_close(tree, h1);
4961
4962         torture_assert_goto(tctx, finfo.standard_info.out.size == 21,
4963                             ret, done, "size != 21\n");
4964
4965         /*
4966          * Test setting EOF to 0
4967          */
4968
4969         torture_comment(tctx, "Setting stream EOF to 0\n");
4970
4971         status = torture_smb2_testfile_access(tree, sname, &h1,
4972                                               SEC_FILE_WRITE_DATA);
4973         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4974                                         "torture_smb2_testfile failed\n");
4975
4976         ZERO_STRUCT(sfinfo);
4977         sfinfo.generic.in.file.handle = h1;
4978         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4979         sfinfo.position_information.in.position = 0;
4980         status = smb2_setinfo_file(tree, &sfinfo);
4981         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4982                                         "set eof 0 failed\n");
4983
4984         ZERO_STRUCT(create);
4985         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4986         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4987         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4988         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4989         create.in.fname = sname;
4990
4991         status = smb2_create(tree, tctx, &create);
4992         torture_assert_ntstatus_equal_goto(
4993                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
4994                 "Unexpected status\n");
4995
4996         smb2_util_close(tree, h1);
4997
4998         ZERO_STRUCT(create);
4999         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5000         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5001         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5002         create.in.create_disposition = NTCREATEX_DISP_OPEN;
5003         create.in.fname = sname;
5004
5005         status = smb2_create(tree, tctx, &create);
5006         torture_assert_ntstatus_equal_goto(
5007                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
5008                 "Unexpected status\n");
5009
5010         status = torture_smb2_testfile_access(tree, sname, &h1,
5011                                               SEC_FILE_WRITE_DATA);
5012         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5013                                         "torture_smb2_testfile failed\n");
5014
5015         ZERO_STRUCT(finfo);
5016         finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
5017         finfo.generic.in.file.handle = h1;
5018         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
5019         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5020                                         "smb2_getinfo_file failed\n");
5021
5022         smb2_util_close(tree, h1);
5023
5024         torture_assert_goto(tctx, finfo.standard_info.out.size == 0,
5025                             ret, done, "size != 0\n");
5026
5027         /*
5028          * Test setinfo end-of-file info to 1
5029          */
5030
5031         torture_comment(tctx, "Setting stream EOF to 1\n");
5032
5033         status = torture_smb2_testfile_access(tree, sname, &h1,
5034                                               SEC_FILE_WRITE_DATA);
5035         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5036                                         "torture_smb2_testfile failed\n");
5037
5038         ZERO_STRUCT(sfinfo);
5039         sfinfo.generic.in.file.handle = h1;
5040         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5041         sfinfo.position_information.in.position = 1;
5042         status = smb2_setinfo_file(tree, &sfinfo);
5043         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5044                                         "set EOF 1 failed\n");
5045
5046         smb2_util_close(tree, h1);
5047
5048         status = torture_smb2_testfile_access(tree, sname, &h1,
5049                                               SEC_FILE_WRITE_DATA);
5050         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5051                                         "torture_smb2_testfile failed\n");
5052
5053         ZERO_STRUCT(finfo);
5054         finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
5055         finfo.generic.in.file.handle = h1;
5056         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
5057         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5058                                         "smb2_getinfo_file failed\n");
5059
5060         smb2_util_close(tree, h1);
5061
5062         torture_assert_goto(tctx, finfo.standard_info.out.size == 1,
5063                             ret, done, "size != 1\n");
5064
5065         /*
5066          * Test setting EOF to 0 with AAPL enabled, should delete stream
5067          */
5068
5069         torture_comment(tctx, "Enabling AAPL extensions\n");
5070
5071         ret = enable_aapl(tctx, tree);
5072         torture_assert(tctx, ret == true, "enable_aapl failed\n");
5073
5074         torture_comment(tctx, "Setting stream EOF to 0\n");
5075         status = torture_smb2_testfile_access(tree, sname, &h1,
5076                                               SEC_FILE_WRITE_DATA);
5077         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5078                                         "torture_smb2_testfile failed\n");
5079
5080         ZERO_STRUCT(sfinfo);
5081         sfinfo.generic.in.file.handle = h1;
5082         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5083         sfinfo.position_information.in.position = 0;
5084         status = smb2_setinfo_file(tree, &sfinfo);
5085         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5086                                         "set eof 0 failed\n");
5087
5088         ZERO_STRUCT(create);
5089         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5090         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5091         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5092         create.in.create_disposition = NTCREATEX_DISP_OPEN;
5093         create.in.fname = sname;
5094
5095         status = smb2_create(tree, tctx, &create);
5096         torture_assert_ntstatus_equal_goto(
5097                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
5098                 "Unexpected status\n");
5099
5100         smb2_util_close(tree, h1);
5101
5102         ZERO_STRUCT(create);
5103         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5104         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5105         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5106         create.in.create_disposition = NTCREATEX_DISP_OPEN;
5107         create.in.fname = sname;
5108
5109         status = smb2_create(tree, tctx, &create);
5110         torture_assert_ntstatus_equal_goto(
5111                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
5112                 "Unexpected status\n");
5113
5114         torture_comment(
5115                 tctx, "Setting main file EOF to 1 to force 0-truncate\n");
5116
5117         status = torture_smb2_testfile_access(
5118                 tree,
5119                 fname,
5120                 &h1,
5121                 SEC_FILE_WRITE_DATA);
5122         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5123                                         "torture_smb2_testfile failed\n");
5124
5125         ZERO_STRUCT(sfinfo);
5126         sfinfo.generic.in.file.handle = h1;
5127         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5128         sfinfo.position_information.in.position = 1;
5129         status = smb2_setinfo_file(tree, &sfinfo);
5130         torture_assert_ntstatus_ok_goto(
5131                 tctx,
5132                 status,
5133                 ret,
5134                 done,
5135                 "set eof 1 failed\n");
5136
5137         sfinfo.position_information.in.position = 0;
5138         status = smb2_setinfo_file(tree, &sfinfo);
5139         torture_assert_ntstatus_ok_goto(
5140                 tctx,
5141                 status,
5142                 ret,
5143                 done,
5144                 "set eof 0 failed\n");
5145
5146         smb2_util_close(tree, h1);
5147
5148         ZERO_STRUCT(create);
5149         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5150         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5151         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5152         create.in.create_disposition = NTCREATEX_DISP_OPEN;
5153         create.in.fname = fname;
5154
5155         status = smb2_create(tree, tctx, &create);
5156         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5157                                         "torture_smb2_testfile failed\n");
5158         smb2_util_close(tree, h1);
5159
5160         torture_comment(tctx, "Writing to stream after setting EOF to 0\n");
5161         status = torture_smb2_testfile_access(tree, sname, &h1,
5162                                               SEC_FILE_WRITE_DATA);
5163         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5164                                         "torture_smb2_testfile failed\n");
5165
5166         status = smb2_util_write(tree, h1, "1234567890", 0, 10);
5167         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5168                                         "smb2_util_write failed\n");
5169
5170         ZERO_STRUCT(sfinfo);
5171         sfinfo.generic.in.file.handle = h1;
5172         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5173         sfinfo.position_information.in.position = 0;
5174         status = smb2_setinfo_file(tree, &sfinfo);
5175         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5176                                         "set eof 0 failed\n");
5177
5178         status = smb2_util_write(tree, h1, "1234567890", 0, 10);
5179         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5180                                         "smb2_util_write failed\n");
5181
5182         smb2_util_close(tree, h1);
5183
5184 done:
5185         smb2_util_unlink(tree, fname);
5186         smb2_util_rmdir(tree, BASEDIR);
5187         return ret;
5188 }
5189
5190 /*
5191  * Note: This test depends on "vfs objects = catia fruit streams_xattr".  For
5192  * some tests torture must be run on the host it tests and takes an additional
5193  * argument with the local path to the share:
5194  * "--option=torture:localdir=<SHAREPATH>".
5195  *
5196  * When running against an OS X SMB server add "--option=torture:osx=true"
5197  */
5198 struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
5199 {
5200         struct torture_suite *suite = torture_suite_create(
5201                 ctx, "fruit");
5202
5203         suite->description = talloc_strdup(suite, "vfs_fruit tests");
5204
5205         torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
5206         torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
5207         torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
5208         torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
5209         torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
5210         torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
5211         torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
5212         torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
5213         torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
5214         torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
5215         torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
5216         torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
5217         torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
5218         torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
5219         torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
5220         torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
5221         torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
5222         torture_suite_add_1smb2_test(suite, "setinfo eof stream", test_setinfo_stream_eof);
5223         torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
5224         torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
5225         torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
5226         torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
5227         torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
5228         torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
5229         torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
5230         torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
5231         torture_suite_add_1smb2_test(suite, "NFS ACE entries", test_nfs_aces);
5232         torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion without embedded xattr", test_adouble_conversion_wo_xattr);
5233
5234         return suite;
5235 }
5236
5237 static bool test_stream_names_local(struct torture_context *tctx,
5238                                     struct smb2_tree *tree)
5239 {
5240         TALLOC_CTX *mem_ctx = talloc_new(tctx);
5241         NTSTATUS status;
5242         struct smb2_create create;
5243         struct smb2_handle h;
5244         const char *fname = BASEDIR "\\stream_names.txt";
5245         const char *sname1;
5246         bool ret;
5247         /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
5248         const char *streams[] = {
5249                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
5250                 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
5251                 "::$DATA"
5252         };
5253         const char *localdir = NULL;
5254
5255         localdir = torture_setting_string(tctx, "localdir", NULL);
5256         if (localdir == NULL) {
5257                 torture_skip(tctx, "Need localdir for test");
5258         }
5259
5260         sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
5261
5262         /* clean slate ...*/
5263         smb2_util_unlink(tree, fname);
5264         smb2_deltree(tree, fname);
5265         smb2_deltree(tree, BASEDIR);
5266
5267         status = torture_smb2_testdir(tree, BASEDIR, &h);
5268         CHECK_STATUS(status, NT_STATUS_OK);
5269         smb2_util_close(tree, h);
5270
5271         torture_comment(tctx, "(%s) testing stream names\n", __location__);
5272         ZERO_STRUCT(create);
5273         create.in.desired_access = SEC_FILE_WRITE_DATA;
5274         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5275         create.in.share_access =
5276                 NTCREATEX_SHARE_ACCESS_DELETE|
5277                 NTCREATEX_SHARE_ACCESS_READ|
5278                 NTCREATEX_SHARE_ACCESS_WRITE;
5279         create.in.create_disposition = NTCREATEX_DISP_CREATE;
5280         create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
5281         create.in.fname = sname1;
5282
5283         status = smb2_create(tree, mem_ctx, &create);
5284         CHECK_STATUS(status, NT_STATUS_OK);
5285
5286         status = smb2_util_write(tree, create.out.file.handle, "foo", 0, 3);
5287         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5288                                         "smb2_util_write failed\n");
5289
5290         smb2_util_close(tree, create.out.file.handle);
5291
5292         ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
5293                                         "user.DosStream.bar:baz:$DATA",
5294                                         "data", strlen("data"));
5295         CHECK_VALUE(ret, true);
5296
5297         ret = check_stream_list(tree, tctx, fname, 3, streams, false);
5298         CHECK_VALUE(ret, true);
5299
5300 done:
5301         status = smb2_util_unlink(tree, fname);
5302         smb2_deltree(tree, BASEDIR);
5303         talloc_free(mem_ctx);
5304
5305         return ret;
5306 }
5307
5308 static bool test_fruit_locking_conflict(struct torture_context *tctx,
5309                                         struct smb2_tree *tree)
5310 {
5311         TALLOC_CTX *mem_ctx;
5312         struct smb2_create create;
5313         struct smb2_handle h;
5314         struct smb2_lock lck;
5315         struct smb2_lock_element el;
5316         const char *fname = BASEDIR "\\locking_conflict.txt";
5317         NTSTATUS status;
5318         bool ret = false;
5319
5320         mem_ctx = talloc_new(tctx);
5321         torture_assert_not_null(tctx, mem_ctx, "talloc_new failed");
5322
5323         /* clean slate ...*/
5324         smb2_util_unlink(tree, fname);
5325         smb2_deltree(tree, fname);
5326         smb2_deltree(tree, BASEDIR);
5327
5328         status = torture_smb2_testdir(tree, BASEDIR, &h);
5329         CHECK_STATUS(status, NT_STATUS_OK);
5330         smb2_util_close(tree, h);
5331
5332         create = (struct smb2_create) {
5333                 .in.desired_access = SEC_RIGHTS_FILE_READ,
5334                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5335                 .in.share_access =
5336                 NTCREATEX_SHARE_ACCESS_READ|
5337                 NTCREATEX_SHARE_ACCESS_WRITE,
5338                 .in.create_disposition = NTCREATEX_DISP_CREATE,
5339                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5340                 .in.fname = fname,
5341         };
5342
5343         status = smb2_create(tree, mem_ctx, &create);
5344         CHECK_STATUS(status, NT_STATUS_OK);
5345         h = create.out.file.handle;
5346
5347         el = (struct smb2_lock_element) {
5348                 .offset = 0xfffffffffffffffc,
5349                 .length = 1,
5350                 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
5351         };
5352         lck = (struct smb2_lock) {
5353                 .in.lock_count = 1,
5354                 .in.file.handle = h,
5355                 .in.locks = &el,
5356         };
5357
5358         status = smb2_lock(tree, &lck);
5359         CHECK_STATUS(status, NT_STATUS_OK);
5360
5361         el = (struct smb2_lock_element) {
5362                 .offset = 0,
5363                 .length = 0x7fffffffffffffff,
5364                 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
5365         };
5366         status = smb2_lock(tree, &lck);
5367         CHECK_STATUS(status, NT_STATUS_OK);
5368
5369         create = (struct smb2_create) {
5370                 .in.desired_access =
5371                 SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
5372                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5373                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5374                 .in.create_disposition = NTCREATEX_DISP_OPEN,
5375                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5376                 .in.fname = fname,
5377         };
5378
5379         status = smb2_create(tree, mem_ctx, &create);
5380         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
5381
5382         {
5383                 struct smb2_close cl = {
5384                         .level = RAW_CLOSE_SMB2,
5385                         .in.file.handle = h,
5386                 };
5387                 smb2_close(tree, &cl);
5388         }
5389
5390         ret = true;
5391 done:
5392         return ret;
5393 }
5394
5395 struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
5396 {
5397         struct torture_suite *suite = torture_suite_create(
5398                 ctx, "fruit_netatalk");
5399
5400         suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
5401
5402         torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
5403         torture_suite_add_1smb2_test(suite, "stream names with locally created xattr", test_stream_names_local);
5404         torture_suite_add_1smb2_test(
5405                 suite, "locking conflict", test_fruit_locking_conflict);
5406
5407         return suite;
5408 }
5409
5410 struct torture_suite *torture_vfs_fruit_file_id(TALLOC_CTX *ctx)
5411 {
5412         struct torture_suite *suite =
5413             torture_suite_create(ctx, "fruit_file_id");
5414
5415         suite->description =
5416             talloc_strdup(suite, "vfs_fruit tests for on-disk file ID that "
5417                                  "require fruit:zero_file_id=yes");
5418
5419         torture_suite_add_1smb2_test(suite, "zero file id if AAPL negotiated",
5420                                      test_zero_file_id);
5421
5422         return suite;
5423 }
5424
5425 static bool test_timemachine_volsize(struct torture_context *tctx,
5426                                      struct smb2_tree *tree)
5427 {
5428         TALLOC_CTX *mem_ctx = talloc_new(tctx);
5429         struct smb2_handle h = {{0}};
5430         union smb_fsinfo fsinfo;
5431         NTSTATUS status;
5432         bool ok = true;
5433         const char *info_plist =
5434                 "<dict>\n"
5435                 "        <key>band-size</key>\n"
5436                 "        <integer>8192</integer>\n"
5437                 "</dict>\n";
5438
5439         smb2_deltree(tree, "test.sparsebundle");
5440
5441         ok = enable_aapl(tctx, tree);
5442         torture_assert_goto(tctx, ok, ok, done, "enable_aapl failed");
5443
5444         status = smb2_util_mkdir(tree, "test.sparsebundle");
5445         torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
5446                                         "smb2_util_mkdir\n");
5447
5448         ok = write_stream(tree, __location__, tctx, mem_ctx,
5449                           "test.sparsebundle/Info.plist", NULL,
5450                            0, strlen(info_plist), info_plist);
5451         torture_assert_goto(tctx, ok, ok, done, "write_stream failed\n");
5452
5453         status = smb2_util_mkdir(tree, "test.sparsebundle/bands");
5454         torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
5455                                         "smb2_util_mkdir\n");
5456
5457         ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/1", false);
5458         torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
5459
5460         ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/2", false);
5461         torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
5462
5463         status = smb2_util_roothandle(tree, &h);
5464         torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
5465
5466         ZERO_STRUCT(fsinfo);
5467         fsinfo.generic.level = RAW_QFS_SIZE_INFORMATION;
5468         fsinfo.generic.handle = h;
5469
5470         status = smb2_getinfo_fs(tree, tree, &fsinfo);
5471         torture_assert_ntstatus_ok(tctx, status, "smb2_getinfo_fs failed");
5472
5473         torture_comment(tctx, "sectors_per_unit: %" PRIu32"\n"
5474                         "bytes_per_sector: %" PRIu32"\n"
5475                         "total_alloc_units: %" PRIu64"\n"
5476                         "avail_alloc_units: %" PRIu64"\n",
5477                         fsinfo.size_info.out.sectors_per_unit,
5478                         fsinfo.size_info.out.bytes_per_sector,
5479                         fsinfo.size_info.out.total_alloc_units,
5480                         fsinfo.size_info.out.avail_alloc_units);
5481
5482         /*
5483          * Let me explain the numbers:
5484          *
5485          * - the share is set to "fruit:time machine max size = 32K"
5486          * - we've faked a bandsize of 8 K in the Info.plist file
5487          * - we've created two bands files
5488          * - one allocation unit is made of two sectors with 512 B each
5489          * => we've consumed 16 allocation units, there should be 16 free
5490          */
5491
5492         torture_assert_goto(tctx, fsinfo.size_info.out.sectors_per_unit == 2,
5493                             ok, done, "Bad sectors_per_unit");
5494
5495         torture_assert_goto(tctx, fsinfo.size_info.out.bytes_per_sector == 512,
5496                             ok, done, "Bad bytes_per_sector");
5497
5498         torture_assert_goto(tctx, fsinfo.size_info.out.total_alloc_units == 32,
5499                             ok, done, "Bad total_alloc_units");
5500
5501         torture_assert_goto(tctx, fsinfo.size_info.out.avail_alloc_units == 16,
5502                             ok, done, "Bad avail_alloc_units");
5503
5504 done:
5505         if (!smb2_util_handle_empty(h)) {
5506                 smb2_util_close(tree, h);
5507         }
5508         smb2_deltree(tree, "test.sparsebundle");
5509         talloc_free(mem_ctx);
5510         return ok;
5511 }
5512
5513 struct torture_suite *torture_vfs_fruit_timemachine(TALLOC_CTX *ctx)
5514 {
5515         struct torture_suite *suite = torture_suite_create(
5516                 ctx, "fruit_timemachine");
5517
5518         suite->description = talloc_strdup(
5519                 suite, "vfs_fruit tests for TimeMachine");
5520
5521         torture_suite_add_1smb2_test(suite, "Timemachine-volsize",
5522                                      test_timemachine_volsize);
5523
5524         return suite;
5525 }
5526
5527 static bool test_convert_xattr_and_empty_rfork_then_delete(
5528         struct torture_context *tctx,
5529         struct smb2_tree *tree1,
5530         struct smb2_tree *tree2)
5531 {
5532         TALLOC_CTX *mem_ctx = talloc_new(tctx);
5533         const char *fname = BASEDIR "\\test_adouble_conversion";
5534         const char *adname = BASEDIR "/._test_adouble_conversion";
5535         const char *rfork = BASEDIR "\\test_adouble_conversion" AFPRESOURCE_STREAM_NAME;
5536         NTSTATUS status;
5537         struct smb2_handle testdirh;
5538         bool ret = true;
5539         const char *streams[] = {
5540                 "::$DATA",
5541                 AFPINFO_STREAM,
5542                 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
5543                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
5544         };
5545         struct smb2_create create;
5546         struct smb2_find find;
5547         unsigned int count;
5548         union smb_search_data *d;
5549         bool delete_empty_adfiles;
5550         int expected_num_files;
5551
5552         delete_empty_adfiles = torture_setting_bool(tctx,
5553                                                     "delete_empty_adfiles",
5554                                                     false);
5555
5556         smb2_deltree(tree1, BASEDIR);
5557
5558         status = torture_smb2_testdir(tree1, BASEDIR, &testdirh);
5559         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5560                                         "torture_smb2_testdir failed\n");
5561         smb2_util_close(tree1, testdirh);
5562
5563         ret = torture_setup_file(tctx, tree1, fname, false);
5564         torture_assert_goto(tctx, ret == true, ret, done,
5565                             "torture_setup_file failed\n");
5566
5567         ret = torture_setup_file(tctx, tree1, adname, false);
5568         torture_assert_goto(tctx, ret == true, ret, done,
5569                             "torture_setup_file failed\n");
5570
5571         ret = write_stream(tree1, __location__, tctx, mem_ctx,
5572                            adname, NULL,
5573                            0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
5574         torture_assert_goto(tctx, ret == true, ret, done,
5575                             "write_stream failed\n");
5576
5577         ret = enable_aapl(tctx, tree2);
5578         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
5579
5580         /*
5581          * Issue a smb2_find(), this triggers the server-side conversion
5582          */
5583
5584         create = (struct smb2_create) {
5585                 .in.desired_access = SEC_RIGHTS_DIR_READ,
5586                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
5587                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
5588                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5589                 .in.create_disposition = NTCREATEX_DISP_OPEN,
5590                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5591                 .in.fname = BASEDIR,
5592         };
5593
5594         status = smb2_create(tree2, tctx, &create);
5595         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5596                                         "smb2_create failed\n");
5597
5598         find = (struct smb2_find) {
5599                 .in.file.handle = create.out.file.handle,
5600                 .in.pattern = "*",
5601                 .in.max_response_size = 0x1000,
5602                 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
5603         };
5604
5605         status = smb2_find_level(tree2, tree2, &find, &count, &d);
5606         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5607                                         "smb2_find_level failed\n");
5608
5609         status = smb2_util_close(tree2, create.out.file.handle);
5610         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5611                                         "smb2_util_close failed");
5612
5613         /*
5614          * Check number of streams
5615          */
5616
5617         ret = check_stream_list(tree2, tctx, fname, 4, streams, false);
5618         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
5619
5620         /*
5621          * Check Resource Fork is gone
5622          */
5623
5624         create = (struct smb2_create) {
5625                 .in.desired_access = SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
5626                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5627                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5628                 .in.create_disposition = NTCREATEX_DISP_OPEN,
5629                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5630                 .in.fname = rfork,
5631         };
5632
5633         status = smb2_create(tree2, mem_ctx, &create);
5634         torture_assert_ntstatus_equal_goto(
5635                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
5636                 ret, done, "Bad smb2_create return\n");
5637
5638         /*
5639          * Check xattr data has been migrated from the AppleDouble file to
5640          * streams.
5641          */
5642
5643         ret = check_stream(tree2, __location__, tctx, mem_ctx,
5644                            fname, AFPINFO_STREAM,
5645                            0, 60, 16, 8, "TESTSLOW");
5646         torture_assert_goto(tctx, ret == true, ret, done,
5647                             "check AFPINFO_STREAM failed\n");
5648
5649         ret = check_stream(tree2, __location__, tctx, mem_ctx,
5650                            fname, ":foo" "\xef\x80\xa2" "bar", /* foo:bar */
5651                            0, 3, 0, 3, "baz");
5652         torture_assert_goto(tctx, ret == true, ret, done,
5653                             "check foo stream failed\n");
5654
5655         /*
5656          * Now check number of files. If delete_empty_adfiles is set, the
5657          * AppleDouble files should have been deleted.
5658          */
5659
5660         create = (struct smb2_create) {
5661                 .in.desired_access = SEC_RIGHTS_DIR_READ,
5662                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
5663                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
5664                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5665                 .in.create_disposition = NTCREATEX_DISP_OPEN,
5666                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5667                 .in.fname = BASEDIR,
5668         };
5669
5670         status = smb2_create(tree2, tctx, &create);
5671         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5672                                         "smb2_create failed\n");
5673
5674         find = (struct smb2_find) {
5675                 .in.file.handle = create.out.file.handle,
5676                 .in.pattern = "*",
5677                 .in.max_response_size = 0x1000,
5678                 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
5679         };
5680
5681         status = smb2_find_level(tree2, tree2, &find, &count, &d);
5682         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5683                                         "smb2_find_level failed\n");
5684
5685         status = smb2_util_close(tree2, create.out.file.handle);
5686         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5687                                         "smb2_util_close failed");
5688
5689         if (delete_empty_adfiles) {
5690                 expected_num_files = 3;
5691         } else {
5692                 expected_num_files = 4;
5693         }
5694         torture_assert_int_equal_goto(tctx, count, expected_num_files, ret, done,
5695                                       "Wrong number of files\n");
5696
5697 done:
5698         smb2_deltree(tree1, BASEDIR);
5699         talloc_free(mem_ctx);
5700         return ret;
5701 }
5702
5703 struct torture_suite *torture_vfs_fruit_conversion(TALLOC_CTX *ctx)
5704 {
5705         struct torture_suite *suite = torture_suite_create(
5706                 ctx, "fruit_conversion");
5707
5708         suite->description = talloc_strdup(
5709                 suite, "vfs_fruit conversion tests");
5710
5711         torture_suite_add_2ns_smb2_test(
5712                 suite, "convert_xattr_and_empty_rfork_then_delete",
5713                 test_convert_xattr_and_empty_rfork_then_delete);
5714
5715         return suite;
5716 }