b788f81e78c526eaea4eed94bdbb122c2d34d7d0
[obnox/samba/samba-obnox.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
40 #define BASEDIR "vfs_fruit_dir"
41 #define FNAME_CC_SRC "testfsctl.dat"
42 #define FNAME_CC_DST "testfsctl2.dat"
43
44 #define CHECK_STATUS(status, correct) do { \
45         if (!NT_STATUS_EQUAL(status, correct)) { \
46                 torture_result(tctx, TORTURE_FAIL, \
47                     "(%s) Incorrect status %s - should be %s\n", \
48                     __location__, nt_errstr(status), nt_errstr(correct)); \
49                 ret = false; \
50                 goto done; \
51         }} while (0)
52
53 #define CHECK_VALUE(v, correct) do { \
54         if ((v) != (correct)) { \
55                 torture_result(tctx, TORTURE_FAIL, \
56                                "(%s) Incorrect value %s=%u - should be %u\n", \
57                                __location__, #v, (unsigned)v, (unsigned)correct); \
58                 ret = false; \
59                 goto done; \
60         }} while (0)
61
62 static bool check_stream_list(struct smb2_tree *tree,
63                               struct torture_context *tctx,
64                               const char *fname,
65                               int num_exp,
66                               const char **exp,
67                               bool is_dir);
68
69 static int qsort_string(char * const *s1, char * const *s2)
70 {
71         return strcmp(*s1, *s2);
72 }
73
74 static int qsort_stream(const struct stream_struct * s1, const struct stream_struct *s2)
75 {
76         return strcmp(s1->stream_name.s, s2->stream_name.s);
77 }
78
79 /*
80  * REVIEW:
81  * This is hokey, but what else can we do?
82  */
83 #if defined(HAVE_ATTROPEN) || defined(FREEBSD)
84 #define AFPINFO_EA_NETATALK "org.netatalk.Metadata"
85 #define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork"
86 #else
87 #define AFPINFO_EA_NETATALK "user.org.netatalk.Metadata"
88 #define AFPRESOURCE_EA_NETATALK "user.org.netatalk.ResourceFork"
89 #endif
90
91 /*
92 The metadata xattr char buf below contains the following attributes:
93
94 -------------------------------------------------------------------------------
95 Entry ID   : 00000008 : File Dates Info
96 Offset     : 00000162 : 354
97 Length     : 00000010 : 16
98
99 -DATE------:          : (GMT)                    : (Local)
100 create     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
101 modify     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
102 backup     : 80000000 : Unknown or Initial
103 access     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
104
105 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
106 00000000   : 1B 44 21 69 1B 44 21 69 80 00 00 00 1B 44 21 69 : .D!i.D!i.....D!i
107
108 -------------------------------------------------------------------------------
109 Entry ID   : 00000009 : Finder Info
110 Offset     : 0000007A : 122
111 Length     : 00000020 : 32
112
113 -FInfo-----:
114 Type       : 42415252 : BARR
115 Creator    : 464F4F4F : FOOO
116 isAlias    : 0
117 Invisible  : 1
118 hasBundle  : 0
119 nameLocked : 0
120 Stationery : 0
121 CustomIcon : 0
122 Reserved   : 0
123 Inited     : 0
124 NoINITS    : 0
125 Shared     : 0
126 SwitchLaunc: 0
127 Hidden Ext : 0
128 color      : 000      : none
129 isOnDesk   : 0
130 Location v : 0000     : 0
131 Location h : 0000     : 0
132 Fldr       : 0000     : ..
133
134 -FXInfo----:
135 Rsvd|IconID: 0000     : 0
136 Rsvd       : 0000     : ..
137 Rsvd       : 0000     : ..
138 Rsvd       : 0000     : ..
139 AreInvalid : 0
140 unknown bit: 0
141 unknown bit: 0
142 unknown bit: 0
143 unknown bit: 0
144 unknown bit: 0
145 unknown bit: 0
146 CustomBadge: 0
147 ObjctIsBusy: 0
148 unknown bit: 0
149 unknown bit: 0
150 unknown bit: 0
151 unknown bit: 0
152 RoutingInfo: 0
153 unknown bit: 0
154 unknown bit: 0
155 Rsvd|commnt: 0000     : 0
156 PutAway    : 00000000 : 0
157
158 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
159 00000000   : 42 41 52 52 46 4F 4F 4F 40 00 00 00 00 00 00 00 : BARRFOOO@.......
160 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
161
162 -------------------------------------------------------------------------------
163 Entry ID   : 0000000E : AFP File Info
164 Offset     : 00000172 : 370
165 Length     : 00000004 : 4
166
167 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
168 00000000   : 00 00 01 A1                                     : ....
169  */
170
171 char metadata_xattr[] = {
172         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
173         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175         0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
176         0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177         0x00, 0x08, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00,
178         0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
179         0x00, 0x7a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
180         0x00, 0x0e, 0x00, 0x00, 0x01, 0x72, 0x00, 0x00,
181         0x00, 0x04, 0x80, 0x44, 0x45, 0x56, 0x00, 0x00,
182         0x01, 0x76, 0x00, 0x00, 0x00, 0x08, 0x80, 0x49,
183         0x4e, 0x4f, 0x00, 0x00, 0x01, 0x7e, 0x00, 0x00,
184         0x00, 0x08, 0x80, 0x53, 0x59, 0x4e, 0x00, 0x00,
185         0x01, 0x86, 0x00, 0x00, 0x00, 0x08, 0x80, 0x53,
186         0x56, 0x7e, 0x00, 0x00, 0x01, 0x8e, 0x00, 0x00,
187         0x00, 0x04, 0x42, 0x41, 0x52, 0x52, 0x46, 0x4f,
188         0x4f, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
189         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216         0x00, 0x00, 0x1b, 0x44, 0x21, 0x69, 0x1b, 0x44,
217         0x21, 0x69, 0x80, 0x00, 0x00, 0x00, 0x1b, 0x44,
218         0x21, 0x69, 0x00, 0x00, 0x01, 0xa1, 0x00, 0xfd,
219         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x20,
220         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xe3,
221         0x86, 0x53, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x01,
222         0x00, 0x00
223 };
224
225 /*
226 The buf below contains the following AppleDouble encoded data:
227
228 -------------------------------------------------------------------------------
229 MagicNumber: 00051607                                        : AppleDouble
230 Version    : 00020000                                        : Version 2
231 Filler     : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
232 Num. of ent: 0002                                            : 2
233
234 -------------------------------------------------------------------------------
235 Entry ID   : 00000009 : Finder Info
236 Offset     : 00000032 : 50
237 Length     : 00000EB0 : 3760
238
239 -FInfo-----:
240 Type       : 54455354 : TEST
241 Creator    : 534C4F57 : SLOW
242 isAlias    : 0
243 Invisible  : 0
244 hasBundle  : 0
245 nameLocked : 0
246 Stationery : 0
247 CustomIcon : 0
248 Reserved   : 0
249 Inited     : 0
250 NoINITS    : 0
251 Shared     : 0
252 SwitchLaunc: 0
253 Hidden Ext : 0
254 color      : 100      : blue
255 isOnDesk   : 0
256 Location v : 0000     : 0
257 Location h : 0000     : 0
258 Fldr       : 0000     : ..
259
260 -FXInfo----:
261 Rsvd|IconID: 0000     : 0
262 Rsvd       : 0000     : ..
263 Rsvd       : 0000     : ..
264 Rsvd       : 0000     : ..
265 AreInvalid : 0
266 unknown bit: 0
267 unknown bit: 0
268 unknown bit: 0
269 unknown bit: 0
270 unknown bit: 0
271 unknown bit: 0
272 CustomBadge: 0
273 ObjctIsBusy: 0
274 unknown bit: 0
275 unknown bit: 0
276 unknown bit: 0
277 unknown bit: 0
278 RoutingInfo: 0
279 unknown bit: 0
280 unknown bit: 0
281 Rsvd|commnt: 0000     : 0
282 PutAway    : 00000000 : 0
283
284 -EA--------:
285 pad        : 0000     : ..
286 magic      : 41545452 : ATTR
287 debug_tag  : 53D4580C : 1406425100
288 total_size : 00000EE2 : 3810
289 data_start : 000000BC : 188
290 data_length: 0000005E : 94
291 reserved[0]: 00000000 : ....
292 reserved[1]: 00000000 : ....
293 reserved[2]: 00000000 : ....
294 flags      : 0000     : ..
295 num_attrs  : 0002     : 2
296 -EA ENTRY--:
297 offset     : 000000BC : 188
298 length     : 0000005B : 91
299 flags      : 0000     : ..
300 namelen    : 24       : 36
301 -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
302 00000000   : 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 61 : com.apple.metada
303 00000010   : 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 54 : ta:_kMDItemUserT
304 00000020   : 61 67 73 00                                     : ags.
305 -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
306 00000000   : 62 70 6C 69 73 74 30 30 A5 01 02 03 04 05 54 74 : bplist00......Tt
307 00000010   : 65 73 74 66 00 47 00 72 00 FC 00 6E 00 0A 00 32 : estf.G.r...n...2
308 00000020   : 56 4C 69 6C 61 0A 33 56 47 65 6C 62 0A 35 56 42 : VLila.3VGelb.5VB
309 00000030   : 6C 61 75 0A 34 08 0E 13 20 27 2E 00 00 00 00 00 : lau.4... '......
310 00000040   : 00 01 01 00 00 00 00 00 00 00 06 00 00 00 00 00 : ................
311 00000050   : 00 00 00 00 00 00 00 00 00 00 35                : ..........5
312 -EA ENTRY--:
313 offset     : 00000117 : 279
314 length     : 00000003 : 3
315 flags      : 0000     : ..
316 namelen    : 08       : 8
317 -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
318 00000000   : 66 6F 6F 3A 62 61 72 00                         : foo:bar.
319 -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
320 00000000   : 62 61 7A                                        : baz
321
322 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
323 00000000   : 54 45 53 54 53 4C 4F 57 00 08 00 00 00 00 00 00 : TESTSLOW........
324 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
325 00000020   : 00 00 41 54 54 52 53 D4 58 0C 00 00 0E E2 00 00 : ..ATTRS.X.......
326 00000030   : 00 BC 00 00 00 5E 00 00 00 00 00 00 00 00 00 00 : .....^..........
327 00000040   : 00 00 00 00 00 02 00 00 00 BC 00 00 00 5B 00 00 : .............[..
328 00000050   : 24 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 : $com.apple.metad
329 00000060   : 61 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 : ata:_kMDItemUser
330 00000070   : 54 61 67 73 00 00 00 00 01 17 00 00 00 03 00 00 : Tags............
331 00000080   : 08 66 6F 6F 3A 62 61 72 00 66 62 70 6C 69 73 74 : .foo:bar.fbplist
332 00000090   : 30 30 A5 01 02 03 04 05 54 74 65 73 74 66 00 47 : 00......Ttestf.G
333 000000A0   : 00 72 00 FC 00 6E 00 0A 00 32 56 4C 69 6C 61 0A : .r...n...2VLila.
334 000000B0   : 33 56 47 65 6C 62 0A 35 56 42 6C 61 75 0A 34 08 : 3VGelb.5VBlau.4.
335 000000C0   : 0E 13 20 27 2E 00 00 00 00 00 00 01 01 00 00 00 : .. '............
336 000000D0   : 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 : ................
337 000000E0   : 00 00 00 00 35 62 61 7A 00 00 00 00 00 00 00 00 : ....5baz........
338 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
339 ... all zeroes ...
340 00000EA0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
341
342 -------------------------------------------------------------------------------
343 Entry ID   : 00000002 : Resource Fork
344 Offset     : 00000EE2 : 3810
345 Length     : 0000011E : 286
346
347 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
348 00000000   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
349 00000010   : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo
350 00000020   : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
351 00000030   : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 :  left blank   ..
352 00000040   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
353 00000050   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
354 00000060   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
355 00000070   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
356 00000080   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
357 00000090   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
358 000000A0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
359 000000B0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
360 000000C0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
361 000000D0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
362 000000E0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
363 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
364 00000100   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
365 00000110   : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF       : ..............
366
367 It was created with:
368 $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
369 */
370 static char osx_adouble_w_xattr[] = {
371         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
372         0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
373         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
374         0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
375         0x00, 0x32, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00,
376         0x00, 0x02, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00,
377         0x01, 0x1e, 0x54, 0x45, 0x53, 0x54, 0x53, 0x4c,
378         0x4f, 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
379         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381         0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
382         0x53, 0xd4, 0x58, 0x0c, 0x00, 0x00, 0x0e, 0xe2,
383         0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5e,
384         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
386         0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5b,
387         0x00, 0x00, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
388         0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x65, 0x74,
389         0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x5f, 0x6b,
390         0x4d, 0x44, 0x49, 0x74, 0x65, 0x6d, 0x55, 0x73,
391         0x65, 0x72, 0x54, 0x61, 0x67, 0x73, 0x00, 0x00,
392         0x00, 0x00, 0x01, 0x17, 0x00, 0x00, 0x00, 0x03,
393         0x00, 0x00, 0x08, 0x66, 0x6f, 0x6f, 0x3a, 0x62,
394         0x61, 0x72, 0x00, 0x66, 0x62, 0x70, 0x6c, 0x69,
395         0x73, 0x74, 0x30, 0x30, 0xa5, 0x01, 0x02, 0x03,
396         0x04, 0x05, 0x54, 0x74, 0x65, 0x73, 0x74, 0x66,
397         0x00, 0x47, 0x00, 0x72, 0x00, 0xfc, 0x00, 0x6e,
398         0x00, 0x0a, 0x00, 0x32, 0x56, 0x4c, 0x69, 0x6c,
399         0x61, 0x0a, 0x33, 0x56, 0x47, 0x65, 0x6c, 0x62,
400         0x0a, 0x35, 0x56, 0x42, 0x6c, 0x61, 0x75, 0x0a,
401         0x34, 0x08, 0x0e, 0x13, 0x20, 0x27, 0x2e, 0x00,
402         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
403         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
404         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x62,
406         0x61, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
418         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
431         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
432         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
439         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
445         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
446         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
457         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
483         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
484         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
487         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
493         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
494         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
509         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
514         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
516         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
523         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
524         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
525         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
529         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
530         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
533         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
549         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
614         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
660         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
677         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
679         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
684         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
706         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
707         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
708         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
721         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
729         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
731         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
733         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
734         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
735         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
736         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
737         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
744         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
745         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
746         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
747         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
748         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
749         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
750         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
751         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
752         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
753         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
754         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
755         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
756         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
757         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
758         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
759         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
760         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
761         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
762         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
763         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
764         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
765         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
766         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
767         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
768         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
769         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
770         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
771         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
772         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
773         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
774         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
775         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
776         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
777         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
778         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
779         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
780         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
782         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
783         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
784         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
785         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
789         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
792         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
793         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
794         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
795         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
796         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
797         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
798         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
799         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
800         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
801         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
802         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
803         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
804         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
805         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
806         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
807         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
808         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
809         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
810         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
811         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
812         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
813         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
814         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
815         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
816         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
817         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
818         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
819         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
820         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
821         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
822         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
823         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
824         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
825         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
826         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
827         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
828         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
829         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
830         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
831         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
832         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
833         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
834         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
835         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
836         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
837         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
838         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
839         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
840         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
841         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
842         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
843         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
844         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
845         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
846         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
847         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
848         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
849         0x00, 0x1e, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72,
850         0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20,
851         0x66, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
852         0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
853         0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
854         0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
855         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
856         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
857         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
858         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
859         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
860         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
861         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
862         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
863         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
864         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
865         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
866         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
867         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
868         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
869         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
870         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
871         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
872         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
873         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
874         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
875         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
876         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
877         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
878         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
879         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
880         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
881         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
882         0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
883 };
884
885 /**
886  * talloc and intialize an AfpInfo
887  **/
888 static AfpInfo *torture_afpinfo_new(TALLOC_CTX *mem_ctx)
889 {
890         AfpInfo *info;
891
892         info = talloc_zero(mem_ctx, AfpInfo);
893         if (info == NULL) {
894                 return NULL;
895         }
896
897         info->afpi_Signature = AFP_Signature;
898         info->afpi_Version = AFP_Version;
899         info->afpi_BackupTime = AFP_BackupTime;
900
901         return info;
902 }
903
904 /**
905  * Pack AfpInfo into a talloced buffer
906  **/
907 static char *torture_afpinfo_pack(TALLOC_CTX *mem_ctx,
908                                   AfpInfo *info)
909 {
910         char *buf;
911
912         buf = talloc_array(mem_ctx, char, AFP_INFO_SIZE);
913         if (buf == NULL) {
914                 return NULL;
915         }
916
917         RSIVAL(buf, 0, info->afpi_Signature);
918         RSIVAL(buf, 4, info->afpi_Version);
919         RSIVAL(buf, 12, info->afpi_BackupTime);
920         memcpy(buf + 16, info->afpi_FinderInfo, sizeof(info->afpi_FinderInfo));
921
922         return buf;
923 }
924
925 /**
926  * Unpack AfpInfo
927  **/
928 #if 0
929 static void torture_afpinfo_unpack(AfpInfo *info, char *data)
930 {
931         info->afpi_Signature = RIVAL(data, 0);
932         info->afpi_Version = RIVAL(data, 4);
933         info->afpi_BackupTime = RIVAL(data, 12);
934         memcpy(info->afpi_FinderInfo, (const char *)data + 16,
935                sizeof(info->afpi_FinderInfo));
936 }
937 #endif
938
939 static bool torture_write_afpinfo(struct smb2_tree *tree,
940                                   struct torture_context *tctx,
941                                   TALLOC_CTX *mem_ctx,
942                                   const char *fname,
943                                   AfpInfo *info)
944 {
945         struct smb2_handle handle;
946         struct smb2_create io;
947         NTSTATUS status;
948         const char *full_name;
949         char *infobuf;
950         bool ret = true;
951
952         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, AFPINFO_STREAM_NAME);
953         if (full_name == NULL) {
954             torture_comment(tctx, "talloc_asprintf error\n");
955             return false;
956         }
957         ZERO_STRUCT(io);
958         io.in.desired_access = SEC_FILE_WRITE_DATA;
959         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
960         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
961         io.in.create_options = 0;
962         io.in.fname = full_name;
963
964         status = smb2_create(tree, mem_ctx, &io);
965         CHECK_STATUS(status, NT_STATUS_OK);
966
967         handle = io.out.file.handle;
968
969         infobuf = torture_afpinfo_pack(mem_ctx, info);
970         if (infobuf == NULL) {
971                 return false;
972         }
973
974         status = smb2_util_write(tree, handle, infobuf, 0, AFP_INFO_SIZE);
975         CHECK_STATUS(status, NT_STATUS_OK);
976
977         smb2_util_close(tree, handle);
978
979 done:
980         return ret;
981 }
982
983 /**
984  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
985  * compare against buffer 'value'
986  **/
987 static bool check_stream(struct smb2_tree *tree,
988                          const char *location,
989                          struct torture_context *tctx,
990                          TALLOC_CTX *mem_ctx,
991                          const char *fname,
992                          const char *sname,
993                          off_t read_offset,
994                          size_t read_count,
995                          off_t comp_offset,
996                          size_t comp_count,
997                          const char *value)
998 {
999         struct smb2_handle handle;
1000         struct smb2_create create;
1001         struct smb2_read r;
1002         NTSTATUS status;
1003         char *full_name;
1004         bool ret = true;
1005
1006         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1007         if (full_name == NULL) {
1008             torture_comment(tctx, "talloc_asprintf error\n");
1009             return false;
1010         }
1011         ZERO_STRUCT(create);
1012         create.in.desired_access = SEC_FILE_READ_DATA;
1013         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1014         create.in.create_disposition = NTCREATEX_DISP_OPEN;
1015         create.in.fname = full_name;
1016
1017         torture_comment(tctx, "Open stream %s\n", full_name);
1018
1019         status = smb2_create(tree, mem_ctx, &create);
1020         if (!NT_STATUS_IS_OK(status)) {
1021                 TALLOC_FREE(full_name);
1022                 if (value == NULL) {
1023                         return true;
1024                 }
1025                 torture_comment(tctx, "Unable to open stream %s\n", full_name);
1026                 return false;
1027         }
1028
1029         handle = create.out.file.handle;
1030         if (value == NULL) {
1031                 TALLOC_FREE(full_name);
1032                 smb2_util_close(tree, handle);
1033                 return true;
1034         }
1035
1036         ZERO_STRUCT(r);
1037         r.in.file.handle = handle;
1038         r.in.length      = read_count;
1039         r.in.offset      = read_offset;
1040
1041         status = smb2_read(tree, tree, &r);
1042
1043         torture_assert_ntstatus_ok_goto(
1044                 tctx, status, ret, done,
1045                 talloc_asprintf(tctx, "(%s) Failed to read %lu bytes from stream '%s'\n",
1046                                 location, (long)strlen(value), full_name));
1047
1048         torture_assert_goto(tctx, r.out.data.length == read_count, ret, done,
1049                             talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected %jd\n",
1050                                             (intmax_t)r.out.data.length, (intmax_t)read_count));
1051
1052         torture_assert_goto(
1053                 tctx, memcmp(r.out.data.data + comp_offset, value, comp_count) == 0,
1054                 ret, done,
1055                 talloc_asprintf(tctx, "(%s) Bad data in stream\n", location));
1056
1057 done:
1058         TALLOC_FREE(full_name);
1059         smb2_util_close(tree, handle);
1060         return ret;
1061 }
1062
1063 /**
1064  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1065  * compare against buffer 'value'
1066  **/
1067 static ssize_t read_stream(struct smb2_tree *tree,
1068                            const char *location,
1069                            struct torture_context *tctx,
1070                            TALLOC_CTX *mem_ctx,
1071                            const char *fname,
1072                            const char *sname,
1073                            off_t read_offset,
1074                            size_t read_count)
1075 {
1076         struct smb2_handle handle;
1077         struct smb2_create create;
1078         struct smb2_read r;
1079         NTSTATUS status;
1080         const char *full_name;
1081         bool ret = true;
1082
1083         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1084         if (full_name == NULL) {
1085             torture_comment(tctx, "talloc_asprintf error\n");
1086             return -1;
1087         }
1088         ZERO_STRUCT(create);
1089         create.in.desired_access = SEC_FILE_READ_DATA;
1090         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1091         create.in.create_disposition = NTCREATEX_DISP_OPEN;
1092         create.in.fname = full_name;
1093
1094         torture_comment(tctx, "Open stream %s\n", full_name);
1095
1096         status = smb2_create(tree, mem_ctx, &create);
1097         if (!NT_STATUS_IS_OK(status)) {
1098                 torture_comment(tctx, "Unable to open stream %s\n",
1099                                 full_name);
1100                 return -1;
1101         }
1102
1103         handle = create.out.file.handle;
1104
1105         ZERO_STRUCT(r);
1106         r.in.file.handle = handle;
1107         r.in.length      = read_count;
1108         r.in.offset      = read_offset;
1109
1110         status = smb2_read(tree, tree, &r);
1111         if (!NT_STATUS_IS_OK(status)) {
1112                 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
1113         }
1114
1115         smb2_util_close(tree, handle);
1116
1117 done:
1118         if (ret == false) {
1119                 return -1;
1120         }
1121         return r.out.data.length;
1122 }
1123
1124 /**
1125  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1126  * compare against buffer 'value'
1127  **/
1128 static bool write_stream(struct smb2_tree *tree,
1129                          const char *location,
1130                          struct torture_context *tctx,
1131                          TALLOC_CTX *mem_ctx,
1132                          const char *fname,
1133                          const char *sname,
1134                          off_t offset,
1135                          size_t size,
1136                          const char *value)
1137 {
1138         struct smb2_handle handle;
1139         struct smb2_create create;
1140         NTSTATUS status;
1141         const char *full_name;
1142
1143         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1144         if (full_name == NULL) {
1145             torture_comment(tctx, "talloc_asprintf error\n");
1146             return false;
1147         }
1148         ZERO_STRUCT(create);
1149         create.in.desired_access = SEC_FILE_WRITE_DATA;
1150         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1151         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1152         create.in.fname = full_name;
1153
1154         status = smb2_create(tree, mem_ctx, &create);
1155         if (!NT_STATUS_IS_OK(status)) {
1156                 if (value == NULL) {
1157                         return true;
1158                 } else {
1159                         torture_comment(tctx, "Unable to open stream %s\n",
1160                             full_name);
1161                         sleep(10000000);
1162                         return false;
1163                 }
1164         }
1165
1166         handle = create.out.file.handle;
1167         if (value == NULL) {
1168                 return true;
1169         }
1170
1171         status = smb2_util_write(tree, handle, value, offset, size);
1172
1173         if (!NT_STATUS_IS_OK(status)) {
1174                 torture_comment(tctx, "(%s) Failed to write %lu bytes to "
1175                     "stream '%s'\n", location, (long)size, full_name);
1176                 return false;
1177         }
1178
1179         smb2_util_close(tree, handle);
1180         return true;
1181 }
1182
1183 static bool torture_setup_local_xattr(struct torture_context *tctx,
1184                                       const char *path_option,
1185                                       const char *name,
1186                                       const char *xattr,
1187                                       const char *metadata,
1188                                       size_t size)
1189 {
1190         int ret = true;
1191         int result;
1192         const char *spath;
1193         char *path;
1194
1195         spath = torture_setting_string(tctx, path_option, NULL);
1196         if (spath == NULL) {
1197                 printf("No sharepath for option %s\n", path_option);
1198                 return false;
1199         }
1200
1201         path = talloc_asprintf(tctx, "%s/%s", spath, name);
1202
1203         result = setxattr(path, xattr, metadata, size, 0);
1204         if (result != 0) {
1205                 ret = false;
1206         }
1207
1208         TALLOC_FREE(path);
1209
1210         return ret;
1211 }
1212
1213 static bool torture_setup_local_file(struct torture_context *tctx,
1214                                      const char *path_option,
1215                                      const char *name,
1216                                      const char *buf,
1217                                      size_t size)
1218 {
1219         int fd;
1220         const char *spath;
1221         char *path;
1222         ssize_t rsize;
1223
1224         spath = torture_setting_string(tctx, path_option, NULL);
1225         if (spath == NULL) {
1226                 printf("No sharepath for option %s\n", path_option);
1227                 return false;
1228         }
1229
1230         path = talloc_asprintf(tctx, "%s/%s", spath, name);
1231         if (path == NULL) {
1232                 return false;
1233         }
1234
1235         fd = creat(path, S_IRWXU);
1236         TALLOC_FREE(path);
1237         if (fd == -1) {
1238                 return false;
1239         }
1240
1241         if ((buf == NULL) || (size == 0)) {
1242                 close(fd);
1243                 return true;
1244         }
1245
1246         rsize = write(fd, buf, size);
1247         if (rsize != size) {
1248                 return false;
1249         }
1250
1251         close(fd);
1252
1253         return true;
1254 }
1255
1256 /**
1257  * Create a file or directory
1258  **/
1259 static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree,
1260                                const char *name, bool dir)
1261 {
1262         struct smb2_create io;
1263         NTSTATUS status;
1264
1265         smb2_util_unlink(tree, name);
1266         ZERO_STRUCT(io);
1267         io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1268         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
1269         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1270         io.in.share_access =
1271                 NTCREATEX_SHARE_ACCESS_DELETE|
1272                 NTCREATEX_SHARE_ACCESS_READ|
1273                 NTCREATEX_SHARE_ACCESS_WRITE;
1274         io.in.create_options = 0;
1275         io.in.fname = name;
1276         if (dir) {
1277                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1278                 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
1279                 io.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
1280                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1281         }
1282
1283         status = smb2_create(tree, mem_ctx, &io);
1284         if (!NT_STATUS_IS_OK(status)) {
1285                 return false;
1286         }
1287
1288         status = smb2_util_close(tree, io.out.file.handle);
1289         if (!NT_STATUS_IS_OK(status)) {
1290                 return false;
1291         }
1292
1293         return true;
1294 }
1295
1296 static bool enable_aapl(struct torture_context *tctx,
1297                         struct smb2_tree *tree)
1298 {
1299         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1300         NTSTATUS status;
1301         bool ret = true;
1302         struct smb2_create io;
1303         DATA_BLOB data;
1304         struct smb2_create_blob *aapl = NULL;
1305         uint32_t aapl_server_caps;
1306         uint32_t expexted_scaps = (SMB2_CRTCTX_AAPL_UNIX_BASED |
1307                                    SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1308                                    SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1309                                    SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
1310         bool is_osx_server = torture_setting_bool(tctx, "osx", false);
1311
1312         ZERO_STRUCT(io);
1313         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
1314         io.in.file_attributes    = FILE_ATTRIBUTE_DIRECTORY;
1315         io.in.create_disposition = NTCREATEX_DISP_OPEN;
1316         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1317                               NTCREATEX_SHARE_ACCESS_READ |
1318                               NTCREATEX_SHARE_ACCESS_WRITE);
1319         io.in.fname = "";
1320
1321         /*
1322          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1323          * controls behaviour of Apple's SMB2 extensions for the whole
1324          * session!
1325          */
1326
1327         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1328         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1329         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1330                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1331                              SMB2_CRTCTX_AAPL_MODEL_INFO));
1332         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1333                               SMB2_CRTCTX_AAPL_UNIX_BASED |
1334                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1335
1336         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1337         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_blob_add");
1338
1339         status = smb2_create(tree, tctx, &io);
1340         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1341
1342         status = smb2_util_close(tree, io.out.file.handle);
1343         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close");
1344
1345         /*
1346          * Now check returned AAPL context
1347          */
1348         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1349
1350         aapl = smb2_create_blob_find(&io.out.blobs,
1351                                      SMB2_CREATE_TAG_AAPL);
1352         torture_assert_goto(tctx, aapl != NULL, ret, done, "missing AAPL context");
1353
1354         if (!is_osx_server) {
1355                 size_t exptected_aapl_ctx_size;
1356
1357                 exptected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
1358
1359                 torture_assert_goto(
1360                         tctx, aapl->data.length == exptected_aapl_ctx_size,
1361                         ret, done, "bad AAPL size");
1362         }
1363
1364         aapl_server_caps = BVAL(aapl->data.data, 16);
1365         torture_assert_goto(tctx, aapl_server_caps == expexted_scaps,
1366                             ret, done, "bad AAPL caps");
1367
1368 done:
1369         talloc_free(mem_ctx);
1370         return ret;
1371 }
1372
1373 static bool test_read_netatalk_metadata(struct torture_context *tctx,
1374                                         struct smb2_tree *tree)
1375 {
1376         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1377         const char *fname = BASEDIR "\\torture_read_metadata";
1378         NTSTATUS status;
1379         struct smb2_handle testdirh;
1380         bool ret = true;
1381         ssize_t len;
1382         const char *localdir = NULL;
1383
1384         torture_comment(tctx, "Checking metadata access\n");
1385
1386         localdir = torture_setting_string(tctx, "localdir", NULL);
1387         if (localdir == NULL) {
1388                 torture_skip(tctx, "Need localdir for test");
1389         }
1390
1391         smb2_util_unlink(tree, fname);
1392
1393         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1394         CHECK_STATUS(status, NT_STATUS_OK);
1395         smb2_util_close(tree, testdirh);
1396
1397         ret = torture_setup_file(mem_ctx, tree, fname, false);
1398         if (ret == false) {
1399                 goto done;
1400         }
1401
1402         ret = torture_setup_local_xattr(tctx, "localdir",
1403                                         BASEDIR "/torture_read_metadata",
1404                                         AFPINFO_EA_NETATALK,
1405                                         metadata_xattr, sizeof(metadata_xattr));
1406         if (ret == false) {
1407                 goto done;
1408         }
1409
1410         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1411                            0, 60, 0, 4, "AFP");
1412         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1413
1414         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1415                            0, 60, 16, 8, "BARRFOOO");
1416         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1417
1418         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1419                            16, 8, 0, 3, "AFP");
1420         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1421
1422         /* Check reading offset and read size > sizeof(AFPINFO_STREAM) */
1423
1424         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1425                           AFPINFO_STREAM, 0, 61);
1426         CHECK_VALUE(len, 60);
1427
1428         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1429                           AFPINFO_STREAM, 59, 2);
1430         CHECK_VALUE(len, 2);
1431
1432         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1433                           AFPINFO_STREAM, 60, 1);
1434         CHECK_VALUE(len, 1);
1435
1436         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1437                           AFPINFO_STREAM, 61, 1);
1438         CHECK_VALUE(len, 0);
1439
1440 done:
1441         smb2_deltree(tree, BASEDIR);
1442         talloc_free(mem_ctx);
1443         return ret;
1444 }
1445
1446 static bool test_read_afpinfo(struct torture_context *tctx,
1447                               struct smb2_tree *tree)
1448 {
1449         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1450         const char *fname = BASEDIR "\\torture_read_metadata";
1451         NTSTATUS status;
1452         struct smb2_handle testdirh;
1453         bool ret = true;
1454         ssize_t len;
1455         AfpInfo *info;
1456         const char *type_creator = "SMB,OLE!";
1457
1458         torture_comment(tctx, "Checking metadata access\n");
1459
1460         smb2_util_unlink(tree, fname);
1461
1462         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1463         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
1464         smb2_util_close(tree, testdirh);
1465
1466         ret = torture_setup_file(mem_ctx, tree, fname, false);
1467         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
1468
1469         info = torture_afpinfo_new(mem_ctx);
1470         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
1471
1472         memcpy(info->afpi_FinderInfo, type_creator, 8);
1473         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1474         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
1475
1476         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1477                            0, 60, 0, 4, "AFP");
1478         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1479
1480         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1481                            0, 60, 16, 8, type_creator);
1482         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1483
1484         /*
1485          * OS X ignores offset <= 60 and treats the as
1486          * offset=0. Reading from offsets > 60 returns EOF=0.
1487          */
1488
1489         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1490                            16, 8, 0, 8, "AFP\0\0\0\001\0");
1491         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1492
1493         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1494                           AFPINFO_STREAM, 0, 61);
1495         torture_assert_goto(tctx, len == 60, ret, done, "read_stream failed");
1496
1497         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1498                           AFPINFO_STREAM, 59, 2);
1499         torture_assert_goto(tctx, len == 2, ret, done, "read_stream failed");
1500
1501         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1502                            59, 2, 0, 2, "AF");
1503         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1504
1505         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1506                           AFPINFO_STREAM, 60, 1);
1507         torture_assert_goto(tctx, len == 1, ret, done, "read_stream failed");
1508
1509         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1510                            60, 1, 0, 1, "A");
1511         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1512
1513         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1514                           AFPINFO_STREAM, 61, 1);
1515         torture_assert_goto(tctx, len == 0, ret, done, "read_stream failed");
1516
1517 done:
1518         smb2_util_unlink(tree, fname);
1519         smb2_deltree(tree, BASEDIR);
1520         talloc_free(mem_ctx);
1521         return ret;
1522 }
1523
1524 static bool test_write_atalk_metadata(struct torture_context *tctx,
1525                                       struct smb2_tree *tree)
1526 {
1527         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1528         const char *fname = BASEDIR "\\torture_write_metadata";
1529         const char *type_creator = "SMB,OLE!";
1530         NTSTATUS status;
1531         struct smb2_handle testdirh;
1532         bool ret = true;
1533         AfpInfo *info;
1534
1535         smb2_deltree(tree, BASEDIR);
1536         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1537         CHECK_STATUS(status, NT_STATUS_OK);
1538         smb2_util_close(tree, testdirh);
1539
1540         ret = torture_setup_file(mem_ctx, tree, fname, false);
1541         if (ret == false) {
1542                 goto done;
1543         }
1544
1545         info = torture_afpinfo_new(mem_ctx);
1546         if (info == NULL) {
1547                 goto done;
1548         }
1549
1550         memcpy(info->afpi_FinderInfo, type_creator, 8);
1551         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1552         ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1553                             0, 60, 16, 8, type_creator);
1554
1555 done:
1556         smb2_util_unlink(tree, fname);
1557         smb2_deltree(tree, BASEDIR);
1558         talloc_free(mem_ctx);
1559         return ret;
1560 }
1561
1562 static bool test_write_atalk_rfork_io(struct torture_context *tctx,
1563                                       struct smb2_tree *tree)
1564 {
1565         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1566         const char *fname = BASEDIR "\\torture_write_rfork_io";
1567         const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
1568         const char *rfork_content = "1234567890";
1569         NTSTATUS status;
1570         struct smb2_handle testdirh;
1571         bool ret = true;
1572
1573         union smb_open io;
1574         struct smb2_handle filehandle;
1575         union smb_fileinfo finfo;
1576         union smb_setfileinfo sinfo;
1577
1578         smb2_util_unlink(tree, fname);
1579
1580         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1581         CHECK_STATUS(status, NT_STATUS_OK);
1582         smb2_util_close(tree, testdirh);
1583
1584         ret = torture_setup_file(mem_ctx, tree, fname, false);
1585         if (ret == false) {
1586                 goto done;
1587         }
1588
1589         torture_comment(tctx, "(%s) writing to resource fork\n",
1590             __location__);
1591
1592         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1593                             fname, AFPRESOURCE_STREAM_NAME,
1594                             10, 10, rfork_content);
1595
1596         ret &= check_stream(tree, __location__, tctx, mem_ctx,
1597                             fname, AFPRESOURCE_STREAM_NAME,
1598                             0, 20, 10, 10, rfork_content);
1599
1600         /* Check size after write */
1601
1602         ZERO_STRUCT(io);
1603         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1604         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1605                 SEC_FILE_WRITE_ATTRIBUTE;
1606         io.smb2.in.fname = rfork;
1607         status = smb2_create(tree, mem_ctx, &(io.smb2));
1608         CHECK_STATUS(status, NT_STATUS_OK);
1609         filehandle = io.smb2.out.file.handle;
1610
1611         torture_comment(tctx, "(%s) check resource fork size after write\n",
1612             __location__);
1613
1614         ZERO_STRUCT(finfo);
1615         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1616         finfo.generic.in.file.handle = filehandle;
1617         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1618         CHECK_STATUS(status, NT_STATUS_OK);
1619         if (finfo.all_info.out.size != 20) {
1620                 torture_result(tctx, TORTURE_FAIL,
1621                                "(%s) Incorrect resource fork size\n",
1622                                __location__);
1623                 ret = false;
1624                 smb2_util_close(tree, filehandle);
1625                 goto done;
1626         }
1627         smb2_util_close(tree, filehandle);
1628
1629         /* Write at large offset */
1630
1631         torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
1632                         __location__);
1633
1634         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1635                             fname, AFPRESOURCE_STREAM_NAME,
1636                             (off_t)1<<32, 10, rfork_content);
1637
1638         ret &= check_stream(tree, __location__, tctx, mem_ctx,
1639                             fname, AFPRESOURCE_STREAM_NAME,
1640                             (off_t)1<<32, 10, 0, 10, rfork_content);
1641
1642         /* Truncate back to size of 1 byte */
1643
1644         torture_comment(tctx, "(%s) truncate resource fork and check size\n",
1645                         __location__);
1646
1647         ZERO_STRUCT(io);
1648         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1649         io.smb2.in.desired_access = SEC_FILE_ALL;
1650         io.smb2.in.fname = rfork;
1651         status = smb2_create(tree, mem_ctx, &(io.smb2));
1652         CHECK_STATUS(status, NT_STATUS_OK);
1653         filehandle = io.smb2.out.file.handle;
1654
1655         ZERO_STRUCT(sinfo);
1656         sinfo.end_of_file_info.level =
1657                 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1658         sinfo.end_of_file_info.in.file.handle = filehandle;
1659         sinfo.end_of_file_info.in.size = 1;
1660         status = smb2_setinfo_file(tree, &sinfo);
1661         CHECK_STATUS(status, NT_STATUS_OK);
1662
1663         smb2_util_close(tree, filehandle);
1664
1665         /* Now check size */
1666         ZERO_STRUCT(io);
1667         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1668         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1669                 SEC_FILE_WRITE_ATTRIBUTE;
1670         io.smb2.in.fname = rfork;
1671         status = smb2_create(tree, mem_ctx, &(io.smb2));
1672         CHECK_STATUS(status, NT_STATUS_OK);
1673         filehandle = io.smb2.out.file.handle;
1674
1675         ZERO_STRUCT(finfo);
1676         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1677         finfo.generic.in.file.handle = filehandle;
1678         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1679         CHECK_STATUS(status, NT_STATUS_OK);
1680         if (finfo.all_info.out.size != 1) {
1681                 torture_result(tctx, TORTURE_FAIL,
1682                                "(%s) Incorrect resource fork size\n",
1683                                __location__);
1684                 ret = false;
1685                 smb2_util_close(tree, filehandle);
1686                 goto done;
1687         }
1688         smb2_util_close(tree, filehandle);
1689
1690 done:
1691         smb2_util_unlink(tree, fname);
1692         smb2_deltree(tree, BASEDIR);
1693         talloc_free(mem_ctx);
1694         return ret;
1695 }
1696
1697 static bool test_rfork_truncate(struct torture_context *tctx,
1698                                 struct smb2_tree *tree)
1699 {
1700         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1701         const char *fname = BASEDIR "\\torture_rfork_truncate";
1702         const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
1703         const char *rfork_content = "1234567890";
1704         NTSTATUS status;
1705         struct smb2_handle testdirh;
1706         bool ret = true;
1707         struct smb2_create create;
1708         struct smb2_handle fh1, fh2, fh3;
1709         union smb_setfileinfo sinfo;
1710
1711         smb2_util_unlink(tree, fname);
1712
1713         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1714         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1715         smb2_util_close(tree, testdirh);
1716
1717         ret = torture_setup_file(mem_ctx, tree, fname, false);
1718         if (ret == false) {
1719                 goto done;
1720         }
1721
1722         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1723                             fname, AFPRESOURCE_STREAM,
1724                             10, 10, rfork_content);
1725
1726         /* Truncate back to size 0, further access MUST return ENOENT */
1727
1728         torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
1729                         __location__);
1730
1731         ZERO_STRUCT(create);
1732         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1733         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1734         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1735         create.in.fname               = fname;
1736         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1737                 NTCREATEX_SHARE_ACCESS_READ |
1738                 NTCREATEX_SHARE_ACCESS_WRITE;
1739         status = smb2_create(tree, mem_ctx, &create);
1740         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1741         fh1 = create.out.file.handle;
1742
1743         ZERO_STRUCT(create);
1744         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1745         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1746         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1747         create.in.fname               = rfork;
1748         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1749                 NTCREATEX_SHARE_ACCESS_READ |
1750                 NTCREATEX_SHARE_ACCESS_WRITE;
1751         status = smb2_create(tree, mem_ctx, &create);
1752         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1753         fh2 = create.out.file.handle;
1754
1755         ZERO_STRUCT(sinfo);
1756         sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1757         sinfo.end_of_file_info.in.file.handle = fh2;
1758         sinfo.end_of_file_info.in.size = 0;
1759         status = smb2_setinfo_file(tree, &sinfo);
1760         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
1761
1762         /*
1763          * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
1764          */
1765         ZERO_STRUCT(create);
1766         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1767         create.in.desired_access      = SEC_FILE_ALL;
1768         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1769         create.in.fname               = rfork;
1770         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1771                 NTCREATEX_SHARE_ACCESS_READ |
1772                 NTCREATEX_SHARE_ACCESS_WRITE;
1773         status = smb2_create(tree, mem_ctx, &create);
1774         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1775
1776         /*
1777          * Do another open on the rfork and write to the new handle. A
1778          * naive server might unlink the AppleDouble resource fork
1779          * file when its truncated to 0 bytes above, so in case both
1780          * open handles share the same underlying fd, the unlink would
1781          * cause the below write to be lost.
1782          */
1783         ZERO_STRUCT(create);
1784         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1785         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1786         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1787         create.in.fname               = rfork;
1788         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1789                 NTCREATEX_SHARE_ACCESS_READ |
1790                 NTCREATEX_SHARE_ACCESS_WRITE;
1791         status = smb2_create(tree, mem_ctx, &create);
1792         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1793         fh3 = create.out.file.handle;
1794
1795         status = smb2_util_write(tree, fh3, "foo", 0, 3);
1796         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
1797
1798         smb2_util_close(tree, fh3);
1799         smb2_util_close(tree, fh2);
1800         smb2_util_close(tree, fh1);
1801
1802         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
1803                            0, 3, 0, 3, "foo");
1804         torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1805
1806 done:
1807         smb2_util_unlink(tree, fname);
1808         smb2_deltree(tree, BASEDIR);
1809         talloc_free(mem_ctx);
1810         return ret;
1811 }
1812
1813 static bool test_rfork_create(struct torture_context *tctx,
1814                               struct smb2_tree *tree)
1815 {
1816         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1817         const char *fname = BASEDIR "\\torture_rfork_create";
1818         const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1819         NTSTATUS status;
1820         struct smb2_handle testdirh;
1821         bool ret = true;
1822         struct smb2_create create;
1823         struct smb2_handle fh1;
1824         const char *streams[] = {
1825                 "::$DATA"
1826         };
1827         union smb_fileinfo finfo;
1828
1829         smb2_util_unlink(tree, fname);
1830
1831         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1832         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1833         smb2_util_close(tree, testdirh);
1834
1835         ret = torture_setup_file(mem_ctx, tree, fname, false);
1836         if (ret == false) {
1837                 goto done;
1838         }
1839
1840         torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
1841                         __location__);
1842
1843         ZERO_STRUCT(create);
1844         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1845         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1846         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1847         create.in.fname               = rfork;
1848         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1849                 NTCREATEX_SHARE_ACCESS_READ |
1850                 NTCREATEX_SHARE_ACCESS_WRITE;
1851         status = smb2_create(tree, mem_ctx, &create);
1852         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1853
1854         torture_comment(tctx, "(%s) create resource fork\n", __location__);
1855
1856         ZERO_STRUCT(create);
1857         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1858         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1859         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1860         create.in.fname               = rfork;
1861         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1862                 NTCREATEX_SHARE_ACCESS_READ |
1863                 NTCREATEX_SHARE_ACCESS_WRITE;
1864         status = smb2_create(tree, mem_ctx, &create);
1865         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1866         fh1 = create.out.file.handle;
1867
1868         torture_comment(tctx, "(%s) getinfo on create handle\n",
1869                         __location__);
1870
1871         ZERO_STRUCT(finfo);
1872         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1873         finfo.generic.in.file.handle = fh1;
1874         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1875         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
1876         if (finfo.all_info.out.size != 0) {
1877                 torture_result(tctx, TORTURE_FAIL,
1878                                "(%s) Incorrect resource fork size\n",
1879                                __location__);
1880                 ret = false;
1881                 smb2_util_close(tree, fh1);
1882                 goto done;
1883         }
1884
1885         torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
1886                         __location__);
1887
1888         ZERO_STRUCT(create);
1889         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1890         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1891         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1892         create.in.fname               = rfork;
1893         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1894                 NTCREATEX_SHARE_ACCESS_READ |
1895                 NTCREATEX_SHARE_ACCESS_WRITE;
1896         status = smb2_create(tree, mem_ctx, &create);
1897         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1898
1899         ret = check_stream_list(tree, tctx, fname, 1, streams, false);
1900         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
1901
1902         torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
1903                         __location__);
1904
1905         ZERO_STRUCT(create);
1906         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1907         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1908         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1909         create.in.fname               = rfork;
1910         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1911                 NTCREATEX_SHARE_ACCESS_READ |
1912                 NTCREATEX_SHARE_ACCESS_WRITE;
1913         status = smb2_create(tree, mem_ctx, &create);
1914         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1915
1916 done:
1917         smb2_util_unlink(tree, fname);
1918         smb2_deltree(tree, BASEDIR);
1919         talloc_free(mem_ctx);
1920         return ret;
1921 }
1922
1923 static bool test_rfork_create_ro(struct torture_context *tctx,
1924                                  struct smb2_tree *tree)
1925 {
1926         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1927         const char *fname = BASEDIR "\\torture_rfork_create";
1928         const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1929         NTSTATUS status;
1930         struct smb2_handle testdirh;
1931         bool ret = true;
1932         struct smb2_create create;
1933
1934         smb2_util_unlink(tree, fname);
1935         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1936         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1937                 "torture_smb2_testdir\n");
1938         smb2_util_close(tree, testdirh);
1939
1940         ret = torture_setup_file(mem_ctx, tree, fname, false);
1941         if (ret == false) {
1942                 goto done;
1943         }
1944
1945         torture_comment(tctx, "(%s) Try opening read-only with "
1946                         "open_if create disposition, should return ENOENT\n",
1947                         __location__);
1948
1949         ZERO_STRUCT(create);
1950         create.in.fname = rfork;
1951         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1952         create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
1953         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1954         create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
1955         status = smb2_create(tree, mem_ctx, &(create));
1956         torture_assert_ntstatus_equal_goto(tctx, status,
1957                                         NT_STATUS_OBJECT_NAME_NOT_FOUND,
1958                                         ret, done, "smb2_create failed\n");
1959
1960         torture_comment(tctx, "(%s) Now write something to the "
1961                         "rsrc stream, then the same open should succeed\n",
1962                         __location__);
1963
1964         ret = write_stream(tree, __location__, tctx, mem_ctx,
1965                            fname, AFPRESOURCE_STREAM_NAME,
1966                            0, 3, "foo");
1967         torture_assert_goto(tctx, ret == true, ret, done,
1968                         "write_stream failed\n");
1969
1970         ret = check_stream(tree, __location__, tctx, mem_ctx,
1971                            fname, AFPRESOURCE_STREAM,
1972                            0, 3, 0, 3, "foo");
1973         torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1974
1975         ZERO_STRUCT(create);
1976         create.in.fname = rfork;
1977         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1978         create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
1979         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1980         create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
1981         status = smb2_create(tree, mem_ctx, &(create));
1982         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1983                 "smb2_create failed\n");
1984
1985         smb2_util_close(tree, create.out.file.handle);
1986
1987 done:
1988         smb2_util_unlink(tree, fname);
1989         smb2_deltree(tree, BASEDIR);
1990         talloc_free(mem_ctx);
1991         return ret;
1992 }
1993
1994 static bool test_adouble_conversion(struct torture_context *tctx,
1995                                     struct smb2_tree *tree)
1996 {
1997         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1998         const char *fname = BASEDIR "\\test_adouble_conversion";
1999         const char *fname_local = BASEDIR "/test_adouble_conversion";
2000         const char *adname_local = BASEDIR "/._test_adouble_conversion";
2001         NTSTATUS status;
2002         struct smb2_handle testdirh;
2003         bool ret = true;
2004         const char *data = "This resource fork intentionally left blank";
2005         size_t datalen = strlen(data);
2006         const char *localdir = NULL;
2007
2008         localdir = torture_setting_string(tctx, "localdir", NULL);
2009         if (localdir == NULL) {
2010                 torture_skip(tctx, "Need localdir for test");
2011         }
2012
2013         smb2_util_unlink(tree, fname);
2014
2015         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2016         CHECK_STATUS(status, NT_STATUS_OK);
2017         smb2_util_close(tree, testdirh);
2018
2019         ret = torture_setup_local_file(tctx, "localdir", fname_local,
2020                                        NULL, 0);
2021         if (ret == false) {
2022                 goto done;
2023         }
2024
2025         ret = torture_setup_local_file(tctx, "localdir", adname_local,
2026                                        osx_adouble_w_xattr,
2027                                        sizeof(osx_adouble_w_xattr));
2028         if (ret == false) {
2029                 goto done;
2030         }
2031
2032         torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
2033             __location__);
2034
2035         ret &= check_stream(tree, __location__, tctx, mem_ctx,
2036                             fname, AFPRESOURCE_STREAM,
2037                             16, datalen, 0, datalen, data);
2038
2039 done:
2040         smb2_deltree(tree, BASEDIR);
2041         talloc_free(mem_ctx);
2042         return ret;
2043 }
2044
2045 static bool test_aapl(struct torture_context *tctx,
2046                       struct smb2_tree *tree)
2047 {
2048         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2049         const char *fname = BASEDIR "\\test_aapl";
2050         NTSTATUS status;
2051         struct smb2_handle testdirh;
2052         bool ret = true;
2053         struct smb2_create io;
2054         DATA_BLOB data;
2055         struct smb2_create_blob *aapl = NULL;
2056         AfpInfo *info;
2057         const char *type_creator = "SMB,OLE!";
2058         char type_creator_buf[9];
2059         uint32_t aapl_cmd;
2060         uint32_t aapl_reply_bitmap;
2061         uint32_t aapl_server_caps;
2062         uint32_t aapl_vol_caps;
2063         char *model;
2064         struct smb2_find f;
2065         unsigned int count;
2066         union smb_search_data *d;
2067         uint64_t rfork_len;
2068
2069         smb2_deltree(tree, BASEDIR);
2070
2071         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2072         CHECK_STATUS(status, NT_STATUS_OK);
2073         smb2_util_close(tree, testdirh);
2074
2075         ZERO_STRUCT(io);
2076         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
2077         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
2078         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2079         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2080                               NTCREATEX_SHARE_ACCESS_READ |
2081                               NTCREATEX_SHARE_ACCESS_WRITE);
2082         io.in.fname = fname;
2083
2084         /*
2085          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
2086          * controls behaviour of Apple's SMB2 extensions for the whole
2087          * session!
2088          */
2089
2090         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2091         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2092         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2093                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2094                              SMB2_CRTCTX_AAPL_MODEL_INFO));
2095         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2096                               SMB2_CRTCTX_AAPL_UNIX_BASED |
2097                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
2098
2099         torture_comment(tctx, "Testing SMB2 create context AAPL\n");
2100         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2101         CHECK_STATUS(status, NT_STATUS_OK);
2102
2103         status = smb2_create(tree, tctx, &io);
2104         CHECK_STATUS(status, NT_STATUS_OK);
2105         status = smb2_util_close(tree, io.out.file.handle);
2106         CHECK_STATUS(status, NT_STATUS_OK);
2107
2108         /*
2109          * Now check returned AAPL context
2110          */
2111         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
2112
2113         aapl = smb2_create_blob_find(&io.out.blobs,
2114                                      SMB2_CREATE_TAG_AAPL);
2115
2116         if (aapl == NULL) {
2117                 torture_result(tctx, TORTURE_FAIL,
2118                                "(%s) unexpectedly no AAPL capabilities were returned.",
2119                                __location__);
2120                 ret = false;
2121                 goto done;
2122         }
2123
2124         if (aapl->data.length != 50) {
2125                 /*
2126                  * uint32_t CommandCode = kAAPL_SERVER_QUERY
2127                  * uint32_t Reserved = 0;
2128                  * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
2129                  *                        kAAPL_VOLUME_CAPS |
2130                  *                        kAAPL_MODEL_INFO;
2131                  * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
2132                  *                       kAAPL_SUPPORTS_OSX_COPYFILE;
2133                  * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
2134                  *                       kAAPL_CASE_SENSITIVE;
2135                  * uint32_t Pad2 = 0;
2136                  * uint32_t ModelStringLen = 10;
2137                  * ucs2_t ModelString[5] = "Samba";
2138                  */
2139                 torture_warning(tctx,
2140                                 "(%s) unexpected AAPL context length: %zd, expected 50",
2141                                 __location__, aapl->data.length);
2142         }
2143
2144         aapl_cmd = IVAL(aapl->data.data, 0);
2145         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2146                 torture_result(tctx, TORTURE_FAIL,
2147                                "(%s) unexpected cmd: %d",
2148                                __location__, (int)aapl_cmd);
2149                 ret = false;
2150                 goto done;
2151         }
2152
2153         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2154         if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2155                                   SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2156                                   SMB2_CRTCTX_AAPL_MODEL_INFO)) {
2157                 torture_result(tctx, TORTURE_FAIL,
2158                                "(%s) unexpected reply_bitmap: %d",
2159                                __location__, (int)aapl_reply_bitmap);
2160                 ret = false;
2161                 goto done;
2162         }
2163
2164         aapl_server_caps = BVAL(aapl->data.data, 16);
2165         if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
2166                                  SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2167                                  SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
2168                                  SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
2169                 torture_result(tctx, TORTURE_FAIL,
2170                                "(%s) unexpected server_caps: %d",
2171                                __location__, (int)aapl_server_caps);
2172                 ret = false;
2173                 goto done;
2174         }
2175
2176         aapl_vol_caps = BVAL(aapl->data.data, 24);
2177         if (aapl_vol_caps != 0) {
2178                 /* this will fail on a case insensitive fs ... */
2179                 torture_result(tctx, TORTURE_FAIL,
2180                                 "(%s) unexpected vol_caps: %d",
2181                                 __location__, (int)aapl_vol_caps);
2182         }
2183
2184         ret = convert_string_talloc(mem_ctx,
2185                                     CH_UTF16LE, CH_UNIX,
2186                                     aapl->data.data + 40, 10,
2187                                     &model, NULL);
2188         if (ret == false) {
2189                 torture_result(tctx, TORTURE_FAIL,
2190                                "(%s) convert_string_talloc() failed",
2191                                __location__);
2192                 goto done;
2193         }
2194         torture_comment(tctx, "Got server model: \"%s\"\n", model);
2195
2196         /*
2197          * Now that Requested AAPL extensions are enabled, setup some
2198          * Mac files with metadata and resource fork
2199          */
2200         ret = torture_setup_file(mem_ctx, tree, fname, false);
2201         if (ret == false) {
2202                 torture_result(tctx, TORTURE_FAIL,
2203                                "(%s) torture_setup_file() failed",
2204                                __location__);
2205                 goto done;
2206         }
2207
2208         info = torture_afpinfo_new(mem_ctx);
2209         if (info == NULL) {
2210                 torture_result(tctx, TORTURE_FAIL,
2211                                "(%s) torture_afpinfo_new() failed",
2212                                __location__);
2213                 ret = false;
2214                 goto done;
2215         }
2216
2217         memcpy(info->afpi_FinderInfo, type_creator, 8);
2218         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2219         if (ret == false) {
2220                 torture_result(tctx, TORTURE_FAIL,
2221                                "(%s) torture_write_afpinfo() failed",
2222                                __location__);
2223                 goto done;
2224         }
2225
2226         ret = write_stream(tree, __location__, tctx, mem_ctx,
2227                            fname, AFPRESOURCE_STREAM_NAME,
2228                            0, 3, "foo");
2229         if (ret == false) {
2230                 torture_result(tctx, TORTURE_FAIL,
2231                                "(%s) write_stream() failed",
2232                                __location__);
2233                 goto done;
2234         }
2235
2236         /*
2237          * Ok, file is prepared, now call smb2/find
2238          */
2239
2240         ZERO_STRUCT(io);
2241         io.in.desired_access = SEC_RIGHTS_DIR_READ;
2242         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2243         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2244         io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
2245                               NTCREATEX_SHARE_ACCESS_WRITE |
2246                               NTCREATEX_SHARE_ACCESS_DELETE);
2247         io.in.create_disposition = NTCREATEX_DISP_OPEN;
2248         io.in.fname = BASEDIR;
2249         status = smb2_create(tree, tctx, &io);
2250         CHECK_STATUS(status, NT_STATUS_OK);
2251
2252         ZERO_STRUCT(f);
2253         f.in.file.handle        = io.out.file.handle;
2254         f.in.pattern            = "test_aapl";
2255         f.in.continue_flags     = SMB2_CONTINUE_FLAG_SINGLE;
2256         f.in.max_response_size  = 0x1000;
2257         f.in.level              = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
2258
2259         status = smb2_find_level(tree, tree, &f, &count, &d);
2260         CHECK_STATUS(status, NT_STATUS_OK);
2261
2262         status = smb2_util_close(tree, io.out.file.handle);
2263         CHECK_STATUS(status, NT_STATUS_OK);
2264
2265         if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2266                 torture_result(tctx, TORTURE_FAIL,
2267                                "(%s) write_stream() failed",
2268                                __location__);
2269                 ret = false;
2270                 goto done;
2271         }
2272
2273         if (d[0].id_both_directory_info.short_name.private_length != 24) {
2274                 torture_result(tctx, TORTURE_FAIL,
2275                                "(%s) bad short_name length %" PRIu32 ", expected 24",
2276                                __location__, d[0].id_both_directory_info.short_name.private_length);
2277                 ret = false;
2278                 goto done;
2279         }
2280
2281         torture_comment(tctx, "short_name buffer:\n");
2282         dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2283
2284         /*
2285          * Extract data as specified by the AAPL extension:
2286          * - ea_size contains max_access
2287          * - short_name contains resource fork length + FinderInfo
2288          * - reserved2 contains the unix mode
2289          */
2290         torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2291                         d[0].id_both_directory_info.ea_size);
2292
2293         rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2294         if (rfork_len != 3) {
2295                 torture_result(tctx, TORTURE_FAIL,
2296                                "(%s) expected resource fork length 3, got: %" PRIu64,
2297                                __location__, rfork_len);
2298                 ret = false;
2299                 goto done;
2300         }
2301
2302         memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2303         type_creator_buf[8] = 0;
2304         if (strcmp(type_creator, type_creator_buf) != 0) {
2305                 torture_result(tctx, TORTURE_FAIL,
2306                                "(%s) expected type/creator \"%s\" , got: %s",
2307                                __location__, type_creator, type_creator_buf);
2308                 ret = false;
2309                 goto done;
2310         }
2311
2312 done:
2313         smb2_util_unlink(tree, fname);
2314         smb2_deltree(tree, BASEDIR);
2315         talloc_free(mem_ctx);
2316         return ret;
2317 }
2318
2319 static uint64_t patt_hash(uint64_t off)
2320 {
2321         return off;
2322 }
2323
2324 static bool write_pattern(struct torture_context *torture,
2325                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2326                           struct smb2_handle h, uint64_t off, uint64_t len,
2327                           uint64_t patt_off)
2328 {
2329         NTSTATUS status;
2330         uint64_t i;
2331         uint8_t *buf;
2332         uint64_t io_sz = MIN(1024 * 64, len);
2333
2334         if (len == 0) {
2335                 return true;
2336         }
2337
2338         torture_assert(torture, (len % 8) == 0, "invalid write len");
2339
2340         buf = talloc_zero_size(mem_ctx, io_sz);
2341         torture_assert(torture, (buf != NULL), "no memory for file data buf");
2342
2343         while (len > 0) {
2344                 for (i = 0; i <= io_sz - 8; i += 8) {
2345                         SBVAL(buf, i, patt_hash(patt_off));
2346                         patt_off += 8;
2347                 }
2348
2349                 status = smb2_util_write(tree, h,
2350                                          buf, off, io_sz);
2351                 torture_assert_ntstatus_ok(torture, status, "file write");
2352
2353                 len -= io_sz;
2354                 off += io_sz;
2355         }
2356
2357         talloc_free(buf);
2358
2359         return true;
2360 }
2361
2362 static bool check_pattern(struct torture_context *torture,
2363                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2364                           struct smb2_handle h, uint64_t off, uint64_t len,
2365                           uint64_t patt_off)
2366 {
2367         if (len == 0) {
2368                 return true;
2369         }
2370
2371         torture_assert(torture, (len % 8) == 0, "invalid read len");
2372
2373         while (len > 0) {
2374                 uint64_t i;
2375                 struct smb2_read r;
2376                 NTSTATUS status;
2377                 uint64_t io_sz = MIN(1024 * 64, len);
2378
2379                 ZERO_STRUCT(r);
2380                 r.in.file.handle = h;
2381                 r.in.length      = io_sz;
2382                 r.in.offset      = off;
2383                 status = smb2_read(tree, mem_ctx, &r);
2384                 torture_assert_ntstatus_ok(torture, status, "read");
2385
2386                 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2387                                          "read data len mismatch");
2388
2389                 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2390                         uint64_t data = BVAL(r.out.data.data, i);
2391                         torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2392                                                  talloc_asprintf(torture, "read data "
2393                                                                  "pattern bad at %llu\n",
2394                                                                  (unsigned long long)off + i));
2395                 }
2396                 talloc_free(r.out.data.data);
2397                 len -= io_sz;
2398                 off += io_sz;
2399         }
2400
2401         return true;
2402 }
2403
2404 static bool test_setup_open(struct torture_context *torture,
2405                             struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2406                             const char *fname,
2407                             struct smb2_handle *fh,
2408                             uint32_t desired_access,
2409                             uint32_t file_attributes)
2410 {
2411         struct smb2_create io;
2412         NTSTATUS status;
2413
2414         ZERO_STRUCT(io);
2415         io.in.desired_access = desired_access;
2416         io.in.file_attributes = file_attributes;
2417         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2418         io.in.share_access =
2419                 NTCREATEX_SHARE_ACCESS_DELETE|
2420                 NTCREATEX_SHARE_ACCESS_READ|
2421                 NTCREATEX_SHARE_ACCESS_WRITE;
2422         if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2423                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2424         }
2425         io.in.fname = fname;
2426
2427         status = smb2_create(tree, mem_ctx, &io);
2428         torture_assert_ntstatus_ok(torture, status, "file create");
2429
2430         *fh = io.out.file.handle;
2431
2432         return true;
2433 }
2434
2435 static bool test_setup_create_fill(struct torture_context *torture,
2436                                    struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2437                                    const char *fname,
2438                                    struct smb2_handle *fh,
2439                                    uint64_t size,
2440                                    uint32_t desired_access,
2441                                    uint32_t file_attributes)
2442 {
2443         bool ok;
2444
2445         ok = test_setup_open(torture, tree, mem_ctx,
2446                              fname,
2447                              fh,
2448                              desired_access,
2449                              file_attributes);
2450         torture_assert(torture, ok, "file open");
2451
2452         if (size > 0) {
2453                 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2454                 torture_assert(torture, ok, "write pattern");
2455         }
2456         return true;
2457 }
2458
2459 static bool test_setup_copy_chunk(struct torture_context *torture,
2460                                   struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2461                                   uint32_t nchunks,
2462                                   const char *src_name,
2463                                   struct smb2_handle *src_h,
2464                                   uint64_t src_size,
2465                                   uint32_t src_desired_access,
2466                                   const char *dst_name,
2467                                   struct smb2_handle *dest_h,
2468                                   uint64_t dest_size,
2469                                   uint32_t dest_desired_access,
2470                                   struct srv_copychunk_copy *cc_copy,
2471                                   union smb_ioctl *io)
2472 {
2473         struct req_resume_key_rsp res_key;
2474         bool ok;
2475         NTSTATUS status;
2476         enum ndr_err_code ndr_ret;
2477
2478         ok = test_setup_create_fill(torture, tree, mem_ctx, src_name,
2479                                     src_h, src_size, src_desired_access,
2480                                     FILE_ATTRIBUTE_NORMAL);
2481         torture_assert(torture, ok, "src file create fill");
2482
2483         ok = test_setup_create_fill(torture, tree, mem_ctx, dst_name,
2484                                     dest_h, dest_size, dest_desired_access,
2485                                     FILE_ATTRIBUTE_NORMAL);
2486         torture_assert(torture, ok, "dest file create fill");
2487
2488         ZERO_STRUCTPN(io);
2489         io->smb2.level = RAW_IOCTL_SMB2;
2490         io->smb2.in.file.handle = *src_h;
2491         io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2492         /* Allow for Key + ContextLength + Context */
2493         io->smb2.in.max_response_size = 32;
2494         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2495
2496         status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2497         torture_assert_ntstatus_ok(torture, status,
2498                                    "FSCTL_SRV_REQUEST_RESUME_KEY");
2499
2500         ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2501                         (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2502
2503         torture_assert_ndr_success(torture, ndr_ret,
2504                                    "ndr_pull_req_resume_key_rsp");
2505
2506         ZERO_STRUCTPN(io);
2507         io->smb2.level = RAW_IOCTL_SMB2;
2508         io->smb2.in.file.handle = *dest_h;
2509         io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2510         io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2511         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2512
2513         ZERO_STRUCTPN(cc_copy);
2514         memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2515         cc_copy->chunk_count = nchunks;
2516         cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2517         torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2518
2519         return true;
2520 }
2521
2522
2523 static bool check_copy_chunk_rsp(struct torture_context *torture,
2524                                  struct srv_copychunk_rsp *cc_rsp,
2525                                  uint32_t ex_chunks_written,
2526                                  uint32_t ex_chunk_bytes_written,
2527                                  uint32_t ex_total_bytes_written)
2528 {
2529         torture_assert_int_equal(torture, cc_rsp->chunks_written,
2530                                  ex_chunks_written, "num chunks");
2531         torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2532                                  ex_chunk_bytes_written, "chunk bytes written");
2533         torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2534                                  ex_total_bytes_written, "chunk total bytes");
2535         return true;
2536 }
2537
2538 static bool neg_aapl_copyfile(struct torture_context *tctx,
2539                               struct smb2_tree *tree,
2540                               uint64_t flags)
2541 {
2542         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2543         const char *fname = "aapl";
2544         NTSTATUS status;
2545         struct smb2_create io;
2546         DATA_BLOB data;
2547         struct smb2_create_blob *aapl = NULL;
2548         uint32_t aapl_cmd;
2549         uint32_t aapl_reply_bitmap;
2550         uint32_t aapl_server_caps;
2551         bool ret = true;
2552
2553         ZERO_STRUCT(io);
2554         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
2555         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
2556         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2557         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2558                               NTCREATEX_SHARE_ACCESS_READ |
2559                               NTCREATEX_SHARE_ACCESS_WRITE);
2560         io.in.fname = fname;
2561
2562         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2563         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2564         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2565         SBVAL(data.data, 16, flags);
2566
2567         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2568         CHECK_STATUS(status, NT_STATUS_OK);
2569
2570         status = smb2_create(tree, tctx, &io);
2571         CHECK_STATUS(status, NT_STATUS_OK);
2572
2573         aapl = smb2_create_blob_find(&io.out.blobs,
2574                                      SMB2_CREATE_TAG_AAPL);
2575         if (aapl == NULL) {
2576                 ret = false;
2577                 goto done;
2578
2579         }
2580         if (aapl->data.length < 24) {
2581                 ret = false;
2582                 goto done;
2583         }
2584
2585         aapl_cmd = IVAL(aapl->data.data, 0);
2586         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2587                 torture_result(tctx, TORTURE_FAIL,
2588                                "(%s) unexpected cmd: %d",
2589                                __location__, (int)aapl_cmd);
2590                 ret = false;
2591                 goto done;
2592         }
2593
2594         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2595         if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2596                 torture_result(tctx, TORTURE_FAIL,
2597                                "(%s) unexpected reply_bitmap: %d",
2598                                __location__, (int)aapl_reply_bitmap);
2599                 ret = false;
2600                 goto done;
2601         }
2602
2603         aapl_server_caps = BVAL(aapl->data.data, 16);
2604         if (!(aapl_server_caps & flags)) {
2605                 torture_result(tctx, TORTURE_FAIL,
2606                                "(%s) unexpected server_caps: %d",
2607                                __location__, (int)aapl_server_caps);
2608                 ret = false;
2609                 goto done;
2610         }
2611
2612 done:
2613         status = smb2_util_close(tree, io.out.file.handle);
2614         CHECK_STATUS(status, NT_STATUS_OK);
2615
2616         smb2_util_unlink(tree, "aapl");
2617         talloc_free(mem_ctx);
2618         return ret;
2619 }
2620
2621 static bool test_copyfile(struct torture_context *torture,
2622                           struct smb2_tree *tree)
2623 {
2624         struct smb2_handle src_h;
2625         struct smb2_handle dest_h;
2626         NTSTATUS status;
2627         union smb_ioctl io;
2628         TALLOC_CTX *tmp_ctx = talloc_new(tree);
2629         struct srv_copychunk_copy cc_copy;
2630         struct srv_copychunk_rsp cc_rsp;
2631         enum ndr_err_code ndr_ret;
2632         bool ok;
2633         const char *sname = ":foo" "\xef\x80\xa2" "bar:$DATA";
2634
2635         /*
2636          * First test a copy_chunk with a 0 chunk count without having
2637          * enabled this via AAPL. The request must not fail and the
2638          * copied length in the response must be 0. This is verified
2639          * against Windows 2008r2.
2640          */
2641
2642         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2643                                    0, /* 0 chunks, copyfile semantics */
2644                                    FNAME_CC_SRC,
2645                                    &src_h, 4096, /* fill 4096 byte src file */
2646                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2647                                    FNAME_CC_DST,
2648                                    &dest_h, 0,  /* 0 byte dest file */
2649                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2650                                    &cc_copy,
2651                                    &io);
2652         if (!ok) {
2653                 torture_fail_goto(torture, done, "setup copy chunk error");
2654         }
2655
2656         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2657                                        &cc_copy,
2658                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2659         torture_assert_ndr_success(torture, ndr_ret,
2660                                    "ndr_push_srv_copychunk_copy");
2661
2662         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2663         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2664
2665         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2666                                        &cc_rsp,
2667                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2668         torture_assert_ndr_success(torture, ndr_ret,
2669                                    "ndr_pull_srv_copychunk_rsp");
2670
2671         ok = check_copy_chunk_rsp(torture, &cc_rsp,
2672                                   0,    /* chunks written */
2673                                   0,    /* chunk bytes unsuccessfully written */
2674                                   0); /* total bytes written */
2675         if (!ok) {
2676                 torture_fail_goto(torture, done, "bad copy chunk response data");
2677         }
2678
2679         /*
2680          * Now enable AAPL copyfile and test again, the file and the
2681          * stream must be copied by the server.
2682          */
2683         ok = neg_aapl_copyfile(torture, tree,
2684                                SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2685         if (!ok) {
2686                 torture_skip_goto(torture, done, "missing AAPL copyfile");
2687                 goto done;
2688         }
2689
2690         smb2_util_close(tree, src_h);
2691         smb2_util_close(tree, dest_h);
2692         smb2_util_unlink(tree, FNAME_CC_SRC);
2693         smb2_util_unlink(tree, FNAME_CC_DST);
2694
2695         ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2696         if (!ok) {
2697                 torture_fail(torture, "setup file error");
2698         }
2699         ok = write_stream(tree, __location__, torture, tmp_ctx,
2700                             FNAME_CC_SRC, AFPRESOURCE_STREAM,
2701                             10, 10, "1234567890");
2702         if (!ok) {
2703                 torture_fail(torture, "setup stream error");
2704         }
2705
2706         ok = write_stream(tree, __location__, torture, tmp_ctx,
2707                             FNAME_CC_SRC, sname,
2708                             10, 10, "abcdefghij");
2709         torture_assert_goto(torture, ok == true, ok, done, "write_stream failed\n");
2710
2711         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2712                                    0, /* 0 chunks, copyfile semantics */
2713                                    FNAME_CC_SRC,
2714                                    &src_h, 4096, /* fill 4096 byte src file */
2715                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2716                                    FNAME_CC_DST,
2717                                    &dest_h, 0,  /* 0 byte dest file */
2718                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2719                                    &cc_copy,
2720                                    &io);
2721         if (!ok) {
2722                 torture_fail_goto(torture, done, "setup copy chunk error");
2723         }
2724
2725         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2726                                        &cc_copy,
2727                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2728         torture_assert_ndr_success(torture, ndr_ret,
2729                                    "ndr_push_srv_copychunk_copy");
2730
2731         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2732         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2733
2734         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2735                                        &cc_rsp,
2736                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2737         torture_assert_ndr_success(torture, ndr_ret,
2738                                    "ndr_pull_srv_copychunk_rsp");
2739
2740         ok = check_copy_chunk_rsp(torture, &cc_rsp,
2741                                   0,    /* chunks written */
2742                                   0,    /* chunk bytes unsuccessfully written */
2743                                   4096); /* total bytes written */
2744         if (!ok) {
2745                 torture_fail_goto(torture, done, "bad copy chunk response data");
2746         }
2747
2748         ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
2749                              SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
2750         if (!ok) {
2751                 torture_fail_goto(torture, done,"open failed");
2752         }
2753         ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
2754         if (!ok) {
2755                 torture_fail_goto(torture, done, "inconsistent file data");
2756         }
2757
2758         ok = check_stream(tree, __location__, torture, tmp_ctx,
2759                             FNAME_CC_DST, AFPRESOURCE_STREAM,
2760                             0, 20, 10, 10, "1234567890");
2761         if (!ok) {
2762                 torture_fail_goto(torture, done, "inconsistent stream data");
2763         }
2764
2765         ok = check_stream(tree, __location__, torture, tmp_ctx,
2766                             FNAME_CC_DST, sname,
2767                             0, 20, 10, 10, "abcdefghij");
2768         torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
2769
2770 done:
2771         smb2_util_close(tree, src_h);
2772         smb2_util_close(tree, dest_h);
2773         smb2_util_unlink(tree, FNAME_CC_SRC);
2774         smb2_util_unlink(tree, FNAME_CC_DST);
2775         talloc_free(tmp_ctx);
2776         return true;
2777 }
2778
2779 static bool check_stream_list(struct smb2_tree *tree,
2780                               struct torture_context *tctx,
2781                               const char *fname,
2782                               int num_exp,
2783                               const char **exp,
2784                               bool is_dir)
2785 {
2786         bool ret = true;
2787         union smb_fileinfo finfo;
2788         NTSTATUS status;
2789         int i;
2790         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
2791         char **exp_sort;
2792         struct stream_struct *stream_sort;
2793         struct smb2_create create;
2794         struct smb2_handle h;
2795
2796         ZERO_STRUCT(h);
2797         torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
2798
2799         ZERO_STRUCT(create);
2800         create.in.fname = fname;
2801         create.in.create_disposition = NTCREATEX_DISP_OPEN;
2802         create.in.desired_access = SEC_FILE_ALL;
2803         create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
2804         create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
2805         status = smb2_create(tree, tmp_ctx, &create);
2806         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2807         h = create.out.file.handle;
2808
2809         finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
2810         finfo.generic.in.file.handle = h;
2811
2812         status = smb2_getinfo_file(tree, tctx, &finfo);
2813         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
2814
2815         smb2_util_close(tree, h);
2816
2817         torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
2818                                       ret, done, "stream count");
2819
2820         if (num_exp == 0) {
2821                 TALLOC_FREE(tmp_ctx);
2822                 goto done;
2823         }
2824
2825         exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
2826         torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
2827
2828         TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
2829
2830         stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
2831                                     finfo.stream_info.out.num_streams *
2832                                     sizeof(*stream_sort));
2833         torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
2834
2835         TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
2836
2837         for (i=0; i<num_exp; i++) {
2838                 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
2839                                 i, exp_sort[i], stream_sort[i].stream_name.s);
2840                 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
2841                                               ret, done, "stream name");
2842         }
2843
2844 done:
2845         TALLOC_FREE(tmp_ctx);
2846         return ret;
2847 }
2848
2849 /*
2850   test stream names
2851 */
2852 static bool test_stream_names(struct torture_context *tctx,
2853                               struct smb2_tree *tree)
2854 {
2855         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2856         NTSTATUS status;
2857         struct smb2_create create;
2858         struct smb2_handle h;
2859         const char *fname = BASEDIR "\\stream_names.txt";
2860         const char *sname1;
2861         bool ret;
2862         /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
2863         const char *streams[] = {
2864                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2865                 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
2866                 "::$DATA"
2867         };
2868         const char *localdir = NULL;
2869
2870         localdir = torture_setting_string(tctx, "localdir", NULL);
2871         if (localdir == NULL) {
2872                 torture_skip(tctx, "Need localdir for test");
2873         }
2874
2875         sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
2876
2877         /* clean slate ...*/
2878         smb2_util_unlink(tree, fname);
2879         smb2_deltree(tree, fname);
2880         smb2_deltree(tree, BASEDIR);
2881
2882         status = torture_smb2_testdir(tree, BASEDIR, &h);
2883         CHECK_STATUS(status, NT_STATUS_OK);
2884         smb2_util_close(tree, h);
2885
2886         torture_comment(tctx, "(%s) testing stream names\n", __location__);
2887         ZERO_STRUCT(create);
2888         create.in.desired_access = SEC_FILE_WRITE_DATA;
2889         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2890         create.in.share_access =
2891                 NTCREATEX_SHARE_ACCESS_DELETE|
2892                 NTCREATEX_SHARE_ACCESS_READ|
2893                 NTCREATEX_SHARE_ACCESS_WRITE;
2894         create.in.create_disposition = NTCREATEX_DISP_CREATE;
2895         create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2896         create.in.fname = sname1;
2897
2898         status = smb2_create(tree, mem_ctx, &create);
2899         CHECK_STATUS(status, NT_STATUS_OK);
2900         smb2_util_close(tree, create.out.file.handle);
2901
2902         ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
2903                                         "user.DosStream.bar:baz:$DATA",
2904                                         "data", strlen("data"));
2905         CHECK_VALUE(ret, true);
2906
2907         ret = check_stream_list(tree, tctx, fname, 3, streams, false);
2908         CHECK_VALUE(ret, true);
2909
2910 done:
2911         status = smb2_util_unlink(tree, fname);
2912         smb2_deltree(tree, BASEDIR);
2913         talloc_free(mem_ctx);
2914
2915         return ret;
2916 }
2917
2918 /* Renaming a directory with open file, should work for OS X AAPL clients */
2919 static bool test_rename_dir_openfile(struct torture_context *torture,
2920                                      struct smb2_tree *tree)
2921 {
2922         bool ret = true;
2923         NTSTATUS status;
2924         union smb_open io;
2925         union smb_close cl;
2926         union smb_setfileinfo sinfo;
2927         struct smb2_handle d1, h1;
2928         const char *renamedir = BASEDIR "-new";
2929         bool server_is_osx = torture_setting_bool(torture, "osx", false);
2930
2931         smb2_deltree(tree, BASEDIR);
2932         smb2_util_rmdir(tree, BASEDIR);
2933         smb2_deltree(tree, renamedir);
2934
2935         ZERO_STRUCT(io.smb2);
2936         io.generic.level = RAW_OPEN_SMB2;
2937         io.smb2.in.create_flags = 0;
2938         io.smb2.in.desired_access = 0x0017019f;
2939         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2940         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2941         io.smb2.in.share_access = 0;
2942         io.smb2.in.alloc_size = 0;
2943         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2944         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2945         io.smb2.in.security_flags = 0;
2946         io.smb2.in.fname = BASEDIR;
2947
2948         status = smb2_create(tree, torture, &(io.smb2));
2949         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2950         d1 = io.smb2.out.file.handle;
2951
2952         ZERO_STRUCT(io.smb2);
2953         io.generic.level = RAW_OPEN_SMB2;
2954         io.smb2.in.create_flags = 0;
2955         io.smb2.in.desired_access = 0x0017019f;
2956         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2957         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2958         io.smb2.in.share_access = 0;
2959         io.smb2.in.alloc_size = 0;
2960         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2961         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2962         io.smb2.in.security_flags = 0;
2963         io.smb2.in.fname = BASEDIR "\\file.txt";
2964
2965         status = smb2_create(tree, torture, &(io.smb2));
2966         torture_assert_ntstatus_ok(torture, status, "smb2_create file");
2967         h1 = io.smb2.out.file.handle;
2968
2969         if (!server_is_osx) {
2970                 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
2971
2972                 ZERO_STRUCT(sinfo);
2973                 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2974                 sinfo.rename_information.in.file.handle = d1;
2975                 sinfo.rename_information.in.overwrite = 0;
2976                 sinfo.rename_information.in.root_fid = 0;
2977                 sinfo.rename_information.in.new_name = renamedir;
2978                 status = smb2_setinfo_file(tree, &sinfo);
2979
2980                 torture_assert_ntstatus_equal(torture, status,
2981                                               NT_STATUS_ACCESS_DENIED,
2982                                               "smb2_setinfo_file");
2983
2984                 ZERO_STRUCT(cl.smb2);
2985                 cl.smb2.level = RAW_CLOSE_SMB2;
2986                 cl.smb2.in.file.handle = d1;
2987                 status = smb2_close(tree, &(cl.smb2));
2988                 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2989                 ZERO_STRUCT(d1);
2990         }
2991
2992         torture_comment(torture, "Enabling AAPL\n");
2993
2994         ret = enable_aapl(torture, tree);
2995         torture_assert(torture, ret == true, "enable_aapl failed");
2996
2997         torture_comment(torture, "Renaming directory with AAPL\n");
2998
2999         ZERO_STRUCT(io.smb2);
3000         io.generic.level = RAW_OPEN_SMB2;
3001         io.smb2.in.desired_access = 0x0017019f;
3002         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3003         io.smb2.in.share_access = 0;
3004         io.smb2.in.alloc_size = 0;
3005         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
3006         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3007         io.smb2.in.security_flags = 0;
3008         io.smb2.in.fname = BASEDIR;
3009
3010         status = smb2_create(tree, torture, &(io.smb2));
3011         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3012         d1 = io.smb2.out.file.handle;
3013
3014         ZERO_STRUCT(sinfo);
3015         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3016         sinfo.rename_information.in.file.handle = d1;
3017         sinfo.rename_information.in.overwrite = 0;
3018         sinfo.rename_information.in.root_fid = 0;
3019         sinfo.rename_information.in.new_name = renamedir;
3020
3021         status = smb2_setinfo_file(tree, &sinfo);
3022         torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
3023
3024         ZERO_STRUCT(cl.smb2);
3025         cl.smb2.level = RAW_CLOSE_SMB2;
3026         cl.smb2.in.file.handle = d1;
3027         status = smb2_close(tree, &(cl.smb2));
3028         torture_assert_ntstatus_ok(torture, status, "smb2_close");
3029         ZERO_STRUCT(d1);
3030
3031         cl.smb2.in.file.handle = h1;
3032         status = smb2_close(tree, &(cl.smb2));
3033         torture_assert_ntstatus_ok(torture, status, "smb2_close");
3034         ZERO_STRUCT(h1);
3035
3036         torture_comment(torture, "Cleaning up\n");
3037
3038         if (h1.data[0] || h1.data[1]) {
3039                 ZERO_STRUCT(cl.smb2);
3040                 cl.smb2.level = RAW_CLOSE_SMB2;
3041                 cl.smb2.in.file.handle = h1;
3042                 status = smb2_close(tree, &(cl.smb2));
3043         }
3044
3045         smb2_util_unlink(tree, BASEDIR "\\file.txt");
3046         smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
3047         smb2_deltree(tree, renamedir);
3048         smb2_deltree(tree, BASEDIR);
3049         return ret;
3050 }
3051
3052 static bool test_afpinfo_enoent(struct torture_context *tctx,
3053                                 struct smb2_tree *tree)
3054 {
3055         bool ret = true;
3056         NTSTATUS status;
3057         struct smb2_create create;
3058         struct smb2_handle h1;
3059         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3060         const char *fname = BASEDIR "\\file";
3061         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3062
3063         torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
3064
3065         smb2_deltree(tree, BASEDIR);
3066         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3067         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3068         smb2_util_close(tree, h1);
3069         ret = torture_setup_file(mem_ctx, tree, fname, false);
3070         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3071
3072         torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3073
3074         ZERO_STRUCT(create);
3075         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3076         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3077         create.in.fname = sname;
3078
3079         status = smb2_create(tree, mem_ctx, &create);
3080         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3081                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3082
3083 done:
3084         smb2_util_unlink(tree, fname);
3085         smb2_util_rmdir(tree, BASEDIR);
3086         return ret;
3087 }
3088
3089 static bool test_create_delete_on_close(struct torture_context *tctx,
3090                                         struct smb2_tree *tree)
3091 {
3092         bool ret = true;
3093         NTSTATUS status;
3094         struct smb2_create create;
3095         struct smb2_handle h1;
3096         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3097         const char *fname = BASEDIR "\\file";
3098         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3099         const char *type_creator = "SMB,OLE!";
3100         AfpInfo *info = NULL;
3101         const char *streams_basic[] = {
3102                 "::$DATA"
3103         };
3104         const char *streams_afpinfo[] = {
3105                 "::$DATA",
3106                 AFPINFO_STREAM
3107         };
3108
3109         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3110
3111         torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
3112
3113         smb2_deltree(tree, BASEDIR);
3114         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3115         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3116         smb2_util_close(tree, h1);
3117         ret = torture_setup_file(mem_ctx, tree, fname, false);
3118         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3119
3120         torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3121
3122         ZERO_STRUCT(create);
3123         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3124         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3125         create.in.fname = sname;
3126
3127         status = smb2_create(tree, mem_ctx, &create);
3128         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3129                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3130
3131         ZERO_STRUCT(create);
3132         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3133         create.in.desired_access = SEC_FILE_ALL;
3134         create.in.fname = sname;
3135
3136         status = smb2_create(tree, mem_ctx, &create);
3137         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3138                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3139
3140         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3141         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3142
3143         torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
3144
3145         info = torture_afpinfo_new(mem_ctx);
3146         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3147
3148         memcpy(info->afpi_FinderInfo, type_creator, 8);
3149         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3150         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3151
3152         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3153                            0, 60, 16, 8, type_creator);
3154         torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
3155
3156         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3157         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3158
3159         ZERO_STRUCT(create);
3160         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3161         create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3162         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3163         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3164         create.in.fname = sname;
3165         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3166
3167         status = smb2_create(tree, mem_ctx, &create);
3168         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3169
3170         h1 = create.out.file.handle;
3171         smb2_util_close(tree, h1);
3172
3173         ZERO_STRUCT(create);
3174         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3175         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
3176         create.in.fname = sname;
3177         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3178         status = smb2_create(tree, mem_ctx, &create);
3179         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3180                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3181
3182         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3183         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3184
3185 done:
3186         smb2_util_unlink(tree, fname);
3187         smb2_util_rmdir(tree, BASEDIR);
3188         return ret;
3189 }
3190
3191 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
3192                                          struct smb2_tree *tree)
3193 {
3194         bool ret = true;
3195         NTSTATUS status;
3196         struct smb2_create create;
3197         union smb_setfileinfo sfinfo;
3198         struct smb2_handle h1;
3199         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3200         const char *fname = BASEDIR "\\file";
3201         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3202         const char *type_creator = "SMB,OLE!";
3203         AfpInfo *info = NULL;
3204         const char *streams_basic[] = {
3205                 "::$DATA"
3206         };
3207
3208         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3209
3210         torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
3211
3212         smb2_deltree(tree, BASEDIR);
3213         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3214         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3215         smb2_util_close(tree, h1);
3216         ret = torture_setup_file(mem_ctx, tree, fname, false);
3217         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3218
3219         info = torture_afpinfo_new(mem_ctx);
3220         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3221         memcpy(info->afpi_FinderInfo, type_creator, 8);
3222         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3223         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3224
3225         ZERO_STRUCT(create);
3226         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3227         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3228         create.in.fname = sname;
3229         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3230         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3231
3232         status = smb2_create(tree, mem_ctx, &create);
3233         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3234
3235         h1 = create.out.file.handle;
3236
3237         /* Delete stream via setinfo delete-on-close */
3238         ZERO_STRUCT(sfinfo);
3239         sfinfo.disposition_info.in.delete_on_close = 1;
3240         sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3241         sfinfo.generic.in.file.handle = h1;
3242         status = smb2_setinfo_file(tree, &sfinfo);
3243         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3244
3245         smb2_util_close(tree, h1);
3246
3247         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3248         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3249
3250         ZERO_STRUCT(create);
3251         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3252         create.in.desired_access = SEC_FILE_ALL;
3253         create.in.fname = sname;
3254         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3255         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3256         status = smb2_create(tree, mem_ctx, &create);
3257         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3258                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3259
3260 done:
3261         smb2_util_unlink(tree, fname);
3262         smb2_util_rmdir(tree, BASEDIR);
3263         return ret;
3264 }
3265
3266 static bool test_setinfo_eof(struct torture_context *tctx,
3267                              struct smb2_tree *tree)
3268 {
3269         bool ret = true;
3270         NTSTATUS status;
3271         struct smb2_create create;
3272         union smb_setfileinfo sfinfo;
3273         struct smb2_handle h1;
3274         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3275         const char *fname = BASEDIR "\\file";
3276         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3277         const char *type_creator = "SMB,OLE!";
3278         AfpInfo *info = NULL;
3279         const char *streams_afpinfo[] = {
3280                 "::$DATA",
3281                 AFPINFO_STREAM
3282         };
3283
3284         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3285
3286         torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\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         info = torture_afpinfo_new(mem_ctx);
3296         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3297         memcpy(info->afpi_FinderInfo, type_creator, 8);
3298         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3299         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3300
3301         ZERO_STRUCT(create);
3302         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3303         create.in.desired_access = SEC_FILE_ALL;
3304         create.in.fname = sname;
3305         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3306         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3307
3308         status = smb2_create(tree, mem_ctx, &create);
3309         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3310
3311         h1 = create.out.file.handle;
3312
3313         torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
3314
3315         /* Test setinfo end-of-file info */
3316         ZERO_STRUCT(sfinfo);
3317         sfinfo.generic.in.file.handle = h1;
3318         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3319         sfinfo.position_information.in.position = 61;
3320         status = smb2_setinfo_file(tree, &sfinfo);
3321         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
3322                                            ret, done, "set eof 61 failed");
3323
3324         torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
3325
3326         /* Truncation returns success, but has no effect */
3327         ZERO_STRUCT(sfinfo);
3328         sfinfo.generic.in.file.handle = h1;
3329         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3330         sfinfo.position_information.in.position = 1;
3331         status = smb2_setinfo_file(tree, &sfinfo);
3332         torture_assert_ntstatus_ok_goto(tctx, status,
3333                                         ret, done, "set eof 1 failed");
3334         smb2_util_close(tree, h1);
3335
3336         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3337         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3338
3339         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3340                            0, 60, 16, 8, type_creator);
3341         torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3342
3343         ZERO_STRUCT(create);
3344         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3345         create.in.desired_access = SEC_FILE_ALL;
3346         create.in.fname = sname;
3347         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3348         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3349
3350         status = smb2_create(tree, mem_ctx, &create);
3351         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3352
3353         h1 = create.out.file.handle;
3354
3355         /*
3356          * Delete stream via setinfo end-of-file info to 0, should
3357          * return success but stream MUST NOT deleted
3358          */
3359         ZERO_STRUCT(sfinfo);
3360         sfinfo.generic.in.file.handle = h1;
3361         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3362         sfinfo.position_information.in.position = 0;
3363         status = smb2_setinfo_file(tree, &sfinfo);
3364         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3365
3366         smb2_util_close(tree, h1);
3367
3368         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3369         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3370
3371         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3372                            0, 60, 16, 8, type_creator);
3373         torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3374
3375 done:
3376         smb2_util_unlink(tree, fname);
3377         smb2_util_rmdir(tree, BASEDIR);
3378         return ret;
3379 }
3380
3381 static bool test_afpinfo_all0(struct torture_context *tctx,
3382                               struct smb2_tree *tree)
3383 {
3384         bool ret = true;
3385         NTSTATUS status;
3386         struct smb2_handle h1;
3387         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3388         const char *fname = BASEDIR "\\file";
3389         const char *type_creator = "SMB,OLE!";
3390         AfpInfo *info = NULL;
3391         const char *streams_basic[] = {
3392                 "::$DATA"
3393         };
3394         const char *streams_afpinfo[] = {
3395                 "::$DATA",
3396                 AFPINFO_STREAM
3397         };
3398
3399         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3400
3401         torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
3402
3403         smb2_deltree(tree, BASEDIR);
3404         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3405         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3406         smb2_util_close(tree, h1);
3407         ret = torture_setup_file(mem_ctx, tree, fname, false);
3408         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3409
3410         info = torture_afpinfo_new(mem_ctx);
3411         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3412         memcpy(info->afpi_FinderInfo, type_creator, 8);
3413         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3414         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3415
3416         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3417         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3418
3419         /* Write all 0 to AFP_AfpInfo */
3420         memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
3421         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3422         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3423
3424         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3425         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3426
3427 done:
3428         smb2_util_unlink(tree, fname);
3429         smb2_util_rmdir(tree, BASEDIR);
3430         return ret;
3431 }
3432
3433 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
3434                                                  struct smb2_tree *tree)
3435 {
3436         bool ret = true;
3437         NTSTATUS status;
3438         struct smb2_create create;
3439         struct smb2_handle h1;
3440         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3441         const char *fname = BASEDIR "\\file";
3442         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3443         const char *streams_basic[] = {
3444                 "::$DATA"
3445         };
3446         const char *streams_afpresource[] = {
3447                 "::$DATA",
3448                 AFPRESOURCE_STREAM
3449         };
3450
3451         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3452
3453         torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
3454
3455         smb2_deltree(tree, BASEDIR);
3456         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3457         torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
3458         smb2_util_close(tree, h1);
3459         ret = torture_setup_file(mem_ctx, tree, fname, false);
3460         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3461
3462         torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
3463
3464         ZERO_STRUCT(create);
3465         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3466         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3467         create.in.fname = sname;
3468
3469         status = smb2_create(tree, mem_ctx, &create);
3470         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3471                                            ret, done, "Got unexpected AFP_AfpResource stream");
3472
3473         ZERO_STRUCT(create);
3474         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3475         create.in.desired_access = SEC_FILE_ALL;
3476         create.in.fname = sname;
3477
3478         status = smb2_create(tree, mem_ctx, &create);
3479         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3480                                            ret, done, "Got unexpected AFP_AfpResource stream");
3481
3482         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3483         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3484
3485         torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
3486
3487         ret = write_stream(tree, __location__, tctx, mem_ctx,
3488                            fname, AFPRESOURCE_STREAM_NAME,
3489                            0, 10, "1234567890");
3490         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3491
3492         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3493                            0, 10, 0, 10, "1234567890");
3494         torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3495
3496         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3497         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3498
3499         ZERO_STRUCT(create);
3500         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3501         create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3502         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3503         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3504         create.in.fname = sname;
3505         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3506
3507         status = smb2_create(tree, mem_ctx, &create);
3508         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3509
3510         h1 = create.out.file.handle;
3511         smb2_util_close(tree, h1);
3512
3513         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3514         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3515
3516         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3517                            0, 10, 0, 10, "1234567890");
3518         torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3519
3520 done:
3521         smb2_util_unlink(tree, fname);
3522         smb2_util_rmdir(tree, BASEDIR);
3523         return ret;
3524 }
3525
3526 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
3527                                                   struct smb2_tree *tree)
3528 {
3529         bool ret = true;
3530         NTSTATUS status;
3531         struct smb2_create create;
3532         union smb_setfileinfo sfinfo;
3533         struct smb2_handle h1;
3534         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3535         const char *fname = BASEDIR "\\file";
3536         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3537         const char *streams_afpresource[] = {
3538                 "::$DATA",
3539                 AFPRESOURCE_STREAM
3540         };
3541
3542         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3543
3544         torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
3545
3546         smb2_deltree(tree, BASEDIR);
3547         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3548         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3549         smb2_util_close(tree, h1);
3550         ret = torture_setup_file(mem_ctx, tree, fname, false);
3551         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3552
3553         ret = write_stream(tree, __location__, tctx, mem_ctx,
3554                            fname, AFPRESOURCE_STREAM_NAME,
3555                            10, 10, "1234567890");
3556         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3557
3558         ZERO_STRUCT(create);
3559         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3560         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3561         create.in.fname = sname;
3562         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3563         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3564
3565         status = smb2_create(tree, mem_ctx, &create);
3566         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3567
3568         h1 = create.out.file.handle;
3569
3570         /* Try to delete stream via setinfo delete-on-close */
3571         ZERO_STRUCT(sfinfo);
3572         sfinfo.disposition_info.in.delete_on_close = 1;
3573         sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3574         sfinfo.generic.in.file.handle = h1;
3575         status = smb2_setinfo_file(tree, &sfinfo);
3576         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3577
3578         smb2_util_close(tree, h1);
3579
3580         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3581         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
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         status = smb2_create(tree, mem_ctx, &create);
3590         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3591                                         "Got unexpected AFP_AfpResource stream");
3592
3593 done:
3594         smb2_util_unlink(tree, fname);
3595         smb2_util_rmdir(tree, BASEDIR);
3596         return ret;
3597 }
3598
3599 static bool test_setinfo_eof_resource(struct torture_context *tctx,
3600                                       struct smb2_tree *tree)
3601 {
3602         bool ret = true;
3603         NTSTATUS status;
3604         struct smb2_create create;
3605         union smb_setfileinfo sfinfo;
3606         union smb_fileinfo finfo;
3607         struct smb2_handle h1;
3608         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3609         const char *fname = BASEDIR "\\file";
3610         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3611         const char *streams_basic[] = {
3612                 "::$DATA"
3613         };
3614
3615         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3616
3617         torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
3618
3619         smb2_deltree(tree, BASEDIR);
3620         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3621         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3622         smb2_util_close(tree, h1);
3623         ret = torture_setup_file(mem_ctx, tree, fname, false);
3624         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3625
3626         ret = write_stream(tree, __location__, tctx, mem_ctx,
3627                            fname, AFPRESOURCE_STREAM_NAME,
3628                            10, 10, "1234567890");
3629         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3630
3631         ZERO_STRUCT(create);
3632         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3633         create.in.desired_access = SEC_FILE_ALL;
3634         create.in.fname = sname;
3635         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3636         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3637
3638         status = smb2_create(tree, mem_ctx, &create);
3639         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3640
3641         h1 = create.out.file.handle;
3642
3643         torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
3644
3645         /* Test setinfo end-of-file info */
3646         ZERO_STRUCT(sfinfo);
3647         sfinfo.generic.in.file.handle = h1;
3648         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3649         sfinfo.position_information.in.position = 1;
3650         status = smb2_setinfo_file(tree, &sfinfo);
3651         torture_assert_ntstatus_ok_goto(tctx, status,
3652                                         ret, done, "set eof 1 failed");
3653
3654         smb2_util_close(tree, h1);
3655
3656         /* Check size == 1 */
3657         ZERO_STRUCT(create);
3658         create.in.fname = sname;
3659         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3660         create.in.desired_access = SEC_FILE_ALL;
3661         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3662         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3663         status = smb2_create(tree, mem_ctx, &create);
3664         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3665
3666         h1 = create.out.file.handle;
3667
3668         ZERO_STRUCT(finfo);
3669         finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
3670         finfo.generic.in.file.handle = h1;
3671         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
3672         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
3673
3674         smb2_util_close(tree, h1);
3675
3676         torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
3677
3678         ZERO_STRUCT(create);
3679         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3680         create.in.desired_access = SEC_FILE_ALL;
3681         create.in.fname = sname;
3682         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3683         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3684
3685         status = smb2_create(tree, mem_ctx, &create);
3686         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3687
3688         h1 = create.out.file.handle;
3689
3690         /*
3691          * Delete stream via setinfo end-of-file info to 0, this
3692          * should delete the stream.
3693          */
3694         ZERO_STRUCT(sfinfo);
3695         sfinfo.generic.in.file.handle = h1;
3696         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3697         sfinfo.position_information.in.position = 0;
3698         status = smb2_setinfo_file(tree, &sfinfo);
3699         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3700
3701         smb2_util_close(tree, h1);
3702
3703         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3704         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3705
3706         ZERO_STRUCT(create);
3707         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3708         create.in.desired_access = SEC_FILE_ALL;
3709         create.in.fname = sname;
3710         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3711         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3712
3713         status = smb2_create(tree, mem_ctx, &create);
3714         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3715                                            ret, done, "smb2_create failed");
3716
3717 done:
3718         smb2_util_unlink(tree, fname);
3719         smb2_util_rmdir(tree, BASEDIR);
3720         return ret;
3721 }
3722
3723 /*
3724  * This tests that right after creating the AFP_AfpInfo stream,
3725  * reading from the stream returns an empty, default metadata blob of
3726  * 60 bytes.
3727  *
3728  * NOTE: against OS X SMB server this only works if the read request
3729  * is compounded with the create that created the stream, is fails
3730  * otherwise. We don't care...
3731  */
3732 static bool test_null_afpinfo(struct torture_context *tctx,
3733                               struct smb2_tree *tree)
3734 {
3735         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3736         const char *fname = "test_null_afpinfo";
3737         const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
3738         NTSTATUS status;
3739         bool ret = true;
3740         struct smb2_request *req[3];
3741         struct smb2_handle handle;
3742         struct smb2_create create;
3743         struct smb2_read read;
3744         AfpInfo *afpinfo = NULL;
3745         char *afpinfo_buf = NULL;
3746         const char *type_creator = "SMB,OLE!";
3747
3748         torture_comment(tctx, "Checking create of AfpInfo stream\n");
3749
3750         smb2_util_unlink(tree, fname);
3751
3752         ret = torture_setup_file(mem_ctx, tree, fname, false);
3753         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
3754
3755         ZERO_STRUCT(create);
3756         create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
3757         create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
3758         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3759         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3760         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
3761         create.in.fname = sname;
3762
3763         smb2_transport_compound_start(tree->session->transport, 2);
3764
3765         req[0] = smb2_create_send(tree, &create);
3766
3767         handle.data[0] = UINT64_MAX;
3768         handle.data[1] = UINT64_MAX;
3769
3770         smb2_transport_compound_set_related(tree->session->transport, true);
3771
3772         ZERO_STRUCT(read);
3773         read.in.file.handle = handle;
3774         read.in.length = AFP_INFO_SIZE;
3775         req[1] = smb2_read_send(tree, &read);
3776
3777         status = smb2_create_recv(req[0], tree, &create);
3778         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
3779
3780         handle = create.out.file.handle;
3781
3782         status = smb2_read_recv(req[1], tree, &read);
3783         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
3784
3785         afpinfo = torture_afpinfo_new(mem_ctx);
3786         torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
3787
3788         memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
3789
3790         afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
3791         torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
3792
3793         status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
3794         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
3795
3796         smb2_util_close(tree, handle);
3797
3798         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3799                            0, 60, 16, 8, type_creator);
3800         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
3801
3802 done:
3803         smb2_util_unlink(tree, fname);
3804         talloc_free(mem_ctx);
3805         return ret;
3806 }
3807
3808 static bool test_delete_file_with_rfork(struct torture_context *tctx,
3809                                         struct smb2_tree *tree)
3810 {
3811         const char *fname = "torture_write_rfork_io";
3812         const char *rfork_content = "1234567890";
3813         NTSTATUS status;
3814         bool ret = true;
3815
3816         smb2_util_unlink(tree, fname);
3817
3818         torture_comment(tctx, "Test deleting file with resource fork\n");
3819
3820         ret = torture_setup_file(tctx, tree, fname, false);
3821         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
3822
3823         ret = write_stream(tree, __location__, tctx, tctx,
3824                            fname, AFPRESOURCE_STREAM_NAME,
3825                            10, 10, rfork_content);
3826         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
3827
3828         ret = check_stream(tree, __location__, tctx, tctx,
3829                            fname, AFPRESOURCE_STREAM_NAME,
3830                            0, 20, 10, 10, rfork_content);
3831         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
3832
3833         status = smb2_util_unlink(tree, fname);
3834         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
3835
3836 done:
3837         return ret;
3838 }
3839
3840 static bool test_rename_and_read_rsrc(struct torture_context *tctx,
3841                                       struct smb2_tree *tree)
3842 {
3843         bool ret = true;
3844         NTSTATUS status;
3845         struct smb2_create create, create2;
3846         struct smb2_handle h1, h2;
3847         const char *fname = "test_rename_openfile";
3848         const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
3849         const char *fname_renamed = "test_rename_openfile_renamed";
3850         const char *data = "1234567890";
3851         union smb_setfileinfo sinfo;
3852         struct smb2_read r;
3853
3854         ret = enable_aapl(tctx, tree);
3855         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
3856
3857         torture_comment(tctx, "Create file with resource fork\n");
3858
3859         ret = torture_setup_file(tctx, tree, fname, false);
3860         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3861
3862         ret = write_stream(tree, __location__, tctx, tctx,
3863                            fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
3864         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
3865
3866         torture_comment(tctx, "Open resource fork\n");
3867
3868         ZERO_STRUCT(create);
3869         create.in.desired_access = SEC_FILE_ALL;
3870         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3871         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3872         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3873         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3874         create.in.fname = sname;
3875
3876         status = smb2_create(tree, tctx, &create);
3877         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3878
3879         h1 = create.out.file.handle;
3880
3881         torture_comment(tctx, "Rename base file\n");
3882
3883         ZERO_STRUCT(create2);
3884         create2.in.desired_access = SEC_FILE_ALL;
3885         create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3886         create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3887         create2.in.create_disposition = NTCREATEX_DISP_OPEN;
3888         create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3889         create2.in.fname = fname;
3890
3891         status = smb2_create(tree, tctx, &create2);
3892         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3893
3894         h2 = create2.out.file.handle;
3895
3896         ZERO_STRUCT(sinfo);
3897         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3898         sinfo.rename_information.in.file.handle = h2;
3899         sinfo.rename_information.in.overwrite = 0;
3900         sinfo.rename_information.in.root_fid = 0;
3901         sinfo.rename_information.in.new_name = fname_renamed;
3902
3903         status = smb2_setinfo_file(tree, &sinfo);
3904         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file failed");
3905
3906         smb2_util_close(tree, h2);
3907
3908         ZERO_STRUCT(r);
3909         r.in.file.handle = h1;
3910         r.in.length      = 10;
3911         r.in.offset      = 0;
3912
3913         torture_comment(tctx, "Read resource fork of renamed file\n");
3914
3915         status = smb2_read(tree, tree, &r);
3916         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read failed");
3917
3918         smb2_util_close(tree, h1);
3919
3920         torture_assert_goto(tctx, r.out.data.length == 10, ret, done,
3921                             talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected 10\n",
3922                                             (intmax_t)r.out.data.length));
3923
3924         torture_assert_goto(tctx, memcmp(r.out.data.data, data, 10) == 0, ret, done,
3925                             talloc_asprintf(tctx, "Bad data in stream\n"));
3926
3927 done:
3928         smb2_util_unlink(tree, fname);
3929         smb2_util_unlink(tree, fname_renamed);
3930
3931         return ret;
3932 }
3933
3934 static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
3935                                            struct smb2_tree *tree)
3936 {
3937         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3938         const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
3939         const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
3940         NTSTATUS status;
3941         struct smb2_handle testdirh;
3942         bool ret = true;
3943         struct smb2_create io;
3944         AfpInfo *info;
3945         const char *type_creator = "SMB,OLE!";
3946         struct smb2_find f;
3947         unsigned int count;
3948         union smb_search_data *d;
3949         uint64_t rfork_len;
3950         int i;
3951
3952         smb2_deltree(tree, BASEDIR);
3953
3954         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
3955         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
3956         smb2_util_close(tree, testdirh);
3957
3958         torture_comment(tctx, "Enabling AAPL\n");
3959
3960         ret = enable_aapl(tctx, tree);
3961         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
3962
3963         /*
3964          * Now that Requested AAPL extensions are enabled, setup some
3965          * Mac files with metadata and resource fork
3966          */
3967
3968         torture_comment(tctx, "Preparing file\n");
3969
3970         ret = torture_setup_file(mem_ctx, tree, fname, false);
3971         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
3972
3973         info = torture_afpinfo_new(mem_ctx);
3974         torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
3975
3976         memcpy(info->afpi_FinderInfo, type_creator, 8);
3977         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3978         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3979
3980         ret = write_stream(tree, __location__, tctx, mem_ctx,
3981                            fname, AFPRESOURCE_STREAM_NAME,
3982                            0, 3, "foo");
3983         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
3984
3985         /*
3986          * Ok, file is prepared, now call smb2/find
3987          */
3988
3989         torture_comment(tctx, "Issue find\n");
3990
3991         ZERO_STRUCT(io);
3992         io.in.desired_access = SEC_RIGHTS_DIR_READ;
3993         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
3994         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3995         io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
3996                               NTCREATEX_SHARE_ACCESS_WRITE |
3997                               NTCREATEX_SHARE_ACCESS_DELETE);
3998         io.in.create_disposition = NTCREATEX_DISP_OPEN;
3999         io.in.fname = BASEDIR;
4000         status = smb2_create(tree, tctx, &io);
4001         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4002
4003         ZERO_STRUCT(f);
4004         f.in.file.handle        = io.out.file.handle;
4005         f.in.pattern            = "*";
4006         f.in.max_response_size  = 0x1000;
4007         f.in.level              = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
4008
4009         status = smb2_find_level(tree, tree, &f, &count, &d);
4010         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
4011
4012         status = smb2_util_close(tree, io.out.file.handle);
4013         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
4014
4015         torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
4016
4017         for (i = 0; i < count; i++) {
4018                 const char *found = d[i].id_both_directory_info.name.s;
4019
4020                 if (!strcmp(found, ".") || !strcmp(found, ".."))
4021                         continue;
4022                 break;
4023         }
4024
4025         torture_assert_str_equal_goto(tctx,
4026                                       d[i].id_both_directory_info.name.s, name,
4027                                       ret, done, "bad name");
4028
4029         rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
4030         torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
4031
4032         torture_assert_mem_equal_goto(tctx, type_creator,
4033                                       d[i].id_both_directory_info.short_name_buf + 8,
4034                                       8, ret, done, "Bad FinderInfo");
4035 done:
4036         smb2_util_unlink(tree, fname);
4037         smb2_deltree(tree, BASEDIR);
4038         talloc_free(mem_ctx);
4039         return ret;
4040 }
4041
4042 static bool test_invalid_afpinfo(struct torture_context *tctx,
4043                                  struct smb2_tree *tree1,
4044                                  struct smb2_tree *tree2)
4045 {
4046         const char *fname = "filtest_invalid_afpinfo";
4047         const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
4048         struct smb2_create create;
4049         const char *streams_basic[] = {
4050                 "::$DATA"
4051         };
4052         const char *streams_afpinfo[] = {
4053                 "::$DATA",
4054                 AFPINFO_STREAM
4055         };
4056         NTSTATUS status;
4057         bool ret = true;
4058
4059         if (tree2 == NULL) {
4060                 torture_skip_goto(tctx, done, "need second share without fruit\n");
4061         }
4062
4063         torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
4064
4065         ret = torture_setup_file(tctx, tree2, fname, false);
4066         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4067
4068         ret = write_stream(tree2, __location__, tctx, tctx,
4069                            fname, AFPINFO_STREAM_NAME,
4070                            0, 3, "foo");
4071         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4072
4073         ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
4074         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4075
4076         torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
4077
4078         ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
4079         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4080
4081         torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
4082
4083         ZERO_STRUCT(create);
4084         create.in.desired_access = SEC_FILE_ALL;
4085         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4086         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4087         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4088         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4089         create.in.fname = sname;
4090
4091         status = smb2_create(tree1, tctx, &create);
4092         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4093                                            ret, done, "Stream still around?");
4094
4095 done:
4096         smb2_util_unlink(tree1, fname);
4097         return ret;
4098 }
4099
4100 static bool test_zero_file_id(struct torture_context *tctx,
4101                               struct smb2_tree *tree)
4102 {
4103         const char *fname = "filtest_file_id";
4104         struct smb2_create create = {0};
4105         NTSTATUS status;
4106         bool ret = true;
4107         uint8_t zero_file_id[8] = {0};
4108
4109         torture_comment(tctx, "Testing zero file id\n");
4110
4111         ret = torture_setup_file(tctx, tree, fname, false);
4112         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4113
4114         ZERO_STRUCT(create);
4115         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4116         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4117         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4118         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4119         create.in.fname = fname;
4120         create.in.query_on_disk_id = true;
4121
4122         status = smb2_create(tree, tctx, &create);
4123         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
4124                                            done,
4125                                            "test file could not be opened");
4126         torture_assert_mem_not_equal_goto(tctx, create.out.on_disk_id,
4127                                           zero_file_id, 8, ret, done,
4128                                           "unexpected zero file id");
4129
4130         smb2_util_close(tree, create.out.file.handle);
4131
4132         ret = enable_aapl(tctx, tree);
4133         torture_assert(tctx, ret == true, "enable_aapl failed");
4134
4135         ZERO_STRUCT(create);
4136         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4137         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4138         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4139         create.in.create_disposition = NTCREATEX_DISP_OPEN;
4140         create.in.fname = fname;
4141         create.in.query_on_disk_id = true;
4142
4143         status = smb2_create(tree, tctx, &create);
4144         torture_assert_ntstatus_equal_goto(
4145             tctx, status, NT_STATUS_OK, ret, done,
4146             "test file could not be opened with AAPL");
4147         torture_assert_mem_equal_goto(tctx, create.out.on_disk_id, zero_file_id,
4148                                       8, ret, done, "non-zero file id");
4149
4150         smb2_util_close(tree, create.out.file.handle);
4151
4152 done:
4153         smb2_util_unlink(tree, fname);
4154         return ret;
4155 }
4156
4157 static bool copy_one_stream(struct torture_context *torture,
4158                             struct smb2_tree *tree,
4159                             TALLOC_CTX *tmp_ctx,
4160                             const char *src_sname,
4161                             const char *dst_sname)
4162 {
4163         struct smb2_handle src_h = {{0}};
4164         struct smb2_handle dest_h = {{0}};
4165         NTSTATUS status;
4166         union smb_ioctl io;
4167         struct srv_copychunk_copy cc_copy;
4168         struct srv_copychunk_rsp cc_rsp;
4169         enum ndr_err_code ndr_ret;
4170         bool ok = false;
4171
4172         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4173                                    1, /* 1 chunk */
4174                                    src_sname,
4175                                    &src_h, 256, /* fill 256 byte src file */
4176                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4177                                    dst_sname,
4178                                    &dest_h, 0,  /* 0 byte dest file */
4179                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4180                                    &cc_copy,
4181                                    &io);
4182         torture_assert_goto(torture, ok == true, ok, done,
4183                             "setup copy chunk error\n");
4184
4185         /* copy all src file data (via a single chunk desc) */
4186         cc_copy.chunks[0].source_off = 0;
4187         cc_copy.chunks[0].target_off = 0;
4188         cc_copy.chunks[0].length = 256;
4189
4190         ndr_ret = ndr_push_struct_blob(
4191                 &io.smb2.in.out, tmp_ctx, &cc_copy,
4192                 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4193
4194         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4195                                    "ndr_push_srv_copychunk_copy\n");
4196
4197         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4198         torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4199                                         "FSCTL_SRV_COPYCHUNK\n");
4200
4201         ndr_ret = ndr_pull_struct_blob(
4202                 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4203                 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4204
4205         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4206                                    "ndr_pull_srv_copychunk_rsp\n");
4207
4208         ok = check_copy_chunk_rsp(torture, &cc_rsp,
4209                                   1,    /* chunks written */
4210                                   0,    /* chunk bytes unsuccessfully written */
4211                                   256); /* total bytes written */
4212         torture_assert_goto(torture, ok == true, ok, done,
4213                             "bad copy chunk response data\n");
4214
4215         ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
4216         if (!ok) {
4217                 torture_fail(torture, "inconsistent file data\n");
4218         }
4219
4220 done:
4221         if (!smb2_util_handle_empty(src_h)) {
4222                 smb2_util_close(tree, src_h);
4223         }
4224         if (!smb2_util_handle_empty(dest_h)) {
4225                 smb2_util_close(tree, dest_h);
4226         }
4227
4228         return ok;
4229 }
4230
4231 static bool copy_finderinfo_stream(struct torture_context *torture,
4232                                    struct smb2_tree *tree,
4233                                    TALLOC_CTX *tmp_ctx,
4234                                    const char *src_name,
4235                                    const char *dst_name)
4236 {
4237         struct smb2_handle src_h = {{0}};
4238         struct smb2_handle dest_h = {{0}};
4239         NTSTATUS status;
4240         union smb_ioctl io;
4241         struct srv_copychunk_copy cc_copy;
4242         struct srv_copychunk_rsp cc_rsp;
4243         enum ndr_err_code ndr_ret;
4244         const char *type_creator = "SMB,OLE!";
4245         AfpInfo *info = NULL;
4246         const char *src_name_afpinfo = NULL;
4247         const char *dst_name_afpinfo = NULL;
4248         bool ok = false;
4249
4250         src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
4251                                            AFPINFO_STREAM);
4252         torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
4253                                      "talloc_asprintf failed\n");
4254
4255         dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
4256                                            AFPINFO_STREAM);
4257         torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
4258                                      "talloc_asprintf failed\n");
4259
4260         info = torture_afpinfo_new(tmp_ctx);
4261         torture_assert_not_null_goto(torture, info, ok, done,
4262                                      "torture_afpinfo_new failed\n");
4263
4264         memcpy(info->afpi_FinderInfo, type_creator, 8);
4265         ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
4266         torture_assert_goto(torture, ok == true, ok, done,
4267                             "torture_write_afpinfo failed\n");
4268
4269         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4270                                    1, /* 1 chunk */
4271                                    src_name_afpinfo,
4272                                    &src_h, 0,
4273                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4274                                    dst_name_afpinfo,
4275                                    &dest_h, 0,
4276                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4277                                    &cc_copy,
4278                                    &io);
4279         torture_assert_goto(torture, ok == true, ok, done,
4280                             "setup copy chunk error\n");
4281
4282         /* copy all src file data (via a single chunk desc) */
4283         cc_copy.chunks[0].source_off = 0;
4284         cc_copy.chunks[0].target_off = 0;
4285         cc_copy.chunks[0].length = 60;
4286
4287         ndr_ret = ndr_push_struct_blob(
4288                 &io.smb2.in.out, tmp_ctx, &cc_copy,
4289                 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4290
4291         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4292                                    "ndr_push_srv_copychunk_copy\n");
4293
4294         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4295         torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4296                                         "FSCTL_SRV_COPYCHUNK\n");
4297
4298         ndr_ret = ndr_pull_struct_blob(
4299                 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4300                 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4301
4302         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4303                                    "ndr_pull_srv_copychunk_rsp\n");
4304
4305         smb2_util_close(tree, src_h);
4306         ZERO_STRUCT(src_h);
4307         smb2_util_close(tree, dest_h);
4308         ZERO_STRUCT(dest_h);
4309
4310         ok = check_copy_chunk_rsp(torture, &cc_rsp,
4311                                   1,    /* chunks written */
4312                                   0,    /* chunk bytes unsuccessfully written */
4313                                   60); /* total bytes written */
4314         torture_assert_goto(torture, ok == true, ok, done,
4315                             "bad copy chunk response data\n");
4316
4317         ok = check_stream(tree, __location__, torture, tmp_ctx,
4318                           dst_name, AFPINFO_STREAM,
4319                           0, 60, 16, 8, type_creator);
4320         torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
4321
4322 done:
4323         if (!smb2_util_handle_empty(src_h)) {
4324                 smb2_util_close(tree, src_h);
4325         }
4326         if (!smb2_util_handle_empty(dest_h)) {
4327                 smb2_util_close(tree, dest_h);
4328         }
4329
4330         return ok;
4331 }
4332
4333 static bool test_copy_chunk_streams(struct torture_context *torture,
4334                                     struct smb2_tree *tree)
4335 {
4336         const char *src_name = "src";
4337         const char *dst_name = "dst";
4338         struct names {
4339                 const char *src_sname;
4340                 const char *dst_sname;
4341         } names[] = {
4342                 { "src:foo", "dst:foo" },
4343                 { "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
4344         };
4345         int i;
4346         TALLOC_CTX *tmp_ctx = NULL;
4347         bool ok = false;
4348
4349         tmp_ctx = talloc_new(tree);
4350         torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
4351                                      "torture_setup_file\n");
4352
4353         smb2_util_unlink(tree, src_name);
4354         smb2_util_unlink(tree, dst_name);
4355
4356         ok = torture_setup_file(torture, tree, src_name, false);
4357         torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4358         ok = torture_setup_file(torture, tree, dst_name, false);
4359         torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4360
4361         for (i = 0; i < ARRAY_SIZE(names); i++) {
4362                 ok = copy_one_stream(torture, tree, tmp_ctx,
4363                                      names[i].src_sname,
4364                                      names[i].dst_sname);
4365                 torture_assert_goto(torture, ok == true, ok, done,
4366                                     "copy_one_stream failed\n");
4367         }
4368
4369         ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
4370                                     src_name, dst_name);
4371         torture_assert_goto(torture, ok == true, ok, done,
4372                             "copy_finderinfo_stream failed\n");
4373
4374 done:
4375         smb2_util_unlink(tree, src_name);
4376         smb2_util_unlink(tree, dst_name);
4377         talloc_free(tmp_ctx);
4378         return ok;
4379 }
4380
4381 /*
4382  * Note: This test depends on "vfs objects = catia fruit streams_xattr".  For
4383  * some tests torture must be run on the host it tests and takes an additional
4384  * argument with the local path to the share:
4385  * "--option=torture:localdir=<SHAREPATH>".
4386  *
4387  * When running against an OS X SMB server add "--option=torture:osx=true"
4388  */
4389 struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
4390 {
4391         struct torture_suite *suite = torture_suite_create(
4392                 ctx, "fruit");
4393
4394         suite->description = talloc_strdup(suite, "vfs_fruit tests");
4395
4396         torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
4397         torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
4398         torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
4399         torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
4400         torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
4401         torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
4402         torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
4403         torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
4404         torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
4405         torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
4406         torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
4407         torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
4408         torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
4409         torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
4410         torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
4411         torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
4412         torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
4413         torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
4414         torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
4415         torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
4416         torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
4417         torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
4418         torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
4419         torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
4420
4421         return suite;
4422 }
4423
4424 struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
4425 {
4426         struct torture_suite *suite = torture_suite_create(
4427                 ctx, "fruit_netatalk");
4428
4429         suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
4430
4431         torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
4432         torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
4433
4434         return suite;
4435 }
4436
4437 struct torture_suite *torture_vfs_fruit_file_id(TALLOC_CTX *ctx)
4438 {
4439         struct torture_suite *suite =
4440             torture_suite_create(ctx, "fruit_file_id");
4441
4442         suite->description =
4443             talloc_strdup(suite, "vfs_fruit tests for on-disk file ID that "
4444                                  "require fruit:zero_file_id=yes");
4445
4446         torture_suite_add_1smb2_test(suite, "zero file id if AAPL negotiated",
4447                                      test_zero_file_id);
4448
4449         return suite;
4450 }