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 work\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_ok_goto(tctx, status, ret, done,
2059 "smb2_create failed\n");
2061 smb2_util_close(tree, create.out.file.handle);
2064 smb2_util_unlink(tree, fname);
2065 smb2_deltree(tree, BASEDIR);
2066 talloc_free(mem_ctx);
2070 static bool test_adouble_conversion(struct torture_context *tctx,
2071 struct smb2_tree *tree)
2073 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2074 const char *fname = BASEDIR "\\test_adouble_conversion";
2075 const char *adname = BASEDIR "/._test_adouble_conversion";
2077 struct smb2_handle testdirh;
2079 const char *data = "This resource fork intentionally left blank";
2080 size_t datalen = strlen(data);
2081 const char *streams[] = {
2085 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
2086 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2088 bool is_osx = torture_setting_bool(tctx, "osx", false);
2091 torture_skip(tctx, "Test only works with Samba\n");
2094 smb2_deltree(tree, BASEDIR);
2096 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2097 CHECK_STATUS(status, NT_STATUS_OK);
2098 smb2_util_close(tree, testdirh);
2100 ret = torture_setup_file(tctx, tree, fname, false);
2101 torture_assert_goto(tctx, ret == true, ret, done,
2102 "torture_setup_file failed\n");
2104 ret = torture_setup_file(tctx, tree, adname, false);
2105 torture_assert_goto(tctx, ret == true, ret, done,
2106 "torture_setup_file failed\n");
2108 ret = write_stream(tree, __location__, tctx, mem_ctx,
2110 0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
2111 torture_assert_goto(tctx, ret == true, ret, done,
2112 "write_stream failed\n");
2114 torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
2117 ret = check_stream(tree, __location__, tctx, mem_ctx,
2118 fname, AFPRESOURCE_STREAM,
2119 16, datalen, 0, datalen, data);
2120 torture_assert_goto(tctx, ret == true, ret, done,
2121 "check AFPRESOURCE_STREAM failed\n");
2123 ret = check_stream(tree, __location__, tctx, mem_ctx,
2124 fname, AFPINFO_STREAM,
2125 0, 60, 16, 8, "TESTSLOW");
2126 torture_assert_goto(tctx, ret == true, ret, done,
2127 "check AFPINFO_STREAM failed\n");
2129 ret = check_stream(tree, __location__, tctx, mem_ctx, fname,
2130 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2132 torture_assert_goto(tctx, ret == true, ret, done,
2133 "check foo:bar stream failed\n");
2135 ret = check_stream_list(tree, tctx, fname, 5, streams, false);
2136 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2139 smb2_deltree(tree, BASEDIR);
2140 talloc_free(mem_ctx);
2145 * Test conversion of AppleDouble file without embedded xattr data
2147 static bool test_adouble_conversion_wo_xattr(struct torture_context *tctx,
2148 struct smb2_tree *tree)
2150 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2151 const char *fname = BASEDIR "\\test_adouble_conversion";
2152 const char *adname = BASEDIR "/._test_adouble_conversion";
2154 struct smb2_handle testdirh;
2156 const char *streams[] = {
2161 struct smb2_create create;
2162 struct smb2_find find;
2164 union smb_search_data *d;
2165 const char *data = "This resource fork intentionally left blank";
2166 size_t datalen = strlen(data);
2167 bool is_osx = torture_setting_bool(tctx, "osx", false);
2170 torture_skip(tctx, "Test only works with Samba\n");
2173 smb2_deltree(tree, BASEDIR);
2175 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2176 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2177 "torture_smb2_testdir failed\n");
2178 smb2_util_close(tree, testdirh);
2180 ret = torture_setup_file(tctx, tree, fname, false);
2181 torture_assert_goto(tctx, ret == true, ret, done,
2182 "torture_setup_file failed\n");
2184 ret = torture_setup_file(tctx, tree, adname, false);
2185 torture_assert_goto(tctx, ret == true, ret, done,
2186 "torture_setup_file failed\n");
2188 ret = write_stream(tree, __location__, tctx, mem_ctx,
2190 sizeof(osx_adouble_without_xattr),
2191 osx_adouble_without_xattr);
2192 torture_assert_goto(tctx, ret == true, ret, done,
2193 "write_stream failed\n");
2195 ret = enable_aapl(tctx, tree);
2196 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
2199 * Issue a smb2_find(), this triggers the server-side conversion
2202 create = (struct smb2_create) {
2203 .in.desired_access = SEC_RIGHTS_DIR_READ,
2204 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
2205 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
2206 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
2207 .in.create_disposition = NTCREATEX_DISP_OPEN,
2208 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
2209 .in.fname = BASEDIR,
2212 status = smb2_create(tree, tctx, &create);
2213 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2214 "smb2_create failed\n");
2216 find = (struct smb2_find) {
2217 .in.file.handle = create.out.file.handle,
2219 .in.max_response_size = 0x1000,
2220 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
2223 status = smb2_find_level(tree, tree, &find, &count, &d);
2224 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2225 "smb2_find_level failed\n");
2227 status = smb2_util_close(tree, create.out.file.handle);
2228 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2229 "smb2_util_close failed");
2232 * Check number of streams
2235 ret = check_stream_list(tree, tctx, fname, 3, streams, false);
2236 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2240 * Check Resourcefork data can be read.
2243 ret = check_stream(tree, __location__, tctx, mem_ctx,
2244 fname, AFPRESOURCE_STREAM,
2245 16, datalen, 0, datalen, data);
2246 torture_assert_goto(tctx, ret == true, ret, done,
2247 "check AFPRESOURCE_STREAM failed\n");
2250 * Check FinderInfo data has been migrated to stream.
2253 ret = check_stream(tree, __location__, tctx, mem_ctx,
2254 fname, AFPINFO_STREAM,
2255 0, 60, 16, 8, "WAVEPTul");
2256 torture_assert_goto(tctx, ret == true, ret, done,
2257 "check AFPINFO_STREAM failed\n");
2260 smb2_deltree(tree, BASEDIR);
2261 talloc_free(mem_ctx);
2265 static bool test_aapl(struct torture_context *tctx,
2266 struct smb2_tree *tree)
2268 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2269 const char *fname = BASEDIR "\\test_aapl";
2271 struct smb2_handle testdirh;
2273 struct smb2_create io;
2275 struct smb2_create_blob *aapl = NULL;
2277 const char *type_creator = "SMB,OLE!";
2278 char type_creator_buf[9];
2280 uint32_t aapl_reply_bitmap;
2281 uint32_t aapl_server_caps;
2282 uint32_t aapl_vol_caps;
2283 uint32_t expected_vol_caps = 0;
2287 union smb_search_data *d;
2289 bool is_osx_server = torture_setting_bool(tctx, "osx", false);
2291 smb2_deltree(tree, BASEDIR);
2293 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2294 CHECK_STATUS(status, NT_STATUS_OK);
2295 smb2_util_close(tree, testdirh);
2298 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2299 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2300 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2301 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2302 NTCREATEX_SHARE_ACCESS_READ |
2303 NTCREATEX_SHARE_ACCESS_WRITE);
2304 io.in.fname = fname;
2307 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
2308 * controls behaviour of Apple's SMB2 extensions for the whole
2312 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2313 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2314 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2315 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2316 SMB2_CRTCTX_AAPL_MODEL_INFO));
2317 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2318 SMB2_CRTCTX_AAPL_UNIX_BASED |
2319 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
2321 torture_comment(tctx, "Testing SMB2 create context AAPL\n");
2322 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2323 CHECK_STATUS(status, NT_STATUS_OK);
2325 status = smb2_create(tree, tctx, &io);
2326 CHECK_STATUS(status, NT_STATUS_OK);
2327 status = smb2_util_close(tree, io.out.file.handle);
2328 CHECK_STATUS(status, NT_STATUS_OK);
2331 * Now check returned AAPL context
2333 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
2335 aapl = smb2_create_blob_find(&io.out.blobs,
2336 SMB2_CREATE_TAG_AAPL);
2339 torture_result(tctx, TORTURE_FAIL,
2340 "(%s) unexpectedly no AAPL capabilities were returned.",
2346 if (!is_osx_server) {
2347 size_t expected_aapl_ctx_size;
2351 * uint32_t CommandCode = kAAPL_SERVER_QUERY
2352 * uint32_t Reserved = 0;
2353 * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
2354 * kAAPL_VOLUME_CAPS |
2356 * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
2357 * kAAPL_SUPPORTS_OSX_COPYFILE;
2358 * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
2359 * kAAPL_CASE_SENSITIVE;
2360 * uint32_t Pad2 = 0;
2361 * uint32_t ModelStringLen = 10;
2362 * ucs2_t ModelString[5] = "MacSamba";
2364 expected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
2366 size_ok = aapl->data.length == expected_aapl_ctx_size;
2367 torture_assert_goto(tctx, size_ok, ret, done, "bad AAPL size");
2370 aapl_cmd = IVAL(aapl->data.data, 0);
2371 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2372 torture_result(tctx, TORTURE_FAIL,
2373 "(%s) unexpected cmd: %d",
2374 __location__, (int)aapl_cmd);
2379 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2380 if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2381 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2382 SMB2_CRTCTX_AAPL_MODEL_INFO)) {
2383 torture_result(tctx, TORTURE_FAIL,
2384 "(%s) unexpected reply_bitmap: %d",
2385 __location__, (int)aapl_reply_bitmap);
2390 aapl_server_caps = BVAL(aapl->data.data, 16);
2391 if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
2392 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2393 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
2394 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
2395 torture_result(tctx, TORTURE_FAIL,
2396 "(%s) unexpected server_caps: %d",
2397 __location__, (int)aapl_server_caps);
2402 if (is_osx_server) {
2403 expected_vol_caps = 5;
2405 aapl_vol_caps = BVAL(aapl->data.data, 24);
2406 if (aapl_vol_caps != expected_vol_caps) {
2407 /* this will fail on a case insensitive fs ... */
2408 torture_result(tctx, TORTURE_FAIL,
2409 "(%s) unexpected vol_caps: %d",
2410 __location__, (int)aapl_vol_caps);
2413 ret = convert_string_talloc(mem_ctx,
2414 CH_UTF16LE, CH_UNIX,
2415 aapl->data.data + 40, 10,
2418 torture_result(tctx, TORTURE_FAIL,
2419 "(%s) convert_string_talloc() failed",
2423 torture_comment(tctx, "Got server model: \"%s\"\n", model);
2426 * Now that Requested AAPL extensions are enabled, setup some
2427 * Mac files with metadata and resource fork
2429 ret = torture_setup_file(mem_ctx, tree, fname, false);
2431 torture_result(tctx, TORTURE_FAIL,
2432 "(%s) torture_setup_file() failed",
2437 info = torture_afpinfo_new(mem_ctx);
2439 torture_result(tctx, TORTURE_FAIL,
2440 "(%s) torture_afpinfo_new() failed",
2446 memcpy(info->afpi_FinderInfo, type_creator, 8);
2447 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2449 torture_result(tctx, TORTURE_FAIL,
2450 "(%s) torture_write_afpinfo() failed",
2455 ret = write_stream(tree, __location__, tctx, mem_ctx,
2456 fname, AFPRESOURCE_STREAM_NAME,
2459 torture_result(tctx, TORTURE_FAIL,
2460 "(%s) write_stream() failed",
2466 * Ok, file is prepared, now call smb2/find
2470 io.in.desired_access = SEC_RIGHTS_DIR_READ;
2471 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2472 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2473 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
2474 NTCREATEX_SHARE_ACCESS_WRITE |
2475 NTCREATEX_SHARE_ACCESS_DELETE);
2476 io.in.create_disposition = NTCREATEX_DISP_OPEN;
2477 io.in.fname = BASEDIR;
2478 status = smb2_create(tree, tctx, &io);
2479 CHECK_STATUS(status, NT_STATUS_OK);
2482 f.in.file.handle = io.out.file.handle;
2483 f.in.pattern = "test_aapl";
2484 f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
2485 f.in.max_response_size = 0x1000;
2486 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
2488 status = smb2_find_level(tree, tree, &f, &count, &d);
2489 CHECK_STATUS(status, NT_STATUS_OK);
2491 status = smb2_util_close(tree, io.out.file.handle);
2492 CHECK_STATUS(status, NT_STATUS_OK);
2494 if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2495 torture_result(tctx, TORTURE_FAIL,
2496 "(%s) write_stream() failed",
2502 if (d[0].id_both_directory_info.short_name.private_length != 24) {
2503 torture_result(tctx, TORTURE_FAIL,
2504 "(%s) bad short_name length %" PRIu32 ", expected 24",
2505 __location__, d[0].id_both_directory_info.short_name.private_length);
2510 torture_comment(tctx, "short_name buffer:\n");
2511 dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2514 * Extract data as specified by the AAPL extension:
2515 * - ea_size contains max_access
2516 * - short_name contains resource fork length + FinderInfo
2517 * - reserved2 contains the unix mode
2519 torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2520 d[0].id_both_directory_info.ea_size);
2522 rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2523 if (rfork_len != 3) {
2524 torture_result(tctx, TORTURE_FAIL,
2525 "(%s) expected resource fork length 3, got: %" PRIu64,
2526 __location__, rfork_len);
2531 memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2532 type_creator_buf[8] = 0;
2533 if (strcmp(type_creator, type_creator_buf) != 0) {
2534 torture_result(tctx, TORTURE_FAIL,
2535 "(%s) expected type/creator \"%s\" , got: %s",
2536 __location__, type_creator, type_creator_buf);
2542 smb2_util_unlink(tree, fname);
2543 smb2_deltree(tree, BASEDIR);
2544 talloc_free(mem_ctx);
2548 static uint64_t patt_hash(uint64_t off)
2553 static bool write_pattern(struct torture_context *torture,
2554 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2555 struct smb2_handle h, uint64_t off, uint64_t len,
2561 uint64_t io_sz = MIN(1024 * 64, len);
2567 torture_assert(torture, (len % 8) == 0, "invalid write len");
2569 buf = talloc_zero_size(mem_ctx, io_sz);
2570 torture_assert(torture, (buf != NULL), "no memory for file data buf");
2573 for (i = 0; i <= io_sz - 8; i += 8) {
2574 SBVAL(buf, i, patt_hash(patt_off));
2578 status = smb2_util_write(tree, h,
2580 torture_assert_ntstatus_ok(torture, status, "file write");
2591 static bool check_pattern(struct torture_context *torture,
2592 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2593 struct smb2_handle h, uint64_t off, uint64_t len,
2600 torture_assert(torture, (len % 8) == 0, "invalid read len");
2606 uint64_t io_sz = MIN(1024 * 64, len);
2609 r.in.file.handle = h;
2610 r.in.length = io_sz;
2612 status = smb2_read(tree, mem_ctx, &r);
2613 torture_assert_ntstatus_ok(torture, status, "read");
2615 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2616 "read data len mismatch");
2618 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2619 uint64_t data = BVAL(r.out.data.data, i);
2620 torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2621 talloc_asprintf(torture, "read data "
2622 "pattern bad at %llu\n",
2623 (unsigned long long)off + i));
2625 talloc_free(r.out.data.data);
2633 static bool test_setup_open(struct torture_context *torture,
2634 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2636 struct smb2_handle *fh,
2637 uint32_t desired_access,
2638 uint32_t file_attributes)
2640 struct smb2_create io;
2644 io.in.desired_access = desired_access;
2645 io.in.file_attributes = file_attributes;
2646 io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2647 io.in.share_access =
2648 NTCREATEX_SHARE_ACCESS_DELETE|
2649 NTCREATEX_SHARE_ACCESS_READ|
2650 NTCREATEX_SHARE_ACCESS_WRITE;
2651 if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2652 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2654 io.in.fname = fname;
2656 status = smb2_create(tree, mem_ctx, &io);
2657 torture_assert_ntstatus_ok(torture, status, "file create");
2659 *fh = io.out.file.handle;
2664 static bool test_setup_create_fill(struct torture_context *torture,
2665 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2667 struct smb2_handle *fh,
2669 uint32_t desired_access,
2670 uint32_t file_attributes)
2674 ok = test_setup_open(torture, tree, mem_ctx,
2679 torture_assert(torture, ok, "file open");
2682 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2683 torture_assert(torture, ok, "write pattern");
2688 static bool test_setup_copy_chunk(struct torture_context *torture,
2689 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2691 const char *src_name,
2692 struct smb2_handle *src_h,
2694 uint32_t src_desired_access,
2695 const char *dst_name,
2696 struct smb2_handle *dest_h,
2698 uint32_t dest_desired_access,
2699 struct srv_copychunk_copy *cc_copy,
2700 union smb_ioctl *io)
2702 struct req_resume_key_rsp res_key;
2705 enum ndr_err_code ndr_ret;
2707 ok = test_setup_create_fill(torture, tree, mem_ctx, src_name,
2708 src_h, src_size, src_desired_access,
2709 FILE_ATTRIBUTE_NORMAL);
2710 torture_assert(torture, ok, "src file create fill");
2712 ok = test_setup_create_fill(torture, tree, mem_ctx, dst_name,
2713 dest_h, dest_size, dest_desired_access,
2714 FILE_ATTRIBUTE_NORMAL);
2715 torture_assert(torture, ok, "dest file create fill");
2718 io->smb2.level = RAW_IOCTL_SMB2;
2719 io->smb2.in.file.handle = *src_h;
2720 io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2721 /* Allow for Key + ContextLength + Context */
2722 io->smb2.in.max_response_size = 32;
2723 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2725 status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2726 torture_assert_ntstatus_ok(torture, status,
2727 "FSCTL_SRV_REQUEST_RESUME_KEY");
2729 ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2730 (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2732 torture_assert_ndr_success(torture, ndr_ret,
2733 "ndr_pull_req_resume_key_rsp");
2736 io->smb2.level = RAW_IOCTL_SMB2;
2737 io->smb2.in.file.handle = *dest_h;
2738 io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2739 io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2740 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2742 ZERO_STRUCTPN(cc_copy);
2743 memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2744 cc_copy->chunk_count = nchunks;
2745 cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2746 torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2752 static bool check_copy_chunk_rsp(struct torture_context *torture,
2753 struct srv_copychunk_rsp *cc_rsp,
2754 uint32_t ex_chunks_written,
2755 uint32_t ex_chunk_bytes_written,
2756 uint32_t ex_total_bytes_written)
2758 torture_assert_int_equal(torture, cc_rsp->chunks_written,
2759 ex_chunks_written, "num chunks");
2760 torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2761 ex_chunk_bytes_written, "chunk bytes written");
2762 torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2763 ex_total_bytes_written, "chunk total bytes");
2767 static bool neg_aapl_copyfile(struct torture_context *tctx,
2768 struct smb2_tree *tree,
2771 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2772 const char *fname = "aapl";
2774 struct smb2_create io;
2776 struct smb2_create_blob *aapl = NULL;
2778 uint32_t aapl_reply_bitmap;
2779 uint32_t aapl_server_caps;
2783 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2784 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2785 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2786 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2787 NTCREATEX_SHARE_ACCESS_READ |
2788 NTCREATEX_SHARE_ACCESS_WRITE);
2789 io.in.fname = fname;
2791 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2792 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2793 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2794 SBVAL(data.data, 16, flags);
2796 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2797 CHECK_STATUS(status, NT_STATUS_OK);
2799 status = smb2_create(tree, tctx, &io);
2800 CHECK_STATUS(status, NT_STATUS_OK);
2802 aapl = smb2_create_blob_find(&io.out.blobs,
2803 SMB2_CREATE_TAG_AAPL);
2809 if (aapl->data.length < 24) {
2814 aapl_cmd = IVAL(aapl->data.data, 0);
2815 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2816 torture_result(tctx, TORTURE_FAIL,
2817 "(%s) unexpected cmd: %d",
2818 __location__, (int)aapl_cmd);
2823 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2824 if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2825 torture_result(tctx, TORTURE_FAIL,
2826 "(%s) unexpected reply_bitmap: %d",
2827 __location__, (int)aapl_reply_bitmap);
2832 aapl_server_caps = BVAL(aapl->data.data, 16);
2833 if (!(aapl_server_caps & flags)) {
2834 torture_result(tctx, TORTURE_FAIL,
2835 "(%s) unexpected server_caps: %d",
2836 __location__, (int)aapl_server_caps);
2842 status = smb2_util_close(tree, io.out.file.handle);
2843 CHECK_STATUS(status, NT_STATUS_OK);
2845 smb2_util_unlink(tree, "aapl");
2846 talloc_free(mem_ctx);
2850 static bool test_copyfile(struct torture_context *torture,
2851 struct smb2_tree *tree)
2853 struct smb2_handle src_h;
2854 struct smb2_handle dest_h;
2857 TALLOC_CTX *tmp_ctx = talloc_new(tree);
2858 struct srv_copychunk_copy cc_copy;
2859 struct srv_copychunk_rsp cc_rsp;
2860 enum ndr_err_code ndr_ret;
2862 const char *sname = ":foo" "\xef\x80\xa2" "bar:$DATA";
2865 * First test a copy_chunk with a 0 chunk count without having
2866 * enabled this via AAPL. The request must not fail and the
2867 * copied length in the response must be 0. This is verified
2868 * against Windows 2008r2.
2871 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2872 0, /* 0 chunks, copyfile semantics */
2874 &src_h, 4096, /* fill 4096 byte src file */
2875 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2877 &dest_h, 0, /* 0 byte dest file */
2878 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2882 torture_fail_goto(torture, done, "setup copy chunk error");
2885 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2887 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2888 torture_assert_ndr_success(torture, ndr_ret,
2889 "ndr_push_srv_copychunk_copy");
2891 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2892 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2894 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2896 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2897 torture_assert_ndr_success(torture, ndr_ret,
2898 "ndr_pull_srv_copychunk_rsp");
2900 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2901 0, /* chunks written */
2902 0, /* chunk bytes unsuccessfully written */
2903 0); /* total bytes written */
2905 torture_fail_goto(torture, done, "bad copy chunk response data");
2909 * Now enable AAPL copyfile and test again, the file and the
2910 * stream must be copied by the server.
2912 ok = neg_aapl_copyfile(torture, tree,
2913 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2915 torture_skip_goto(torture, done, "missing AAPL copyfile");
2919 smb2_util_close(tree, src_h);
2920 smb2_util_close(tree, dest_h);
2921 smb2_util_unlink(tree, FNAME_CC_SRC);
2922 smb2_util_unlink(tree, FNAME_CC_DST);
2924 ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2926 torture_fail(torture, "setup file error");
2928 ok = write_stream(tree, __location__, torture, tmp_ctx,
2929 FNAME_CC_SRC, AFPRESOURCE_STREAM,
2930 10, 10, "1234567890");
2932 torture_fail(torture, "setup stream error");
2935 ok = write_stream(tree, __location__, torture, tmp_ctx,
2936 FNAME_CC_SRC, sname,
2937 10, 10, "abcdefghij");
2938 torture_assert_goto(torture, ok == true, ok, done, "write_stream failed\n");
2940 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2941 0, /* 0 chunks, copyfile semantics */
2943 &src_h, 4096, /* fill 4096 byte src file */
2944 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2946 &dest_h, 0, /* 0 byte dest file */
2947 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2951 torture_fail_goto(torture, done, "setup copy chunk error");
2954 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2956 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2957 torture_assert_ndr_success(torture, ndr_ret,
2958 "ndr_push_srv_copychunk_copy");
2960 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2961 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2963 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2965 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2966 torture_assert_ndr_success(torture, ndr_ret,
2967 "ndr_pull_srv_copychunk_rsp");
2969 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2970 0, /* chunks written */
2971 0, /* chunk bytes unsuccessfully written */
2972 4096); /* total bytes written */
2974 torture_fail_goto(torture, done, "bad copy chunk response data");
2977 ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
2978 SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
2980 torture_fail_goto(torture, done,"open failed");
2982 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
2984 torture_fail_goto(torture, done, "inconsistent file data");
2987 ok = check_stream(tree, __location__, torture, tmp_ctx,
2988 FNAME_CC_DST, AFPRESOURCE_STREAM,
2989 0, 20, 10, 10, "1234567890");
2991 torture_fail_goto(torture, done, "inconsistent stream data");
2994 ok = check_stream(tree, __location__, torture, tmp_ctx,
2995 FNAME_CC_DST, sname,
2996 0, 20, 10, 10, "abcdefghij");
2997 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
3000 smb2_util_close(tree, src_h);
3001 smb2_util_close(tree, dest_h);
3002 smb2_util_unlink(tree, FNAME_CC_SRC);
3003 smb2_util_unlink(tree, FNAME_CC_DST);
3004 talloc_free(tmp_ctx);
3008 static bool check_stream_list(struct smb2_tree *tree,
3009 struct torture_context *tctx,
3016 union smb_fileinfo finfo;
3019 TALLOC_CTX *tmp_ctx = talloc_new(tctx);
3021 struct stream_struct *stream_sort;
3022 struct smb2_create create;
3023 struct smb2_handle h;
3026 torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
3028 ZERO_STRUCT(create);
3029 create.in.fname = fname;
3030 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3031 create.in.desired_access = SEC_FILE_ALL;
3032 create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
3033 create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
3034 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3035 status = smb2_create(tree, tmp_ctx, &create);
3036 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
3037 h = create.out.file.handle;
3039 finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
3040 finfo.generic.in.file.handle = h;
3042 status = smb2_getinfo_file(tree, tctx, &finfo);
3043 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
3045 smb2_util_close(tree, h);
3047 torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
3048 ret, done, "stream count");
3051 TALLOC_FREE(tmp_ctx);
3055 exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
3056 torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
3058 TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
3060 stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
3061 finfo.stream_info.out.num_streams *
3062 sizeof(*stream_sort));
3063 torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
3065 TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
3067 for (i=0; i<num_exp; i++) {
3068 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
3069 i, exp_sort[i], stream_sort[i].stream_name.s);
3070 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
3071 ret, done, "stream name");
3075 TALLOC_FREE(tmp_ctx);
3082 static bool test_stream_names(struct torture_context *tctx,
3083 struct smb2_tree *tree)
3085 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3087 struct smb2_create create;
3088 struct smb2_handle h;
3089 const char *fname = BASEDIR "\\stream_names.txt";
3092 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
3093 const char *streams[] = {
3094 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
3098 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
3100 /* clean slate ...*/
3101 smb2_util_unlink(tree, fname);
3102 smb2_deltree(tree, fname);
3103 smb2_deltree(tree, BASEDIR);
3105 status = torture_smb2_testdir(tree, BASEDIR, &h);
3106 CHECK_STATUS(status, NT_STATUS_OK);
3107 smb2_util_close(tree, h);
3109 ret = torture_setup_file(mem_ctx, tree, fname, false);
3110 torture_assert_goto(tctx, ret, ret, done, "torture_setup_file");
3112 torture_comment(tctx, "(%s) testing stream names\n", __location__);
3113 ZERO_STRUCT(create);
3114 create.in.desired_access = SEC_FILE_WRITE_DATA;
3115 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3116 create.in.share_access =
3117 NTCREATEX_SHARE_ACCESS_DELETE|
3118 NTCREATEX_SHARE_ACCESS_READ|
3119 NTCREATEX_SHARE_ACCESS_WRITE;
3120 create.in.create_disposition = NTCREATEX_DISP_CREATE;
3121 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3122 create.in.fname = sname1;
3124 status = smb2_create(tree, mem_ctx, &create);
3125 CHECK_STATUS(status, NT_STATUS_OK);
3127 status = smb2_util_write(tree, create.out.file.handle, "foo", 0, 3);
3128 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3129 "smb2_util_write failed\n");
3131 smb2_util_close(tree, create.out.file.handle);
3133 ret = check_stream_list(tree, tctx, fname, 2, streams, false);
3134 CHECK_VALUE(ret, true);
3137 status = smb2_util_unlink(tree, fname);
3138 smb2_deltree(tree, BASEDIR);
3139 talloc_free(mem_ctx);
3144 /* Renaming a directory with open file, should work for OS X AAPL clients */
3145 static bool test_rename_dir_openfile(struct torture_context *torture,
3146 struct smb2_tree *tree)
3152 union smb_setfileinfo sinfo;
3153 struct smb2_handle d1, h1;
3154 const char *renamedir = BASEDIR "-new";
3155 bool server_is_osx = torture_setting_bool(torture, "osx", false);
3157 smb2_deltree(tree, BASEDIR);
3158 smb2_util_rmdir(tree, BASEDIR);
3159 smb2_deltree(tree, renamedir);
3161 ZERO_STRUCT(io.smb2);
3162 io.generic.level = RAW_OPEN_SMB2;
3163 io.smb2.in.create_flags = 0;
3164 io.smb2.in.desired_access = 0x0017019f;
3165 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
3166 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3167 io.smb2.in.share_access = 0;
3168 io.smb2.in.alloc_size = 0;
3169 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
3170 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3171 io.smb2.in.security_flags = 0;
3172 io.smb2.in.fname = BASEDIR;
3174 status = smb2_create(tree, torture, &(io.smb2));
3175 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3176 d1 = io.smb2.out.file.handle;
3178 ZERO_STRUCT(io.smb2);
3179 io.generic.level = RAW_OPEN_SMB2;
3180 io.smb2.in.create_flags = 0;
3181 io.smb2.in.desired_access = 0x0017019f;
3182 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
3183 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3184 io.smb2.in.share_access = 0;
3185 io.smb2.in.alloc_size = 0;
3186 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
3187 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3188 io.smb2.in.security_flags = 0;
3189 io.smb2.in.fname = BASEDIR "\\file.txt";
3191 status = smb2_create(tree, torture, &(io.smb2));
3192 torture_assert_ntstatus_ok(torture, status, "smb2_create file");
3193 h1 = io.smb2.out.file.handle;
3195 if (!server_is_osx) {
3196 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
3199 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3200 sinfo.rename_information.in.file.handle = d1;
3201 sinfo.rename_information.in.overwrite = 0;
3202 sinfo.rename_information.in.root_fid = 0;
3203 sinfo.rename_information.in.new_name = renamedir;
3204 status = smb2_setinfo_file(tree, &sinfo);
3206 torture_assert_ntstatus_equal(torture, status,
3207 NT_STATUS_ACCESS_DENIED,
3208 "smb2_setinfo_file");
3211 status = smb2_util_close(tree, d1);
3212 torture_assert_ntstatus_ok(torture, status, "smb2_util_close\n");
3215 torture_comment(torture, "Enabling AAPL\n");
3217 ret = enable_aapl(torture, tree);
3218 torture_assert(torture, ret == true, "enable_aapl failed");
3220 torture_comment(torture, "Renaming directory with AAPL\n");
3222 ZERO_STRUCT(io.smb2);
3223 io.generic.level = RAW_OPEN_SMB2;
3224 io.smb2.in.desired_access = 0x0017019f;
3225 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3226 io.smb2.in.share_access = 0;
3227 io.smb2.in.alloc_size = 0;
3228 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
3229 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3230 io.smb2.in.security_flags = 0;
3231 io.smb2.in.fname = BASEDIR;
3233 status = smb2_create(tree, torture, &(io.smb2));
3234 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3235 d1 = io.smb2.out.file.handle;
3238 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3239 sinfo.rename_information.in.file.handle = d1;
3240 sinfo.rename_information.in.overwrite = 0;
3241 sinfo.rename_information.in.root_fid = 0;
3242 sinfo.rename_information.in.new_name = renamedir;
3244 status = smb2_setinfo_file(tree, &sinfo);
3245 torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
3247 ZERO_STRUCT(cl.smb2);
3248 cl.smb2.level = RAW_CLOSE_SMB2;
3249 cl.smb2.in.file.handle = d1;
3250 status = smb2_close(tree, &(cl.smb2));
3251 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3254 cl.smb2.in.file.handle = h1;
3255 status = smb2_close(tree, &(cl.smb2));
3256 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3259 torture_comment(torture, "Cleaning up\n");
3261 if (h1.data[0] || h1.data[1]) {
3262 ZERO_STRUCT(cl.smb2);
3263 cl.smb2.level = RAW_CLOSE_SMB2;
3264 cl.smb2.in.file.handle = h1;
3265 status = smb2_close(tree, &(cl.smb2));
3268 smb2_util_unlink(tree, BASEDIR "\\file.txt");
3269 smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
3270 smb2_deltree(tree, renamedir);
3271 smb2_deltree(tree, BASEDIR);
3275 static bool test_afpinfo_enoent(struct torture_context *tctx,
3276 struct smb2_tree *tree)
3280 struct smb2_create create;
3281 struct smb2_handle h1;
3282 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3283 const char *fname = BASEDIR "\\file";
3284 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3286 torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
3288 smb2_deltree(tree, BASEDIR);
3289 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3290 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3291 smb2_util_close(tree, h1);
3292 ret = torture_setup_file(mem_ctx, tree, fname, false);
3293 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3295 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3297 ZERO_STRUCT(create);
3298 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3299 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3300 create.in.fname = sname;
3302 status = smb2_create(tree, mem_ctx, &create);
3303 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3304 ret, done, "Got unexpected AFP_AfpInfo stream");
3307 smb2_util_unlink(tree, fname);
3308 smb2_util_rmdir(tree, BASEDIR);
3312 static bool test_create_delete_on_close(struct torture_context *tctx,
3313 struct smb2_tree *tree)
3317 struct smb2_create create;
3318 struct smb2_handle h1;
3319 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3320 const char *fname = BASEDIR "\\file";
3321 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3322 const char *type_creator = "SMB,OLE!";
3323 AfpInfo *info = NULL;
3324 const char *streams_basic[] = {
3327 const char *streams_afpinfo[] = {
3332 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3334 torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
3336 smb2_deltree(tree, BASEDIR);
3337 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3338 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3339 smb2_util_close(tree, h1);
3340 ret = torture_setup_file(mem_ctx, tree, fname, false);
3341 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3343 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3345 ZERO_STRUCT(create);
3346 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3347 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3348 create.in.fname = sname;
3350 status = smb2_create(tree, mem_ctx, &create);
3351 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3352 ret, done, "Got unexpected AFP_AfpInfo stream");
3354 ZERO_STRUCT(create);
3355 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3356 create.in.desired_access = SEC_FILE_ALL;
3357 create.in.fname = sname;
3359 status = smb2_create(tree, mem_ctx, &create);
3360 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3361 ret, done, "Got unexpected AFP_AfpInfo stream");
3363 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3364 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3366 torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
3368 info = torture_afpinfo_new(mem_ctx);
3369 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3371 memcpy(info->afpi_FinderInfo, type_creator, 8);
3372 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3373 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3375 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3376 0, 60, 16, 8, type_creator);
3377 torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
3379 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3380 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3382 ZERO_STRUCT(create);
3383 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3384 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3385 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3386 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3387 create.in.fname = sname;
3388 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3390 status = smb2_create(tree, mem_ctx, &create);
3391 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3393 h1 = create.out.file.handle;
3394 smb2_util_close(tree, h1);
3396 ZERO_STRUCT(create);
3397 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3398 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
3399 create.in.fname = sname;
3400 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3401 status = smb2_create(tree, mem_ctx, &create);
3402 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3403 ret, done, "Got unexpected AFP_AfpInfo stream");
3405 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3406 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3409 smb2_util_unlink(tree, fname);
3410 smb2_util_rmdir(tree, BASEDIR);
3414 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
3415 struct smb2_tree *tree)
3419 struct smb2_create create;
3420 union smb_setfileinfo sfinfo;
3421 struct smb2_handle h1;
3422 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3423 const char *fname = BASEDIR "\\file";
3424 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3425 const char *type_creator = "SMB,OLE!";
3426 AfpInfo *info = NULL;
3427 const char *streams[] = {
3431 const char *streams_basic[] = {
3435 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3437 torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
3439 smb2_deltree(tree, BASEDIR);
3440 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3441 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3442 smb2_util_close(tree, h1);
3443 ret = torture_setup_file(mem_ctx, tree, fname, false);
3444 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3446 info = torture_afpinfo_new(mem_ctx);
3447 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3448 memcpy(info->afpi_FinderInfo, type_creator, 8);
3449 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3450 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3452 ZERO_STRUCT(create);
3453 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3454 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3455 create.in.fname = sname;
3456 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3457 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3459 status = smb2_create(tree, mem_ctx, &create);
3460 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3462 h1 = create.out.file.handle;
3464 /* Delete stream via setinfo delete-on-close */
3465 ZERO_STRUCT(sfinfo);
3466 sfinfo.disposition_info.in.delete_on_close = 1;
3467 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3468 sfinfo.generic.in.file.handle = h1;
3469 status = smb2_setinfo_file(tree, &sfinfo);
3470 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3472 ret = check_stream_list(tree, tctx, fname, 2, streams, false);
3473 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3475 ZERO_STRUCT(create);
3476 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3477 create.in.desired_access = SEC_FILE_ALL;
3478 create.in.fname = sname;
3479 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3480 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3481 status = smb2_create(tree, mem_ctx, &create);
3482 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_DELETE_PENDING,
3483 ret, done, "Got unexpected AFP_AfpInfo stream");
3485 smb2_util_close(tree, h1);
3487 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3488 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3490 ZERO_STRUCT(create);
3491 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3492 create.in.desired_access = SEC_FILE_ALL;
3493 create.in.fname = sname;
3494 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3495 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3496 status = smb2_create(tree, mem_ctx, &create);
3497 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3498 ret, done, "Got unexpected AFP_AfpInfo stream");
3501 smb2_util_unlink(tree, fname);
3502 smb2_util_rmdir(tree, BASEDIR);
3506 static bool test_setinfo_eof(struct torture_context *tctx,
3507 struct smb2_tree *tree)
3511 struct smb2_create create;
3512 union smb_setfileinfo sfinfo;
3513 struct smb2_handle h1;
3514 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3515 const char *fname = BASEDIR "\\file";
3516 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3517 const char *type_creator = "SMB,OLE!";
3518 AfpInfo *info = NULL;
3519 const char *streams_afpinfo[] = {
3524 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3526 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
3528 smb2_deltree(tree, BASEDIR);
3529 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3530 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3531 smb2_util_close(tree, h1);
3532 ret = torture_setup_file(mem_ctx, tree, fname, false);
3533 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3535 info = torture_afpinfo_new(mem_ctx);
3536 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3537 memcpy(info->afpi_FinderInfo, type_creator, 8);
3538 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3539 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3541 ZERO_STRUCT(create);
3542 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3543 create.in.desired_access = SEC_FILE_ALL;
3544 create.in.fname = sname;
3545 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3546 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3548 status = smb2_create(tree, mem_ctx, &create);
3549 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3551 h1 = create.out.file.handle;
3553 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
3555 /* Test setinfo end-of-file info */
3556 ZERO_STRUCT(sfinfo);
3557 sfinfo.generic.in.file.handle = h1;
3558 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3559 sfinfo.position_information.in.position = 61;
3560 status = smb2_setinfo_file(tree, &sfinfo);
3561 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
3562 ret, done, "set eof 61 failed");
3564 torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
3566 /* Truncation returns success, but has no effect */
3567 ZERO_STRUCT(sfinfo);
3568 sfinfo.generic.in.file.handle = h1;
3569 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3570 sfinfo.position_information.in.position = 1;
3571 status = smb2_setinfo_file(tree, &sfinfo);
3572 torture_assert_ntstatus_ok_goto(tctx, status,
3573 ret, done, "set eof 1 failed");
3574 smb2_util_close(tree, h1);
3576 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3577 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3579 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3580 0, 60, 16, 8, type_creator);
3581 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3583 ZERO_STRUCT(create);
3584 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3585 create.in.desired_access = SEC_FILE_ALL;
3586 create.in.fname = sname;
3587 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3588 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3590 status = smb2_create(tree, mem_ctx, &create);
3591 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3593 h1 = create.out.file.handle;
3596 * Delete stream via setinfo end-of-file info to 0, should
3597 * return success but stream MUST NOT deleted
3599 ZERO_STRUCT(sfinfo);
3600 sfinfo.generic.in.file.handle = h1;
3601 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3602 sfinfo.position_information.in.position = 0;
3603 status = smb2_setinfo_file(tree, &sfinfo);
3604 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3606 smb2_util_close(tree, h1);
3608 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3609 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3611 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3612 0, 60, 16, 8, type_creator);
3613 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3616 smb2_util_unlink(tree, fname);
3617 smb2_util_rmdir(tree, BASEDIR);
3621 static bool test_afpinfo_all0(struct torture_context *tctx,
3622 struct smb2_tree *tree)
3626 struct smb2_create create;
3627 struct smb2_handle h1 = {{0}};
3628 struct smb2_handle baseh = {{0}};
3629 union smb_setfileinfo setfinfo;
3630 union smb_fileinfo getfinfo;
3631 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3632 const char *fname = BASEDIR "\\file";
3633 const char *sname = BASEDIR "\\file" AFPINFO_STREAM;
3634 const char *type_creator = "SMB,OLE!";
3635 AfpInfo *info = NULL;
3636 char *infobuf = NULL;
3637 const char *streams_basic[] = {
3640 const char *streams_afpinfo[] = {
3645 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3647 torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
3649 smb2_deltree(tree, BASEDIR);
3650 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3651 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3652 smb2_util_close(tree, h1);
3653 ret = torture_setup_file(mem_ctx, tree, fname, false);
3654 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3656 info = torture_afpinfo_new(mem_ctx);
3657 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3658 memcpy(info->afpi_FinderInfo, type_creator, 8);
3659 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3660 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3662 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3663 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3665 /* Write all 0 to AFP_AfpInfo */
3666 memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
3667 infobuf = torture_afpinfo_pack(mem_ctx, info);
3668 torture_assert_not_null_goto(tctx, infobuf, ret, done,
3669 "torture_afpinfo_pack failed\n");
3671 ZERO_STRUCT(create);
3672 create.in.desired_access = SEC_FILE_ALL;
3673 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3674 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3675 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3676 create.in.fname = fname;
3678 status = smb2_create(tree, mem_ctx, &create);
3679 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3680 "smb2_create failed\n");
3681 baseh = create.out.file.handle;
3683 ZERO_STRUCT(create);
3684 create.in.desired_access = SEC_FILE_ALL;
3685 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3686 create.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
3687 create.in.fname = sname;
3689 status = smb2_create(tree, mem_ctx, &create);
3690 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3691 "smb2_create failed\n");
3692 h1 = create.out.file.handle;
3694 status = smb2_util_write(tree, h1, infobuf, 0, AFP_INFO_SIZE);
3695 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3696 "smb2_util_write failed\n");
3699 * Get stream information on open handle, must return only default
3700 * stream, the AFP_AfpInfo stream must not be returned.
3703 ZERO_STRUCT(getfinfo);
3704 getfinfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
3705 getfinfo.generic.in.file.handle = baseh;
3707 status = smb2_getinfo_file(tree, tctx, &getfinfo);
3708 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3709 "get stream info\n");
3711 torture_assert_int_equal_goto(tctx, getfinfo.stream_info.out.num_streams,
3712 1, ret, done, "stream count");
3714 smb2_util_close(tree, baseh);
3718 * Try to set some file-basic-info (time) on the stream. This catches
3719 * naive implementation mistakes that simply deleted the backing store
3720 * from the filesystem in the zero-out step.
3723 ZERO_STRUCT(setfinfo);
3724 unix_to_nt_time(&setfinfo.basic_info.in.write_time, time(NULL));
3725 setfinfo.basic_info.in.attrib = 0x20;
3726 setfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
3727 setfinfo.generic.in.file.handle = h1;
3729 status = smb2_setinfo_file(tree, &setfinfo);
3730 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3731 "smb2_getinfo_file failed\n");
3733 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3734 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
3736 smb2_util_close(tree, h1);
3739 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3740 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3743 if (!smb2_util_handle_empty(h1)) {
3744 smb2_util_close(tree, h1);
3746 if (!smb2_util_handle_empty(baseh)) {
3747 smb2_util_close(tree, baseh);
3749 smb2_util_unlink(tree, fname);
3750 smb2_util_rmdir(tree, BASEDIR);
3754 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
3755 struct smb2_tree *tree)
3759 struct smb2_create create;
3760 struct smb2_handle h1;
3761 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3762 const char *fname = BASEDIR "\\file";
3763 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3764 const char *streams_basic[] = {
3767 const char *streams_afpresource[] = {
3772 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3774 torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
3776 smb2_deltree(tree, BASEDIR);
3777 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3778 torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
3779 smb2_util_close(tree, h1);
3780 ret = torture_setup_file(mem_ctx, tree, fname, false);
3781 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3783 torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
3785 ZERO_STRUCT(create);
3786 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3787 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3788 create.in.fname = sname;
3790 status = smb2_create(tree, mem_ctx, &create);
3791 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3792 ret, done, "Got unexpected AFP_AfpResource stream");
3794 ZERO_STRUCT(create);
3795 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3796 create.in.desired_access = SEC_FILE_ALL;
3797 create.in.fname = sname;
3799 status = smb2_create(tree, mem_ctx, &create);
3800 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3801 ret, done, "Got unexpected AFP_AfpResource stream");
3803 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3804 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3806 torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
3808 ret = write_stream(tree, __location__, tctx, mem_ctx,
3809 fname, AFPRESOURCE_STREAM_NAME,
3810 0, 10, "1234567890");
3811 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3813 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3814 0, 10, 0, 10, "1234567890");
3815 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3817 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3818 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3820 ZERO_STRUCT(create);
3821 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3822 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3823 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3824 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3825 create.in.fname = sname;
3826 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3828 status = smb2_create(tree, mem_ctx, &create);
3829 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3831 h1 = create.out.file.handle;
3832 smb2_util_close(tree, h1);
3834 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3835 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3837 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3838 0, 10, 0, 10, "1234567890");
3839 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3842 smb2_util_unlink(tree, fname);
3843 smb2_util_rmdir(tree, BASEDIR);
3847 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
3848 struct smb2_tree *tree)
3852 struct smb2_create create;
3853 union smb_setfileinfo sfinfo;
3854 struct smb2_handle h1;
3855 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3856 const char *fname = BASEDIR "\\file";
3857 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3858 const char *streams_afpresource[] = {
3863 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3865 torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
3867 smb2_deltree(tree, BASEDIR);
3868 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3869 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3870 smb2_util_close(tree, h1);
3871 ret = torture_setup_file(mem_ctx, tree, fname, false);
3872 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3874 ret = write_stream(tree, __location__, tctx, mem_ctx,
3875 fname, AFPRESOURCE_STREAM_NAME,
3876 10, 10, "1234567890");
3877 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3879 ZERO_STRUCT(create);
3880 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3881 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3882 create.in.fname = sname;
3883 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3884 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3886 status = smb2_create(tree, mem_ctx, &create);
3887 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3889 h1 = create.out.file.handle;
3891 /* Try to delete stream via setinfo delete-on-close */
3892 ZERO_STRUCT(sfinfo);
3893 sfinfo.disposition_info.in.delete_on_close = 1;
3894 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3895 sfinfo.generic.in.file.handle = h1;
3896 status = smb2_setinfo_file(tree, &sfinfo);
3897 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3899 smb2_util_close(tree, h1);
3901 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3902 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3904 ZERO_STRUCT(create);
3905 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3906 create.in.desired_access = SEC_FILE_ALL;
3907 create.in.fname = sname;
3908 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3909 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3910 status = smb2_create(tree, mem_ctx, &create);
3911 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3912 "Got unexpected AFP_AfpResource stream");
3915 smb2_util_unlink(tree, fname);
3916 smb2_util_rmdir(tree, BASEDIR);
3920 static bool test_setinfo_eof_resource(struct torture_context *tctx,
3921 struct smb2_tree *tree)
3925 struct smb2_create create;
3926 union smb_setfileinfo sfinfo;
3927 union smb_fileinfo finfo;
3928 struct smb2_handle h1;
3929 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3930 const char *fname = BASEDIR "\\file";
3931 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3932 const char *streams_basic[] = {
3936 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3938 torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
3940 smb2_deltree(tree, BASEDIR);
3941 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3942 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3943 smb2_util_close(tree, h1);
3944 ret = torture_setup_file(mem_ctx, tree, fname, false);
3945 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3947 ret = write_stream(tree, __location__, tctx, mem_ctx,
3948 fname, AFPRESOURCE_STREAM_NAME,
3949 10, 10, "1234567890");
3950 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3952 ZERO_STRUCT(create);
3953 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3954 create.in.desired_access = SEC_FILE_ALL;
3955 create.in.fname = sname;
3956 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3957 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3959 status = smb2_create(tree, mem_ctx, &create);
3960 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3962 h1 = create.out.file.handle;
3964 torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
3966 /* Test setinfo end-of-file info */
3967 ZERO_STRUCT(sfinfo);
3968 sfinfo.generic.in.file.handle = h1;
3969 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3970 sfinfo.position_information.in.position = 1;
3971 status = smb2_setinfo_file(tree, &sfinfo);
3972 torture_assert_ntstatus_ok_goto(tctx, status,
3973 ret, done, "set eof 1 failed");
3975 smb2_util_close(tree, h1);
3977 /* Check size == 1 */
3978 ZERO_STRUCT(create);
3979 create.in.fname = sname;
3980 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3981 create.in.desired_access = SEC_FILE_ALL;
3982 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3983 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3984 status = smb2_create(tree, mem_ctx, &create);
3985 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3987 h1 = create.out.file.handle;
3990 finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
3991 finfo.generic.in.file.handle = h1;
3992 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
3993 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
3995 smb2_util_close(tree, h1);
3997 torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
3999 ZERO_STRUCT(create);
4000 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4001 create.in.desired_access = SEC_FILE_ALL;
4002 create.in.fname = sname;
4003 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4004 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4006 status = smb2_create(tree, mem_ctx, &create);
4007 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4009 h1 = create.out.file.handle;
4012 * Delete stream via setinfo end-of-file info to 0, this
4013 * should delete the stream.
4015 ZERO_STRUCT(sfinfo);
4016 sfinfo.generic.in.file.handle = h1;
4017 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4018 sfinfo.position_information.in.position = 0;
4019 status = smb2_setinfo_file(tree, &sfinfo);
4020 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
4022 smb2_util_close(tree, h1);
4024 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
4025 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4027 ZERO_STRUCT(create);
4028 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4029 create.in.desired_access = SEC_FILE_ALL;
4030 create.in.fname = sname;
4031 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4032 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
4034 status = smb2_create(tree, mem_ctx, &create);
4035 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4036 ret, done, "smb2_create failed");
4039 smb2_util_unlink(tree, fname);
4040 smb2_util_rmdir(tree, BASEDIR);
4045 * This tests that right after creating the AFP_AfpInfo stream,
4046 * reading from the stream returns an empty, default metadata blob of
4049 * NOTE: against OS X SMB server this only works if the read request
4050 * is compounded with the create that created the stream, is fails
4051 * otherwise. We don't care...
4053 static bool test_null_afpinfo(struct torture_context *tctx,
4054 struct smb2_tree *tree)
4056 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4057 const char *fname = "test_null_afpinfo";
4058 const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
4061 struct smb2_request *req[3];
4062 struct smb2_handle handle;
4063 struct smb2_create create;
4064 struct smb2_read read;
4065 AfpInfo *afpinfo = NULL;
4066 char *afpinfo_buf = NULL;
4067 const char *type_creator = "SMB,OLE!";
4068 struct smb2_handle handle2;
4071 torture_comment(tctx, "Checking create of AfpInfo stream\n");
4073 smb2_util_unlink(tree, fname);
4075 ret = torture_setup_file(mem_ctx, tree, fname, false);
4076 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
4078 ZERO_STRUCT(create);
4079 create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
4080 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
4081 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4082 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4083 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
4084 create.in.fname = sname;
4086 smb2_transport_compound_start(tree->session->transport, 2);
4088 req[0] = smb2_create_send(tree, &create);
4090 handle.data[0] = UINT64_MAX;
4091 handle.data[1] = UINT64_MAX;
4093 smb2_transport_compound_set_related(tree->session->transport, true);
4096 read.in.file.handle = handle;
4097 read.in.length = AFP_INFO_SIZE;
4098 req[1] = smb2_read_send(tree, &read);
4100 status = smb2_create_recv(req[0], tree, &create);
4101 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
4103 handle = create.out.file.handle;
4105 status = smb2_read_recv(req[1], tree, &read);
4106 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
4108 status = torture_smb2_testfile_access(tree, sname, &handle2,
4109 SEC_FILE_READ_DATA);
4110 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4111 "torture_smb2_testfile failed\n");
4112 r = (struct smb2_read) {
4113 .in.file.handle = handle2,
4114 .in.length = AFP_INFO_SIZE,
4117 status = smb2_read(tree, tree, &r);
4118 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4119 "torture_smb2_testfile failed\n");
4120 smb2_util_close(tree, handle2);
4122 afpinfo = torture_afpinfo_new(mem_ctx);
4123 torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
4125 memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
4127 afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
4128 torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
4130 status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
4131 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
4133 smb2_util_close(tree, handle);
4135 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
4136 0, 60, 16, 8, type_creator);
4137 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
4140 smb2_util_unlink(tree, fname);
4141 talloc_free(mem_ctx);
4145 static bool test_delete_file_with_rfork(struct torture_context *tctx,
4146 struct smb2_tree *tree)
4148 const char *fname = "torture_write_rfork_io";
4149 const char *rfork_content = "1234567890";
4153 smb2_util_unlink(tree, fname);
4155 torture_comment(tctx, "Test deleting file with resource fork\n");
4157 ret = torture_setup_file(tctx, tree, fname, false);
4158 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
4160 ret = write_stream(tree, __location__, tctx, tctx,
4161 fname, AFPRESOURCE_STREAM_NAME,
4162 10, 10, rfork_content);
4163 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
4165 ret = check_stream(tree, __location__, tctx, tctx,
4166 fname, AFPRESOURCE_STREAM_NAME,
4167 0, 20, 10, 10, rfork_content);
4168 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
4170 status = smb2_util_unlink(tree, fname);
4171 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
4177 static bool test_rename_and_read_rsrc(struct torture_context *tctx,
4178 struct smb2_tree *tree)
4182 struct smb2_create create, create2;
4183 struct smb2_handle h1, h2;
4184 const char *fname = "test_rename_openfile";
4185 const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
4186 const char *fname_renamed = "test_rename_openfile_renamed";
4187 const char *data = "1234567890";
4188 union smb_setfileinfo sinfo;
4189 bool server_is_macos = torture_setting_bool(tctx, "osx", false);
4190 NTSTATUS expected_status;
4192 ret = enable_aapl(tctx, tree);
4193 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
4195 torture_comment(tctx, "Create file with resource fork\n");
4197 ret = torture_setup_file(tctx, tree, fname, false);
4198 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4200 ret = write_stream(tree, __location__, tctx, tctx,
4201 fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
4202 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4204 torture_comment(tctx, "Open resource fork\n");
4206 ZERO_STRUCT(create);
4207 create.in.desired_access = SEC_FILE_ALL;
4208 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4209 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4210 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4211 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4212 create.in.fname = sname;
4214 status = smb2_create(tree, tctx, &create);
4215 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4217 h1 = create.out.file.handle;
4219 torture_comment(tctx, "Rename base file\n");
4221 ZERO_STRUCT(create2);
4222 create2.in.desired_access = SEC_FILE_ALL;
4223 create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4224 create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4225 create2.in.create_disposition = NTCREATEX_DISP_OPEN;
4226 create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4227 create2.in.fname = fname;
4229 status = smb2_create(tree, tctx, &create2);
4230 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4232 h2 = create2.out.file.handle;
4235 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
4236 sinfo.rename_information.in.file.handle = h2;
4237 sinfo.rename_information.in.overwrite = 0;
4238 sinfo.rename_information.in.root_fid = 0;
4239 sinfo.rename_information.in.new_name = fname_renamed;
4241 if (server_is_macos) {
4242 expected_status = NT_STATUS_SHARING_VIOLATION;
4244 expected_status = NT_STATUS_ACCESS_DENIED;
4247 status = smb2_setinfo_file(tree, &sinfo);
4248 torture_assert_ntstatus_equal_goto(
4249 tctx, status, expected_status, ret, done,
4250 "smb2_setinfo_file failed");
4252 smb2_util_close(tree, h2);
4254 status = smb2_util_write(tree, h1, "foo", 0, 3);
4255 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4258 smb2_util_close(tree, h1);
4261 smb2_util_unlink(tree, fname);
4262 smb2_util_unlink(tree, fname_renamed);
4267 static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
4268 struct smb2_tree *tree)
4270 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4271 const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
4272 const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
4274 struct smb2_handle testdirh;
4276 struct smb2_create io;
4278 const char *type_creator = "SMB,OLE!";
4281 union smb_search_data *d;
4285 smb2_deltree(tree, BASEDIR);
4287 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
4288 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
4289 smb2_util_close(tree, testdirh);
4291 torture_comment(tctx, "Enabling AAPL\n");
4293 ret = enable_aapl(tctx, tree);
4294 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
4297 * Now that Requested AAPL extensions are enabled, setup some
4298 * Mac files with metadata and resource fork
4301 torture_comment(tctx, "Preparing file\n");
4303 ret = torture_setup_file(mem_ctx, tree, fname, false);
4304 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
4306 info = torture_afpinfo_new(mem_ctx);
4307 torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
4309 memcpy(info->afpi_FinderInfo, type_creator, 8);
4310 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
4311 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
4313 ret = write_stream(tree, __location__, tctx, mem_ctx,
4314 fname, AFPRESOURCE_STREAM_NAME,
4316 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4319 * Ok, file is prepared, now call smb2/find
4322 torture_comment(tctx, "Issue find\n");
4325 io.in.desired_access = SEC_RIGHTS_DIR_READ;
4326 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
4327 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
4328 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
4329 NTCREATEX_SHARE_ACCESS_WRITE |
4330 NTCREATEX_SHARE_ACCESS_DELETE);
4331 io.in.create_disposition = NTCREATEX_DISP_OPEN;
4332 io.in.fname = BASEDIR;
4333 status = smb2_create(tree, tctx, &io);
4334 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4337 f.in.file.handle = io.out.file.handle;
4339 f.in.max_response_size = 0x1000;
4340 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
4342 status = smb2_find_level(tree, tree, &f, &count, &d);
4343 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
4345 status = smb2_util_close(tree, io.out.file.handle);
4346 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
4348 torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
4350 for (i = 0; i < count; i++) {
4351 const char *found = d[i].id_both_directory_info.name.s;
4353 if (!strcmp(found, ".") || !strcmp(found, ".."))
4355 if (strncmp(found, "._", 2) == 0) {
4361 torture_assert_str_equal_goto(tctx,
4362 d[i].id_both_directory_info.name.s, name,
4363 ret, done, "bad name");
4365 rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
4366 torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
4368 torture_assert_mem_equal_goto(tctx, type_creator,
4369 d[i].id_both_directory_info.short_name_buf + 8,
4370 8, ret, done, "Bad FinderInfo");
4372 smb2_util_unlink(tree, fname);
4373 smb2_deltree(tree, BASEDIR);
4374 talloc_free(mem_ctx);
4378 static bool test_invalid_afpinfo(struct torture_context *tctx,
4379 struct smb2_tree *tree1,
4380 struct smb2_tree *tree2)
4382 const char *fname = "filtest_invalid_afpinfo";
4383 const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
4384 struct smb2_create create;
4385 const char *streams_basic[] = {
4388 const char *streams_afpinfo[] = {
4395 if (tree2 == NULL) {
4396 torture_skip_goto(tctx, done, "need second share without fruit\n");
4399 torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
4401 ret = torture_setup_file(tctx, tree2, fname, false);
4402 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4404 ret = write_stream(tree2, __location__, tctx, tctx,
4405 fname, AFPINFO_STREAM_NAME,
4407 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4409 ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
4410 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4412 torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
4414 ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
4415 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4417 torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
4419 ZERO_STRUCT(create);
4420 create.in.desired_access = SEC_FILE_ALL;
4421 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4422 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4423 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4424 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4425 create.in.fname = sname;
4427 status = smb2_create(tree1, tctx, &create);
4428 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4429 ret, done, "Stream still around?");
4432 smb2_util_unlink(tree1, fname);
4436 static bool test_zero_file_id(struct torture_context *tctx,
4437 struct smb2_tree *tree)
4439 const char *fname = "filtest_file_id";
4440 struct smb2_create create = {0};
4443 uint8_t zero_file_id[8] = {0};
4445 torture_comment(tctx, "Testing zero file id\n");
4447 ret = torture_setup_file(tctx, tree, fname, false);
4448 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4450 ZERO_STRUCT(create);
4451 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4452 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4453 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4454 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4455 create.in.fname = fname;
4456 create.in.query_on_disk_id = true;
4458 status = smb2_create(tree, tctx, &create);
4459 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
4461 "test file could not be opened");
4462 torture_assert_mem_not_equal_goto(tctx, create.out.on_disk_id,
4463 zero_file_id, 8, ret, done,
4464 "unexpected zero file id");
4466 smb2_util_close(tree, create.out.file.handle);
4468 ret = enable_aapl(tctx, tree);
4469 torture_assert(tctx, ret == true, "enable_aapl failed");
4471 ZERO_STRUCT(create);
4472 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4473 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4474 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4475 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4476 create.in.fname = fname;
4477 create.in.query_on_disk_id = true;
4479 status = smb2_create(tree, tctx, &create);
4480 torture_assert_ntstatus_equal_goto(
4481 tctx, status, NT_STATUS_OK, ret, done,
4482 "test file could not be opened with AAPL");
4483 torture_assert_mem_equal_goto(tctx, create.out.on_disk_id, zero_file_id,
4484 8, ret, done, "non-zero file id");
4486 smb2_util_close(tree, create.out.file.handle);
4489 smb2_util_unlink(tree, fname);
4493 static bool copy_one_stream(struct torture_context *torture,
4494 struct smb2_tree *tree,
4495 TALLOC_CTX *tmp_ctx,
4496 const char *src_sname,
4497 const char *dst_sname)
4499 struct smb2_handle src_h = {{0}};
4500 struct smb2_handle dest_h = {{0}};
4503 struct srv_copychunk_copy cc_copy;
4504 struct srv_copychunk_rsp cc_rsp;
4505 enum ndr_err_code ndr_ret;
4508 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4511 &src_h, 256, /* fill 256 byte src file */
4512 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4514 &dest_h, 0, /* 0 byte dest file */
4515 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4518 torture_assert_goto(torture, ok == true, ok, done,
4519 "setup copy chunk error\n");
4521 /* copy all src file data (via a single chunk desc) */
4522 cc_copy.chunks[0].source_off = 0;
4523 cc_copy.chunks[0].target_off = 0;
4524 cc_copy.chunks[0].length = 256;
4526 ndr_ret = ndr_push_struct_blob(
4527 &io.smb2.in.out, tmp_ctx, &cc_copy,
4528 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4530 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4531 "ndr_push_srv_copychunk_copy\n");
4533 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4534 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4535 "FSCTL_SRV_COPYCHUNK\n");
4537 ndr_ret = ndr_pull_struct_blob(
4538 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4539 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4541 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4542 "ndr_pull_srv_copychunk_rsp\n");
4544 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4545 1, /* chunks written */
4546 0, /* chunk bytes unsuccessfully written */
4547 256); /* total bytes written */
4548 torture_assert_goto(torture, ok == true, ok, done,
4549 "bad copy chunk response data\n");
4551 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
4553 torture_fail(torture, "inconsistent file data\n");
4557 if (!smb2_util_handle_empty(src_h)) {
4558 smb2_util_close(tree, src_h);
4560 if (!smb2_util_handle_empty(dest_h)) {
4561 smb2_util_close(tree, dest_h);
4567 static bool copy_finderinfo_stream(struct torture_context *torture,
4568 struct smb2_tree *tree,
4569 TALLOC_CTX *tmp_ctx,
4570 const char *src_name,
4571 const char *dst_name)
4573 struct smb2_handle src_h = {{0}};
4574 struct smb2_handle dest_h = {{0}};
4577 struct srv_copychunk_copy cc_copy;
4578 struct srv_copychunk_rsp cc_rsp;
4579 enum ndr_err_code ndr_ret;
4580 const char *type_creator = "SMB,OLE!";
4581 AfpInfo *info = NULL;
4582 const char *src_name_afpinfo = NULL;
4583 const char *dst_name_afpinfo = NULL;
4586 src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
4588 torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
4589 "talloc_asprintf failed\n");
4591 dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
4593 torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
4594 "talloc_asprintf failed\n");
4596 info = torture_afpinfo_new(tmp_ctx);
4597 torture_assert_not_null_goto(torture, info, ok, done,
4598 "torture_afpinfo_new failed\n");
4600 memcpy(info->afpi_FinderInfo, type_creator, 8);
4601 ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
4602 torture_assert_goto(torture, ok == true, ok, done,
4603 "torture_write_afpinfo failed\n");
4605 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4609 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4612 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4615 torture_assert_goto(torture, ok == true, ok, done,
4616 "setup copy chunk error\n");
4618 /* copy all src file data (via a single chunk desc) */
4619 cc_copy.chunks[0].source_off = 0;
4620 cc_copy.chunks[0].target_off = 0;
4621 cc_copy.chunks[0].length = 60;
4623 ndr_ret = ndr_push_struct_blob(
4624 &io.smb2.in.out, tmp_ctx, &cc_copy,
4625 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4627 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4628 "ndr_push_srv_copychunk_copy\n");
4630 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4631 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4632 "FSCTL_SRV_COPYCHUNK\n");
4634 ndr_ret = ndr_pull_struct_blob(
4635 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4636 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4638 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4639 "ndr_pull_srv_copychunk_rsp\n");
4641 smb2_util_close(tree, src_h);
4643 smb2_util_close(tree, dest_h);
4644 ZERO_STRUCT(dest_h);
4646 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4647 1, /* chunks written */
4648 0, /* chunk bytes unsuccessfully written */
4649 60); /* total bytes written */
4650 torture_assert_goto(torture, ok == true, ok, done,
4651 "bad copy chunk response data\n");
4653 ok = check_stream(tree, __location__, torture, tmp_ctx,
4654 dst_name, AFPINFO_STREAM,
4655 0, 60, 16, 8, type_creator);
4656 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
4659 if (!smb2_util_handle_empty(src_h)) {
4660 smb2_util_close(tree, src_h);
4662 if (!smb2_util_handle_empty(dest_h)) {
4663 smb2_util_close(tree, dest_h);
4669 static bool test_copy_chunk_streams(struct torture_context *torture,
4670 struct smb2_tree *tree)
4672 const char *src_name = "src";
4673 const char *dst_name = "dst";
4675 const char *src_sname;
4676 const char *dst_sname;
4678 { "src:foo", "dst:foo" },
4679 { "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
4682 TALLOC_CTX *tmp_ctx = NULL;
4685 tmp_ctx = talloc_new(tree);
4686 torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
4687 "torture_setup_file\n");
4689 smb2_util_unlink(tree, src_name);
4690 smb2_util_unlink(tree, dst_name);
4692 ok = torture_setup_file(torture, tree, src_name, false);
4693 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4694 ok = torture_setup_file(torture, tree, dst_name, false);
4695 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4697 for (i = 0; i < ARRAY_SIZE(names); i++) {
4698 ok = copy_one_stream(torture, tree, tmp_ctx,
4700 names[i].dst_sname);
4701 torture_assert_goto(torture, ok == true, ok, done,
4702 "copy_one_stream failed\n");
4705 ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
4706 src_name, dst_name);
4707 torture_assert_goto(torture, ok == true, ok, done,
4708 "copy_finderinfo_stream failed\n");
4711 smb2_util_unlink(tree, src_name);
4712 smb2_util_unlink(tree, dst_name);
4713 talloc_free(tmp_ctx);
4718 * Ensure this security descriptor has exactly one mode, uid
4722 static NTSTATUS check_nfs_sd(const struct security_descriptor *psd)
4725 bool got_one_mode = false;
4726 bool got_one_uid = false;
4727 bool got_one_gid = false;
4729 if (psd->dacl == NULL) {
4730 return NT_STATUS_INVALID_SECURITY_DESCR;
4733 for (i = 0; i < psd->dacl->num_aces; i++) {
4734 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Mode,
4735 &psd->dacl->aces[i].trustee) == 0) {
4736 if (got_one_mode == true) {
4737 /* Can't have more than one. */
4738 return NT_STATUS_INVALID_SECURITY_DESCR;
4740 got_one_mode = true;
4743 for (i = 0; i < psd->dacl->num_aces; i++) {
4744 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Users,
4745 &psd->dacl->aces[i].trustee) == 0) {
4746 if (got_one_uid == true) {
4747 /* Can't have more than one. */
4748 return NT_STATUS_INVALID_SECURITY_DESCR;
4753 for (i = 0; i < psd->dacl->num_aces; i++) {
4754 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Groups,
4755 &psd->dacl->aces[i].trustee) == 0) {
4756 if (got_one_gid == true) {
4757 /* Can't have more than one. */
4758 return NT_STATUS_INVALID_SECURITY_DESCR;
4763 /* Must have at least one of each. */
4764 if (got_one_mode == false ||
4765 got_one_uid == false ||
4766 got_one_gid == false) {
4767 return NT_STATUS_INVALID_SECURITY_DESCR;
4769 return NT_STATUS_OK;
4772 static bool test_nfs_aces(struct torture_context *tctx,
4773 struct smb2_tree *tree)
4775 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4776 struct security_ace ace;
4778 const char *fname = BASEDIR "\\nfs_aces.txt";
4779 struct smb2_handle h = {{0}};
4780 union smb_fileinfo finfo2;
4781 union smb_setfileinfo set;
4782 struct security_descriptor *psd = NULL;
4785 bool is_osx = torture_setting_bool(tctx, "osx", false);
4788 torture_skip(tctx, "Test only works with Samba\n");
4791 ret = enable_aapl(tctx, tree);
4792 torture_assert(tctx, ret == true, "enable_aapl failed");
4794 /* clean slate ...*/
4795 smb2_util_unlink(tree, fname);
4796 smb2_deltree(tree, fname);
4797 smb2_deltree(tree, BASEDIR);
4799 status = torture_smb2_testdir(tree, BASEDIR, &h);
4800 CHECK_STATUS(status, NT_STATUS_OK);
4801 smb2_util_close(tree, h);
4803 /* Create a test file. */
4804 status = torture_smb2_testfile_access(tree,
4807 SEC_STD_READ_CONTROL |
4809 SEC_RIGHTS_FILE_ALL);
4810 CHECK_STATUS(status, NT_STATUS_OK);
4813 finfo2.query_secdesc.in.secinfo_flags =
4817 finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
4818 finfo2.generic.in.file.handle = h;
4819 status = smb2_getinfo_file(tree, tctx, &finfo2);
4820 CHECK_STATUS(status, NT_STATUS_OK);
4822 psd = finfo2.query_secdesc.out.sd;
4824 /* Ensure we have only single mode/uid/gid NFS entries. */
4825 status = check_nfs_sd(psd);
4826 if (!NT_STATUS_IS_OK(status)) {
4828 security_descriptor,
4829 discard_const_p(struct security_descriptor, psd));
4831 CHECK_STATUS(status, NT_STATUS_OK);
4833 /* Add a couple of extra NFS uids and gids. */
4834 sid_compose(&sid, &global_sid_Unix_NFS_Users, 27);
4835 init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
4836 status = security_descriptor_dacl_add(psd, &ace);
4837 CHECK_STATUS(status, NT_STATUS_OK);
4838 status = security_descriptor_dacl_add(psd, &ace);
4839 CHECK_STATUS(status, NT_STATUS_OK);
4841 sid_compose(&sid, &global_sid_Unix_NFS_Groups, 300);
4842 init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
4843 status = security_descriptor_dacl_add(psd, &ace);
4844 CHECK_STATUS(status, NT_STATUS_OK);
4845 status = security_descriptor_dacl_add(psd, &ace);
4846 CHECK_STATUS(status, NT_STATUS_OK);
4848 /* Now set on the file handle. */
4849 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
4850 set.set_secdesc.in.file.handle = h;
4851 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
4852 set.set_secdesc.in.sd = psd;
4853 status = smb2_setinfo_file(tree, &set);
4854 CHECK_STATUS(status, NT_STATUS_OK);
4856 /* Get the ACL again. */
4857 finfo2.query_secdesc.in.secinfo_flags =
4861 finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
4862 finfo2.generic.in.file.handle = h;
4863 status = smb2_getinfo_file(tree, tctx, &finfo2);
4864 CHECK_STATUS(status, NT_STATUS_OK);
4866 psd = finfo2.query_secdesc.out.sd;
4868 /* Ensure we have only single mode/uid/gid NFS entries. */
4869 status = check_nfs_sd(psd);
4870 if (!NT_STATUS_IS_OK(status)) {
4872 security_descriptor,
4873 discard_const_p(struct security_descriptor, psd));
4875 CHECK_STATUS(status, NT_STATUS_OK);
4878 if (!smb2_util_handle_empty(h)) {
4879 smb2_util_close(tree, h);
4881 smb2_util_unlink(tree, fname);
4882 smb2_deltree(tree, fname);
4883 smb2_deltree(tree, BASEDIR);
4884 talloc_free(mem_ctx);
4888 static bool test_setinfo_stream_eof(struct torture_context *tctx,
4889 struct smb2_tree *tree)
4893 struct smb2_create create;
4894 union smb_setfileinfo sfinfo;
4895 union smb_fileinfo finfo;
4896 struct smb2_handle h1;
4897 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4898 const char *fname = BASEDIR "\\file";
4899 const char *sname = BASEDIR "\\file:foo";
4901 torture_assert_goto(tctx, mem_ctx != NULL, ret, done,
4902 "talloc_new failed\n");
4904 torture_comment(tctx, "Test setting EOF on a stream\n");
4906 smb2_deltree(tree, BASEDIR);
4907 status = torture_smb2_testdir(tree, BASEDIR, &h1);
4908 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4909 "torture_smb2_testdir\n");
4910 smb2_util_close(tree, h1);
4912 status = torture_smb2_testfile(tree, fname, &h1);
4913 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4914 "torture_smb2_testfile failed\n");
4915 smb2_util_close(tree, h1);
4917 status = torture_smb2_testfile_access(tree, sname, &h1,
4918 SEC_FILE_WRITE_DATA);
4919 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4920 "torture_smb2_testfile failed\n");
4922 status = smb2_util_write(tree, h1, "1234567890", 0, 10);
4923 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4924 "smb2_util_write failed\n");
4925 smb2_util_close(tree, h1);
4928 * Test setting EOF to 21
4931 torture_comment(tctx, "Setting stream EOF to 21\n");
4933 status = torture_smb2_testfile_access(tree, sname, &h1,
4934 SEC_FILE_WRITE_DATA);
4935 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4936 "torture_smb2_testfile failed\n");
4938 ZERO_STRUCT(sfinfo);
4939 sfinfo.generic.in.file.handle = h1;
4940 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4941 sfinfo.position_information.in.position = 21;
4942 status = smb2_setinfo_file(tree, &sfinfo);
4943 torture_assert_ntstatus_ok_goto(tctx, status,
4944 ret, done, "set EOF 21 failed\n");
4946 smb2_util_close(tree, h1);
4948 status = torture_smb2_testfile_access(tree, sname, &h1,
4949 SEC_FILE_WRITE_DATA);
4950 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4951 "torture_smb2_testfile failed\n");
4954 finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
4955 finfo.generic.in.file.handle = h1;
4956 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
4957 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4958 "smb2_getinfo_file failed");
4960 smb2_util_close(tree, h1);
4962 torture_assert_goto(tctx, finfo.standard_info.out.size == 21,
4963 ret, done, "size != 21\n");
4966 * Test setting EOF to 0
4969 torture_comment(tctx, "Setting stream EOF to 0\n");
4971 status = torture_smb2_testfile_access(tree, sname, &h1,
4972 SEC_FILE_WRITE_DATA);
4973 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4974 "torture_smb2_testfile failed\n");
4976 ZERO_STRUCT(sfinfo);
4977 sfinfo.generic.in.file.handle = h1;
4978 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
4979 sfinfo.position_information.in.position = 0;
4980 status = smb2_setinfo_file(tree, &sfinfo);
4981 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4982 "set eof 0 failed\n");
4984 ZERO_STRUCT(create);
4985 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4986 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4987 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4988 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4989 create.in.fname = sname;
4991 status = smb2_create(tree, tctx, &create);
4992 torture_assert_ntstatus_equal_goto(
4993 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
4994 "Unexpected status\n");
4996 smb2_util_close(tree, h1);
4998 ZERO_STRUCT(create);
4999 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5000 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5001 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5002 create.in.create_disposition = NTCREATEX_DISP_OPEN;
5003 create.in.fname = sname;
5005 status = smb2_create(tree, tctx, &create);
5006 torture_assert_ntstatus_equal_goto(
5007 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
5008 "Unexpected status\n");
5010 status = torture_smb2_testfile_access(tree, sname, &h1,
5011 SEC_FILE_WRITE_DATA);
5012 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5013 "torture_smb2_testfile failed\n");
5016 finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
5017 finfo.generic.in.file.handle = h1;
5018 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
5019 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5020 "smb2_getinfo_file failed\n");
5022 smb2_util_close(tree, h1);
5024 torture_assert_goto(tctx, finfo.standard_info.out.size == 0,
5025 ret, done, "size != 0\n");
5028 * Test setinfo end-of-file info to 1
5031 torture_comment(tctx, "Setting stream EOF to 1\n");
5033 status = torture_smb2_testfile_access(tree, sname, &h1,
5034 SEC_FILE_WRITE_DATA);
5035 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5036 "torture_smb2_testfile failed\n");
5038 ZERO_STRUCT(sfinfo);
5039 sfinfo.generic.in.file.handle = h1;
5040 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5041 sfinfo.position_information.in.position = 1;
5042 status = smb2_setinfo_file(tree, &sfinfo);
5043 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5044 "set EOF 1 failed\n");
5046 smb2_util_close(tree, h1);
5048 status = torture_smb2_testfile_access(tree, sname, &h1,
5049 SEC_FILE_WRITE_DATA);
5050 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5051 "torture_smb2_testfile failed\n");
5054 finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
5055 finfo.generic.in.file.handle = h1;
5056 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
5057 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5058 "smb2_getinfo_file failed\n");
5060 smb2_util_close(tree, h1);
5062 torture_assert_goto(tctx, finfo.standard_info.out.size == 1,
5063 ret, done, "size != 1\n");
5066 * Test setting EOF to 0 with AAPL enabled, should delete stream
5069 torture_comment(tctx, "Enabling AAPL extensions\n");
5071 ret = enable_aapl(tctx, tree);
5072 torture_assert(tctx, ret == true, "enable_aapl failed\n");
5074 torture_comment(tctx, "Setting stream EOF to 0\n");
5075 status = torture_smb2_testfile_access(tree, sname, &h1,
5076 SEC_FILE_WRITE_DATA);
5077 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5078 "torture_smb2_testfile failed\n");
5080 ZERO_STRUCT(sfinfo);
5081 sfinfo.generic.in.file.handle = h1;
5082 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5083 sfinfo.position_information.in.position = 0;
5084 status = smb2_setinfo_file(tree, &sfinfo);
5085 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5086 "set eof 0 failed\n");
5088 ZERO_STRUCT(create);
5089 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5090 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5091 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5092 create.in.create_disposition = NTCREATEX_DISP_OPEN;
5093 create.in.fname = sname;
5095 status = smb2_create(tree, tctx, &create);
5096 torture_assert_ntstatus_equal_goto(
5097 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
5098 "Unexpected status\n");
5100 smb2_util_close(tree, h1);
5102 ZERO_STRUCT(create);
5103 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5104 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5105 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5106 create.in.create_disposition = NTCREATEX_DISP_OPEN;
5107 create.in.fname = sname;
5109 status = smb2_create(tree, tctx, &create);
5110 torture_assert_ntstatus_equal_goto(
5111 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
5112 "Unexpected status\n");
5115 tctx, "Setting main file EOF to 1 to force 0-truncate\n");
5117 status = torture_smb2_testfile_access(
5121 SEC_FILE_WRITE_DATA);
5122 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5123 "torture_smb2_testfile failed\n");
5125 ZERO_STRUCT(sfinfo);
5126 sfinfo.generic.in.file.handle = h1;
5127 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5128 sfinfo.position_information.in.position = 1;
5129 status = smb2_setinfo_file(tree, &sfinfo);
5130 torture_assert_ntstatus_ok_goto(
5135 "set eof 1 failed\n");
5137 sfinfo.position_information.in.position = 0;
5138 status = smb2_setinfo_file(tree, &sfinfo);
5139 torture_assert_ntstatus_ok_goto(
5144 "set eof 0 failed\n");
5146 smb2_util_close(tree, h1);
5148 ZERO_STRUCT(create);
5149 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
5150 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
5151 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5152 create.in.create_disposition = NTCREATEX_DISP_OPEN;
5153 create.in.fname = fname;
5155 status = smb2_create(tree, tctx, &create);
5156 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5157 "torture_smb2_testfile failed\n");
5158 smb2_util_close(tree, h1);
5160 torture_comment(tctx, "Writing to stream after setting EOF to 0\n");
5161 status = torture_smb2_testfile_access(tree, sname, &h1,
5162 SEC_FILE_WRITE_DATA);
5163 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5164 "torture_smb2_testfile failed\n");
5166 status = smb2_util_write(tree, h1, "1234567890", 0, 10);
5167 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5168 "smb2_util_write failed\n");
5170 ZERO_STRUCT(sfinfo);
5171 sfinfo.generic.in.file.handle = h1;
5172 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
5173 sfinfo.position_information.in.position = 0;
5174 status = smb2_setinfo_file(tree, &sfinfo);
5175 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5176 "set eof 0 failed\n");
5178 status = smb2_util_write(tree, h1, "1234567890", 0, 10);
5179 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5180 "smb2_util_write failed\n");
5182 smb2_util_close(tree, h1);
5185 smb2_util_unlink(tree, fname);
5186 smb2_util_rmdir(tree, BASEDIR);
5191 * Note: This test depends on "vfs objects = catia fruit streams_xattr". For
5192 * some tests torture must be run on the host it tests and takes an additional
5193 * argument with the local path to the share:
5194 * "--option=torture:localdir=<SHAREPATH>".
5196 * When running against an OS X SMB server add "--option=torture:osx=true"
5198 struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
5200 struct torture_suite *suite = torture_suite_create(
5203 suite->description = talloc_strdup(suite, "vfs_fruit tests");
5205 torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
5206 torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
5207 torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
5208 torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
5209 torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
5210 torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
5211 torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
5212 torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
5213 torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
5214 torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
5215 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
5216 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
5217 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
5218 torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
5219 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
5220 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
5221 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
5222 torture_suite_add_1smb2_test(suite, "setinfo eof stream", test_setinfo_stream_eof);
5223 torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
5224 torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
5225 torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
5226 torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
5227 torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
5228 torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
5229 torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
5230 torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
5231 torture_suite_add_1smb2_test(suite, "NFS ACE entries", test_nfs_aces);
5232 torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion without embedded xattr", test_adouble_conversion_wo_xattr);
5237 static bool test_stream_names_local(struct torture_context *tctx,
5238 struct smb2_tree *tree)
5240 TALLOC_CTX *mem_ctx = talloc_new(tctx);
5242 struct smb2_create create;
5243 struct smb2_handle h;
5244 const char *fname = BASEDIR "\\stream_names.txt";
5247 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
5248 const char *streams[] = {
5249 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
5250 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
5253 const char *localdir = NULL;
5255 localdir = torture_setting_string(tctx, "localdir", NULL);
5256 if (localdir == NULL) {
5257 torture_skip(tctx, "Need localdir for test");
5260 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
5262 /* clean slate ...*/
5263 smb2_util_unlink(tree, fname);
5264 smb2_deltree(tree, fname);
5265 smb2_deltree(tree, BASEDIR);
5267 status = torture_smb2_testdir(tree, BASEDIR, &h);
5268 CHECK_STATUS(status, NT_STATUS_OK);
5269 smb2_util_close(tree, h);
5271 torture_comment(tctx, "(%s) testing stream names\n", __location__);
5272 ZERO_STRUCT(create);
5273 create.in.desired_access = SEC_FILE_WRITE_DATA;
5274 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
5275 create.in.share_access =
5276 NTCREATEX_SHARE_ACCESS_DELETE|
5277 NTCREATEX_SHARE_ACCESS_READ|
5278 NTCREATEX_SHARE_ACCESS_WRITE;
5279 create.in.create_disposition = NTCREATEX_DISP_CREATE;
5280 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
5281 create.in.fname = sname1;
5283 status = smb2_create(tree, mem_ctx, &create);
5284 CHECK_STATUS(status, NT_STATUS_OK);
5286 status = smb2_util_write(tree, create.out.file.handle, "foo", 0, 3);
5287 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5288 "smb2_util_write failed\n");
5290 smb2_util_close(tree, create.out.file.handle);
5292 ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
5293 "user.DosStream.bar:baz:$DATA",
5294 "data", strlen("data"));
5295 CHECK_VALUE(ret, true);
5297 ret = check_stream_list(tree, tctx, fname, 3, streams, false);
5298 CHECK_VALUE(ret, true);
5301 status = smb2_util_unlink(tree, fname);
5302 smb2_deltree(tree, BASEDIR);
5303 talloc_free(mem_ctx);
5308 static bool test_fruit_locking_conflict(struct torture_context *tctx,
5309 struct smb2_tree *tree)
5311 TALLOC_CTX *mem_ctx;
5312 struct smb2_create create;
5313 struct smb2_handle h;
5314 struct smb2_lock lck;
5315 struct smb2_lock_element el;
5316 const char *fname = BASEDIR "\\locking_conflict.txt";
5320 mem_ctx = talloc_new(tctx);
5321 torture_assert_not_null(tctx, mem_ctx, "talloc_new failed");
5323 /* clean slate ...*/
5324 smb2_util_unlink(tree, fname);
5325 smb2_deltree(tree, fname);
5326 smb2_deltree(tree, BASEDIR);
5328 status = torture_smb2_testdir(tree, BASEDIR, &h);
5329 CHECK_STATUS(status, NT_STATUS_OK);
5330 smb2_util_close(tree, h);
5332 create = (struct smb2_create) {
5333 .in.desired_access = SEC_RIGHTS_FILE_READ,
5334 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5336 NTCREATEX_SHARE_ACCESS_READ|
5337 NTCREATEX_SHARE_ACCESS_WRITE,
5338 .in.create_disposition = NTCREATEX_DISP_CREATE,
5339 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5343 status = smb2_create(tree, mem_ctx, &create);
5344 CHECK_STATUS(status, NT_STATUS_OK);
5345 h = create.out.file.handle;
5347 el = (struct smb2_lock_element) {
5348 .offset = 0xfffffffffffffffc,
5350 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
5352 lck = (struct smb2_lock) {
5354 .in.file.handle = h,
5358 status = smb2_lock(tree, &lck);
5359 CHECK_STATUS(status, NT_STATUS_OK);
5361 el = (struct smb2_lock_element) {
5363 .length = 0x7fffffffffffffff,
5364 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
5366 status = smb2_lock(tree, &lck);
5367 CHECK_STATUS(status, NT_STATUS_OK);
5369 create = (struct smb2_create) {
5370 .in.desired_access =
5371 SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
5372 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5373 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5374 .in.create_disposition = NTCREATEX_DISP_OPEN,
5375 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5379 status = smb2_create(tree, mem_ctx, &create);
5380 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
5383 struct smb2_close cl = {
5384 .level = RAW_CLOSE_SMB2,
5385 .in.file.handle = h,
5387 smb2_close(tree, &cl);
5395 struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
5397 struct torture_suite *suite = torture_suite_create(
5398 ctx, "fruit_netatalk");
5400 suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
5402 torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
5403 torture_suite_add_1smb2_test(suite, "stream names with locally created xattr", test_stream_names_local);
5404 torture_suite_add_1smb2_test(
5405 suite, "locking conflict", test_fruit_locking_conflict);
5410 struct torture_suite *torture_vfs_fruit_file_id(TALLOC_CTX *ctx)
5412 struct torture_suite *suite =
5413 torture_suite_create(ctx, "fruit_file_id");
5415 suite->description =
5416 talloc_strdup(suite, "vfs_fruit tests for on-disk file ID that "
5417 "require fruit:zero_file_id=yes");
5419 torture_suite_add_1smb2_test(suite, "zero file id if AAPL negotiated",
5425 static bool test_timemachine_volsize(struct torture_context *tctx,
5426 struct smb2_tree *tree)
5428 TALLOC_CTX *mem_ctx = talloc_new(tctx);
5429 struct smb2_handle h = {{0}};
5430 union smb_fsinfo fsinfo;
5433 const char *info_plist =
5435 " <key>band-size</key>\n"
5436 " <integer>8192</integer>\n"
5439 smb2_deltree(tree, "test.sparsebundle");
5441 ok = enable_aapl(tctx, tree);
5442 torture_assert_goto(tctx, ok, ok, done, "enable_aapl failed");
5444 status = smb2_util_mkdir(tree, "test.sparsebundle");
5445 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
5446 "smb2_util_mkdir\n");
5448 ok = write_stream(tree, __location__, tctx, mem_ctx,
5449 "test.sparsebundle/Info.plist", NULL,
5450 0, strlen(info_plist), info_plist);
5451 torture_assert_goto(tctx, ok, ok, done, "write_stream failed\n");
5453 status = smb2_util_mkdir(tree, "test.sparsebundle/bands");
5454 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
5455 "smb2_util_mkdir\n");
5457 ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/1", false);
5458 torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
5460 ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/2", false);
5461 torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
5463 status = smb2_util_roothandle(tree, &h);
5464 torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
5466 ZERO_STRUCT(fsinfo);
5467 fsinfo.generic.level = RAW_QFS_SIZE_INFORMATION;
5468 fsinfo.generic.handle = h;
5470 status = smb2_getinfo_fs(tree, tree, &fsinfo);
5471 torture_assert_ntstatus_ok(tctx, status, "smb2_getinfo_fs failed");
5473 torture_comment(tctx, "sectors_per_unit: %" PRIu32"\n"
5474 "bytes_per_sector: %" PRIu32"\n"
5475 "total_alloc_units: %" PRIu64"\n"
5476 "avail_alloc_units: %" PRIu64"\n",
5477 fsinfo.size_info.out.sectors_per_unit,
5478 fsinfo.size_info.out.bytes_per_sector,
5479 fsinfo.size_info.out.total_alloc_units,
5480 fsinfo.size_info.out.avail_alloc_units);
5483 * Let me explain the numbers:
5485 * - the share is set to "fruit:time machine max size = 32K"
5486 * - we've faked a bandsize of 8 K in the Info.plist file
5487 * - we've created two bands files
5488 * - one allocation unit is made of two sectors with 512 B each
5489 * => we've consumed 16 allocation units, there should be 16 free
5492 torture_assert_goto(tctx, fsinfo.size_info.out.sectors_per_unit == 2,
5493 ok, done, "Bad sectors_per_unit");
5495 torture_assert_goto(tctx, fsinfo.size_info.out.bytes_per_sector == 512,
5496 ok, done, "Bad bytes_per_sector");
5498 torture_assert_goto(tctx, fsinfo.size_info.out.total_alloc_units == 32,
5499 ok, done, "Bad total_alloc_units");
5501 torture_assert_goto(tctx, fsinfo.size_info.out.avail_alloc_units == 16,
5502 ok, done, "Bad avail_alloc_units");
5505 if (!smb2_util_handle_empty(h)) {
5506 smb2_util_close(tree, h);
5508 smb2_deltree(tree, "test.sparsebundle");
5509 talloc_free(mem_ctx);
5513 struct torture_suite *torture_vfs_fruit_timemachine(TALLOC_CTX *ctx)
5515 struct torture_suite *suite = torture_suite_create(
5516 ctx, "fruit_timemachine");
5518 suite->description = talloc_strdup(
5519 suite, "vfs_fruit tests for TimeMachine");
5521 torture_suite_add_1smb2_test(suite, "Timemachine-volsize",
5522 test_timemachine_volsize);
5527 static bool test_convert_xattr_and_empty_rfork_then_delete(
5528 struct torture_context *tctx,
5529 struct smb2_tree *tree1,
5530 struct smb2_tree *tree2)
5532 TALLOC_CTX *mem_ctx = talloc_new(tctx);
5533 const char *fname = BASEDIR "\\test_adouble_conversion";
5534 const char *adname = BASEDIR "/._test_adouble_conversion";
5535 const char *rfork = BASEDIR "\\test_adouble_conversion" AFPRESOURCE_STREAM_NAME;
5537 struct smb2_handle testdirh;
5539 const char *streams[] = {
5542 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
5543 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
5545 struct smb2_create create;
5546 struct smb2_find find;
5548 union smb_search_data *d;
5549 bool delete_empty_adfiles;
5550 int expected_num_files;
5552 delete_empty_adfiles = torture_setting_bool(tctx,
5553 "delete_empty_adfiles",
5556 smb2_deltree(tree1, BASEDIR);
5558 status = torture_smb2_testdir(tree1, BASEDIR, &testdirh);
5559 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5560 "torture_smb2_testdir failed\n");
5561 smb2_util_close(tree1, testdirh);
5563 ret = torture_setup_file(tctx, tree1, fname, false);
5564 torture_assert_goto(tctx, ret == true, ret, done,
5565 "torture_setup_file failed\n");
5567 ret = torture_setup_file(tctx, tree1, adname, false);
5568 torture_assert_goto(tctx, ret == true, ret, done,
5569 "torture_setup_file failed\n");
5571 ret = write_stream(tree1, __location__, tctx, mem_ctx,
5573 0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
5574 torture_assert_goto(tctx, ret == true, ret, done,
5575 "write_stream failed\n");
5577 ret = enable_aapl(tctx, tree2);
5578 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
5581 * Issue a smb2_find(), this triggers the server-side conversion
5584 create = (struct smb2_create) {
5585 .in.desired_access = SEC_RIGHTS_DIR_READ,
5586 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
5587 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
5588 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5589 .in.create_disposition = NTCREATEX_DISP_OPEN,
5590 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5591 .in.fname = BASEDIR,
5594 status = smb2_create(tree2, tctx, &create);
5595 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5596 "smb2_create failed\n");
5598 find = (struct smb2_find) {
5599 .in.file.handle = create.out.file.handle,
5601 .in.max_response_size = 0x1000,
5602 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
5605 status = smb2_find_level(tree2, tree2, &find, &count, &d);
5606 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5607 "smb2_find_level failed\n");
5609 status = smb2_util_close(tree2, create.out.file.handle);
5610 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5611 "smb2_util_close failed");
5614 * Check number of streams
5617 ret = check_stream_list(tree2, tctx, fname, 4, streams, false);
5618 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
5621 * Check Resource Fork is gone
5624 create = (struct smb2_create) {
5625 .in.desired_access = SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
5626 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
5627 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5628 .in.create_disposition = NTCREATEX_DISP_OPEN,
5629 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5633 status = smb2_create(tree2, mem_ctx, &create);
5634 torture_assert_ntstatus_equal_goto(
5635 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
5636 ret, done, "Bad smb2_create return\n");
5639 * Check xattr data has been migrated from the AppleDouble file to
5643 ret = check_stream(tree2, __location__, tctx, mem_ctx,
5644 fname, AFPINFO_STREAM,
5645 0, 60, 16, 8, "TESTSLOW");
5646 torture_assert_goto(tctx, ret == true, ret, done,
5647 "check AFPINFO_STREAM failed\n");
5649 ret = check_stream(tree2, __location__, tctx, mem_ctx,
5650 fname, ":foo" "\xef\x80\xa2" "bar", /* foo:bar */
5652 torture_assert_goto(tctx, ret == true, ret, done,
5653 "check foo stream failed\n");
5656 * Now check number of files. If delete_empty_adfiles is set, the
5657 * AppleDouble files should have been deleted.
5660 create = (struct smb2_create) {
5661 .in.desired_access = SEC_RIGHTS_DIR_READ,
5662 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
5663 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
5664 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
5665 .in.create_disposition = NTCREATEX_DISP_OPEN,
5666 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
5667 .in.fname = BASEDIR,
5670 status = smb2_create(tree2, tctx, &create);
5671 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5672 "smb2_create failed\n");
5674 find = (struct smb2_find) {
5675 .in.file.handle = create.out.file.handle,
5677 .in.max_response_size = 0x1000,
5678 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
5681 status = smb2_find_level(tree2, tree2, &find, &count, &d);
5682 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5683 "smb2_find_level failed\n");
5685 status = smb2_util_close(tree2, create.out.file.handle);
5686 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5687 "smb2_util_close failed");
5689 if (delete_empty_adfiles) {
5690 expected_num_files = 3;
5692 expected_num_files = 4;
5694 torture_assert_int_equal_goto(tctx, count, expected_num_files, ret, done,
5695 "Wrong number of files\n");
5698 smb2_deltree(tree1, BASEDIR);
5699 talloc_free(mem_ctx);
5703 struct torture_suite *torture_vfs_fruit_conversion(TALLOC_CTX *ctx)
5705 struct torture_suite *suite = torture_suite_create(
5706 ctx, "fruit_conversion");
5708 suite->description = talloc_strdup(
5709 suite, "vfs_fruit conversion tests");
5711 torture_suite_add_2ns_smb2_test(
5712 suite, "convert_xattr_and_empty_rfork_then_delete",
5713 test_convert_xattr_and_empty_rfork_then_delete);