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"
40 #define BASEDIR "vfs_fruit_dir"
41 #define FNAME_CC_SRC "testfsctl.dat"
42 #define FNAME_CC_DST "testfsctl2.dat"
44 #define CHECK_STATUS(status, correct) do { \
45 if (!NT_STATUS_EQUAL(status, correct)) { \
46 torture_result(tctx, TORTURE_FAIL, \
47 "(%s) Incorrect status %s - should be %s\n", \
48 __location__, nt_errstr(status), nt_errstr(correct)); \
53 #define CHECK_VALUE(v, correct) do { \
54 if ((v) != (correct)) { \
55 torture_result(tctx, TORTURE_FAIL, \
56 "(%s) Incorrect value %s=%u - should be %u\n", \
57 __location__, #v, (unsigned)v, (unsigned)correct); \
62 static bool check_stream_list(struct smb2_tree *tree,
63 struct torture_context *tctx,
69 static int qsort_string(char * const *s1, char * const *s2)
71 return strcmp(*s1, *s2);
74 static int qsort_stream(const struct stream_struct * s1, const struct stream_struct *s2)
76 return strcmp(s1->stream_name.s, s2->stream_name.s);
81 * This is hokey, but what else can we do?
83 #if defined(HAVE_ATTROPEN) || defined(FREEBSD)
84 #define AFPINFO_EA_NETATALK "org.netatalk.Metadata"
85 #define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork"
87 #define AFPINFO_EA_NETATALK "user.org.netatalk.Metadata"
88 #define AFPRESOURCE_EA_NETATALK "user.org.netatalk.ResourceFork"
92 The metadata xattr char buf below contains the following attributes:
94 -------------------------------------------------------------------------------
95 Entry ID : 00000008 : File Dates Info
96 Offset : 00000162 : 354
97 Length : 00000010 : 16
99 -DATE------: : (GMT) : (Local)
100 create : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
101 modify : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
102 backup : 80000000 : Unknown or Initial
103 access : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
105 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
106 00000000 : 1B 44 21 69 1B 44 21 69 80 00 00 00 1B 44 21 69 : .D!i.D!i.....D!i
108 -------------------------------------------------------------------------------
109 Entry ID : 00000009 : Finder Info
110 Offset : 0000007A : 122
111 Length : 00000020 : 32
114 Type : 42415252 : BARR
115 Creator : 464F4F4F : FOOO
130 Location v : 0000 : 0
131 Location h : 0000 : 0
135 Rsvd|IconID: 0000 : 0
155 Rsvd|commnt: 0000 : 0
156 PutAway : 00000000 : 0
158 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
159 00000000 : 42 41 52 52 46 4F 4F 4F 40 00 00 00 00 00 00 00 : BARRFOOO@.......
160 00000010 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
162 -------------------------------------------------------------------------------
163 Entry ID : 0000000E : AFP File Info
164 Offset : 00000172 : 370
165 Length : 00000004 : 4
167 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
168 00000000 : 00 00 01 A1 : ....
171 char metadata_xattr[] = {
172 0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
176 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x08, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00,
178 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
179 0x00, 0x7a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
180 0x00, 0x0e, 0x00, 0x00, 0x01, 0x72, 0x00, 0x00,
181 0x00, 0x04, 0x80, 0x44, 0x45, 0x56, 0x00, 0x00,
182 0x01, 0x76, 0x00, 0x00, 0x00, 0x08, 0x80, 0x49,
183 0x4e, 0x4f, 0x00, 0x00, 0x01, 0x7e, 0x00, 0x00,
184 0x00, 0x08, 0x80, 0x53, 0x59, 0x4e, 0x00, 0x00,
185 0x01, 0x86, 0x00, 0x00, 0x00, 0x08, 0x80, 0x53,
186 0x56, 0x7e, 0x00, 0x00, 0x01, 0x8e, 0x00, 0x00,
187 0x00, 0x04, 0x42, 0x41, 0x52, 0x52, 0x46, 0x4f,
188 0x4f, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 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, 0x1b, 0x44, 0x21, 0x69, 0x1b, 0x44,
217 0x21, 0x69, 0x80, 0x00, 0x00, 0x00, 0x1b, 0x44,
218 0x21, 0x69, 0x00, 0x00, 0x01, 0xa1, 0x00, 0xfd,
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x20,
220 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xe3,
221 0x86, 0x53, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x01,
226 The buf below contains the following AppleDouble encoded data:
228 -------------------------------------------------------------------------------
229 MagicNumber: 00051607 : AppleDouble
230 Version : 00020000 : Version 2
231 Filler : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
232 Num. of ent: 0002 : 2
234 -------------------------------------------------------------------------------
235 Entry ID : 00000009 : Finder Info
236 Offset : 00000032 : 50
237 Length : 00000EB0 : 3760
240 Type : 54455354 : TEST
241 Creator : 534C4F57 : SLOW
256 Location v : 0000 : 0
257 Location h : 0000 : 0
261 Rsvd|IconID: 0000 : 0
281 Rsvd|commnt: 0000 : 0
282 PutAway : 00000000 : 0
286 magic : 41545452 : ATTR
287 debug_tag : 53D4580C : 1406425100
288 total_size : 00000EE2 : 3810
289 data_start : 000000BC : 188
290 data_length: 0000005E : 94
291 reserved[0]: 00000000 : ....
292 reserved[1]: 00000000 : ....
293 reserved[2]: 00000000 : ....
297 offset : 000000BC : 188
298 length : 0000005B : 91
301 -EA NAME---: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
302 00000000 : 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 61 : com.apple.metada
303 00000010 : 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 54 : ta:_kMDItemUserT
304 00000020 : 61 67 73 00 : ags.
305 -EA VALUE--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
306 00000000 : 62 70 6C 69 73 74 30 30 A5 01 02 03 04 05 54 74 : bplist00......Tt
307 00000010 : 65 73 74 66 00 47 00 72 00 FC 00 6E 00 0A 00 32 : estf.G.r...n...2
308 00000020 : 56 4C 69 6C 61 0A 33 56 47 65 6C 62 0A 35 56 42 : VLila.3VGelb.5VB
309 00000030 : 6C 61 75 0A 34 08 0E 13 20 27 2E 00 00 00 00 00 : lau.4... '......
310 00000040 : 00 01 01 00 00 00 00 00 00 00 06 00 00 00 00 00 : ................
311 00000050 : 00 00 00 00 00 00 00 00 00 00 35 : ..........5
313 offset : 00000117 : 279
314 length : 00000003 : 3
317 -EA NAME---: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
318 00000000 : 66 6F 6F 3A 62 61 72 00 : foo:bar.
319 -EA VALUE--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
320 00000000 : 62 61 7A : baz
322 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
323 00000000 : 54 45 53 54 53 4C 4F 57 00 08 00 00 00 00 00 00 : TESTSLOW........
324 00000010 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
325 00000020 : 00 00 41 54 54 52 53 D4 58 0C 00 00 0E E2 00 00 : ..ATTRS.X.......
326 00000030 : 00 BC 00 00 00 5E 00 00 00 00 00 00 00 00 00 00 : .....^..........
327 00000040 : 00 00 00 00 00 02 00 00 00 BC 00 00 00 5B 00 00 : .............[..
328 00000050 : 24 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 : $com.apple.metad
329 00000060 : 61 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 : ata:_kMDItemUser
330 00000070 : 54 61 67 73 00 00 00 00 01 17 00 00 00 03 00 00 : Tags............
331 00000080 : 08 66 6F 6F 3A 62 61 72 00 66 62 70 6C 69 73 74 : .foo:bar.fbplist
332 00000090 : 30 30 A5 01 02 03 04 05 54 74 65 73 74 66 00 47 : 00......Ttestf.G
333 000000A0 : 00 72 00 FC 00 6E 00 0A 00 32 56 4C 69 6C 61 0A : .r...n...2VLila.
334 000000B0 : 33 56 47 65 6C 62 0A 35 56 42 6C 61 75 0A 34 08 : 3VGelb.5VBlau.4.
335 000000C0 : 0E 13 20 27 2E 00 00 00 00 00 00 01 01 00 00 00 : .. '............
336 000000D0 : 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 : ................
337 000000E0 : 00 00 00 00 35 62 61 7A 00 00 00 00 00 00 00 00 : ....5baz........
338 000000F0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
340 00000EA0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
342 -------------------------------------------------------------------------------
343 Entry ID : 00000002 : Resource Fork
344 Offset : 00000EE2 : 3810
345 Length : 0000011E : 286
347 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
348 00000000 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
349 00000010 : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo
350 00000020 : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
351 00000030 : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 : left blank ..
352 00000040 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
353 00000050 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
354 00000060 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
355 00000070 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
356 00000080 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
357 00000090 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
358 000000A0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
359 000000B0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
360 000000C0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
361 000000D0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
362 000000E0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
363 000000F0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
364 00000100 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
365 00000110 : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF : ..............
368 $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
370 static char osx_adouble_w_xattr[] = {
371 0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
372 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
373 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
374 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
375 0x00, 0x32, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00,
376 0x00, 0x02, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00,
377 0x01, 0x1e, 0x54, 0x45, 0x53, 0x54, 0x53, 0x4c,
378 0x4f, 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
382 0x53, 0xd4, 0x58, 0x0c, 0x00, 0x00, 0x0e, 0xe2,
383 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5e,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
386 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5b,
387 0x00, 0x00, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
388 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x65, 0x74,
389 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x5f, 0x6b,
390 0x4d, 0x44, 0x49, 0x74, 0x65, 0x6d, 0x55, 0x73,
391 0x65, 0x72, 0x54, 0x61, 0x67, 0x73, 0x00, 0x00,
392 0x00, 0x00, 0x01, 0x17, 0x00, 0x00, 0x00, 0x03,
393 0x00, 0x00, 0x08, 0x66, 0x6f, 0x6f, 0x3a, 0x62,
394 0x61, 0x72, 0x00, 0x66, 0x62, 0x70, 0x6c, 0x69,
395 0x73, 0x74, 0x30, 0x30, 0xa5, 0x01, 0x02, 0x03,
396 0x04, 0x05, 0x54, 0x74, 0x65, 0x73, 0x74, 0x66,
397 0x00, 0x47, 0x00, 0x72, 0x00, 0xfc, 0x00, 0x6e,
398 0x00, 0x0a, 0x00, 0x32, 0x56, 0x4c, 0x69, 0x6c,
399 0x61, 0x0a, 0x33, 0x56, 0x47, 0x65, 0x6c, 0x62,
400 0x0a, 0x35, 0x56, 0x42, 0x6c, 0x61, 0x75, 0x0a,
401 0x34, 0x08, 0x0e, 0x13, 0x20, 0x27, 0x2e, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x62,
406 0x61, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0x00, 0x00, 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, 0x01, 0x00, 0x00, 0x00,
848 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
849 0x00, 0x1e, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72,
850 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20,
851 0x66, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
852 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
853 0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
854 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
855 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
856 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x01, 0x00, 0x00, 0x00,
880 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
881 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
882 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
886 * talloc and intialize an AfpInfo
888 static AfpInfo *torture_afpinfo_new(TALLOC_CTX *mem_ctx)
892 info = talloc_zero(mem_ctx, AfpInfo);
897 info->afpi_Signature = AFP_Signature;
898 info->afpi_Version = AFP_Version;
899 info->afpi_BackupTime = AFP_BackupTime;
905 * Pack AfpInfo into a talloced buffer
907 static char *torture_afpinfo_pack(TALLOC_CTX *mem_ctx,
912 buf = talloc_array(mem_ctx, char, AFP_INFO_SIZE);
917 RSIVAL(buf, 0, info->afpi_Signature);
918 RSIVAL(buf, 4, info->afpi_Version);
919 RSIVAL(buf, 12, info->afpi_BackupTime);
920 memcpy(buf + 16, info->afpi_FinderInfo, sizeof(info->afpi_FinderInfo));
929 static void torture_afpinfo_unpack(AfpInfo *info, char *data)
931 info->afpi_Signature = RIVAL(data, 0);
932 info->afpi_Version = RIVAL(data, 4);
933 info->afpi_BackupTime = RIVAL(data, 12);
934 memcpy(info->afpi_FinderInfo, (const char *)data + 16,
935 sizeof(info->afpi_FinderInfo));
939 static bool torture_write_afpinfo(struct smb2_tree *tree,
940 struct torture_context *tctx,
945 struct smb2_handle handle;
946 struct smb2_create io;
948 const char *full_name;
952 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, AFPINFO_STREAM_NAME);
953 if (full_name == NULL) {
954 torture_comment(tctx, "talloc_asprintf error\n");
958 io.in.desired_access = SEC_FILE_WRITE_DATA;
959 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
960 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
961 io.in.create_options = 0;
962 io.in.fname = full_name;
964 status = smb2_create(tree, mem_ctx, &io);
965 CHECK_STATUS(status, NT_STATUS_OK);
967 handle = io.out.file.handle;
969 infobuf = torture_afpinfo_pack(mem_ctx, info);
970 if (infobuf == NULL) {
974 status = smb2_util_write(tree, handle, infobuf, 0, AFP_INFO_SIZE);
975 CHECK_STATUS(status, NT_STATUS_OK);
977 smb2_util_close(tree, handle);
984 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
985 * compare against buffer 'value'
987 static bool check_stream(struct smb2_tree *tree,
988 const char *location,
989 struct torture_context *tctx,
999 struct smb2_handle handle;
1000 struct smb2_create create;
1006 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1007 if (full_name == NULL) {
1008 torture_comment(tctx, "talloc_asprintf error\n");
1011 ZERO_STRUCT(create);
1012 create.in.desired_access = SEC_FILE_READ_DATA;
1013 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1014 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1015 create.in.fname = full_name;
1017 torture_comment(tctx, "Open stream %s\n", full_name);
1019 status = smb2_create(tree, mem_ctx, &create);
1020 if (!NT_STATUS_IS_OK(status)) {
1021 TALLOC_FREE(full_name);
1022 if (value == NULL) {
1025 torture_comment(tctx, "Unable to open stream %s\n", full_name);
1029 handle = create.out.file.handle;
1030 if (value == NULL) {
1031 TALLOC_FREE(full_name);
1032 smb2_util_close(tree, handle);
1037 r.in.file.handle = handle;
1038 r.in.length = read_count;
1039 r.in.offset = read_offset;
1041 status = smb2_read(tree, tree, &r);
1043 torture_assert_ntstatus_ok_goto(
1044 tctx, status, ret, done,
1045 talloc_asprintf(tctx, "(%s) Failed to read %lu bytes from stream '%s'\n",
1046 location, (long)strlen(value), full_name));
1048 torture_assert_goto(tctx, r.out.data.length == read_count, ret, done,
1049 talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected %jd\n",
1050 (intmax_t)r.out.data.length, (intmax_t)read_count));
1052 torture_assert_goto(
1053 tctx, memcmp(r.out.data.data + comp_offset, value, comp_count) == 0,
1055 talloc_asprintf(tctx, "(%s) Bad data in stream\n", location));
1058 TALLOC_FREE(full_name);
1059 smb2_util_close(tree, handle);
1064 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1065 * compare against buffer 'value'
1067 static ssize_t read_stream(struct smb2_tree *tree,
1068 const char *location,
1069 struct torture_context *tctx,
1070 TALLOC_CTX *mem_ctx,
1076 struct smb2_handle handle;
1077 struct smb2_create create;
1080 const char *full_name;
1083 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1084 if (full_name == NULL) {
1085 torture_comment(tctx, "talloc_asprintf error\n");
1088 ZERO_STRUCT(create);
1089 create.in.desired_access = SEC_FILE_READ_DATA;
1090 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1091 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1092 create.in.fname = full_name;
1094 torture_comment(tctx, "Open stream %s\n", full_name);
1096 status = smb2_create(tree, mem_ctx, &create);
1097 if (!NT_STATUS_IS_OK(status)) {
1098 torture_comment(tctx, "Unable to open stream %s\n",
1103 handle = create.out.file.handle;
1106 r.in.file.handle = handle;
1107 r.in.length = read_count;
1108 r.in.offset = read_offset;
1110 status = smb2_read(tree, tree, &r);
1111 if (!NT_STATUS_IS_OK(status)) {
1112 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
1115 smb2_util_close(tree, handle);
1121 return r.out.data.length;
1125 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1126 * compare against buffer 'value'
1128 static bool write_stream(struct smb2_tree *tree,
1129 const char *location,
1130 struct torture_context *tctx,
1131 TALLOC_CTX *mem_ctx,
1138 struct smb2_handle handle;
1139 struct smb2_create create;
1141 const char *full_name;
1143 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname ? sname : "");
1144 if (full_name == NULL) {
1145 torture_comment(tctx, "talloc_asprintf error\n");
1148 ZERO_STRUCT(create);
1149 create.in.desired_access = SEC_FILE_WRITE_DATA;
1150 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1151 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1152 create.in.fname = full_name;
1154 status = smb2_create(tree, mem_ctx, &create);
1155 if (!NT_STATUS_IS_OK(status)) {
1156 if (value == NULL) {
1159 torture_comment(tctx, "Unable to open stream %s\n",
1166 handle = create.out.file.handle;
1167 if (value == NULL) {
1171 status = smb2_util_write(tree, handle, value, offset, size);
1173 if (!NT_STATUS_IS_OK(status)) {
1174 torture_comment(tctx, "(%s) Failed to write %lu bytes to "
1175 "stream '%s'\n", location, (long)size, full_name);
1179 smb2_util_close(tree, handle);
1183 static bool torture_setup_local_xattr(struct torture_context *tctx,
1184 const char *path_option,
1187 const char *metadata,
1195 spath = torture_setting_string(tctx, path_option, NULL);
1196 if (spath == NULL) {
1197 printf("No sharepath for option %s\n", path_option);
1201 path = talloc_asprintf(tctx, "%s/%s", spath, name);
1203 result = setxattr(path, xattr, metadata, size, 0);
1214 * Create a file or directory
1216 static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree,
1217 const char *name, bool dir)
1219 struct smb2_create io;
1222 smb2_util_unlink(tree, name);
1224 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1225 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1226 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1227 io.in.share_access =
1228 NTCREATEX_SHARE_ACCESS_DELETE|
1229 NTCREATEX_SHARE_ACCESS_READ|
1230 NTCREATEX_SHARE_ACCESS_WRITE;
1231 io.in.create_options = 0;
1234 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1235 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
1236 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1237 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1240 status = smb2_create(tree, mem_ctx, &io);
1241 if (!NT_STATUS_IS_OK(status)) {
1245 status = smb2_util_close(tree, io.out.file.handle);
1246 if (!NT_STATUS_IS_OK(status)) {
1253 static bool enable_aapl(struct torture_context *tctx,
1254 struct smb2_tree *tree)
1256 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1259 struct smb2_create io;
1261 struct smb2_create_blob *aapl = NULL;
1262 uint32_t aapl_server_caps;
1263 uint32_t expexted_scaps = (SMB2_CRTCTX_AAPL_UNIX_BASED |
1264 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1265 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1266 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
1267 bool is_osx_server = torture_setting_bool(tctx, "osx", false);
1270 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1271 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1272 io.in.create_disposition = NTCREATEX_DISP_OPEN;
1273 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1274 NTCREATEX_SHARE_ACCESS_READ |
1275 NTCREATEX_SHARE_ACCESS_WRITE);
1279 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1280 * controls behaviour of Apple's SMB2 extensions for the whole
1284 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1285 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1286 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1287 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1288 SMB2_CRTCTX_AAPL_MODEL_INFO));
1289 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1290 SMB2_CRTCTX_AAPL_UNIX_BASED |
1291 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1293 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1294 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_blob_add");
1296 status = smb2_create(tree, tctx, &io);
1297 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1299 status = smb2_util_close(tree, io.out.file.handle);
1300 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close");
1303 * Now check returned AAPL context
1305 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1307 aapl = smb2_create_blob_find(&io.out.blobs,
1308 SMB2_CREATE_TAG_AAPL);
1309 torture_assert_goto(tctx, aapl != NULL, ret, done, "missing AAPL context");
1311 if (!is_osx_server) {
1312 size_t exptected_aapl_ctx_size;
1314 exptected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
1316 torture_assert_goto(
1317 tctx, aapl->data.length == exptected_aapl_ctx_size,
1318 ret, done, "bad AAPL size");
1321 aapl_server_caps = BVAL(aapl->data.data, 16);
1322 torture_assert_goto(tctx, aapl_server_caps == expexted_scaps,
1323 ret, done, "bad AAPL caps");
1326 talloc_free(mem_ctx);
1330 static bool test_read_netatalk_metadata(struct torture_context *tctx,
1331 struct smb2_tree *tree)
1333 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1334 const char *fname = BASEDIR "\\torture_read_metadata";
1336 struct smb2_handle testdirh;
1339 const char *localdir = NULL;
1341 torture_comment(tctx, "Checking metadata access\n");
1343 localdir = torture_setting_string(tctx, "localdir", NULL);
1344 if (localdir == NULL) {
1345 torture_skip(tctx, "Need localdir for test");
1348 smb2_util_unlink(tree, fname);
1350 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1351 CHECK_STATUS(status, NT_STATUS_OK);
1352 smb2_util_close(tree, testdirh);
1354 ret = torture_setup_file(mem_ctx, tree, fname, false);
1359 ret = torture_setup_local_xattr(tctx, "localdir",
1360 BASEDIR "/torture_read_metadata",
1361 AFPINFO_EA_NETATALK,
1362 metadata_xattr, sizeof(metadata_xattr));
1367 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1368 0, 60, 0, 4, "AFP");
1369 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1371 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1372 0, 60, 16, 8, "BARRFOOO");
1373 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1375 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1376 16, 8, 0, 3, "AFP");
1377 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1379 /* Check reading offset and read size > sizeof(AFPINFO_STREAM) */
1381 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1382 AFPINFO_STREAM, 0, 61);
1383 CHECK_VALUE(len, 60);
1385 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1386 AFPINFO_STREAM, 59, 2);
1387 CHECK_VALUE(len, 2);
1389 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1390 AFPINFO_STREAM, 60, 1);
1391 CHECK_VALUE(len, 1);
1393 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1394 AFPINFO_STREAM, 61, 1);
1395 CHECK_VALUE(len, 0);
1398 smb2_deltree(tree, BASEDIR);
1399 talloc_free(mem_ctx);
1403 static bool test_read_afpinfo(struct torture_context *tctx,
1404 struct smb2_tree *tree)
1406 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1407 const char *fname = BASEDIR "\\torture_read_metadata";
1409 struct smb2_handle testdirh;
1413 const char *type_creator = "SMB,OLE!";
1415 torture_comment(tctx, "Checking metadata access\n");
1417 smb2_util_unlink(tree, fname);
1419 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1420 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
1421 smb2_util_close(tree, testdirh);
1423 ret = torture_setup_file(mem_ctx, tree, fname, false);
1424 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
1426 info = torture_afpinfo_new(mem_ctx);
1427 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
1429 memcpy(info->afpi_FinderInfo, type_creator, 8);
1430 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1431 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
1433 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1434 0, 60, 0, 4, "AFP");
1435 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1437 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1438 0, 60, 16, 8, type_creator);
1439 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1442 * OS X ignores offset <= 60 and treats the as
1443 * offset=0. Reading from offsets > 60 returns EOF=0.
1446 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1447 16, 8, 0, 8, "AFP\0\0\0\001\0");
1448 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1450 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1451 AFPINFO_STREAM, 0, 61);
1452 torture_assert_goto(tctx, len == 60, ret, done, "read_stream failed");
1454 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1455 AFPINFO_STREAM, 59, 2);
1456 torture_assert_goto(tctx, len == 2, ret, done, "read_stream failed");
1458 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1460 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1462 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1463 AFPINFO_STREAM, 60, 1);
1464 torture_assert_goto(tctx, len == 1, ret, done, "read_stream failed");
1466 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1468 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1470 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1471 AFPINFO_STREAM, 61, 1);
1472 torture_assert_goto(tctx, len == 0, ret, done, "read_stream failed");
1475 smb2_util_unlink(tree, fname);
1476 smb2_deltree(tree, BASEDIR);
1477 talloc_free(mem_ctx);
1481 static bool test_write_atalk_metadata(struct torture_context *tctx,
1482 struct smb2_tree *tree)
1484 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1485 const char *fname = BASEDIR "\\torture_write_metadata";
1486 const char *type_creator = "SMB,OLE!";
1488 struct smb2_handle testdirh;
1492 smb2_deltree(tree, BASEDIR);
1493 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1494 CHECK_STATUS(status, NT_STATUS_OK);
1495 smb2_util_close(tree, testdirh);
1497 ret = torture_setup_file(mem_ctx, tree, fname, false);
1502 info = torture_afpinfo_new(mem_ctx);
1507 memcpy(info->afpi_FinderInfo, type_creator, 8);
1508 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1509 ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1510 0, 60, 16, 8, type_creator);
1513 smb2_util_unlink(tree, fname);
1514 smb2_deltree(tree, BASEDIR);
1515 talloc_free(mem_ctx);
1519 static bool test_write_atalk_rfork_io(struct torture_context *tctx,
1520 struct smb2_tree *tree)
1522 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1523 const char *fname = BASEDIR "\\torture_write_rfork_io";
1524 const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
1525 const char *rfork_content = "1234567890";
1527 struct smb2_handle testdirh;
1531 struct smb2_handle filehandle;
1532 union smb_fileinfo finfo;
1533 union smb_setfileinfo sinfo;
1535 smb2_util_unlink(tree, fname);
1537 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1538 CHECK_STATUS(status, NT_STATUS_OK);
1539 smb2_util_close(tree, testdirh);
1541 ret = torture_setup_file(mem_ctx, tree, fname, false);
1546 torture_comment(tctx, "(%s) writing to resource fork\n",
1549 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1550 fname, AFPRESOURCE_STREAM_NAME,
1551 10, 10, rfork_content);
1553 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1554 fname, AFPRESOURCE_STREAM_NAME,
1555 0, 20, 10, 10, rfork_content);
1557 /* Check size after write */
1560 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1561 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1562 SEC_FILE_WRITE_ATTRIBUTE;
1563 io.smb2.in.fname = rfork;
1564 status = smb2_create(tree, mem_ctx, &(io.smb2));
1565 CHECK_STATUS(status, NT_STATUS_OK);
1566 filehandle = io.smb2.out.file.handle;
1568 torture_comment(tctx, "(%s) check resource fork size after write\n",
1572 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1573 finfo.generic.in.file.handle = filehandle;
1574 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1575 CHECK_STATUS(status, NT_STATUS_OK);
1576 if (finfo.all_info.out.size != 20) {
1577 torture_result(tctx, TORTURE_FAIL,
1578 "(%s) Incorrect resource fork size\n",
1581 smb2_util_close(tree, filehandle);
1584 smb2_util_close(tree, filehandle);
1586 /* Write at large offset */
1588 torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
1591 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1592 fname, AFPRESOURCE_STREAM_NAME,
1593 (off_t)1<<32, 10, rfork_content);
1595 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1596 fname, AFPRESOURCE_STREAM_NAME,
1597 (off_t)1<<32, 10, 0, 10, rfork_content);
1599 /* Truncate back to size of 1 byte */
1601 torture_comment(tctx, "(%s) truncate resource fork and check size\n",
1605 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1606 io.smb2.in.desired_access = SEC_FILE_ALL;
1607 io.smb2.in.fname = rfork;
1608 status = smb2_create(tree, mem_ctx, &(io.smb2));
1609 CHECK_STATUS(status, NT_STATUS_OK);
1610 filehandle = io.smb2.out.file.handle;
1613 sinfo.end_of_file_info.level =
1614 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1615 sinfo.end_of_file_info.in.file.handle = filehandle;
1616 sinfo.end_of_file_info.in.size = 1;
1617 status = smb2_setinfo_file(tree, &sinfo);
1618 CHECK_STATUS(status, NT_STATUS_OK);
1620 smb2_util_close(tree, filehandle);
1622 /* Now check size */
1624 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1625 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1626 SEC_FILE_WRITE_ATTRIBUTE;
1627 io.smb2.in.fname = rfork;
1628 status = smb2_create(tree, mem_ctx, &(io.smb2));
1629 CHECK_STATUS(status, NT_STATUS_OK);
1630 filehandle = io.smb2.out.file.handle;
1633 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1634 finfo.generic.in.file.handle = filehandle;
1635 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1636 CHECK_STATUS(status, NT_STATUS_OK);
1637 if (finfo.all_info.out.size != 1) {
1638 torture_result(tctx, TORTURE_FAIL,
1639 "(%s) Incorrect resource fork size\n",
1642 smb2_util_close(tree, filehandle);
1645 smb2_util_close(tree, filehandle);
1648 smb2_util_unlink(tree, fname);
1649 smb2_deltree(tree, BASEDIR);
1650 talloc_free(mem_ctx);
1654 static bool test_rfork_truncate(struct torture_context *tctx,
1655 struct smb2_tree *tree)
1657 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1658 const char *fname = BASEDIR "\\torture_rfork_truncate";
1659 const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
1660 const char *rfork_content = "1234567890";
1662 struct smb2_handle testdirh;
1664 struct smb2_create create;
1665 struct smb2_handle fh1, fh2, fh3;
1666 union smb_setfileinfo sinfo;
1668 smb2_util_unlink(tree, fname);
1670 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1671 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1672 smb2_util_close(tree, testdirh);
1674 ret = torture_setup_file(mem_ctx, tree, fname, false);
1679 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1680 fname, AFPRESOURCE_STREAM,
1681 10, 10, rfork_content);
1683 /* Truncate back to size 0, further access MUST return ENOENT */
1685 torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
1688 ZERO_STRUCT(create);
1689 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1690 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1691 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1692 create.in.fname = fname;
1693 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1694 NTCREATEX_SHARE_ACCESS_READ |
1695 NTCREATEX_SHARE_ACCESS_WRITE;
1696 status = smb2_create(tree, mem_ctx, &create);
1697 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1698 fh1 = create.out.file.handle;
1700 ZERO_STRUCT(create);
1701 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1702 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1703 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1704 create.in.fname = rfork;
1705 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1706 NTCREATEX_SHARE_ACCESS_READ |
1707 NTCREATEX_SHARE_ACCESS_WRITE;
1708 status = smb2_create(tree, mem_ctx, &create);
1709 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1710 fh2 = create.out.file.handle;
1713 sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1714 sinfo.end_of_file_info.in.file.handle = fh2;
1715 sinfo.end_of_file_info.in.size = 0;
1716 status = smb2_setinfo_file(tree, &sinfo);
1717 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
1720 * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
1722 ZERO_STRUCT(create);
1723 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1724 create.in.desired_access = SEC_FILE_ALL;
1725 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1726 create.in.fname = rfork;
1727 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1728 NTCREATEX_SHARE_ACCESS_READ |
1729 NTCREATEX_SHARE_ACCESS_WRITE;
1730 status = smb2_create(tree, mem_ctx, &create);
1731 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1734 * Do another open on the rfork and write to the new handle. A
1735 * naive server might unlink the AppleDouble resource fork
1736 * file when its truncated to 0 bytes above, so in case both
1737 * open handles share the same underlying fd, the unlink would
1738 * cause the below write to be lost.
1740 ZERO_STRUCT(create);
1741 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1742 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1743 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1744 create.in.fname = rfork;
1745 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1746 NTCREATEX_SHARE_ACCESS_READ |
1747 NTCREATEX_SHARE_ACCESS_WRITE;
1748 status = smb2_create(tree, mem_ctx, &create);
1749 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1750 fh3 = create.out.file.handle;
1752 status = smb2_util_write(tree, fh3, "foo", 0, 3);
1753 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
1755 smb2_util_close(tree, fh3);
1756 smb2_util_close(tree, fh2);
1757 smb2_util_close(tree, fh1);
1759 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
1761 torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1764 smb2_util_unlink(tree, fname);
1765 smb2_deltree(tree, BASEDIR);
1766 talloc_free(mem_ctx);
1770 static bool test_rfork_create(struct torture_context *tctx,
1771 struct smb2_tree *tree)
1773 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1774 const char *fname = BASEDIR "\\torture_rfork_create";
1775 const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1777 struct smb2_handle testdirh;
1779 struct smb2_create create;
1780 struct smb2_handle fh1;
1781 const char *streams[] = {
1784 union smb_fileinfo finfo;
1786 smb2_util_unlink(tree, fname);
1788 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1789 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1790 smb2_util_close(tree, testdirh);
1792 ret = torture_setup_file(mem_ctx, tree, fname, false);
1797 torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
1800 ZERO_STRUCT(create);
1801 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1802 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1803 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1804 create.in.fname = rfork;
1805 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1806 NTCREATEX_SHARE_ACCESS_READ |
1807 NTCREATEX_SHARE_ACCESS_WRITE;
1808 status = smb2_create(tree, mem_ctx, &create);
1809 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1811 torture_comment(tctx, "(%s) create resource fork\n", __location__);
1813 ZERO_STRUCT(create);
1814 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1815 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1816 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1817 create.in.fname = rfork;
1818 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1819 NTCREATEX_SHARE_ACCESS_READ |
1820 NTCREATEX_SHARE_ACCESS_WRITE;
1821 status = smb2_create(tree, mem_ctx, &create);
1822 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1823 fh1 = create.out.file.handle;
1825 torture_comment(tctx, "(%s) getinfo on create handle\n",
1829 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1830 finfo.generic.in.file.handle = fh1;
1831 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1832 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
1833 if (finfo.all_info.out.size != 0) {
1834 torture_result(tctx, TORTURE_FAIL,
1835 "(%s) Incorrect resource fork size\n",
1838 smb2_util_close(tree, fh1);
1842 torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
1845 ZERO_STRUCT(create);
1846 create.in.create_disposition = NTCREATEX_DISP_OPEN;
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_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1856 ret = check_stream_list(tree, tctx, fname, 1, streams, false);
1857 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
1859 torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
1862 ZERO_STRUCT(create);
1863 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1864 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1865 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1866 create.in.fname = rfork;
1867 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1868 NTCREATEX_SHARE_ACCESS_READ |
1869 NTCREATEX_SHARE_ACCESS_WRITE;
1870 status = smb2_create(tree, mem_ctx, &create);
1871 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1874 smb2_util_unlink(tree, fname);
1875 smb2_deltree(tree, BASEDIR);
1876 talloc_free(mem_ctx);
1880 static bool test_rfork_create_ro(struct torture_context *tctx,
1881 struct smb2_tree *tree)
1883 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1884 const char *fname = BASEDIR "\\torture_rfork_create";
1885 const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1887 struct smb2_handle testdirh;
1889 struct smb2_create create;
1891 smb2_util_unlink(tree, fname);
1892 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1893 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1894 "torture_smb2_testdir\n");
1895 smb2_util_close(tree, testdirh);
1897 ret = torture_setup_file(mem_ctx, tree, fname, false);
1902 torture_comment(tctx, "(%s) Try opening read-only with "
1903 "open_if create disposition, should return ENOENT\n",
1906 ZERO_STRUCT(create);
1907 create.in.fname = rfork;
1908 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1909 create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
1910 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1911 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
1912 status = smb2_create(tree, mem_ctx, &(create));
1913 torture_assert_ntstatus_equal_goto(tctx, status,
1914 NT_STATUS_OBJECT_NAME_NOT_FOUND,
1915 ret, done, "smb2_create failed\n");
1917 torture_comment(tctx, "(%s) Now write something to the "
1918 "rsrc stream, then the same open should succeed\n",
1921 ret = write_stream(tree, __location__, tctx, mem_ctx,
1922 fname, AFPRESOURCE_STREAM_NAME,
1924 torture_assert_goto(tctx, ret == true, ret, done,
1925 "write_stream failed\n");
1927 ret = check_stream(tree, __location__, tctx, mem_ctx,
1928 fname, AFPRESOURCE_STREAM,
1930 torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1932 ZERO_STRUCT(create);
1933 create.in.fname = rfork;
1934 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1935 create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
1936 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1937 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
1938 status = smb2_create(tree, mem_ctx, &(create));
1939 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1940 "smb2_create failed\n");
1942 smb2_util_close(tree, create.out.file.handle);
1945 smb2_util_unlink(tree, fname);
1946 smb2_deltree(tree, BASEDIR);
1947 talloc_free(mem_ctx);
1951 static bool test_adouble_conversion(struct torture_context *tctx,
1952 struct smb2_tree *tree)
1954 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1955 const char *fname = BASEDIR "\\test_adouble_conversion";
1956 const char *adname = BASEDIR "/._test_adouble_conversion";
1958 struct smb2_handle testdirh;
1960 const char *data = "This resource fork intentionally left blank";
1961 size_t datalen = strlen(data);
1962 const char *streams[] = {
1966 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
1967 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
1970 smb2_deltree(tree, BASEDIR);
1972 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1973 CHECK_STATUS(status, NT_STATUS_OK);
1974 smb2_util_close(tree, testdirh);
1976 ret = torture_setup_file(tctx, tree, fname, false);
1977 torture_assert_goto(tctx, ret == true, ret, done,
1978 "torture_setup_file failed\n");
1980 ret = torture_setup_file(tctx, tree, adname, false);
1981 torture_assert_goto(tctx, ret == true, ret, done,
1982 "torture_setup_file failed\n");
1984 ret = write_stream(tree, __location__, tctx, mem_ctx,
1986 0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
1987 torture_assert_goto(tctx, ret == true, ret, done,
1988 "write_stream failed\n");
1990 torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
1993 ret = check_stream(tree, __location__, tctx, mem_ctx,
1994 fname, AFPRESOURCE_STREAM,
1995 16, datalen, 0, datalen, data);
1996 torture_assert_goto(tctx, ret == true, ret, done,
1997 "check AFPRESOURCE_STREAM failed\n");
1999 ret = check_stream(tree, __location__, tctx, mem_ctx,
2000 fname, AFPINFO_STREAM,
2001 0, 60, 16, 8, "TESTSLOW");
2002 torture_assert_goto(tctx, ret == true, ret, done,
2003 "check AFPINFO_STREAM failed\n");
2005 ret = check_stream(tree, __location__, tctx, mem_ctx, fname,
2006 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2008 torture_assert_goto(tctx, ret == true, ret, done,
2009 "check foo:bar stream failed\n");
2011 ret = check_stream_list(tree, tctx, fname, 5, streams, false);
2012 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2015 smb2_deltree(tree, BASEDIR);
2016 talloc_free(mem_ctx);
2020 static bool test_aapl(struct torture_context *tctx,
2021 struct smb2_tree *tree)
2023 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2024 const char *fname = BASEDIR "\\test_aapl";
2026 struct smb2_handle testdirh;
2028 struct smb2_create io;
2030 struct smb2_create_blob *aapl = NULL;
2032 const char *type_creator = "SMB,OLE!";
2033 char type_creator_buf[9];
2035 uint32_t aapl_reply_bitmap;
2036 uint32_t aapl_server_caps;
2037 uint32_t aapl_vol_caps;
2041 union smb_search_data *d;
2044 smb2_deltree(tree, BASEDIR);
2046 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2047 CHECK_STATUS(status, NT_STATUS_OK);
2048 smb2_util_close(tree, testdirh);
2051 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2052 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2053 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2054 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2055 NTCREATEX_SHARE_ACCESS_READ |
2056 NTCREATEX_SHARE_ACCESS_WRITE);
2057 io.in.fname = fname;
2060 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
2061 * controls behaviour of Apple's SMB2 extensions for the whole
2065 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2066 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2067 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2068 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2069 SMB2_CRTCTX_AAPL_MODEL_INFO));
2070 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2071 SMB2_CRTCTX_AAPL_UNIX_BASED |
2072 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
2074 torture_comment(tctx, "Testing SMB2 create context AAPL\n");
2075 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2076 CHECK_STATUS(status, NT_STATUS_OK);
2078 status = smb2_create(tree, tctx, &io);
2079 CHECK_STATUS(status, NT_STATUS_OK);
2080 status = smb2_util_close(tree, io.out.file.handle);
2081 CHECK_STATUS(status, NT_STATUS_OK);
2084 * Now check returned AAPL context
2086 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
2088 aapl = smb2_create_blob_find(&io.out.blobs,
2089 SMB2_CREATE_TAG_AAPL);
2092 torture_result(tctx, TORTURE_FAIL,
2093 "(%s) unexpectedly no AAPL capabilities were returned.",
2099 if (aapl->data.length != 50) {
2101 * uint32_t CommandCode = kAAPL_SERVER_QUERY
2102 * uint32_t Reserved = 0;
2103 * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
2104 * kAAPL_VOLUME_CAPS |
2106 * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
2107 * kAAPL_SUPPORTS_OSX_COPYFILE;
2108 * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
2109 * kAAPL_CASE_SENSITIVE;
2110 * uint32_t Pad2 = 0;
2111 * uint32_t ModelStringLen = 10;
2112 * ucs2_t ModelString[5] = "Samba";
2114 torture_warning(tctx,
2115 "(%s) unexpected AAPL context length: %zd, expected 50",
2116 __location__, aapl->data.length);
2119 aapl_cmd = IVAL(aapl->data.data, 0);
2120 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2121 torture_result(tctx, TORTURE_FAIL,
2122 "(%s) unexpected cmd: %d",
2123 __location__, (int)aapl_cmd);
2128 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2129 if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2130 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2131 SMB2_CRTCTX_AAPL_MODEL_INFO)) {
2132 torture_result(tctx, TORTURE_FAIL,
2133 "(%s) unexpected reply_bitmap: %d",
2134 __location__, (int)aapl_reply_bitmap);
2139 aapl_server_caps = BVAL(aapl->data.data, 16);
2140 if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
2141 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2142 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
2143 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
2144 torture_result(tctx, TORTURE_FAIL,
2145 "(%s) unexpected server_caps: %d",
2146 __location__, (int)aapl_server_caps);
2151 aapl_vol_caps = BVAL(aapl->data.data, 24);
2152 if (aapl_vol_caps != 0) {
2153 /* this will fail on a case insensitive fs ... */
2154 torture_result(tctx, TORTURE_FAIL,
2155 "(%s) unexpected vol_caps: %d",
2156 __location__, (int)aapl_vol_caps);
2159 ret = convert_string_talloc(mem_ctx,
2160 CH_UTF16LE, CH_UNIX,
2161 aapl->data.data + 40, 10,
2164 torture_result(tctx, TORTURE_FAIL,
2165 "(%s) convert_string_talloc() failed",
2169 torture_comment(tctx, "Got server model: \"%s\"\n", model);
2172 * Now that Requested AAPL extensions are enabled, setup some
2173 * Mac files with metadata and resource fork
2175 ret = torture_setup_file(mem_ctx, tree, fname, false);
2177 torture_result(tctx, TORTURE_FAIL,
2178 "(%s) torture_setup_file() failed",
2183 info = torture_afpinfo_new(mem_ctx);
2185 torture_result(tctx, TORTURE_FAIL,
2186 "(%s) torture_afpinfo_new() failed",
2192 memcpy(info->afpi_FinderInfo, type_creator, 8);
2193 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2195 torture_result(tctx, TORTURE_FAIL,
2196 "(%s) torture_write_afpinfo() failed",
2201 ret = write_stream(tree, __location__, tctx, mem_ctx,
2202 fname, AFPRESOURCE_STREAM_NAME,
2205 torture_result(tctx, TORTURE_FAIL,
2206 "(%s) write_stream() failed",
2212 * Ok, file is prepared, now call smb2/find
2216 io.in.desired_access = SEC_RIGHTS_DIR_READ;
2217 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2218 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2219 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
2220 NTCREATEX_SHARE_ACCESS_WRITE |
2221 NTCREATEX_SHARE_ACCESS_DELETE);
2222 io.in.create_disposition = NTCREATEX_DISP_OPEN;
2223 io.in.fname = BASEDIR;
2224 status = smb2_create(tree, tctx, &io);
2225 CHECK_STATUS(status, NT_STATUS_OK);
2228 f.in.file.handle = io.out.file.handle;
2229 f.in.pattern = "test_aapl";
2230 f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
2231 f.in.max_response_size = 0x1000;
2232 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
2234 status = smb2_find_level(tree, tree, &f, &count, &d);
2235 CHECK_STATUS(status, NT_STATUS_OK);
2237 status = smb2_util_close(tree, io.out.file.handle);
2238 CHECK_STATUS(status, NT_STATUS_OK);
2240 if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2241 torture_result(tctx, TORTURE_FAIL,
2242 "(%s) write_stream() failed",
2248 if (d[0].id_both_directory_info.short_name.private_length != 24) {
2249 torture_result(tctx, TORTURE_FAIL,
2250 "(%s) bad short_name length %" PRIu32 ", expected 24",
2251 __location__, d[0].id_both_directory_info.short_name.private_length);
2256 torture_comment(tctx, "short_name buffer:\n");
2257 dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2260 * Extract data as specified by the AAPL extension:
2261 * - ea_size contains max_access
2262 * - short_name contains resource fork length + FinderInfo
2263 * - reserved2 contains the unix mode
2265 torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2266 d[0].id_both_directory_info.ea_size);
2268 rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2269 if (rfork_len != 3) {
2270 torture_result(tctx, TORTURE_FAIL,
2271 "(%s) expected resource fork length 3, got: %" PRIu64,
2272 __location__, rfork_len);
2277 memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2278 type_creator_buf[8] = 0;
2279 if (strcmp(type_creator, type_creator_buf) != 0) {
2280 torture_result(tctx, TORTURE_FAIL,
2281 "(%s) expected type/creator \"%s\" , got: %s",
2282 __location__, type_creator, type_creator_buf);
2288 smb2_util_unlink(tree, fname);
2289 smb2_deltree(tree, BASEDIR);
2290 talloc_free(mem_ctx);
2294 static uint64_t patt_hash(uint64_t off)
2299 static bool write_pattern(struct torture_context *torture,
2300 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2301 struct smb2_handle h, uint64_t off, uint64_t len,
2307 uint64_t io_sz = MIN(1024 * 64, len);
2313 torture_assert(torture, (len % 8) == 0, "invalid write len");
2315 buf = talloc_zero_size(mem_ctx, io_sz);
2316 torture_assert(torture, (buf != NULL), "no memory for file data buf");
2319 for (i = 0; i <= io_sz - 8; i += 8) {
2320 SBVAL(buf, i, patt_hash(patt_off));
2324 status = smb2_util_write(tree, h,
2326 torture_assert_ntstatus_ok(torture, status, "file write");
2337 static bool check_pattern(struct torture_context *torture,
2338 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2339 struct smb2_handle h, uint64_t off, uint64_t len,
2346 torture_assert(torture, (len % 8) == 0, "invalid read len");
2352 uint64_t io_sz = MIN(1024 * 64, len);
2355 r.in.file.handle = h;
2356 r.in.length = io_sz;
2358 status = smb2_read(tree, mem_ctx, &r);
2359 torture_assert_ntstatus_ok(torture, status, "read");
2361 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2362 "read data len mismatch");
2364 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2365 uint64_t data = BVAL(r.out.data.data, i);
2366 torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2367 talloc_asprintf(torture, "read data "
2368 "pattern bad at %llu\n",
2369 (unsigned long long)off + i));
2371 talloc_free(r.out.data.data);
2379 static bool test_setup_open(struct torture_context *torture,
2380 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2382 struct smb2_handle *fh,
2383 uint32_t desired_access,
2384 uint32_t file_attributes)
2386 struct smb2_create io;
2390 io.in.desired_access = desired_access;
2391 io.in.file_attributes = file_attributes;
2392 io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2393 io.in.share_access =
2394 NTCREATEX_SHARE_ACCESS_DELETE|
2395 NTCREATEX_SHARE_ACCESS_READ|
2396 NTCREATEX_SHARE_ACCESS_WRITE;
2397 if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2398 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2400 io.in.fname = fname;
2402 status = smb2_create(tree, mem_ctx, &io);
2403 torture_assert_ntstatus_ok(torture, status, "file create");
2405 *fh = io.out.file.handle;
2410 static bool test_setup_create_fill(struct torture_context *torture,
2411 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2413 struct smb2_handle *fh,
2415 uint32_t desired_access,
2416 uint32_t file_attributes)
2420 ok = test_setup_open(torture, tree, mem_ctx,
2425 torture_assert(torture, ok, "file open");
2428 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2429 torture_assert(torture, ok, "write pattern");
2434 static bool test_setup_copy_chunk(struct torture_context *torture,
2435 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2437 const char *src_name,
2438 struct smb2_handle *src_h,
2440 uint32_t src_desired_access,
2441 const char *dst_name,
2442 struct smb2_handle *dest_h,
2444 uint32_t dest_desired_access,
2445 struct srv_copychunk_copy *cc_copy,
2446 union smb_ioctl *io)
2448 struct req_resume_key_rsp res_key;
2451 enum ndr_err_code ndr_ret;
2453 ok = test_setup_create_fill(torture, tree, mem_ctx, src_name,
2454 src_h, src_size, src_desired_access,
2455 FILE_ATTRIBUTE_NORMAL);
2456 torture_assert(torture, ok, "src file create fill");
2458 ok = test_setup_create_fill(torture, tree, mem_ctx, dst_name,
2459 dest_h, dest_size, dest_desired_access,
2460 FILE_ATTRIBUTE_NORMAL);
2461 torture_assert(torture, ok, "dest file create fill");
2464 io->smb2.level = RAW_IOCTL_SMB2;
2465 io->smb2.in.file.handle = *src_h;
2466 io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2467 /* Allow for Key + ContextLength + Context */
2468 io->smb2.in.max_response_size = 32;
2469 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2471 status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2472 torture_assert_ntstatus_ok(torture, status,
2473 "FSCTL_SRV_REQUEST_RESUME_KEY");
2475 ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2476 (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2478 torture_assert_ndr_success(torture, ndr_ret,
2479 "ndr_pull_req_resume_key_rsp");
2482 io->smb2.level = RAW_IOCTL_SMB2;
2483 io->smb2.in.file.handle = *dest_h;
2484 io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2485 io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2486 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2488 ZERO_STRUCTPN(cc_copy);
2489 memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2490 cc_copy->chunk_count = nchunks;
2491 cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2492 torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2498 static bool check_copy_chunk_rsp(struct torture_context *torture,
2499 struct srv_copychunk_rsp *cc_rsp,
2500 uint32_t ex_chunks_written,
2501 uint32_t ex_chunk_bytes_written,
2502 uint32_t ex_total_bytes_written)
2504 torture_assert_int_equal(torture, cc_rsp->chunks_written,
2505 ex_chunks_written, "num chunks");
2506 torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2507 ex_chunk_bytes_written, "chunk bytes written");
2508 torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2509 ex_total_bytes_written, "chunk total bytes");
2513 static bool neg_aapl_copyfile(struct torture_context *tctx,
2514 struct smb2_tree *tree,
2517 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2518 const char *fname = "aapl";
2520 struct smb2_create io;
2522 struct smb2_create_blob *aapl = NULL;
2524 uint32_t aapl_reply_bitmap;
2525 uint32_t aapl_server_caps;
2529 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2530 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2531 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2532 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2533 NTCREATEX_SHARE_ACCESS_READ |
2534 NTCREATEX_SHARE_ACCESS_WRITE);
2535 io.in.fname = fname;
2537 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2538 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2539 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2540 SBVAL(data.data, 16, flags);
2542 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2543 CHECK_STATUS(status, NT_STATUS_OK);
2545 status = smb2_create(tree, tctx, &io);
2546 CHECK_STATUS(status, NT_STATUS_OK);
2548 aapl = smb2_create_blob_find(&io.out.blobs,
2549 SMB2_CREATE_TAG_AAPL);
2555 if (aapl->data.length < 24) {
2560 aapl_cmd = IVAL(aapl->data.data, 0);
2561 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2562 torture_result(tctx, TORTURE_FAIL,
2563 "(%s) unexpected cmd: %d",
2564 __location__, (int)aapl_cmd);
2569 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2570 if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2571 torture_result(tctx, TORTURE_FAIL,
2572 "(%s) unexpected reply_bitmap: %d",
2573 __location__, (int)aapl_reply_bitmap);
2578 aapl_server_caps = BVAL(aapl->data.data, 16);
2579 if (!(aapl_server_caps & flags)) {
2580 torture_result(tctx, TORTURE_FAIL,
2581 "(%s) unexpected server_caps: %d",
2582 __location__, (int)aapl_server_caps);
2588 status = smb2_util_close(tree, io.out.file.handle);
2589 CHECK_STATUS(status, NT_STATUS_OK);
2591 smb2_util_unlink(tree, "aapl");
2592 talloc_free(mem_ctx);
2596 static bool test_copyfile(struct torture_context *torture,
2597 struct smb2_tree *tree)
2599 struct smb2_handle src_h;
2600 struct smb2_handle dest_h;
2603 TALLOC_CTX *tmp_ctx = talloc_new(tree);
2604 struct srv_copychunk_copy cc_copy;
2605 struct srv_copychunk_rsp cc_rsp;
2606 enum ndr_err_code ndr_ret;
2608 const char *sname = ":foo" "\xef\x80\xa2" "bar:$DATA";
2611 * First test a copy_chunk with a 0 chunk count without having
2612 * enabled this via AAPL. The request must not fail and the
2613 * copied length in the response must be 0. This is verified
2614 * against Windows 2008r2.
2617 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2618 0, /* 0 chunks, copyfile semantics */
2620 &src_h, 4096, /* fill 4096 byte src file */
2621 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2623 &dest_h, 0, /* 0 byte dest file */
2624 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2628 torture_fail_goto(torture, done, "setup copy chunk error");
2631 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2633 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2634 torture_assert_ndr_success(torture, ndr_ret,
2635 "ndr_push_srv_copychunk_copy");
2637 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2638 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2640 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2642 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2643 torture_assert_ndr_success(torture, ndr_ret,
2644 "ndr_pull_srv_copychunk_rsp");
2646 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2647 0, /* chunks written */
2648 0, /* chunk bytes unsuccessfully written */
2649 0); /* total bytes written */
2651 torture_fail_goto(torture, done, "bad copy chunk response data");
2655 * Now enable AAPL copyfile and test again, the file and the
2656 * stream must be copied by the server.
2658 ok = neg_aapl_copyfile(torture, tree,
2659 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2661 torture_skip_goto(torture, done, "missing AAPL copyfile");
2665 smb2_util_close(tree, src_h);
2666 smb2_util_close(tree, dest_h);
2667 smb2_util_unlink(tree, FNAME_CC_SRC);
2668 smb2_util_unlink(tree, FNAME_CC_DST);
2670 ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2672 torture_fail(torture, "setup file error");
2674 ok = write_stream(tree, __location__, torture, tmp_ctx,
2675 FNAME_CC_SRC, AFPRESOURCE_STREAM,
2676 10, 10, "1234567890");
2678 torture_fail(torture, "setup stream error");
2681 ok = write_stream(tree, __location__, torture, tmp_ctx,
2682 FNAME_CC_SRC, sname,
2683 10, 10, "abcdefghij");
2684 torture_assert_goto(torture, ok == true, ok, done, "write_stream failed\n");
2686 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2687 0, /* 0 chunks, copyfile semantics */
2689 &src_h, 4096, /* fill 4096 byte src file */
2690 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2692 &dest_h, 0, /* 0 byte dest file */
2693 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2697 torture_fail_goto(torture, done, "setup copy chunk error");
2700 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2702 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2703 torture_assert_ndr_success(torture, ndr_ret,
2704 "ndr_push_srv_copychunk_copy");
2706 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2707 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2709 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2711 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2712 torture_assert_ndr_success(torture, ndr_ret,
2713 "ndr_pull_srv_copychunk_rsp");
2715 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2716 0, /* chunks written */
2717 0, /* chunk bytes unsuccessfully written */
2718 4096); /* total bytes written */
2720 torture_fail_goto(torture, done, "bad copy chunk response data");
2723 ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
2724 SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
2726 torture_fail_goto(torture, done,"open failed");
2728 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
2730 torture_fail_goto(torture, done, "inconsistent file data");
2733 ok = check_stream(tree, __location__, torture, tmp_ctx,
2734 FNAME_CC_DST, AFPRESOURCE_STREAM,
2735 0, 20, 10, 10, "1234567890");
2737 torture_fail_goto(torture, done, "inconsistent stream data");
2740 ok = check_stream(tree, __location__, torture, tmp_ctx,
2741 FNAME_CC_DST, sname,
2742 0, 20, 10, 10, "abcdefghij");
2743 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
2746 smb2_util_close(tree, src_h);
2747 smb2_util_close(tree, dest_h);
2748 smb2_util_unlink(tree, FNAME_CC_SRC);
2749 smb2_util_unlink(tree, FNAME_CC_DST);
2750 talloc_free(tmp_ctx);
2754 static bool check_stream_list(struct smb2_tree *tree,
2755 struct torture_context *tctx,
2762 union smb_fileinfo finfo;
2765 TALLOC_CTX *tmp_ctx = talloc_new(tctx);
2767 struct stream_struct *stream_sort;
2768 struct smb2_create create;
2769 struct smb2_handle h;
2772 torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
2774 ZERO_STRUCT(create);
2775 create.in.fname = fname;
2776 create.in.create_disposition = NTCREATEX_DISP_OPEN;
2777 create.in.desired_access = SEC_FILE_ALL;
2778 create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
2779 create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
2780 status = smb2_create(tree, tmp_ctx, &create);
2781 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2782 h = create.out.file.handle;
2784 finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
2785 finfo.generic.in.file.handle = h;
2787 status = smb2_getinfo_file(tree, tctx, &finfo);
2788 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
2790 smb2_util_close(tree, h);
2792 torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
2793 ret, done, "stream count");
2796 TALLOC_FREE(tmp_ctx);
2800 exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
2801 torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
2803 TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
2805 stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
2806 finfo.stream_info.out.num_streams *
2807 sizeof(*stream_sort));
2808 torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
2810 TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
2812 for (i=0; i<num_exp; i++) {
2813 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
2814 i, exp_sort[i], stream_sort[i].stream_name.s);
2815 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
2816 ret, done, "stream name");
2820 TALLOC_FREE(tmp_ctx);
2827 static bool test_stream_names(struct torture_context *tctx,
2828 struct smb2_tree *tree)
2830 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2832 struct smb2_create create;
2833 struct smb2_handle h;
2834 const char *fname = BASEDIR "\\stream_names.txt";
2837 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
2838 const char *streams[] = {
2839 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2843 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
2845 /* clean slate ...*/
2846 smb2_util_unlink(tree, fname);
2847 smb2_deltree(tree, fname);
2848 smb2_deltree(tree, BASEDIR);
2850 status = torture_smb2_testdir(tree, BASEDIR, &h);
2851 CHECK_STATUS(status, NT_STATUS_OK);
2852 smb2_util_close(tree, h);
2854 torture_comment(tctx, "(%s) testing stream names\n", __location__);
2855 ZERO_STRUCT(create);
2856 create.in.desired_access = SEC_FILE_WRITE_DATA;
2857 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2858 create.in.share_access =
2859 NTCREATEX_SHARE_ACCESS_DELETE|
2860 NTCREATEX_SHARE_ACCESS_READ|
2861 NTCREATEX_SHARE_ACCESS_WRITE;
2862 create.in.create_disposition = NTCREATEX_DISP_CREATE;
2863 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2864 create.in.fname = sname1;
2866 status = smb2_create(tree, mem_ctx, &create);
2867 CHECK_STATUS(status, NT_STATUS_OK);
2868 smb2_util_close(tree, create.out.file.handle);
2870 ret = check_stream_list(tree, tctx, fname, 2, streams, false);
2871 CHECK_VALUE(ret, true);
2874 status = smb2_util_unlink(tree, fname);
2875 smb2_deltree(tree, BASEDIR);
2876 talloc_free(mem_ctx);
2881 /* Renaming a directory with open file, should work for OS X AAPL clients */
2882 static bool test_rename_dir_openfile(struct torture_context *torture,
2883 struct smb2_tree *tree)
2889 union smb_setfileinfo sinfo;
2890 struct smb2_handle d1, h1;
2891 const char *renamedir = BASEDIR "-new";
2892 bool server_is_osx = torture_setting_bool(torture, "osx", false);
2894 smb2_deltree(tree, BASEDIR);
2895 smb2_util_rmdir(tree, BASEDIR);
2896 smb2_deltree(tree, renamedir);
2898 ZERO_STRUCT(io.smb2);
2899 io.generic.level = RAW_OPEN_SMB2;
2900 io.smb2.in.create_flags = 0;
2901 io.smb2.in.desired_access = 0x0017019f;
2902 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2903 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2904 io.smb2.in.share_access = 0;
2905 io.smb2.in.alloc_size = 0;
2906 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2907 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2908 io.smb2.in.security_flags = 0;
2909 io.smb2.in.fname = BASEDIR;
2911 status = smb2_create(tree, torture, &(io.smb2));
2912 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2913 d1 = io.smb2.out.file.handle;
2915 ZERO_STRUCT(io.smb2);
2916 io.generic.level = RAW_OPEN_SMB2;
2917 io.smb2.in.create_flags = 0;
2918 io.smb2.in.desired_access = 0x0017019f;
2919 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2920 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2921 io.smb2.in.share_access = 0;
2922 io.smb2.in.alloc_size = 0;
2923 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2924 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2925 io.smb2.in.security_flags = 0;
2926 io.smb2.in.fname = BASEDIR "\\file.txt";
2928 status = smb2_create(tree, torture, &(io.smb2));
2929 torture_assert_ntstatus_ok(torture, status, "smb2_create file");
2930 h1 = io.smb2.out.file.handle;
2932 if (!server_is_osx) {
2933 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
2936 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2937 sinfo.rename_information.in.file.handle = d1;
2938 sinfo.rename_information.in.overwrite = 0;
2939 sinfo.rename_information.in.root_fid = 0;
2940 sinfo.rename_information.in.new_name = renamedir;
2941 status = smb2_setinfo_file(tree, &sinfo);
2943 torture_assert_ntstatus_equal(torture, status,
2944 NT_STATUS_ACCESS_DENIED,
2945 "smb2_setinfo_file");
2947 ZERO_STRUCT(cl.smb2);
2948 cl.smb2.level = RAW_CLOSE_SMB2;
2949 cl.smb2.in.file.handle = d1;
2950 status = smb2_close(tree, &(cl.smb2));
2951 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2955 torture_comment(torture, "Enabling AAPL\n");
2957 ret = enable_aapl(torture, tree);
2958 torture_assert(torture, ret == true, "enable_aapl failed");
2960 torture_comment(torture, "Renaming directory with AAPL\n");
2962 ZERO_STRUCT(io.smb2);
2963 io.generic.level = RAW_OPEN_SMB2;
2964 io.smb2.in.desired_access = 0x0017019f;
2965 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2966 io.smb2.in.share_access = 0;
2967 io.smb2.in.alloc_size = 0;
2968 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
2969 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2970 io.smb2.in.security_flags = 0;
2971 io.smb2.in.fname = BASEDIR;
2973 status = smb2_create(tree, torture, &(io.smb2));
2974 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2975 d1 = io.smb2.out.file.handle;
2978 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2979 sinfo.rename_information.in.file.handle = d1;
2980 sinfo.rename_information.in.overwrite = 0;
2981 sinfo.rename_information.in.root_fid = 0;
2982 sinfo.rename_information.in.new_name = renamedir;
2984 status = smb2_setinfo_file(tree, &sinfo);
2985 torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
2987 ZERO_STRUCT(cl.smb2);
2988 cl.smb2.level = RAW_CLOSE_SMB2;
2989 cl.smb2.in.file.handle = d1;
2990 status = smb2_close(tree, &(cl.smb2));
2991 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2994 cl.smb2.in.file.handle = h1;
2995 status = smb2_close(tree, &(cl.smb2));
2996 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2999 torture_comment(torture, "Cleaning up\n");
3001 if (h1.data[0] || h1.data[1]) {
3002 ZERO_STRUCT(cl.smb2);
3003 cl.smb2.level = RAW_CLOSE_SMB2;
3004 cl.smb2.in.file.handle = h1;
3005 status = smb2_close(tree, &(cl.smb2));
3008 smb2_util_unlink(tree, BASEDIR "\\file.txt");
3009 smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
3010 smb2_deltree(tree, renamedir);
3011 smb2_deltree(tree, BASEDIR);
3015 static bool test_afpinfo_enoent(struct torture_context *tctx,
3016 struct smb2_tree *tree)
3020 struct smb2_create create;
3021 struct smb2_handle h1;
3022 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3023 const char *fname = BASEDIR "\\file";
3024 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3026 torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
3028 smb2_deltree(tree, BASEDIR);
3029 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3030 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3031 smb2_util_close(tree, h1);
3032 ret = torture_setup_file(mem_ctx, tree, fname, false);
3033 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3035 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3037 ZERO_STRUCT(create);
3038 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3039 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3040 create.in.fname = sname;
3042 status = smb2_create(tree, mem_ctx, &create);
3043 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3044 ret, done, "Got unexpected AFP_AfpInfo stream");
3047 smb2_util_unlink(tree, fname);
3048 smb2_util_rmdir(tree, BASEDIR);
3052 static bool test_create_delete_on_close(struct torture_context *tctx,
3053 struct smb2_tree *tree)
3057 struct smb2_create create;
3058 struct smb2_handle h1;
3059 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3060 const char *fname = BASEDIR "\\file";
3061 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3062 const char *type_creator = "SMB,OLE!";
3063 AfpInfo *info = NULL;
3064 const char *streams_basic[] = {
3067 const char *streams_afpinfo[] = {
3072 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3074 torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
3076 smb2_deltree(tree, BASEDIR);
3077 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3078 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3079 smb2_util_close(tree, h1);
3080 ret = torture_setup_file(mem_ctx, tree, fname, false);
3081 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3083 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3085 ZERO_STRUCT(create);
3086 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3087 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3088 create.in.fname = sname;
3090 status = smb2_create(tree, mem_ctx, &create);
3091 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3092 ret, done, "Got unexpected AFP_AfpInfo stream");
3094 ZERO_STRUCT(create);
3095 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3096 create.in.desired_access = SEC_FILE_ALL;
3097 create.in.fname = sname;
3099 status = smb2_create(tree, mem_ctx, &create);
3100 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3101 ret, done, "Got unexpected AFP_AfpInfo stream");
3103 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3104 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3106 torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
3108 info = torture_afpinfo_new(mem_ctx);
3109 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3111 memcpy(info->afpi_FinderInfo, type_creator, 8);
3112 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3113 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3115 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3116 0, 60, 16, 8, type_creator);
3117 torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
3119 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3120 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3122 ZERO_STRUCT(create);
3123 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3124 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3125 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3126 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3127 create.in.fname = sname;
3128 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3130 status = smb2_create(tree, mem_ctx, &create);
3131 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3133 h1 = create.out.file.handle;
3134 smb2_util_close(tree, h1);
3136 ZERO_STRUCT(create);
3137 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3138 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
3139 create.in.fname = sname;
3140 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3141 status = smb2_create(tree, mem_ctx, &create);
3142 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3143 ret, done, "Got unexpected AFP_AfpInfo stream");
3145 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3146 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3149 smb2_util_unlink(tree, fname);
3150 smb2_util_rmdir(tree, BASEDIR);
3154 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
3155 struct smb2_tree *tree)
3159 struct smb2_create create;
3160 union smb_setfileinfo sfinfo;
3161 struct smb2_handle h1;
3162 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3163 const char *fname = BASEDIR "\\file";
3164 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3165 const char *type_creator = "SMB,OLE!";
3166 AfpInfo *info = NULL;
3167 const char *streams_basic[] = {
3171 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3173 torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
3175 smb2_deltree(tree, BASEDIR);
3176 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3177 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3178 smb2_util_close(tree, h1);
3179 ret = torture_setup_file(mem_ctx, tree, fname, false);
3180 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3182 info = torture_afpinfo_new(mem_ctx);
3183 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3184 memcpy(info->afpi_FinderInfo, type_creator, 8);
3185 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3186 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3188 ZERO_STRUCT(create);
3189 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3190 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3191 create.in.fname = sname;
3192 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3193 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3195 status = smb2_create(tree, mem_ctx, &create);
3196 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3198 h1 = create.out.file.handle;
3200 /* Delete stream via setinfo delete-on-close */
3201 ZERO_STRUCT(sfinfo);
3202 sfinfo.disposition_info.in.delete_on_close = 1;
3203 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3204 sfinfo.generic.in.file.handle = h1;
3205 status = smb2_setinfo_file(tree, &sfinfo);
3206 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3208 smb2_util_close(tree, h1);
3210 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3211 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3213 ZERO_STRUCT(create);
3214 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3215 create.in.desired_access = SEC_FILE_ALL;
3216 create.in.fname = sname;
3217 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3218 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3219 status = smb2_create(tree, mem_ctx, &create);
3220 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3221 ret, done, "Got unexpected AFP_AfpInfo stream");
3224 smb2_util_unlink(tree, fname);
3225 smb2_util_rmdir(tree, BASEDIR);
3229 static bool test_setinfo_eof(struct torture_context *tctx,
3230 struct smb2_tree *tree)
3234 struct smb2_create create;
3235 union smb_setfileinfo sfinfo;
3236 struct smb2_handle h1;
3237 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3238 const char *fname = BASEDIR "\\file";
3239 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3240 const char *type_creator = "SMB,OLE!";
3241 AfpInfo *info = NULL;
3242 const char *streams_afpinfo[] = {
3247 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3249 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
3251 smb2_deltree(tree, BASEDIR);
3252 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3253 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3254 smb2_util_close(tree, h1);
3255 ret = torture_setup_file(mem_ctx, tree, fname, false);
3256 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3258 info = torture_afpinfo_new(mem_ctx);
3259 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3260 memcpy(info->afpi_FinderInfo, type_creator, 8);
3261 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3262 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3264 ZERO_STRUCT(create);
3265 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3266 create.in.desired_access = SEC_FILE_ALL;
3267 create.in.fname = sname;
3268 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3269 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3271 status = smb2_create(tree, mem_ctx, &create);
3272 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3274 h1 = create.out.file.handle;
3276 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
3278 /* Test setinfo end-of-file info */
3279 ZERO_STRUCT(sfinfo);
3280 sfinfo.generic.in.file.handle = h1;
3281 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3282 sfinfo.position_information.in.position = 61;
3283 status = smb2_setinfo_file(tree, &sfinfo);
3284 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
3285 ret, done, "set eof 61 failed");
3287 torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
3289 /* Truncation returns success, but has no effect */
3290 ZERO_STRUCT(sfinfo);
3291 sfinfo.generic.in.file.handle = h1;
3292 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3293 sfinfo.position_information.in.position = 1;
3294 status = smb2_setinfo_file(tree, &sfinfo);
3295 torture_assert_ntstatus_ok_goto(tctx, status,
3296 ret, done, "set eof 1 failed");
3297 smb2_util_close(tree, h1);
3299 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3300 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3302 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3303 0, 60, 16, 8, type_creator);
3304 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3306 ZERO_STRUCT(create);
3307 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3308 create.in.desired_access = SEC_FILE_ALL;
3309 create.in.fname = sname;
3310 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3311 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3313 status = smb2_create(tree, mem_ctx, &create);
3314 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3316 h1 = create.out.file.handle;
3319 * Delete stream via setinfo end-of-file info to 0, should
3320 * return success but stream MUST NOT deleted
3322 ZERO_STRUCT(sfinfo);
3323 sfinfo.generic.in.file.handle = h1;
3324 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3325 sfinfo.position_information.in.position = 0;
3326 status = smb2_setinfo_file(tree, &sfinfo);
3327 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3329 smb2_util_close(tree, h1);
3331 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3332 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3334 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3335 0, 60, 16, 8, type_creator);
3336 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3339 smb2_util_unlink(tree, fname);
3340 smb2_util_rmdir(tree, BASEDIR);
3344 static bool test_afpinfo_all0(struct torture_context *tctx,
3345 struct smb2_tree *tree)
3349 struct smb2_handle h1;
3350 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3351 const char *fname = BASEDIR "\\file";
3352 const char *type_creator = "SMB,OLE!";
3353 AfpInfo *info = NULL;
3354 const char *streams_basic[] = {
3357 const char *streams_afpinfo[] = {
3362 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3364 torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
3366 smb2_deltree(tree, BASEDIR);
3367 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3368 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3369 smb2_util_close(tree, h1);
3370 ret = torture_setup_file(mem_ctx, tree, fname, false);
3371 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3373 info = torture_afpinfo_new(mem_ctx);
3374 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3375 memcpy(info->afpi_FinderInfo, type_creator, 8);
3376 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3377 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3379 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3380 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3382 /* Write all 0 to AFP_AfpInfo */
3383 memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
3384 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3385 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3387 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3388 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3391 smb2_util_unlink(tree, fname);
3392 smb2_util_rmdir(tree, BASEDIR);
3396 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
3397 struct smb2_tree *tree)
3401 struct smb2_create create;
3402 struct smb2_handle h1;
3403 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3404 const char *fname = BASEDIR "\\file";
3405 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3406 const char *streams_basic[] = {
3409 const char *streams_afpresource[] = {
3414 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3416 torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
3418 smb2_deltree(tree, BASEDIR);
3419 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3420 torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
3421 smb2_util_close(tree, h1);
3422 ret = torture_setup_file(mem_ctx, tree, fname, false);
3423 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3425 torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
3427 ZERO_STRUCT(create);
3428 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3429 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3430 create.in.fname = sname;
3432 status = smb2_create(tree, mem_ctx, &create);
3433 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3434 ret, done, "Got unexpected AFP_AfpResource stream");
3436 ZERO_STRUCT(create);
3437 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3438 create.in.desired_access = SEC_FILE_ALL;
3439 create.in.fname = sname;
3441 status = smb2_create(tree, mem_ctx, &create);
3442 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3443 ret, done, "Got unexpected AFP_AfpResource stream");
3445 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3446 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3448 torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
3450 ret = write_stream(tree, __location__, tctx, mem_ctx,
3451 fname, AFPRESOURCE_STREAM_NAME,
3452 0, 10, "1234567890");
3453 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3455 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3456 0, 10, 0, 10, "1234567890");
3457 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3459 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3460 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3462 ZERO_STRUCT(create);
3463 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3464 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3465 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3466 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3467 create.in.fname = sname;
3468 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3470 status = smb2_create(tree, mem_ctx, &create);
3471 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3473 h1 = create.out.file.handle;
3474 smb2_util_close(tree, h1);
3476 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3477 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3479 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3480 0, 10, 0, 10, "1234567890");
3481 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3484 smb2_util_unlink(tree, fname);
3485 smb2_util_rmdir(tree, BASEDIR);
3489 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
3490 struct smb2_tree *tree)
3494 struct smb2_create create;
3495 union smb_setfileinfo sfinfo;
3496 struct smb2_handle h1;
3497 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3498 const char *fname = BASEDIR "\\file";
3499 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3500 const char *streams_afpresource[] = {
3505 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3507 torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
3509 smb2_deltree(tree, BASEDIR);
3510 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3511 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3512 smb2_util_close(tree, h1);
3513 ret = torture_setup_file(mem_ctx, tree, fname, false);
3514 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3516 ret = write_stream(tree, __location__, tctx, mem_ctx,
3517 fname, AFPRESOURCE_STREAM_NAME,
3518 10, 10, "1234567890");
3519 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3521 ZERO_STRUCT(create);
3522 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3523 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3524 create.in.fname = sname;
3525 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3526 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3528 status = smb2_create(tree, mem_ctx, &create);
3529 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3531 h1 = create.out.file.handle;
3533 /* Try to delete stream via setinfo delete-on-close */
3534 ZERO_STRUCT(sfinfo);
3535 sfinfo.disposition_info.in.delete_on_close = 1;
3536 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3537 sfinfo.generic.in.file.handle = h1;
3538 status = smb2_setinfo_file(tree, &sfinfo);
3539 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3541 smb2_util_close(tree, h1);
3543 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3544 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3546 ZERO_STRUCT(create);
3547 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3548 create.in.desired_access = SEC_FILE_ALL;
3549 create.in.fname = sname;
3550 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3551 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3552 status = smb2_create(tree, mem_ctx, &create);
3553 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3554 "Got unexpected AFP_AfpResource stream");
3557 smb2_util_unlink(tree, fname);
3558 smb2_util_rmdir(tree, BASEDIR);
3562 static bool test_setinfo_eof_resource(struct torture_context *tctx,
3563 struct smb2_tree *tree)
3567 struct smb2_create create;
3568 union smb_setfileinfo sfinfo;
3569 union smb_fileinfo finfo;
3570 struct smb2_handle h1;
3571 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3572 const char *fname = BASEDIR "\\file";
3573 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3574 const char *streams_basic[] = {
3578 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3580 torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
3582 smb2_deltree(tree, BASEDIR);
3583 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3584 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3585 smb2_util_close(tree, h1);
3586 ret = torture_setup_file(mem_ctx, tree, fname, false);
3587 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3589 ret = write_stream(tree, __location__, tctx, mem_ctx,
3590 fname, AFPRESOURCE_STREAM_NAME,
3591 10, 10, "1234567890");
3592 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3594 ZERO_STRUCT(create);
3595 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3596 create.in.desired_access = SEC_FILE_ALL;
3597 create.in.fname = sname;
3598 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3599 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3601 status = smb2_create(tree, mem_ctx, &create);
3602 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3604 h1 = create.out.file.handle;
3606 torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
3608 /* Test setinfo end-of-file info */
3609 ZERO_STRUCT(sfinfo);
3610 sfinfo.generic.in.file.handle = h1;
3611 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3612 sfinfo.position_information.in.position = 1;
3613 status = smb2_setinfo_file(tree, &sfinfo);
3614 torture_assert_ntstatus_ok_goto(tctx, status,
3615 ret, done, "set eof 1 failed");
3617 smb2_util_close(tree, h1);
3619 /* Check size == 1 */
3620 ZERO_STRUCT(create);
3621 create.in.fname = sname;
3622 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3623 create.in.desired_access = SEC_FILE_ALL;
3624 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3625 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3626 status = smb2_create(tree, mem_ctx, &create);
3627 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3629 h1 = create.out.file.handle;
3632 finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
3633 finfo.generic.in.file.handle = h1;
3634 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
3635 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
3637 smb2_util_close(tree, h1);
3639 torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
3641 ZERO_STRUCT(create);
3642 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3643 create.in.desired_access = SEC_FILE_ALL;
3644 create.in.fname = sname;
3645 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3646 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3648 status = smb2_create(tree, mem_ctx, &create);
3649 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3651 h1 = create.out.file.handle;
3654 * Delete stream via setinfo end-of-file info to 0, this
3655 * should delete the stream.
3657 ZERO_STRUCT(sfinfo);
3658 sfinfo.generic.in.file.handle = h1;
3659 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3660 sfinfo.position_information.in.position = 0;
3661 status = smb2_setinfo_file(tree, &sfinfo);
3662 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3664 smb2_util_close(tree, h1);
3666 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3667 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3669 ZERO_STRUCT(create);
3670 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3671 create.in.desired_access = SEC_FILE_ALL;
3672 create.in.fname = sname;
3673 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3674 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3676 status = smb2_create(tree, mem_ctx, &create);
3677 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3678 ret, done, "smb2_create failed");
3681 smb2_util_unlink(tree, fname);
3682 smb2_util_rmdir(tree, BASEDIR);
3687 * This tests that right after creating the AFP_AfpInfo stream,
3688 * reading from the stream returns an empty, default metadata blob of
3691 * NOTE: against OS X SMB server this only works if the read request
3692 * is compounded with the create that created the stream, is fails
3693 * otherwise. We don't care...
3695 static bool test_null_afpinfo(struct torture_context *tctx,
3696 struct smb2_tree *tree)
3698 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3699 const char *fname = "test_null_afpinfo";
3700 const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
3703 struct smb2_request *req[3];
3704 struct smb2_handle handle;
3705 struct smb2_create create;
3706 struct smb2_read read;
3707 AfpInfo *afpinfo = NULL;
3708 char *afpinfo_buf = NULL;
3709 const char *type_creator = "SMB,OLE!";
3711 torture_comment(tctx, "Checking create of AfpInfo stream\n");
3713 smb2_util_unlink(tree, fname);
3715 ret = torture_setup_file(mem_ctx, tree, fname, false);
3716 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
3718 ZERO_STRUCT(create);
3719 create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
3720 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
3721 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3722 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3723 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
3724 create.in.fname = sname;
3726 smb2_transport_compound_start(tree->session->transport, 2);
3728 req[0] = smb2_create_send(tree, &create);
3730 handle.data[0] = UINT64_MAX;
3731 handle.data[1] = UINT64_MAX;
3733 smb2_transport_compound_set_related(tree->session->transport, true);
3736 read.in.file.handle = handle;
3737 read.in.length = AFP_INFO_SIZE;
3738 req[1] = smb2_read_send(tree, &read);
3740 status = smb2_create_recv(req[0], tree, &create);
3741 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
3743 handle = create.out.file.handle;
3745 status = smb2_read_recv(req[1], tree, &read);
3746 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
3748 afpinfo = torture_afpinfo_new(mem_ctx);
3749 torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
3751 memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
3753 afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
3754 torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
3756 status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
3757 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
3759 smb2_util_close(tree, handle);
3761 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3762 0, 60, 16, 8, type_creator);
3763 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
3766 smb2_util_unlink(tree, fname);
3767 talloc_free(mem_ctx);
3771 static bool test_delete_file_with_rfork(struct torture_context *tctx,
3772 struct smb2_tree *tree)
3774 const char *fname = "torture_write_rfork_io";
3775 const char *rfork_content = "1234567890";
3779 smb2_util_unlink(tree, fname);
3781 torture_comment(tctx, "Test deleting file with resource fork\n");
3783 ret = torture_setup_file(tctx, tree, fname, false);
3784 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
3786 ret = write_stream(tree, __location__, tctx, tctx,
3787 fname, AFPRESOURCE_STREAM_NAME,
3788 10, 10, rfork_content);
3789 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
3791 ret = check_stream(tree, __location__, tctx, tctx,
3792 fname, AFPRESOURCE_STREAM_NAME,
3793 0, 20, 10, 10, rfork_content);
3794 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
3796 status = smb2_util_unlink(tree, fname);
3797 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
3803 static bool test_rename_and_read_rsrc(struct torture_context *tctx,
3804 struct smb2_tree *tree)
3808 struct smb2_create create, create2;
3809 struct smb2_handle h1, h2;
3810 const char *fname = "test_rename_openfile";
3811 const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
3812 const char *fname_renamed = "test_rename_openfile_renamed";
3813 const char *data = "1234567890";
3814 union smb_setfileinfo sinfo;
3817 ret = enable_aapl(tctx, tree);
3818 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
3820 torture_comment(tctx, "Create file with resource fork\n");
3822 ret = torture_setup_file(tctx, tree, fname, false);
3823 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3825 ret = write_stream(tree, __location__, tctx, tctx,
3826 fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
3827 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
3829 torture_comment(tctx, "Open resource fork\n");
3831 ZERO_STRUCT(create);
3832 create.in.desired_access = SEC_FILE_ALL;
3833 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3834 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3835 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3836 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3837 create.in.fname = sname;
3839 status = smb2_create(tree, tctx, &create);
3840 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3842 h1 = create.out.file.handle;
3844 torture_comment(tctx, "Rename base file\n");
3846 ZERO_STRUCT(create2);
3847 create2.in.desired_access = SEC_FILE_ALL;
3848 create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3849 create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3850 create2.in.create_disposition = NTCREATEX_DISP_OPEN;
3851 create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3852 create2.in.fname = fname;
3854 status = smb2_create(tree, tctx, &create2);
3855 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3857 h2 = create2.out.file.handle;
3860 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3861 sinfo.rename_information.in.file.handle = h2;
3862 sinfo.rename_information.in.overwrite = 0;
3863 sinfo.rename_information.in.root_fid = 0;
3864 sinfo.rename_information.in.new_name = fname_renamed;
3866 status = smb2_setinfo_file(tree, &sinfo);
3867 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file failed");
3869 smb2_util_close(tree, h2);
3872 r.in.file.handle = h1;
3876 torture_comment(tctx, "Read resource fork of renamed file\n");
3878 status = smb2_read(tree, tree, &r);
3879 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read failed");
3881 smb2_util_close(tree, h1);
3883 torture_assert_goto(tctx, r.out.data.length == 10, ret, done,
3884 talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected 10\n",
3885 (intmax_t)r.out.data.length));
3887 torture_assert_goto(tctx, memcmp(r.out.data.data, data, 10) == 0, ret, done,
3888 talloc_asprintf(tctx, "Bad data in stream\n"));
3891 smb2_util_unlink(tree, fname);
3892 smb2_util_unlink(tree, fname_renamed);
3897 static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
3898 struct smb2_tree *tree)
3900 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3901 const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
3902 const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
3904 struct smb2_handle testdirh;
3906 struct smb2_create io;
3908 const char *type_creator = "SMB,OLE!";
3911 union smb_search_data *d;
3915 smb2_deltree(tree, BASEDIR);
3917 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
3918 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
3919 smb2_util_close(tree, testdirh);
3921 torture_comment(tctx, "Enabling AAPL\n");
3923 ret = enable_aapl(tctx, tree);
3924 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
3927 * Now that Requested AAPL extensions are enabled, setup some
3928 * Mac files with metadata and resource fork
3931 torture_comment(tctx, "Preparing file\n");
3933 ret = torture_setup_file(mem_ctx, tree, fname, false);
3934 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
3936 info = torture_afpinfo_new(mem_ctx);
3937 torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
3939 memcpy(info->afpi_FinderInfo, type_creator, 8);
3940 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3941 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3943 ret = write_stream(tree, __location__, tctx, mem_ctx,
3944 fname, AFPRESOURCE_STREAM_NAME,
3946 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
3949 * Ok, file is prepared, now call smb2/find
3952 torture_comment(tctx, "Issue find\n");
3955 io.in.desired_access = SEC_RIGHTS_DIR_READ;
3956 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
3957 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3958 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
3959 NTCREATEX_SHARE_ACCESS_WRITE |
3960 NTCREATEX_SHARE_ACCESS_DELETE);
3961 io.in.create_disposition = NTCREATEX_DISP_OPEN;
3962 io.in.fname = BASEDIR;
3963 status = smb2_create(tree, tctx, &io);
3964 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3967 f.in.file.handle = io.out.file.handle;
3969 f.in.max_response_size = 0x1000;
3970 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
3972 status = smb2_find_level(tree, tree, &f, &count, &d);
3973 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
3975 status = smb2_util_close(tree, io.out.file.handle);
3976 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
3978 torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
3980 for (i = 0; i < count; i++) {
3981 const char *found = d[i].id_both_directory_info.name.s;
3983 if (!strcmp(found, ".") || !strcmp(found, ".."))
3985 if (strncmp(found, "._", 2) == 0) {
3991 torture_assert_str_equal_goto(tctx,
3992 d[i].id_both_directory_info.name.s, name,
3993 ret, done, "bad name");
3995 rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
3996 torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
3998 torture_assert_mem_equal_goto(tctx, type_creator,
3999 d[i].id_both_directory_info.short_name_buf + 8,
4000 8, ret, done, "Bad FinderInfo");
4002 smb2_util_unlink(tree, fname);
4003 smb2_deltree(tree, BASEDIR);
4004 talloc_free(mem_ctx);
4008 static bool test_invalid_afpinfo(struct torture_context *tctx,
4009 struct smb2_tree *tree1,
4010 struct smb2_tree *tree2)
4012 const char *fname = "filtest_invalid_afpinfo";
4013 const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
4014 struct smb2_create create;
4015 const char *streams_basic[] = {
4018 const char *streams_afpinfo[] = {
4025 if (tree2 == NULL) {
4026 torture_skip_goto(tctx, done, "need second share without fruit\n");
4029 torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
4031 ret = torture_setup_file(tctx, tree2, fname, false);
4032 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4034 ret = write_stream(tree2, __location__, tctx, tctx,
4035 fname, AFPINFO_STREAM_NAME,
4037 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4039 ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
4040 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4042 torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
4044 ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
4045 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4047 torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
4049 ZERO_STRUCT(create);
4050 create.in.desired_access = SEC_FILE_ALL;
4051 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4052 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4053 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4054 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4055 create.in.fname = sname;
4057 status = smb2_create(tree1, tctx, &create);
4058 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4059 ret, done, "Stream still around?");
4062 smb2_util_unlink(tree1, fname);
4066 static bool test_zero_file_id(struct torture_context *tctx,
4067 struct smb2_tree *tree)
4069 const char *fname = "filtest_file_id";
4070 struct smb2_create create = {0};
4073 uint8_t zero_file_id[8] = {0};
4075 torture_comment(tctx, "Testing zero file id\n");
4077 ret = torture_setup_file(tctx, tree, fname, false);
4078 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4080 ZERO_STRUCT(create);
4081 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4082 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4083 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4084 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4085 create.in.fname = fname;
4086 create.in.query_on_disk_id = true;
4088 status = smb2_create(tree, tctx, &create);
4089 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
4091 "test file could not be opened");
4092 torture_assert_mem_not_equal_goto(tctx, create.out.on_disk_id,
4093 zero_file_id, 8, ret, done,
4094 "unexpected zero file id");
4096 smb2_util_close(tree, create.out.file.handle);
4098 ret = enable_aapl(tctx, tree);
4099 torture_assert(tctx, ret == true, "enable_aapl failed");
4101 ZERO_STRUCT(create);
4102 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4103 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4104 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4105 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4106 create.in.fname = fname;
4107 create.in.query_on_disk_id = true;
4109 status = smb2_create(tree, tctx, &create);
4110 torture_assert_ntstatus_equal_goto(
4111 tctx, status, NT_STATUS_OK, ret, done,
4112 "test file could not be opened with AAPL");
4113 torture_assert_mem_equal_goto(tctx, create.out.on_disk_id, zero_file_id,
4114 8, ret, done, "non-zero file id");
4116 smb2_util_close(tree, create.out.file.handle);
4119 smb2_util_unlink(tree, fname);
4123 static bool copy_one_stream(struct torture_context *torture,
4124 struct smb2_tree *tree,
4125 TALLOC_CTX *tmp_ctx,
4126 const char *src_sname,
4127 const char *dst_sname)
4129 struct smb2_handle src_h = {{0}};
4130 struct smb2_handle dest_h = {{0}};
4133 struct srv_copychunk_copy cc_copy;
4134 struct srv_copychunk_rsp cc_rsp;
4135 enum ndr_err_code ndr_ret;
4138 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4141 &src_h, 256, /* fill 256 byte src file */
4142 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4144 &dest_h, 0, /* 0 byte dest file */
4145 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4148 torture_assert_goto(torture, ok == true, ok, done,
4149 "setup copy chunk error\n");
4151 /* copy all src file data (via a single chunk desc) */
4152 cc_copy.chunks[0].source_off = 0;
4153 cc_copy.chunks[0].target_off = 0;
4154 cc_copy.chunks[0].length = 256;
4156 ndr_ret = ndr_push_struct_blob(
4157 &io.smb2.in.out, tmp_ctx, &cc_copy,
4158 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4160 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4161 "ndr_push_srv_copychunk_copy\n");
4163 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4164 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4165 "FSCTL_SRV_COPYCHUNK\n");
4167 ndr_ret = ndr_pull_struct_blob(
4168 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4169 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4171 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4172 "ndr_pull_srv_copychunk_rsp\n");
4174 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4175 1, /* chunks written */
4176 0, /* chunk bytes unsuccessfully written */
4177 256); /* total bytes written */
4178 torture_assert_goto(torture, ok == true, ok, done,
4179 "bad copy chunk response data\n");
4181 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
4183 torture_fail(torture, "inconsistent file data\n");
4187 if (!smb2_util_handle_empty(src_h)) {
4188 smb2_util_close(tree, src_h);
4190 if (!smb2_util_handle_empty(dest_h)) {
4191 smb2_util_close(tree, dest_h);
4197 static bool copy_finderinfo_stream(struct torture_context *torture,
4198 struct smb2_tree *tree,
4199 TALLOC_CTX *tmp_ctx,
4200 const char *src_name,
4201 const char *dst_name)
4203 struct smb2_handle src_h = {{0}};
4204 struct smb2_handle dest_h = {{0}};
4207 struct srv_copychunk_copy cc_copy;
4208 struct srv_copychunk_rsp cc_rsp;
4209 enum ndr_err_code ndr_ret;
4210 const char *type_creator = "SMB,OLE!";
4211 AfpInfo *info = NULL;
4212 const char *src_name_afpinfo = NULL;
4213 const char *dst_name_afpinfo = NULL;
4216 src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
4218 torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
4219 "talloc_asprintf failed\n");
4221 dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
4223 torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
4224 "talloc_asprintf failed\n");
4226 info = torture_afpinfo_new(tmp_ctx);
4227 torture_assert_not_null_goto(torture, info, ok, done,
4228 "torture_afpinfo_new failed\n");
4230 memcpy(info->afpi_FinderInfo, type_creator, 8);
4231 ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
4232 torture_assert_goto(torture, ok == true, ok, done,
4233 "torture_write_afpinfo failed\n");
4235 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4239 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4242 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4245 torture_assert_goto(torture, ok == true, ok, done,
4246 "setup copy chunk error\n");
4248 /* copy all src file data (via a single chunk desc) */
4249 cc_copy.chunks[0].source_off = 0;
4250 cc_copy.chunks[0].target_off = 0;
4251 cc_copy.chunks[0].length = 60;
4253 ndr_ret = ndr_push_struct_blob(
4254 &io.smb2.in.out, tmp_ctx, &cc_copy,
4255 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4257 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4258 "ndr_push_srv_copychunk_copy\n");
4260 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4261 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4262 "FSCTL_SRV_COPYCHUNK\n");
4264 ndr_ret = ndr_pull_struct_blob(
4265 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4266 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4268 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4269 "ndr_pull_srv_copychunk_rsp\n");
4271 smb2_util_close(tree, src_h);
4273 smb2_util_close(tree, dest_h);
4274 ZERO_STRUCT(dest_h);
4276 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4277 1, /* chunks written */
4278 0, /* chunk bytes unsuccessfully written */
4279 60); /* total bytes written */
4280 torture_assert_goto(torture, ok == true, ok, done,
4281 "bad copy chunk response data\n");
4283 ok = check_stream(tree, __location__, torture, tmp_ctx,
4284 dst_name, AFPINFO_STREAM,
4285 0, 60, 16, 8, type_creator);
4286 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
4289 if (!smb2_util_handle_empty(src_h)) {
4290 smb2_util_close(tree, src_h);
4292 if (!smb2_util_handle_empty(dest_h)) {
4293 smb2_util_close(tree, dest_h);
4299 static bool test_copy_chunk_streams(struct torture_context *torture,
4300 struct smb2_tree *tree)
4302 const char *src_name = "src";
4303 const char *dst_name = "dst";
4305 const char *src_sname;
4306 const char *dst_sname;
4308 { "src:foo", "dst:foo" },
4309 { "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
4312 TALLOC_CTX *tmp_ctx = NULL;
4315 tmp_ctx = talloc_new(tree);
4316 torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
4317 "torture_setup_file\n");
4319 smb2_util_unlink(tree, src_name);
4320 smb2_util_unlink(tree, dst_name);
4322 ok = torture_setup_file(torture, tree, src_name, false);
4323 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4324 ok = torture_setup_file(torture, tree, dst_name, false);
4325 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4327 for (i = 0; i < ARRAY_SIZE(names); i++) {
4328 ok = copy_one_stream(torture, tree, tmp_ctx,
4330 names[i].dst_sname);
4331 torture_assert_goto(torture, ok == true, ok, done,
4332 "copy_one_stream failed\n");
4335 ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
4336 src_name, dst_name);
4337 torture_assert_goto(torture, ok == true, ok, done,
4338 "copy_finderinfo_stream failed\n");
4341 smb2_util_unlink(tree, src_name);
4342 smb2_util_unlink(tree, dst_name);
4343 talloc_free(tmp_ctx);
4348 * Note: This test depends on "vfs objects = catia fruit streams_xattr". For
4349 * some tests torture must be run on the host it tests and takes an additional
4350 * argument with the local path to the share:
4351 * "--option=torture:localdir=<SHAREPATH>".
4353 * When running against an OS X SMB server add "--option=torture:osx=true"
4355 struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
4357 struct torture_suite *suite = torture_suite_create(
4360 suite->description = talloc_strdup(suite, "vfs_fruit tests");
4362 torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
4363 torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
4364 torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
4365 torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
4366 torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
4367 torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
4368 torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
4369 torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
4370 torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
4371 torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
4372 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
4373 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
4374 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
4375 torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
4376 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
4377 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
4378 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
4379 torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
4380 torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
4381 torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
4382 torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
4383 torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
4384 torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
4385 torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
4386 torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
4391 static bool test_stream_names_local(struct torture_context *tctx,
4392 struct smb2_tree *tree)
4394 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4396 struct smb2_create create;
4397 struct smb2_handle h;
4398 const char *fname = BASEDIR "\\stream_names.txt";
4401 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
4402 const char *streams[] = {
4403 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
4404 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
4407 const char *localdir = NULL;
4409 localdir = torture_setting_string(tctx, "localdir", NULL);
4410 if (localdir == NULL) {
4411 torture_skip(tctx, "Need localdir for test");
4414 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
4416 /* clean slate ...*/
4417 smb2_util_unlink(tree, fname);
4418 smb2_deltree(tree, fname);
4419 smb2_deltree(tree, BASEDIR);
4421 status = torture_smb2_testdir(tree, BASEDIR, &h);
4422 CHECK_STATUS(status, NT_STATUS_OK);
4423 smb2_util_close(tree, h);
4425 torture_comment(tctx, "(%s) testing stream names\n", __location__);
4426 ZERO_STRUCT(create);
4427 create.in.desired_access = SEC_FILE_WRITE_DATA;
4428 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4429 create.in.share_access =
4430 NTCREATEX_SHARE_ACCESS_DELETE|
4431 NTCREATEX_SHARE_ACCESS_READ|
4432 NTCREATEX_SHARE_ACCESS_WRITE;
4433 create.in.create_disposition = NTCREATEX_DISP_CREATE;
4434 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
4435 create.in.fname = sname1;
4437 status = smb2_create(tree, mem_ctx, &create);
4438 CHECK_STATUS(status, NT_STATUS_OK);
4439 smb2_util_close(tree, create.out.file.handle);
4441 ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
4442 "user.DosStream.bar:baz:$DATA",
4443 "data", strlen("data"));
4444 CHECK_VALUE(ret, true);
4446 ret = check_stream_list(tree, tctx, fname, 3, streams, false);
4447 CHECK_VALUE(ret, true);
4450 status = smb2_util_unlink(tree, fname);
4451 smb2_deltree(tree, BASEDIR);
4452 talloc_free(mem_ctx);
4457 struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
4459 struct torture_suite *suite = torture_suite_create(
4460 ctx, "fruit_netatalk");
4462 suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
4464 torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
4465 torture_suite_add_1smb2_test(suite, "stream names with locally created xattr", test_stream_names_local);
4470 struct torture_suite *torture_vfs_fruit_file_id(TALLOC_CTX *ctx)
4472 struct torture_suite *suite =
4473 torture_suite_create(ctx, "fruit_file_id");
4475 suite->description =
4476 talloc_strdup(suite, "vfs_fruit tests for on-disk file ID that "
4477 "require fruit:zero_file_id=yes");
4479 torture_suite_add_1smb2_test(suite, "zero file id if AAPL negotiated",