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