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 torture_comment(tctx, "(%s) testing stream names\n", __location__);
3136 ZERO_STRUCT(create);
3137 create.in.desired_access = SEC_FILE_WRITE_DATA;
3138 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3139 create.in.share_access =
3140 NTCREATEX_SHARE_ACCESS_DELETE|
3141 NTCREATEX_SHARE_ACCESS_READ|
3142 NTCREATEX_SHARE_ACCESS_WRITE;
3143 create.in.create_disposition = NTCREATEX_DISP_CREATE;
3144 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3145 create.in.fname = sname1;
3147 status = smb2_create(tree, mem_ctx, &create);
3148 CHECK_STATUS(status, NT_STATUS_OK);
3149 smb2_util_close(tree, create.out.file.handle);
3151 ret = check_stream_list(tree, tctx, fname, 2, streams, false);
3152 CHECK_VALUE(ret, true);
3155 status = smb2_util_unlink(tree, fname);
3156 smb2_deltree(tree, BASEDIR);
3157 talloc_free(mem_ctx);
3162 /* Renaming a directory with open file, should work for OS X AAPL clients */
3163 static bool test_rename_dir_openfile(struct torture_context *torture,
3164 struct smb2_tree *tree)
3170 union smb_setfileinfo sinfo;
3171 struct smb2_handle d1, h1;
3172 const char *renamedir = BASEDIR "-new";
3173 bool server_is_osx = torture_setting_bool(torture, "osx", false);
3175 smb2_deltree(tree, BASEDIR);
3176 smb2_util_rmdir(tree, BASEDIR);
3177 smb2_deltree(tree, renamedir);
3179 ZERO_STRUCT(io.smb2);
3180 io.generic.level = RAW_OPEN_SMB2;
3181 io.smb2.in.create_flags = 0;
3182 io.smb2.in.desired_access = 0x0017019f;
3183 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
3184 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3185 io.smb2.in.share_access = 0;
3186 io.smb2.in.alloc_size = 0;
3187 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
3188 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3189 io.smb2.in.security_flags = 0;
3190 io.smb2.in.fname = BASEDIR;
3192 status = smb2_create(tree, torture, &(io.smb2));
3193 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3194 d1 = io.smb2.out.file.handle;
3196 ZERO_STRUCT(io.smb2);
3197 io.generic.level = RAW_OPEN_SMB2;
3198 io.smb2.in.create_flags = 0;
3199 io.smb2.in.desired_access = 0x0017019f;
3200 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
3201 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3202 io.smb2.in.share_access = 0;
3203 io.smb2.in.alloc_size = 0;
3204 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
3205 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3206 io.smb2.in.security_flags = 0;
3207 io.smb2.in.fname = BASEDIR "\\file.txt";
3209 status = smb2_create(tree, torture, &(io.smb2));
3210 torture_assert_ntstatus_ok(torture, status, "smb2_create file");
3211 h1 = io.smb2.out.file.handle;
3213 if (!server_is_osx) {
3214 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
3217 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3218 sinfo.rename_information.in.file.handle = d1;
3219 sinfo.rename_information.in.overwrite = 0;
3220 sinfo.rename_information.in.root_fid = 0;
3221 sinfo.rename_information.in.new_name = renamedir;
3222 status = smb2_setinfo_file(tree, &sinfo);
3224 torture_assert_ntstatus_equal(torture, status,
3225 NT_STATUS_ACCESS_DENIED,
3226 "smb2_setinfo_file");
3228 ZERO_STRUCT(cl.smb2);
3229 cl.smb2.level = RAW_CLOSE_SMB2;
3230 cl.smb2.in.file.handle = d1;
3231 status = smb2_close(tree, &(cl.smb2));
3232 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3236 torture_comment(torture, "Enabling AAPL\n");
3238 ret = enable_aapl(torture, tree);
3239 torture_assert(torture, ret == true, "enable_aapl failed");
3241 torture_comment(torture, "Renaming directory with AAPL\n");
3243 ZERO_STRUCT(io.smb2);
3244 io.generic.level = RAW_OPEN_SMB2;
3245 io.smb2.in.desired_access = 0x0017019f;
3246 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3247 io.smb2.in.share_access = 0;
3248 io.smb2.in.alloc_size = 0;
3249 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
3250 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3251 io.smb2.in.security_flags = 0;
3252 io.smb2.in.fname = BASEDIR;
3254 status = smb2_create(tree, torture, &(io.smb2));
3255 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3256 d1 = io.smb2.out.file.handle;
3259 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3260 sinfo.rename_information.in.file.handle = d1;
3261 sinfo.rename_information.in.overwrite = 0;
3262 sinfo.rename_information.in.root_fid = 0;
3263 sinfo.rename_information.in.new_name = renamedir;
3265 status = smb2_setinfo_file(tree, &sinfo);
3266 torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
3268 ZERO_STRUCT(cl.smb2);
3269 cl.smb2.level = RAW_CLOSE_SMB2;
3270 cl.smb2.in.file.handle = d1;
3271 status = smb2_close(tree, &(cl.smb2));
3272 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3275 cl.smb2.in.file.handle = h1;
3276 status = smb2_close(tree, &(cl.smb2));
3277 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3280 torture_comment(torture, "Cleaning up\n");
3282 if (h1.data[0] || h1.data[1]) {
3283 ZERO_STRUCT(cl.smb2);
3284 cl.smb2.level = RAW_CLOSE_SMB2;
3285 cl.smb2.in.file.handle = h1;
3286 status = smb2_close(tree, &(cl.smb2));
3289 smb2_util_unlink(tree, BASEDIR "\\file.txt");
3290 smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
3291 smb2_deltree(tree, renamedir);
3292 smb2_deltree(tree, BASEDIR);
3296 static bool test_afpinfo_enoent(struct torture_context *tctx,
3297 struct smb2_tree *tree)
3301 struct smb2_create create;
3302 struct smb2_handle h1;
3303 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3304 const char *fname = BASEDIR "\\file";
3305 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3307 torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
3309 smb2_deltree(tree, BASEDIR);
3310 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3311 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3312 smb2_util_close(tree, h1);
3313 ret = torture_setup_file(mem_ctx, tree, fname, false);
3314 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3316 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3318 ZERO_STRUCT(create);
3319 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3320 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3321 create.in.fname = sname;
3323 status = smb2_create(tree, mem_ctx, &create);
3324 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3325 ret, done, "Got unexpected AFP_AfpInfo stream");
3328 smb2_util_unlink(tree, fname);
3329 smb2_util_rmdir(tree, BASEDIR);
3333 static bool test_create_delete_on_close(struct torture_context *tctx,
3334 struct smb2_tree *tree)
3338 struct smb2_create create;
3339 struct smb2_handle h1;
3340 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3341 const char *fname = BASEDIR "\\file";
3342 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3343 const char *type_creator = "SMB,OLE!";
3344 AfpInfo *info = NULL;
3345 const char *streams_basic[] = {
3348 const char *streams_afpinfo[] = {
3353 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3355 torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
3357 smb2_deltree(tree, BASEDIR);
3358 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3359 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3360 smb2_util_close(tree, h1);
3361 ret = torture_setup_file(mem_ctx, tree, fname, false);
3362 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3364 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3366 ZERO_STRUCT(create);
3367 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3368 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3369 create.in.fname = sname;
3371 status = smb2_create(tree, mem_ctx, &create);
3372 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3373 ret, done, "Got unexpected AFP_AfpInfo stream");
3375 ZERO_STRUCT(create);
3376 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3377 create.in.desired_access = SEC_FILE_ALL;
3378 create.in.fname = sname;
3380 status = smb2_create(tree, mem_ctx, &create);
3381 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3382 ret, done, "Got unexpected AFP_AfpInfo stream");
3384 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3385 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3387 torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
3389 info = torture_afpinfo_new(mem_ctx);
3390 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3392 memcpy(info->afpi_FinderInfo, type_creator, 8);
3393 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3394 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3396 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3397 0, 60, 16, 8, type_creator);
3398 torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
3400 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3401 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3403 ZERO_STRUCT(create);
3404 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3405 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3406 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3407 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3408 create.in.fname = sname;
3409 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3411 status = smb2_create(tree, mem_ctx, &create);
3412 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3414 h1 = create.out.file.handle;
3415 smb2_util_close(tree, h1);
3417 ZERO_STRUCT(create);
3418 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3419 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
3420 create.in.fname = sname;
3421 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3422 status = smb2_create(tree, mem_ctx, &create);
3423 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3424 ret, done, "Got unexpected AFP_AfpInfo stream");
3426 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3427 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3430 smb2_util_unlink(tree, fname);
3431 smb2_util_rmdir(tree, BASEDIR);
3435 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
3436 struct smb2_tree *tree)
3440 struct smb2_create create;
3441 union smb_setfileinfo sfinfo;
3442 struct smb2_handle h1;
3443 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3444 const char *fname = BASEDIR "\\file";
3445 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3446 const char *type_creator = "SMB,OLE!";
3447 AfpInfo *info = NULL;
3448 const char *streams_basic[] = {
3452 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3454 torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
3456 smb2_deltree(tree, BASEDIR);
3457 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3458 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3459 smb2_util_close(tree, h1);
3460 ret = torture_setup_file(mem_ctx, tree, fname, false);
3461 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3463 info = torture_afpinfo_new(mem_ctx);
3464 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3465 memcpy(info->afpi_FinderInfo, type_creator, 8);
3466 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3467 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3469 ZERO_STRUCT(create);
3470 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3471 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3472 create.in.fname = sname;
3473 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3474 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3476 status = smb2_create(tree, mem_ctx, &create);
3477 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3479 h1 = create.out.file.handle;
3481 /* Delete stream via setinfo delete-on-close */
3482 ZERO_STRUCT(sfinfo);
3483 sfinfo.disposition_info.in.delete_on_close = 1;
3484 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3485 sfinfo.generic.in.file.handle = h1;
3486 status = smb2_setinfo_file(tree, &sfinfo);
3487 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3489 smb2_util_close(tree, h1);
3491 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3492 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3494 ZERO_STRUCT(create);
3495 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3496 create.in.desired_access = SEC_FILE_ALL;
3497 create.in.fname = sname;
3498 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3499 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3500 status = smb2_create(tree, mem_ctx, &create);
3501 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3502 ret, done, "Got unexpected AFP_AfpInfo stream");
3505 smb2_util_unlink(tree, fname);
3506 smb2_util_rmdir(tree, BASEDIR);
3510 static bool test_setinfo_eof(struct torture_context *tctx,
3511 struct smb2_tree *tree)
3515 struct smb2_create create;
3516 union smb_setfileinfo sfinfo;
3517 struct smb2_handle h1;
3518 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3519 const char *fname = BASEDIR "\\file";
3520 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3521 const char *type_creator = "SMB,OLE!";
3522 AfpInfo *info = NULL;
3523 const char *streams_afpinfo[] = {
3528 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3530 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
3532 smb2_deltree(tree, BASEDIR);
3533 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3534 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3535 smb2_util_close(tree, h1);
3536 ret = torture_setup_file(mem_ctx, tree, fname, false);
3537 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3539 info = torture_afpinfo_new(mem_ctx);
3540 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3541 memcpy(info->afpi_FinderInfo, type_creator, 8);
3542 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3543 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3545 ZERO_STRUCT(create);
3546 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3547 create.in.desired_access = SEC_FILE_ALL;
3548 create.in.fname = sname;
3549 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3550 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3552 status = smb2_create(tree, mem_ctx, &create);
3553 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3555 h1 = create.out.file.handle;
3557 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
3559 /* Test setinfo end-of-file info */
3560 ZERO_STRUCT(sfinfo);
3561 sfinfo.generic.in.file.handle = h1;
3562 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3563 sfinfo.position_information.in.position = 61;
3564 status = smb2_setinfo_file(tree, &sfinfo);
3565 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
3566 ret, done, "set eof 61 failed");
3568 torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
3570 /* Truncation returns success, but has no effect */
3571 ZERO_STRUCT(sfinfo);
3572 sfinfo.generic.in.file.handle = h1;
3573 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3574 sfinfo.position_information.in.position = 1;
3575 status = smb2_setinfo_file(tree, &sfinfo);
3576 torture_assert_ntstatus_ok_goto(tctx, status,
3577 ret, done, "set eof 1 failed");
3578 smb2_util_close(tree, h1);
3580 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3581 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3583 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3584 0, 60, 16, 8, type_creator);
3585 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3587 ZERO_STRUCT(create);
3588 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3589 create.in.desired_access = SEC_FILE_ALL;
3590 create.in.fname = sname;
3591 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3592 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3594 status = smb2_create(tree, mem_ctx, &create);
3595 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3597 h1 = create.out.file.handle;
3600 * Delete stream via setinfo end-of-file info to 0, should
3601 * return success but stream MUST NOT deleted
3603 ZERO_STRUCT(sfinfo);
3604 sfinfo.generic.in.file.handle = h1;
3605 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3606 sfinfo.position_information.in.position = 0;
3607 status = smb2_setinfo_file(tree, &sfinfo);
3608 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3610 smb2_util_close(tree, h1);
3612 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3613 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3615 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3616 0, 60, 16, 8, type_creator);
3617 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3620 smb2_util_unlink(tree, fname);
3621 smb2_util_rmdir(tree, BASEDIR);
3625 static bool test_afpinfo_all0(struct torture_context *tctx,
3626 struct smb2_tree *tree)
3630 struct smb2_create create;
3631 struct smb2_handle h1 = {{0}};
3632 struct smb2_handle baseh = {{0}};
3633 union smb_setfileinfo setfinfo;
3634 union smb_fileinfo getfinfo;
3635 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3636 const char *fname = BASEDIR "\\file";
3637 const char *sname = BASEDIR "\\file" AFPINFO_STREAM;
3638 const char *type_creator = "SMB,OLE!";
3639 AfpInfo *info = NULL;
3640 char *infobuf = NULL;
3641 const char *streams_basic[] = {
3644 const char *streams_afpinfo[] = {
3649 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3651 torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
3653 smb2_deltree(tree, BASEDIR);
3654 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3655 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3656 smb2_util_close(tree, h1);
3657 ret = torture_setup_file(mem_ctx, tree, fname, false);
3658 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3660 info = torture_afpinfo_new(mem_ctx);
3661 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3662 memcpy(info->afpi_FinderInfo, type_creator, 8);
3663 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3664 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3666 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3667 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3669 /* Write all 0 to AFP_AfpInfo */
3670 memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
3671 infobuf = torture_afpinfo_pack(mem_ctx, info);
3672 torture_assert_not_null_goto(tctx, infobuf, ret, done,
3673 "torture_afpinfo_pack failed\n");
3675 ZERO_STRUCT(create);
3676 create.in.desired_access = SEC_FILE_ALL;
3677 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3678 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3679 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3680 create.in.fname = fname;
3682 status = smb2_create(tree, mem_ctx, &create);
3683 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3684 "smb2_create failed\n");
3685 baseh = create.out.file.handle;
3687 ZERO_STRUCT(create);
3688 create.in.desired_access = SEC_FILE_ALL;
3689 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3690 create.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
3691 create.in.fname = sname;
3693 status = smb2_create(tree, mem_ctx, &create);
3694 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3695 "smb2_create failed\n");
3696 h1 = create.out.file.handle;
3698 status = smb2_util_write(tree, h1, infobuf, 0, AFP_INFO_SIZE);
3699 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3700 "smb2_util_write failed\n");
3703 * Get stream information on open handle, must return only default
3704 * stream, the AFP_AfpInfo stream must not be returned.
3707 ZERO_STRUCT(getfinfo);
3708 getfinfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
3709 getfinfo.generic.in.file.handle = baseh;
3711 status = smb2_getinfo_file(tree, tctx, &getfinfo);
3712 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3713 "get stream info\n");
3715 torture_assert_int_equal_goto(tctx, getfinfo.stream_info.out.num_streams,
3716 1, ret, done, "stream count");
3718 smb2_util_close(tree, baseh);
3722 * Try to set some file-basic-info (time) on the stream. This catches
3723 * naive implementation mistakes that simply deleted the backing store
3724 * from the filesystem in the zero-out step.
3727 ZERO_STRUCT(setfinfo);
3728 unix_to_nt_time(&setfinfo.basic_info.in.write_time, time(NULL));
3729 setfinfo.basic_info.in.attrib = 0x20;
3730 setfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
3731 setfinfo.generic.in.file.handle = h1;
3733 status = smb2_setinfo_file(tree, &setfinfo);
3734 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3735 "smb2_getinfo_file failed\n");
3737 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3738 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
3740 smb2_util_close(tree, h1);
3743 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3744 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3747 if (!smb2_util_handle_empty(h1)) {
3748 smb2_util_close(tree, h1);
3750 if (!smb2_util_handle_empty(baseh)) {
3751 smb2_util_close(tree, baseh);
3753 smb2_util_unlink(tree, fname);
3754 smb2_util_rmdir(tree, BASEDIR);
3758 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
3759 struct smb2_tree *tree)
3763 struct smb2_create create;
3764 struct smb2_handle h1;
3765 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3766 const char *fname = BASEDIR "\\file";
3767 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3768 const char *streams_basic[] = {
3771 const char *streams_afpresource[] = {
3776 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3778 torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
3780 smb2_deltree(tree, BASEDIR);
3781 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3782 torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
3783 smb2_util_close(tree, h1);
3784 ret = torture_setup_file(mem_ctx, tree, fname, false);
3785 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3787 torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
3789 ZERO_STRUCT(create);
3790 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3791 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3792 create.in.fname = sname;
3794 status = smb2_create(tree, mem_ctx, &create);
3795 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3796 ret, done, "Got unexpected AFP_AfpResource stream");
3798 ZERO_STRUCT(create);
3799 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3800 create.in.desired_access = SEC_FILE_ALL;
3801 create.in.fname = sname;
3803 status = smb2_create(tree, mem_ctx, &create);
3804 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3805 ret, done, "Got unexpected AFP_AfpResource stream");
3807 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3808 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3810 torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
3812 ret = write_stream(tree, __location__, tctx, mem_ctx,
3813 fname, AFPRESOURCE_STREAM_NAME,
3814 0, 10, "1234567890");
3815 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3817 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3818 0, 10, 0, 10, "1234567890");
3819 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3821 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3822 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3824 ZERO_STRUCT(create);
3825 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3826 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3827 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3828 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3829 create.in.fname = sname;
3830 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3832 status = smb2_create(tree, mem_ctx, &create);
3833 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3835 h1 = create.out.file.handle;
3836 smb2_util_close(tree, h1);
3838 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3839 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3841 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3842 0, 10, 0, 10, "1234567890");
3843 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3846 smb2_util_unlink(tree, fname);
3847 smb2_util_rmdir(tree, BASEDIR);
3851 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
3852 struct smb2_tree *tree)
3856 struct smb2_create create;
3857 union smb_setfileinfo sfinfo;
3858 struct smb2_handle h1;
3859 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3860 const char *fname = BASEDIR "\\file";
3861 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3862 const char *streams_afpresource[] = {
3867 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3869 torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
3871 smb2_deltree(tree, BASEDIR);
3872 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3873 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3874 smb2_util_close(tree, h1);
3875 ret = torture_setup_file(mem_ctx, tree, fname, false);
3876 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3878 ret = write_stream(tree, __location__, tctx, mem_ctx,
3879 fname, AFPRESOURCE_STREAM_NAME,
3880 10, 10, "1234567890");
3881 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3883 ZERO_STRUCT(create);
3884 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3885 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3886 create.in.fname = sname;
3887 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3888 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3890 status = smb2_create(tree, mem_ctx, &create);
3891 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3893 h1 = create.out.file.handle;
3895 /* Try to delete stream via setinfo delete-on-close */
3896 ZERO_STRUCT(sfinfo);
3897 sfinfo.disposition_info.in.delete_on_close = 1;
3898 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3899 sfinfo.generic.in.file.handle = h1;
3900 status = smb2_setinfo_file(tree, &sfinfo);
3901 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3903 smb2_util_close(tree, h1);
3905 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3906 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3908 ZERO_STRUCT(create);
3909 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3910 create.in.desired_access = SEC_FILE_ALL;
3911 create.in.fname = sname;
3912 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3913 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3914 status = smb2_create(tree, mem_ctx, &create);
3915 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3916 "Got unexpected AFP_AfpResource stream");
3919 smb2_util_unlink(tree, fname);
3920 smb2_util_rmdir(tree, BASEDIR);
3924 static bool test_setinfo_eof_resource(struct torture_context *tctx,
3925 struct smb2_tree *tree)
3929 struct smb2_create create;
3930 union smb_setfileinfo sfinfo;
3931 union smb_fileinfo finfo;
3932 struct smb2_handle h1;
3933 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3934 const char *fname = BASEDIR "\\file";
3935 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3936 const char *streams_basic[] = {
3940 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3942 torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
3944 smb2_deltree(tree, BASEDIR);
3945 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3946 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3947 smb2_util_close(tree, h1);
3948 ret = torture_setup_file(mem_ctx, tree, fname, false);
3949 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3951 ret = write_stream(tree, __location__, tctx, mem_ctx,
3952 fname, AFPRESOURCE_STREAM_NAME,
3953 10, 10, "1234567890");
3954 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3956 ZERO_STRUCT(create);
3957 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3958 create.in.desired_access = SEC_FILE_ALL;
3959 create.in.fname = sname;
3960 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3961 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3963 status = smb2_create(tree, mem_ctx, &create);
3964 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3966 h1 = create.out.file.handle;
3968 torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
3970 /* Test setinfo end-of-file info */
3971 ZERO_STRUCT(sfinfo);
3972 sfinfo.generic.in.file.handle = h1;
3973 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3974 sfinfo.position_information.in.position = 1;
3975 status = smb2_setinfo_file(tree, &sfinfo);
3976 torture_assert_ntstatus_ok_goto(tctx, status,
3977 ret, done, "set eof 1 failed");
3979 smb2_util_close(tree, h1);
3981 /* Check size == 1 */
3982 ZERO_STRUCT(create);
3983 create.in.fname = sname;
3984 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3985 create.in.desired_access = SEC_FILE_ALL;
3986 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3987 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3988 status = smb2_create(tree, mem_ctx, &create);
3989 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3991 h1 = create.out.file.handle;
3994 finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
3995 finfo.generic.in.file.handle = h1;
3996 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
3997 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
3999 smb2_util_close(tree, h1);
4001 torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
4003 ZERO_STRUCT(create);
4004 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4005 create.in.desired_access = SEC_FILE_ALL;
4006 create.in.fname = sname;
4007 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4008 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 * Delete stream via setinfo end-of-file info to 0, this
4017 * should delete the stream.
4019 ZERO_STRUCT(sfinfo);
4020 sfinfo.generic.in.file.handle = h1;
4021 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4022 sfinfo.position_information.in.position = 0;
4023 status = smb2_setinfo_file(tree, &sfinfo);
4024 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
4026 smb2_util_close(tree, h1);
4028 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
4029 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4031 ZERO_STRUCT(create);
4032 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4033 create.in.desired_access = SEC_FILE_ALL;
4034 create.in.fname = sname;
4035 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4036 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4038 status = smb2_create(tree, mem_ctx, &create);
4039 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4040 ret, done, "smb2_create failed");
4043 smb2_util_unlink(tree, fname);
4044 smb2_util_rmdir(tree, BASEDIR);
4049 * This tests that right after creating the AFP_AfpInfo stream,
4050 * reading from the stream returns an empty, default metadata blob of
4053 * NOTE: against OS X SMB server this only works if the read request
4054 * is compounded with the create that created the stream, is fails
4055 * otherwise. We don't care...
4057 static bool test_null_afpinfo(struct torture_context *tctx,
4058 struct smb2_tree *tree)
4060 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4061 const char *fname = "test_null_afpinfo";
4062 const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
4065 struct smb2_request *req[3];
4066 struct smb2_handle handle;
4067 struct smb2_create create;
4068 struct smb2_read read;
4069 AfpInfo *afpinfo = NULL;
4070 char *afpinfo_buf = NULL;
4071 const char *type_creator = "SMB,OLE!";
4073 torture_comment(tctx, "Checking create of AfpInfo stream\n");
4075 smb2_util_unlink(tree, fname);
4077 ret = torture_setup_file(mem_ctx, tree, fname, false);
4078 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
4080 ZERO_STRUCT(create);
4081 create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
4082 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
4083 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4084 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4085 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
4086 create.in.fname = sname;
4088 smb2_transport_compound_start(tree->session->transport, 2);
4090 req[0] = smb2_create_send(tree, &create);
4092 handle.data[0] = UINT64_MAX;
4093 handle.data[1] = UINT64_MAX;
4095 smb2_transport_compound_set_related(tree->session->transport, true);
4098 read.in.file.handle = handle;
4099 read.in.length = AFP_INFO_SIZE;
4100 req[1] = smb2_read_send(tree, &read);
4102 status = smb2_create_recv(req[0], tree, &create);
4103 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
4105 handle = create.out.file.handle;
4107 status = smb2_read_recv(req[1], tree, &read);
4108 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
4110 afpinfo = torture_afpinfo_new(mem_ctx);
4111 torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
4113 memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
4115 afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
4116 torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
4118 status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
4119 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
4121 smb2_util_close(tree, handle);
4123 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
4124 0, 60, 16, 8, type_creator);
4125 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
4128 smb2_util_unlink(tree, fname);
4129 talloc_free(mem_ctx);
4133 static bool test_delete_file_with_rfork(struct torture_context *tctx,
4134 struct smb2_tree *tree)
4136 const char *fname = "torture_write_rfork_io";
4137 const char *rfork_content = "1234567890";
4141 smb2_util_unlink(tree, fname);
4143 torture_comment(tctx, "Test deleting file with resource fork\n");
4145 ret = torture_setup_file(tctx, tree, fname, false);
4146 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
4148 ret = write_stream(tree, __location__, tctx, tctx,
4149 fname, AFPRESOURCE_STREAM_NAME,
4150 10, 10, rfork_content);
4151 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
4153 ret = check_stream(tree, __location__, tctx, tctx,
4154 fname, AFPRESOURCE_STREAM_NAME,
4155 0, 20, 10, 10, rfork_content);
4156 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
4158 status = smb2_util_unlink(tree, fname);
4159 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
4165 static bool test_rename_and_read_rsrc(struct torture_context *tctx,
4166 struct smb2_tree *tree)
4170 struct smb2_create create, create2;
4171 struct smb2_handle h1, h2;
4172 const char *fname = "test_rename_openfile";
4173 const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
4174 const char *fname_renamed = "test_rename_openfile_renamed";
4175 const char *data = "1234567890";
4176 union smb_setfileinfo sinfo;
4178 ret = enable_aapl(tctx, tree);
4179 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
4181 torture_comment(tctx, "Create 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");
4186 ret = write_stream(tree, __location__, tctx, tctx,
4187 fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
4188 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4190 torture_comment(tctx, "Open resource fork\n");
4192 ZERO_STRUCT(create);
4193 create.in.desired_access = SEC_FILE_ALL;
4194 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4195 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4196 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4197 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4198 create.in.fname = sname;
4200 status = smb2_create(tree, tctx, &create);
4201 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4203 h1 = create.out.file.handle;
4205 torture_comment(tctx, "Rename base file\n");
4207 ZERO_STRUCT(create2);
4208 create2.in.desired_access = SEC_FILE_ALL;
4209 create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4210 create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4211 create2.in.create_disposition = NTCREATEX_DISP_OPEN;
4212 create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4213 create2.in.fname = fname;
4215 status = smb2_create(tree, tctx, &create2);
4216 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4218 h2 = create2.out.file.handle;
4221 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
4222 sinfo.rename_information.in.file.handle = h2;
4223 sinfo.rename_information.in.overwrite = 0;
4224 sinfo.rename_information.in.root_fid = 0;
4225 sinfo.rename_information.in.new_name = fname_renamed;
4227 status = smb2_setinfo_file(tree, &sinfo);
4228 torture_assert_ntstatus_equal_goto(
4229 tctx, status, NT_STATUS_ACCESS_DENIED, ret, done,
4230 "smb2_setinfo_file failed");
4232 smb2_util_close(tree, h1);
4233 smb2_util_close(tree, h2);
4236 smb2_util_unlink(tree, fname);
4237 smb2_util_unlink(tree, fname_renamed);
4242 static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
4243 struct smb2_tree *tree)
4245 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4246 const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
4247 const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
4249 struct smb2_handle testdirh;
4251 struct smb2_create io;
4253 const char *type_creator = "SMB,OLE!";
4256 union smb_search_data *d;
4260 smb2_deltree(tree, BASEDIR);
4262 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
4263 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
4264 smb2_util_close(tree, testdirh);
4266 torture_comment(tctx, "Enabling AAPL\n");
4268 ret = enable_aapl(tctx, tree);
4269 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
4272 * Now that Requested AAPL extensions are enabled, setup some
4273 * Mac files with metadata and resource fork
4276 torture_comment(tctx, "Preparing file\n");
4278 ret = torture_setup_file(mem_ctx, tree, fname, false);
4279 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
4281 info = torture_afpinfo_new(mem_ctx);
4282 torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
4284 memcpy(info->afpi_FinderInfo, type_creator, 8);
4285 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
4286 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
4288 ret = write_stream(tree, __location__, tctx, mem_ctx,
4289 fname, AFPRESOURCE_STREAM_NAME,
4291 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4294 * Ok, file is prepared, now call smb2/find
4297 torture_comment(tctx, "Issue find\n");
4300 io.in.desired_access = SEC_RIGHTS_DIR_READ;
4301 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
4302 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
4303 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
4304 NTCREATEX_SHARE_ACCESS_WRITE |
4305 NTCREATEX_SHARE_ACCESS_DELETE);
4306 io.in.create_disposition = NTCREATEX_DISP_OPEN;
4307 io.in.fname = BASEDIR;
4308 status = smb2_create(tree, tctx, &io);
4309 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4312 f.in.file.handle = io.out.file.handle;
4314 f.in.max_response_size = 0x1000;
4315 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
4317 status = smb2_find_level(tree, tree, &f, &count, &d);
4318 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
4320 status = smb2_util_close(tree, io.out.file.handle);
4321 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
4323 torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
4325 for (i = 0; i < count; i++) {
4326 const char *found = d[i].id_both_directory_info.name.s;
4328 if (!strcmp(found, ".") || !strcmp(found, ".."))
4330 if (strncmp(found, "._", 2) == 0) {
4336 torture_assert_str_equal_goto(tctx,
4337 d[i].id_both_directory_info.name.s, name,
4338 ret, done, "bad name");
4340 rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
4341 torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
4343 torture_assert_mem_equal_goto(tctx, type_creator,
4344 d[i].id_both_directory_info.short_name_buf + 8,
4345 8, ret, done, "Bad FinderInfo");
4347 smb2_util_unlink(tree, fname);
4348 smb2_deltree(tree, BASEDIR);
4349 talloc_free(mem_ctx);
4353 static bool test_invalid_afpinfo(struct torture_context *tctx,
4354 struct smb2_tree *tree1,
4355 struct smb2_tree *tree2)
4357 const char *fname = "filtest_invalid_afpinfo";
4358 const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
4359 struct smb2_create create;
4360 const char *streams_basic[] = {
4363 const char *streams_afpinfo[] = {
4370 if (tree2 == NULL) {
4371 torture_skip_goto(tctx, done, "need second share without fruit\n");
4374 torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
4376 ret = torture_setup_file(tctx, tree2, fname, false);
4377 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4379 ret = write_stream(tree2, __location__, tctx, tctx,
4380 fname, AFPINFO_STREAM_NAME,
4382 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4384 ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
4385 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4387 torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
4389 ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
4390 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4392 torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
4394 ZERO_STRUCT(create);
4395 create.in.desired_access = SEC_FILE_ALL;
4396 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4397 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4398 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4399 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4400 create.in.fname = sname;
4402 status = smb2_create(tree1, tctx, &create);
4403 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4404 ret, done, "Stream still around?");
4407 smb2_util_unlink(tree1, fname);
4411 static bool test_zero_file_id(struct torture_context *tctx,
4412 struct smb2_tree *tree)
4414 const char *fname = "filtest_file_id";
4415 struct smb2_create create = {0};
4418 uint8_t zero_file_id[8] = {0};
4420 torture_comment(tctx, "Testing zero file id\n");
4422 ret = torture_setup_file(tctx, tree, fname, false);
4423 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4425 ZERO_STRUCT(create);
4426 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4427 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4428 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4429 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4430 create.in.fname = fname;
4431 create.in.query_on_disk_id = true;
4433 status = smb2_create(tree, tctx, &create);
4434 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
4436 "test file could not be opened");
4437 torture_assert_mem_not_equal_goto(tctx, create.out.on_disk_id,
4438 zero_file_id, 8, ret, done,
4439 "unexpected zero file id");
4441 smb2_util_close(tree, create.out.file.handle);
4443 ret = enable_aapl(tctx, tree);
4444 torture_assert(tctx, ret == true, "enable_aapl failed");
4446 ZERO_STRUCT(create);
4447 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4448 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4449 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4450 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4451 create.in.fname = fname;
4452 create.in.query_on_disk_id = true;
4454 status = smb2_create(tree, tctx, &create);
4455 torture_assert_ntstatus_equal_goto(
4456 tctx, status, NT_STATUS_OK, ret, done,
4457 "test file could not be opened with AAPL");
4458 torture_assert_mem_equal_goto(tctx, create.out.on_disk_id, zero_file_id,
4459 8, ret, done, "non-zero file id");
4461 smb2_util_close(tree, create.out.file.handle);
4464 smb2_util_unlink(tree, fname);
4468 static bool copy_one_stream(struct torture_context *torture,
4469 struct smb2_tree *tree,
4470 TALLOC_CTX *tmp_ctx,
4471 const char *src_sname,
4472 const char *dst_sname)
4474 struct smb2_handle src_h = {{0}};
4475 struct smb2_handle dest_h = {{0}};
4478 struct srv_copychunk_copy cc_copy;
4479 struct srv_copychunk_rsp cc_rsp;
4480 enum ndr_err_code ndr_ret;
4483 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4486 &src_h, 256, /* fill 256 byte src file */
4487 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4489 &dest_h, 0, /* 0 byte dest file */
4490 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4493 torture_assert_goto(torture, ok == true, ok, done,
4494 "setup copy chunk error\n");
4496 /* copy all src file data (via a single chunk desc) */
4497 cc_copy.chunks[0].source_off = 0;
4498 cc_copy.chunks[0].target_off = 0;
4499 cc_copy.chunks[0].length = 256;
4501 ndr_ret = ndr_push_struct_blob(
4502 &io.smb2.in.out, tmp_ctx, &cc_copy,
4503 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4505 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4506 "ndr_push_srv_copychunk_copy\n");
4508 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4509 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4510 "FSCTL_SRV_COPYCHUNK\n");
4512 ndr_ret = ndr_pull_struct_blob(
4513 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4514 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4516 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4517 "ndr_pull_srv_copychunk_rsp\n");
4519 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4520 1, /* chunks written */
4521 0, /* chunk bytes unsuccessfully written */
4522 256); /* total bytes written */
4523 torture_assert_goto(torture, ok == true, ok, done,
4524 "bad copy chunk response data\n");
4526 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
4528 torture_fail(torture, "inconsistent file data\n");
4532 if (!smb2_util_handle_empty(src_h)) {
4533 smb2_util_close(tree, src_h);
4535 if (!smb2_util_handle_empty(dest_h)) {
4536 smb2_util_close(tree, dest_h);
4542 static bool copy_finderinfo_stream(struct torture_context *torture,
4543 struct smb2_tree *tree,
4544 TALLOC_CTX *tmp_ctx,
4545 const char *src_name,
4546 const char *dst_name)
4548 struct smb2_handle src_h = {{0}};
4549 struct smb2_handle dest_h = {{0}};
4552 struct srv_copychunk_copy cc_copy;
4553 struct srv_copychunk_rsp cc_rsp;
4554 enum ndr_err_code ndr_ret;
4555 const char *type_creator = "SMB,OLE!";
4556 AfpInfo *info = NULL;
4557 const char *src_name_afpinfo = NULL;
4558 const char *dst_name_afpinfo = NULL;
4561 src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
4563 torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
4564 "talloc_asprintf failed\n");
4566 dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
4568 torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
4569 "talloc_asprintf failed\n");
4571 info = torture_afpinfo_new(tmp_ctx);
4572 torture_assert_not_null_goto(torture, info, ok, done,
4573 "torture_afpinfo_new failed\n");
4575 memcpy(info->afpi_FinderInfo, type_creator, 8);
4576 ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
4577 torture_assert_goto(torture, ok == true, ok, done,
4578 "torture_write_afpinfo failed\n");
4580 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4584 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4587 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4590 torture_assert_goto(torture, ok == true, ok, done,
4591 "setup copy chunk error\n");
4593 /* copy all src file data (via a single chunk desc) */
4594 cc_copy.chunks[0].source_off = 0;
4595 cc_copy.chunks[0].target_off = 0;
4596 cc_copy.chunks[0].length = 60;
4598 ndr_ret = ndr_push_struct_blob(
4599 &io.smb2.in.out, tmp_ctx, &cc_copy,
4600 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4602 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4603 "ndr_push_srv_copychunk_copy\n");
4605 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4606 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4607 "FSCTL_SRV_COPYCHUNK\n");
4609 ndr_ret = ndr_pull_struct_blob(
4610 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4611 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4613 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4614 "ndr_pull_srv_copychunk_rsp\n");
4616 smb2_util_close(tree, src_h);
4618 smb2_util_close(tree, dest_h);
4619 ZERO_STRUCT(dest_h);
4621 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4622 1, /* chunks written */
4623 0, /* chunk bytes unsuccessfully written */
4624 60); /* total bytes written */
4625 torture_assert_goto(torture, ok == true, ok, done,
4626 "bad copy chunk response data\n");
4628 ok = check_stream(tree, __location__, torture, tmp_ctx,
4629 dst_name, AFPINFO_STREAM,
4630 0, 60, 16, 8, type_creator);
4631 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
4634 if (!smb2_util_handle_empty(src_h)) {
4635 smb2_util_close(tree, src_h);
4637 if (!smb2_util_handle_empty(dest_h)) {
4638 smb2_util_close(tree, dest_h);
4644 static bool test_copy_chunk_streams(struct torture_context *torture,
4645 struct smb2_tree *tree)
4647 const char *src_name = "src";
4648 const char *dst_name = "dst";
4650 const char *src_sname;
4651 const char *dst_sname;
4653 { "src:foo", "dst:foo" },
4654 { "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
4657 TALLOC_CTX *tmp_ctx = NULL;
4660 tmp_ctx = talloc_new(tree);
4661 torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
4662 "torture_setup_file\n");
4664 smb2_util_unlink(tree, src_name);
4665 smb2_util_unlink(tree, dst_name);
4667 ok = torture_setup_file(torture, tree, src_name, false);
4668 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4669 ok = torture_setup_file(torture, tree, dst_name, false);
4670 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4672 for (i = 0; i < ARRAY_SIZE(names); i++) {
4673 ok = copy_one_stream(torture, tree, tmp_ctx,
4675 names[i].dst_sname);
4676 torture_assert_goto(torture, ok == true, ok, done,
4677 "copy_one_stream failed\n");
4680 ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
4681 src_name, dst_name);
4682 torture_assert_goto(torture, ok == true, ok, done,
4683 "copy_finderinfo_stream failed\n");
4686 smb2_util_unlink(tree, src_name);
4687 smb2_util_unlink(tree, dst_name);
4688 talloc_free(tmp_ctx);
4693 * Ensure this security descriptor has exactly one mode, uid
4697 static NTSTATUS check_nfs_sd(const struct security_descriptor *psd)
4700 bool got_one_mode = false;
4701 bool got_one_uid = false;
4702 bool got_one_gid = false;
4704 if (psd->dacl == NULL) {
4705 return NT_STATUS_INVALID_SECURITY_DESCR;
4708 for (i = 0; i < psd->dacl->num_aces; i++) {
4709 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Mode,
4710 &psd->dacl->aces[i].trustee) == 0) {
4711 if (got_one_mode == true) {
4712 /* Can't have more than one. */
4713 return NT_STATUS_INVALID_SECURITY_DESCR;
4715 got_one_mode = true;
4718 for (i = 0; i < psd->dacl->num_aces; i++) {
4719 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Users,
4720 &psd->dacl->aces[i].trustee) == 0) {
4721 if (got_one_uid == true) {
4722 /* Can't have more than one. */
4723 return NT_STATUS_INVALID_SECURITY_DESCR;
4728 for (i = 0; i < psd->dacl->num_aces; i++) {
4729 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Groups,
4730 &psd->dacl->aces[i].trustee) == 0) {
4731 if (got_one_gid == true) {
4732 /* Can't have more than one. */
4733 return NT_STATUS_INVALID_SECURITY_DESCR;
4738 /* Must have at least one of each. */
4739 if (got_one_mode == false ||
4740 got_one_uid == false ||
4741 got_one_gid == false) {
4742 return NT_STATUS_INVALID_SECURITY_DESCR;
4744 return NT_STATUS_OK;
4747 static bool test_nfs_aces(struct torture_context *tctx,
4748 struct smb2_tree *tree)
4750 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4751 struct security_ace ace;
4753 const char *fname = BASEDIR "\\nfs_aces.txt";
4754 struct smb2_handle h = {{0}};
4755 union smb_fileinfo finfo2;
4756 union smb_setfileinfo set;
4757 struct security_descriptor *psd = NULL;
4760 bool is_osx = torture_setting_bool(tctx, "osx", false);
4763 torture_skip(tctx, "Test only works with Samba\n");
4766 ret = enable_aapl(tctx, tree);
4767 torture_assert(tctx, ret == true, "enable_aapl failed");
4769 /* clean slate ...*/
4770 smb2_util_unlink(tree, fname);
4771 smb2_deltree(tree, fname);
4772 smb2_deltree(tree, BASEDIR);
4774 status = torture_smb2_testdir(tree, BASEDIR, &h);
4775 CHECK_STATUS(status, NT_STATUS_OK);
4776 smb2_util_close(tree, h);
4778 /* Create a test file. */
4779 status = torture_smb2_testfile_access(tree,
4782 SEC_STD_READ_CONTROL |
4784 SEC_RIGHTS_FILE_ALL);
4785 CHECK_STATUS(status, NT_STATUS_OK);
4788 finfo2.query_secdesc.in.secinfo_flags =
4792 finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
4793 finfo2.generic.in.file.handle = h;
4794 status = smb2_getinfo_file(tree, tctx, &finfo2);
4795 CHECK_STATUS(status, NT_STATUS_OK);
4797 psd = finfo2.query_secdesc.out.sd;
4799 /* Ensure we have only single mode/uid/gid NFS entries. */
4800 status = check_nfs_sd(psd);
4801 if (!NT_STATUS_IS_OK(status)) {
4803 security_descriptor,
4804 discard_const_p(struct security_descriptor, psd));
4806 CHECK_STATUS(status, NT_STATUS_OK);
4808 /* Add a couple of extra NFS uids and gids. */
4809 sid_compose(&sid, &global_sid_Unix_NFS_Users, 27);
4810 init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
4811 status = security_descriptor_dacl_add(psd, &ace);
4812 CHECK_STATUS(status, NT_STATUS_OK);
4813 status = security_descriptor_dacl_add(psd, &ace);
4814 CHECK_STATUS(status, NT_STATUS_OK);
4816 sid_compose(&sid, &global_sid_Unix_NFS_Groups, 300);
4817 init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
4818 status = security_descriptor_dacl_add(psd, &ace);
4819 CHECK_STATUS(status, NT_STATUS_OK);
4820 status = security_descriptor_dacl_add(psd, &ace);
4821 CHECK_STATUS(status, NT_STATUS_OK);
4823 /* Now set on the file handle. */
4824 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
4825 set.set_secdesc.in.file.handle = h;
4826 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
4827 set.set_secdesc.in.sd = psd;
4828 status = smb2_setinfo_file(tree, &set);
4829 CHECK_STATUS(status, NT_STATUS_OK);
4831 /* Get the ACL again. */
4832 finfo2.query_secdesc.in.secinfo_flags =
4836 finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
4837 finfo2.generic.in.file.handle = h;
4838 status = smb2_getinfo_file(tree, tctx, &finfo2);
4839 CHECK_STATUS(status, NT_STATUS_OK);
4841 psd = finfo2.query_secdesc.out.sd;
4843 /* Ensure we have only single mode/uid/gid NFS entries. */
4844 status = check_nfs_sd(psd);
4845 if (!NT_STATUS_IS_OK(status)) {
4847 security_descriptor,
4848 discard_const_p(struct security_descriptor, psd));
4850 CHECK_STATUS(status, NT_STATUS_OK);
4853 if (!smb2_util_handle_empty(h)) {
4854 smb2_util_close(tree, h);
4856 smb2_util_unlink(tree, fname);
4857 smb2_deltree(tree, fname);
4858 smb2_deltree(tree, BASEDIR);
4859 talloc_free(mem_ctx);
4863 static bool test_setinfo_stream_eof(struct torture_context *tctx,
4864 struct smb2_tree *tree)
4868 struct smb2_create create;
4869 union smb_setfileinfo sfinfo;
4870 union smb_fileinfo finfo;
4871 struct smb2_handle h1;
4872 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4873 const char *fname = BASEDIR "\\file";
4874 const char *sname = BASEDIR "\\file:foo";
4876 torture_assert_goto(tctx, mem_ctx != NULL, ret, done,
4877 "talloc_new failed\n");
4879 torture_comment(tctx, "Test setting EOF on a stream\n");
4881 smb2_deltree(tree, BASEDIR);
4882 status = torture_smb2_testdir(tree, BASEDIR, &h1);
4883 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4884 "torture_smb2_testdir\n");
4885 smb2_util_close(tree, h1);
4887 status = torture_smb2_testfile(tree, fname, &h1);
4888 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4889 "torture_smb2_testfile failed\n");
4890 smb2_util_close(tree, h1);
4892 status = torture_smb2_testfile_access(tree, sname, &h1,
4893 SEC_FILE_WRITE_DATA);
4894 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4895 "torture_smb2_testfile failed\n");
4897 status = smb2_util_write(tree, h1, "1234567890", 0, 10);
4898 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4899 "smb2_util_write failed\n");
4900 smb2_util_close(tree, h1);
4903 * Test setting EOF to 21
4906 torture_comment(tctx, "Setting stream EOF to 21\n");
4908 status = torture_smb2_testfile_access(tree, sname, &h1,
4909 SEC_FILE_WRITE_DATA);
4910 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4911 "torture_smb2_testfile failed\n");
4913 ZERO_STRUCT(sfinfo);
4914 sfinfo.generic.in.file.handle = h1;
4915 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4916 sfinfo.position_information.in.position = 21;
4917 status = smb2_setinfo_file(tree, &sfinfo);
4918 torture_assert_ntstatus_ok_goto(tctx, status,
4919 ret, done, "set EOF 21 failed\n");
4921 smb2_util_close(tree, h1);
4923 status = torture_smb2_testfile_access(tree, sname, &h1,
4924 SEC_FILE_WRITE_DATA);
4925 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4926 "torture_smb2_testfile failed\n");
4929 finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
4930 finfo.generic.in.file.handle = h1;
4931 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
4932 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4933 "smb2_getinfo_file failed");
4935 smb2_util_close(tree, h1);
4937 torture_assert_goto(tctx, finfo.standard_info.out.size == 21,
4938 ret, done, "size != 21\n");
4941 * Test setting EOF to 0
4944 torture_comment(tctx, "Setting stream EOF to 0\n");
4946 status = torture_smb2_testfile_access(tree, sname, &h1,
4947 SEC_FILE_WRITE_DATA);
4948 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4949 "torture_smb2_testfile failed\n");
4951 ZERO_STRUCT(sfinfo);
4952 sfinfo.generic.in.file.handle = h1;
4953 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4954 sfinfo.position_information.in.position = 0;
4955 status = smb2_setinfo_file(tree, &sfinfo);
4956 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4957 "set eof 0 failed\n");
4959 smb2_util_close(tree, h1);
4961 status = torture_smb2_testfile_access(tree, sname, &h1,
4962 SEC_FILE_WRITE_DATA);
4963 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4964 "torture_smb2_testfile failed\n");
4967 finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
4968 finfo.generic.in.file.handle = h1;
4969 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
4970 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4971 "smb2_getinfo_file failed\n");
4973 smb2_util_close(tree, h1);
4975 torture_assert_goto(tctx, finfo.standard_info.out.size == 0,
4976 ret, done, "size != 0\n");
4979 * Test setinfo end-of-file info to 1
4982 torture_comment(tctx, "Setting stream EOF to 1\n");
4984 status = torture_smb2_testfile_access(tree, sname, &h1,
4985 SEC_FILE_WRITE_DATA);
4986 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4987 "torture_smb2_testfile failed\n");
4989 ZERO_STRUCT(sfinfo);
4990 sfinfo.generic.in.file.handle = h1;
4991 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4992 sfinfo.position_information.in.position = 1;
4993 status = smb2_setinfo_file(tree, &sfinfo);
4994 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4995 "set EOF 1 failed\n");
4997 smb2_util_close(tree, h1);
4999 status = torture_smb2_testfile_access(tree, sname, &h1,
5000 SEC_FILE_WRITE_DATA);
5001 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5002 "torture_smb2_testfile failed\n");
5005 finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
5006 finfo.generic.in.file.handle = h1;
5007 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
5008 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5009 "smb2_getinfo_file failed\n");
5011 smb2_util_close(tree, h1);
5013 torture_assert_goto(tctx, finfo.standard_info.out.size == 1,
5014 ret, done, "size != 1\n");
5017 * Test setting EOF to 0 with AAPL enabled, should delete stream
5020 torture_comment(tctx, "Enabling AAPL extensions\n");
5022 ret = enable_aapl(tctx, tree);
5023 torture_assert(tctx, ret == true, "enable_aapl failed\n");
5025 torture_comment(tctx, "Setting stream EOF to 0\n");
5026 status = torture_smb2_testfile_access(tree, sname, &h1,
5027 SEC_FILE_WRITE_DATA);
5028 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5029 "torture_smb2_testfile failed\n");
5031 ZERO_STRUCT(sfinfo);
5032 sfinfo.generic.in.file.handle = h1;
5033 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5034 sfinfo.position_information.in.position = 0;
5035 status = smb2_setinfo_file(tree, &sfinfo);
5036 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5037 "set eof 0 failed\n");
5039 smb2_util_close(tree, h1);
5041 ZERO_STRUCT(create);
5042 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5043 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5044 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5045 create.in.create_disposition = NTCREATEX_DISP_OPEN;
5046 create.in.fname = sname;
5048 status = smb2_create(tree, tctx, &create);
5049 torture_assert_ntstatus_equal_goto(
5050 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
5051 "Unexpected status\n");
5054 tctx, "Setting main file EOF to 1 to force 0-truncate\n");
5056 status = torture_smb2_testfile_access(
5060 SEC_FILE_WRITE_DATA);
5061 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5062 "torture_smb2_testfile failed\n");
5064 ZERO_STRUCT(sfinfo);
5065 sfinfo.generic.in.file.handle = h1;
5066 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5067 sfinfo.position_information.in.position = 1;
5068 status = smb2_setinfo_file(tree, &sfinfo);
5069 torture_assert_ntstatus_ok_goto(
5074 "set eof 1 failed\n");
5076 sfinfo.position_information.in.position = 0;
5077 status = smb2_setinfo_file(tree, &sfinfo);
5078 torture_assert_ntstatus_ok_goto(
5083 "set eof 0 failed\n");
5085 smb2_util_close(tree, h1);
5087 ZERO_STRUCT(create);
5088 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5089 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5090 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5091 create.in.create_disposition = NTCREATEX_DISP_OPEN;
5092 create.in.fname = fname;
5094 status = smb2_create(tree, tctx, &create);
5095 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5096 "torture_smb2_testfile failed\n");
5097 smb2_util_close(tree, h1);
5099 smb2_util_unlink(tree, fname);
5100 smb2_util_rmdir(tree, BASEDIR);
5105 * Note: This test depends on "vfs objects = catia fruit streams_xattr". For
5106 * some tests torture must be run on the host it tests and takes an additional
5107 * argument with the local path to the share:
5108 * "--option=torture:localdir=<SHAREPATH>".
5110 * When running against an OS X SMB server add "--option=torture:osx=true"
5112 struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
5114 struct torture_suite *suite = torture_suite_create(
5117 suite->description = talloc_strdup(suite, "vfs_fruit tests");
5119 torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
5120 torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
5121 torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
5122 torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
5123 torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
5124 torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
5125 torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
5126 torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
5127 torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
5128 torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
5129 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
5130 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
5131 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
5132 torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
5133 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
5134 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
5135 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
5136 torture_suite_add_1smb2_test(suite, "setinfo eof stream", test_setinfo_stream_eof);
5137 torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
5138 torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
5139 torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
5140 torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
5141 torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
5142 torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
5143 torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
5144 torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
5145 torture_suite_add_1smb2_test(suite, "NFS ACE entries", test_nfs_aces);
5146 torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion without embedded xattr", test_adouble_conversion_wo_xattr);
5151 static bool test_stream_names_local(struct torture_context *tctx,
5152 struct smb2_tree *tree)
5154 TALLOC_CTX *mem_ctx = talloc_new(tctx);
5156 struct smb2_create create;
5157 struct smb2_handle h;
5158 const char *fname = BASEDIR "\\stream_names.txt";
5161 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
5162 const char *streams[] = {
5163 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
5164 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
5167 const char *localdir = NULL;
5169 localdir = torture_setting_string(tctx, "localdir", NULL);
5170 if (localdir == NULL) {
5171 torture_skip(tctx, "Need localdir for test");
5174 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
5176 /* clean slate ...*/
5177 smb2_util_unlink(tree, fname);
5178 smb2_deltree(tree, fname);
5179 smb2_deltree(tree, BASEDIR);
5181 status = torture_smb2_testdir(tree, BASEDIR, &h);
5182 CHECK_STATUS(status, NT_STATUS_OK);
5183 smb2_util_close(tree, h);
5185 torture_comment(tctx, "(%s) testing stream names\n", __location__);
5186 ZERO_STRUCT(create);
5187 create.in.desired_access = SEC_FILE_WRITE_DATA;
5188 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5189 create.in.share_access =
5190 NTCREATEX_SHARE_ACCESS_DELETE|
5191 NTCREATEX_SHARE_ACCESS_READ|
5192 NTCREATEX_SHARE_ACCESS_WRITE;
5193 create.in.create_disposition = NTCREATEX_DISP_CREATE;
5194 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
5195 create.in.fname = sname1;
5197 status = smb2_create(tree, mem_ctx, &create);
5198 CHECK_STATUS(status, NT_STATUS_OK);
5199 smb2_util_close(tree, create.out.file.handle);
5201 ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
5202 "user.DosStream.bar:baz:$DATA",
5203 "data", strlen("data"));
5204 CHECK_VALUE(ret, true);
5206 ret = check_stream_list(tree, tctx, fname, 3, streams, false);
5207 CHECK_VALUE(ret, true);
5210 status = smb2_util_unlink(tree, fname);
5211 smb2_deltree(tree, BASEDIR);
5212 talloc_free(mem_ctx);
5217 static bool test_fruit_locking_conflict(struct torture_context *tctx,
5218 struct smb2_tree *tree)
5220 TALLOC_CTX *mem_ctx;
5221 struct smb2_create create;
5222 struct smb2_handle h;
5223 struct smb2_lock lck;
5224 struct smb2_lock_element el;
5225 const char *fname = BASEDIR "\\locking_conflict.txt";
5229 mem_ctx = talloc_new(tctx);
5230 torture_assert_not_null(tctx, mem_ctx, "talloc_new failed");
5232 /* clean slate ...*/
5233 smb2_util_unlink(tree, fname);
5234 smb2_deltree(tree, fname);
5235 smb2_deltree(tree, BASEDIR);
5237 status = torture_smb2_testdir(tree, BASEDIR, &h);
5238 CHECK_STATUS(status, NT_STATUS_OK);
5239 smb2_util_close(tree, h);
5241 create = (struct smb2_create) {
5242 .in.desired_access = SEC_RIGHTS_FILE_READ,
5243 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5245 NTCREATEX_SHARE_ACCESS_READ|
5246 NTCREATEX_SHARE_ACCESS_WRITE,
5247 .in.create_disposition = NTCREATEX_DISP_CREATE,
5248 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5252 status = smb2_create(tree, mem_ctx, &create);
5253 CHECK_STATUS(status, NT_STATUS_OK);
5254 h = create.out.file.handle;
5256 el = (struct smb2_lock_element) {
5257 .offset = 0xfffffffffffffffc,
5259 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
5261 lck = (struct smb2_lock) {
5263 .in.file.handle = h,
5267 status = smb2_lock(tree, &lck);
5268 CHECK_STATUS(status, NT_STATUS_OK);
5270 el = (struct smb2_lock_element) {
5272 .length = 0x7fffffffffffffff,
5273 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
5275 status = smb2_lock(tree, &lck);
5276 CHECK_STATUS(status, NT_STATUS_OK);
5278 create = (struct smb2_create) {
5279 .in.desired_access =
5280 SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
5281 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5282 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5283 .in.create_disposition = NTCREATEX_DISP_OPEN,
5284 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5288 status = smb2_create(tree, mem_ctx, &create);
5289 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
5292 struct smb2_close cl = {
5293 .level = RAW_CLOSE_SMB2,
5294 .in.file.handle = h,
5296 smb2_close(tree, &cl);
5304 struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
5306 struct torture_suite *suite = torture_suite_create(
5307 ctx, "fruit_netatalk");
5309 suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
5311 torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
5312 torture_suite_add_1smb2_test(suite, "stream names with locally created xattr", test_stream_names_local);
5313 torture_suite_add_1smb2_test(
5314 suite, "locking conflict", test_fruit_locking_conflict);
5319 struct torture_suite *torture_vfs_fruit_file_id(TALLOC_CTX *ctx)
5321 struct torture_suite *suite =
5322 torture_suite_create(ctx, "fruit_file_id");
5324 suite->description =
5325 talloc_strdup(suite, "vfs_fruit tests for on-disk file ID that "
5326 "require fruit:zero_file_id=yes");
5328 torture_suite_add_1smb2_test(suite, "zero file id if AAPL negotiated",
5334 static bool test_timemachine_volsize(struct torture_context *tctx,
5335 struct smb2_tree *tree)
5337 TALLOC_CTX *mem_ctx = talloc_new(tctx);
5338 struct smb2_handle h = {{0}};
5339 union smb_fsinfo fsinfo;
5342 const char *info_plist =
5344 " <key>band-size</key>\n"
5345 " <integer>8192</integer>\n"
5348 smb2_deltree(tree, "test.sparsebundle");
5350 ok = enable_aapl(tctx, tree);
5351 torture_assert_goto(tctx, ok, ok, done, "enable_aapl failed");
5353 status = smb2_util_mkdir(tree, "test.sparsebundle");
5354 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
5355 "smb2_util_mkdir\n");
5357 ok = write_stream(tree, __location__, tctx, mem_ctx,
5358 "test.sparsebundle/Info.plist", NULL,
5359 0, strlen(info_plist), info_plist);
5360 torture_assert_goto(tctx, ok, ok, done, "write_stream failed\n");
5362 status = smb2_util_mkdir(tree, "test.sparsebundle/bands");
5363 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
5364 "smb2_util_mkdir\n");
5366 ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/1", false);
5367 torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
5369 ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/2", false);
5370 torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
5372 status = smb2_util_roothandle(tree, &h);
5373 torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
5375 ZERO_STRUCT(fsinfo);
5376 fsinfo.generic.level = RAW_QFS_SIZE_INFORMATION;
5377 fsinfo.generic.handle = h;
5379 status = smb2_getinfo_fs(tree, tree, &fsinfo);
5380 torture_assert_ntstatus_ok(tctx, status, "smb2_getinfo_fs failed");
5382 torture_comment(tctx, "sectors_per_unit: %" PRIu32"\n"
5383 "bytes_per_sector: %" PRIu32"\n"
5384 "total_alloc_units: %" PRIu64"\n"
5385 "avail_alloc_units: %" PRIu64"\n",
5386 fsinfo.size_info.out.sectors_per_unit,
5387 fsinfo.size_info.out.bytes_per_sector,
5388 fsinfo.size_info.out.total_alloc_units,
5389 fsinfo.size_info.out.avail_alloc_units);
5392 * Let me explain the numbers:
5394 * - the share is set to "fruit:time machine max size = 32K"
5395 * - we've faked a bandsize of 8 K in the Info.plist file
5396 * - we've created two bands files
5397 * - one allocation unit is made of two sectors with 512 B each
5398 * => we've consumed 16 allocation units, there should be 16 free
5401 torture_assert_goto(tctx, fsinfo.size_info.out.sectors_per_unit == 2,
5402 ok, done, "Bad sectors_per_unit");
5404 torture_assert_goto(tctx, fsinfo.size_info.out.bytes_per_sector == 512,
5405 ok, done, "Bad bytes_per_sector");
5407 torture_assert_goto(tctx, fsinfo.size_info.out.total_alloc_units == 32,
5408 ok, done, "Bad total_alloc_units");
5410 torture_assert_goto(tctx, fsinfo.size_info.out.avail_alloc_units == 16,
5411 ok, done, "Bad avail_alloc_units");
5414 if (!smb2_util_handle_empty(h)) {
5415 smb2_util_close(tree, h);
5417 smb2_deltree(tree, "test.sparsebundle");
5418 talloc_free(mem_ctx);
5422 struct torture_suite *torture_vfs_fruit_timemachine(TALLOC_CTX *ctx)
5424 struct torture_suite *suite = torture_suite_create(
5425 ctx, "fruit_timemachine");
5427 suite->description = talloc_strdup(
5428 suite, "vfs_fruit tests for TimeMachine");
5430 torture_suite_add_1smb2_test(suite, "Timemachine-volsize",
5431 test_timemachine_volsize);
5436 static bool test_convert_xattr_and_empty_rfork_then_delete(
5437 struct torture_context *tctx,
5438 struct smb2_tree *tree1,
5439 struct smb2_tree *tree2)
5441 TALLOC_CTX *mem_ctx = talloc_new(tctx);
5442 const char *fname = BASEDIR "\\test_adouble_conversion";
5443 const char *adname = BASEDIR "/._test_adouble_conversion";
5444 const char *rfork = BASEDIR "\\test_adouble_conversion" AFPRESOURCE_STREAM_NAME;
5446 struct smb2_handle testdirh;
5448 const char *streams[] = {
5451 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
5452 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
5454 struct smb2_create create;
5455 struct smb2_find find;
5457 union smb_search_data *d;
5458 bool delete_empty_adfiles;
5459 int expected_num_files;
5461 delete_empty_adfiles = torture_setting_bool(tctx,
5462 "delete_empty_adfiles",
5465 smb2_deltree(tree1, BASEDIR);
5467 status = torture_smb2_testdir(tree1, BASEDIR, &testdirh);
5468 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5469 "torture_smb2_testdir failed\n");
5470 smb2_util_close(tree1, testdirh);
5472 ret = torture_setup_file(tctx, tree1, fname, false);
5473 torture_assert_goto(tctx, ret == true, ret, done,
5474 "torture_setup_file failed\n");
5476 ret = torture_setup_file(tctx, tree1, adname, false);
5477 torture_assert_goto(tctx, ret == true, ret, done,
5478 "torture_setup_file failed\n");
5480 ret = write_stream(tree1, __location__, tctx, mem_ctx,
5482 0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
5483 torture_assert_goto(tctx, ret == true, ret, done,
5484 "write_stream failed\n");
5486 ret = enable_aapl(tctx, tree2);
5487 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
5490 * Issue a smb2_find(), this triggers the server-side conversion
5493 create = (struct smb2_create) {
5494 .in.desired_access = SEC_RIGHTS_DIR_READ,
5495 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
5496 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
5497 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5498 .in.create_disposition = NTCREATEX_DISP_OPEN,
5499 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5500 .in.fname = BASEDIR,
5503 status = smb2_create(tree2, tctx, &create);
5504 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5505 "smb2_create failed\n");
5507 find = (struct smb2_find) {
5508 .in.file.handle = create.out.file.handle,
5510 .in.max_response_size = 0x1000,
5511 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
5514 status = smb2_find_level(tree2, tree2, &find, &count, &d);
5515 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5516 "smb2_find_level failed\n");
5518 status = smb2_util_close(tree2, create.out.file.handle);
5519 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5520 "smb2_util_close failed");
5523 * Check number of streams
5526 ret = check_stream_list(tree2, tctx, fname, 4, streams, false);
5527 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
5530 * Check Resource Fork is gone
5533 create = (struct smb2_create) {
5534 .in.desired_access = SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
5535 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5536 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5537 .in.create_disposition = NTCREATEX_DISP_OPEN,
5538 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5542 status = smb2_create(tree2, mem_ctx, &create);
5543 torture_assert_ntstatus_equal_goto(
5544 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
5545 ret, done, "Bad smb2_create return\n");
5548 * Check xattr data has been migrated from the AppleDouble file to
5552 ret = check_stream(tree2, __location__, tctx, mem_ctx,
5553 fname, AFPINFO_STREAM,
5554 0, 60, 16, 8, "TESTSLOW");
5555 torture_assert_goto(tctx, ret == true, ret, done,
5556 "check AFPINFO_STREAM failed\n");
5558 ret = check_stream(tree2, __location__, tctx, mem_ctx,
5559 fname, ":foo" "\xef\x80\xa2" "bar", /* foo:bar */
5561 torture_assert_goto(tctx, ret == true, ret, done,
5562 "check foo stream failed\n");
5565 * Now check number of files. If delete_empty_adfiles is set, the
5566 * AppleDouble files should have been deleted.
5569 create = (struct smb2_create) {
5570 .in.desired_access = SEC_RIGHTS_DIR_READ,
5571 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
5572 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
5573 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5574 .in.create_disposition = NTCREATEX_DISP_OPEN,
5575 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5576 .in.fname = BASEDIR,
5579 status = smb2_create(tree2, tctx, &create);
5580 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5581 "smb2_create failed\n");
5583 find = (struct smb2_find) {
5584 .in.file.handle = create.out.file.handle,
5586 .in.max_response_size = 0x1000,
5587 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
5590 status = smb2_find_level(tree2, tree2, &find, &count, &d);
5591 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5592 "smb2_find_level failed\n");
5594 status = smb2_util_close(tree2, create.out.file.handle);
5595 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5596 "smb2_util_close failed");
5598 if (delete_empty_adfiles) {
5599 expected_num_files = 3;
5601 expected_num_files = 4;
5603 torture_assert_int_equal_goto(tctx, count, expected_num_files, ret, done,
5604 "Wrong number of files\n");
5607 smb2_deltree(tree1, BASEDIR);
5608 talloc_free(mem_ctx);
5612 struct torture_suite *torture_vfs_fruit_conversion(TALLOC_CTX *ctx)
5614 struct torture_suite *suite = torture_suite_create(
5615 ctx, "fruit_conversion");
5617 suite->description = talloc_strdup(
5618 suite, "vfs_fruit conversion tests");
5620 torture_suite_add_2ns_smb2_test(
5621 suite, "convert_xattr_and_empty_rfork_then_delete",
5622 test_convert_xattr_and_empty_rfork_then_delete);