2 Unix SMB/CIFS implementation.
6 Copyright (C) Ralph Boehme 2014
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.
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.
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/>.
23 #include "system/filesys.h"
24 #include "libcli/libcli.h"
25 #include "libcli/smb2/smb2.h"
26 #include "libcli/smb2/smb2_calls.h"
27 #include "libcli/smb/smb2_create_ctx.h"
28 #include "lib/cmdline/popt_common.h"
29 #include "param/param.h"
30 #include "libcli/resolve/resolve.h"
31 #include "MacExtensions.h"
32 #include "lib/util/tsort.h"
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"
44 #define BASEDIR "vfs_fruit_dir"
45 #define FNAME_CC_SRC "testfsctl.dat"
46 #define FNAME_CC_DST "testfsctl2.dat"
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)); \
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); \
66 static bool check_stream_list(struct smb2_tree *tree,
67 struct torture_context *tctx,
73 static int qsort_string(char * const *s1, char * const *s2)
75 return strcmp(*s1, *s2);
78 static int qsort_stream(const struct stream_struct * s1, const struct stream_struct *s2)
80 return strcmp(s1->stream_name.s, s2->stream_name.s);
85 * This is hokey, but what else can we do?
87 #if defined(HAVE_ATTROPEN) || defined(FREEBSD)
88 #define AFPINFO_EA_NETATALK "org.netatalk.Metadata"
89 #define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork"
91 #define AFPINFO_EA_NETATALK "user.org.netatalk.Metadata"
92 #define AFPRESOURCE_EA_NETATALK "user.org.netatalk.ResourceFork"
96 The metadata xattr char buf below contains the following attributes:
98 -------------------------------------------------------------------------------
99 Entry ID : 00000008 : File Dates Info
100 Offset : 00000162 : 354
101 Length : 00000010 : 16
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
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
112 -------------------------------------------------------------------------------
113 Entry ID : 00000009 : Finder Info
114 Offset : 0000007A : 122
115 Length : 00000020 : 32
118 Type : 42415252 : BARR
119 Creator : 464F4F4F : FOOO
134 Location v : 0000 : 0
135 Location h : 0000 : 0
139 Rsvd|IconID: 0000 : 0
159 Rsvd|commnt: 0000 : 0
160 PutAway : 00000000 : 0
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 : ................
166 -------------------------------------------------------------------------------
167 Entry ID : 0000000E : AFP File Info
168 Offset : 00000172 : 370
169 Length : 00000004 : 4
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 : ....
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,
230 The buf below contains the following AppleDouble encoded data:
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
238 -------------------------------------------------------------------------------
239 Entry ID : 00000009 : Finder Info
240 Offset : 00000032 : 50
241 Length : 00000EB0 : 3760
244 Type : 54455354 : TEST
245 Creator : 534C4F57 : SLOW
260 Location v : 0000 : 0
261 Location h : 0000 : 0
265 Rsvd|IconID: 0000 : 0
285 Rsvd|commnt: 0000 : 0
286 PutAway : 00000000 : 0
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 : ....
301 offset : 000000BC : 188
302 length : 0000005B : 91
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
317 offset : 00000117 : 279
318 length : 00000003 : 3
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
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 : ................
344 00000EA0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
346 -------------------------------------------------------------------------------
347 Entry ID : 00000002 : Resource Fork
348 Offset : 00000EE2 : 3810
349 Length : 0000011E : 286
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 : ..............
372 $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
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
890 * The buf below contains the following AppleDouble encoded data:
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
898 * -------------------------------------------------------------------------------
899 * Entry ID : 00000002 : Resource Fork
900 * Offset : 00000052 : 82
901 * Length : 0000011E : 286
903 * -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
904 * 00000000 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
905 * 00000010 : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo
906 * 00000020 : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
907 * 00000030 : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 : left blank ..
908 * 00000040 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
909 * 00000050 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
910 * 00000060 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
911 * 00000070 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
912 * 00000080 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
913 * 00000090 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
914 * 000000A0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
915 * 000000B0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
916 * 000000C0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
917 * 000000D0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
918 * 000000E0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
919 * 000000F0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
920 * 00000100 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
921 * 00000110 : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF : ..............
923 * Entry ID : 00000009 : Finder Info
924 * Offset : 00000032 : 50
925 * Length : 00000020 : 32
927 * -NOTE------: cannot detect whether FInfo or DInfo. assume FInfo.
930 * Type : 57415645 : WAVE
931 * Creator : 5054756C : PTul
946 * Location v : 0000 : 0
947 * Location h : 0000 : 0
951 * Rsvd|IconID: 0000 : 0
971 * Rsvd|commnt: 0000 : 0
972 * PutAway : 00000000 : 0
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 : ................
978 * It was created with:
979 * $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
981 static char osx_adouble_without_xattr[] = {
982 0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
983 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
984 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
985 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
986 0x00, 0x52, 0x00, 0x00, 0x01, 0x1e, 0x00, 0x00,
987 0x00, 0x09, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00,
988 0x00, 0x20, 0x57, 0x41, 0x56, 0x45, 0x50, 0x54,
989 0x75, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
990 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
992 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
993 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
994 0x00, 0x1e, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72,
995 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20,
996 0x66, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
997 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
998 0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
999 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
1000 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1001 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1002 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1003 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1004 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1005 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1007 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1008 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1009 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1010 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1011 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1012 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1013 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1014 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1015 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1016 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1017 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1018 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1019 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1020 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1021 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1022 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1023 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1024 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1025 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1026 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1027 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
1031 * talloc and intialize an AfpInfo
1033 static AfpInfo *torture_afpinfo_new(TALLOC_CTX *mem_ctx)
1037 info = talloc_zero(mem_ctx, AfpInfo);
1042 info->afpi_Signature = AFP_Signature;
1043 info->afpi_Version = AFP_Version;
1044 info->afpi_BackupTime = AFP_BackupTime;
1050 * Pack AfpInfo into a talloced buffer
1052 static char *torture_afpinfo_pack(TALLOC_CTX *mem_ctx,
1057 buf = talloc_zero_array(mem_ctx, char, AFP_INFO_SIZE);
1062 RSIVAL(buf, 0, info->afpi_Signature);
1063 RSIVAL(buf, 4, info->afpi_Version);
1064 RSIVAL(buf, 12, info->afpi_BackupTime);
1065 memcpy(buf + 16, info->afpi_FinderInfo, sizeof(info->afpi_FinderInfo));
1074 static void torture_afpinfo_unpack(AfpInfo *info, char *data)
1076 info->afpi_Signature = RIVAL(data, 0);
1077 info->afpi_Version = RIVAL(data, 4);
1078 info->afpi_BackupTime = RIVAL(data, 12);
1079 memcpy(info->afpi_FinderInfo, (const char *)data + 16,
1080 sizeof(info->afpi_FinderInfo));
1084 static bool torture_write_afpinfo(struct smb2_tree *tree,
1085 struct torture_context *tctx,
1086 TALLOC_CTX *mem_ctx,
1090 struct smb2_handle handle;
1091 struct smb2_create io;
1093 const char *full_name;
1097 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, AFPINFO_STREAM_NAME);
1098 if (full_name == NULL) {
1099 torture_comment(tctx, "talloc_asprintf error\n");
1103 io.in.desired_access = SEC_FILE_WRITE_DATA;
1104 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1105 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1106 io.in.create_options = 0;
1107 io.in.fname = full_name;
1109 status = smb2_create(tree, mem_ctx, &io);
1110 CHECK_STATUS(status, NT_STATUS_OK);
1112 handle = io.out.file.handle;
1114 infobuf = torture_afpinfo_pack(mem_ctx, info);
1115 if (infobuf == NULL) {
1119 status = smb2_util_write(tree, handle, infobuf, 0, AFP_INFO_SIZE);
1120 CHECK_STATUS(status, NT_STATUS_OK);
1122 smb2_util_close(tree, handle);
1129 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1130 * compare against buffer 'value'
1132 static bool check_stream(struct smb2_tree *tree,
1133 const char *location,
1134 struct torture_context *tctx,
1135 TALLOC_CTX *mem_ctx,
1144 struct smb2_handle handle;
1145 struct smb2_create create;
1151 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1152 if (full_name == NULL) {
1153 torture_comment(tctx, "talloc_asprintf error\n");
1156 ZERO_STRUCT(create);
1157 create.in.desired_access = SEC_FILE_READ_DATA;
1158 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1159 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1160 create.in.fname = full_name;
1162 torture_comment(tctx, "Open stream %s\n", full_name);
1164 status = smb2_create(tree, mem_ctx, &create);
1165 if (!NT_STATUS_IS_OK(status)) {
1166 TALLOC_FREE(full_name);
1167 if (value == NULL) {
1170 torture_comment(tctx, "Unable to open stream %s\n", full_name);
1174 handle = create.out.file.handle;
1175 if (value == NULL) {
1176 TALLOC_FREE(full_name);
1177 smb2_util_close(tree, handle);
1182 r.in.file.handle = handle;
1183 r.in.length = read_count;
1184 r.in.offset = read_offset;
1186 status = smb2_read(tree, tree, &r);
1188 torture_assert_ntstatus_ok_goto(
1189 tctx, status, ret, done,
1190 talloc_asprintf(tctx, "(%s) Failed to read %lu bytes from stream '%s'\n",
1191 location, (long)strlen(value), full_name));
1193 torture_assert_goto(tctx, r.out.data.length == read_count, ret, done,
1194 talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected %jd\n",
1195 (intmax_t)r.out.data.length, (intmax_t)read_count));
1197 torture_assert_goto(
1198 tctx, memcmp(r.out.data.data + comp_offset, value, comp_count) == 0,
1200 talloc_asprintf(tctx, "(%s) Bad data in stream\n", location));
1203 TALLOC_FREE(full_name);
1204 smb2_util_close(tree, handle);
1209 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1210 * compare against buffer 'value'
1212 static ssize_t read_stream(struct smb2_tree *tree,
1213 const char *location,
1214 struct torture_context *tctx,
1215 TALLOC_CTX *mem_ctx,
1221 struct smb2_handle handle;
1222 struct smb2_create create;
1225 const char *full_name;
1228 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1229 if (full_name == NULL) {
1230 torture_comment(tctx, "talloc_asprintf error\n");
1233 ZERO_STRUCT(create);
1234 create.in.desired_access = SEC_FILE_READ_DATA;
1235 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1236 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1237 create.in.fname = full_name;
1239 torture_comment(tctx, "Open stream %s\n", full_name);
1241 status = smb2_create(tree, mem_ctx, &create);
1242 if (!NT_STATUS_IS_OK(status)) {
1243 torture_comment(tctx, "Unable to open stream %s\n",
1248 handle = create.out.file.handle;
1251 r.in.file.handle = handle;
1252 r.in.length = read_count;
1253 r.in.offset = read_offset;
1255 status = smb2_read(tree, tree, &r);
1256 if (!NT_STATUS_IS_OK(status)) {
1257 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
1260 smb2_util_close(tree, handle);
1266 return r.out.data.length;
1270 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1271 * compare against buffer 'value'
1273 static bool write_stream(struct smb2_tree *tree,
1274 const char *location,
1275 struct torture_context *tctx,
1276 TALLOC_CTX *mem_ctx,
1283 struct smb2_handle handle;
1284 struct smb2_create create;
1286 const char *full_name;
1288 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname ? sname : "");
1289 if (full_name == NULL) {
1290 torture_comment(tctx, "talloc_asprintf error\n");
1293 ZERO_STRUCT(create);
1294 create.in.desired_access = SEC_FILE_WRITE_DATA;
1295 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1296 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1297 create.in.fname = full_name;
1299 status = smb2_create(tree, mem_ctx, &create);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 if (value == NULL) {
1304 torture_comment(tctx, "Unable to open stream %s\n",
1311 handle = create.out.file.handle;
1312 if (value == NULL) {
1316 status = smb2_util_write(tree, handle, value, offset, size);
1318 if (!NT_STATUS_IS_OK(status)) {
1319 torture_comment(tctx, "(%s) Failed to write %lu bytes to "
1320 "stream '%s'\n", location, (long)size, full_name);
1324 smb2_util_close(tree, handle);
1328 static bool torture_setup_local_xattr(struct torture_context *tctx,
1329 const char *path_option,
1332 const char *metadata,
1340 spath = torture_setting_string(tctx, path_option, NULL);
1341 if (spath == NULL) {
1342 printf("No sharepath for option %s\n", path_option);
1346 path = talloc_asprintf(tctx, "%s/%s", spath, name);
1348 result = setxattr(path, xattr, metadata, size, 0);
1359 * Create a file or directory
1361 static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree,
1362 const char *name, bool dir)
1364 struct smb2_create io;
1367 smb2_util_unlink(tree, name);
1369 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1370 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1371 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1372 io.in.share_access =
1373 NTCREATEX_SHARE_ACCESS_DELETE|
1374 NTCREATEX_SHARE_ACCESS_READ|
1375 NTCREATEX_SHARE_ACCESS_WRITE;
1376 io.in.create_options = 0;
1379 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1380 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
1381 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1382 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1385 status = smb2_create(tree, mem_ctx, &io);
1386 if (!NT_STATUS_IS_OK(status)) {
1390 status = smb2_util_close(tree, io.out.file.handle);
1391 if (!NT_STATUS_IS_OK(status)) {
1398 static bool enable_aapl(struct torture_context *tctx,
1399 struct smb2_tree *tree)
1401 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1404 struct smb2_create io;
1406 struct smb2_create_blob *aapl = NULL;
1407 uint32_t aapl_server_caps;
1408 uint32_t expected_scaps = (SMB2_CRTCTX_AAPL_UNIX_BASED |
1409 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1410 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1411 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
1412 bool is_osx_server = torture_setting_bool(tctx, "osx", false);
1415 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1416 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1417 io.in.create_disposition = NTCREATEX_DISP_OPEN;
1418 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1419 NTCREATEX_SHARE_ACCESS_READ |
1420 NTCREATEX_SHARE_ACCESS_WRITE);
1424 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1425 * controls behaviour of Apple's SMB2 extensions for the whole
1429 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1430 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1431 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1432 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1433 SMB2_CRTCTX_AAPL_MODEL_INFO));
1434 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1435 SMB2_CRTCTX_AAPL_UNIX_BASED |
1436 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1438 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1439 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_blob_add");
1441 status = smb2_create(tree, tctx, &io);
1442 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1444 status = smb2_util_close(tree, io.out.file.handle);
1445 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close");
1448 * Now check returned AAPL context
1450 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1452 aapl = smb2_create_blob_find(&io.out.blobs,
1453 SMB2_CREATE_TAG_AAPL);
1454 torture_assert_goto(tctx, aapl != NULL, ret, done, "missing AAPL context");
1456 if (!is_osx_server) {
1457 size_t expected_aapl_ctx_size;
1459 expected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
1461 torture_assert_goto(
1462 tctx, aapl->data.length == expected_aapl_ctx_size,
1463 ret, done, "bad AAPL size");
1466 aapl_server_caps = BVAL(aapl->data.data, 16);
1467 torture_assert_goto(tctx, aapl_server_caps == expected_scaps,
1468 ret, done, "bad AAPL caps");
1471 talloc_free(mem_ctx);
1475 static bool test_read_netatalk_metadata(struct torture_context *tctx,
1476 struct smb2_tree *tree)
1478 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1479 const char *fname = BASEDIR "\\torture_read_metadata";
1481 struct smb2_handle testdirh;
1484 const char *localdir = NULL;
1486 torture_comment(tctx, "Checking metadata access\n");
1488 localdir = torture_setting_string(tctx, "localdir", NULL);
1489 if (localdir == NULL) {
1490 torture_skip(tctx, "Need localdir for test");
1493 smb2_util_unlink(tree, fname);
1495 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1496 CHECK_STATUS(status, NT_STATUS_OK);
1497 smb2_util_close(tree, testdirh);
1499 ret = torture_setup_file(mem_ctx, tree, fname, false);
1504 ret = torture_setup_local_xattr(tctx, "localdir",
1505 BASEDIR "/torture_read_metadata",
1506 AFPINFO_EA_NETATALK,
1507 metadata_xattr, sizeof(metadata_xattr));
1512 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1513 0, 60, 0, 4, "AFP");
1514 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1516 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1517 0, 60, 16, 8, "BARRFOOO");
1518 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1520 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1521 16, 8, 0, 3, "AFP");
1522 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1524 /* Check reading offset and read size > sizeof(AFPINFO_STREAM) */
1526 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1527 AFPINFO_STREAM, 0, 61);
1528 CHECK_VALUE(len, 60);
1530 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1531 AFPINFO_STREAM, 59, 2);
1532 CHECK_VALUE(len, 2);
1534 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1535 AFPINFO_STREAM, 60, 1);
1536 CHECK_VALUE(len, 1);
1538 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1539 AFPINFO_STREAM, 61, 1);
1540 CHECK_VALUE(len, 0);
1543 smb2_deltree(tree, BASEDIR);
1544 talloc_free(mem_ctx);
1548 static bool test_read_afpinfo(struct torture_context *tctx,
1549 struct smb2_tree *tree)
1551 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1552 const char *fname = BASEDIR "\\torture_read_metadata";
1554 struct smb2_handle testdirh;
1558 const char *type_creator = "SMB,OLE!";
1560 torture_comment(tctx, "Checking metadata access\n");
1562 smb2_util_unlink(tree, fname);
1564 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1565 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
1566 smb2_util_close(tree, testdirh);
1568 ret = torture_setup_file(mem_ctx, tree, fname, false);
1569 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
1571 info = torture_afpinfo_new(mem_ctx);
1572 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
1574 memcpy(info->afpi_FinderInfo, type_creator, 8);
1575 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1576 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
1578 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1579 0, 60, 0, 4, "AFP");
1580 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1582 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1583 0, 60, 16, 8, type_creator);
1584 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1587 * OS X ignores offset <= 60 and treats the as
1588 * offset=0. Reading from offsets > 60 returns EOF=0.
1591 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1592 16, 8, 0, 8, "AFP\0\0\0\001\0");
1593 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1595 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1596 AFPINFO_STREAM, 0, 61);
1597 torture_assert_goto(tctx, len == 60, ret, done, "read_stream failed");
1599 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1600 AFPINFO_STREAM, 59, 2);
1601 torture_assert_goto(tctx, len == 2, ret, done, "read_stream failed");
1603 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1605 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1607 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1608 AFPINFO_STREAM, 60, 1);
1609 torture_assert_goto(tctx, len == 1, ret, done, "read_stream failed");
1611 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1613 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1615 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1616 AFPINFO_STREAM, 61, 1);
1617 torture_assert_goto(tctx, len == 0, ret, done, "read_stream failed");
1620 smb2_util_unlink(tree, fname);
1621 smb2_deltree(tree, BASEDIR);
1622 talloc_free(mem_ctx);
1626 static bool test_write_atalk_metadata(struct torture_context *tctx,
1627 struct smb2_tree *tree)
1629 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1630 const char *fname = BASEDIR "\\torture_write_metadata";
1631 const char *type_creator = "SMB,OLE!";
1633 struct smb2_handle testdirh;
1637 smb2_deltree(tree, BASEDIR);
1638 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1639 CHECK_STATUS(status, NT_STATUS_OK);
1640 smb2_util_close(tree, testdirh);
1642 ret = torture_setup_file(mem_ctx, tree, fname, false);
1647 info = torture_afpinfo_new(mem_ctx);
1652 memcpy(info->afpi_FinderInfo, type_creator, 8);
1653 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1654 ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1655 0, 60, 16, 8, type_creator);
1658 smb2_util_unlink(tree, fname);
1659 smb2_deltree(tree, BASEDIR);
1660 talloc_free(mem_ctx);
1664 static bool test_write_atalk_rfork_io(struct torture_context *tctx,
1665 struct smb2_tree *tree)
1667 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1668 const char *fname = BASEDIR "\\torture_write_rfork_io";
1669 const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
1670 const char *rfork_content = "1234567890";
1672 struct smb2_handle testdirh;
1676 struct smb2_handle filehandle;
1677 union smb_fileinfo finfo;
1678 union smb_setfileinfo sinfo;
1680 smb2_util_unlink(tree, fname);
1682 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1683 CHECK_STATUS(status, NT_STATUS_OK);
1684 smb2_util_close(tree, testdirh);
1686 ret = torture_setup_file(mem_ctx, tree, fname, false);
1691 torture_comment(tctx, "(%s) writing to resource fork\n",
1694 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1695 fname, AFPRESOURCE_STREAM_NAME,
1696 10, 10, rfork_content);
1698 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1699 fname, AFPRESOURCE_STREAM_NAME,
1700 0, 20, 10, 10, rfork_content);
1702 /* Check size after write */
1705 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1706 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1707 SEC_FILE_WRITE_ATTRIBUTE;
1708 io.smb2.in.fname = rfork;
1709 status = smb2_create(tree, mem_ctx, &(io.smb2));
1710 CHECK_STATUS(status, NT_STATUS_OK);
1711 filehandle = io.smb2.out.file.handle;
1713 torture_comment(tctx, "(%s) check resource fork size after write\n",
1717 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1718 finfo.generic.in.file.handle = filehandle;
1719 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1720 CHECK_STATUS(status, NT_STATUS_OK);
1721 if (finfo.all_info.out.size != 20) {
1722 torture_result(tctx, TORTURE_FAIL,
1723 "(%s) Incorrect resource fork size\n",
1726 smb2_util_close(tree, filehandle);
1729 smb2_util_close(tree, filehandle);
1731 /* Write at large offset */
1733 torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
1736 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1737 fname, AFPRESOURCE_STREAM_NAME,
1738 (off_t)64*1024*1024, 10, rfork_content);
1740 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1741 fname, AFPRESOURCE_STREAM_NAME,
1742 (off_t)64*1024*1024, 10, 0, 10, rfork_content);
1744 /* Truncate back to size of 1 byte */
1746 torture_comment(tctx, "(%s) truncate resource fork and check size\n",
1750 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1751 io.smb2.in.desired_access = SEC_FILE_ALL;
1752 io.smb2.in.fname = rfork;
1753 status = smb2_create(tree, mem_ctx, &(io.smb2));
1754 CHECK_STATUS(status, NT_STATUS_OK);
1755 filehandle = io.smb2.out.file.handle;
1758 sinfo.end_of_file_info.level =
1759 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1760 sinfo.end_of_file_info.in.file.handle = filehandle;
1761 sinfo.end_of_file_info.in.size = 1;
1762 status = smb2_setinfo_file(tree, &sinfo);
1763 CHECK_STATUS(status, NT_STATUS_OK);
1765 smb2_util_close(tree, filehandle);
1767 /* Now check size */
1769 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1770 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1771 SEC_FILE_WRITE_ATTRIBUTE;
1772 io.smb2.in.fname = rfork;
1773 status = smb2_create(tree, mem_ctx, &(io.smb2));
1774 CHECK_STATUS(status, NT_STATUS_OK);
1775 filehandle = io.smb2.out.file.handle;
1778 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1779 finfo.generic.in.file.handle = filehandle;
1780 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1781 CHECK_STATUS(status, NT_STATUS_OK);
1782 if (finfo.all_info.out.size != 1) {
1783 torture_result(tctx, TORTURE_FAIL,
1784 "(%s) Incorrect resource fork size\n",
1787 smb2_util_close(tree, filehandle);
1790 smb2_util_close(tree, filehandle);
1793 smb2_util_unlink(tree, fname);
1794 smb2_deltree(tree, BASEDIR);
1795 talloc_free(mem_ctx);
1799 static bool test_rfork_truncate(struct torture_context *tctx,
1800 struct smb2_tree *tree)
1802 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1803 const char *fname = BASEDIR "\\torture_rfork_truncate";
1804 const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
1805 const char *rfork_content = "1234567890";
1807 struct smb2_handle testdirh;
1809 struct smb2_create create;
1810 struct smb2_handle fh1, fh2, fh3;
1811 union smb_setfileinfo sinfo;
1813 smb2_util_unlink(tree, fname);
1815 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1816 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1817 smb2_util_close(tree, testdirh);
1819 ret = torture_setup_file(mem_ctx, tree, fname, false);
1824 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1825 fname, AFPRESOURCE_STREAM,
1826 10, 10, rfork_content);
1828 /* Truncate back to size 0, further access MUST return ENOENT */
1830 torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
1833 ZERO_STRUCT(create);
1834 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1835 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1836 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1837 create.in.fname = fname;
1838 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1839 NTCREATEX_SHARE_ACCESS_READ |
1840 NTCREATEX_SHARE_ACCESS_WRITE;
1841 status = smb2_create(tree, mem_ctx, &create);
1842 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1843 fh1 = create.out.file.handle;
1845 ZERO_STRUCT(create);
1846 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1847 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1848 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1849 create.in.fname = rfork;
1850 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1851 NTCREATEX_SHARE_ACCESS_READ |
1852 NTCREATEX_SHARE_ACCESS_WRITE;
1853 status = smb2_create(tree, mem_ctx, &create);
1854 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1855 fh2 = create.out.file.handle;
1858 sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1859 sinfo.end_of_file_info.in.file.handle = fh2;
1860 sinfo.end_of_file_info.in.size = 0;
1861 status = smb2_setinfo_file(tree, &sinfo);
1862 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
1865 * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
1867 ZERO_STRUCT(create);
1868 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1869 create.in.desired_access = SEC_FILE_ALL;
1870 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1871 create.in.fname = rfork;
1872 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1873 NTCREATEX_SHARE_ACCESS_READ |
1874 NTCREATEX_SHARE_ACCESS_WRITE;
1875 status = smb2_create(tree, mem_ctx, &create);
1876 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1879 * Do another open on the rfork and write to the new handle. A
1880 * naive server might unlink the AppleDouble resource fork
1881 * file when its truncated to 0 bytes above, so in case both
1882 * open handles share the same underlying fd, the unlink would
1883 * cause the below write to be lost.
1885 ZERO_STRUCT(create);
1886 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1887 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1888 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1889 create.in.fname = rfork;
1890 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1891 NTCREATEX_SHARE_ACCESS_READ |
1892 NTCREATEX_SHARE_ACCESS_WRITE;
1893 status = smb2_create(tree, mem_ctx, &create);
1894 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1895 fh3 = create.out.file.handle;
1897 status = smb2_util_write(tree, fh3, "foo", 0, 3);
1898 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
1900 smb2_util_close(tree, fh3);
1901 smb2_util_close(tree, fh2);
1902 smb2_util_close(tree, fh1);
1904 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
1906 torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1909 smb2_util_unlink(tree, fname);
1910 smb2_deltree(tree, BASEDIR);
1911 talloc_free(mem_ctx);
1915 static bool test_rfork_create(struct torture_context *tctx,
1916 struct smb2_tree *tree)
1918 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1919 const char *fname = BASEDIR "\\torture_rfork_create";
1920 const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1922 struct smb2_handle testdirh;
1924 struct smb2_create create;
1925 struct smb2_handle fh1;
1926 const char *streams[] = {
1929 union smb_fileinfo finfo;
1931 smb2_util_unlink(tree, fname);
1933 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1934 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1935 smb2_util_close(tree, testdirh);
1937 ret = torture_setup_file(mem_ctx, tree, fname, false);
1942 torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
1945 ZERO_STRUCT(create);
1946 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1947 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1948 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1949 create.in.fname = rfork;
1950 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1951 NTCREATEX_SHARE_ACCESS_READ |
1952 NTCREATEX_SHARE_ACCESS_WRITE;
1953 status = smb2_create(tree, mem_ctx, &create);
1954 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1956 torture_comment(tctx, "(%s) create resource fork\n", __location__);
1958 ZERO_STRUCT(create);
1959 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1960 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1961 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1962 create.in.fname = rfork;
1963 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1964 NTCREATEX_SHARE_ACCESS_READ |
1965 NTCREATEX_SHARE_ACCESS_WRITE;
1966 status = smb2_create(tree, mem_ctx, &create);
1967 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1968 fh1 = create.out.file.handle;
1970 torture_comment(tctx, "(%s) getinfo on create handle\n",
1974 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1975 finfo.generic.in.file.handle = fh1;
1976 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1977 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
1978 if (finfo.all_info.out.size != 0) {
1979 torture_result(tctx, TORTURE_FAIL,
1980 "(%s) Incorrect resource fork size\n",
1983 smb2_util_close(tree, fh1);
1987 torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
1990 ZERO_STRUCT(create);
1991 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1992 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1993 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1994 create.in.fname = rfork;
1995 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1996 NTCREATEX_SHARE_ACCESS_READ |
1997 NTCREATEX_SHARE_ACCESS_WRITE;
1998 status = smb2_create(tree, mem_ctx, &create);
1999 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
2001 ret = check_stream_list(tree, tctx, fname, 1, streams, false);
2002 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2004 torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
2007 ZERO_STRUCT(create);
2008 create.in.create_disposition = NTCREATEX_DISP_OPEN;
2009 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
2010 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2011 create.in.fname = rfork;
2012 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
2013 NTCREATEX_SHARE_ACCESS_READ |
2014 NTCREATEX_SHARE_ACCESS_WRITE;
2015 status = smb2_create(tree, mem_ctx, &create);
2016 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
2019 smb2_util_unlink(tree, fname);
2020 smb2_deltree(tree, BASEDIR);
2021 talloc_free(mem_ctx);
2025 static bool test_rfork_create_ro(struct torture_context *tctx,
2026 struct smb2_tree *tree)
2028 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2029 const char *fname = BASEDIR "\\torture_rfork_create";
2030 const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
2032 struct smb2_handle testdirh;
2034 struct smb2_create create;
2036 smb2_util_unlink(tree, fname);
2037 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2038 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2039 "torture_smb2_testdir\n");
2040 smb2_util_close(tree, testdirh);
2042 ret = torture_setup_file(mem_ctx, tree, fname, false);
2047 torture_comment(tctx, "(%s) Try opening read-only with "
2048 "open_if create disposition, should return ENOENT\n",
2051 ZERO_STRUCT(create);
2052 create.in.fname = rfork;
2053 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2054 create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
2055 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2056 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
2057 status = smb2_create(tree, mem_ctx, &(create));
2058 torture_assert_ntstatus_equal_goto(tctx, status,
2059 NT_STATUS_OBJECT_NAME_NOT_FOUND,
2060 ret, done, "smb2_create failed\n");
2062 torture_comment(tctx, "(%s) Now write something to the "
2063 "rsrc stream, then the same open should succeed\n",
2066 ret = write_stream(tree, __location__, tctx, mem_ctx,
2067 fname, AFPRESOURCE_STREAM_NAME,
2069 torture_assert_goto(tctx, ret == true, ret, done,
2070 "write_stream failed\n");
2072 ret = check_stream(tree, __location__, tctx, mem_ctx,
2073 fname, AFPRESOURCE_STREAM,
2075 torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
2077 ZERO_STRUCT(create);
2078 create.in.fname = rfork;
2079 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2080 create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
2081 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2082 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
2083 status = smb2_create(tree, mem_ctx, &(create));
2084 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2085 "smb2_create failed\n");
2087 smb2_util_close(tree, create.out.file.handle);
2090 smb2_util_unlink(tree, fname);
2091 smb2_deltree(tree, BASEDIR);
2092 talloc_free(mem_ctx);
2096 static bool test_adouble_conversion(struct torture_context *tctx,
2097 struct smb2_tree *tree)
2099 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2100 const char *fname = BASEDIR "\\test_adouble_conversion";
2101 const char *adname = BASEDIR "/._test_adouble_conversion";
2103 struct smb2_handle testdirh;
2105 const char *data = "This resource fork intentionally left blank";
2106 size_t datalen = strlen(data);
2107 const char *streams[] = {
2111 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
2112 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2114 bool is_osx = torture_setting_bool(tctx, "osx", false);
2117 torture_skip(tctx, "Test only works with Samba\n");
2120 smb2_deltree(tree, BASEDIR);
2122 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2123 CHECK_STATUS(status, NT_STATUS_OK);
2124 smb2_util_close(tree, testdirh);
2126 ret = torture_setup_file(tctx, tree, fname, false);
2127 torture_assert_goto(tctx, ret == true, ret, done,
2128 "torture_setup_file failed\n");
2130 ret = torture_setup_file(tctx, tree, adname, false);
2131 torture_assert_goto(tctx, ret == true, ret, done,
2132 "torture_setup_file failed\n");
2134 ret = write_stream(tree, __location__, tctx, mem_ctx,
2136 0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
2137 torture_assert_goto(tctx, ret == true, ret, done,
2138 "write_stream failed\n");
2140 torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
2143 ret = check_stream(tree, __location__, tctx, mem_ctx,
2144 fname, AFPRESOURCE_STREAM,
2145 16, datalen, 0, datalen, data);
2146 torture_assert_goto(tctx, ret == true, ret, done,
2147 "check AFPRESOURCE_STREAM failed\n");
2149 ret = check_stream(tree, __location__, tctx, mem_ctx,
2150 fname, AFPINFO_STREAM,
2151 0, 60, 16, 8, "TESTSLOW");
2152 torture_assert_goto(tctx, ret == true, ret, done,
2153 "check AFPINFO_STREAM failed\n");
2155 ret = check_stream(tree, __location__, tctx, mem_ctx, fname,
2156 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2158 torture_assert_goto(tctx, ret == true, ret, done,
2159 "check foo:bar stream failed\n");
2161 ret = check_stream_list(tree, tctx, fname, 5, streams, false);
2162 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2165 smb2_deltree(tree, BASEDIR);
2166 talloc_free(mem_ctx);
2171 * Test conversion of AppleDouble file without embedded xattr data
2173 static bool test_adouble_conversion_wo_xattr(struct torture_context *tctx,
2174 struct smb2_tree *tree)
2176 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2177 const char *fname = BASEDIR "\\test_adouble_conversion";
2178 const char *adname = BASEDIR "/._test_adouble_conversion";
2180 struct smb2_handle testdirh;
2182 const char *streams[] = {
2187 struct smb2_create create;
2188 struct smb2_find find;
2190 union smb_search_data *d;
2191 const char *data = "This resource fork intentionally left blank";
2192 size_t datalen = strlen(data);
2193 bool is_osx = torture_setting_bool(tctx, "osx", false);
2196 torture_skip(tctx, "Test only works with Samba\n");
2199 smb2_deltree(tree, BASEDIR);
2201 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2202 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2203 "torture_smb2_testdir failed\n");
2204 smb2_util_close(tree, testdirh);
2206 ret = torture_setup_file(tctx, tree, fname, false);
2207 torture_assert_goto(tctx, ret == true, ret, done,
2208 "torture_setup_file failed\n");
2210 ret = torture_setup_file(tctx, tree, adname, false);
2211 torture_assert_goto(tctx, ret == true, ret, done,
2212 "torture_setup_file failed\n");
2214 ret = write_stream(tree, __location__, tctx, mem_ctx,
2216 sizeof(osx_adouble_without_xattr),
2217 osx_adouble_without_xattr);
2218 torture_assert_goto(tctx, ret == true, ret, done,
2219 "write_stream failed\n");
2221 ret = enable_aapl(tctx, tree);
2222 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
2225 * Issue a smb2_find(), this triggers the server-side conversion
2228 create = (struct smb2_create) {
2229 .in.desired_access = SEC_RIGHTS_DIR_READ,
2230 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
2231 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
2232 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
2233 .in.create_disposition = NTCREATEX_DISP_OPEN,
2234 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
2235 .in.fname = BASEDIR,
2238 status = smb2_create(tree, tctx, &create);
2239 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2240 "smb2_create failed\n");
2242 find = (struct smb2_find) {
2243 .in.file.handle = create.out.file.handle,
2245 .in.max_response_size = 0x1000,
2246 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
2249 status = smb2_find_level(tree, tree, &find, &count, &d);
2250 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2251 "smb2_find_level failed\n");
2253 status = smb2_util_close(tree, create.out.file.handle);
2254 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2255 "smb2_util_close failed");
2258 * Check number of streams
2261 ret = check_stream_list(tree, tctx, fname, 3, streams, false);
2262 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2266 * Check Resourcefork data can be read.
2269 ret = check_stream(tree, __location__, tctx, mem_ctx,
2270 fname, AFPRESOURCE_STREAM,
2271 16, datalen, 0, datalen, data);
2272 torture_assert_goto(tctx, ret == true, ret, done,
2273 "check AFPRESOURCE_STREAM failed\n");
2276 * Check FinderInfo data has been migrated to stream.
2279 ret = check_stream(tree, __location__, tctx, mem_ctx,
2280 fname, AFPINFO_STREAM,
2281 0, 60, 16, 8, "WAVEPTul");
2282 torture_assert_goto(tctx, ret == true, ret, done,
2283 "check AFPINFO_STREAM failed\n");
2286 smb2_deltree(tree, BASEDIR);
2287 talloc_free(mem_ctx);
2291 static bool test_aapl(struct torture_context *tctx,
2292 struct smb2_tree *tree)
2294 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2295 const char *fname = BASEDIR "\\test_aapl";
2297 struct smb2_handle testdirh;
2299 struct smb2_create io;
2301 struct smb2_create_blob *aapl = NULL;
2303 const char *type_creator = "SMB,OLE!";
2304 char type_creator_buf[9];
2306 uint32_t aapl_reply_bitmap;
2307 uint32_t aapl_server_caps;
2308 uint32_t aapl_vol_caps;
2309 uint32_t expected_vol_caps = 0;
2313 union smb_search_data *d;
2315 bool is_osx_server = torture_setting_bool(tctx, "osx", false);
2317 smb2_deltree(tree, BASEDIR);
2319 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2320 CHECK_STATUS(status, NT_STATUS_OK);
2321 smb2_util_close(tree, testdirh);
2324 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2325 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2326 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2327 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2328 NTCREATEX_SHARE_ACCESS_READ |
2329 NTCREATEX_SHARE_ACCESS_WRITE);
2330 io.in.fname = fname;
2333 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
2334 * controls behaviour of Apple's SMB2 extensions for the whole
2338 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2339 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2340 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2341 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2342 SMB2_CRTCTX_AAPL_MODEL_INFO));
2343 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2344 SMB2_CRTCTX_AAPL_UNIX_BASED |
2345 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
2347 torture_comment(tctx, "Testing SMB2 create context AAPL\n");
2348 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2349 CHECK_STATUS(status, NT_STATUS_OK);
2351 status = smb2_create(tree, tctx, &io);
2352 CHECK_STATUS(status, NT_STATUS_OK);
2353 status = smb2_util_close(tree, io.out.file.handle);
2354 CHECK_STATUS(status, NT_STATUS_OK);
2357 * Now check returned AAPL context
2359 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
2361 aapl = smb2_create_blob_find(&io.out.blobs,
2362 SMB2_CREATE_TAG_AAPL);
2365 torture_result(tctx, TORTURE_FAIL,
2366 "(%s) unexpectedly no AAPL capabilities were returned.",
2372 if (!is_osx_server) {
2373 size_t expected_aapl_ctx_size;
2377 * uint32_t CommandCode = kAAPL_SERVER_QUERY
2378 * uint32_t Reserved = 0;
2379 * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
2380 * kAAPL_VOLUME_CAPS |
2382 * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
2383 * kAAPL_SUPPORTS_OSX_COPYFILE;
2384 * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
2385 * kAAPL_CASE_SENSITIVE;
2386 * uint32_t Pad2 = 0;
2387 * uint32_t ModelStringLen = 10;
2388 * ucs2_t ModelString[5] = "MacSamba";
2390 expected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
2392 size_ok = aapl->data.length == expected_aapl_ctx_size;
2393 torture_assert_goto(tctx, size_ok, ret, done, "bad AAPL size");
2396 aapl_cmd = IVAL(aapl->data.data, 0);
2397 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2398 torture_result(tctx, TORTURE_FAIL,
2399 "(%s) unexpected cmd: %d",
2400 __location__, (int)aapl_cmd);
2405 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2406 if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2407 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2408 SMB2_CRTCTX_AAPL_MODEL_INFO)) {
2409 torture_result(tctx, TORTURE_FAIL,
2410 "(%s) unexpected reply_bitmap: %d",
2411 __location__, (int)aapl_reply_bitmap);
2416 aapl_server_caps = BVAL(aapl->data.data, 16);
2417 if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
2418 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2419 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
2420 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
2421 torture_result(tctx, TORTURE_FAIL,
2422 "(%s) unexpected server_caps: %d",
2423 __location__, (int)aapl_server_caps);
2428 if (is_osx_server) {
2429 expected_vol_caps = 5;
2431 aapl_vol_caps = BVAL(aapl->data.data, 24);
2432 if (aapl_vol_caps != expected_vol_caps) {
2433 /* this will fail on a case insensitive fs ... */
2434 torture_result(tctx, TORTURE_FAIL,
2435 "(%s) unexpected vol_caps: %d",
2436 __location__, (int)aapl_vol_caps);
2439 ret = convert_string_talloc(mem_ctx,
2440 CH_UTF16LE, CH_UNIX,
2441 aapl->data.data + 40, 10,
2444 torture_result(tctx, TORTURE_FAIL,
2445 "(%s) convert_string_talloc() failed",
2449 torture_comment(tctx, "Got server model: \"%s\"\n", model);
2452 * Now that Requested AAPL extensions are enabled, setup some
2453 * Mac files with metadata and resource fork
2455 ret = torture_setup_file(mem_ctx, tree, fname, false);
2457 torture_result(tctx, TORTURE_FAIL,
2458 "(%s) torture_setup_file() failed",
2463 info = torture_afpinfo_new(mem_ctx);
2465 torture_result(tctx, TORTURE_FAIL,
2466 "(%s) torture_afpinfo_new() failed",
2472 memcpy(info->afpi_FinderInfo, type_creator, 8);
2473 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2475 torture_result(tctx, TORTURE_FAIL,
2476 "(%s) torture_write_afpinfo() failed",
2481 ret = write_stream(tree, __location__, tctx, mem_ctx,
2482 fname, AFPRESOURCE_STREAM_NAME,
2485 torture_result(tctx, TORTURE_FAIL,
2486 "(%s) write_stream() failed",
2492 * Ok, file is prepared, now call smb2/find
2496 io.in.desired_access = SEC_RIGHTS_DIR_READ;
2497 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2498 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2499 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
2500 NTCREATEX_SHARE_ACCESS_WRITE |
2501 NTCREATEX_SHARE_ACCESS_DELETE);
2502 io.in.create_disposition = NTCREATEX_DISP_OPEN;
2503 io.in.fname = BASEDIR;
2504 status = smb2_create(tree, tctx, &io);
2505 CHECK_STATUS(status, NT_STATUS_OK);
2508 f.in.file.handle = io.out.file.handle;
2509 f.in.pattern = "test_aapl";
2510 f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
2511 f.in.max_response_size = 0x1000;
2512 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
2514 status = smb2_find_level(tree, tree, &f, &count, &d);
2515 CHECK_STATUS(status, NT_STATUS_OK);
2517 status = smb2_util_close(tree, io.out.file.handle);
2518 CHECK_STATUS(status, NT_STATUS_OK);
2520 if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2521 torture_result(tctx, TORTURE_FAIL,
2522 "(%s) write_stream() failed",
2528 if (d[0].id_both_directory_info.short_name.private_length != 24) {
2529 torture_result(tctx, TORTURE_FAIL,
2530 "(%s) bad short_name length %" PRIu32 ", expected 24",
2531 __location__, d[0].id_both_directory_info.short_name.private_length);
2536 torture_comment(tctx, "short_name buffer:\n");
2537 dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2540 * Extract data as specified by the AAPL extension:
2541 * - ea_size contains max_access
2542 * - short_name contains resource fork length + FinderInfo
2543 * - reserved2 contains the unix mode
2545 torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2546 d[0].id_both_directory_info.ea_size);
2548 rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2549 if (rfork_len != 3) {
2550 torture_result(tctx, TORTURE_FAIL,
2551 "(%s) expected resource fork length 3, got: %" PRIu64,
2552 __location__, rfork_len);
2557 memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2558 type_creator_buf[8] = 0;
2559 if (strcmp(type_creator, type_creator_buf) != 0) {
2560 torture_result(tctx, TORTURE_FAIL,
2561 "(%s) expected type/creator \"%s\" , got: %s",
2562 __location__, type_creator, type_creator_buf);
2568 smb2_util_unlink(tree, fname);
2569 smb2_deltree(tree, BASEDIR);
2570 talloc_free(mem_ctx);
2574 static uint64_t patt_hash(uint64_t off)
2579 static bool write_pattern(struct torture_context *torture,
2580 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2581 struct smb2_handle h, uint64_t off, uint64_t len,
2587 uint64_t io_sz = MIN(1024 * 64, len);
2593 torture_assert(torture, (len % 8) == 0, "invalid write len");
2595 buf = talloc_zero_size(mem_ctx, io_sz);
2596 torture_assert(torture, (buf != NULL), "no memory for file data buf");
2599 for (i = 0; i <= io_sz - 8; i += 8) {
2600 SBVAL(buf, i, patt_hash(patt_off));
2604 status = smb2_util_write(tree, h,
2606 torture_assert_ntstatus_ok(torture, status, "file write");
2617 static bool check_pattern(struct torture_context *torture,
2618 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2619 struct smb2_handle h, uint64_t off, uint64_t len,
2626 torture_assert(torture, (len % 8) == 0, "invalid read len");
2632 uint64_t io_sz = MIN(1024 * 64, len);
2635 r.in.file.handle = h;
2636 r.in.length = io_sz;
2638 status = smb2_read(tree, mem_ctx, &r);
2639 torture_assert_ntstatus_ok(torture, status, "read");
2641 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2642 "read data len mismatch");
2644 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2645 uint64_t data = BVAL(r.out.data.data, i);
2646 torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2647 talloc_asprintf(torture, "read data "
2648 "pattern bad at %llu\n",
2649 (unsigned long long)off + i));
2651 talloc_free(r.out.data.data);
2659 static bool test_setup_open(struct torture_context *torture,
2660 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2662 struct smb2_handle *fh,
2663 uint32_t desired_access,
2664 uint32_t file_attributes)
2666 struct smb2_create io;
2670 io.in.desired_access = desired_access;
2671 io.in.file_attributes = file_attributes;
2672 io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2673 io.in.share_access =
2674 NTCREATEX_SHARE_ACCESS_DELETE|
2675 NTCREATEX_SHARE_ACCESS_READ|
2676 NTCREATEX_SHARE_ACCESS_WRITE;
2677 if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2678 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2680 io.in.fname = fname;
2682 status = smb2_create(tree, mem_ctx, &io);
2683 torture_assert_ntstatus_ok(torture, status, "file create");
2685 *fh = io.out.file.handle;
2690 static bool test_setup_create_fill(struct torture_context *torture,
2691 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2693 struct smb2_handle *fh,
2695 uint32_t desired_access,
2696 uint32_t file_attributes)
2700 ok = test_setup_open(torture, tree, mem_ctx,
2705 torture_assert(torture, ok, "file open");
2708 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2709 torture_assert(torture, ok, "write pattern");
2714 static bool test_setup_copy_chunk(struct torture_context *torture,
2715 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2717 const char *src_name,
2718 struct smb2_handle *src_h,
2720 uint32_t src_desired_access,
2721 const char *dst_name,
2722 struct smb2_handle *dest_h,
2724 uint32_t dest_desired_access,
2725 struct srv_copychunk_copy *cc_copy,
2726 union smb_ioctl *io)
2728 struct req_resume_key_rsp res_key;
2731 enum ndr_err_code ndr_ret;
2733 ok = test_setup_create_fill(torture, tree, mem_ctx, src_name,
2734 src_h, src_size, src_desired_access,
2735 FILE_ATTRIBUTE_NORMAL);
2736 torture_assert(torture, ok, "src file create fill");
2738 ok = test_setup_create_fill(torture, tree, mem_ctx, dst_name,
2739 dest_h, dest_size, dest_desired_access,
2740 FILE_ATTRIBUTE_NORMAL);
2741 torture_assert(torture, ok, "dest file create fill");
2744 io->smb2.level = RAW_IOCTL_SMB2;
2745 io->smb2.in.file.handle = *src_h;
2746 io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2747 /* Allow for Key + ContextLength + Context */
2748 io->smb2.in.max_response_size = 32;
2749 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2751 status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2752 torture_assert_ntstatus_ok(torture, status,
2753 "FSCTL_SRV_REQUEST_RESUME_KEY");
2755 ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2756 (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2758 torture_assert_ndr_success(torture, ndr_ret,
2759 "ndr_pull_req_resume_key_rsp");
2762 io->smb2.level = RAW_IOCTL_SMB2;
2763 io->smb2.in.file.handle = *dest_h;
2764 io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2765 io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2766 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2768 ZERO_STRUCTPN(cc_copy);
2769 memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2770 cc_copy->chunk_count = nchunks;
2771 cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2772 torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2778 static bool check_copy_chunk_rsp(struct torture_context *torture,
2779 struct srv_copychunk_rsp *cc_rsp,
2780 uint32_t ex_chunks_written,
2781 uint32_t ex_chunk_bytes_written,
2782 uint32_t ex_total_bytes_written)
2784 torture_assert_int_equal(torture, cc_rsp->chunks_written,
2785 ex_chunks_written, "num chunks");
2786 torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2787 ex_chunk_bytes_written, "chunk bytes written");
2788 torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2789 ex_total_bytes_written, "chunk total bytes");
2793 static bool neg_aapl_copyfile(struct torture_context *tctx,
2794 struct smb2_tree *tree,
2797 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2798 const char *fname = "aapl";
2800 struct smb2_create io;
2802 struct smb2_create_blob *aapl = NULL;
2804 uint32_t aapl_reply_bitmap;
2805 uint32_t aapl_server_caps;
2809 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2810 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2811 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2812 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2813 NTCREATEX_SHARE_ACCESS_READ |
2814 NTCREATEX_SHARE_ACCESS_WRITE);
2815 io.in.fname = fname;
2817 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2818 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2819 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2820 SBVAL(data.data, 16, flags);
2822 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2823 CHECK_STATUS(status, NT_STATUS_OK);
2825 status = smb2_create(tree, tctx, &io);
2826 CHECK_STATUS(status, NT_STATUS_OK);
2828 aapl = smb2_create_blob_find(&io.out.blobs,
2829 SMB2_CREATE_TAG_AAPL);
2835 if (aapl->data.length < 24) {
2840 aapl_cmd = IVAL(aapl->data.data, 0);
2841 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2842 torture_result(tctx, TORTURE_FAIL,
2843 "(%s) unexpected cmd: %d",
2844 __location__, (int)aapl_cmd);
2849 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2850 if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2851 torture_result(tctx, TORTURE_FAIL,
2852 "(%s) unexpected reply_bitmap: %d",
2853 __location__, (int)aapl_reply_bitmap);
2858 aapl_server_caps = BVAL(aapl->data.data, 16);
2859 if (!(aapl_server_caps & flags)) {
2860 torture_result(tctx, TORTURE_FAIL,
2861 "(%s) unexpected server_caps: %d",
2862 __location__, (int)aapl_server_caps);
2868 status = smb2_util_close(tree, io.out.file.handle);
2869 CHECK_STATUS(status, NT_STATUS_OK);
2871 smb2_util_unlink(tree, "aapl");
2872 talloc_free(mem_ctx);
2876 static bool test_copyfile(struct torture_context *torture,
2877 struct smb2_tree *tree)
2879 struct smb2_handle src_h;
2880 struct smb2_handle dest_h;
2883 TALLOC_CTX *tmp_ctx = talloc_new(tree);
2884 struct srv_copychunk_copy cc_copy;
2885 struct srv_copychunk_rsp cc_rsp;
2886 enum ndr_err_code ndr_ret;
2888 const char *sname = ":foo" "\xef\x80\xa2" "bar:$DATA";
2891 * First test a copy_chunk with a 0 chunk count without having
2892 * enabled this via AAPL. The request must not fail and the
2893 * copied length in the response must be 0. This is verified
2894 * against Windows 2008r2.
2897 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2898 0, /* 0 chunks, copyfile semantics */
2900 &src_h, 4096, /* fill 4096 byte src file */
2901 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2903 &dest_h, 0, /* 0 byte dest file */
2904 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2908 torture_fail_goto(torture, done, "setup copy chunk error");
2911 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2913 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2914 torture_assert_ndr_success(torture, ndr_ret,
2915 "ndr_push_srv_copychunk_copy");
2917 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2918 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2920 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2922 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2923 torture_assert_ndr_success(torture, ndr_ret,
2924 "ndr_pull_srv_copychunk_rsp");
2926 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2927 0, /* chunks written */
2928 0, /* chunk bytes unsuccessfully written */
2929 0); /* total bytes written */
2931 torture_fail_goto(torture, done, "bad copy chunk response data");
2935 * Now enable AAPL copyfile and test again, the file and the
2936 * stream must be copied by the server.
2938 ok = neg_aapl_copyfile(torture, tree,
2939 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2941 torture_skip_goto(torture, done, "missing AAPL copyfile");
2945 smb2_util_close(tree, src_h);
2946 smb2_util_close(tree, dest_h);
2947 smb2_util_unlink(tree, FNAME_CC_SRC);
2948 smb2_util_unlink(tree, FNAME_CC_DST);
2950 ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2952 torture_fail(torture, "setup file error");
2954 ok = write_stream(tree, __location__, torture, tmp_ctx,
2955 FNAME_CC_SRC, AFPRESOURCE_STREAM,
2956 10, 10, "1234567890");
2958 torture_fail(torture, "setup stream error");
2961 ok = write_stream(tree, __location__, torture, tmp_ctx,
2962 FNAME_CC_SRC, sname,
2963 10, 10, "abcdefghij");
2964 torture_assert_goto(torture, ok == true, ok, done, "write_stream failed\n");
2966 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2967 0, /* 0 chunks, copyfile semantics */
2969 &src_h, 4096, /* fill 4096 byte src file */
2970 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2972 &dest_h, 0, /* 0 byte dest file */
2973 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2977 torture_fail_goto(torture, done, "setup copy chunk error");
2980 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2982 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2983 torture_assert_ndr_success(torture, ndr_ret,
2984 "ndr_push_srv_copychunk_copy");
2986 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2987 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2989 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2991 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2992 torture_assert_ndr_success(torture, ndr_ret,
2993 "ndr_pull_srv_copychunk_rsp");
2995 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2996 0, /* chunks written */
2997 0, /* chunk bytes unsuccessfully written */
2998 4096); /* total bytes written */
3000 torture_fail_goto(torture, done, "bad copy chunk response data");
3003 ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
3004 SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
3006 torture_fail_goto(torture, done,"open failed");
3008 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
3010 torture_fail_goto(torture, done, "inconsistent file data");
3013 ok = check_stream(tree, __location__, torture, tmp_ctx,
3014 FNAME_CC_DST, AFPRESOURCE_STREAM,
3015 0, 20, 10, 10, "1234567890");
3017 torture_fail_goto(torture, done, "inconsistent stream data");
3020 ok = check_stream(tree, __location__, torture, tmp_ctx,
3021 FNAME_CC_DST, sname,
3022 0, 20, 10, 10, "abcdefghij");
3023 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
3026 smb2_util_close(tree, src_h);
3027 smb2_util_close(tree, dest_h);
3028 smb2_util_unlink(tree, FNAME_CC_SRC);
3029 smb2_util_unlink(tree, FNAME_CC_DST);
3030 talloc_free(tmp_ctx);
3034 static bool check_stream_list(struct smb2_tree *tree,
3035 struct torture_context *tctx,
3042 union smb_fileinfo finfo;
3045 TALLOC_CTX *tmp_ctx = talloc_new(tctx);
3047 struct stream_struct *stream_sort;
3048 struct smb2_create create;
3049 struct smb2_handle h;
3052 torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
3054 ZERO_STRUCT(create);
3055 create.in.fname = fname;
3056 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3057 create.in.desired_access = SEC_FILE_ALL;
3058 create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
3059 create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
3060 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3061 status = smb2_create(tree, tmp_ctx, &create);
3062 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
3063 h = create.out.file.handle;
3065 finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
3066 finfo.generic.in.file.handle = h;
3068 status = smb2_getinfo_file(tree, tctx, &finfo);
3069 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
3071 smb2_util_close(tree, h);
3073 torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
3074 ret, done, "stream count");
3077 TALLOC_FREE(tmp_ctx);
3081 exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
3082 torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
3084 TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
3086 stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
3087 finfo.stream_info.out.num_streams *
3088 sizeof(*stream_sort));
3089 torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
3091 TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
3093 for (i=0; i<num_exp; i++) {
3094 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
3095 i, exp_sort[i], stream_sort[i].stream_name.s);
3096 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
3097 ret, done, "stream name");
3101 TALLOC_FREE(tmp_ctx);
3108 static bool test_stream_names(struct torture_context *tctx,
3109 struct smb2_tree *tree)
3111 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3113 struct smb2_create create;
3114 struct smb2_handle h;
3115 const char *fname = BASEDIR "\\stream_names.txt";
3118 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
3119 const char *streams[] = {
3120 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
3124 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
3126 /* clean slate ...*/
3127 smb2_util_unlink(tree, fname);
3128 smb2_deltree(tree, fname);
3129 smb2_deltree(tree, BASEDIR);
3131 status = torture_smb2_testdir(tree, BASEDIR, &h);
3132 CHECK_STATUS(status, NT_STATUS_OK);
3133 smb2_util_close(tree, h);
3135 ret = torture_setup_file(mem_ctx, tree, fname, false);
3136 torture_assert_goto(tctx, ret, ret, done, "torture_setup_file");
3138 torture_comment(tctx, "(%s) testing stream names\n", __location__);
3139 ZERO_STRUCT(create);
3140 create.in.desired_access = SEC_FILE_WRITE_DATA;
3141 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3142 create.in.share_access =
3143 NTCREATEX_SHARE_ACCESS_DELETE|
3144 NTCREATEX_SHARE_ACCESS_READ|
3145 NTCREATEX_SHARE_ACCESS_WRITE;
3146 create.in.create_disposition = NTCREATEX_DISP_CREATE;
3147 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3148 create.in.fname = sname1;
3150 status = smb2_create(tree, mem_ctx, &create);
3151 CHECK_STATUS(status, NT_STATUS_OK);
3153 status = smb2_util_write(tree, create.out.file.handle, "foo", 0, 3);
3154 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3155 "smb2_util_write failed\n");
3157 smb2_util_close(tree, create.out.file.handle);
3159 ret = check_stream_list(tree, tctx, fname, 2, streams, false);
3160 CHECK_VALUE(ret, true);
3163 status = smb2_util_unlink(tree, fname);
3164 smb2_deltree(tree, BASEDIR);
3165 talloc_free(mem_ctx);
3170 /* Renaming a directory with open file, should work for OS X AAPL clients */
3171 static bool test_rename_dir_openfile(struct torture_context *torture,
3172 struct smb2_tree *tree)
3178 union smb_setfileinfo sinfo;
3179 struct smb2_handle d1, h1;
3180 const char *renamedir = BASEDIR "-new";
3181 bool server_is_osx = torture_setting_bool(torture, "osx", false);
3183 smb2_deltree(tree, BASEDIR);
3184 smb2_util_rmdir(tree, BASEDIR);
3185 smb2_deltree(tree, renamedir);
3187 ZERO_STRUCT(io.smb2);
3188 io.generic.level = RAW_OPEN_SMB2;
3189 io.smb2.in.create_flags = 0;
3190 io.smb2.in.desired_access = 0x0017019f;
3191 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
3192 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3193 io.smb2.in.share_access = 0;
3194 io.smb2.in.alloc_size = 0;
3195 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
3196 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3197 io.smb2.in.security_flags = 0;
3198 io.smb2.in.fname = BASEDIR;
3200 status = smb2_create(tree, torture, &(io.smb2));
3201 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3202 d1 = io.smb2.out.file.handle;
3204 ZERO_STRUCT(io.smb2);
3205 io.generic.level = RAW_OPEN_SMB2;
3206 io.smb2.in.create_flags = 0;
3207 io.smb2.in.desired_access = 0x0017019f;
3208 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
3209 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3210 io.smb2.in.share_access = 0;
3211 io.smb2.in.alloc_size = 0;
3212 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
3213 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3214 io.smb2.in.security_flags = 0;
3215 io.smb2.in.fname = BASEDIR "\\file.txt";
3217 status = smb2_create(tree, torture, &(io.smb2));
3218 torture_assert_ntstatus_ok(torture, status, "smb2_create file");
3219 h1 = io.smb2.out.file.handle;
3221 if (!server_is_osx) {
3222 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
3225 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3226 sinfo.rename_information.in.file.handle = d1;
3227 sinfo.rename_information.in.overwrite = 0;
3228 sinfo.rename_information.in.root_fid = 0;
3229 sinfo.rename_information.in.new_name = renamedir;
3230 status = smb2_setinfo_file(tree, &sinfo);
3232 torture_assert_ntstatus_equal(torture, status,
3233 NT_STATUS_ACCESS_DENIED,
3234 "smb2_setinfo_file");
3237 status = smb2_util_close(tree, d1);
3238 torture_assert_ntstatus_ok(torture, status, "smb2_util_close\n");
3241 torture_comment(torture, "Enabling AAPL\n");
3243 ret = enable_aapl(torture, tree);
3244 torture_assert(torture, ret == true, "enable_aapl failed");
3246 torture_comment(torture, "Renaming directory with AAPL\n");
3248 ZERO_STRUCT(io.smb2);
3249 io.generic.level = RAW_OPEN_SMB2;
3250 io.smb2.in.desired_access = 0x0017019f;
3251 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3252 io.smb2.in.share_access = 0;
3253 io.smb2.in.alloc_size = 0;
3254 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
3255 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3256 io.smb2.in.security_flags = 0;
3257 io.smb2.in.fname = BASEDIR;
3259 status = smb2_create(tree, torture, &(io.smb2));
3260 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3261 d1 = io.smb2.out.file.handle;
3264 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3265 sinfo.rename_information.in.file.handle = d1;
3266 sinfo.rename_information.in.overwrite = 0;
3267 sinfo.rename_information.in.root_fid = 0;
3268 sinfo.rename_information.in.new_name = renamedir;
3270 status = smb2_setinfo_file(tree, &sinfo);
3271 torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
3273 ZERO_STRUCT(cl.smb2);
3274 cl.smb2.level = RAW_CLOSE_SMB2;
3275 cl.smb2.in.file.handle = d1;
3276 status = smb2_close(tree, &(cl.smb2));
3277 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3280 cl.smb2.in.file.handle = h1;
3281 status = smb2_close(tree, &(cl.smb2));
3282 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3285 torture_comment(torture, "Cleaning up\n");
3287 if (h1.data[0] || h1.data[1]) {
3288 ZERO_STRUCT(cl.smb2);
3289 cl.smb2.level = RAW_CLOSE_SMB2;
3290 cl.smb2.in.file.handle = h1;
3291 status = smb2_close(tree, &(cl.smb2));
3294 smb2_util_unlink(tree, BASEDIR "\\file.txt");
3295 smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
3296 smb2_deltree(tree, renamedir);
3297 smb2_deltree(tree, BASEDIR);
3301 static bool test_afpinfo_enoent(struct torture_context *tctx,
3302 struct smb2_tree *tree)
3306 struct smb2_create create;
3307 struct smb2_handle h1;
3308 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3309 const char *fname = BASEDIR "\\file";
3310 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3312 torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
3314 smb2_deltree(tree, BASEDIR);
3315 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3316 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3317 smb2_util_close(tree, h1);
3318 ret = torture_setup_file(mem_ctx, tree, fname, false);
3319 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3321 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3323 ZERO_STRUCT(create);
3324 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3325 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3326 create.in.fname = sname;
3328 status = smb2_create(tree, mem_ctx, &create);
3329 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3330 ret, done, "Got unexpected AFP_AfpInfo stream");
3333 smb2_util_unlink(tree, fname);
3334 smb2_util_rmdir(tree, BASEDIR);
3338 static bool test_create_delete_on_close(struct torture_context *tctx,
3339 struct smb2_tree *tree)
3343 struct smb2_create create;
3344 struct smb2_handle h1;
3345 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3346 const char *fname = BASEDIR "\\file";
3347 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3348 const char *type_creator = "SMB,OLE!";
3349 AfpInfo *info = NULL;
3350 const char *streams_basic[] = {
3353 const char *streams_afpinfo[] = {
3358 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3360 torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
3362 smb2_deltree(tree, BASEDIR);
3363 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3364 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3365 smb2_util_close(tree, h1);
3366 ret = torture_setup_file(mem_ctx, tree, fname, false);
3367 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3369 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3371 ZERO_STRUCT(create);
3372 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3373 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3374 create.in.fname = sname;
3376 status = smb2_create(tree, mem_ctx, &create);
3377 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3378 ret, done, "Got unexpected AFP_AfpInfo stream");
3380 ZERO_STRUCT(create);
3381 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3382 create.in.desired_access = SEC_FILE_ALL;
3383 create.in.fname = sname;
3385 status = smb2_create(tree, mem_ctx, &create);
3386 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3387 ret, done, "Got unexpected AFP_AfpInfo stream");
3389 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3390 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3392 torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
3394 info = torture_afpinfo_new(mem_ctx);
3395 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3397 memcpy(info->afpi_FinderInfo, type_creator, 8);
3398 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3399 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3401 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3402 0, 60, 16, 8, type_creator);
3403 torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
3405 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3406 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3408 ZERO_STRUCT(create);
3409 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3410 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3411 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3412 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3413 create.in.fname = sname;
3414 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3416 status = smb2_create(tree, mem_ctx, &create);
3417 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3419 h1 = create.out.file.handle;
3420 smb2_util_close(tree, h1);
3422 ZERO_STRUCT(create);
3423 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3424 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
3425 create.in.fname = sname;
3426 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3427 status = smb2_create(tree, mem_ctx, &create);
3428 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3429 ret, done, "Got unexpected AFP_AfpInfo stream");
3431 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3432 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3435 smb2_util_unlink(tree, fname);
3436 smb2_util_rmdir(tree, BASEDIR);
3440 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
3441 struct smb2_tree *tree)
3445 struct smb2_create create;
3446 union smb_setfileinfo sfinfo;
3447 struct smb2_handle h1;
3448 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3449 const char *fname = BASEDIR "\\file";
3450 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3451 const char *type_creator = "SMB,OLE!";
3452 AfpInfo *info = NULL;
3453 const char *streams[] = {
3457 const char *streams_basic[] = {
3461 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3463 torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
3465 smb2_deltree(tree, BASEDIR);
3466 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3467 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3468 smb2_util_close(tree, h1);
3469 ret = torture_setup_file(mem_ctx, tree, fname, false);
3470 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3472 info = torture_afpinfo_new(mem_ctx);
3473 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3474 memcpy(info->afpi_FinderInfo, type_creator, 8);
3475 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3476 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3478 ZERO_STRUCT(create);
3479 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3480 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3481 create.in.fname = sname;
3482 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3483 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3485 status = smb2_create(tree, mem_ctx, &create);
3486 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3488 h1 = create.out.file.handle;
3490 /* Delete stream via setinfo delete-on-close */
3491 ZERO_STRUCT(sfinfo);
3492 sfinfo.disposition_info.in.delete_on_close = 1;
3493 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3494 sfinfo.generic.in.file.handle = h1;
3495 status = smb2_setinfo_file(tree, &sfinfo);
3496 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3498 ret = check_stream_list(tree, tctx, fname, 2, streams, false);
3499 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3501 ZERO_STRUCT(create);
3502 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3503 create.in.desired_access = SEC_FILE_ALL;
3504 create.in.fname = sname;
3505 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3506 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3507 status = smb2_create(tree, mem_ctx, &create);
3508 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_DELETE_PENDING,
3509 ret, done, "Got unexpected AFP_AfpInfo stream");
3511 smb2_util_close(tree, h1);
3513 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3514 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3516 ZERO_STRUCT(create);
3517 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3518 create.in.desired_access = SEC_FILE_ALL;
3519 create.in.fname = sname;
3520 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3521 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3522 status = smb2_create(tree, mem_ctx, &create);
3523 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3524 ret, done, "Got unexpected AFP_AfpInfo stream");
3527 smb2_util_unlink(tree, fname);
3528 smb2_util_rmdir(tree, BASEDIR);
3532 static bool test_setinfo_eof(struct torture_context *tctx,
3533 struct smb2_tree *tree)
3537 struct smb2_create create;
3538 union smb_setfileinfo sfinfo;
3539 struct smb2_handle h1;
3540 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3541 const char *fname = BASEDIR "\\file";
3542 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3543 const char *type_creator = "SMB,OLE!";
3544 AfpInfo *info = NULL;
3545 const char *streams_afpinfo[] = {
3550 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3552 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
3554 smb2_deltree(tree, BASEDIR);
3555 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3556 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3557 smb2_util_close(tree, h1);
3558 ret = torture_setup_file(mem_ctx, tree, fname, false);
3559 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3561 info = torture_afpinfo_new(mem_ctx);
3562 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3563 memcpy(info->afpi_FinderInfo, type_creator, 8);
3564 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3565 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3567 ZERO_STRUCT(create);
3568 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3569 create.in.desired_access = SEC_FILE_ALL;
3570 create.in.fname = sname;
3571 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3572 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3574 status = smb2_create(tree, mem_ctx, &create);
3575 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3577 h1 = create.out.file.handle;
3579 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
3581 /* Test setinfo end-of-file info */
3582 ZERO_STRUCT(sfinfo);
3583 sfinfo.generic.in.file.handle = h1;
3584 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3585 sfinfo.position_information.in.position = 61;
3586 status = smb2_setinfo_file(tree, &sfinfo);
3587 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
3588 ret, done, "set eof 61 failed");
3590 torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
3592 /* Truncation returns success, but has no effect */
3593 ZERO_STRUCT(sfinfo);
3594 sfinfo.generic.in.file.handle = h1;
3595 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3596 sfinfo.position_information.in.position = 1;
3597 status = smb2_setinfo_file(tree, &sfinfo);
3598 torture_assert_ntstatus_ok_goto(tctx, status,
3599 ret, done, "set eof 1 failed");
3600 smb2_util_close(tree, h1);
3602 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3603 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3605 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3606 0, 60, 16, 8, type_creator);
3607 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3609 ZERO_STRUCT(create);
3610 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3611 create.in.desired_access = SEC_FILE_ALL;
3612 create.in.fname = sname;
3613 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3614 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3616 status = smb2_create(tree, mem_ctx, &create);
3617 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3619 h1 = create.out.file.handle;
3622 * Delete stream via setinfo end-of-file info to 0, should
3623 * return success but stream MUST NOT deleted
3625 ZERO_STRUCT(sfinfo);
3626 sfinfo.generic.in.file.handle = h1;
3627 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3628 sfinfo.position_information.in.position = 0;
3629 status = smb2_setinfo_file(tree, &sfinfo);
3630 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3632 smb2_util_close(tree, h1);
3634 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3635 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3637 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3638 0, 60, 16, 8, type_creator);
3639 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3642 smb2_util_unlink(tree, fname);
3643 smb2_util_rmdir(tree, BASEDIR);
3647 static bool test_afpinfo_all0(struct torture_context *tctx,
3648 struct smb2_tree *tree)
3652 struct smb2_create create;
3653 struct smb2_handle h1 = {{0}};
3654 struct smb2_handle baseh = {{0}};
3655 union smb_setfileinfo setfinfo;
3656 union smb_fileinfo getfinfo;
3657 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3658 const char *fname = BASEDIR "\\file";
3659 const char *sname = BASEDIR "\\file" AFPINFO_STREAM;
3660 const char *type_creator = "SMB,OLE!";
3661 AfpInfo *info = NULL;
3662 char *infobuf = NULL;
3663 const char *streams_basic[] = {
3666 const char *streams_afpinfo[] = {
3671 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3673 torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
3675 smb2_deltree(tree, BASEDIR);
3676 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3677 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3678 smb2_util_close(tree, h1);
3679 ret = torture_setup_file(mem_ctx, tree, fname, false);
3680 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3682 info = torture_afpinfo_new(mem_ctx);
3683 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3684 memcpy(info->afpi_FinderInfo, type_creator, 8);
3685 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3686 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3688 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3689 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3691 /* Write all 0 to AFP_AfpInfo */
3692 memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
3693 infobuf = torture_afpinfo_pack(mem_ctx, info);
3694 torture_assert_not_null_goto(tctx, infobuf, ret, done,
3695 "torture_afpinfo_pack failed\n");
3697 ZERO_STRUCT(create);
3698 create.in.desired_access = SEC_FILE_ALL;
3699 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3700 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3701 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3702 create.in.fname = fname;
3704 status = smb2_create(tree, mem_ctx, &create);
3705 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3706 "smb2_create failed\n");
3707 baseh = create.out.file.handle;
3709 ZERO_STRUCT(create);
3710 create.in.desired_access = SEC_FILE_ALL;
3711 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3712 create.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
3713 create.in.fname = sname;
3715 status = smb2_create(tree, mem_ctx, &create);
3716 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3717 "smb2_create failed\n");
3718 h1 = create.out.file.handle;
3720 status = smb2_util_write(tree, h1, infobuf, 0, AFP_INFO_SIZE);
3721 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3722 "smb2_util_write failed\n");
3725 * Get stream information on open handle, must return only default
3726 * stream, the AFP_AfpInfo stream must not be returned.
3729 ZERO_STRUCT(getfinfo);
3730 getfinfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
3731 getfinfo.generic.in.file.handle = baseh;
3733 status = smb2_getinfo_file(tree, tctx, &getfinfo);
3734 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3735 "get stream info\n");
3737 torture_assert_int_equal_goto(tctx, getfinfo.stream_info.out.num_streams,
3738 1, ret, done, "stream count");
3740 smb2_util_close(tree, baseh);
3744 * Try to set some file-basic-info (time) on the stream. This catches
3745 * naive implementation mistakes that simply deleted the backing store
3746 * from the filesystem in the zero-out step.
3749 ZERO_STRUCT(setfinfo);
3750 unix_to_nt_time(&setfinfo.basic_info.in.write_time, time(NULL));
3751 setfinfo.basic_info.in.attrib = 0x20;
3752 setfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
3753 setfinfo.generic.in.file.handle = h1;
3755 status = smb2_setinfo_file(tree, &setfinfo);
3756 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3757 "smb2_getinfo_file failed\n");
3759 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3760 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
3762 smb2_util_close(tree, h1);
3765 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3766 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3769 if (!smb2_util_handle_empty(h1)) {
3770 smb2_util_close(tree, h1);
3772 if (!smb2_util_handle_empty(baseh)) {
3773 smb2_util_close(tree, baseh);
3775 smb2_util_unlink(tree, fname);
3776 smb2_util_rmdir(tree, BASEDIR);
3780 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
3781 struct smb2_tree *tree)
3785 struct smb2_create create;
3786 struct smb2_handle h1;
3787 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3788 const char *fname = BASEDIR "\\file";
3789 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3790 const char *streams_basic[] = {
3793 const char *streams_afpresource[] = {
3798 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3800 torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
3802 smb2_deltree(tree, BASEDIR);
3803 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3804 torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
3805 smb2_util_close(tree, h1);
3806 ret = torture_setup_file(mem_ctx, tree, fname, false);
3807 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3809 torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
3811 ZERO_STRUCT(create);
3812 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3813 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3814 create.in.fname = sname;
3816 status = smb2_create(tree, mem_ctx, &create);
3817 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3818 ret, done, "Got unexpected AFP_AfpResource stream");
3820 ZERO_STRUCT(create);
3821 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3822 create.in.desired_access = SEC_FILE_ALL;
3823 create.in.fname = sname;
3825 status = smb2_create(tree, mem_ctx, &create);
3826 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3827 ret, done, "Got unexpected AFP_AfpResource stream");
3829 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3830 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3832 torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
3834 ret = write_stream(tree, __location__, tctx, mem_ctx,
3835 fname, AFPRESOURCE_STREAM_NAME,
3836 0, 10, "1234567890");
3837 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3839 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3840 0, 10, 0, 10, "1234567890");
3841 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3843 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3844 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3846 ZERO_STRUCT(create);
3847 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3848 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3849 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3850 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3851 create.in.fname = sname;
3852 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3854 status = smb2_create(tree, mem_ctx, &create);
3855 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3857 h1 = create.out.file.handle;
3858 smb2_util_close(tree, h1);
3860 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3861 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3863 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3864 0, 10, 0, 10, "1234567890");
3865 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3868 smb2_util_unlink(tree, fname);
3869 smb2_util_rmdir(tree, BASEDIR);
3873 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
3874 struct smb2_tree *tree)
3878 struct smb2_create create;
3879 union smb_setfileinfo sfinfo;
3880 struct smb2_handle h1;
3881 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3882 const char *fname = BASEDIR "\\file";
3883 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3884 const char *streams_afpresource[] = {
3889 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3891 torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
3893 smb2_deltree(tree, BASEDIR);
3894 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3895 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3896 smb2_util_close(tree, h1);
3897 ret = torture_setup_file(mem_ctx, tree, fname, false);
3898 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3900 ret = write_stream(tree, __location__, tctx, mem_ctx,
3901 fname, AFPRESOURCE_STREAM_NAME,
3902 10, 10, "1234567890");
3903 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3905 ZERO_STRUCT(create);
3906 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3907 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3908 create.in.fname = sname;
3909 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3910 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3912 status = smb2_create(tree, mem_ctx, &create);
3913 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3915 h1 = create.out.file.handle;
3917 /* Try to delete stream via setinfo delete-on-close */
3918 ZERO_STRUCT(sfinfo);
3919 sfinfo.disposition_info.in.delete_on_close = 1;
3920 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3921 sfinfo.generic.in.file.handle = h1;
3922 status = smb2_setinfo_file(tree, &sfinfo);
3923 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3925 smb2_util_close(tree, h1);
3927 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3928 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3930 ZERO_STRUCT(create);
3931 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3932 create.in.desired_access = SEC_FILE_ALL;
3933 create.in.fname = sname;
3934 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3935 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3936 status = smb2_create(tree, mem_ctx, &create);
3937 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3938 "Got unexpected AFP_AfpResource stream");
3941 smb2_util_unlink(tree, fname);
3942 smb2_util_rmdir(tree, BASEDIR);
3946 static bool test_setinfo_eof_resource(struct torture_context *tctx,
3947 struct smb2_tree *tree)
3951 struct smb2_create create;
3952 union smb_setfileinfo sfinfo;
3953 union smb_fileinfo finfo;
3954 struct smb2_handle h1;
3955 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3956 const char *fname = BASEDIR "\\file";
3957 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3958 const char *streams_basic[] = {
3962 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3964 torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
3966 smb2_deltree(tree, BASEDIR);
3967 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3968 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3969 smb2_util_close(tree, h1);
3970 ret = torture_setup_file(mem_ctx, tree, fname, false);
3971 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3973 ret = write_stream(tree, __location__, tctx, mem_ctx,
3974 fname, AFPRESOURCE_STREAM_NAME,
3975 10, 10, "1234567890");
3976 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3978 ZERO_STRUCT(create);
3979 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3980 create.in.desired_access = SEC_FILE_ALL;
3981 create.in.fname = sname;
3982 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3983 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3985 status = smb2_create(tree, mem_ctx, &create);
3986 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3988 h1 = create.out.file.handle;
3990 torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
3992 /* Test setinfo end-of-file info */
3993 ZERO_STRUCT(sfinfo);
3994 sfinfo.generic.in.file.handle = h1;
3995 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3996 sfinfo.position_information.in.position = 1;
3997 status = smb2_setinfo_file(tree, &sfinfo);
3998 torture_assert_ntstatus_ok_goto(tctx, status,
3999 ret, done, "set eof 1 failed");
4001 smb2_util_close(tree, h1);
4003 /* Check size == 1 */
4004 ZERO_STRUCT(create);
4005 create.in.fname = sname;
4006 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4007 create.in.desired_access = SEC_FILE_ALL;
4008 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4009 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4010 status = smb2_create(tree, mem_ctx, &create);
4011 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4013 h1 = create.out.file.handle;
4016 finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
4017 finfo.generic.in.file.handle = h1;
4018 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
4019 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
4021 smb2_util_close(tree, h1);
4023 torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
4025 ZERO_STRUCT(create);
4026 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4027 create.in.desired_access = SEC_FILE_ALL;
4028 create.in.fname = sname;
4029 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4030 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4032 status = smb2_create(tree, mem_ctx, &create);
4033 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4035 h1 = create.out.file.handle;
4038 * Delete stream via setinfo end-of-file info to 0, this
4039 * should delete the stream.
4041 ZERO_STRUCT(sfinfo);
4042 sfinfo.generic.in.file.handle = h1;
4043 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4044 sfinfo.position_information.in.position = 0;
4045 status = smb2_setinfo_file(tree, &sfinfo);
4046 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
4048 smb2_util_close(tree, h1);
4050 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
4051 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4053 ZERO_STRUCT(create);
4054 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4055 create.in.desired_access = SEC_FILE_ALL;
4056 create.in.fname = sname;
4057 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4058 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4060 status = smb2_create(tree, mem_ctx, &create);
4061 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4062 ret, done, "smb2_create failed");
4065 smb2_util_unlink(tree, fname);
4066 smb2_util_rmdir(tree, BASEDIR);
4071 * This tests that right after creating the AFP_AfpInfo stream,
4072 * reading from the stream returns an empty, default metadata blob of
4075 * NOTE: against OS X SMB server this only works if the read request
4076 * is compounded with the create that created the stream, is fails
4077 * otherwise. We don't care...
4079 static bool test_null_afpinfo(struct torture_context *tctx,
4080 struct smb2_tree *tree)
4082 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4083 const char *fname = "test_null_afpinfo";
4084 const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
4087 struct smb2_request *req[3];
4088 struct smb2_handle handle;
4089 struct smb2_create create;
4090 struct smb2_read read;
4091 AfpInfo *afpinfo = NULL;
4092 char *afpinfo_buf = NULL;
4093 const char *type_creator = "SMB,OLE!";
4094 struct smb2_handle handle2;
4097 torture_comment(tctx, "Checking create of AfpInfo stream\n");
4099 smb2_util_unlink(tree, fname);
4101 ret = torture_setup_file(mem_ctx, tree, fname, false);
4102 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
4104 ZERO_STRUCT(create);
4105 create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
4106 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
4107 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4108 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4109 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
4110 create.in.fname = sname;
4112 smb2_transport_compound_start(tree->session->transport, 2);
4114 req[0] = smb2_create_send(tree, &create);
4116 handle.data[0] = UINT64_MAX;
4117 handle.data[1] = UINT64_MAX;
4119 smb2_transport_compound_set_related(tree->session->transport, true);
4122 read.in.file.handle = handle;
4123 read.in.length = AFP_INFO_SIZE;
4124 req[1] = smb2_read_send(tree, &read);
4126 status = smb2_create_recv(req[0], tree, &create);
4127 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
4129 handle = create.out.file.handle;
4131 status = smb2_read_recv(req[1], tree, &read);
4132 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
4134 status = torture_smb2_testfile_access(tree, sname, &handle2,
4135 SEC_FILE_READ_DATA);
4136 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4137 "torture_smb2_testfile failed\n");
4138 r = (struct smb2_read) {
4139 .in.file.handle = handle2,
4140 .in.length = AFP_INFO_SIZE,
4143 status = smb2_read(tree, tree, &r);
4144 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4145 "torture_smb2_testfile failed\n");
4146 smb2_util_close(tree, handle2);
4148 afpinfo = torture_afpinfo_new(mem_ctx);
4149 torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
4151 memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
4153 afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
4154 torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
4156 status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
4157 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
4159 smb2_util_close(tree, handle);
4161 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
4162 0, 60, 16, 8, type_creator);
4163 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
4166 smb2_util_unlink(tree, fname);
4167 talloc_free(mem_ctx);
4171 static bool test_delete_file_with_rfork(struct torture_context *tctx,
4172 struct smb2_tree *tree)
4174 const char *fname = "torture_write_rfork_io";
4175 const char *rfork_content = "1234567890";
4179 smb2_util_unlink(tree, fname);
4181 torture_comment(tctx, "Test deleting file with resource fork\n");
4183 ret = torture_setup_file(tctx, tree, fname, false);
4184 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
4186 ret = write_stream(tree, __location__, tctx, tctx,
4187 fname, AFPRESOURCE_STREAM_NAME,
4188 10, 10, rfork_content);
4189 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
4191 ret = check_stream(tree, __location__, tctx, tctx,
4192 fname, AFPRESOURCE_STREAM_NAME,
4193 0, 20, 10, 10, rfork_content);
4194 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
4196 status = smb2_util_unlink(tree, fname);
4197 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
4203 static bool test_rename_and_read_rsrc(struct torture_context *tctx,
4204 struct smb2_tree *tree)
4208 struct smb2_create create, create2;
4209 struct smb2_handle h1, h2;
4210 const char *fname = "test_rename_openfile";
4211 const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
4212 const char *fname_renamed = "test_rename_openfile_renamed";
4213 const char *data = "1234567890";
4214 union smb_setfileinfo sinfo;
4215 bool server_is_macos = torture_setting_bool(tctx, "osx", false);
4216 NTSTATUS expected_status;
4218 ret = enable_aapl(tctx, tree);
4219 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
4221 torture_comment(tctx, "Create file with resource fork\n");
4223 ret = torture_setup_file(tctx, tree, fname, false);
4224 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4226 ret = write_stream(tree, __location__, tctx, tctx,
4227 fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
4228 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4230 torture_comment(tctx, "Open resource fork\n");
4232 ZERO_STRUCT(create);
4233 create.in.desired_access = SEC_FILE_ALL;
4234 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4235 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4236 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4237 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4238 create.in.fname = sname;
4240 status = smb2_create(tree, tctx, &create);
4241 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4243 h1 = create.out.file.handle;
4245 torture_comment(tctx, "Rename base file\n");
4247 ZERO_STRUCT(create2);
4248 create2.in.desired_access = SEC_FILE_ALL;
4249 create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4250 create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4251 create2.in.create_disposition = NTCREATEX_DISP_OPEN;
4252 create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4253 create2.in.fname = fname;
4255 status = smb2_create(tree, tctx, &create2);
4256 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4258 h2 = create2.out.file.handle;
4261 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
4262 sinfo.rename_information.in.file.handle = h2;
4263 sinfo.rename_information.in.overwrite = 0;
4264 sinfo.rename_information.in.root_fid = 0;
4265 sinfo.rename_information.in.new_name = fname_renamed;
4267 if (server_is_macos) {
4268 expected_status = NT_STATUS_SHARING_VIOLATION;
4270 expected_status = NT_STATUS_ACCESS_DENIED;
4273 status = smb2_setinfo_file(tree, &sinfo);
4274 torture_assert_ntstatus_equal_goto(
4275 tctx, status, expected_status, ret, done,
4276 "smb2_setinfo_file failed");
4278 smb2_util_close(tree, h2);
4280 status = smb2_util_write(tree, h1, "foo", 0, 3);
4281 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4284 smb2_util_close(tree, h1);
4287 smb2_util_unlink(tree, fname);
4288 smb2_util_unlink(tree, fname_renamed);
4293 static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
4294 struct smb2_tree *tree)
4296 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4297 const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
4298 const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
4300 struct smb2_handle testdirh;
4302 struct smb2_create io;
4304 const char *type_creator = "SMB,OLE!";
4307 union smb_search_data *d;
4311 smb2_deltree(tree, BASEDIR);
4313 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
4314 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
4315 smb2_util_close(tree, testdirh);
4317 torture_comment(tctx, "Enabling AAPL\n");
4319 ret = enable_aapl(tctx, tree);
4320 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
4323 * Now that Requested AAPL extensions are enabled, setup some
4324 * Mac files with metadata and resource fork
4327 torture_comment(tctx, "Preparing file\n");
4329 ret = torture_setup_file(mem_ctx, tree, fname, false);
4330 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
4332 info = torture_afpinfo_new(mem_ctx);
4333 torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
4335 memcpy(info->afpi_FinderInfo, type_creator, 8);
4336 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
4337 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
4339 ret = write_stream(tree, __location__, tctx, mem_ctx,
4340 fname, AFPRESOURCE_STREAM_NAME,
4342 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4345 * Ok, file is prepared, now call smb2/find
4348 torture_comment(tctx, "Issue find\n");
4351 io.in.desired_access = SEC_RIGHTS_DIR_READ;
4352 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
4353 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
4354 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
4355 NTCREATEX_SHARE_ACCESS_WRITE |
4356 NTCREATEX_SHARE_ACCESS_DELETE);
4357 io.in.create_disposition = NTCREATEX_DISP_OPEN;
4358 io.in.fname = BASEDIR;
4359 status = smb2_create(tree, tctx, &io);
4360 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4363 f.in.file.handle = io.out.file.handle;
4365 f.in.max_response_size = 0x1000;
4366 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
4368 status = smb2_find_level(tree, tree, &f, &count, &d);
4369 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
4371 status = smb2_util_close(tree, io.out.file.handle);
4372 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
4374 torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
4376 for (i = 0; i < count; i++) {
4377 const char *found = d[i].id_both_directory_info.name.s;
4379 if (!strcmp(found, ".") || !strcmp(found, ".."))
4381 if (strncmp(found, "._", 2) == 0) {
4387 torture_assert_str_equal_goto(tctx,
4388 d[i].id_both_directory_info.name.s, name,
4389 ret, done, "bad name");
4391 rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
4392 torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
4394 torture_assert_mem_equal_goto(tctx, type_creator,
4395 d[i].id_both_directory_info.short_name_buf + 8,
4396 8, ret, done, "Bad FinderInfo");
4398 smb2_util_unlink(tree, fname);
4399 smb2_deltree(tree, BASEDIR);
4400 talloc_free(mem_ctx);
4404 static bool test_invalid_afpinfo(struct torture_context *tctx,
4405 struct smb2_tree *tree1,
4406 struct smb2_tree *tree2)
4408 const char *fname = "filtest_invalid_afpinfo";
4409 const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
4410 struct smb2_create create;
4411 const char *streams_basic[] = {
4414 const char *streams_afpinfo[] = {
4421 if (tree2 == NULL) {
4422 torture_skip_goto(tctx, done, "need second share without fruit\n");
4425 torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
4427 ret = torture_setup_file(tctx, tree2, fname, false);
4428 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4430 ret = write_stream(tree2, __location__, tctx, tctx,
4431 fname, AFPINFO_STREAM_NAME,
4433 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4435 ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
4436 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4438 torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
4440 ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
4441 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4443 torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
4445 ZERO_STRUCT(create);
4446 create.in.desired_access = SEC_FILE_ALL;
4447 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4448 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4449 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4450 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4451 create.in.fname = sname;
4453 status = smb2_create(tree1, tctx, &create);
4454 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4455 ret, done, "Stream still around?");
4458 smb2_util_unlink(tree1, fname);
4462 static bool test_zero_file_id(struct torture_context *tctx,
4463 struct smb2_tree *tree)
4465 const char *fname = "filtest_file_id";
4466 struct smb2_create create = {0};
4469 uint8_t zero_file_id[8] = {0};
4471 torture_comment(tctx, "Testing zero file id\n");
4473 ret = torture_setup_file(tctx, tree, fname, false);
4474 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4476 ZERO_STRUCT(create);
4477 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4478 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4479 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4480 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4481 create.in.fname = fname;
4482 create.in.query_on_disk_id = true;
4484 status = smb2_create(tree, tctx, &create);
4485 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
4487 "test file could not be opened");
4488 torture_assert_mem_not_equal_goto(tctx, create.out.on_disk_id,
4489 zero_file_id, 8, ret, done,
4490 "unexpected zero file id");
4492 smb2_util_close(tree, create.out.file.handle);
4494 ret = enable_aapl(tctx, tree);
4495 torture_assert(tctx, ret == true, "enable_aapl failed");
4497 ZERO_STRUCT(create);
4498 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4499 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4500 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4501 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4502 create.in.fname = fname;
4503 create.in.query_on_disk_id = true;
4505 status = smb2_create(tree, tctx, &create);
4506 torture_assert_ntstatus_equal_goto(
4507 tctx, status, NT_STATUS_OK, ret, done,
4508 "test file could not be opened with AAPL");
4509 torture_assert_mem_equal_goto(tctx, create.out.on_disk_id, zero_file_id,
4510 8, ret, done, "non-zero file id");
4512 smb2_util_close(tree, create.out.file.handle);
4515 smb2_util_unlink(tree, fname);
4519 static bool copy_one_stream(struct torture_context *torture,
4520 struct smb2_tree *tree,
4521 TALLOC_CTX *tmp_ctx,
4522 const char *src_sname,
4523 const char *dst_sname)
4525 struct smb2_handle src_h = {{0}};
4526 struct smb2_handle dest_h = {{0}};
4529 struct srv_copychunk_copy cc_copy;
4530 struct srv_copychunk_rsp cc_rsp;
4531 enum ndr_err_code ndr_ret;
4534 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4537 &src_h, 256, /* fill 256 byte src file */
4538 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4540 &dest_h, 0, /* 0 byte dest file */
4541 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4544 torture_assert_goto(torture, ok == true, ok, done,
4545 "setup copy chunk error\n");
4547 /* copy all src file data (via a single chunk desc) */
4548 cc_copy.chunks[0].source_off = 0;
4549 cc_copy.chunks[0].target_off = 0;
4550 cc_copy.chunks[0].length = 256;
4552 ndr_ret = ndr_push_struct_blob(
4553 &io.smb2.in.out, tmp_ctx, &cc_copy,
4554 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4556 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4557 "ndr_push_srv_copychunk_copy\n");
4559 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4560 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4561 "FSCTL_SRV_COPYCHUNK\n");
4563 ndr_ret = ndr_pull_struct_blob(
4564 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4565 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4567 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4568 "ndr_pull_srv_copychunk_rsp\n");
4570 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4571 1, /* chunks written */
4572 0, /* chunk bytes unsuccessfully written */
4573 256); /* total bytes written */
4574 torture_assert_goto(torture, ok == true, ok, done,
4575 "bad copy chunk response data\n");
4577 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
4579 torture_fail(torture, "inconsistent file data\n");
4583 if (!smb2_util_handle_empty(src_h)) {
4584 smb2_util_close(tree, src_h);
4586 if (!smb2_util_handle_empty(dest_h)) {
4587 smb2_util_close(tree, dest_h);
4593 static bool copy_finderinfo_stream(struct torture_context *torture,
4594 struct smb2_tree *tree,
4595 TALLOC_CTX *tmp_ctx,
4596 const char *src_name,
4597 const char *dst_name)
4599 struct smb2_handle src_h = {{0}};
4600 struct smb2_handle dest_h = {{0}};
4603 struct srv_copychunk_copy cc_copy;
4604 struct srv_copychunk_rsp cc_rsp;
4605 enum ndr_err_code ndr_ret;
4606 const char *type_creator = "SMB,OLE!";
4607 AfpInfo *info = NULL;
4608 const char *src_name_afpinfo = NULL;
4609 const char *dst_name_afpinfo = NULL;
4612 src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
4614 torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
4615 "talloc_asprintf failed\n");
4617 dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
4619 torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
4620 "talloc_asprintf failed\n");
4622 info = torture_afpinfo_new(tmp_ctx);
4623 torture_assert_not_null_goto(torture, info, ok, done,
4624 "torture_afpinfo_new failed\n");
4626 memcpy(info->afpi_FinderInfo, type_creator, 8);
4627 ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
4628 torture_assert_goto(torture, ok == true, ok, done,
4629 "torture_write_afpinfo failed\n");
4631 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4635 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4638 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4641 torture_assert_goto(torture, ok == true, ok, done,
4642 "setup copy chunk error\n");
4644 /* copy all src file data (via a single chunk desc) */
4645 cc_copy.chunks[0].source_off = 0;
4646 cc_copy.chunks[0].target_off = 0;
4647 cc_copy.chunks[0].length = 60;
4649 ndr_ret = ndr_push_struct_blob(
4650 &io.smb2.in.out, tmp_ctx, &cc_copy,
4651 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4653 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4654 "ndr_push_srv_copychunk_copy\n");
4656 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4657 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4658 "FSCTL_SRV_COPYCHUNK\n");
4660 ndr_ret = ndr_pull_struct_blob(
4661 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4662 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4664 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4665 "ndr_pull_srv_copychunk_rsp\n");
4667 smb2_util_close(tree, src_h);
4669 smb2_util_close(tree, dest_h);
4670 ZERO_STRUCT(dest_h);
4672 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4673 1, /* chunks written */
4674 0, /* chunk bytes unsuccessfully written */
4675 60); /* total bytes written */
4676 torture_assert_goto(torture, ok == true, ok, done,
4677 "bad copy chunk response data\n");
4679 ok = check_stream(tree, __location__, torture, tmp_ctx,
4680 dst_name, AFPINFO_STREAM,
4681 0, 60, 16, 8, type_creator);
4682 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
4685 if (!smb2_util_handle_empty(src_h)) {
4686 smb2_util_close(tree, src_h);
4688 if (!smb2_util_handle_empty(dest_h)) {
4689 smb2_util_close(tree, dest_h);
4695 static bool test_copy_chunk_streams(struct torture_context *torture,
4696 struct smb2_tree *tree)
4698 const char *src_name = "src";
4699 const char *dst_name = "dst";
4701 const char *src_sname;
4702 const char *dst_sname;
4704 { "src:foo", "dst:foo" },
4705 { "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
4708 TALLOC_CTX *tmp_ctx = NULL;
4711 tmp_ctx = talloc_new(tree);
4712 torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
4713 "torture_setup_file\n");
4715 smb2_util_unlink(tree, src_name);
4716 smb2_util_unlink(tree, dst_name);
4718 ok = torture_setup_file(torture, tree, src_name, false);
4719 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4720 ok = torture_setup_file(torture, tree, dst_name, false);
4721 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4723 for (i = 0; i < ARRAY_SIZE(names); i++) {
4724 ok = copy_one_stream(torture, tree, tmp_ctx,
4726 names[i].dst_sname);
4727 torture_assert_goto(torture, ok == true, ok, done,
4728 "copy_one_stream failed\n");
4731 ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
4732 src_name, dst_name);
4733 torture_assert_goto(torture, ok == true, ok, done,
4734 "copy_finderinfo_stream failed\n");
4737 smb2_util_unlink(tree, src_name);
4738 smb2_util_unlink(tree, dst_name);
4739 talloc_free(tmp_ctx);
4744 * Ensure this security descriptor has exactly one mode, uid
4748 static NTSTATUS check_nfs_sd(const struct security_descriptor *psd)
4751 bool got_one_mode = false;
4752 bool got_one_uid = false;
4753 bool got_one_gid = false;
4755 if (psd->dacl == NULL) {
4756 return NT_STATUS_INVALID_SECURITY_DESCR;
4759 for (i = 0; i < psd->dacl->num_aces; i++) {
4760 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Mode,
4761 &psd->dacl->aces[i].trustee) == 0) {
4762 if (got_one_mode == true) {
4763 /* Can't have more than one. */
4764 return NT_STATUS_INVALID_SECURITY_DESCR;
4766 got_one_mode = true;
4769 for (i = 0; i < psd->dacl->num_aces; i++) {
4770 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Users,
4771 &psd->dacl->aces[i].trustee) == 0) {
4772 if (got_one_uid == true) {
4773 /* Can't have more than one. */
4774 return NT_STATUS_INVALID_SECURITY_DESCR;
4779 for (i = 0; i < psd->dacl->num_aces; i++) {
4780 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Groups,
4781 &psd->dacl->aces[i].trustee) == 0) {
4782 if (got_one_gid == true) {
4783 /* Can't have more than one. */
4784 return NT_STATUS_INVALID_SECURITY_DESCR;
4789 /* Must have at least one of each. */
4790 if (got_one_mode == false ||
4791 got_one_uid == false ||
4792 got_one_gid == false) {
4793 return NT_STATUS_INVALID_SECURITY_DESCR;
4795 return NT_STATUS_OK;
4798 static bool test_nfs_aces(struct torture_context *tctx,
4799 struct smb2_tree *tree)
4801 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4802 struct security_ace ace;
4804 const char *fname = BASEDIR "\\nfs_aces.txt";
4805 struct smb2_handle h = {{0}};
4806 union smb_fileinfo finfo2;
4807 union smb_setfileinfo set;
4808 struct security_descriptor *psd = NULL;
4811 bool is_osx = torture_setting_bool(tctx, "osx", false);
4814 torture_skip(tctx, "Test only works with Samba\n");
4817 ret = enable_aapl(tctx, tree);
4818 torture_assert(tctx, ret == true, "enable_aapl failed");
4820 /* clean slate ...*/
4821 smb2_util_unlink(tree, fname);
4822 smb2_deltree(tree, fname);
4823 smb2_deltree(tree, BASEDIR);
4825 status = torture_smb2_testdir(tree, BASEDIR, &h);
4826 CHECK_STATUS(status, NT_STATUS_OK);
4827 smb2_util_close(tree, h);
4829 /* Create a test file. */
4830 status = torture_smb2_testfile_access(tree,
4833 SEC_STD_READ_CONTROL |
4835 SEC_RIGHTS_FILE_ALL);
4836 CHECK_STATUS(status, NT_STATUS_OK);
4839 finfo2.query_secdesc.in.secinfo_flags =
4843 finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
4844 finfo2.generic.in.file.handle = h;
4845 status = smb2_getinfo_file(tree, tctx, &finfo2);
4846 CHECK_STATUS(status, NT_STATUS_OK);
4848 psd = finfo2.query_secdesc.out.sd;
4850 /* Ensure we have only single mode/uid/gid NFS entries. */
4851 status = check_nfs_sd(psd);
4852 if (!NT_STATUS_IS_OK(status)) {
4854 security_descriptor,
4855 discard_const_p(struct security_descriptor, psd));
4857 CHECK_STATUS(status, NT_STATUS_OK);
4859 /* Add a couple of extra NFS uids and gids. */
4860 sid_compose(&sid, &global_sid_Unix_NFS_Users, 27);
4861 init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
4862 status = security_descriptor_dacl_add(psd, &ace);
4863 CHECK_STATUS(status, NT_STATUS_OK);
4864 status = security_descriptor_dacl_add(psd, &ace);
4865 CHECK_STATUS(status, NT_STATUS_OK);
4867 sid_compose(&sid, &global_sid_Unix_NFS_Groups, 300);
4868 init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
4869 status = security_descriptor_dacl_add(psd, &ace);
4870 CHECK_STATUS(status, NT_STATUS_OK);
4871 status = security_descriptor_dacl_add(psd, &ace);
4872 CHECK_STATUS(status, NT_STATUS_OK);
4874 /* Now set on the file handle. */
4875 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
4876 set.set_secdesc.in.file.handle = h;
4877 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
4878 set.set_secdesc.in.sd = psd;
4879 status = smb2_setinfo_file(tree, &set);
4880 CHECK_STATUS(status, NT_STATUS_OK);
4882 /* Get the ACL again. */
4883 finfo2.query_secdesc.in.secinfo_flags =
4887 finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
4888 finfo2.generic.in.file.handle = h;
4889 status = smb2_getinfo_file(tree, tctx, &finfo2);
4890 CHECK_STATUS(status, NT_STATUS_OK);
4892 psd = finfo2.query_secdesc.out.sd;
4894 /* Ensure we have only single mode/uid/gid NFS entries. */
4895 status = check_nfs_sd(psd);
4896 if (!NT_STATUS_IS_OK(status)) {
4898 security_descriptor,
4899 discard_const_p(struct security_descriptor, psd));
4901 CHECK_STATUS(status, NT_STATUS_OK);
4904 if (!smb2_util_handle_empty(h)) {
4905 smb2_util_close(tree, h);
4907 smb2_util_unlink(tree, fname);
4908 smb2_deltree(tree, fname);
4909 smb2_deltree(tree, BASEDIR);
4910 talloc_free(mem_ctx);
4914 static bool test_setinfo_stream_eof(struct torture_context *tctx,
4915 struct smb2_tree *tree)
4919 struct smb2_create create;
4920 union smb_setfileinfo sfinfo;
4921 union smb_fileinfo finfo;
4922 struct smb2_handle h1;
4923 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4924 const char *fname = BASEDIR "\\file";
4925 const char *sname = BASEDIR "\\file:foo";
4927 torture_assert_goto(tctx, mem_ctx != NULL, ret, done,
4928 "talloc_new failed\n");
4930 torture_comment(tctx, "Test setting EOF on a stream\n");
4932 smb2_deltree(tree, BASEDIR);
4933 status = torture_smb2_testdir(tree, BASEDIR, &h1);
4934 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4935 "torture_smb2_testdir\n");
4936 smb2_util_close(tree, h1);
4938 status = torture_smb2_testfile(tree, fname, &h1);
4939 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4940 "torture_smb2_testfile failed\n");
4941 smb2_util_close(tree, h1);
4943 status = torture_smb2_testfile_access(tree, sname, &h1,
4944 SEC_FILE_WRITE_DATA);
4945 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4946 "torture_smb2_testfile failed\n");
4948 status = smb2_util_write(tree, h1, "1234567890", 0, 10);
4949 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4950 "smb2_util_write failed\n");
4951 smb2_util_close(tree, h1);
4954 * Test setting EOF to 21
4957 torture_comment(tctx, "Setting stream EOF to 21\n");
4959 status = torture_smb2_testfile_access(tree, sname, &h1,
4960 SEC_FILE_WRITE_DATA);
4961 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4962 "torture_smb2_testfile failed\n");
4964 ZERO_STRUCT(sfinfo);
4965 sfinfo.generic.in.file.handle = h1;
4966 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4967 sfinfo.position_information.in.position = 21;
4968 status = smb2_setinfo_file(tree, &sfinfo);
4969 torture_assert_ntstatus_ok_goto(tctx, status,
4970 ret, done, "set EOF 21 failed\n");
4972 smb2_util_close(tree, h1);
4974 status = torture_smb2_testfile_access(tree, sname, &h1,
4975 SEC_FILE_WRITE_DATA);
4976 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4977 "torture_smb2_testfile failed\n");
4980 finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
4981 finfo.generic.in.file.handle = h1;
4982 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
4983 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4984 "smb2_getinfo_file failed");
4986 smb2_util_close(tree, h1);
4988 torture_assert_goto(tctx, finfo.standard_info.out.size == 21,
4989 ret, done, "size != 21\n");
4992 * Test setting EOF to 0
4995 torture_comment(tctx, "Setting stream EOF to 0\n");
4997 status = torture_smb2_testfile_access(tree, sname, &h1,
4998 SEC_FILE_WRITE_DATA);
4999 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5000 "torture_smb2_testfile failed\n");
5002 ZERO_STRUCT(sfinfo);
5003 sfinfo.generic.in.file.handle = h1;
5004 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5005 sfinfo.position_information.in.position = 0;
5006 status = smb2_setinfo_file(tree, &sfinfo);
5007 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5008 "set eof 0 failed\n");
5010 smb2_util_close(tree, h1);
5012 status = torture_smb2_testfile_access(tree, sname, &h1,
5013 SEC_FILE_WRITE_DATA);
5014 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5015 "torture_smb2_testfile failed\n");
5018 finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
5019 finfo.generic.in.file.handle = h1;
5020 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
5021 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5022 "smb2_getinfo_file failed\n");
5024 smb2_util_close(tree, h1);
5026 torture_assert_goto(tctx, finfo.standard_info.out.size == 0,
5027 ret, done, "size != 0\n");
5030 * Test setinfo end-of-file info to 1
5033 torture_comment(tctx, "Setting stream EOF to 1\n");
5035 status = torture_smb2_testfile_access(tree, sname, &h1,
5036 SEC_FILE_WRITE_DATA);
5037 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5038 "torture_smb2_testfile failed\n");
5040 ZERO_STRUCT(sfinfo);
5041 sfinfo.generic.in.file.handle = h1;
5042 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5043 sfinfo.position_information.in.position = 1;
5044 status = smb2_setinfo_file(tree, &sfinfo);
5045 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5046 "set EOF 1 failed\n");
5048 smb2_util_close(tree, h1);
5050 status = torture_smb2_testfile_access(tree, sname, &h1,
5051 SEC_FILE_WRITE_DATA);
5052 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5053 "torture_smb2_testfile failed\n");
5056 finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
5057 finfo.generic.in.file.handle = h1;
5058 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
5059 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5060 "smb2_getinfo_file failed\n");
5062 smb2_util_close(tree, h1);
5064 torture_assert_goto(tctx, finfo.standard_info.out.size == 1,
5065 ret, done, "size != 1\n");
5068 * Test setting EOF to 0 with AAPL enabled, should delete stream
5071 torture_comment(tctx, "Enabling AAPL extensions\n");
5073 ret = enable_aapl(tctx, tree);
5074 torture_assert(tctx, ret == true, "enable_aapl failed\n");
5076 torture_comment(tctx, "Setting stream EOF to 0\n");
5077 status = torture_smb2_testfile_access(tree, sname, &h1,
5078 SEC_FILE_WRITE_DATA);
5079 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5080 "torture_smb2_testfile failed\n");
5082 ZERO_STRUCT(sfinfo);
5083 sfinfo.generic.in.file.handle = h1;
5084 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5085 sfinfo.position_information.in.position = 0;
5086 status = smb2_setinfo_file(tree, &sfinfo);
5087 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5088 "set eof 0 failed\n");
5090 smb2_util_close(tree, h1);
5092 ZERO_STRUCT(create);
5093 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5094 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5095 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5096 create.in.create_disposition = NTCREATEX_DISP_OPEN;
5097 create.in.fname = sname;
5099 status = smb2_create(tree, tctx, &create);
5100 torture_assert_ntstatus_equal_goto(
5101 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
5102 "Unexpected status\n");
5105 tctx, "Setting main file EOF to 1 to force 0-truncate\n");
5107 status = torture_smb2_testfile_access(
5111 SEC_FILE_WRITE_DATA);
5112 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5113 "torture_smb2_testfile failed\n");
5115 ZERO_STRUCT(sfinfo);
5116 sfinfo.generic.in.file.handle = h1;
5117 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5118 sfinfo.position_information.in.position = 1;
5119 status = smb2_setinfo_file(tree, &sfinfo);
5120 torture_assert_ntstatus_ok_goto(
5125 "set eof 1 failed\n");
5127 sfinfo.position_information.in.position = 0;
5128 status = smb2_setinfo_file(tree, &sfinfo);
5129 torture_assert_ntstatus_ok_goto(
5134 "set eof 0 failed\n");
5136 smb2_util_close(tree, h1);
5138 ZERO_STRUCT(create);
5139 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5140 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5141 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5142 create.in.create_disposition = NTCREATEX_DISP_OPEN;
5143 create.in.fname = fname;
5145 status = smb2_create(tree, tctx, &create);
5146 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5147 "torture_smb2_testfile failed\n");
5148 smb2_util_close(tree, h1);
5150 smb2_util_unlink(tree, fname);
5151 smb2_util_rmdir(tree, BASEDIR);
5156 * Note: This test depends on "vfs objects = catia fruit streams_xattr". For
5157 * some tests torture must be run on the host it tests and takes an additional
5158 * argument with the local path to the share:
5159 * "--option=torture:localdir=<SHAREPATH>".
5161 * When running against an OS X SMB server add "--option=torture:osx=true"
5163 struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
5165 struct torture_suite *suite = torture_suite_create(
5168 suite->description = talloc_strdup(suite, "vfs_fruit tests");
5170 torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
5171 torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
5172 torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
5173 torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
5174 torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
5175 torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
5176 torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
5177 torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
5178 torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
5179 torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
5180 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
5181 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
5182 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
5183 torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
5184 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
5185 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
5186 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
5187 torture_suite_add_1smb2_test(suite, "setinfo eof stream", test_setinfo_stream_eof);
5188 torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
5189 torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
5190 torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
5191 torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
5192 torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
5193 torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
5194 torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
5195 torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
5196 torture_suite_add_1smb2_test(suite, "NFS ACE entries", test_nfs_aces);
5197 torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion without embedded xattr", test_adouble_conversion_wo_xattr);
5202 static bool test_stream_names_local(struct torture_context *tctx,
5203 struct smb2_tree *tree)
5205 TALLOC_CTX *mem_ctx = talloc_new(tctx);
5207 struct smb2_create create;
5208 struct smb2_handle h;
5209 const char *fname = BASEDIR "\\stream_names.txt";
5212 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
5213 const char *streams[] = {
5214 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
5215 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
5218 const char *localdir = NULL;
5220 localdir = torture_setting_string(tctx, "localdir", NULL);
5221 if (localdir == NULL) {
5222 torture_skip(tctx, "Need localdir for test");
5225 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
5227 /* clean slate ...*/
5228 smb2_util_unlink(tree, fname);
5229 smb2_deltree(tree, fname);
5230 smb2_deltree(tree, BASEDIR);
5232 status = torture_smb2_testdir(tree, BASEDIR, &h);
5233 CHECK_STATUS(status, NT_STATUS_OK);
5234 smb2_util_close(tree, h);
5236 torture_comment(tctx, "(%s) testing stream names\n", __location__);
5237 ZERO_STRUCT(create);
5238 create.in.desired_access = SEC_FILE_WRITE_DATA;
5239 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5240 create.in.share_access =
5241 NTCREATEX_SHARE_ACCESS_DELETE|
5242 NTCREATEX_SHARE_ACCESS_READ|
5243 NTCREATEX_SHARE_ACCESS_WRITE;
5244 create.in.create_disposition = NTCREATEX_DISP_CREATE;
5245 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
5246 create.in.fname = sname1;
5248 status = smb2_create(tree, mem_ctx, &create);
5249 CHECK_STATUS(status, NT_STATUS_OK);
5250 smb2_util_close(tree, create.out.file.handle);
5252 ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
5253 "user.DosStream.bar:baz:$DATA",
5254 "data", strlen("data"));
5255 CHECK_VALUE(ret, true);
5257 ret = check_stream_list(tree, tctx, fname, 3, streams, false);
5258 CHECK_VALUE(ret, true);
5261 status = smb2_util_unlink(tree, fname);
5262 smb2_deltree(tree, BASEDIR);
5263 talloc_free(mem_ctx);
5268 static bool test_fruit_locking_conflict(struct torture_context *tctx,
5269 struct smb2_tree *tree)
5271 TALLOC_CTX *mem_ctx;
5272 struct smb2_create create;
5273 struct smb2_handle h;
5274 struct smb2_lock lck;
5275 struct smb2_lock_element el;
5276 const char *fname = BASEDIR "\\locking_conflict.txt";
5280 mem_ctx = talloc_new(tctx);
5281 torture_assert_not_null(tctx, mem_ctx, "talloc_new failed");
5283 /* clean slate ...*/
5284 smb2_util_unlink(tree, fname);
5285 smb2_deltree(tree, fname);
5286 smb2_deltree(tree, BASEDIR);
5288 status = torture_smb2_testdir(tree, BASEDIR, &h);
5289 CHECK_STATUS(status, NT_STATUS_OK);
5290 smb2_util_close(tree, h);
5292 create = (struct smb2_create) {
5293 .in.desired_access = SEC_RIGHTS_FILE_READ,
5294 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5296 NTCREATEX_SHARE_ACCESS_READ|
5297 NTCREATEX_SHARE_ACCESS_WRITE,
5298 .in.create_disposition = NTCREATEX_DISP_CREATE,
5299 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5303 status = smb2_create(tree, mem_ctx, &create);
5304 CHECK_STATUS(status, NT_STATUS_OK);
5305 h = create.out.file.handle;
5307 el = (struct smb2_lock_element) {
5308 .offset = 0xfffffffffffffffc,
5310 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
5312 lck = (struct smb2_lock) {
5314 .in.file.handle = h,
5318 status = smb2_lock(tree, &lck);
5319 CHECK_STATUS(status, NT_STATUS_OK);
5321 el = (struct smb2_lock_element) {
5323 .length = 0x7fffffffffffffff,
5324 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
5326 status = smb2_lock(tree, &lck);
5327 CHECK_STATUS(status, NT_STATUS_OK);
5329 create = (struct smb2_create) {
5330 .in.desired_access =
5331 SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
5332 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5333 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5334 .in.create_disposition = NTCREATEX_DISP_OPEN,
5335 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5339 status = smb2_create(tree, mem_ctx, &create);
5340 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
5343 struct smb2_close cl = {
5344 .level = RAW_CLOSE_SMB2,
5345 .in.file.handle = h,
5347 smb2_close(tree, &cl);
5355 struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
5357 struct torture_suite *suite = torture_suite_create(
5358 ctx, "fruit_netatalk");
5360 suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
5362 torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
5363 torture_suite_add_1smb2_test(suite, "stream names with locally created xattr", test_stream_names_local);
5364 torture_suite_add_1smb2_test(
5365 suite, "locking conflict", test_fruit_locking_conflict);
5370 struct torture_suite *torture_vfs_fruit_file_id(TALLOC_CTX *ctx)
5372 struct torture_suite *suite =
5373 torture_suite_create(ctx, "fruit_file_id");
5375 suite->description =
5376 talloc_strdup(suite, "vfs_fruit tests for on-disk file ID that "
5377 "require fruit:zero_file_id=yes");
5379 torture_suite_add_1smb2_test(suite, "zero file id if AAPL negotiated",
5385 static bool test_timemachine_volsize(struct torture_context *tctx,
5386 struct smb2_tree *tree)
5388 TALLOC_CTX *mem_ctx = talloc_new(tctx);
5389 struct smb2_handle h = {{0}};
5390 union smb_fsinfo fsinfo;
5393 const char *info_plist =
5395 " <key>band-size</key>\n"
5396 " <integer>8192</integer>\n"
5399 smb2_deltree(tree, "test.sparsebundle");
5401 ok = enable_aapl(tctx, tree);
5402 torture_assert_goto(tctx, ok, ok, done, "enable_aapl failed");
5404 status = smb2_util_mkdir(tree, "test.sparsebundle");
5405 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
5406 "smb2_util_mkdir\n");
5408 ok = write_stream(tree, __location__, tctx, mem_ctx,
5409 "test.sparsebundle/Info.plist", NULL,
5410 0, strlen(info_plist), info_plist);
5411 torture_assert_goto(tctx, ok, ok, done, "write_stream failed\n");
5413 status = smb2_util_mkdir(tree, "test.sparsebundle/bands");
5414 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
5415 "smb2_util_mkdir\n");
5417 ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/1", false);
5418 torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
5420 ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/2", false);
5421 torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
5423 status = smb2_util_roothandle(tree, &h);
5424 torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
5426 ZERO_STRUCT(fsinfo);
5427 fsinfo.generic.level = RAW_QFS_SIZE_INFORMATION;
5428 fsinfo.generic.handle = h;
5430 status = smb2_getinfo_fs(tree, tree, &fsinfo);
5431 torture_assert_ntstatus_ok(tctx, status, "smb2_getinfo_fs failed");
5433 torture_comment(tctx, "sectors_per_unit: %" PRIu32"\n"
5434 "bytes_per_sector: %" PRIu32"\n"
5435 "total_alloc_units: %" PRIu64"\n"
5436 "avail_alloc_units: %" PRIu64"\n",
5437 fsinfo.size_info.out.sectors_per_unit,
5438 fsinfo.size_info.out.bytes_per_sector,
5439 fsinfo.size_info.out.total_alloc_units,
5440 fsinfo.size_info.out.avail_alloc_units);
5443 * Let me explain the numbers:
5445 * - the share is set to "fruit:time machine max size = 32K"
5446 * - we've faked a bandsize of 8 K in the Info.plist file
5447 * - we've created two bands files
5448 * - one allocation unit is made of two sectors with 512 B each
5449 * => we've consumed 16 allocation units, there should be 16 free
5452 torture_assert_goto(tctx, fsinfo.size_info.out.sectors_per_unit == 2,
5453 ok, done, "Bad sectors_per_unit");
5455 torture_assert_goto(tctx, fsinfo.size_info.out.bytes_per_sector == 512,
5456 ok, done, "Bad bytes_per_sector");
5458 torture_assert_goto(tctx, fsinfo.size_info.out.total_alloc_units == 32,
5459 ok, done, "Bad total_alloc_units");
5461 torture_assert_goto(tctx, fsinfo.size_info.out.avail_alloc_units == 16,
5462 ok, done, "Bad avail_alloc_units");
5465 if (!smb2_util_handle_empty(h)) {
5466 smb2_util_close(tree, h);
5468 smb2_deltree(tree, "test.sparsebundle");
5469 talloc_free(mem_ctx);
5473 struct torture_suite *torture_vfs_fruit_timemachine(TALLOC_CTX *ctx)
5475 struct torture_suite *suite = torture_suite_create(
5476 ctx, "fruit_timemachine");
5478 suite->description = talloc_strdup(
5479 suite, "vfs_fruit tests for TimeMachine");
5481 torture_suite_add_1smb2_test(suite, "Timemachine-volsize",
5482 test_timemachine_volsize);
5487 static bool test_convert_xattr_and_empty_rfork_then_delete(
5488 struct torture_context *tctx,
5489 struct smb2_tree *tree1,
5490 struct smb2_tree *tree2)
5492 TALLOC_CTX *mem_ctx = talloc_new(tctx);
5493 const char *fname = BASEDIR "\\test_adouble_conversion";
5494 const char *adname = BASEDIR "/._test_adouble_conversion";
5495 const char *rfork = BASEDIR "\\test_adouble_conversion" AFPRESOURCE_STREAM_NAME;
5497 struct smb2_handle testdirh;
5499 const char *streams[] = {
5502 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
5503 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
5505 struct smb2_create create;
5506 struct smb2_find find;
5508 union smb_search_data *d;
5509 bool delete_empty_adfiles;
5510 int expected_num_files;
5512 delete_empty_adfiles = torture_setting_bool(tctx,
5513 "delete_empty_adfiles",
5516 smb2_deltree(tree1, BASEDIR);
5518 status = torture_smb2_testdir(tree1, BASEDIR, &testdirh);
5519 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5520 "torture_smb2_testdir failed\n");
5521 smb2_util_close(tree1, testdirh);
5523 ret = torture_setup_file(tctx, tree1, fname, false);
5524 torture_assert_goto(tctx, ret == true, ret, done,
5525 "torture_setup_file failed\n");
5527 ret = torture_setup_file(tctx, tree1, adname, false);
5528 torture_assert_goto(tctx, ret == true, ret, done,
5529 "torture_setup_file failed\n");
5531 ret = write_stream(tree1, __location__, tctx, mem_ctx,
5533 0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
5534 torture_assert_goto(tctx, ret == true, ret, done,
5535 "write_stream failed\n");
5537 ret = enable_aapl(tctx, tree2);
5538 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
5541 * Issue a smb2_find(), this triggers the server-side conversion
5544 create = (struct smb2_create) {
5545 .in.desired_access = SEC_RIGHTS_DIR_READ,
5546 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
5547 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
5548 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5549 .in.create_disposition = NTCREATEX_DISP_OPEN,
5550 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5551 .in.fname = BASEDIR,
5554 status = smb2_create(tree2, tctx, &create);
5555 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5556 "smb2_create failed\n");
5558 find = (struct smb2_find) {
5559 .in.file.handle = create.out.file.handle,
5561 .in.max_response_size = 0x1000,
5562 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
5565 status = smb2_find_level(tree2, tree2, &find, &count, &d);
5566 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5567 "smb2_find_level failed\n");
5569 status = smb2_util_close(tree2, create.out.file.handle);
5570 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5571 "smb2_util_close failed");
5574 * Check number of streams
5577 ret = check_stream_list(tree2, tctx, fname, 4, streams, false);
5578 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
5581 * Check Resource Fork is gone
5584 create = (struct smb2_create) {
5585 .in.desired_access = SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
5586 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5587 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5588 .in.create_disposition = NTCREATEX_DISP_OPEN,
5589 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5593 status = smb2_create(tree2, mem_ctx, &create);
5594 torture_assert_ntstatus_equal_goto(
5595 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
5596 ret, done, "Bad smb2_create return\n");
5599 * Check xattr data has been migrated from the AppleDouble file to
5603 ret = check_stream(tree2, __location__, tctx, mem_ctx,
5604 fname, AFPINFO_STREAM,
5605 0, 60, 16, 8, "TESTSLOW");
5606 torture_assert_goto(tctx, ret == true, ret, done,
5607 "check AFPINFO_STREAM failed\n");
5609 ret = check_stream(tree2, __location__, tctx, mem_ctx,
5610 fname, ":foo" "\xef\x80\xa2" "bar", /* foo:bar */
5612 torture_assert_goto(tctx, ret == true, ret, done,
5613 "check foo stream failed\n");
5616 * Now check number of files. If delete_empty_adfiles is set, the
5617 * AppleDouble files should have been deleted.
5620 create = (struct smb2_create) {
5621 .in.desired_access = SEC_RIGHTS_DIR_READ,
5622 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
5623 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
5624 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5625 .in.create_disposition = NTCREATEX_DISP_OPEN,
5626 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5627 .in.fname = BASEDIR,
5630 status = smb2_create(tree2, tctx, &create);
5631 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5632 "smb2_create failed\n");
5634 find = (struct smb2_find) {
5635 .in.file.handle = create.out.file.handle,
5637 .in.max_response_size = 0x1000,
5638 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
5641 status = smb2_find_level(tree2, tree2, &find, &count, &d);
5642 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5643 "smb2_find_level failed\n");
5645 status = smb2_util_close(tree2, create.out.file.handle);
5646 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5647 "smb2_util_close failed");
5649 if (delete_empty_adfiles) {
5650 expected_num_files = 3;
5652 expected_num_files = 4;
5654 torture_assert_int_equal_goto(tctx, count, expected_num_files, ret, done,
5655 "Wrong number of files\n");
5658 smb2_deltree(tree1, BASEDIR);
5659 talloc_free(mem_ctx);
5663 struct torture_suite *torture_vfs_fruit_conversion(TALLOC_CTX *ctx)
5665 struct torture_suite *suite = torture_suite_create(
5666 ctx, "fruit_conversion");
5668 suite->description = talloc_strdup(
5669 suite, "vfs_fruit conversion tests");
5671 torture_suite_add_2ns_smb2_test(
5672 suite, "convert_xattr_and_empty_rfork_then_delete",
5673 test_convert_xattr_and_empty_rfork_then_delete);