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);
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);
1213 static bool torture_setup_local_file(struct torture_context *tctx,
1214 const char *path_option,
1224 spath = torture_setting_string(tctx, path_option, NULL);
1225 if (spath == NULL) {
1226 printf("No sharepath for option %s\n", path_option);
1230 path = talloc_asprintf(tctx, "%s/%s", spath, name);
1235 fd = creat(path, S_IRWXU);
1241 if ((buf == NULL) || (size == 0)) {
1246 rsize = write(fd, buf, size);
1247 if (rsize != size) {
1257 * Create a file or directory
1259 static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree,
1260 const char *name, bool dir)
1262 struct smb2_create io;
1265 smb2_util_unlink(tree, name);
1267 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1268 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1269 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1270 io.in.share_access =
1271 NTCREATEX_SHARE_ACCESS_DELETE|
1272 NTCREATEX_SHARE_ACCESS_READ|
1273 NTCREATEX_SHARE_ACCESS_WRITE;
1274 io.in.create_options = 0;
1277 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1278 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
1279 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1280 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1283 status = smb2_create(tree, mem_ctx, &io);
1284 if (!NT_STATUS_IS_OK(status)) {
1288 status = smb2_util_close(tree, io.out.file.handle);
1289 if (!NT_STATUS_IS_OK(status)) {
1296 static bool enable_aapl(struct torture_context *tctx,
1297 struct smb2_tree *tree)
1299 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1302 struct smb2_create io;
1304 struct smb2_create_blob *aapl = NULL;
1305 uint32_t aapl_server_caps;
1306 uint32_t expexted_scaps = (SMB2_CRTCTX_AAPL_UNIX_BASED |
1307 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1308 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1309 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
1310 bool is_osx_server = torture_setting_bool(tctx, "osx", false);
1313 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1314 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1315 io.in.create_disposition = NTCREATEX_DISP_OPEN;
1316 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1317 NTCREATEX_SHARE_ACCESS_READ |
1318 NTCREATEX_SHARE_ACCESS_WRITE);
1322 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1323 * controls behaviour of Apple's SMB2 extensions for the whole
1327 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1328 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1329 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1330 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1331 SMB2_CRTCTX_AAPL_MODEL_INFO));
1332 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1333 SMB2_CRTCTX_AAPL_UNIX_BASED |
1334 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1336 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1337 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_blob_add");
1339 status = smb2_create(tree, tctx, &io);
1340 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1342 status = smb2_util_close(tree, io.out.file.handle);
1343 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close");
1346 * Now check returned AAPL context
1348 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1350 aapl = smb2_create_blob_find(&io.out.blobs,
1351 SMB2_CREATE_TAG_AAPL);
1352 torture_assert_goto(tctx, aapl != NULL, ret, done, "missing AAPL context");
1354 if (!is_osx_server) {
1355 size_t exptected_aapl_ctx_size;
1357 exptected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
1359 torture_assert_goto(
1360 tctx, aapl->data.length == exptected_aapl_ctx_size,
1361 ret, done, "bad AAPL size");
1364 aapl_server_caps = BVAL(aapl->data.data, 16);
1365 torture_assert_goto(tctx, aapl_server_caps == expexted_scaps,
1366 ret, done, "bad AAPL caps");
1369 talloc_free(mem_ctx);
1373 static bool test_read_netatalk_metadata(struct torture_context *tctx,
1374 struct smb2_tree *tree)
1376 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1377 const char *fname = BASEDIR "\\torture_read_metadata";
1379 struct smb2_handle testdirh;
1382 const char *localdir = NULL;
1384 torture_comment(tctx, "Checking metadata access\n");
1386 localdir = torture_setting_string(tctx, "localdir", NULL);
1387 if (localdir == NULL) {
1388 torture_skip(tctx, "Need localdir for test");
1391 smb2_util_unlink(tree, fname);
1393 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1394 CHECK_STATUS(status, NT_STATUS_OK);
1395 smb2_util_close(tree, testdirh);
1397 ret = torture_setup_file(mem_ctx, tree, fname, false);
1402 ret = torture_setup_local_xattr(tctx, "localdir",
1403 BASEDIR "/torture_read_metadata",
1404 AFPINFO_EA_NETATALK,
1405 metadata_xattr, sizeof(metadata_xattr));
1410 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1411 0, 60, 0, 4, "AFP");
1412 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1414 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1415 0, 60, 16, 8, "BARRFOOO");
1416 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1418 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1419 16, 8, 0, 3, "AFP");
1420 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1422 /* Check reading offset and read size > sizeof(AFPINFO_STREAM) */
1424 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1425 AFPINFO_STREAM, 0, 61);
1426 CHECK_VALUE(len, 60);
1428 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1429 AFPINFO_STREAM, 59, 2);
1430 CHECK_VALUE(len, 2);
1432 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1433 AFPINFO_STREAM, 60, 1);
1434 CHECK_VALUE(len, 1);
1436 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1437 AFPINFO_STREAM, 61, 1);
1438 CHECK_VALUE(len, 0);
1441 smb2_deltree(tree, BASEDIR);
1442 talloc_free(mem_ctx);
1446 static bool test_read_afpinfo(struct torture_context *tctx,
1447 struct smb2_tree *tree)
1449 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1450 const char *fname = BASEDIR "\\torture_read_metadata";
1452 struct smb2_handle testdirh;
1456 const char *type_creator = "SMB,OLE!";
1458 torture_comment(tctx, "Checking metadata access\n");
1460 smb2_util_unlink(tree, fname);
1462 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1463 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
1464 smb2_util_close(tree, testdirh);
1466 ret = torture_setup_file(mem_ctx, tree, fname, false);
1467 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
1469 info = torture_afpinfo_new(mem_ctx);
1470 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
1472 memcpy(info->afpi_FinderInfo, type_creator, 8);
1473 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1474 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
1476 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1477 0, 60, 0, 4, "AFP");
1478 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1480 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1481 0, 60, 16, 8, type_creator);
1482 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1485 * OS X ignores offset <= 60 and treats the as
1486 * offset=0. Reading from offsets > 60 returns EOF=0.
1489 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1490 16, 8, 0, 8, "AFP\0\0\0\001\0");
1491 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1493 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1494 AFPINFO_STREAM, 0, 61);
1495 torture_assert_goto(tctx, len == 60, ret, done, "read_stream failed");
1497 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1498 AFPINFO_STREAM, 59, 2);
1499 torture_assert_goto(tctx, len == 2, ret, done, "read_stream failed");
1501 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1503 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1505 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1506 AFPINFO_STREAM, 60, 1);
1507 torture_assert_goto(tctx, len == 1, ret, done, "read_stream failed");
1509 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1511 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1513 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1514 AFPINFO_STREAM, 61, 1);
1515 torture_assert_goto(tctx, len == 0, ret, done, "read_stream failed");
1518 smb2_util_unlink(tree, fname);
1519 smb2_deltree(tree, BASEDIR);
1520 talloc_free(mem_ctx);
1524 static bool test_write_atalk_metadata(struct torture_context *tctx,
1525 struct smb2_tree *tree)
1527 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1528 const char *fname = BASEDIR "\\torture_write_metadata";
1529 const char *type_creator = "SMB,OLE!";
1531 struct smb2_handle testdirh;
1535 smb2_deltree(tree, BASEDIR);
1536 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1537 CHECK_STATUS(status, NT_STATUS_OK);
1538 smb2_util_close(tree, testdirh);
1540 ret = torture_setup_file(mem_ctx, tree, fname, false);
1545 info = torture_afpinfo_new(mem_ctx);
1550 memcpy(info->afpi_FinderInfo, type_creator, 8);
1551 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1552 ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1553 0, 60, 16, 8, type_creator);
1556 smb2_util_unlink(tree, fname);
1557 smb2_deltree(tree, BASEDIR);
1558 talloc_free(mem_ctx);
1562 static bool test_write_atalk_rfork_io(struct torture_context *tctx,
1563 struct smb2_tree *tree)
1565 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1566 const char *fname = BASEDIR "\\torture_write_rfork_io";
1567 const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
1568 const char *rfork_content = "1234567890";
1570 struct smb2_handle testdirh;
1574 struct smb2_handle filehandle;
1575 union smb_fileinfo finfo;
1576 union smb_setfileinfo sinfo;
1578 smb2_util_unlink(tree, fname);
1580 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1581 CHECK_STATUS(status, NT_STATUS_OK);
1582 smb2_util_close(tree, testdirh);
1584 ret = torture_setup_file(mem_ctx, tree, fname, false);
1589 torture_comment(tctx, "(%s) writing to resource fork\n",
1592 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1593 fname, AFPRESOURCE_STREAM_NAME,
1594 10, 10, rfork_content);
1596 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1597 fname, AFPRESOURCE_STREAM_NAME,
1598 0, 20, 10, 10, rfork_content);
1600 /* Check size after write */
1603 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1604 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1605 SEC_FILE_WRITE_ATTRIBUTE;
1606 io.smb2.in.fname = rfork;
1607 status = smb2_create(tree, mem_ctx, &(io.smb2));
1608 CHECK_STATUS(status, NT_STATUS_OK);
1609 filehandle = io.smb2.out.file.handle;
1611 torture_comment(tctx, "(%s) check resource fork size after write\n",
1615 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1616 finfo.generic.in.file.handle = filehandle;
1617 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1618 CHECK_STATUS(status, NT_STATUS_OK);
1619 if (finfo.all_info.out.size != 20) {
1620 torture_result(tctx, TORTURE_FAIL,
1621 "(%s) Incorrect resource fork size\n",
1624 smb2_util_close(tree, filehandle);
1627 smb2_util_close(tree, filehandle);
1629 /* Write at large offset */
1631 torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
1634 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1635 fname, AFPRESOURCE_STREAM_NAME,
1636 (off_t)1<<32, 10, rfork_content);
1638 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1639 fname, AFPRESOURCE_STREAM_NAME,
1640 (off_t)1<<32, 10, 0, 10, rfork_content);
1642 /* Truncate back to size of 1 byte */
1644 torture_comment(tctx, "(%s) truncate resource fork and check size\n",
1648 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1649 io.smb2.in.desired_access = SEC_FILE_ALL;
1650 io.smb2.in.fname = rfork;
1651 status = smb2_create(tree, mem_ctx, &(io.smb2));
1652 CHECK_STATUS(status, NT_STATUS_OK);
1653 filehandle = io.smb2.out.file.handle;
1656 sinfo.end_of_file_info.level =
1657 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1658 sinfo.end_of_file_info.in.file.handle = filehandle;
1659 sinfo.end_of_file_info.in.size = 1;
1660 status = smb2_setinfo_file(tree, &sinfo);
1661 CHECK_STATUS(status, NT_STATUS_OK);
1663 smb2_util_close(tree, filehandle);
1665 /* Now check size */
1667 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1668 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1669 SEC_FILE_WRITE_ATTRIBUTE;
1670 io.smb2.in.fname = rfork;
1671 status = smb2_create(tree, mem_ctx, &(io.smb2));
1672 CHECK_STATUS(status, NT_STATUS_OK);
1673 filehandle = io.smb2.out.file.handle;
1676 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1677 finfo.generic.in.file.handle = filehandle;
1678 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1679 CHECK_STATUS(status, NT_STATUS_OK);
1680 if (finfo.all_info.out.size != 1) {
1681 torture_result(tctx, TORTURE_FAIL,
1682 "(%s) Incorrect resource fork size\n",
1685 smb2_util_close(tree, filehandle);
1688 smb2_util_close(tree, filehandle);
1691 smb2_util_unlink(tree, fname);
1692 smb2_deltree(tree, BASEDIR);
1693 talloc_free(mem_ctx);
1697 static bool test_rfork_truncate(struct torture_context *tctx,
1698 struct smb2_tree *tree)
1700 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1701 const char *fname = BASEDIR "\\torture_rfork_truncate";
1702 const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
1703 const char *rfork_content = "1234567890";
1705 struct smb2_handle testdirh;
1707 struct smb2_create create;
1708 struct smb2_handle fh1, fh2, fh3;
1709 union smb_setfileinfo sinfo;
1711 smb2_util_unlink(tree, fname);
1713 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1714 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1715 smb2_util_close(tree, testdirh);
1717 ret = torture_setup_file(mem_ctx, tree, fname, false);
1722 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1723 fname, AFPRESOURCE_STREAM,
1724 10, 10, rfork_content);
1726 /* Truncate back to size 0, further access MUST return ENOENT */
1728 torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
1731 ZERO_STRUCT(create);
1732 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1733 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1734 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1735 create.in.fname = fname;
1736 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1737 NTCREATEX_SHARE_ACCESS_READ |
1738 NTCREATEX_SHARE_ACCESS_WRITE;
1739 status = smb2_create(tree, mem_ctx, &create);
1740 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1741 fh1 = create.out.file.handle;
1743 ZERO_STRUCT(create);
1744 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1745 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1746 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1747 create.in.fname = rfork;
1748 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1749 NTCREATEX_SHARE_ACCESS_READ |
1750 NTCREATEX_SHARE_ACCESS_WRITE;
1751 status = smb2_create(tree, mem_ctx, &create);
1752 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1753 fh2 = create.out.file.handle;
1756 sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1757 sinfo.end_of_file_info.in.file.handle = fh2;
1758 sinfo.end_of_file_info.in.size = 0;
1759 status = smb2_setinfo_file(tree, &sinfo);
1760 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
1763 * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
1765 ZERO_STRUCT(create);
1766 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1767 create.in.desired_access = SEC_FILE_ALL;
1768 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1769 create.in.fname = rfork;
1770 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1771 NTCREATEX_SHARE_ACCESS_READ |
1772 NTCREATEX_SHARE_ACCESS_WRITE;
1773 status = smb2_create(tree, mem_ctx, &create);
1774 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1777 * Do another open on the rfork and write to the new handle. A
1778 * naive server might unlink the AppleDouble resource fork
1779 * file when its truncated to 0 bytes above, so in case both
1780 * open handles share the same underlying fd, the unlink would
1781 * cause the below write to be lost.
1783 ZERO_STRUCT(create);
1784 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1785 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1786 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1787 create.in.fname = rfork;
1788 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1789 NTCREATEX_SHARE_ACCESS_READ |
1790 NTCREATEX_SHARE_ACCESS_WRITE;
1791 status = smb2_create(tree, mem_ctx, &create);
1792 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1793 fh3 = create.out.file.handle;
1795 status = smb2_util_write(tree, fh3, "foo", 0, 3);
1796 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
1798 smb2_util_close(tree, fh3);
1799 smb2_util_close(tree, fh2);
1800 smb2_util_close(tree, fh1);
1802 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
1804 torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1807 smb2_util_unlink(tree, fname);
1808 smb2_deltree(tree, BASEDIR);
1809 talloc_free(mem_ctx);
1813 static bool test_rfork_create(struct torture_context *tctx,
1814 struct smb2_tree *tree)
1816 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1817 const char *fname = BASEDIR "\\torture_rfork_create";
1818 const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1820 struct smb2_handle testdirh;
1822 struct smb2_create create;
1823 struct smb2_handle fh1;
1824 const char *streams[] = {
1827 union smb_fileinfo finfo;
1829 smb2_util_unlink(tree, fname);
1831 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1832 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1833 smb2_util_close(tree, testdirh);
1835 ret = torture_setup_file(mem_ctx, tree, fname, false);
1840 torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
1843 ZERO_STRUCT(create);
1844 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1845 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1846 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1847 create.in.fname = rfork;
1848 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1849 NTCREATEX_SHARE_ACCESS_READ |
1850 NTCREATEX_SHARE_ACCESS_WRITE;
1851 status = smb2_create(tree, mem_ctx, &create);
1852 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1854 torture_comment(tctx, "(%s) create resource fork\n", __location__);
1856 ZERO_STRUCT(create);
1857 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1858 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1859 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1860 create.in.fname = rfork;
1861 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1862 NTCREATEX_SHARE_ACCESS_READ |
1863 NTCREATEX_SHARE_ACCESS_WRITE;
1864 status = smb2_create(tree, mem_ctx, &create);
1865 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1866 fh1 = create.out.file.handle;
1868 torture_comment(tctx, "(%s) getinfo on create handle\n",
1872 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1873 finfo.generic.in.file.handle = fh1;
1874 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1875 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
1876 if (finfo.all_info.out.size != 0) {
1877 torture_result(tctx, TORTURE_FAIL,
1878 "(%s) Incorrect resource fork size\n",
1881 smb2_util_close(tree, fh1);
1885 torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
1888 ZERO_STRUCT(create);
1889 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1890 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1891 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1892 create.in.fname = rfork;
1893 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1894 NTCREATEX_SHARE_ACCESS_READ |
1895 NTCREATEX_SHARE_ACCESS_WRITE;
1896 status = smb2_create(tree, mem_ctx, &create);
1897 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1899 ret = check_stream_list(tree, tctx, fname, 1, streams, false);
1900 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
1902 torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
1905 ZERO_STRUCT(create);
1906 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1907 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1908 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1909 create.in.fname = rfork;
1910 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1911 NTCREATEX_SHARE_ACCESS_READ |
1912 NTCREATEX_SHARE_ACCESS_WRITE;
1913 status = smb2_create(tree, mem_ctx, &create);
1914 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1917 smb2_util_unlink(tree, fname);
1918 smb2_deltree(tree, BASEDIR);
1919 talloc_free(mem_ctx);
1923 static bool test_rfork_create_ro(struct torture_context *tctx,
1924 struct smb2_tree *tree)
1926 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1927 const char *fname = BASEDIR "\\torture_rfork_create";
1928 const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1930 struct smb2_handle testdirh;
1932 struct smb2_create create;
1934 smb2_util_unlink(tree, fname);
1935 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1936 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1937 "torture_smb2_testdir\n");
1938 smb2_util_close(tree, testdirh);
1940 ret = torture_setup_file(mem_ctx, tree, fname, false);
1945 torture_comment(tctx, "(%s) Try opening read-only with "
1946 "open_if create disposition, should return ENOENT\n",
1949 ZERO_STRUCT(create);
1950 create.in.fname = rfork;
1951 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1952 create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
1953 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1954 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
1955 status = smb2_create(tree, mem_ctx, &(create));
1956 torture_assert_ntstatus_equal_goto(tctx, status,
1957 NT_STATUS_OBJECT_NAME_NOT_FOUND,
1958 ret, done, "smb2_create failed\n");
1960 torture_comment(tctx, "(%s) Now write something to the "
1961 "rsrc stream, then the same open should succeed\n",
1964 ret = write_stream(tree, __location__, tctx, mem_ctx,
1965 fname, AFPRESOURCE_STREAM_NAME,
1967 torture_assert_goto(tctx, ret == true, ret, done,
1968 "write_stream failed\n");
1970 ret = check_stream(tree, __location__, tctx, mem_ctx,
1971 fname, AFPRESOURCE_STREAM,
1973 torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1975 ZERO_STRUCT(create);
1976 create.in.fname = rfork;
1977 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1978 create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
1979 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1980 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
1981 status = smb2_create(tree, mem_ctx, &(create));
1982 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1983 "smb2_create failed\n");
1985 smb2_util_close(tree, create.out.file.handle);
1988 smb2_util_unlink(tree, fname);
1989 smb2_deltree(tree, BASEDIR);
1990 talloc_free(mem_ctx);
1994 static bool test_adouble_conversion(struct torture_context *tctx,
1995 struct smb2_tree *tree)
1997 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1998 const char *fname = BASEDIR "\\test_adouble_conversion";
1999 const char *fname_local = BASEDIR "/test_adouble_conversion";
2000 const char *adname_local = BASEDIR "/._test_adouble_conversion";
2002 struct smb2_handle testdirh;
2004 const char *data = "This resource fork intentionally left blank";
2005 size_t datalen = strlen(data);
2006 const char *localdir = NULL;
2008 localdir = torture_setting_string(tctx, "localdir", NULL);
2009 if (localdir == NULL) {
2010 torture_skip(tctx, "Need localdir for test");
2013 smb2_util_unlink(tree, fname);
2015 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2016 CHECK_STATUS(status, NT_STATUS_OK);
2017 smb2_util_close(tree, testdirh);
2019 ret = torture_setup_local_file(tctx, "localdir", fname_local,
2025 ret = torture_setup_local_file(tctx, "localdir", adname_local,
2026 osx_adouble_w_xattr,
2027 sizeof(osx_adouble_w_xattr));
2032 torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
2035 ret &= check_stream(tree, __location__, tctx, mem_ctx,
2036 fname, AFPRESOURCE_STREAM,
2037 16, datalen, 0, datalen, data);
2040 smb2_deltree(tree, BASEDIR);
2041 talloc_free(mem_ctx);
2045 static bool test_aapl(struct torture_context *tctx,
2046 struct smb2_tree *tree)
2048 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2049 const char *fname = BASEDIR "\\test_aapl";
2051 struct smb2_handle testdirh;
2053 struct smb2_create io;
2055 struct smb2_create_blob *aapl = NULL;
2057 const char *type_creator = "SMB,OLE!";
2058 char type_creator_buf[9];
2060 uint32_t aapl_reply_bitmap;
2061 uint32_t aapl_server_caps;
2062 uint32_t aapl_vol_caps;
2066 union smb_search_data *d;
2069 smb2_deltree(tree, BASEDIR);
2071 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2072 CHECK_STATUS(status, NT_STATUS_OK);
2073 smb2_util_close(tree, testdirh);
2076 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2077 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2078 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2079 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2080 NTCREATEX_SHARE_ACCESS_READ |
2081 NTCREATEX_SHARE_ACCESS_WRITE);
2082 io.in.fname = fname;
2085 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
2086 * controls behaviour of Apple's SMB2 extensions for the whole
2090 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2091 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2092 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2093 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2094 SMB2_CRTCTX_AAPL_MODEL_INFO));
2095 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2096 SMB2_CRTCTX_AAPL_UNIX_BASED |
2097 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
2099 torture_comment(tctx, "Testing SMB2 create context AAPL\n");
2100 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2101 CHECK_STATUS(status, NT_STATUS_OK);
2103 status = smb2_create(tree, tctx, &io);
2104 CHECK_STATUS(status, NT_STATUS_OK);
2105 status = smb2_util_close(tree, io.out.file.handle);
2106 CHECK_STATUS(status, NT_STATUS_OK);
2109 * Now check returned AAPL context
2111 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
2113 aapl = smb2_create_blob_find(&io.out.blobs,
2114 SMB2_CREATE_TAG_AAPL);
2117 torture_result(tctx, TORTURE_FAIL,
2118 "(%s) unexpectedly no AAPL capabilities were returned.",
2124 if (aapl->data.length != 50) {
2126 * uint32_t CommandCode = kAAPL_SERVER_QUERY
2127 * uint32_t Reserved = 0;
2128 * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
2129 * kAAPL_VOLUME_CAPS |
2131 * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
2132 * kAAPL_SUPPORTS_OSX_COPYFILE;
2133 * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
2134 * kAAPL_CASE_SENSITIVE;
2135 * uint32_t Pad2 = 0;
2136 * uint32_t ModelStringLen = 10;
2137 * ucs2_t ModelString[5] = "Samba";
2139 torture_warning(tctx,
2140 "(%s) unexpected AAPL context length: %zd, expected 50",
2141 __location__, aapl->data.length);
2144 aapl_cmd = IVAL(aapl->data.data, 0);
2145 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2146 torture_result(tctx, TORTURE_FAIL,
2147 "(%s) unexpected cmd: %d",
2148 __location__, (int)aapl_cmd);
2153 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2154 if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2155 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2156 SMB2_CRTCTX_AAPL_MODEL_INFO)) {
2157 torture_result(tctx, TORTURE_FAIL,
2158 "(%s) unexpected reply_bitmap: %d",
2159 __location__, (int)aapl_reply_bitmap);
2164 aapl_server_caps = BVAL(aapl->data.data, 16);
2165 if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
2166 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2167 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
2168 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
2169 torture_result(tctx, TORTURE_FAIL,
2170 "(%s) unexpected server_caps: %d",
2171 __location__, (int)aapl_server_caps);
2176 aapl_vol_caps = BVAL(aapl->data.data, 24);
2177 if (aapl_vol_caps != 0) {
2178 /* this will fail on a case insensitive fs ... */
2179 torture_result(tctx, TORTURE_FAIL,
2180 "(%s) unexpected vol_caps: %d",
2181 __location__, (int)aapl_vol_caps);
2184 ret = convert_string_talloc(mem_ctx,
2185 CH_UTF16LE, CH_UNIX,
2186 aapl->data.data + 40, 10,
2189 torture_result(tctx, TORTURE_FAIL,
2190 "(%s) convert_string_talloc() failed",
2194 torture_comment(tctx, "Got server model: \"%s\"\n", model);
2197 * Now that Requested AAPL extensions are enabled, setup some
2198 * Mac files with metadata and resource fork
2200 ret = torture_setup_file(mem_ctx, tree, fname, false);
2202 torture_result(tctx, TORTURE_FAIL,
2203 "(%s) torture_setup_file() failed",
2208 info = torture_afpinfo_new(mem_ctx);
2210 torture_result(tctx, TORTURE_FAIL,
2211 "(%s) torture_afpinfo_new() failed",
2217 memcpy(info->afpi_FinderInfo, type_creator, 8);
2218 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2220 torture_result(tctx, TORTURE_FAIL,
2221 "(%s) torture_write_afpinfo() failed",
2226 ret = write_stream(tree, __location__, tctx, mem_ctx,
2227 fname, AFPRESOURCE_STREAM_NAME,
2230 torture_result(tctx, TORTURE_FAIL,
2231 "(%s) write_stream() failed",
2237 * Ok, file is prepared, now call smb2/find
2241 io.in.desired_access = SEC_RIGHTS_DIR_READ;
2242 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2243 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2244 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
2245 NTCREATEX_SHARE_ACCESS_WRITE |
2246 NTCREATEX_SHARE_ACCESS_DELETE);
2247 io.in.create_disposition = NTCREATEX_DISP_OPEN;
2248 io.in.fname = BASEDIR;
2249 status = smb2_create(tree, tctx, &io);
2250 CHECK_STATUS(status, NT_STATUS_OK);
2253 f.in.file.handle = io.out.file.handle;
2254 f.in.pattern = "test_aapl";
2255 f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
2256 f.in.max_response_size = 0x1000;
2257 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
2259 status = smb2_find_level(tree, tree, &f, &count, &d);
2260 CHECK_STATUS(status, NT_STATUS_OK);
2262 status = smb2_util_close(tree, io.out.file.handle);
2263 CHECK_STATUS(status, NT_STATUS_OK);
2265 if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2266 torture_result(tctx, TORTURE_FAIL,
2267 "(%s) write_stream() failed",
2273 if (d[0].id_both_directory_info.short_name.private_length != 24) {
2274 torture_result(tctx, TORTURE_FAIL,
2275 "(%s) bad short_name length %" PRIu32 ", expected 24",
2276 __location__, d[0].id_both_directory_info.short_name.private_length);
2281 torture_comment(tctx, "short_name buffer:\n");
2282 dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2285 * Extract data as specified by the AAPL extension:
2286 * - ea_size contains max_access
2287 * - short_name contains resource fork length + FinderInfo
2288 * - reserved2 contains the unix mode
2290 torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2291 d[0].id_both_directory_info.ea_size);
2293 rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2294 if (rfork_len != 3) {
2295 torture_result(tctx, TORTURE_FAIL,
2296 "(%s) expected resource fork length 3, got: %" PRIu64,
2297 __location__, rfork_len);
2302 memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2303 type_creator_buf[8] = 0;
2304 if (strcmp(type_creator, type_creator_buf) != 0) {
2305 torture_result(tctx, TORTURE_FAIL,
2306 "(%s) expected type/creator \"%s\" , got: %s",
2307 __location__, type_creator, type_creator_buf);
2313 smb2_util_unlink(tree, fname);
2314 smb2_deltree(tree, BASEDIR);
2315 talloc_free(mem_ctx);
2319 static uint64_t patt_hash(uint64_t off)
2324 static bool write_pattern(struct torture_context *torture,
2325 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2326 struct smb2_handle h, uint64_t off, uint64_t len,
2332 uint64_t io_sz = MIN(1024 * 64, len);
2338 torture_assert(torture, (len % 8) == 0, "invalid write len");
2340 buf = talloc_zero_size(mem_ctx, io_sz);
2341 torture_assert(torture, (buf != NULL), "no memory for file data buf");
2344 for (i = 0; i <= io_sz - 8; i += 8) {
2345 SBVAL(buf, i, patt_hash(patt_off));
2349 status = smb2_util_write(tree, h,
2351 torture_assert_ntstatus_ok(torture, status, "file write");
2362 static bool check_pattern(struct torture_context *torture,
2363 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2364 struct smb2_handle h, uint64_t off, uint64_t len,
2371 torture_assert(torture, (len % 8) == 0, "invalid read len");
2377 uint64_t io_sz = MIN(1024 * 64, len);
2380 r.in.file.handle = h;
2381 r.in.length = io_sz;
2383 status = smb2_read(tree, mem_ctx, &r);
2384 torture_assert_ntstatus_ok(torture, status, "read");
2386 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2387 "read data len mismatch");
2389 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2390 uint64_t data = BVAL(r.out.data.data, i);
2391 torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2392 talloc_asprintf(torture, "read data "
2393 "pattern bad at %llu\n",
2394 (unsigned long long)off + i));
2396 talloc_free(r.out.data.data);
2404 static bool test_setup_open(struct torture_context *torture,
2405 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2407 struct smb2_handle *fh,
2408 uint32_t desired_access,
2409 uint32_t file_attributes)
2411 struct smb2_create io;
2415 io.in.desired_access = desired_access;
2416 io.in.file_attributes = file_attributes;
2417 io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2418 io.in.share_access =
2419 NTCREATEX_SHARE_ACCESS_DELETE|
2420 NTCREATEX_SHARE_ACCESS_READ|
2421 NTCREATEX_SHARE_ACCESS_WRITE;
2422 if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2423 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2425 io.in.fname = fname;
2427 status = smb2_create(tree, mem_ctx, &io);
2428 torture_assert_ntstatus_ok(torture, status, "file create");
2430 *fh = io.out.file.handle;
2435 static bool test_setup_create_fill(struct torture_context *torture,
2436 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2438 struct smb2_handle *fh,
2440 uint32_t desired_access,
2441 uint32_t file_attributes)
2445 ok = test_setup_open(torture, tree, mem_ctx,
2450 torture_assert(torture, ok, "file open");
2453 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2454 torture_assert(torture, ok, "write pattern");
2459 static bool test_setup_copy_chunk(struct torture_context *torture,
2460 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2462 const char *src_name,
2463 struct smb2_handle *src_h,
2465 uint32_t src_desired_access,
2466 const char *dst_name,
2467 struct smb2_handle *dest_h,
2469 uint32_t dest_desired_access,
2470 struct srv_copychunk_copy *cc_copy,
2471 union smb_ioctl *io)
2473 struct req_resume_key_rsp res_key;
2476 enum ndr_err_code ndr_ret;
2478 ok = test_setup_create_fill(torture, tree, mem_ctx, src_name,
2479 src_h, src_size, src_desired_access,
2480 FILE_ATTRIBUTE_NORMAL);
2481 torture_assert(torture, ok, "src file create fill");
2483 ok = test_setup_create_fill(torture, tree, mem_ctx, dst_name,
2484 dest_h, dest_size, dest_desired_access,
2485 FILE_ATTRIBUTE_NORMAL);
2486 torture_assert(torture, ok, "dest file create fill");
2489 io->smb2.level = RAW_IOCTL_SMB2;
2490 io->smb2.in.file.handle = *src_h;
2491 io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2492 /* Allow for Key + ContextLength + Context */
2493 io->smb2.in.max_response_size = 32;
2494 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2496 status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2497 torture_assert_ntstatus_ok(torture, status,
2498 "FSCTL_SRV_REQUEST_RESUME_KEY");
2500 ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2501 (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2503 torture_assert_ndr_success(torture, ndr_ret,
2504 "ndr_pull_req_resume_key_rsp");
2507 io->smb2.level = RAW_IOCTL_SMB2;
2508 io->smb2.in.file.handle = *dest_h;
2509 io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2510 io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2511 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2513 ZERO_STRUCTPN(cc_copy);
2514 memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2515 cc_copy->chunk_count = nchunks;
2516 cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2517 torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2523 static bool check_copy_chunk_rsp(struct torture_context *torture,
2524 struct srv_copychunk_rsp *cc_rsp,
2525 uint32_t ex_chunks_written,
2526 uint32_t ex_chunk_bytes_written,
2527 uint32_t ex_total_bytes_written)
2529 torture_assert_int_equal(torture, cc_rsp->chunks_written,
2530 ex_chunks_written, "num chunks");
2531 torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2532 ex_chunk_bytes_written, "chunk bytes written");
2533 torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2534 ex_total_bytes_written, "chunk total bytes");
2538 static bool neg_aapl_copyfile(struct torture_context *tctx,
2539 struct smb2_tree *tree,
2542 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2543 const char *fname = "aapl";
2545 struct smb2_create io;
2547 struct smb2_create_blob *aapl = NULL;
2549 uint32_t aapl_reply_bitmap;
2550 uint32_t aapl_server_caps;
2554 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2555 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2556 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2557 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2558 NTCREATEX_SHARE_ACCESS_READ |
2559 NTCREATEX_SHARE_ACCESS_WRITE);
2560 io.in.fname = fname;
2562 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2563 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2564 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2565 SBVAL(data.data, 16, flags);
2567 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2568 CHECK_STATUS(status, NT_STATUS_OK);
2570 status = smb2_create(tree, tctx, &io);
2571 CHECK_STATUS(status, NT_STATUS_OK);
2573 aapl = smb2_create_blob_find(&io.out.blobs,
2574 SMB2_CREATE_TAG_AAPL);
2580 if (aapl->data.length < 24) {
2585 aapl_cmd = IVAL(aapl->data.data, 0);
2586 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2587 torture_result(tctx, TORTURE_FAIL,
2588 "(%s) unexpected cmd: %d",
2589 __location__, (int)aapl_cmd);
2594 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2595 if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2596 torture_result(tctx, TORTURE_FAIL,
2597 "(%s) unexpected reply_bitmap: %d",
2598 __location__, (int)aapl_reply_bitmap);
2603 aapl_server_caps = BVAL(aapl->data.data, 16);
2604 if (!(aapl_server_caps & flags)) {
2605 torture_result(tctx, TORTURE_FAIL,
2606 "(%s) unexpected server_caps: %d",
2607 __location__, (int)aapl_server_caps);
2613 status = smb2_util_close(tree, io.out.file.handle);
2614 CHECK_STATUS(status, NT_STATUS_OK);
2616 smb2_util_unlink(tree, "aapl");
2617 talloc_free(mem_ctx);
2621 static bool test_copyfile(struct torture_context *torture,
2622 struct smb2_tree *tree)
2624 struct smb2_handle src_h;
2625 struct smb2_handle dest_h;
2628 TALLOC_CTX *tmp_ctx = talloc_new(tree);
2629 struct srv_copychunk_copy cc_copy;
2630 struct srv_copychunk_rsp cc_rsp;
2631 enum ndr_err_code ndr_ret;
2633 const char *sname = ":foo" "\xef\x80\xa2" "bar:$DATA";
2636 * First test a copy_chunk with a 0 chunk count without having
2637 * enabled this via AAPL. The request must not fail and the
2638 * copied length in the response must be 0. This is verified
2639 * against Windows 2008r2.
2642 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2643 0, /* 0 chunks, copyfile semantics */
2645 &src_h, 4096, /* fill 4096 byte src file */
2646 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2648 &dest_h, 0, /* 0 byte dest file */
2649 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2653 torture_fail_goto(torture, done, "setup copy chunk error");
2656 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2658 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2659 torture_assert_ndr_success(torture, ndr_ret,
2660 "ndr_push_srv_copychunk_copy");
2662 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2663 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2665 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2667 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2668 torture_assert_ndr_success(torture, ndr_ret,
2669 "ndr_pull_srv_copychunk_rsp");
2671 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2672 0, /* chunks written */
2673 0, /* chunk bytes unsuccessfully written */
2674 0); /* total bytes written */
2676 torture_fail_goto(torture, done, "bad copy chunk response data");
2680 * Now enable AAPL copyfile and test again, the file and the
2681 * stream must be copied by the server.
2683 ok = neg_aapl_copyfile(torture, tree,
2684 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2686 torture_skip_goto(torture, done, "missing AAPL copyfile");
2690 smb2_util_close(tree, src_h);
2691 smb2_util_close(tree, dest_h);
2692 smb2_util_unlink(tree, FNAME_CC_SRC);
2693 smb2_util_unlink(tree, FNAME_CC_DST);
2695 ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2697 torture_fail(torture, "setup file error");
2699 ok = write_stream(tree, __location__, torture, tmp_ctx,
2700 FNAME_CC_SRC, AFPRESOURCE_STREAM,
2701 10, 10, "1234567890");
2703 torture_fail(torture, "setup stream error");
2706 ok = write_stream(tree, __location__, torture, tmp_ctx,
2707 FNAME_CC_SRC, sname,
2708 10, 10, "abcdefghij");
2709 torture_assert_goto(torture, ok == true, ok, done, "write_stream failed\n");
2711 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2712 0, /* 0 chunks, copyfile semantics */
2714 &src_h, 4096, /* fill 4096 byte src file */
2715 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2717 &dest_h, 0, /* 0 byte dest file */
2718 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2722 torture_fail_goto(torture, done, "setup copy chunk error");
2725 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2727 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2728 torture_assert_ndr_success(torture, ndr_ret,
2729 "ndr_push_srv_copychunk_copy");
2731 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2732 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2734 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2736 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2737 torture_assert_ndr_success(torture, ndr_ret,
2738 "ndr_pull_srv_copychunk_rsp");
2740 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2741 0, /* chunks written */
2742 0, /* chunk bytes unsuccessfully written */
2743 4096); /* total bytes written */
2745 torture_fail_goto(torture, done, "bad copy chunk response data");
2748 ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
2749 SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
2751 torture_fail_goto(torture, done,"open failed");
2753 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
2755 torture_fail_goto(torture, done, "inconsistent file data");
2758 ok = check_stream(tree, __location__, torture, tmp_ctx,
2759 FNAME_CC_DST, AFPRESOURCE_STREAM,
2760 0, 20, 10, 10, "1234567890");
2762 torture_fail_goto(torture, done, "inconsistent stream data");
2765 ok = check_stream(tree, __location__, torture, tmp_ctx,
2766 FNAME_CC_DST, sname,
2767 0, 20, 10, 10, "abcdefghij");
2768 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
2771 smb2_util_close(tree, src_h);
2772 smb2_util_close(tree, dest_h);
2773 smb2_util_unlink(tree, FNAME_CC_SRC);
2774 smb2_util_unlink(tree, FNAME_CC_DST);
2775 talloc_free(tmp_ctx);
2779 static bool check_stream_list(struct smb2_tree *tree,
2780 struct torture_context *tctx,
2787 union smb_fileinfo finfo;
2790 TALLOC_CTX *tmp_ctx = talloc_new(tctx);
2792 struct stream_struct *stream_sort;
2793 struct smb2_create create;
2794 struct smb2_handle h;
2797 torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
2799 ZERO_STRUCT(create);
2800 create.in.fname = fname;
2801 create.in.create_disposition = NTCREATEX_DISP_OPEN;
2802 create.in.desired_access = SEC_FILE_ALL;
2803 create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
2804 create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
2805 status = smb2_create(tree, tmp_ctx, &create);
2806 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2807 h = create.out.file.handle;
2809 finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
2810 finfo.generic.in.file.handle = h;
2812 status = smb2_getinfo_file(tree, tctx, &finfo);
2813 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
2815 smb2_util_close(tree, h);
2817 torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
2818 ret, done, "stream count");
2821 TALLOC_FREE(tmp_ctx);
2825 exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
2826 torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
2828 TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
2830 stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
2831 finfo.stream_info.out.num_streams *
2832 sizeof(*stream_sort));
2833 torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
2835 TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
2837 for (i=0; i<num_exp; i++) {
2838 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
2839 i, exp_sort[i], stream_sort[i].stream_name.s);
2840 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
2841 ret, done, "stream name");
2845 TALLOC_FREE(tmp_ctx);
2852 static bool test_stream_names(struct torture_context *tctx,
2853 struct smb2_tree *tree)
2855 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2857 struct smb2_create create;
2858 struct smb2_handle h;
2859 const char *fname = BASEDIR "\\stream_names.txt";
2862 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
2863 const char *streams[] = {
2864 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2865 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
2868 const char *localdir = NULL;
2870 localdir = torture_setting_string(tctx, "localdir", NULL);
2871 if (localdir == NULL) {
2872 torture_skip(tctx, "Need localdir for test");
2875 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
2877 /* clean slate ...*/
2878 smb2_util_unlink(tree, fname);
2879 smb2_deltree(tree, fname);
2880 smb2_deltree(tree, BASEDIR);
2882 status = torture_smb2_testdir(tree, BASEDIR, &h);
2883 CHECK_STATUS(status, NT_STATUS_OK);
2884 smb2_util_close(tree, h);
2886 torture_comment(tctx, "(%s) testing stream names\n", __location__);
2887 ZERO_STRUCT(create);
2888 create.in.desired_access = SEC_FILE_WRITE_DATA;
2889 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2890 create.in.share_access =
2891 NTCREATEX_SHARE_ACCESS_DELETE|
2892 NTCREATEX_SHARE_ACCESS_READ|
2893 NTCREATEX_SHARE_ACCESS_WRITE;
2894 create.in.create_disposition = NTCREATEX_DISP_CREATE;
2895 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2896 create.in.fname = sname1;
2898 status = smb2_create(tree, mem_ctx, &create);
2899 CHECK_STATUS(status, NT_STATUS_OK);
2900 smb2_util_close(tree, create.out.file.handle);
2902 ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
2903 "user.DosStream.bar:baz:$DATA",
2904 "data", strlen("data"));
2905 CHECK_VALUE(ret, true);
2907 ret = check_stream_list(tree, tctx, fname, 3, streams, false);
2908 CHECK_VALUE(ret, true);
2911 status = smb2_util_unlink(tree, fname);
2912 smb2_deltree(tree, BASEDIR);
2913 talloc_free(mem_ctx);
2918 /* Renaming a directory with open file, should work for OS X AAPL clients */
2919 static bool test_rename_dir_openfile(struct torture_context *torture,
2920 struct smb2_tree *tree)
2926 union smb_setfileinfo sinfo;
2927 struct smb2_handle d1, h1;
2928 const char *renamedir = BASEDIR "-new";
2929 bool server_is_osx = torture_setting_bool(torture, "osx", false);
2931 smb2_deltree(tree, BASEDIR);
2932 smb2_util_rmdir(tree, BASEDIR);
2933 smb2_deltree(tree, renamedir);
2935 ZERO_STRUCT(io.smb2);
2936 io.generic.level = RAW_OPEN_SMB2;
2937 io.smb2.in.create_flags = 0;
2938 io.smb2.in.desired_access = 0x0017019f;
2939 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2940 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2941 io.smb2.in.share_access = 0;
2942 io.smb2.in.alloc_size = 0;
2943 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2944 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2945 io.smb2.in.security_flags = 0;
2946 io.smb2.in.fname = BASEDIR;
2948 status = smb2_create(tree, torture, &(io.smb2));
2949 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2950 d1 = io.smb2.out.file.handle;
2952 ZERO_STRUCT(io.smb2);
2953 io.generic.level = RAW_OPEN_SMB2;
2954 io.smb2.in.create_flags = 0;
2955 io.smb2.in.desired_access = 0x0017019f;
2956 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2957 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2958 io.smb2.in.share_access = 0;
2959 io.smb2.in.alloc_size = 0;
2960 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2961 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2962 io.smb2.in.security_flags = 0;
2963 io.smb2.in.fname = BASEDIR "\\file.txt";
2965 status = smb2_create(tree, torture, &(io.smb2));
2966 torture_assert_ntstatus_ok(torture, status, "smb2_create file");
2967 h1 = io.smb2.out.file.handle;
2969 if (!server_is_osx) {
2970 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
2973 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2974 sinfo.rename_information.in.file.handle = d1;
2975 sinfo.rename_information.in.overwrite = 0;
2976 sinfo.rename_information.in.root_fid = 0;
2977 sinfo.rename_information.in.new_name = renamedir;
2978 status = smb2_setinfo_file(tree, &sinfo);
2980 torture_assert_ntstatus_equal(torture, status,
2981 NT_STATUS_ACCESS_DENIED,
2982 "smb2_setinfo_file");
2984 ZERO_STRUCT(cl.smb2);
2985 cl.smb2.level = RAW_CLOSE_SMB2;
2986 cl.smb2.in.file.handle = d1;
2987 status = smb2_close(tree, &(cl.smb2));
2988 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2992 torture_comment(torture, "Enabling AAPL\n");
2994 ret = enable_aapl(torture, tree);
2995 torture_assert(torture, ret == true, "enable_aapl failed");
2997 torture_comment(torture, "Renaming directory with AAPL\n");
2999 ZERO_STRUCT(io.smb2);
3000 io.generic.level = RAW_OPEN_SMB2;
3001 io.smb2.in.desired_access = 0x0017019f;
3002 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3003 io.smb2.in.share_access = 0;
3004 io.smb2.in.alloc_size = 0;
3005 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
3006 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
3007 io.smb2.in.security_flags = 0;
3008 io.smb2.in.fname = BASEDIR;
3010 status = smb2_create(tree, torture, &(io.smb2));
3011 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
3012 d1 = io.smb2.out.file.handle;
3015 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3016 sinfo.rename_information.in.file.handle = d1;
3017 sinfo.rename_information.in.overwrite = 0;
3018 sinfo.rename_information.in.root_fid = 0;
3019 sinfo.rename_information.in.new_name = renamedir;
3021 status = smb2_setinfo_file(tree, &sinfo);
3022 torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
3024 ZERO_STRUCT(cl.smb2);
3025 cl.smb2.level = RAW_CLOSE_SMB2;
3026 cl.smb2.in.file.handle = d1;
3027 status = smb2_close(tree, &(cl.smb2));
3028 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3031 cl.smb2.in.file.handle = h1;
3032 status = smb2_close(tree, &(cl.smb2));
3033 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3036 torture_comment(torture, "Cleaning up\n");
3038 if (h1.data[0] || h1.data[1]) {
3039 ZERO_STRUCT(cl.smb2);
3040 cl.smb2.level = RAW_CLOSE_SMB2;
3041 cl.smb2.in.file.handle = h1;
3042 status = smb2_close(tree, &(cl.smb2));
3045 smb2_util_unlink(tree, BASEDIR "\\file.txt");
3046 smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
3047 smb2_deltree(tree, renamedir);
3048 smb2_deltree(tree, BASEDIR);
3052 static bool test_afpinfo_enoent(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;
3063 torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
3065 smb2_deltree(tree, BASEDIR);
3066 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3067 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3068 smb2_util_close(tree, h1);
3069 ret = torture_setup_file(mem_ctx, tree, fname, false);
3070 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3072 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3074 ZERO_STRUCT(create);
3075 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3076 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3077 create.in.fname = sname;
3079 status = smb2_create(tree, mem_ctx, &create);
3080 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3081 ret, done, "Got unexpected AFP_AfpInfo stream");
3084 smb2_util_unlink(tree, fname);
3085 smb2_util_rmdir(tree, BASEDIR);
3089 static bool test_create_delete_on_close(struct torture_context *tctx,
3090 struct smb2_tree *tree)
3094 struct smb2_create create;
3095 struct smb2_handle h1;
3096 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3097 const char *fname = BASEDIR "\\file";
3098 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3099 const char *type_creator = "SMB,OLE!";
3100 AfpInfo *info = NULL;
3101 const char *streams_basic[] = {
3104 const char *streams_afpinfo[] = {
3109 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3111 torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
3113 smb2_deltree(tree, BASEDIR);
3114 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3115 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3116 smb2_util_close(tree, h1);
3117 ret = torture_setup_file(mem_ctx, tree, fname, false);
3118 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3120 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3122 ZERO_STRUCT(create);
3123 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3124 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3125 create.in.fname = sname;
3127 status = smb2_create(tree, mem_ctx, &create);
3128 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3129 ret, done, "Got unexpected AFP_AfpInfo stream");
3131 ZERO_STRUCT(create);
3132 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3133 create.in.desired_access = SEC_FILE_ALL;
3134 create.in.fname = sname;
3136 status = smb2_create(tree, mem_ctx, &create);
3137 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3138 ret, done, "Got unexpected AFP_AfpInfo stream");
3140 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3141 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3143 torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
3145 info = torture_afpinfo_new(mem_ctx);
3146 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3148 memcpy(info->afpi_FinderInfo, type_creator, 8);
3149 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3150 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3152 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3153 0, 60, 16, 8, type_creator);
3154 torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
3156 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3157 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3159 ZERO_STRUCT(create);
3160 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3161 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3162 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3163 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3164 create.in.fname = sname;
3165 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3167 status = smb2_create(tree, mem_ctx, &create);
3168 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3170 h1 = create.out.file.handle;
3171 smb2_util_close(tree, h1);
3173 ZERO_STRUCT(create);
3174 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3175 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
3176 create.in.fname = sname;
3177 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3178 status = smb2_create(tree, mem_ctx, &create);
3179 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3180 ret, done, "Got unexpected AFP_AfpInfo stream");
3182 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3183 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3186 smb2_util_unlink(tree, fname);
3187 smb2_util_rmdir(tree, BASEDIR);
3191 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
3192 struct smb2_tree *tree)
3196 struct smb2_create create;
3197 union smb_setfileinfo sfinfo;
3198 struct smb2_handle h1;
3199 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3200 const char *fname = BASEDIR "\\file";
3201 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3202 const char *type_creator = "SMB,OLE!";
3203 AfpInfo *info = NULL;
3204 const char *streams_basic[] = {
3208 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3210 torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
3212 smb2_deltree(tree, BASEDIR);
3213 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3214 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3215 smb2_util_close(tree, h1);
3216 ret = torture_setup_file(mem_ctx, tree, fname, false);
3217 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3219 info = torture_afpinfo_new(mem_ctx);
3220 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3221 memcpy(info->afpi_FinderInfo, type_creator, 8);
3222 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3223 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3225 ZERO_STRUCT(create);
3226 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3227 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3228 create.in.fname = sname;
3229 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3230 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3232 status = smb2_create(tree, mem_ctx, &create);
3233 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3235 h1 = create.out.file.handle;
3237 /* Delete stream via setinfo delete-on-close */
3238 ZERO_STRUCT(sfinfo);
3239 sfinfo.disposition_info.in.delete_on_close = 1;
3240 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3241 sfinfo.generic.in.file.handle = h1;
3242 status = smb2_setinfo_file(tree, &sfinfo);
3243 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3245 smb2_util_close(tree, h1);
3247 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3248 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3250 ZERO_STRUCT(create);
3251 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3252 create.in.desired_access = SEC_FILE_ALL;
3253 create.in.fname = sname;
3254 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3255 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3256 status = smb2_create(tree, mem_ctx, &create);
3257 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3258 ret, done, "Got unexpected AFP_AfpInfo stream");
3261 smb2_util_unlink(tree, fname);
3262 smb2_util_rmdir(tree, BASEDIR);
3266 static bool test_setinfo_eof(struct torture_context *tctx,
3267 struct smb2_tree *tree)
3271 struct smb2_create create;
3272 union smb_setfileinfo sfinfo;
3273 struct smb2_handle h1;
3274 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3275 const char *fname = BASEDIR "\\file";
3276 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3277 const char *type_creator = "SMB,OLE!";
3278 AfpInfo *info = NULL;
3279 const char *streams_afpinfo[] = {
3284 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3286 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
3288 smb2_deltree(tree, BASEDIR);
3289 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3290 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3291 smb2_util_close(tree, h1);
3292 ret = torture_setup_file(mem_ctx, tree, fname, false);
3293 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3295 info = torture_afpinfo_new(mem_ctx);
3296 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3297 memcpy(info->afpi_FinderInfo, type_creator, 8);
3298 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3299 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3301 ZERO_STRUCT(create);
3302 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3303 create.in.desired_access = SEC_FILE_ALL;
3304 create.in.fname = sname;
3305 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3306 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3308 status = smb2_create(tree, mem_ctx, &create);
3309 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3311 h1 = create.out.file.handle;
3313 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
3315 /* Test setinfo end-of-file info */
3316 ZERO_STRUCT(sfinfo);
3317 sfinfo.generic.in.file.handle = h1;
3318 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3319 sfinfo.position_information.in.position = 61;
3320 status = smb2_setinfo_file(tree, &sfinfo);
3321 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
3322 ret, done, "set eof 61 failed");
3324 torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
3326 /* Truncation returns success, but has no effect */
3327 ZERO_STRUCT(sfinfo);
3328 sfinfo.generic.in.file.handle = h1;
3329 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3330 sfinfo.position_information.in.position = 1;
3331 status = smb2_setinfo_file(tree, &sfinfo);
3332 torture_assert_ntstatus_ok_goto(tctx, status,
3333 ret, done, "set eof 1 failed");
3334 smb2_util_close(tree, h1);
3336 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3337 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3339 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3340 0, 60, 16, 8, type_creator);
3341 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3343 ZERO_STRUCT(create);
3344 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3345 create.in.desired_access = SEC_FILE_ALL;
3346 create.in.fname = sname;
3347 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3348 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3350 status = smb2_create(tree, mem_ctx, &create);
3351 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3353 h1 = create.out.file.handle;
3356 * Delete stream via setinfo end-of-file info to 0, should
3357 * return success but stream MUST NOT deleted
3359 ZERO_STRUCT(sfinfo);
3360 sfinfo.generic.in.file.handle = h1;
3361 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3362 sfinfo.position_information.in.position = 0;
3363 status = smb2_setinfo_file(tree, &sfinfo);
3364 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3366 smb2_util_close(tree, h1);
3368 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3369 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3371 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3372 0, 60, 16, 8, type_creator);
3373 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3376 smb2_util_unlink(tree, fname);
3377 smb2_util_rmdir(tree, BASEDIR);
3381 static bool test_afpinfo_all0(struct torture_context *tctx,
3382 struct smb2_tree *tree)
3386 struct smb2_handle h1;
3387 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3388 const char *fname = BASEDIR "\\file";
3389 const char *type_creator = "SMB,OLE!";
3390 AfpInfo *info = NULL;
3391 const char *streams_basic[] = {
3394 const char *streams_afpinfo[] = {
3399 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3401 torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
3403 smb2_deltree(tree, BASEDIR);
3404 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3405 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3406 smb2_util_close(tree, h1);
3407 ret = torture_setup_file(mem_ctx, tree, fname, false);
3408 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3410 info = torture_afpinfo_new(mem_ctx);
3411 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3412 memcpy(info->afpi_FinderInfo, type_creator, 8);
3413 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3414 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3416 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3417 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3419 /* Write all 0 to AFP_AfpInfo */
3420 memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
3421 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3422 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3424 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3425 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3428 smb2_util_unlink(tree, fname);
3429 smb2_util_rmdir(tree, BASEDIR);
3433 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
3434 struct smb2_tree *tree)
3438 struct smb2_create create;
3439 struct smb2_handle h1;
3440 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3441 const char *fname = BASEDIR "\\file";
3442 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3443 const char *streams_basic[] = {
3446 const char *streams_afpresource[] = {
3451 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3453 torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
3455 smb2_deltree(tree, BASEDIR);
3456 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3457 torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
3458 smb2_util_close(tree, h1);
3459 ret = torture_setup_file(mem_ctx, tree, fname, false);
3460 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3462 torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
3464 ZERO_STRUCT(create);
3465 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3466 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3467 create.in.fname = sname;
3469 status = smb2_create(tree, mem_ctx, &create);
3470 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3471 ret, done, "Got unexpected AFP_AfpResource stream");
3473 ZERO_STRUCT(create);
3474 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3475 create.in.desired_access = SEC_FILE_ALL;
3476 create.in.fname = sname;
3478 status = smb2_create(tree, mem_ctx, &create);
3479 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3480 ret, done, "Got unexpected AFP_AfpResource stream");
3482 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3483 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3485 torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
3487 ret = write_stream(tree, __location__, tctx, mem_ctx,
3488 fname, AFPRESOURCE_STREAM_NAME,
3489 0, 10, "1234567890");
3490 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3492 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3493 0, 10, 0, 10, "1234567890");
3494 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3496 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3497 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3499 ZERO_STRUCT(create);
3500 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3501 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3502 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3503 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3504 create.in.fname = sname;
3505 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3507 status = smb2_create(tree, mem_ctx, &create);
3508 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3510 h1 = create.out.file.handle;
3511 smb2_util_close(tree, h1);
3513 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3514 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3516 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3517 0, 10, 0, 10, "1234567890");
3518 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3521 smb2_util_unlink(tree, fname);
3522 smb2_util_rmdir(tree, BASEDIR);
3526 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
3527 struct smb2_tree *tree)
3531 struct smb2_create create;
3532 union smb_setfileinfo sfinfo;
3533 struct smb2_handle h1;
3534 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3535 const char *fname = BASEDIR "\\file";
3536 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3537 const char *streams_afpresource[] = {
3542 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3544 torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
3546 smb2_deltree(tree, BASEDIR);
3547 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3548 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3549 smb2_util_close(tree, h1);
3550 ret = torture_setup_file(mem_ctx, tree, fname, false);
3551 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3553 ret = write_stream(tree, __location__, tctx, mem_ctx,
3554 fname, AFPRESOURCE_STREAM_NAME,
3555 10, 10, "1234567890");
3556 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3558 ZERO_STRUCT(create);
3559 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3560 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3561 create.in.fname = sname;
3562 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3563 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3565 status = smb2_create(tree, mem_ctx, &create);
3566 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3568 h1 = create.out.file.handle;
3570 /* Try to delete stream via setinfo delete-on-close */
3571 ZERO_STRUCT(sfinfo);
3572 sfinfo.disposition_info.in.delete_on_close = 1;
3573 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3574 sfinfo.generic.in.file.handle = h1;
3575 status = smb2_setinfo_file(tree, &sfinfo);
3576 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3578 smb2_util_close(tree, h1);
3580 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3581 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3583 ZERO_STRUCT(create);
3584 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3585 create.in.desired_access = SEC_FILE_ALL;
3586 create.in.fname = sname;
3587 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3588 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3589 status = smb2_create(tree, mem_ctx, &create);
3590 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3591 "Got unexpected AFP_AfpResource stream");
3594 smb2_util_unlink(tree, fname);
3595 smb2_util_rmdir(tree, BASEDIR);
3599 static bool test_setinfo_eof_resource(struct torture_context *tctx,
3600 struct smb2_tree *tree)
3604 struct smb2_create create;
3605 union smb_setfileinfo sfinfo;
3606 union smb_fileinfo finfo;
3607 struct smb2_handle h1;
3608 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3609 const char *fname = BASEDIR "\\file";
3610 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3611 const char *streams_basic[] = {
3615 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3617 torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
3619 smb2_deltree(tree, BASEDIR);
3620 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3621 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3622 smb2_util_close(tree, h1);
3623 ret = torture_setup_file(mem_ctx, tree, fname, false);
3624 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3626 ret = write_stream(tree, __location__, tctx, mem_ctx,
3627 fname, AFPRESOURCE_STREAM_NAME,
3628 10, 10, "1234567890");
3629 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3631 ZERO_STRUCT(create);
3632 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3633 create.in.desired_access = SEC_FILE_ALL;
3634 create.in.fname = sname;
3635 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3636 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3638 status = smb2_create(tree, mem_ctx, &create);
3639 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3641 h1 = create.out.file.handle;
3643 torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
3645 /* Test setinfo end-of-file info */
3646 ZERO_STRUCT(sfinfo);
3647 sfinfo.generic.in.file.handle = h1;
3648 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3649 sfinfo.position_information.in.position = 1;
3650 status = smb2_setinfo_file(tree, &sfinfo);
3651 torture_assert_ntstatus_ok_goto(tctx, status,
3652 ret, done, "set eof 1 failed");
3654 smb2_util_close(tree, h1);
3656 /* Check size == 1 */
3657 ZERO_STRUCT(create);
3658 create.in.fname = sname;
3659 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3660 create.in.desired_access = SEC_FILE_ALL;
3661 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3662 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3663 status = smb2_create(tree, mem_ctx, &create);
3664 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3666 h1 = create.out.file.handle;
3669 finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
3670 finfo.generic.in.file.handle = h1;
3671 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
3672 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
3674 smb2_util_close(tree, h1);
3676 torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
3678 ZERO_STRUCT(create);
3679 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3680 create.in.desired_access = SEC_FILE_ALL;
3681 create.in.fname = sname;
3682 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3683 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3685 status = smb2_create(tree, mem_ctx, &create);
3686 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3688 h1 = create.out.file.handle;
3691 * Delete stream via setinfo end-of-file info to 0, this
3692 * should delete the stream.
3694 ZERO_STRUCT(sfinfo);
3695 sfinfo.generic.in.file.handle = h1;
3696 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3697 sfinfo.position_information.in.position = 0;
3698 status = smb2_setinfo_file(tree, &sfinfo);
3699 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3701 smb2_util_close(tree, h1);
3703 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3704 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3706 ZERO_STRUCT(create);
3707 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3708 create.in.desired_access = SEC_FILE_ALL;
3709 create.in.fname = sname;
3710 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3711 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3713 status = smb2_create(tree, mem_ctx, &create);
3714 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3715 ret, done, "smb2_create failed");
3718 smb2_util_unlink(tree, fname);
3719 smb2_util_rmdir(tree, BASEDIR);
3724 * This tests that right after creating the AFP_AfpInfo stream,
3725 * reading from the stream returns an empty, default metadata blob of
3728 * NOTE: against OS X SMB server this only works if the read request
3729 * is compounded with the create that created the stream, is fails
3730 * otherwise. We don't care...
3732 static bool test_null_afpinfo(struct torture_context *tctx,
3733 struct smb2_tree *tree)
3735 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3736 const char *fname = "test_null_afpinfo";
3737 const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
3740 struct smb2_request *req[3];
3741 struct smb2_handle handle;
3742 struct smb2_create create;
3743 struct smb2_read read;
3744 AfpInfo *afpinfo = NULL;
3745 char *afpinfo_buf = NULL;
3746 const char *type_creator = "SMB,OLE!";
3748 torture_comment(tctx, "Checking create of AfpInfo stream\n");
3750 smb2_util_unlink(tree, fname);
3752 ret = torture_setup_file(mem_ctx, tree, fname, false);
3753 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
3755 ZERO_STRUCT(create);
3756 create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
3757 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
3758 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3759 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3760 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
3761 create.in.fname = sname;
3763 smb2_transport_compound_start(tree->session->transport, 2);
3765 req[0] = smb2_create_send(tree, &create);
3767 handle.data[0] = UINT64_MAX;
3768 handle.data[1] = UINT64_MAX;
3770 smb2_transport_compound_set_related(tree->session->transport, true);
3773 read.in.file.handle = handle;
3774 read.in.length = AFP_INFO_SIZE;
3775 req[1] = smb2_read_send(tree, &read);
3777 status = smb2_create_recv(req[0], tree, &create);
3778 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
3780 handle = create.out.file.handle;
3782 status = smb2_read_recv(req[1], tree, &read);
3783 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
3785 afpinfo = torture_afpinfo_new(mem_ctx);
3786 torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
3788 memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
3790 afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
3791 torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
3793 status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
3794 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
3796 smb2_util_close(tree, handle);
3798 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3799 0, 60, 16, 8, type_creator);
3800 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
3803 smb2_util_unlink(tree, fname);
3804 talloc_free(mem_ctx);
3808 static bool test_delete_file_with_rfork(struct torture_context *tctx,
3809 struct smb2_tree *tree)
3811 const char *fname = "torture_write_rfork_io";
3812 const char *rfork_content = "1234567890";
3816 smb2_util_unlink(tree, fname);
3818 torture_comment(tctx, "Test deleting file with resource fork\n");
3820 ret = torture_setup_file(tctx, tree, fname, false);
3821 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
3823 ret = write_stream(tree, __location__, tctx, tctx,
3824 fname, AFPRESOURCE_STREAM_NAME,
3825 10, 10, rfork_content);
3826 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
3828 ret = check_stream(tree, __location__, tctx, tctx,
3829 fname, AFPRESOURCE_STREAM_NAME,
3830 0, 20, 10, 10, rfork_content);
3831 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
3833 status = smb2_util_unlink(tree, fname);
3834 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
3840 static bool test_rename_and_read_rsrc(struct torture_context *tctx,
3841 struct smb2_tree *tree)
3845 struct smb2_create create, create2;
3846 struct smb2_handle h1, h2;
3847 const char *fname = "test_rename_openfile";
3848 const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
3849 const char *fname_renamed = "test_rename_openfile_renamed";
3850 const char *data = "1234567890";
3851 union smb_setfileinfo sinfo;
3854 ret = enable_aapl(tctx, tree);
3855 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
3857 torture_comment(tctx, "Create file with resource fork\n");
3859 ret = torture_setup_file(tctx, tree, fname, false);
3860 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3862 ret = write_stream(tree, __location__, tctx, tctx,
3863 fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
3864 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
3866 torture_comment(tctx, "Open resource fork\n");
3868 ZERO_STRUCT(create);
3869 create.in.desired_access = SEC_FILE_ALL;
3870 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3871 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3872 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3873 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3874 create.in.fname = sname;
3876 status = smb2_create(tree, tctx, &create);
3877 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3879 h1 = create.out.file.handle;
3881 torture_comment(tctx, "Rename base file\n");
3883 ZERO_STRUCT(create2);
3884 create2.in.desired_access = SEC_FILE_ALL;
3885 create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3886 create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3887 create2.in.create_disposition = NTCREATEX_DISP_OPEN;
3888 create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3889 create2.in.fname = fname;
3891 status = smb2_create(tree, tctx, &create2);
3892 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3894 h2 = create2.out.file.handle;
3897 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3898 sinfo.rename_information.in.file.handle = h2;
3899 sinfo.rename_information.in.overwrite = 0;
3900 sinfo.rename_information.in.root_fid = 0;
3901 sinfo.rename_information.in.new_name = fname_renamed;
3903 status = smb2_setinfo_file(tree, &sinfo);
3904 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file failed");
3906 smb2_util_close(tree, h2);
3909 r.in.file.handle = h1;
3913 torture_comment(tctx, "Read resource fork of renamed file\n");
3915 status = smb2_read(tree, tree, &r);
3916 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read failed");
3918 smb2_util_close(tree, h1);
3920 torture_assert_goto(tctx, r.out.data.length == 10, ret, done,
3921 talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected 10\n",
3922 (intmax_t)r.out.data.length));
3924 torture_assert_goto(tctx, memcmp(r.out.data.data, data, 10) == 0, ret, done,
3925 talloc_asprintf(tctx, "Bad data in stream\n"));
3928 smb2_util_unlink(tree, fname);
3929 smb2_util_unlink(tree, fname_renamed);
3934 static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
3935 struct smb2_tree *tree)
3937 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3938 const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
3939 const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
3941 struct smb2_handle testdirh;
3943 struct smb2_create io;
3945 const char *type_creator = "SMB,OLE!";
3948 union smb_search_data *d;
3952 smb2_deltree(tree, BASEDIR);
3954 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
3955 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
3956 smb2_util_close(tree, testdirh);
3958 torture_comment(tctx, "Enabling AAPL\n");
3960 ret = enable_aapl(tctx, tree);
3961 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
3964 * Now that Requested AAPL extensions are enabled, setup some
3965 * Mac files with metadata and resource fork
3968 torture_comment(tctx, "Preparing file\n");
3970 ret = torture_setup_file(mem_ctx, tree, fname, false);
3971 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
3973 info = torture_afpinfo_new(mem_ctx);
3974 torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
3976 memcpy(info->afpi_FinderInfo, type_creator, 8);
3977 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3978 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3980 ret = write_stream(tree, __location__, tctx, mem_ctx,
3981 fname, AFPRESOURCE_STREAM_NAME,
3983 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
3986 * Ok, file is prepared, now call smb2/find
3989 torture_comment(tctx, "Issue find\n");
3992 io.in.desired_access = SEC_RIGHTS_DIR_READ;
3993 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
3994 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
3995 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
3996 NTCREATEX_SHARE_ACCESS_WRITE |
3997 NTCREATEX_SHARE_ACCESS_DELETE);
3998 io.in.create_disposition = NTCREATEX_DISP_OPEN;
3999 io.in.fname = BASEDIR;
4000 status = smb2_create(tree, tctx, &io);
4001 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4004 f.in.file.handle = io.out.file.handle;
4006 f.in.max_response_size = 0x1000;
4007 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
4009 status = smb2_find_level(tree, tree, &f, &count, &d);
4010 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
4012 status = smb2_util_close(tree, io.out.file.handle);
4013 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
4015 torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
4017 for (i = 0; i < count; i++) {
4018 const char *found = d[i].id_both_directory_info.name.s;
4020 if (!strcmp(found, ".") || !strcmp(found, ".."))
4025 torture_assert_str_equal_goto(tctx,
4026 d[i].id_both_directory_info.name.s, name,
4027 ret, done, "bad name");
4029 rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
4030 torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
4032 torture_assert_mem_equal_goto(tctx, type_creator,
4033 d[i].id_both_directory_info.short_name_buf + 8,
4034 8, ret, done, "Bad FinderInfo");
4036 smb2_util_unlink(tree, fname);
4037 smb2_deltree(tree, BASEDIR);
4038 talloc_free(mem_ctx);
4042 static bool test_invalid_afpinfo(struct torture_context *tctx,
4043 struct smb2_tree *tree1,
4044 struct smb2_tree *tree2)
4046 const char *fname = "filtest_invalid_afpinfo";
4047 const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
4048 struct smb2_create create;
4049 const char *streams_basic[] = {
4052 const char *streams_afpinfo[] = {
4059 if (tree2 == NULL) {
4060 torture_skip_goto(tctx, done, "need second share without fruit\n");
4063 torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
4065 ret = torture_setup_file(tctx, tree2, fname, false);
4066 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4068 ret = write_stream(tree2, __location__, tctx, tctx,
4069 fname, AFPINFO_STREAM_NAME,
4071 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4073 ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
4074 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4076 torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
4078 ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
4079 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4081 torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
4083 ZERO_STRUCT(create);
4084 create.in.desired_access = SEC_FILE_ALL;
4085 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4086 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4087 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4088 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4089 create.in.fname = sname;
4091 status = smb2_create(tree1, tctx, &create);
4092 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4093 ret, done, "Stream still around?");
4096 smb2_util_unlink(tree1, fname);
4100 static bool test_zero_file_id(struct torture_context *tctx,
4101 struct smb2_tree *tree)
4103 const char *fname = "filtest_file_id";
4104 struct smb2_create create = {0};
4107 uint8_t zero_file_id[8] = {0};
4109 torture_comment(tctx, "Testing zero file id\n");
4111 ret = torture_setup_file(tctx, tree, fname, false);
4112 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4114 ZERO_STRUCT(create);
4115 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4116 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4117 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4118 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4119 create.in.fname = fname;
4120 create.in.query_on_disk_id = true;
4122 status = smb2_create(tree, tctx, &create);
4123 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
4125 "test file could not be opened");
4126 torture_assert_mem_not_equal_goto(tctx, create.out.on_disk_id,
4127 zero_file_id, 8, ret, done,
4128 "unexpected zero file id");
4130 smb2_util_close(tree, create.out.file.handle);
4132 ret = enable_aapl(tctx, tree);
4133 torture_assert(tctx, ret == true, "enable_aapl failed");
4135 ZERO_STRUCT(create);
4136 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4137 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4138 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4139 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4140 create.in.fname = fname;
4141 create.in.query_on_disk_id = true;
4143 status = smb2_create(tree, tctx, &create);
4144 torture_assert_ntstatus_equal_goto(
4145 tctx, status, NT_STATUS_OK, ret, done,
4146 "test file could not be opened with AAPL");
4147 torture_assert_mem_equal_goto(tctx, create.out.on_disk_id, zero_file_id,
4148 8, ret, done, "non-zero file id");
4150 smb2_util_close(tree, create.out.file.handle);
4153 smb2_util_unlink(tree, fname);
4157 static bool copy_one_stream(struct torture_context *torture,
4158 struct smb2_tree *tree,
4159 TALLOC_CTX *tmp_ctx,
4160 const char *src_sname,
4161 const char *dst_sname)
4163 struct smb2_handle src_h = {{0}};
4164 struct smb2_handle dest_h = {{0}};
4167 struct srv_copychunk_copy cc_copy;
4168 struct srv_copychunk_rsp cc_rsp;
4169 enum ndr_err_code ndr_ret;
4172 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4175 &src_h, 256, /* fill 256 byte src file */
4176 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4178 &dest_h, 0, /* 0 byte dest file */
4179 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4182 torture_assert_goto(torture, ok == true, ok, done,
4183 "setup copy chunk error\n");
4185 /* copy all src file data (via a single chunk desc) */
4186 cc_copy.chunks[0].source_off = 0;
4187 cc_copy.chunks[0].target_off = 0;
4188 cc_copy.chunks[0].length = 256;
4190 ndr_ret = ndr_push_struct_blob(
4191 &io.smb2.in.out, tmp_ctx, &cc_copy,
4192 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4194 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4195 "ndr_push_srv_copychunk_copy\n");
4197 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4198 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4199 "FSCTL_SRV_COPYCHUNK\n");
4201 ndr_ret = ndr_pull_struct_blob(
4202 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4203 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4205 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4206 "ndr_pull_srv_copychunk_rsp\n");
4208 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4209 1, /* chunks written */
4210 0, /* chunk bytes unsuccessfully written */
4211 256); /* total bytes written */
4212 torture_assert_goto(torture, ok == true, ok, done,
4213 "bad copy chunk response data\n");
4215 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
4217 torture_fail(torture, "inconsistent file data\n");
4221 if (!smb2_util_handle_empty(src_h)) {
4222 smb2_util_close(tree, src_h);
4224 if (!smb2_util_handle_empty(dest_h)) {
4225 smb2_util_close(tree, dest_h);
4231 static bool copy_finderinfo_stream(struct torture_context *torture,
4232 struct smb2_tree *tree,
4233 TALLOC_CTX *tmp_ctx,
4234 const char *src_name,
4235 const char *dst_name)
4237 struct smb2_handle src_h = {{0}};
4238 struct smb2_handle dest_h = {{0}};
4241 struct srv_copychunk_copy cc_copy;
4242 struct srv_copychunk_rsp cc_rsp;
4243 enum ndr_err_code ndr_ret;
4244 const char *type_creator = "SMB,OLE!";
4245 AfpInfo *info = NULL;
4246 const char *src_name_afpinfo = NULL;
4247 const char *dst_name_afpinfo = NULL;
4250 src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
4252 torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
4253 "talloc_asprintf failed\n");
4255 dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
4257 torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
4258 "talloc_asprintf failed\n");
4260 info = torture_afpinfo_new(tmp_ctx);
4261 torture_assert_not_null_goto(torture, info, ok, done,
4262 "torture_afpinfo_new failed\n");
4264 memcpy(info->afpi_FinderInfo, type_creator, 8);
4265 ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
4266 torture_assert_goto(torture, ok == true, ok, done,
4267 "torture_write_afpinfo failed\n");
4269 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4273 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4276 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4279 torture_assert_goto(torture, ok == true, ok, done,
4280 "setup copy chunk error\n");
4282 /* copy all src file data (via a single chunk desc) */
4283 cc_copy.chunks[0].source_off = 0;
4284 cc_copy.chunks[0].target_off = 0;
4285 cc_copy.chunks[0].length = 60;
4287 ndr_ret = ndr_push_struct_blob(
4288 &io.smb2.in.out, tmp_ctx, &cc_copy,
4289 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4291 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4292 "ndr_push_srv_copychunk_copy\n");
4294 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4295 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4296 "FSCTL_SRV_COPYCHUNK\n");
4298 ndr_ret = ndr_pull_struct_blob(
4299 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4300 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4302 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4303 "ndr_pull_srv_copychunk_rsp\n");
4305 smb2_util_close(tree, src_h);
4307 smb2_util_close(tree, dest_h);
4308 ZERO_STRUCT(dest_h);
4310 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4311 1, /* chunks written */
4312 0, /* chunk bytes unsuccessfully written */
4313 60); /* total bytes written */
4314 torture_assert_goto(torture, ok == true, ok, done,
4315 "bad copy chunk response data\n");
4317 ok = check_stream(tree, __location__, torture, tmp_ctx,
4318 dst_name, AFPINFO_STREAM,
4319 0, 60, 16, 8, type_creator);
4320 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
4323 if (!smb2_util_handle_empty(src_h)) {
4324 smb2_util_close(tree, src_h);
4326 if (!smb2_util_handle_empty(dest_h)) {
4327 smb2_util_close(tree, dest_h);
4333 static bool test_copy_chunk_streams(struct torture_context *torture,
4334 struct smb2_tree *tree)
4336 const char *src_name = "src";
4337 const char *dst_name = "dst";
4339 const char *src_sname;
4340 const char *dst_sname;
4342 { "src:foo", "dst:foo" },
4343 { "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
4346 TALLOC_CTX *tmp_ctx = NULL;
4349 tmp_ctx = talloc_new(tree);
4350 torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
4351 "torture_setup_file\n");
4353 smb2_util_unlink(tree, src_name);
4354 smb2_util_unlink(tree, dst_name);
4356 ok = torture_setup_file(torture, tree, src_name, false);
4357 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4358 ok = torture_setup_file(torture, tree, dst_name, false);
4359 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4361 for (i = 0; i < ARRAY_SIZE(names); i++) {
4362 ok = copy_one_stream(torture, tree, tmp_ctx,
4364 names[i].dst_sname);
4365 torture_assert_goto(torture, ok == true, ok, done,
4366 "copy_one_stream failed\n");
4369 ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
4370 src_name, dst_name);
4371 torture_assert_goto(torture, ok == true, ok, done,
4372 "copy_finderinfo_stream failed\n");
4375 smb2_util_unlink(tree, src_name);
4376 smb2_util_unlink(tree, dst_name);
4377 talloc_free(tmp_ctx);
4382 * Note: This test depends on "vfs objects = catia fruit streams_xattr". For
4383 * some tests torture must be run on the host it tests and takes an additional
4384 * argument with the local path to the share:
4385 * "--option=torture:localdir=<SHAREPATH>".
4387 * When running against an OS X SMB server add "--option=torture:osx=true"
4389 struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
4391 struct torture_suite *suite = torture_suite_create(
4394 suite->description = talloc_strdup(suite, "vfs_fruit tests");
4396 torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
4397 torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
4398 torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
4399 torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
4400 torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
4401 torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
4402 torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
4403 torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
4404 torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
4405 torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
4406 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
4407 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
4408 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
4409 torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
4410 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
4411 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
4412 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
4413 torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
4414 torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
4415 torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
4416 torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
4417 torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
4418 torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
4419 torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
4424 struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
4426 struct torture_suite *suite = torture_suite_create(
4427 ctx, "fruit_netatalk");
4429 suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
4431 torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
4432 torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
4437 struct torture_suite *torture_vfs_fruit_file_id(TALLOC_CTX *ctx)
4439 struct torture_suite *suite =
4440 torture_suite_create(ctx, "fruit_file_id");
4442 suite->description =
4443 talloc_strdup(suite, "vfs_fruit tests for on-disk file ID that "
4444 "require fruit:zero_file_id=yes");
4446 torture_suite_add_1smb2_test(suite, "zero file id if AAPL negotiated",