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