s4:torture/vfs/fruit: decrease large resource fork size in test from 1 GB to 64 MB
[Samba.git] / source4 / torture / vfs / fruit.c
blob6067bc64b5234a161a390e942332c9e69f8f2203
1 /*
2 Unix SMB/CIFS implementation.
4 vfs_fruit tests
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/>.
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "libcli/libcli.h"
25 #include "libcli/smb2/smb2.h"
26 #include "libcli/smb2/smb2_calls.h"
27 #include "libcli/smb/smb2_create_ctx.h"
28 #include "lib/cmdline/popt_common.h"
29 #include "param/param.h"
30 #include "libcli/resolve/resolve.h"
31 #include "MacExtensions.h"
32 #include "lib/util/tsort.h"
34 #include "torture/torture.h"
35 #include "torture/util.h"
36 #include "torture/smb2/proto.h"
37 #include "torture/vfs/proto.h"
38 #include "librpc/gen_ndr/ndr_ioctl.h"
39 #include "libcli/security/dom_sid.h"
40 #include "../librpc/gen_ndr/ndr_security.h"
41 #include "libcli/security/secace.h"
42 #include "libcli/security/security_descriptor.h"
44 #define BASEDIR "vfs_fruit_dir"
45 #define FNAME_CC_SRC "testfsctl.dat"
46 #define FNAME_CC_DST "testfsctl2.dat"
48 #define CHECK_STATUS(status, correct) do { \
49 if (!NT_STATUS_EQUAL(status, correct)) { \
50 torture_result(tctx, TORTURE_FAIL, \
51 "(%s) Incorrect status %s - should be %s\n", \
52 __location__, nt_errstr(status), nt_errstr(correct)); \
53 ret = false; \
54 goto done; \
55 }} while (0)
57 #define CHECK_VALUE(v, correct) do { \
58 if ((v) != (correct)) { \
59 torture_result(tctx, TORTURE_FAIL, \
60 "(%s) Incorrect value %s=%u - should be %u\n", \
61 __location__, #v, (unsigned)v, (unsigned)correct); \
62 ret = false; \
63 goto done; \
64 }} while (0)
66 static bool check_stream_list(struct smb2_tree *tree,
67 struct torture_context *tctx,
68 const char *fname,
69 int num_exp,
70 const char **exp,
71 bool is_dir);
73 static int qsort_string(char * const *s1, char * const *s2)
75 return strcmp(*s1, *s2);
78 static int qsort_stream(const struct stream_struct * s1, const struct stream_struct *s2)
80 return strcmp(s1->stream_name.s, s2->stream_name.s);
84 * REVIEW:
85 * This is hokey, but what else can we do?
87 #if defined(HAVE_ATTROPEN) || defined(FREEBSD)
88 #define AFPINFO_EA_NETATALK "org.netatalk.Metadata"
89 #define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork"
90 #else
91 #define AFPINFO_EA_NETATALK "user.org.netatalk.Metadata"
92 #define AFPRESOURCE_EA_NETATALK "user.org.netatalk.ResourceFork"
93 #endif
96 The metadata xattr char buf below contains the following attributes:
98 -------------------------------------------------------------------------------
99 Entry ID : 00000008 : File Dates Info
100 Offset : 00000162 : 354
101 Length : 00000010 : 16
103 -DATE------: : (GMT) : (Local)
104 create : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
105 modify : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
106 backup : 80000000 : Unknown or Initial
107 access : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
109 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
110 00000000 : 1B 44 21 69 1B 44 21 69 80 00 00 00 1B 44 21 69 : .D!i.D!i.....D!i
112 -------------------------------------------------------------------------------
113 Entry ID : 00000009 : Finder Info
114 Offset : 0000007A : 122
115 Length : 00000020 : 32
117 -FInfo-----:
118 Type : 42415252 : BARR
119 Creator : 464F4F4F : FOOO
120 isAlias : 0
121 Invisible : 1
122 hasBundle : 0
123 nameLocked : 0
124 Stationery : 0
125 CustomIcon : 0
126 Reserved : 0
127 Inited : 0
128 NoINITS : 0
129 Shared : 0
130 SwitchLaunc: 0
131 Hidden Ext : 0
132 color : 000 : none
133 isOnDesk : 0
134 Location v : 0000 : 0
135 Location h : 0000 : 0
136 Fldr : 0000 : ..
138 -FXInfo----:
139 Rsvd|IconID: 0000 : 0
140 Rsvd : 0000 : ..
141 Rsvd : 0000 : ..
142 Rsvd : 0000 : ..
143 AreInvalid : 0
144 unknown bit: 0
145 unknown bit: 0
146 unknown bit: 0
147 unknown bit: 0
148 unknown bit: 0
149 unknown bit: 0
150 CustomBadge: 0
151 ObjctIsBusy: 0
152 unknown bit: 0
153 unknown bit: 0
154 unknown bit: 0
155 unknown bit: 0
156 RoutingInfo: 0
157 unknown bit: 0
158 unknown bit: 0
159 Rsvd|commnt: 0000 : 0
160 PutAway : 00000000 : 0
162 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
163 00000000 : 42 41 52 52 46 4F 4F 4F 40 00 00 00 00 00 00 00 : BARRFOOO@.......
164 00000010 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
166 -------------------------------------------------------------------------------
167 Entry ID : 0000000E : AFP File Info
168 Offset : 00000172 : 370
169 Length : 00000004 : 4
171 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
172 00000000 : 00 00 01 A1 : ....
175 char metadata_xattr[] = {
176 0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
180 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x08, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00,
182 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
183 0x00, 0x7a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
184 0x00, 0x0e, 0x00, 0x00, 0x01, 0x72, 0x00, 0x00,
185 0x00, 0x04, 0x80, 0x44, 0x45, 0x56, 0x00, 0x00,
186 0x01, 0x76, 0x00, 0x00, 0x00, 0x08, 0x80, 0x49,
187 0x4e, 0x4f, 0x00, 0x00, 0x01, 0x7e, 0x00, 0x00,
188 0x00, 0x08, 0x80, 0x53, 0x59, 0x4e, 0x00, 0x00,
189 0x01, 0x86, 0x00, 0x00, 0x00, 0x08, 0x80, 0x53,
190 0x56, 0x7e, 0x00, 0x00, 0x01, 0x8e, 0x00, 0x00,
191 0x00, 0x04, 0x42, 0x41, 0x52, 0x52, 0x46, 0x4f,
192 0x4f, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
220 0x00, 0x00, 0x1b, 0x44, 0x21, 0x69, 0x1b, 0x44,
221 0x21, 0x69, 0x80, 0x00, 0x00, 0x00, 0x1b, 0x44,
222 0x21, 0x69, 0x00, 0x00, 0x01, 0xa1, 0x00, 0xfd,
223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x20,
224 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xe3,
225 0x86, 0x53, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x01,
226 0x00, 0x00
230 The buf below contains the following AppleDouble encoded data:
232 -------------------------------------------------------------------------------
233 MagicNumber: 00051607 : AppleDouble
234 Version : 00020000 : Version 2
235 Filler : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
236 Num. of ent: 0002 : 2
238 -------------------------------------------------------------------------------
239 Entry ID : 00000009 : Finder Info
240 Offset : 00000032 : 50
241 Length : 00000EB0 : 3760
243 -FInfo-----:
244 Type : 54455354 : TEST
245 Creator : 534C4F57 : SLOW
246 isAlias : 0
247 Invisible : 0
248 hasBundle : 0
249 nameLocked : 0
250 Stationery : 0
251 CustomIcon : 0
252 Reserved : 0
253 Inited : 0
254 NoINITS : 0
255 Shared : 0
256 SwitchLaunc: 0
257 Hidden Ext : 0
258 color : 100 : blue
259 isOnDesk : 0
260 Location v : 0000 : 0
261 Location h : 0000 : 0
262 Fldr : 0000 : ..
264 -FXInfo----:
265 Rsvd|IconID: 0000 : 0
266 Rsvd : 0000 : ..
267 Rsvd : 0000 : ..
268 Rsvd : 0000 : ..
269 AreInvalid : 0
270 unknown bit: 0
271 unknown bit: 0
272 unknown bit: 0
273 unknown bit: 0
274 unknown bit: 0
275 unknown bit: 0
276 CustomBadge: 0
277 ObjctIsBusy: 0
278 unknown bit: 0
279 unknown bit: 0
280 unknown bit: 0
281 unknown bit: 0
282 RoutingInfo: 0
283 unknown bit: 0
284 unknown bit: 0
285 Rsvd|commnt: 0000 : 0
286 PutAway : 00000000 : 0
288 -EA--------:
289 pad : 0000 : ..
290 magic : 41545452 : ATTR
291 debug_tag : 53D4580C : 1406425100
292 total_size : 00000EE2 : 3810
293 data_start : 000000BC : 188
294 data_length: 0000005E : 94
295 reserved[0]: 00000000 : ....
296 reserved[1]: 00000000 : ....
297 reserved[2]: 00000000 : ....
298 flags : 0000 : ..
299 num_attrs : 0002 : 2
300 -EA ENTRY--:
301 offset : 000000BC : 188
302 length : 0000005B : 91
303 flags : 0000 : ..
304 namelen : 24 : 36
305 -EA NAME---: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
306 00000000 : 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 61 : com.apple.metada
307 00000010 : 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 54 : ta:_kMDItemUserT
308 00000020 : 61 67 73 00 : ags.
309 -EA VALUE--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
310 00000000 : 62 70 6C 69 73 74 30 30 A5 01 02 03 04 05 54 74 : bplist00......Tt
311 00000010 : 65 73 74 66 00 47 00 72 00 FC 00 6E 00 0A 00 32 : estf.G.r...n...2
312 00000020 : 56 4C 69 6C 61 0A 33 56 47 65 6C 62 0A 35 56 42 : VLila.3VGelb.5VB
313 00000030 : 6C 61 75 0A 34 08 0E 13 20 27 2E 00 00 00 00 00 : lau.4... '......
314 00000040 : 00 01 01 00 00 00 00 00 00 00 06 00 00 00 00 00 : ................
315 00000050 : 00 00 00 00 00 00 00 00 00 00 35 : ..........5
316 -EA ENTRY--:
317 offset : 00000117 : 279
318 length : 00000003 : 3
319 flags : 0000 : ..
320 namelen : 08 : 8
321 -EA NAME---: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
322 00000000 : 66 6F 6F 3A 62 61 72 00 : foo:bar.
323 -EA VALUE--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
324 00000000 : 62 61 7A : baz
326 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
327 00000000 : 54 45 53 54 53 4C 4F 57 00 08 00 00 00 00 00 00 : TESTSLOW........
328 00000010 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
329 00000020 : 00 00 41 54 54 52 53 D4 58 0C 00 00 0E E2 00 00 : ..ATTRS.X.......
330 00000030 : 00 BC 00 00 00 5E 00 00 00 00 00 00 00 00 00 00 : .....^..........
331 00000040 : 00 00 00 00 00 02 00 00 00 BC 00 00 00 5B 00 00 : .............[..
332 00000050 : 24 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 : $com.apple.metad
333 00000060 : 61 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 : ata:_kMDItemUser
334 00000070 : 54 61 67 73 00 00 00 00 01 17 00 00 00 03 00 00 : Tags............
335 00000080 : 08 66 6F 6F 3A 62 61 72 00 66 62 70 6C 69 73 74 : .foo:bar.fbplist
336 00000090 : 30 30 A5 01 02 03 04 05 54 74 65 73 74 66 00 47 : 00......Ttestf.G
337 000000A0 : 00 72 00 FC 00 6E 00 0A 00 32 56 4C 69 6C 61 0A : .r...n...2VLila.
338 000000B0 : 33 56 47 65 6C 62 0A 35 56 42 6C 61 75 0A 34 08 : 3VGelb.5VBlau.4.
339 000000C0 : 0E 13 20 27 2E 00 00 00 00 00 00 01 01 00 00 00 : .. '............
340 000000D0 : 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 : ................
341 000000E0 : 00 00 00 00 35 62 61 7A 00 00 00 00 00 00 00 00 : ....5baz........
342 000000F0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
343 ... all zeroes ...
344 00000EA0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
346 -------------------------------------------------------------------------------
347 Entry ID : 00000002 : Resource Fork
348 Offset : 00000EE2 : 3810
349 Length : 0000011E : 286
351 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
352 00000000 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
353 00000010 : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo
354 00000020 : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
355 00000030 : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 : left blank ..
356 00000040 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
357 00000050 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
358 00000060 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
359 00000070 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
360 00000080 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
361 00000090 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
362 000000A0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
363 000000B0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
364 000000C0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
365 000000D0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
366 000000E0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
367 000000F0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
368 00000100 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
369 00000110 : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF : ..............
371 It was created with:
372 $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
374 static char osx_adouble_w_xattr[] = {
375 0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
376 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
377 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
378 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
379 0x00, 0x32, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00,
380 0x00, 0x02, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00,
381 0x01, 0x1e, 0x54, 0x45, 0x53, 0x54, 0x53, 0x4c,
382 0x4f, 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
386 0x53, 0xd4, 0x58, 0x0c, 0x00, 0x00, 0x0e, 0xe2,
387 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5e,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
390 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5b,
391 0x00, 0x00, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
392 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x65, 0x74,
393 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x5f, 0x6b,
394 0x4d, 0x44, 0x49, 0x74, 0x65, 0x6d, 0x55, 0x73,
395 0x65, 0x72, 0x54, 0x61, 0x67, 0x73, 0x00, 0x00,
396 0x00, 0x00, 0x01, 0x17, 0x00, 0x00, 0x00, 0x03,
397 0x00, 0x00, 0x08, 0x66, 0x6f, 0x6f, 0x3a, 0x62,
398 0x61, 0x72, 0x00, 0x66, 0x62, 0x70, 0x6c, 0x69,
399 0x73, 0x74, 0x30, 0x30, 0xa5, 0x01, 0x02, 0x03,
400 0x04, 0x05, 0x54, 0x74, 0x65, 0x73, 0x74, 0x66,
401 0x00, 0x47, 0x00, 0x72, 0x00, 0xfc, 0x00, 0x6e,
402 0x00, 0x0a, 0x00, 0x32, 0x56, 0x4c, 0x69, 0x6c,
403 0x61, 0x0a, 0x33, 0x56, 0x47, 0x65, 0x6c, 0x62,
404 0x0a, 0x35, 0x56, 0x42, 0x6c, 0x61, 0x75, 0x0a,
405 0x34, 0x08, 0x0e, 0x13, 0x20, 0x27, 0x2e, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x62,
410 0x61, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
418 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
431 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
445 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
457 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
487 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
493 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
509 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
514 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
523 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
524 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
525 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
530 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
549 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
614 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
679 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
721 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
733 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
734 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
736 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
737 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
744 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
745 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
746 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
747 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
748 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
750 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
751 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
752 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
757 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
759 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
760 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
761 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
762 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
763 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
764 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
769 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
771 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
783 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
784 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
785 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
789 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
792 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
795 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
797 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
798 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
799 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
800 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
801 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
802 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
803 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
804 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
805 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
817 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
818 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
819 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
820 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
821 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
822 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
823 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
824 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
825 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
826 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
827 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
829 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
830 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
831 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
832 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
833 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
834 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
848 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
849 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
850 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
851 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
852 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
853 0x00, 0x1e, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72,
854 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20,
855 0x66, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
856 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
857 0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
858 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
860 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
861 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
862 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
863 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
864 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
865 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
868 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
870 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
871 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
872 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
873 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
874 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
875 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
876 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
877 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
878 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
879 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
880 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
881 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
882 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
883 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
884 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
885 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
886 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
890 * talloc and intialize an AfpInfo
892 static AfpInfo *torture_afpinfo_new(TALLOC_CTX *mem_ctx)
894 AfpInfo *info;
896 info = talloc_zero(mem_ctx, AfpInfo);
897 if (info == NULL) {
898 return NULL;
901 info->afpi_Signature = AFP_Signature;
902 info->afpi_Version = AFP_Version;
903 info->afpi_BackupTime = AFP_BackupTime;
905 return info;
909 * Pack AfpInfo into a talloced buffer
911 static char *torture_afpinfo_pack(TALLOC_CTX *mem_ctx,
912 AfpInfo *info)
914 char *buf;
916 buf = talloc_zero_array(mem_ctx, char, AFP_INFO_SIZE);
917 if (buf == NULL) {
918 return NULL;
921 RSIVAL(buf, 0, info->afpi_Signature);
922 RSIVAL(buf, 4, info->afpi_Version);
923 RSIVAL(buf, 12, info->afpi_BackupTime);
924 memcpy(buf + 16, info->afpi_FinderInfo, sizeof(info->afpi_FinderInfo));
926 return buf;
930 * Unpack AfpInfo
932 #if 0
933 static void torture_afpinfo_unpack(AfpInfo *info, char *data)
935 info->afpi_Signature = RIVAL(data, 0);
936 info->afpi_Version = RIVAL(data, 4);
937 info->afpi_BackupTime = RIVAL(data, 12);
938 memcpy(info->afpi_FinderInfo, (const char *)data + 16,
939 sizeof(info->afpi_FinderInfo));
941 #endif
943 static bool torture_write_afpinfo(struct smb2_tree *tree,
944 struct torture_context *tctx,
945 TALLOC_CTX *mem_ctx,
946 const char *fname,
947 AfpInfo *info)
949 struct smb2_handle handle;
950 struct smb2_create io;
951 NTSTATUS status;
952 const char *full_name;
953 char *infobuf;
954 bool ret = true;
956 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, AFPINFO_STREAM_NAME);
957 if (full_name == NULL) {
958 torture_comment(tctx, "talloc_asprintf error\n");
959 return false;
961 ZERO_STRUCT(io);
962 io.in.desired_access = SEC_FILE_WRITE_DATA;
963 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
964 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
965 io.in.create_options = 0;
966 io.in.fname = full_name;
968 status = smb2_create(tree, mem_ctx, &io);
969 CHECK_STATUS(status, NT_STATUS_OK);
971 handle = io.out.file.handle;
973 infobuf = torture_afpinfo_pack(mem_ctx, info);
974 if (infobuf == NULL) {
975 return false;
978 status = smb2_util_write(tree, handle, infobuf, 0, AFP_INFO_SIZE);
979 CHECK_STATUS(status, NT_STATUS_OK);
981 smb2_util_close(tree, handle);
983 done:
984 return ret;
988 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
989 * compare against buffer 'value'
991 static bool check_stream(struct smb2_tree *tree,
992 const char *location,
993 struct torture_context *tctx,
994 TALLOC_CTX *mem_ctx,
995 const char *fname,
996 const char *sname,
997 off_t read_offset,
998 size_t read_count,
999 off_t comp_offset,
1000 size_t comp_count,
1001 const char *value)
1003 struct smb2_handle handle;
1004 struct smb2_create create;
1005 struct smb2_read r;
1006 NTSTATUS status;
1007 char *full_name;
1008 bool ret = true;
1010 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1011 if (full_name == NULL) {
1012 torture_comment(tctx, "talloc_asprintf error\n");
1013 return false;
1015 ZERO_STRUCT(create);
1016 create.in.desired_access = SEC_FILE_READ_DATA;
1017 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1018 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1019 create.in.fname = full_name;
1021 torture_comment(tctx, "Open stream %s\n", full_name);
1023 status = smb2_create(tree, mem_ctx, &create);
1024 if (!NT_STATUS_IS_OK(status)) {
1025 TALLOC_FREE(full_name);
1026 if (value == NULL) {
1027 return true;
1029 torture_comment(tctx, "Unable to open stream %s\n", full_name);
1030 return false;
1033 handle = create.out.file.handle;
1034 if (value == NULL) {
1035 TALLOC_FREE(full_name);
1036 smb2_util_close(tree, handle);
1037 return true;
1040 ZERO_STRUCT(r);
1041 r.in.file.handle = handle;
1042 r.in.length = read_count;
1043 r.in.offset = read_offset;
1045 status = smb2_read(tree, tree, &r);
1047 torture_assert_ntstatus_ok_goto(
1048 tctx, status, ret, done,
1049 talloc_asprintf(tctx, "(%s) Failed to read %lu bytes from stream '%s'\n",
1050 location, (long)strlen(value), full_name));
1052 torture_assert_goto(tctx, r.out.data.length == read_count, ret, done,
1053 talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected %jd\n",
1054 (intmax_t)r.out.data.length, (intmax_t)read_count));
1056 torture_assert_goto(
1057 tctx, memcmp(r.out.data.data + comp_offset, value, comp_count) == 0,
1058 ret, done,
1059 talloc_asprintf(tctx, "(%s) Bad data in stream\n", location));
1061 done:
1062 TALLOC_FREE(full_name);
1063 smb2_util_close(tree, handle);
1064 return ret;
1068 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1069 * compare against buffer 'value'
1071 static ssize_t read_stream(struct smb2_tree *tree,
1072 const char *location,
1073 struct torture_context *tctx,
1074 TALLOC_CTX *mem_ctx,
1075 const char *fname,
1076 const char *sname,
1077 off_t read_offset,
1078 size_t read_count)
1080 struct smb2_handle handle;
1081 struct smb2_create create;
1082 struct smb2_read r;
1083 NTSTATUS status;
1084 const char *full_name;
1085 bool ret = true;
1087 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1088 if (full_name == NULL) {
1089 torture_comment(tctx, "talloc_asprintf error\n");
1090 return -1;
1092 ZERO_STRUCT(create);
1093 create.in.desired_access = SEC_FILE_READ_DATA;
1094 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1095 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1096 create.in.fname = full_name;
1098 torture_comment(tctx, "Open stream %s\n", full_name);
1100 status = smb2_create(tree, mem_ctx, &create);
1101 if (!NT_STATUS_IS_OK(status)) {
1102 torture_comment(tctx, "Unable to open stream %s\n",
1103 full_name);
1104 return -1;
1107 handle = create.out.file.handle;
1109 ZERO_STRUCT(r);
1110 r.in.file.handle = handle;
1111 r.in.length = read_count;
1112 r.in.offset = read_offset;
1114 status = smb2_read(tree, tree, &r);
1115 if (!NT_STATUS_IS_OK(status)) {
1116 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
1119 smb2_util_close(tree, handle);
1121 done:
1122 if (ret == false) {
1123 return -1;
1125 return r.out.data.length;
1129 * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1130 * compare against buffer 'value'
1132 static bool write_stream(struct smb2_tree *tree,
1133 const char *location,
1134 struct torture_context *tctx,
1135 TALLOC_CTX *mem_ctx,
1136 const char *fname,
1137 const char *sname,
1138 off_t offset,
1139 size_t size,
1140 const char *value)
1142 struct smb2_handle handle;
1143 struct smb2_create create;
1144 NTSTATUS status;
1145 const char *full_name;
1147 full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname ? sname : "");
1148 if (full_name == NULL) {
1149 torture_comment(tctx, "talloc_asprintf error\n");
1150 return false;
1152 ZERO_STRUCT(create);
1153 create.in.desired_access = SEC_FILE_WRITE_DATA;
1154 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1155 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1156 create.in.fname = full_name;
1158 status = smb2_create(tree, mem_ctx, &create);
1159 if (!NT_STATUS_IS_OK(status)) {
1160 if (value == NULL) {
1161 return true;
1162 } else {
1163 torture_comment(tctx, "Unable to open stream %s\n",
1164 full_name);
1165 sleep(10000000);
1166 return false;
1170 handle = create.out.file.handle;
1171 if (value == NULL) {
1172 return true;
1175 status = smb2_util_write(tree, handle, value, offset, size);
1177 if (!NT_STATUS_IS_OK(status)) {
1178 torture_comment(tctx, "(%s) Failed to write %lu bytes to "
1179 "stream '%s'\n", location, (long)size, full_name);
1180 return false;
1183 smb2_util_close(tree, handle);
1184 return true;
1187 static bool torture_setup_local_xattr(struct torture_context *tctx,
1188 const char *path_option,
1189 const char *name,
1190 const char *xattr,
1191 const char *metadata,
1192 size_t size)
1194 int ret = true;
1195 int result;
1196 const char *spath;
1197 char *path;
1199 spath = torture_setting_string(tctx, path_option, NULL);
1200 if (spath == NULL) {
1201 printf("No sharepath for option %s\n", path_option);
1202 return false;
1205 path = talloc_asprintf(tctx, "%s/%s", spath, name);
1207 result = setxattr(path, xattr, metadata, size, 0);
1208 if (result != 0) {
1209 ret = false;
1212 TALLOC_FREE(path);
1214 return ret;
1218 * Create a file or directory
1220 static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree,
1221 const char *name, bool dir)
1223 struct smb2_create io;
1224 NTSTATUS status;
1226 smb2_util_unlink(tree, name);
1227 ZERO_STRUCT(io);
1228 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1229 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1230 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1231 io.in.share_access =
1232 NTCREATEX_SHARE_ACCESS_DELETE|
1233 NTCREATEX_SHARE_ACCESS_READ|
1234 NTCREATEX_SHARE_ACCESS_WRITE;
1235 io.in.create_options = 0;
1236 io.in.fname = name;
1237 if (dir) {
1238 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1239 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
1240 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1241 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1244 status = smb2_create(tree, mem_ctx, &io);
1245 if (!NT_STATUS_IS_OK(status)) {
1246 return false;
1249 status = smb2_util_close(tree, io.out.file.handle);
1250 if (!NT_STATUS_IS_OK(status)) {
1251 return false;
1254 return true;
1257 static bool enable_aapl(struct torture_context *tctx,
1258 struct smb2_tree *tree)
1260 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1261 NTSTATUS status;
1262 bool ret = true;
1263 struct smb2_create io;
1264 DATA_BLOB data;
1265 struct smb2_create_blob *aapl = NULL;
1266 uint32_t aapl_server_caps;
1267 uint32_t expected_scaps = (SMB2_CRTCTX_AAPL_UNIX_BASED |
1268 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1269 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1270 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
1271 bool is_osx_server = torture_setting_bool(tctx, "osx", false);
1273 ZERO_STRUCT(io);
1274 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1275 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1276 io.in.create_disposition = NTCREATEX_DISP_OPEN;
1277 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1278 NTCREATEX_SHARE_ACCESS_READ |
1279 NTCREATEX_SHARE_ACCESS_WRITE);
1280 io.in.fname = "";
1283 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1284 * controls behaviour of Apple's SMB2 extensions for the whole
1285 * session!
1288 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1289 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1290 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1291 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1292 SMB2_CRTCTX_AAPL_MODEL_INFO));
1293 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1294 SMB2_CRTCTX_AAPL_UNIX_BASED |
1295 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1297 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1298 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_blob_add");
1300 status = smb2_create(tree, tctx, &io);
1301 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1303 status = smb2_util_close(tree, io.out.file.handle);
1304 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close");
1307 * Now check returned AAPL context
1309 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1311 aapl = smb2_create_blob_find(&io.out.blobs,
1312 SMB2_CREATE_TAG_AAPL);
1313 torture_assert_goto(tctx, aapl != NULL, ret, done, "missing AAPL context");
1315 if (!is_osx_server) {
1316 size_t expected_aapl_ctx_size;
1318 expected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
1320 torture_assert_goto(
1321 tctx, aapl->data.length == expected_aapl_ctx_size,
1322 ret, done, "bad AAPL size");
1325 aapl_server_caps = BVAL(aapl->data.data, 16);
1326 torture_assert_goto(tctx, aapl_server_caps == expected_scaps,
1327 ret, done, "bad AAPL caps");
1329 done:
1330 talloc_free(mem_ctx);
1331 return ret;
1334 static bool test_read_netatalk_metadata(struct torture_context *tctx,
1335 struct smb2_tree *tree)
1337 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1338 const char *fname = BASEDIR "\\torture_read_metadata";
1339 NTSTATUS status;
1340 struct smb2_handle testdirh;
1341 bool ret = true;
1342 ssize_t len;
1343 const char *localdir = NULL;
1345 torture_comment(tctx, "Checking metadata access\n");
1347 localdir = torture_setting_string(tctx, "localdir", NULL);
1348 if (localdir == NULL) {
1349 torture_skip(tctx, "Need localdir for test");
1352 smb2_util_unlink(tree, fname);
1354 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1355 CHECK_STATUS(status, NT_STATUS_OK);
1356 smb2_util_close(tree, testdirh);
1358 ret = torture_setup_file(mem_ctx, tree, fname, false);
1359 if (ret == false) {
1360 goto done;
1363 ret = torture_setup_local_xattr(tctx, "localdir",
1364 BASEDIR "/torture_read_metadata",
1365 AFPINFO_EA_NETATALK,
1366 metadata_xattr, sizeof(metadata_xattr));
1367 if (ret == false) {
1368 goto done;
1371 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1372 0, 60, 0, 4, "AFP");
1373 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1375 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1376 0, 60, 16, 8, "BARRFOOO");
1377 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1379 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1380 16, 8, 0, 3, "AFP");
1381 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1383 /* Check reading offset and read size > sizeof(AFPINFO_STREAM) */
1385 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1386 AFPINFO_STREAM, 0, 61);
1387 CHECK_VALUE(len, 60);
1389 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1390 AFPINFO_STREAM, 59, 2);
1391 CHECK_VALUE(len, 2);
1393 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1394 AFPINFO_STREAM, 60, 1);
1395 CHECK_VALUE(len, 1);
1397 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1398 AFPINFO_STREAM, 61, 1);
1399 CHECK_VALUE(len, 0);
1401 done:
1402 smb2_deltree(tree, BASEDIR);
1403 talloc_free(mem_ctx);
1404 return ret;
1407 static bool test_read_afpinfo(struct torture_context *tctx,
1408 struct smb2_tree *tree)
1410 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1411 const char *fname = BASEDIR "\\torture_read_metadata";
1412 NTSTATUS status;
1413 struct smb2_handle testdirh;
1414 bool ret = true;
1415 ssize_t len;
1416 AfpInfo *info;
1417 const char *type_creator = "SMB,OLE!";
1419 torture_comment(tctx, "Checking metadata access\n");
1421 smb2_util_unlink(tree, fname);
1423 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1424 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
1425 smb2_util_close(tree, testdirh);
1427 ret = torture_setup_file(mem_ctx, tree, fname, false);
1428 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
1430 info = torture_afpinfo_new(mem_ctx);
1431 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
1433 memcpy(info->afpi_FinderInfo, type_creator, 8);
1434 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1435 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
1437 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1438 0, 60, 0, 4, "AFP");
1439 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1441 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1442 0, 60, 16, 8, type_creator);
1443 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1446 * OS X ignores offset <= 60 and treats the as
1447 * offset=0. Reading from offsets > 60 returns EOF=0.
1450 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1451 16, 8, 0, 8, "AFP\0\0\0\001\0");
1452 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1454 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1455 AFPINFO_STREAM, 0, 61);
1456 torture_assert_goto(tctx, len == 60, ret, done, "read_stream failed");
1458 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1459 AFPINFO_STREAM, 59, 2);
1460 torture_assert_goto(tctx, len == 2, ret, done, "read_stream failed");
1462 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1463 59, 2, 0, 2, "AF");
1464 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1466 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1467 AFPINFO_STREAM, 60, 1);
1468 torture_assert_goto(tctx, len == 1, ret, done, "read_stream failed");
1470 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1471 60, 1, 0, 1, "A");
1472 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1474 len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1475 AFPINFO_STREAM, 61, 1);
1476 torture_assert_goto(tctx, len == 0, ret, done, "read_stream failed");
1478 done:
1479 smb2_util_unlink(tree, fname);
1480 smb2_deltree(tree, BASEDIR);
1481 talloc_free(mem_ctx);
1482 return ret;
1485 static bool test_write_atalk_metadata(struct torture_context *tctx,
1486 struct smb2_tree *tree)
1488 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1489 const char *fname = BASEDIR "\\torture_write_metadata";
1490 const char *type_creator = "SMB,OLE!";
1491 NTSTATUS status;
1492 struct smb2_handle testdirh;
1493 bool ret = true;
1494 AfpInfo *info;
1496 smb2_deltree(tree, BASEDIR);
1497 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1498 CHECK_STATUS(status, NT_STATUS_OK);
1499 smb2_util_close(tree, testdirh);
1501 ret = torture_setup_file(mem_ctx, tree, fname, false);
1502 if (ret == false) {
1503 goto done;
1506 info = torture_afpinfo_new(mem_ctx);
1507 if (info == NULL) {
1508 goto done;
1511 memcpy(info->afpi_FinderInfo, type_creator, 8);
1512 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1513 ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1514 0, 60, 16, 8, type_creator);
1516 done:
1517 smb2_util_unlink(tree, fname);
1518 smb2_deltree(tree, BASEDIR);
1519 talloc_free(mem_ctx);
1520 return ret;
1523 static bool test_write_atalk_rfork_io(struct torture_context *tctx,
1524 struct smb2_tree *tree)
1526 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1527 const char *fname = BASEDIR "\\torture_write_rfork_io";
1528 const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
1529 const char *rfork_content = "1234567890";
1530 NTSTATUS status;
1531 struct smb2_handle testdirh;
1532 bool ret = true;
1534 union smb_open io;
1535 struct smb2_handle filehandle;
1536 union smb_fileinfo finfo;
1537 union smb_setfileinfo sinfo;
1539 smb2_util_unlink(tree, fname);
1541 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1542 CHECK_STATUS(status, NT_STATUS_OK);
1543 smb2_util_close(tree, testdirh);
1545 ret = torture_setup_file(mem_ctx, tree, fname, false);
1546 if (ret == false) {
1547 goto done;
1550 torture_comment(tctx, "(%s) writing to resource fork\n",
1551 __location__);
1553 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1554 fname, AFPRESOURCE_STREAM_NAME,
1555 10, 10, rfork_content);
1557 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1558 fname, AFPRESOURCE_STREAM_NAME,
1559 0, 20, 10, 10, rfork_content);
1561 /* Check size after write */
1563 ZERO_STRUCT(io);
1564 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1565 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1566 SEC_FILE_WRITE_ATTRIBUTE;
1567 io.smb2.in.fname = rfork;
1568 status = smb2_create(tree, mem_ctx, &(io.smb2));
1569 CHECK_STATUS(status, NT_STATUS_OK);
1570 filehandle = io.smb2.out.file.handle;
1572 torture_comment(tctx, "(%s) check resource fork size after write\n",
1573 __location__);
1575 ZERO_STRUCT(finfo);
1576 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1577 finfo.generic.in.file.handle = filehandle;
1578 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1579 CHECK_STATUS(status, NT_STATUS_OK);
1580 if (finfo.all_info.out.size != 20) {
1581 torture_result(tctx, TORTURE_FAIL,
1582 "(%s) Incorrect resource fork size\n",
1583 __location__);
1584 ret = false;
1585 smb2_util_close(tree, filehandle);
1586 goto done;
1588 smb2_util_close(tree, filehandle);
1590 /* Write at large offset */
1592 torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
1593 __location__);
1595 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1596 fname, AFPRESOURCE_STREAM_NAME,
1597 (off_t)64*1024*1024, 10, rfork_content);
1599 ret &= check_stream(tree, __location__, tctx, mem_ctx,
1600 fname, AFPRESOURCE_STREAM_NAME,
1601 (off_t)64*1024*1024, 10, 0, 10, rfork_content);
1603 /* Truncate back to size of 1 byte */
1605 torture_comment(tctx, "(%s) truncate resource fork and check size\n",
1606 __location__);
1608 ZERO_STRUCT(io);
1609 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1610 io.smb2.in.desired_access = SEC_FILE_ALL;
1611 io.smb2.in.fname = rfork;
1612 status = smb2_create(tree, mem_ctx, &(io.smb2));
1613 CHECK_STATUS(status, NT_STATUS_OK);
1614 filehandle = io.smb2.out.file.handle;
1616 ZERO_STRUCT(sinfo);
1617 sinfo.end_of_file_info.level =
1618 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1619 sinfo.end_of_file_info.in.file.handle = filehandle;
1620 sinfo.end_of_file_info.in.size = 1;
1621 status = smb2_setinfo_file(tree, &sinfo);
1622 CHECK_STATUS(status, NT_STATUS_OK);
1624 smb2_util_close(tree, filehandle);
1626 /* Now check size */
1627 ZERO_STRUCT(io);
1628 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1629 io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1630 SEC_FILE_WRITE_ATTRIBUTE;
1631 io.smb2.in.fname = rfork;
1632 status = smb2_create(tree, mem_ctx, &(io.smb2));
1633 CHECK_STATUS(status, NT_STATUS_OK);
1634 filehandle = io.smb2.out.file.handle;
1636 ZERO_STRUCT(finfo);
1637 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1638 finfo.generic.in.file.handle = filehandle;
1639 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1640 CHECK_STATUS(status, NT_STATUS_OK);
1641 if (finfo.all_info.out.size != 1) {
1642 torture_result(tctx, TORTURE_FAIL,
1643 "(%s) Incorrect resource fork size\n",
1644 __location__);
1645 ret = false;
1646 smb2_util_close(tree, filehandle);
1647 goto done;
1649 smb2_util_close(tree, filehandle);
1651 done:
1652 smb2_util_unlink(tree, fname);
1653 smb2_deltree(tree, BASEDIR);
1654 talloc_free(mem_ctx);
1655 return ret;
1658 static bool test_rfork_truncate(struct torture_context *tctx,
1659 struct smb2_tree *tree)
1661 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1662 const char *fname = BASEDIR "\\torture_rfork_truncate";
1663 const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
1664 const char *rfork_content = "1234567890";
1665 NTSTATUS status;
1666 struct smb2_handle testdirh;
1667 bool ret = true;
1668 struct smb2_create create;
1669 struct smb2_handle fh1, fh2, fh3;
1670 union smb_setfileinfo sinfo;
1672 smb2_util_unlink(tree, fname);
1674 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1675 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1676 smb2_util_close(tree, testdirh);
1678 ret = torture_setup_file(mem_ctx, tree, fname, false);
1679 if (ret == false) {
1680 goto done;
1683 ret &= write_stream(tree, __location__, tctx, mem_ctx,
1684 fname, AFPRESOURCE_STREAM,
1685 10, 10, rfork_content);
1687 /* Truncate back to size 0, further access MUST return ENOENT */
1689 torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
1690 __location__);
1692 ZERO_STRUCT(create);
1693 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1694 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1695 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1696 create.in.fname = fname;
1697 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1698 NTCREATEX_SHARE_ACCESS_READ |
1699 NTCREATEX_SHARE_ACCESS_WRITE;
1700 status = smb2_create(tree, mem_ctx, &create);
1701 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1702 fh1 = create.out.file.handle;
1704 ZERO_STRUCT(create);
1705 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1706 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1707 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1708 create.in.fname = rfork;
1709 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1710 NTCREATEX_SHARE_ACCESS_READ |
1711 NTCREATEX_SHARE_ACCESS_WRITE;
1712 status = smb2_create(tree, mem_ctx, &create);
1713 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1714 fh2 = create.out.file.handle;
1716 ZERO_STRUCT(sinfo);
1717 sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1718 sinfo.end_of_file_info.in.file.handle = fh2;
1719 sinfo.end_of_file_info.in.size = 0;
1720 status = smb2_setinfo_file(tree, &sinfo);
1721 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
1724 * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
1726 ZERO_STRUCT(create);
1727 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1728 create.in.desired_access = SEC_FILE_ALL;
1729 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1730 create.in.fname = rfork;
1731 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1732 NTCREATEX_SHARE_ACCESS_READ |
1733 NTCREATEX_SHARE_ACCESS_WRITE;
1734 status = smb2_create(tree, mem_ctx, &create);
1735 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1738 * Do another open on the rfork and write to the new handle. A
1739 * naive server might unlink the AppleDouble resource fork
1740 * file when its truncated to 0 bytes above, so in case both
1741 * open handles share the same underlying fd, the unlink would
1742 * cause the below write to be lost.
1744 ZERO_STRUCT(create);
1745 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1746 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1747 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1748 create.in.fname = rfork;
1749 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1750 NTCREATEX_SHARE_ACCESS_READ |
1751 NTCREATEX_SHARE_ACCESS_WRITE;
1752 status = smb2_create(tree, mem_ctx, &create);
1753 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1754 fh3 = create.out.file.handle;
1756 status = smb2_util_write(tree, fh3, "foo", 0, 3);
1757 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
1759 smb2_util_close(tree, fh3);
1760 smb2_util_close(tree, fh2);
1761 smb2_util_close(tree, fh1);
1763 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
1764 0, 3, 0, 3, "foo");
1765 torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1767 done:
1768 smb2_util_unlink(tree, fname);
1769 smb2_deltree(tree, BASEDIR);
1770 talloc_free(mem_ctx);
1771 return ret;
1774 static bool test_rfork_create(struct torture_context *tctx,
1775 struct smb2_tree *tree)
1777 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1778 const char *fname = BASEDIR "\\torture_rfork_create";
1779 const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1780 NTSTATUS status;
1781 struct smb2_handle testdirh;
1782 bool ret = true;
1783 struct smb2_create create;
1784 struct smb2_handle fh1;
1785 const char *streams[] = {
1786 "::$DATA"
1788 union smb_fileinfo finfo;
1790 smb2_util_unlink(tree, fname);
1792 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1793 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1794 smb2_util_close(tree, testdirh);
1796 ret = torture_setup_file(mem_ctx, tree, fname, false);
1797 if (ret == false) {
1798 goto done;
1801 torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
1802 __location__);
1804 ZERO_STRUCT(create);
1805 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1806 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1807 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1808 create.in.fname = rfork;
1809 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1810 NTCREATEX_SHARE_ACCESS_READ |
1811 NTCREATEX_SHARE_ACCESS_WRITE;
1812 status = smb2_create(tree, mem_ctx, &create);
1813 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1815 torture_comment(tctx, "(%s) create resource fork\n", __location__);
1817 ZERO_STRUCT(create);
1818 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1819 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1820 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1821 create.in.fname = rfork;
1822 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1823 NTCREATEX_SHARE_ACCESS_READ |
1824 NTCREATEX_SHARE_ACCESS_WRITE;
1825 status = smb2_create(tree, mem_ctx, &create);
1826 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1827 fh1 = create.out.file.handle;
1829 torture_comment(tctx, "(%s) getinfo on create handle\n",
1830 __location__);
1832 ZERO_STRUCT(finfo);
1833 finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1834 finfo.generic.in.file.handle = fh1;
1835 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1836 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
1837 if (finfo.all_info.out.size != 0) {
1838 torture_result(tctx, TORTURE_FAIL,
1839 "(%s) Incorrect resource fork size\n",
1840 __location__);
1841 ret = false;
1842 smb2_util_close(tree, fh1);
1843 goto done;
1846 torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
1847 __location__);
1849 ZERO_STRUCT(create);
1850 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1851 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1852 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1853 create.in.fname = rfork;
1854 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1855 NTCREATEX_SHARE_ACCESS_READ |
1856 NTCREATEX_SHARE_ACCESS_WRITE;
1857 status = smb2_create(tree, mem_ctx, &create);
1858 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1860 ret = check_stream_list(tree, tctx, fname, 1, streams, false);
1861 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
1863 torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
1864 __location__);
1866 ZERO_STRUCT(create);
1867 create.in.create_disposition = NTCREATEX_DISP_OPEN;
1868 create.in.desired_access = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1869 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1870 create.in.fname = rfork;
1871 create.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
1872 NTCREATEX_SHARE_ACCESS_READ |
1873 NTCREATEX_SHARE_ACCESS_WRITE;
1874 status = smb2_create(tree, mem_ctx, &create);
1875 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1877 done:
1878 smb2_util_unlink(tree, fname);
1879 smb2_deltree(tree, BASEDIR);
1880 talloc_free(mem_ctx);
1881 return ret;
1884 static bool test_rfork_create_ro(struct torture_context *tctx,
1885 struct smb2_tree *tree)
1887 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1888 const char *fname = BASEDIR "\\torture_rfork_create";
1889 const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1890 NTSTATUS status;
1891 struct smb2_handle testdirh;
1892 bool ret = true;
1893 struct smb2_create create;
1895 smb2_util_unlink(tree, fname);
1896 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1897 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1898 "torture_smb2_testdir\n");
1899 smb2_util_close(tree, testdirh);
1901 ret = torture_setup_file(mem_ctx, tree, fname, false);
1902 if (ret == false) {
1903 goto done;
1906 torture_comment(tctx, "(%s) Try opening read-only with "
1907 "open_if create disposition, should return ENOENT\n",
1908 __location__);
1910 ZERO_STRUCT(create);
1911 create.in.fname = rfork;
1912 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1913 create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
1914 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1915 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
1916 status = smb2_create(tree, mem_ctx, &(create));
1917 torture_assert_ntstatus_equal_goto(tctx, status,
1918 NT_STATUS_OBJECT_NAME_NOT_FOUND,
1919 ret, done, "smb2_create failed\n");
1921 torture_comment(tctx, "(%s) Now write something to the "
1922 "rsrc stream, then the same open should succeed\n",
1923 __location__);
1925 ret = write_stream(tree, __location__, tctx, mem_ctx,
1926 fname, AFPRESOURCE_STREAM_NAME,
1927 0, 3, "foo");
1928 torture_assert_goto(tctx, ret == true, ret, done,
1929 "write_stream failed\n");
1931 ret = check_stream(tree, __location__, tctx, mem_ctx,
1932 fname, AFPRESOURCE_STREAM,
1933 0, 3, 0, 3, "foo");
1934 torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1936 ZERO_STRUCT(create);
1937 create.in.fname = rfork;
1938 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1939 create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
1940 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1941 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
1942 status = smb2_create(tree, mem_ctx, &(create));
1943 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1944 "smb2_create failed\n");
1946 smb2_util_close(tree, create.out.file.handle);
1948 done:
1949 smb2_util_unlink(tree, fname);
1950 smb2_deltree(tree, BASEDIR);
1951 talloc_free(mem_ctx);
1952 return ret;
1955 static bool test_adouble_conversion(struct torture_context *tctx,
1956 struct smb2_tree *tree)
1958 TALLOC_CTX *mem_ctx = talloc_new(tctx);
1959 const char *fname = BASEDIR "\\test_adouble_conversion";
1960 const char *adname = BASEDIR "/._test_adouble_conversion";
1961 NTSTATUS status;
1962 struct smb2_handle testdirh;
1963 bool ret = true;
1964 const char *data = "This resource fork intentionally left blank";
1965 size_t datalen = strlen(data);
1966 const char *streams[] = {
1967 "::$DATA",
1968 AFPINFO_STREAM,
1969 AFPRESOURCE_STREAM,
1970 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
1971 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
1974 smb2_deltree(tree, BASEDIR);
1976 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1977 CHECK_STATUS(status, NT_STATUS_OK);
1978 smb2_util_close(tree, testdirh);
1980 ret = torture_setup_file(tctx, tree, fname, false);
1981 torture_assert_goto(tctx, ret == true, ret, done,
1982 "torture_setup_file failed\n");
1984 ret = torture_setup_file(tctx, tree, adname, false);
1985 torture_assert_goto(tctx, ret == true, ret, done,
1986 "torture_setup_file failed\n");
1988 ret = write_stream(tree, __location__, tctx, mem_ctx,
1989 adname, NULL,
1990 0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
1991 torture_assert_goto(tctx, ret == true, ret, done,
1992 "write_stream failed\n");
1994 torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
1995 __location__);
1997 ret = check_stream(tree, __location__, tctx, mem_ctx,
1998 fname, AFPRESOURCE_STREAM,
1999 16, datalen, 0, datalen, data);
2000 torture_assert_goto(tctx, ret == true, ret, done,
2001 "check AFPRESOURCE_STREAM failed\n");
2003 ret = check_stream(tree, __location__, tctx, mem_ctx,
2004 fname, AFPINFO_STREAM,
2005 0, 60, 16, 8, "TESTSLOW");
2006 torture_assert_goto(tctx, ret == true, ret, done,
2007 "check AFPINFO_STREAM failed\n");
2009 ret = check_stream(tree, __location__, tctx, mem_ctx, fname,
2010 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2011 0, 3, 0, 3, "baz");
2012 torture_assert_goto(tctx, ret == true, ret, done,
2013 "check foo:bar stream failed\n");
2015 ret = check_stream_list(tree, tctx, fname, 5, streams, false);
2016 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
2018 done:
2019 smb2_deltree(tree, BASEDIR);
2020 talloc_free(mem_ctx);
2021 return ret;
2024 static bool test_aapl(struct torture_context *tctx,
2025 struct smb2_tree *tree)
2027 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2028 const char *fname = BASEDIR "\\test_aapl";
2029 NTSTATUS status;
2030 struct smb2_handle testdirh;
2031 bool ret = true;
2032 struct smb2_create io;
2033 DATA_BLOB data;
2034 struct smb2_create_blob *aapl = NULL;
2035 AfpInfo *info;
2036 const char *type_creator = "SMB,OLE!";
2037 char type_creator_buf[9];
2038 uint32_t aapl_cmd;
2039 uint32_t aapl_reply_bitmap;
2040 uint32_t aapl_server_caps;
2041 uint32_t aapl_vol_caps;
2042 char *model;
2043 struct smb2_find f;
2044 unsigned int count;
2045 union smb_search_data *d;
2046 uint64_t rfork_len;
2047 bool is_osx_server = torture_setting_bool(tctx, "osx", false);
2049 smb2_deltree(tree, BASEDIR);
2051 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
2052 CHECK_STATUS(status, NT_STATUS_OK);
2053 smb2_util_close(tree, testdirh);
2055 ZERO_STRUCT(io);
2056 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2057 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2058 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2059 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2060 NTCREATEX_SHARE_ACCESS_READ |
2061 NTCREATEX_SHARE_ACCESS_WRITE);
2062 io.in.fname = fname;
2065 * Issuing an SMB2/CREATE with a suitably formed AAPL context,
2066 * controls behaviour of Apple's SMB2 extensions for the whole
2067 * session!
2070 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2071 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2072 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2073 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2074 SMB2_CRTCTX_AAPL_MODEL_INFO));
2075 SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2076 SMB2_CRTCTX_AAPL_UNIX_BASED |
2077 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
2079 torture_comment(tctx, "Testing SMB2 create context AAPL\n");
2080 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2081 CHECK_STATUS(status, NT_STATUS_OK);
2083 status = smb2_create(tree, tctx, &io);
2084 CHECK_STATUS(status, NT_STATUS_OK);
2085 status = smb2_util_close(tree, io.out.file.handle);
2086 CHECK_STATUS(status, NT_STATUS_OK);
2089 * Now check returned AAPL context
2091 torture_comment(tctx, "Comparing returned AAPL capabilities\n");
2093 aapl = smb2_create_blob_find(&io.out.blobs,
2094 SMB2_CREATE_TAG_AAPL);
2096 if (aapl == NULL) {
2097 torture_result(tctx, TORTURE_FAIL,
2098 "(%s) unexpectedly no AAPL capabilities were returned.",
2099 __location__);
2100 ret = false;
2101 goto done;
2104 if (!is_osx_server) {
2105 size_t expected_aapl_ctx_size;
2106 bool size_ok;
2109 * uint32_t CommandCode = kAAPL_SERVER_QUERY
2110 * uint32_t Reserved = 0;
2111 * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
2112 * kAAPL_VOLUME_CAPS |
2113 * kAAPL_MODEL_INFO;
2114 * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
2115 * kAAPL_SUPPORTS_OSX_COPYFILE;
2116 * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
2117 * kAAPL_CASE_SENSITIVE;
2118 * uint32_t Pad2 = 0;
2119 * uint32_t ModelStringLen = 10;
2120 * ucs2_t ModelString[5] = "MacSamba";
2122 expected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
2124 size_ok = aapl->data.length == expected_aapl_ctx_size;
2125 torture_assert_goto(tctx, size_ok, ret, done, "bad AAPL size");
2128 aapl_cmd = IVAL(aapl->data.data, 0);
2129 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2130 torture_result(tctx, TORTURE_FAIL,
2131 "(%s) unexpected cmd: %d",
2132 __location__, (int)aapl_cmd);
2133 ret = false;
2134 goto done;
2137 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2138 if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
2139 SMB2_CRTCTX_AAPL_VOLUME_CAPS |
2140 SMB2_CRTCTX_AAPL_MODEL_INFO)) {
2141 torture_result(tctx, TORTURE_FAIL,
2142 "(%s) unexpected reply_bitmap: %d",
2143 __location__, (int)aapl_reply_bitmap);
2144 ret = false;
2145 goto done;
2148 aapl_server_caps = BVAL(aapl->data.data, 16);
2149 if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
2150 SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
2151 SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
2152 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
2153 torture_result(tctx, TORTURE_FAIL,
2154 "(%s) unexpected server_caps: %d",
2155 __location__, (int)aapl_server_caps);
2156 ret = false;
2157 goto done;
2160 aapl_vol_caps = BVAL(aapl->data.data, 24);
2161 if (aapl_vol_caps != 0) {
2162 /* this will fail on a case insensitive fs ... */
2163 torture_result(tctx, TORTURE_FAIL,
2164 "(%s) unexpected vol_caps: %d",
2165 __location__, (int)aapl_vol_caps);
2168 ret = convert_string_talloc(mem_ctx,
2169 CH_UTF16LE, CH_UNIX,
2170 aapl->data.data + 40, 10,
2171 &model, NULL);
2172 if (ret == false) {
2173 torture_result(tctx, TORTURE_FAIL,
2174 "(%s) convert_string_talloc() failed",
2175 __location__);
2176 goto done;
2178 torture_comment(tctx, "Got server model: \"%s\"\n", model);
2181 * Now that Requested AAPL extensions are enabled, setup some
2182 * Mac files with metadata and resource fork
2184 ret = torture_setup_file(mem_ctx, tree, fname, false);
2185 if (ret == false) {
2186 torture_result(tctx, TORTURE_FAIL,
2187 "(%s) torture_setup_file() failed",
2188 __location__);
2189 goto done;
2192 info = torture_afpinfo_new(mem_ctx);
2193 if (info == NULL) {
2194 torture_result(tctx, TORTURE_FAIL,
2195 "(%s) torture_afpinfo_new() failed",
2196 __location__);
2197 ret = false;
2198 goto done;
2201 memcpy(info->afpi_FinderInfo, type_creator, 8);
2202 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2203 if (ret == false) {
2204 torture_result(tctx, TORTURE_FAIL,
2205 "(%s) torture_write_afpinfo() failed",
2206 __location__);
2207 goto done;
2210 ret = write_stream(tree, __location__, tctx, mem_ctx,
2211 fname, AFPRESOURCE_STREAM_NAME,
2212 0, 3, "foo");
2213 if (ret == false) {
2214 torture_result(tctx, TORTURE_FAIL,
2215 "(%s) write_stream() failed",
2216 __location__);
2217 goto done;
2221 * Ok, file is prepared, now call smb2/find
2224 ZERO_STRUCT(io);
2225 io.in.desired_access = SEC_RIGHTS_DIR_READ;
2226 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2227 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2228 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
2229 NTCREATEX_SHARE_ACCESS_WRITE |
2230 NTCREATEX_SHARE_ACCESS_DELETE);
2231 io.in.create_disposition = NTCREATEX_DISP_OPEN;
2232 io.in.fname = BASEDIR;
2233 status = smb2_create(tree, tctx, &io);
2234 CHECK_STATUS(status, NT_STATUS_OK);
2236 ZERO_STRUCT(f);
2237 f.in.file.handle = io.out.file.handle;
2238 f.in.pattern = "test_aapl";
2239 f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
2240 f.in.max_response_size = 0x1000;
2241 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
2243 status = smb2_find_level(tree, tree, &f, &count, &d);
2244 CHECK_STATUS(status, NT_STATUS_OK);
2246 status = smb2_util_close(tree, io.out.file.handle);
2247 CHECK_STATUS(status, NT_STATUS_OK);
2249 if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2250 torture_result(tctx, TORTURE_FAIL,
2251 "(%s) write_stream() failed",
2252 __location__);
2253 ret = false;
2254 goto done;
2257 if (d[0].id_both_directory_info.short_name.private_length != 24) {
2258 torture_result(tctx, TORTURE_FAIL,
2259 "(%s) bad short_name length %" PRIu32 ", expected 24",
2260 __location__, d[0].id_both_directory_info.short_name.private_length);
2261 ret = false;
2262 goto done;
2265 torture_comment(tctx, "short_name buffer:\n");
2266 dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2269 * Extract data as specified by the AAPL extension:
2270 * - ea_size contains max_access
2271 * - short_name contains resource fork length + FinderInfo
2272 * - reserved2 contains the unix mode
2274 torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2275 d[0].id_both_directory_info.ea_size);
2277 rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2278 if (rfork_len != 3) {
2279 torture_result(tctx, TORTURE_FAIL,
2280 "(%s) expected resource fork length 3, got: %" PRIu64,
2281 __location__, rfork_len);
2282 ret = false;
2283 goto done;
2286 memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2287 type_creator_buf[8] = 0;
2288 if (strcmp(type_creator, type_creator_buf) != 0) {
2289 torture_result(tctx, TORTURE_FAIL,
2290 "(%s) expected type/creator \"%s\" , got: %s",
2291 __location__, type_creator, type_creator_buf);
2292 ret = false;
2293 goto done;
2296 done:
2297 smb2_util_unlink(tree, fname);
2298 smb2_deltree(tree, BASEDIR);
2299 talloc_free(mem_ctx);
2300 return ret;
2303 static uint64_t patt_hash(uint64_t off)
2305 return off;
2308 static bool write_pattern(struct torture_context *torture,
2309 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2310 struct smb2_handle h, uint64_t off, uint64_t len,
2311 uint64_t patt_off)
2313 NTSTATUS status;
2314 uint64_t i;
2315 uint8_t *buf;
2316 uint64_t io_sz = MIN(1024 * 64, len);
2318 if (len == 0) {
2319 return true;
2322 torture_assert(torture, (len % 8) == 0, "invalid write len");
2324 buf = talloc_zero_size(mem_ctx, io_sz);
2325 torture_assert(torture, (buf != NULL), "no memory for file data buf");
2327 while (len > 0) {
2328 for (i = 0; i <= io_sz - 8; i += 8) {
2329 SBVAL(buf, i, patt_hash(patt_off));
2330 patt_off += 8;
2333 status = smb2_util_write(tree, h,
2334 buf, off, io_sz);
2335 torture_assert_ntstatus_ok(torture, status, "file write");
2337 len -= io_sz;
2338 off += io_sz;
2341 talloc_free(buf);
2343 return true;
2346 static bool check_pattern(struct torture_context *torture,
2347 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2348 struct smb2_handle h, uint64_t off, uint64_t len,
2349 uint64_t patt_off)
2351 if (len == 0) {
2352 return true;
2355 torture_assert(torture, (len % 8) == 0, "invalid read len");
2357 while (len > 0) {
2358 uint64_t i;
2359 struct smb2_read r;
2360 NTSTATUS status;
2361 uint64_t io_sz = MIN(1024 * 64, len);
2363 ZERO_STRUCT(r);
2364 r.in.file.handle = h;
2365 r.in.length = io_sz;
2366 r.in.offset = off;
2367 status = smb2_read(tree, mem_ctx, &r);
2368 torture_assert_ntstatus_ok(torture, status, "read");
2370 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2371 "read data len mismatch");
2373 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2374 uint64_t data = BVAL(r.out.data.data, i);
2375 torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2376 talloc_asprintf(torture, "read data "
2377 "pattern bad at %llu\n",
2378 (unsigned long long)off + i));
2380 talloc_free(r.out.data.data);
2381 len -= io_sz;
2382 off += io_sz;
2385 return true;
2388 static bool test_setup_open(struct torture_context *torture,
2389 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2390 const char *fname,
2391 struct smb2_handle *fh,
2392 uint32_t desired_access,
2393 uint32_t file_attributes)
2395 struct smb2_create io;
2396 NTSTATUS status;
2398 ZERO_STRUCT(io);
2399 io.in.desired_access = desired_access;
2400 io.in.file_attributes = file_attributes;
2401 io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2402 io.in.share_access =
2403 NTCREATEX_SHARE_ACCESS_DELETE|
2404 NTCREATEX_SHARE_ACCESS_READ|
2405 NTCREATEX_SHARE_ACCESS_WRITE;
2406 if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2407 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2409 io.in.fname = fname;
2411 status = smb2_create(tree, mem_ctx, &io);
2412 torture_assert_ntstatus_ok(torture, status, "file create");
2414 *fh = io.out.file.handle;
2416 return true;
2419 static bool test_setup_create_fill(struct torture_context *torture,
2420 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2421 const char *fname,
2422 struct smb2_handle *fh,
2423 uint64_t size,
2424 uint32_t desired_access,
2425 uint32_t file_attributes)
2427 bool ok;
2429 ok = test_setup_open(torture, tree, mem_ctx,
2430 fname,
2432 desired_access,
2433 file_attributes);
2434 torture_assert(torture, ok, "file open");
2436 if (size > 0) {
2437 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2438 torture_assert(torture, ok, "write pattern");
2440 return true;
2443 static bool test_setup_copy_chunk(struct torture_context *torture,
2444 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2445 uint32_t nchunks,
2446 const char *src_name,
2447 struct smb2_handle *src_h,
2448 uint64_t src_size,
2449 uint32_t src_desired_access,
2450 const char *dst_name,
2451 struct smb2_handle *dest_h,
2452 uint64_t dest_size,
2453 uint32_t dest_desired_access,
2454 struct srv_copychunk_copy *cc_copy,
2455 union smb_ioctl *io)
2457 struct req_resume_key_rsp res_key;
2458 bool ok;
2459 NTSTATUS status;
2460 enum ndr_err_code ndr_ret;
2462 ok = test_setup_create_fill(torture, tree, mem_ctx, src_name,
2463 src_h, src_size, src_desired_access,
2464 FILE_ATTRIBUTE_NORMAL);
2465 torture_assert(torture, ok, "src file create fill");
2467 ok = test_setup_create_fill(torture, tree, mem_ctx, dst_name,
2468 dest_h, dest_size, dest_desired_access,
2469 FILE_ATTRIBUTE_NORMAL);
2470 torture_assert(torture, ok, "dest file create fill");
2472 ZERO_STRUCTPN(io);
2473 io->smb2.level = RAW_IOCTL_SMB2;
2474 io->smb2.in.file.handle = *src_h;
2475 io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2476 /* Allow for Key + ContextLength + Context */
2477 io->smb2.in.max_response_size = 32;
2478 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2480 status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2481 torture_assert_ntstatus_ok(torture, status,
2482 "FSCTL_SRV_REQUEST_RESUME_KEY");
2484 ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2485 (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2487 torture_assert_ndr_success(torture, ndr_ret,
2488 "ndr_pull_req_resume_key_rsp");
2490 ZERO_STRUCTPN(io);
2491 io->smb2.level = RAW_IOCTL_SMB2;
2492 io->smb2.in.file.handle = *dest_h;
2493 io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2494 io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2495 io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2497 ZERO_STRUCTPN(cc_copy);
2498 memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2499 cc_copy->chunk_count = nchunks;
2500 cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2501 torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2503 return true;
2507 static bool check_copy_chunk_rsp(struct torture_context *torture,
2508 struct srv_copychunk_rsp *cc_rsp,
2509 uint32_t ex_chunks_written,
2510 uint32_t ex_chunk_bytes_written,
2511 uint32_t ex_total_bytes_written)
2513 torture_assert_int_equal(torture, cc_rsp->chunks_written,
2514 ex_chunks_written, "num chunks");
2515 torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2516 ex_chunk_bytes_written, "chunk bytes written");
2517 torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2518 ex_total_bytes_written, "chunk total bytes");
2519 return true;
2522 static bool neg_aapl_copyfile(struct torture_context *tctx,
2523 struct smb2_tree *tree,
2524 uint64_t flags)
2526 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2527 const char *fname = "aapl";
2528 NTSTATUS status;
2529 struct smb2_create io;
2530 DATA_BLOB data;
2531 struct smb2_create_blob *aapl = NULL;
2532 uint32_t aapl_cmd;
2533 uint32_t aapl_reply_bitmap;
2534 uint32_t aapl_server_caps;
2535 bool ret = true;
2537 ZERO_STRUCT(io);
2538 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
2539 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2540 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2541 io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2542 NTCREATEX_SHARE_ACCESS_READ |
2543 NTCREATEX_SHARE_ACCESS_WRITE);
2544 io.in.fname = fname;
2546 data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2547 SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2548 SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2549 SBVAL(data.data, 16, flags);
2551 status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2552 CHECK_STATUS(status, NT_STATUS_OK);
2554 status = smb2_create(tree, tctx, &io);
2555 CHECK_STATUS(status, NT_STATUS_OK);
2557 aapl = smb2_create_blob_find(&io.out.blobs,
2558 SMB2_CREATE_TAG_AAPL);
2559 if (aapl == NULL) {
2560 ret = false;
2561 goto done;
2564 if (aapl->data.length < 24) {
2565 ret = false;
2566 goto done;
2569 aapl_cmd = IVAL(aapl->data.data, 0);
2570 if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2571 torture_result(tctx, TORTURE_FAIL,
2572 "(%s) unexpected cmd: %d",
2573 __location__, (int)aapl_cmd);
2574 ret = false;
2575 goto done;
2578 aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2579 if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2580 torture_result(tctx, TORTURE_FAIL,
2581 "(%s) unexpected reply_bitmap: %d",
2582 __location__, (int)aapl_reply_bitmap);
2583 ret = false;
2584 goto done;
2587 aapl_server_caps = BVAL(aapl->data.data, 16);
2588 if (!(aapl_server_caps & flags)) {
2589 torture_result(tctx, TORTURE_FAIL,
2590 "(%s) unexpected server_caps: %d",
2591 __location__, (int)aapl_server_caps);
2592 ret = false;
2593 goto done;
2596 done:
2597 status = smb2_util_close(tree, io.out.file.handle);
2598 CHECK_STATUS(status, NT_STATUS_OK);
2600 smb2_util_unlink(tree, "aapl");
2601 talloc_free(mem_ctx);
2602 return ret;
2605 static bool test_copyfile(struct torture_context *torture,
2606 struct smb2_tree *tree)
2608 struct smb2_handle src_h;
2609 struct smb2_handle dest_h;
2610 NTSTATUS status;
2611 union smb_ioctl io;
2612 TALLOC_CTX *tmp_ctx = talloc_new(tree);
2613 struct srv_copychunk_copy cc_copy;
2614 struct srv_copychunk_rsp cc_rsp;
2615 enum ndr_err_code ndr_ret;
2616 bool ok;
2617 const char *sname = ":foo" "\xef\x80\xa2" "bar:$DATA";
2620 * First test a copy_chunk with a 0 chunk count without having
2621 * enabled this via AAPL. The request must not fail and the
2622 * copied length in the response must be 0. This is verified
2623 * against Windows 2008r2.
2626 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2627 0, /* 0 chunks, copyfile semantics */
2628 FNAME_CC_SRC,
2629 &src_h, 4096, /* fill 4096 byte src file */
2630 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2631 FNAME_CC_DST,
2632 &dest_h, 0, /* 0 byte dest file */
2633 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2634 &cc_copy,
2635 &io);
2636 if (!ok) {
2637 torture_fail_goto(torture, done, "setup copy chunk error");
2640 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2641 &cc_copy,
2642 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2643 torture_assert_ndr_success(torture, ndr_ret,
2644 "ndr_push_srv_copychunk_copy");
2646 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2647 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2649 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2650 &cc_rsp,
2651 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2652 torture_assert_ndr_success(torture, ndr_ret,
2653 "ndr_pull_srv_copychunk_rsp");
2655 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2656 0, /* chunks written */
2657 0, /* chunk bytes unsuccessfully written */
2658 0); /* total bytes written */
2659 if (!ok) {
2660 torture_fail_goto(torture, done, "bad copy chunk response data");
2664 * Now enable AAPL copyfile and test again, the file and the
2665 * stream must be copied by the server.
2667 ok = neg_aapl_copyfile(torture, tree,
2668 SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2669 if (!ok) {
2670 torture_skip_goto(torture, done, "missing AAPL copyfile");
2671 goto done;
2674 smb2_util_close(tree, src_h);
2675 smb2_util_close(tree, dest_h);
2676 smb2_util_unlink(tree, FNAME_CC_SRC);
2677 smb2_util_unlink(tree, FNAME_CC_DST);
2679 ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2680 if (!ok) {
2681 torture_fail(torture, "setup file error");
2683 ok = write_stream(tree, __location__, torture, tmp_ctx,
2684 FNAME_CC_SRC, AFPRESOURCE_STREAM,
2685 10, 10, "1234567890");
2686 if (!ok) {
2687 torture_fail(torture, "setup stream error");
2690 ok = write_stream(tree, __location__, torture, tmp_ctx,
2691 FNAME_CC_SRC, sname,
2692 10, 10, "abcdefghij");
2693 torture_assert_goto(torture, ok == true, ok, done, "write_stream failed\n");
2695 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2696 0, /* 0 chunks, copyfile semantics */
2697 FNAME_CC_SRC,
2698 &src_h, 4096, /* fill 4096 byte src file */
2699 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2700 FNAME_CC_DST,
2701 &dest_h, 0, /* 0 byte dest file */
2702 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2703 &cc_copy,
2704 &io);
2705 if (!ok) {
2706 torture_fail_goto(torture, done, "setup copy chunk error");
2709 ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2710 &cc_copy,
2711 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2712 torture_assert_ndr_success(torture, ndr_ret,
2713 "ndr_push_srv_copychunk_copy");
2715 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2716 torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2718 ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2719 &cc_rsp,
2720 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2721 torture_assert_ndr_success(torture, ndr_ret,
2722 "ndr_pull_srv_copychunk_rsp");
2724 ok = check_copy_chunk_rsp(torture, &cc_rsp,
2725 0, /* chunks written */
2726 0, /* chunk bytes unsuccessfully written */
2727 4096); /* total bytes written */
2728 if (!ok) {
2729 torture_fail_goto(torture, done, "bad copy chunk response data");
2732 ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
2733 SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
2734 if (!ok) {
2735 torture_fail_goto(torture, done,"open failed");
2737 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
2738 if (!ok) {
2739 torture_fail_goto(torture, done, "inconsistent file data");
2742 ok = check_stream(tree, __location__, torture, tmp_ctx,
2743 FNAME_CC_DST, AFPRESOURCE_STREAM,
2744 0, 20, 10, 10, "1234567890");
2745 if (!ok) {
2746 torture_fail_goto(torture, done, "inconsistent stream data");
2749 ok = check_stream(tree, __location__, torture, tmp_ctx,
2750 FNAME_CC_DST, sname,
2751 0, 20, 10, 10, "abcdefghij");
2752 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
2754 done:
2755 smb2_util_close(tree, src_h);
2756 smb2_util_close(tree, dest_h);
2757 smb2_util_unlink(tree, FNAME_CC_SRC);
2758 smb2_util_unlink(tree, FNAME_CC_DST);
2759 talloc_free(tmp_ctx);
2760 return true;
2763 static bool check_stream_list(struct smb2_tree *tree,
2764 struct torture_context *tctx,
2765 const char *fname,
2766 int num_exp,
2767 const char **exp,
2768 bool is_dir)
2770 bool ret = true;
2771 union smb_fileinfo finfo;
2772 NTSTATUS status;
2773 int i;
2774 TALLOC_CTX *tmp_ctx = talloc_new(tctx);
2775 char **exp_sort;
2776 struct stream_struct *stream_sort;
2777 struct smb2_create create;
2778 struct smb2_handle h;
2780 ZERO_STRUCT(h);
2781 torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
2783 ZERO_STRUCT(create);
2784 create.in.fname = fname;
2785 create.in.create_disposition = NTCREATEX_DISP_OPEN;
2786 create.in.desired_access = SEC_FILE_ALL;
2787 create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
2788 create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
2789 status = smb2_create(tree, tmp_ctx, &create);
2790 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2791 h = create.out.file.handle;
2793 finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
2794 finfo.generic.in.file.handle = h;
2796 status = smb2_getinfo_file(tree, tctx, &finfo);
2797 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
2799 smb2_util_close(tree, h);
2801 torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
2802 ret, done, "stream count");
2804 if (num_exp == 0) {
2805 TALLOC_FREE(tmp_ctx);
2806 goto done;
2809 exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
2810 torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
2812 TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
2814 stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
2815 finfo.stream_info.out.num_streams *
2816 sizeof(*stream_sort));
2817 torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
2819 TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
2821 for (i=0; i<num_exp; i++) {
2822 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
2823 i, exp_sort[i], stream_sort[i].stream_name.s);
2824 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
2825 ret, done, "stream name");
2828 done:
2829 TALLOC_FREE(tmp_ctx);
2830 return ret;
2834 test stream names
2836 static bool test_stream_names(struct torture_context *tctx,
2837 struct smb2_tree *tree)
2839 TALLOC_CTX *mem_ctx = talloc_new(tctx);
2840 NTSTATUS status;
2841 struct smb2_create create;
2842 struct smb2_handle h;
2843 const char *fname = BASEDIR "\\stream_names.txt";
2844 const char *sname1;
2845 bool ret;
2846 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
2847 const char *streams[] = {
2848 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2849 "::$DATA"
2852 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
2854 /* clean slate ...*/
2855 smb2_util_unlink(tree, fname);
2856 smb2_deltree(tree, fname);
2857 smb2_deltree(tree, BASEDIR);
2859 status = torture_smb2_testdir(tree, BASEDIR, &h);
2860 CHECK_STATUS(status, NT_STATUS_OK);
2861 smb2_util_close(tree, h);
2863 torture_comment(tctx, "(%s) testing stream names\n", __location__);
2864 ZERO_STRUCT(create);
2865 create.in.desired_access = SEC_FILE_WRITE_DATA;
2866 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2867 create.in.share_access =
2868 NTCREATEX_SHARE_ACCESS_DELETE|
2869 NTCREATEX_SHARE_ACCESS_READ|
2870 NTCREATEX_SHARE_ACCESS_WRITE;
2871 create.in.create_disposition = NTCREATEX_DISP_CREATE;
2872 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2873 create.in.fname = sname1;
2875 status = smb2_create(tree, mem_ctx, &create);
2876 CHECK_STATUS(status, NT_STATUS_OK);
2877 smb2_util_close(tree, create.out.file.handle);
2879 ret = check_stream_list(tree, tctx, fname, 2, streams, false);
2880 CHECK_VALUE(ret, true);
2882 done:
2883 status = smb2_util_unlink(tree, fname);
2884 smb2_deltree(tree, BASEDIR);
2885 talloc_free(mem_ctx);
2887 return ret;
2890 /* Renaming a directory with open file, should work for OS X AAPL clients */
2891 static bool test_rename_dir_openfile(struct torture_context *torture,
2892 struct smb2_tree *tree)
2894 bool ret = true;
2895 NTSTATUS status;
2896 union smb_open io;
2897 union smb_close cl;
2898 union smb_setfileinfo sinfo;
2899 struct smb2_handle d1, h1;
2900 const char *renamedir = BASEDIR "-new";
2901 bool server_is_osx = torture_setting_bool(torture, "osx", false);
2903 smb2_deltree(tree, BASEDIR);
2904 smb2_util_rmdir(tree, BASEDIR);
2905 smb2_deltree(tree, renamedir);
2907 ZERO_STRUCT(io.smb2);
2908 io.generic.level = RAW_OPEN_SMB2;
2909 io.smb2.in.create_flags = 0;
2910 io.smb2.in.desired_access = 0x0017019f;
2911 io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2912 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2913 io.smb2.in.share_access = 0;
2914 io.smb2.in.alloc_size = 0;
2915 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2916 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2917 io.smb2.in.security_flags = 0;
2918 io.smb2.in.fname = BASEDIR;
2920 status = smb2_create(tree, torture, &(io.smb2));
2921 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2922 d1 = io.smb2.out.file.handle;
2924 ZERO_STRUCT(io.smb2);
2925 io.generic.level = RAW_OPEN_SMB2;
2926 io.smb2.in.create_flags = 0;
2927 io.smb2.in.desired_access = 0x0017019f;
2928 io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2929 io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2930 io.smb2.in.share_access = 0;
2931 io.smb2.in.alloc_size = 0;
2932 io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2933 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2934 io.smb2.in.security_flags = 0;
2935 io.smb2.in.fname = BASEDIR "\\file.txt";
2937 status = smb2_create(tree, torture, &(io.smb2));
2938 torture_assert_ntstatus_ok(torture, status, "smb2_create file");
2939 h1 = io.smb2.out.file.handle;
2941 if (!server_is_osx) {
2942 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
2944 ZERO_STRUCT(sinfo);
2945 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2946 sinfo.rename_information.in.file.handle = d1;
2947 sinfo.rename_information.in.overwrite = 0;
2948 sinfo.rename_information.in.root_fid = 0;
2949 sinfo.rename_information.in.new_name = renamedir;
2950 status = smb2_setinfo_file(tree, &sinfo);
2952 torture_assert_ntstatus_equal(torture, status,
2953 NT_STATUS_ACCESS_DENIED,
2954 "smb2_setinfo_file");
2956 ZERO_STRUCT(cl.smb2);
2957 cl.smb2.level = RAW_CLOSE_SMB2;
2958 cl.smb2.in.file.handle = d1;
2959 status = smb2_close(tree, &(cl.smb2));
2960 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2961 ZERO_STRUCT(d1);
2964 torture_comment(torture, "Enabling AAPL\n");
2966 ret = enable_aapl(torture, tree);
2967 torture_assert(torture, ret == true, "enable_aapl failed");
2969 torture_comment(torture, "Renaming directory with AAPL\n");
2971 ZERO_STRUCT(io.smb2);
2972 io.generic.level = RAW_OPEN_SMB2;
2973 io.smb2.in.desired_access = 0x0017019f;
2974 io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2975 io.smb2.in.share_access = 0;
2976 io.smb2.in.alloc_size = 0;
2977 io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
2978 io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2979 io.smb2.in.security_flags = 0;
2980 io.smb2.in.fname = BASEDIR;
2982 status = smb2_create(tree, torture, &(io.smb2));
2983 torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2984 d1 = io.smb2.out.file.handle;
2986 ZERO_STRUCT(sinfo);
2987 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2988 sinfo.rename_information.in.file.handle = d1;
2989 sinfo.rename_information.in.overwrite = 0;
2990 sinfo.rename_information.in.root_fid = 0;
2991 sinfo.rename_information.in.new_name = renamedir;
2993 status = smb2_setinfo_file(tree, &sinfo);
2994 torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
2996 ZERO_STRUCT(cl.smb2);
2997 cl.smb2.level = RAW_CLOSE_SMB2;
2998 cl.smb2.in.file.handle = d1;
2999 status = smb2_close(tree, &(cl.smb2));
3000 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3001 ZERO_STRUCT(d1);
3003 cl.smb2.in.file.handle = h1;
3004 status = smb2_close(tree, &(cl.smb2));
3005 torture_assert_ntstatus_ok(torture, status, "smb2_close");
3006 ZERO_STRUCT(h1);
3008 torture_comment(torture, "Cleaning up\n");
3010 if (h1.data[0] || h1.data[1]) {
3011 ZERO_STRUCT(cl.smb2);
3012 cl.smb2.level = RAW_CLOSE_SMB2;
3013 cl.smb2.in.file.handle = h1;
3014 status = smb2_close(tree, &(cl.smb2));
3017 smb2_util_unlink(tree, BASEDIR "\\file.txt");
3018 smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
3019 smb2_deltree(tree, renamedir);
3020 smb2_deltree(tree, BASEDIR);
3021 return ret;
3024 static bool test_afpinfo_enoent(struct torture_context *tctx,
3025 struct smb2_tree *tree)
3027 bool ret = true;
3028 NTSTATUS status;
3029 struct smb2_create create;
3030 struct smb2_handle h1;
3031 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3032 const char *fname = BASEDIR "\\file";
3033 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3035 torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
3037 smb2_deltree(tree, BASEDIR);
3038 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3039 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3040 smb2_util_close(tree, h1);
3041 ret = torture_setup_file(mem_ctx, tree, fname, false);
3042 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3044 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3046 ZERO_STRUCT(create);
3047 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3048 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3049 create.in.fname = sname;
3051 status = smb2_create(tree, mem_ctx, &create);
3052 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3053 ret, done, "Got unexpected AFP_AfpInfo stream");
3055 done:
3056 smb2_util_unlink(tree, fname);
3057 smb2_util_rmdir(tree, BASEDIR);
3058 return ret;
3061 static bool test_create_delete_on_close(struct torture_context *tctx,
3062 struct smb2_tree *tree)
3064 bool ret = true;
3065 NTSTATUS status;
3066 struct smb2_create create;
3067 struct smb2_handle h1;
3068 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3069 const char *fname = BASEDIR "\\file";
3070 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3071 const char *type_creator = "SMB,OLE!";
3072 AfpInfo *info = NULL;
3073 const char *streams_basic[] = {
3074 "::$DATA"
3076 const char *streams_afpinfo[] = {
3077 "::$DATA",
3078 AFPINFO_STREAM
3081 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3083 torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
3085 smb2_deltree(tree, BASEDIR);
3086 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3087 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3088 smb2_util_close(tree, h1);
3089 ret = torture_setup_file(mem_ctx, tree, fname, false);
3090 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3092 torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
3094 ZERO_STRUCT(create);
3095 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3096 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3097 create.in.fname = sname;
3099 status = smb2_create(tree, mem_ctx, &create);
3100 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3101 ret, done, "Got unexpected AFP_AfpInfo stream");
3103 ZERO_STRUCT(create);
3104 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3105 create.in.desired_access = SEC_FILE_ALL;
3106 create.in.fname = sname;
3108 status = smb2_create(tree, mem_ctx, &create);
3109 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3110 ret, done, "Got unexpected AFP_AfpInfo stream");
3112 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3113 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3115 torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
3117 info = torture_afpinfo_new(mem_ctx);
3118 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3120 memcpy(info->afpi_FinderInfo, type_creator, 8);
3121 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3122 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3124 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3125 0, 60, 16, 8, type_creator);
3126 torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
3128 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3129 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3131 ZERO_STRUCT(create);
3132 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3133 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3134 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3135 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3136 create.in.fname = sname;
3137 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3139 status = smb2_create(tree, mem_ctx, &create);
3140 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3142 h1 = create.out.file.handle;
3143 smb2_util_close(tree, h1);
3145 ZERO_STRUCT(create);
3146 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3147 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
3148 create.in.fname = sname;
3149 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3150 status = smb2_create(tree, mem_ctx, &create);
3151 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3152 ret, done, "Got unexpected AFP_AfpInfo stream");
3154 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3155 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3157 done:
3158 smb2_util_unlink(tree, fname);
3159 smb2_util_rmdir(tree, BASEDIR);
3160 return ret;
3163 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
3164 struct smb2_tree *tree)
3166 bool ret = true;
3167 NTSTATUS status;
3168 struct smb2_create create;
3169 union smb_setfileinfo sfinfo;
3170 struct smb2_handle h1;
3171 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3172 const char *fname = BASEDIR "\\file";
3173 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3174 const char *type_creator = "SMB,OLE!";
3175 AfpInfo *info = NULL;
3176 const char *streams_basic[] = {
3177 "::$DATA"
3180 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3182 torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
3184 smb2_deltree(tree, BASEDIR);
3185 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3186 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3187 smb2_util_close(tree, h1);
3188 ret = torture_setup_file(mem_ctx, tree, fname, false);
3189 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3191 info = torture_afpinfo_new(mem_ctx);
3192 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3193 memcpy(info->afpi_FinderInfo, type_creator, 8);
3194 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3195 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3197 ZERO_STRUCT(create);
3198 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3199 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3200 create.in.fname = sname;
3201 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3202 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3204 status = smb2_create(tree, mem_ctx, &create);
3205 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3207 h1 = create.out.file.handle;
3209 /* Delete stream via setinfo delete-on-close */
3210 ZERO_STRUCT(sfinfo);
3211 sfinfo.disposition_info.in.delete_on_close = 1;
3212 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3213 sfinfo.generic.in.file.handle = h1;
3214 status = smb2_setinfo_file(tree, &sfinfo);
3215 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3217 smb2_util_close(tree, h1);
3219 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3220 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3222 ZERO_STRUCT(create);
3223 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3224 create.in.desired_access = SEC_FILE_ALL;
3225 create.in.fname = sname;
3226 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3227 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3228 status = smb2_create(tree, mem_ctx, &create);
3229 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3230 ret, done, "Got unexpected AFP_AfpInfo stream");
3232 done:
3233 smb2_util_unlink(tree, fname);
3234 smb2_util_rmdir(tree, BASEDIR);
3235 return ret;
3238 static bool test_setinfo_eof(struct torture_context *tctx,
3239 struct smb2_tree *tree)
3241 bool ret = true;
3242 NTSTATUS status;
3243 struct smb2_create create;
3244 union smb_setfileinfo sfinfo;
3245 struct smb2_handle h1;
3246 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3247 const char *fname = BASEDIR "\\file";
3248 const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3249 const char *type_creator = "SMB,OLE!";
3250 AfpInfo *info = NULL;
3251 const char *streams_afpinfo[] = {
3252 "::$DATA",
3253 AFPINFO_STREAM
3256 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3258 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
3260 smb2_deltree(tree, BASEDIR);
3261 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3262 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3263 smb2_util_close(tree, h1);
3264 ret = torture_setup_file(mem_ctx, tree, fname, false);
3265 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3267 info = torture_afpinfo_new(mem_ctx);
3268 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3269 memcpy(info->afpi_FinderInfo, type_creator, 8);
3270 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3271 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3273 ZERO_STRUCT(create);
3274 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3275 create.in.desired_access = SEC_FILE_ALL;
3276 create.in.fname = sname;
3277 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3278 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3280 status = smb2_create(tree, mem_ctx, &create);
3281 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3283 h1 = create.out.file.handle;
3285 torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
3287 /* Test setinfo end-of-file info */
3288 ZERO_STRUCT(sfinfo);
3289 sfinfo.generic.in.file.handle = h1;
3290 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3291 sfinfo.position_information.in.position = 61;
3292 status = smb2_setinfo_file(tree, &sfinfo);
3293 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
3294 ret, done, "set eof 61 failed");
3296 torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
3298 /* Truncation returns success, but has no effect */
3299 ZERO_STRUCT(sfinfo);
3300 sfinfo.generic.in.file.handle = h1;
3301 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3302 sfinfo.position_information.in.position = 1;
3303 status = smb2_setinfo_file(tree, &sfinfo);
3304 torture_assert_ntstatus_ok_goto(tctx, status,
3305 ret, done, "set eof 1 failed");
3306 smb2_util_close(tree, h1);
3308 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3309 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3311 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3312 0, 60, 16, 8, type_creator);
3313 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3315 ZERO_STRUCT(create);
3316 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3317 create.in.desired_access = SEC_FILE_ALL;
3318 create.in.fname = sname;
3319 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3320 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3322 status = smb2_create(tree, mem_ctx, &create);
3323 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3325 h1 = create.out.file.handle;
3328 * Delete stream via setinfo end-of-file info to 0, should
3329 * return success but stream MUST NOT deleted
3331 ZERO_STRUCT(sfinfo);
3332 sfinfo.generic.in.file.handle = h1;
3333 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3334 sfinfo.position_information.in.position = 0;
3335 status = smb2_setinfo_file(tree, &sfinfo);
3336 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3338 smb2_util_close(tree, h1);
3340 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3341 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3343 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3344 0, 60, 16, 8, type_creator);
3345 torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3347 done:
3348 smb2_util_unlink(tree, fname);
3349 smb2_util_rmdir(tree, BASEDIR);
3350 return ret;
3353 static bool test_afpinfo_all0(struct torture_context *tctx,
3354 struct smb2_tree *tree)
3356 bool ret = true;
3357 NTSTATUS status;
3358 struct smb2_create create;
3359 struct smb2_handle h1 = {{0}};
3360 struct smb2_handle baseh = {{0}};
3361 union smb_setfileinfo setfinfo;
3362 union smb_fileinfo getfinfo;
3363 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3364 const char *fname = BASEDIR "\\file";
3365 const char *sname = BASEDIR "\\file" AFPINFO_STREAM;
3366 const char *type_creator = "SMB,OLE!";
3367 AfpInfo *info = NULL;
3368 char *infobuf = NULL;
3369 const char *streams_basic[] = {
3370 "::$DATA"
3372 const char *streams_afpinfo[] = {
3373 "::$DATA",
3374 AFPINFO_STREAM
3377 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3379 torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
3381 smb2_deltree(tree, BASEDIR);
3382 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3383 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3384 smb2_util_close(tree, h1);
3385 ret = torture_setup_file(mem_ctx, tree, fname, false);
3386 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3388 info = torture_afpinfo_new(mem_ctx);
3389 torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3390 memcpy(info->afpi_FinderInfo, type_creator, 8);
3391 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3392 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3394 ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3395 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3397 /* Write all 0 to AFP_AfpInfo */
3398 memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
3399 infobuf = torture_afpinfo_pack(mem_ctx, info);
3400 torture_assert_not_null_goto(tctx, infobuf, ret, done,
3401 "torture_afpinfo_pack failed\n");
3403 ZERO_STRUCT(create);
3404 create.in.desired_access = SEC_FILE_ALL;
3405 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3406 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3407 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3408 create.in.fname = fname;
3410 status = smb2_create(tree, mem_ctx, &create);
3411 torture_assert_goto(tctx, ret == true, ret, done,
3412 "smb2_create failed\n");
3413 baseh = create.out.file.handle;
3415 ZERO_STRUCT(create);
3416 create.in.desired_access = SEC_FILE_ALL;
3417 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3418 create.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
3419 create.in.fname = sname;
3421 status = smb2_create(tree, mem_ctx, &create);
3422 torture_assert_goto(tctx, ret == true, ret, done,
3423 "smb2_create failed\n");
3424 h1 = create.out.file.handle;
3426 status = smb2_util_write(tree, h1, infobuf, 0, AFP_INFO_SIZE);
3427 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3428 "smb2_util_write failed\n");
3431 * Get stream information on open handle, must return only default
3432 * stream, the AFP_AfpInfo stream must not be returned.
3435 ZERO_STRUCT(getfinfo);
3436 getfinfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
3437 getfinfo.generic.in.file.handle = baseh;
3439 status = smb2_getinfo_file(tree, tctx, &getfinfo);
3440 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3441 "get stream info\n");
3443 torture_assert_int_equal_goto(tctx, getfinfo.stream_info.out.num_streams,
3444 1, ret, done, "stream count");
3446 smb2_util_close(tree, baseh);
3447 ZERO_STRUCT(baseh);
3450 * Try to set some file-basic-info (time) on the stream. This catches
3451 * naive implementation mistakes that simply deleted the backing store
3452 * from the filesystem in the zero-out step.
3455 ZERO_STRUCT(setfinfo);
3456 unix_to_nt_time(&setfinfo.basic_info.in.write_time, time(NULL));
3457 setfinfo.basic_info.in.attrib = 0x20;
3458 setfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
3459 setfinfo.generic.in.file.handle = h1;
3461 status = smb2_setinfo_file(tree, &setfinfo);
3462 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3463 "smb2_getinfo_file failed\n");
3465 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3466 torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
3468 smb2_util_close(tree, h1);
3469 ZERO_STRUCT(h1);
3471 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3472 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3474 done:
3475 if (!smb2_util_handle_empty(h1)) {
3476 smb2_util_close(tree, h1);
3478 if (!smb2_util_handle_empty(baseh)) {
3479 smb2_util_close(tree, baseh);
3481 smb2_util_unlink(tree, fname);
3482 smb2_util_rmdir(tree, BASEDIR);
3483 return ret;
3486 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
3487 struct smb2_tree *tree)
3489 bool ret = true;
3490 NTSTATUS status;
3491 struct smb2_create create;
3492 struct smb2_handle h1;
3493 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3494 const char *fname = BASEDIR "\\file";
3495 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3496 const char *streams_basic[] = {
3497 "::$DATA"
3499 const char *streams_afpresource[] = {
3500 "::$DATA",
3501 AFPRESOURCE_STREAM
3504 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3506 torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
3508 smb2_deltree(tree, BASEDIR);
3509 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3510 torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
3511 smb2_util_close(tree, h1);
3512 ret = torture_setup_file(mem_ctx, tree, fname, false);
3513 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3515 torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
3517 ZERO_STRUCT(create);
3518 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3519 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3520 create.in.fname = sname;
3522 status = smb2_create(tree, mem_ctx, &create);
3523 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3524 ret, done, "Got unexpected AFP_AfpResource stream");
3526 ZERO_STRUCT(create);
3527 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3528 create.in.desired_access = SEC_FILE_ALL;
3529 create.in.fname = sname;
3531 status = smb2_create(tree, mem_ctx, &create);
3532 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3533 ret, done, "Got unexpected AFP_AfpResource stream");
3535 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3536 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3538 torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
3540 ret = write_stream(tree, __location__, tctx, mem_ctx,
3541 fname, AFPRESOURCE_STREAM_NAME,
3542 0, 10, "1234567890");
3543 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3545 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3546 0, 10, 0, 10, "1234567890");
3547 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3549 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3550 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3552 ZERO_STRUCT(create);
3553 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3554 create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3555 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3556 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3557 create.in.fname = sname;
3558 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3560 status = smb2_create(tree, mem_ctx, &create);
3561 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3563 h1 = create.out.file.handle;
3564 smb2_util_close(tree, h1);
3566 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3567 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3569 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3570 0, 10, 0, 10, "1234567890");
3571 torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3573 done:
3574 smb2_util_unlink(tree, fname);
3575 smb2_util_rmdir(tree, BASEDIR);
3576 return ret;
3579 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
3580 struct smb2_tree *tree)
3582 bool ret = true;
3583 NTSTATUS status;
3584 struct smb2_create create;
3585 union smb_setfileinfo sfinfo;
3586 struct smb2_handle h1;
3587 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3588 const char *fname = BASEDIR "\\file";
3589 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3590 const char *streams_afpresource[] = {
3591 "::$DATA",
3592 AFPRESOURCE_STREAM
3595 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3597 torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
3599 smb2_deltree(tree, BASEDIR);
3600 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3601 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3602 smb2_util_close(tree, h1);
3603 ret = torture_setup_file(mem_ctx, tree, fname, false);
3604 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3606 ret = write_stream(tree, __location__, tctx, mem_ctx,
3607 fname, AFPRESOURCE_STREAM_NAME,
3608 10, 10, "1234567890");
3609 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3611 ZERO_STRUCT(create);
3612 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3613 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3614 create.in.fname = sname;
3615 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3616 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3618 status = smb2_create(tree, mem_ctx, &create);
3619 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3621 h1 = create.out.file.handle;
3623 /* Try to delete stream via setinfo delete-on-close */
3624 ZERO_STRUCT(sfinfo);
3625 sfinfo.disposition_info.in.delete_on_close = 1;
3626 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3627 sfinfo.generic.in.file.handle = h1;
3628 status = smb2_setinfo_file(tree, &sfinfo);
3629 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3631 smb2_util_close(tree, h1);
3633 ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3634 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3636 ZERO_STRUCT(create);
3637 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3638 create.in.desired_access = SEC_FILE_ALL;
3639 create.in.fname = sname;
3640 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3641 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3642 status = smb2_create(tree, mem_ctx, &create);
3643 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3644 "Got unexpected AFP_AfpResource stream");
3646 done:
3647 smb2_util_unlink(tree, fname);
3648 smb2_util_rmdir(tree, BASEDIR);
3649 return ret;
3652 static bool test_setinfo_eof_resource(struct torture_context *tctx,
3653 struct smb2_tree *tree)
3655 bool ret = true;
3656 NTSTATUS status;
3657 struct smb2_create create;
3658 union smb_setfileinfo sfinfo;
3659 union smb_fileinfo finfo;
3660 struct smb2_handle h1;
3661 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3662 const char *fname = BASEDIR "\\file";
3663 const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3664 const char *streams_basic[] = {
3665 "::$DATA"
3668 torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3670 torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
3672 smb2_deltree(tree, BASEDIR);
3673 status = torture_smb2_testdir(tree, BASEDIR, &h1);
3674 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3675 smb2_util_close(tree, h1);
3676 ret = torture_setup_file(mem_ctx, tree, fname, false);
3677 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3679 ret = write_stream(tree, __location__, tctx, mem_ctx,
3680 fname, AFPRESOURCE_STREAM_NAME,
3681 10, 10, "1234567890");
3682 torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3684 ZERO_STRUCT(create);
3685 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3686 create.in.desired_access = SEC_FILE_ALL;
3687 create.in.fname = sname;
3688 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3689 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3691 status = smb2_create(tree, mem_ctx, &create);
3692 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3694 h1 = create.out.file.handle;
3696 torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
3698 /* Test setinfo end-of-file info */
3699 ZERO_STRUCT(sfinfo);
3700 sfinfo.generic.in.file.handle = h1;
3701 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3702 sfinfo.position_information.in.position = 1;
3703 status = smb2_setinfo_file(tree, &sfinfo);
3704 torture_assert_ntstatus_ok_goto(tctx, status,
3705 ret, done, "set eof 1 failed");
3707 smb2_util_close(tree, h1);
3709 /* Check size == 1 */
3710 ZERO_STRUCT(create);
3711 create.in.fname = sname;
3712 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3713 create.in.desired_access = SEC_FILE_ALL;
3714 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3715 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3716 status = smb2_create(tree, mem_ctx, &create);
3717 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3719 h1 = create.out.file.handle;
3721 ZERO_STRUCT(finfo);
3722 finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
3723 finfo.generic.in.file.handle = h1;
3724 status = smb2_getinfo_file(tree, mem_ctx, &finfo);
3725 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
3727 smb2_util_close(tree, h1);
3729 torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
3731 ZERO_STRUCT(create);
3732 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3733 create.in.desired_access = SEC_FILE_ALL;
3734 create.in.fname = sname;
3735 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3736 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3738 status = smb2_create(tree, mem_ctx, &create);
3739 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3741 h1 = create.out.file.handle;
3744 * Delete stream via setinfo end-of-file info to 0, this
3745 * should delete the stream.
3747 ZERO_STRUCT(sfinfo);
3748 sfinfo.generic.in.file.handle = h1;
3749 sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3750 sfinfo.position_information.in.position = 0;
3751 status = smb2_setinfo_file(tree, &sfinfo);
3752 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3754 smb2_util_close(tree, h1);
3756 ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3757 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3759 ZERO_STRUCT(create);
3760 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3761 create.in.desired_access = SEC_FILE_ALL;
3762 create.in.fname = sname;
3763 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3764 create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3766 status = smb2_create(tree, mem_ctx, &create);
3767 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3768 ret, done, "smb2_create failed");
3770 done:
3771 smb2_util_unlink(tree, fname);
3772 smb2_util_rmdir(tree, BASEDIR);
3773 return ret;
3777 * This tests that right after creating the AFP_AfpInfo stream,
3778 * reading from the stream returns an empty, default metadata blob of
3779 * 60 bytes.
3781 * NOTE: against OS X SMB server this only works if the read request
3782 * is compounded with the create that created the stream, is fails
3783 * otherwise. We don't care...
3785 static bool test_null_afpinfo(struct torture_context *tctx,
3786 struct smb2_tree *tree)
3788 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3789 const char *fname = "test_null_afpinfo";
3790 const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
3791 NTSTATUS status;
3792 bool ret = true;
3793 struct smb2_request *req[3];
3794 struct smb2_handle handle;
3795 struct smb2_create create;
3796 struct smb2_read read;
3797 AfpInfo *afpinfo = NULL;
3798 char *afpinfo_buf = NULL;
3799 const char *type_creator = "SMB,OLE!";
3801 torture_comment(tctx, "Checking create of AfpInfo stream\n");
3803 smb2_util_unlink(tree, fname);
3805 ret = torture_setup_file(mem_ctx, tree, fname, false);
3806 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
3808 ZERO_STRUCT(create);
3809 create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
3810 create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
3811 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3812 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3813 create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
3814 create.in.fname = sname;
3816 smb2_transport_compound_start(tree->session->transport, 2);
3818 req[0] = smb2_create_send(tree, &create);
3820 handle.data[0] = UINT64_MAX;
3821 handle.data[1] = UINT64_MAX;
3823 smb2_transport_compound_set_related(tree->session->transport, true);
3825 ZERO_STRUCT(read);
3826 read.in.file.handle = handle;
3827 read.in.length = AFP_INFO_SIZE;
3828 req[1] = smb2_read_send(tree, &read);
3830 status = smb2_create_recv(req[0], tree, &create);
3831 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
3833 handle = create.out.file.handle;
3835 status = smb2_read_recv(req[1], tree, &read);
3836 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
3838 afpinfo = torture_afpinfo_new(mem_ctx);
3839 torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
3841 memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
3843 afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
3844 torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
3846 status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
3847 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
3849 smb2_util_close(tree, handle);
3851 ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3852 0, 60, 16, 8, type_creator);
3853 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
3855 done:
3856 smb2_util_unlink(tree, fname);
3857 talloc_free(mem_ctx);
3858 return ret;
3861 static bool test_delete_file_with_rfork(struct torture_context *tctx,
3862 struct smb2_tree *tree)
3864 const char *fname = "torture_write_rfork_io";
3865 const char *rfork_content = "1234567890";
3866 NTSTATUS status;
3867 bool ret = true;
3869 smb2_util_unlink(tree, fname);
3871 torture_comment(tctx, "Test deleting file with resource fork\n");
3873 ret = torture_setup_file(tctx, tree, fname, false);
3874 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
3876 ret = write_stream(tree, __location__, tctx, tctx,
3877 fname, AFPRESOURCE_STREAM_NAME,
3878 10, 10, rfork_content);
3879 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
3881 ret = check_stream(tree, __location__, tctx, tctx,
3882 fname, AFPRESOURCE_STREAM_NAME,
3883 0, 20, 10, 10, rfork_content);
3884 torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
3886 status = smb2_util_unlink(tree, fname);
3887 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
3889 done:
3890 return ret;
3893 static bool test_rename_and_read_rsrc(struct torture_context *tctx,
3894 struct smb2_tree *tree)
3896 bool ret = true;
3897 NTSTATUS status;
3898 struct smb2_create create, create2;
3899 struct smb2_handle h1, h2;
3900 const char *fname = "test_rename_openfile";
3901 const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
3902 const char *fname_renamed = "test_rename_openfile_renamed";
3903 const char *data = "1234567890";
3904 union smb_setfileinfo sinfo;
3905 struct smb2_read r;
3907 ret = enable_aapl(tctx, tree);
3908 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
3910 torture_comment(tctx, "Create file with resource fork\n");
3912 ret = torture_setup_file(tctx, tree, fname, false);
3913 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3915 ret = write_stream(tree, __location__, tctx, tctx,
3916 fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
3917 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
3919 torture_comment(tctx, "Open resource fork\n");
3921 ZERO_STRUCT(create);
3922 create.in.desired_access = SEC_FILE_ALL;
3923 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3924 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3925 create.in.create_disposition = NTCREATEX_DISP_OPEN;
3926 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3927 create.in.fname = sname;
3929 status = smb2_create(tree, tctx, &create);
3930 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3932 h1 = create.out.file.handle;
3934 torture_comment(tctx, "Rename base file\n");
3936 ZERO_STRUCT(create2);
3937 create2.in.desired_access = SEC_FILE_ALL;
3938 create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3939 create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
3940 create2.in.create_disposition = NTCREATEX_DISP_OPEN;
3941 create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
3942 create2.in.fname = fname;
3944 status = smb2_create(tree, tctx, &create2);
3945 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3947 h2 = create2.out.file.handle;
3949 ZERO_STRUCT(sinfo);
3950 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
3951 sinfo.rename_information.in.file.handle = h2;
3952 sinfo.rename_information.in.overwrite = 0;
3953 sinfo.rename_information.in.root_fid = 0;
3954 sinfo.rename_information.in.new_name = fname_renamed;
3956 status = smb2_setinfo_file(tree, &sinfo);
3957 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file failed");
3959 smb2_util_close(tree, h2);
3961 ZERO_STRUCT(r);
3962 r.in.file.handle = h1;
3963 r.in.length = 10;
3964 r.in.offset = 0;
3966 torture_comment(tctx, "Read resource fork of renamed file\n");
3968 status = smb2_read(tree, tree, &r);
3969 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read failed");
3971 smb2_util_close(tree, h1);
3973 torture_assert_goto(tctx, r.out.data.length == 10, ret, done,
3974 talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected 10\n",
3975 (intmax_t)r.out.data.length));
3977 torture_assert_goto(tctx, memcmp(r.out.data.data, data, 10) == 0, ret, done,
3978 talloc_asprintf(tctx, "Bad data in stream\n"));
3980 done:
3981 smb2_util_unlink(tree, fname);
3982 smb2_util_unlink(tree, fname_renamed);
3984 return ret;
3987 static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
3988 struct smb2_tree *tree)
3990 TALLOC_CTX *mem_ctx = talloc_new(tctx);
3991 const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
3992 const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
3993 NTSTATUS status;
3994 struct smb2_handle testdirh;
3995 bool ret = true;
3996 struct smb2_create io;
3997 AfpInfo *info;
3998 const char *type_creator = "SMB,OLE!";
3999 struct smb2_find f;
4000 unsigned int count;
4001 union smb_search_data *d;
4002 uint64_t rfork_len;
4003 int i;
4005 smb2_deltree(tree, BASEDIR);
4007 status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
4008 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
4009 smb2_util_close(tree, testdirh);
4011 torture_comment(tctx, "Enabling AAPL\n");
4013 ret = enable_aapl(tctx, tree);
4014 torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
4017 * Now that Requested AAPL extensions are enabled, setup some
4018 * Mac files with metadata and resource fork
4021 torture_comment(tctx, "Preparing file\n");
4023 ret = torture_setup_file(mem_ctx, tree, fname, false);
4024 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
4026 info = torture_afpinfo_new(mem_ctx);
4027 torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
4029 memcpy(info->afpi_FinderInfo, type_creator, 8);
4030 ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
4031 torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
4033 ret = write_stream(tree, __location__, tctx, mem_ctx,
4034 fname, AFPRESOURCE_STREAM_NAME,
4035 0, 3, "foo");
4036 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4039 * Ok, file is prepared, now call smb2/find
4042 torture_comment(tctx, "Issue find\n");
4044 ZERO_STRUCT(io);
4045 io.in.desired_access = SEC_RIGHTS_DIR_READ;
4046 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
4047 io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
4048 io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
4049 NTCREATEX_SHARE_ACCESS_WRITE |
4050 NTCREATEX_SHARE_ACCESS_DELETE);
4051 io.in.create_disposition = NTCREATEX_DISP_OPEN;
4052 io.in.fname = BASEDIR;
4053 status = smb2_create(tree, tctx, &io);
4054 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
4056 ZERO_STRUCT(f);
4057 f.in.file.handle = io.out.file.handle;
4058 f.in.pattern = "*";
4059 f.in.max_response_size = 0x1000;
4060 f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
4062 status = smb2_find_level(tree, tree, &f, &count, &d);
4063 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
4065 status = smb2_util_close(tree, io.out.file.handle);
4066 torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
4068 torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
4070 for (i = 0; i < count; i++) {
4071 const char *found = d[i].id_both_directory_info.name.s;
4073 if (!strcmp(found, ".") || !strcmp(found, ".."))
4074 continue;
4075 if (strncmp(found, "._", 2) == 0) {
4076 continue;
4078 break;
4081 torture_assert_str_equal_goto(tctx,
4082 d[i].id_both_directory_info.name.s, name,
4083 ret, done, "bad name");
4085 rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
4086 torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
4088 torture_assert_mem_equal_goto(tctx, type_creator,
4089 d[i].id_both_directory_info.short_name_buf + 8,
4090 8, ret, done, "Bad FinderInfo");
4091 done:
4092 smb2_util_unlink(tree, fname);
4093 smb2_deltree(tree, BASEDIR);
4094 talloc_free(mem_ctx);
4095 return ret;
4098 static bool test_invalid_afpinfo(struct torture_context *tctx,
4099 struct smb2_tree *tree1,
4100 struct smb2_tree *tree2)
4102 const char *fname = "filtest_invalid_afpinfo";
4103 const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
4104 struct smb2_create create;
4105 const char *streams_basic[] = {
4106 "::$DATA"
4108 const char *streams_afpinfo[] = {
4109 "::$DATA",
4110 AFPINFO_STREAM
4112 NTSTATUS status;
4113 bool ret = true;
4115 if (tree2 == NULL) {
4116 torture_skip_goto(tctx, done, "need second share without fruit\n");
4119 torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
4121 ret = torture_setup_file(tctx, tree2, fname, false);
4122 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4124 ret = write_stream(tree2, __location__, tctx, tctx,
4125 fname, AFPINFO_STREAM_NAME,
4126 0, 3, "foo");
4127 torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
4129 ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
4130 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4132 torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
4134 ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
4135 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
4137 torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
4139 ZERO_STRUCT(create);
4140 create.in.desired_access = SEC_FILE_ALL;
4141 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4142 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4143 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4144 create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
4145 create.in.fname = sname;
4147 status = smb2_create(tree1, tctx, &create);
4148 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4149 ret, done, "Stream still around?");
4151 done:
4152 smb2_util_unlink(tree1, fname);
4153 return ret;
4156 static bool test_zero_file_id(struct torture_context *tctx,
4157 struct smb2_tree *tree)
4159 const char *fname = "filtest_file_id";
4160 struct smb2_create create = {0};
4161 NTSTATUS status;
4162 bool ret = true;
4163 uint8_t zero_file_id[8] = {0};
4165 torture_comment(tctx, "Testing zero file id\n");
4167 ret = torture_setup_file(tctx, tree, fname, false);
4168 torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
4170 ZERO_STRUCT(create);
4171 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4172 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4173 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4174 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4175 create.in.fname = fname;
4176 create.in.query_on_disk_id = true;
4178 status = smb2_create(tree, tctx, &create);
4179 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
4180 done,
4181 "test file could not be opened");
4182 torture_assert_mem_not_equal_goto(tctx, create.out.on_disk_id,
4183 zero_file_id, 8, ret, done,
4184 "unexpected zero file id");
4186 smb2_util_close(tree, create.out.file.handle);
4188 ret = enable_aapl(tctx, tree);
4189 torture_assert(tctx, ret == true, "enable_aapl failed");
4191 ZERO_STRUCT(create);
4192 create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
4193 create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
4194 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4195 create.in.create_disposition = NTCREATEX_DISP_OPEN;
4196 create.in.fname = fname;
4197 create.in.query_on_disk_id = true;
4199 status = smb2_create(tree, tctx, &create);
4200 torture_assert_ntstatus_equal_goto(
4201 tctx, status, NT_STATUS_OK, ret, done,
4202 "test file could not be opened with AAPL");
4203 torture_assert_mem_equal_goto(tctx, create.out.on_disk_id, zero_file_id,
4204 8, ret, done, "non-zero file id");
4206 smb2_util_close(tree, create.out.file.handle);
4208 done:
4209 smb2_util_unlink(tree, fname);
4210 return ret;
4213 static bool copy_one_stream(struct torture_context *torture,
4214 struct smb2_tree *tree,
4215 TALLOC_CTX *tmp_ctx,
4216 const char *src_sname,
4217 const char *dst_sname)
4219 struct smb2_handle src_h = {{0}};
4220 struct smb2_handle dest_h = {{0}};
4221 NTSTATUS status;
4222 union smb_ioctl io;
4223 struct srv_copychunk_copy cc_copy;
4224 struct srv_copychunk_rsp cc_rsp;
4225 enum ndr_err_code ndr_ret;
4226 bool ok = false;
4228 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4229 1, /* 1 chunk */
4230 src_sname,
4231 &src_h, 256, /* fill 256 byte src file */
4232 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4233 dst_sname,
4234 &dest_h, 0, /* 0 byte dest file */
4235 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4236 &cc_copy,
4237 &io);
4238 torture_assert_goto(torture, ok == true, ok, done,
4239 "setup copy chunk error\n");
4241 /* copy all src file data (via a single chunk desc) */
4242 cc_copy.chunks[0].source_off = 0;
4243 cc_copy.chunks[0].target_off = 0;
4244 cc_copy.chunks[0].length = 256;
4246 ndr_ret = ndr_push_struct_blob(
4247 &io.smb2.in.out, tmp_ctx, &cc_copy,
4248 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4250 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4251 "ndr_push_srv_copychunk_copy\n");
4253 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4254 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4255 "FSCTL_SRV_COPYCHUNK\n");
4257 ndr_ret = ndr_pull_struct_blob(
4258 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4259 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4261 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4262 "ndr_pull_srv_copychunk_rsp\n");
4264 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4265 1, /* chunks written */
4266 0, /* chunk bytes unsuccessfully written */
4267 256); /* total bytes written */
4268 torture_assert_goto(torture, ok == true, ok, done,
4269 "bad copy chunk response data\n");
4271 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
4272 if (!ok) {
4273 torture_fail(torture, "inconsistent file data\n");
4276 done:
4277 if (!smb2_util_handle_empty(src_h)) {
4278 smb2_util_close(tree, src_h);
4280 if (!smb2_util_handle_empty(dest_h)) {
4281 smb2_util_close(tree, dest_h);
4284 return ok;
4287 static bool copy_finderinfo_stream(struct torture_context *torture,
4288 struct smb2_tree *tree,
4289 TALLOC_CTX *tmp_ctx,
4290 const char *src_name,
4291 const char *dst_name)
4293 struct smb2_handle src_h = {{0}};
4294 struct smb2_handle dest_h = {{0}};
4295 NTSTATUS status;
4296 union smb_ioctl io;
4297 struct srv_copychunk_copy cc_copy;
4298 struct srv_copychunk_rsp cc_rsp;
4299 enum ndr_err_code ndr_ret;
4300 const char *type_creator = "SMB,OLE!";
4301 AfpInfo *info = NULL;
4302 const char *src_name_afpinfo = NULL;
4303 const char *dst_name_afpinfo = NULL;
4304 bool ok = false;
4306 src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
4307 AFPINFO_STREAM);
4308 torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
4309 "talloc_asprintf failed\n");
4311 dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
4312 AFPINFO_STREAM);
4313 torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
4314 "talloc_asprintf failed\n");
4316 info = torture_afpinfo_new(tmp_ctx);
4317 torture_assert_not_null_goto(torture, info, ok, done,
4318 "torture_afpinfo_new failed\n");
4320 memcpy(info->afpi_FinderInfo, type_creator, 8);
4321 ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
4322 torture_assert_goto(torture, ok == true, ok, done,
4323 "torture_write_afpinfo failed\n");
4325 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
4326 1, /* 1 chunk */
4327 src_name_afpinfo,
4328 &src_h, 0,
4329 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4330 dst_name_afpinfo,
4331 &dest_h, 0,
4332 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
4333 &cc_copy,
4334 &io);
4335 torture_assert_goto(torture, ok == true, ok, done,
4336 "setup copy chunk error\n");
4338 /* copy all src file data (via a single chunk desc) */
4339 cc_copy.chunks[0].source_off = 0;
4340 cc_copy.chunks[0].target_off = 0;
4341 cc_copy.chunks[0].length = 60;
4343 ndr_ret = ndr_push_struct_blob(
4344 &io.smb2.in.out, tmp_ctx, &cc_copy,
4345 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
4347 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4348 "ndr_push_srv_copychunk_copy\n");
4350 status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
4351 torture_assert_ntstatus_ok_goto(torture, status, ok, done,
4352 "FSCTL_SRV_COPYCHUNK\n");
4354 ndr_ret = ndr_pull_struct_blob(
4355 &io.smb2.out.out, tmp_ctx, &cc_rsp,
4356 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
4358 torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
4359 "ndr_pull_srv_copychunk_rsp\n");
4361 smb2_util_close(tree, src_h);
4362 ZERO_STRUCT(src_h);
4363 smb2_util_close(tree, dest_h);
4364 ZERO_STRUCT(dest_h);
4366 ok = check_copy_chunk_rsp(torture, &cc_rsp,
4367 1, /* chunks written */
4368 0, /* chunk bytes unsuccessfully written */
4369 60); /* total bytes written */
4370 torture_assert_goto(torture, ok == true, ok, done,
4371 "bad copy chunk response data\n");
4373 ok = check_stream(tree, __location__, torture, tmp_ctx,
4374 dst_name, AFPINFO_STREAM,
4375 0, 60, 16, 8, type_creator);
4376 torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
4378 done:
4379 if (!smb2_util_handle_empty(src_h)) {
4380 smb2_util_close(tree, src_h);
4382 if (!smb2_util_handle_empty(dest_h)) {
4383 smb2_util_close(tree, dest_h);
4386 return ok;
4389 static bool test_copy_chunk_streams(struct torture_context *torture,
4390 struct smb2_tree *tree)
4392 const char *src_name = "src";
4393 const char *dst_name = "dst";
4394 struct names {
4395 const char *src_sname;
4396 const char *dst_sname;
4397 } names[] = {
4398 { "src:foo", "dst:foo" },
4399 { "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
4401 int i;
4402 TALLOC_CTX *tmp_ctx = NULL;
4403 bool ok = false;
4405 tmp_ctx = talloc_new(tree);
4406 torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
4407 "torture_setup_file\n");
4409 smb2_util_unlink(tree, src_name);
4410 smb2_util_unlink(tree, dst_name);
4412 ok = torture_setup_file(torture, tree, src_name, false);
4413 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4414 ok = torture_setup_file(torture, tree, dst_name, false);
4415 torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
4417 for (i = 0; i < ARRAY_SIZE(names); i++) {
4418 ok = copy_one_stream(torture, tree, tmp_ctx,
4419 names[i].src_sname,
4420 names[i].dst_sname);
4421 torture_assert_goto(torture, ok == true, ok, done,
4422 "copy_one_stream failed\n");
4425 ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
4426 src_name, dst_name);
4427 torture_assert_goto(torture, ok == true, ok, done,
4428 "copy_finderinfo_stream failed\n");
4430 done:
4431 smb2_util_unlink(tree, src_name);
4432 smb2_util_unlink(tree, dst_name);
4433 talloc_free(tmp_ctx);
4434 return ok;
4438 * Ensure this security descriptor has exactly one mode, uid
4439 * and gid.
4442 static NTSTATUS check_nfs_sd(const struct security_descriptor *psd)
4444 uint32_t i;
4445 bool got_one_mode = false;
4446 bool got_one_uid = false;
4447 bool got_one_gid = false;
4449 if (psd->dacl == NULL) {
4450 return NT_STATUS_INVALID_SECURITY_DESCR;
4453 for (i = 0; i < psd->dacl->num_aces; i++) {
4454 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Mode,
4455 &psd->dacl->aces[i].trustee) == 0) {
4456 if (got_one_mode == true) {
4457 /* Can't have more than one. */
4458 return NT_STATUS_INVALID_SECURITY_DESCR;
4460 got_one_mode = true;
4463 for (i = 0; i < psd->dacl->num_aces; i++) {
4464 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Users,
4465 &psd->dacl->aces[i].trustee) == 0) {
4466 if (got_one_uid == true) {
4467 /* Can't have more than one. */
4468 return NT_STATUS_INVALID_SECURITY_DESCR;
4470 got_one_uid = true;
4473 for (i = 0; i < psd->dacl->num_aces; i++) {
4474 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Groups,
4475 &psd->dacl->aces[i].trustee) == 0) {
4476 if (got_one_gid == true) {
4477 /* Can't have more than one. */
4478 return NT_STATUS_INVALID_SECURITY_DESCR;
4480 got_one_gid = true;
4483 /* Must have at least one of each. */
4484 if (got_one_mode == false ||
4485 got_one_uid == false ||
4486 got_one_gid == false) {
4487 return NT_STATUS_INVALID_SECURITY_DESCR;
4489 return NT_STATUS_OK;
4492 static bool test_nfs_aces(struct torture_context *tctx,
4493 struct smb2_tree *tree)
4495 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4496 struct security_ace ace;
4497 struct dom_sid sid;
4498 const char *fname = BASEDIR "\\nfs_aces.txt";
4499 struct smb2_handle h = {{0}};
4500 union smb_fileinfo finfo2;
4501 union smb_setfileinfo set;
4502 struct security_descriptor *psd = NULL;
4503 NTSTATUS status;
4504 bool ret = true;
4506 ret = enable_aapl(tctx, tree);
4507 torture_assert(tctx, ret == true, "enable_aapl failed");
4509 /* clean slate ...*/
4510 smb2_util_unlink(tree, fname);
4511 smb2_deltree(tree, fname);
4512 smb2_deltree(tree, BASEDIR);
4514 status = torture_smb2_testdir(tree, BASEDIR, &h);
4515 CHECK_STATUS(status, NT_STATUS_OK);
4516 smb2_util_close(tree, h);
4518 /* Create a test file. */
4519 status = torture_smb2_testfile_access(tree,
4520 fname,
4522 SEC_STD_READ_CONTROL |
4523 SEC_STD_WRITE_DAC |
4524 SEC_RIGHTS_FILE_ALL);
4525 CHECK_STATUS(status, NT_STATUS_OK);
4527 /* Get the ACL. */
4528 finfo2.query_secdesc.in.secinfo_flags =
4529 SECINFO_OWNER |
4530 SECINFO_GROUP |
4531 SECINFO_DACL;
4532 finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
4533 finfo2.generic.in.file.handle = h;
4534 status = smb2_getinfo_file(tree, tctx, &finfo2);
4535 CHECK_STATUS(status, NT_STATUS_OK);
4537 psd = finfo2.query_secdesc.out.sd;
4539 /* Ensure we have only single mode/uid/gid NFS entries. */
4540 status = check_nfs_sd(psd);
4541 if (!NT_STATUS_IS_OK(status)) {
4542 NDR_PRINT_DEBUG(
4543 security_descriptor,
4544 discard_const_p(struct security_descriptor, psd));
4546 CHECK_STATUS(status, NT_STATUS_OK);
4548 /* Add a couple of extra NFS uids and gids. */
4549 sid_compose(&sid, &global_sid_Unix_NFS_Users, 27);
4550 init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
4551 status = security_descriptor_dacl_add(psd, &ace);
4552 CHECK_STATUS(status, NT_STATUS_OK);
4553 status = security_descriptor_dacl_add(psd, &ace);
4554 CHECK_STATUS(status, NT_STATUS_OK);
4556 sid_compose(&sid, &global_sid_Unix_NFS_Groups, 300);
4557 init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
4558 status = security_descriptor_dacl_add(psd, &ace);
4559 CHECK_STATUS(status, NT_STATUS_OK);
4560 status = security_descriptor_dacl_add(psd, &ace);
4561 CHECK_STATUS(status, NT_STATUS_OK);
4563 /* Now set on the file handle. */
4564 set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
4565 set.set_secdesc.in.file.handle = h;
4566 set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
4567 set.set_secdesc.in.sd = psd;
4568 status = smb2_setinfo_file(tree, &set);
4569 CHECK_STATUS(status, NT_STATUS_OK);
4571 /* Get the ACL again. */
4572 finfo2.query_secdesc.in.secinfo_flags =
4573 SECINFO_OWNER |
4574 SECINFO_GROUP |
4575 SECINFO_DACL;
4576 finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
4577 finfo2.generic.in.file.handle = h;
4578 status = smb2_getinfo_file(tree, tctx, &finfo2);
4579 CHECK_STATUS(status, NT_STATUS_OK);
4581 psd = finfo2.query_secdesc.out.sd;
4583 /* Ensure we have only single mode/uid/gid NFS entries. */
4584 status = check_nfs_sd(psd);
4585 if (!NT_STATUS_IS_OK(status)) {
4586 NDR_PRINT_DEBUG(
4587 security_descriptor,
4588 discard_const_p(struct security_descriptor, psd));
4590 CHECK_STATUS(status, NT_STATUS_OK);
4592 done:
4593 if (!smb2_util_handle_empty(h)) {
4594 smb2_util_close(tree, h);
4596 smb2_util_unlink(tree, fname);
4597 smb2_deltree(tree, fname);
4598 smb2_deltree(tree, BASEDIR);
4599 talloc_free(mem_ctx);
4600 return ret;
4604 * Note: This test depends on "vfs objects = catia fruit streams_xattr". For
4605 * some tests torture must be run on the host it tests and takes an additional
4606 * argument with the local path to the share:
4607 * "--option=torture:localdir=<SHAREPATH>".
4609 * When running against an OS X SMB server add "--option=torture:osx=true"
4611 struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
4613 struct torture_suite *suite = torture_suite_create(
4614 ctx, "fruit");
4616 suite->description = talloc_strdup(suite, "vfs_fruit tests");
4618 torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
4619 torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
4620 torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
4621 torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
4622 torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
4623 torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
4624 torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
4625 torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
4626 torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
4627 torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
4628 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
4629 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
4630 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
4631 torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
4632 torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
4633 torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
4634 torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
4635 torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
4636 torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
4637 torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
4638 torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
4639 torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
4640 torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
4641 torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
4642 torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
4643 torture_suite_add_1smb2_test(suite, "NFS ACE entries", test_nfs_aces);
4645 return suite;
4648 static bool test_stream_names_local(struct torture_context *tctx,
4649 struct smb2_tree *tree)
4651 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4652 NTSTATUS status;
4653 struct smb2_create create;
4654 struct smb2_handle h;
4655 const char *fname = BASEDIR "\\stream_names.txt";
4656 const char *sname1;
4657 bool ret;
4658 /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
4659 const char *streams[] = {
4660 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
4661 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
4662 "::$DATA"
4664 const char *localdir = NULL;
4666 localdir = torture_setting_string(tctx, "localdir", NULL);
4667 if (localdir == NULL) {
4668 torture_skip(tctx, "Need localdir for test");
4671 sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
4673 /* clean slate ...*/
4674 smb2_util_unlink(tree, fname);
4675 smb2_deltree(tree, fname);
4676 smb2_deltree(tree, BASEDIR);
4678 status = torture_smb2_testdir(tree, BASEDIR, &h);
4679 CHECK_STATUS(status, NT_STATUS_OK);
4680 smb2_util_close(tree, h);
4682 torture_comment(tctx, "(%s) testing stream names\n", __location__);
4683 ZERO_STRUCT(create);
4684 create.in.desired_access = SEC_FILE_WRITE_DATA;
4685 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
4686 create.in.share_access =
4687 NTCREATEX_SHARE_ACCESS_DELETE|
4688 NTCREATEX_SHARE_ACCESS_READ|
4689 NTCREATEX_SHARE_ACCESS_WRITE;
4690 create.in.create_disposition = NTCREATEX_DISP_CREATE;
4691 create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
4692 create.in.fname = sname1;
4694 status = smb2_create(tree, mem_ctx, &create);
4695 CHECK_STATUS(status, NT_STATUS_OK);
4696 smb2_util_close(tree, create.out.file.handle);
4698 ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
4699 "user.DosStream.bar:baz:$DATA",
4700 "data", strlen("data"));
4701 CHECK_VALUE(ret, true);
4703 ret = check_stream_list(tree, tctx, fname, 3, streams, false);
4704 CHECK_VALUE(ret, true);
4706 done:
4707 status = smb2_util_unlink(tree, fname);
4708 smb2_deltree(tree, BASEDIR);
4709 talloc_free(mem_ctx);
4711 return ret;
4714 struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
4716 struct torture_suite *suite = torture_suite_create(
4717 ctx, "fruit_netatalk");
4719 suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
4721 torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
4722 torture_suite_add_1smb2_test(suite, "stream names with locally created xattr", test_stream_names_local);
4724 return suite;
4727 struct torture_suite *torture_vfs_fruit_file_id(TALLOC_CTX *ctx)
4729 struct torture_suite *suite =
4730 torture_suite_create(ctx, "fruit_file_id");
4732 suite->description =
4733 talloc_strdup(suite, "vfs_fruit tests for on-disk file ID that "
4734 "require fruit:zero_file_id=yes");
4736 torture_suite_add_1smb2_test(suite, "zero file id if AAPL negotiated",
4737 test_zero_file_id);
4739 return suite;
4742 static bool test_timemachine_volsize(struct torture_context *tctx,
4743 struct smb2_tree *tree)
4745 TALLOC_CTX *mem_ctx = talloc_new(tctx);
4746 struct smb2_handle h = {{0}};
4747 union smb_fsinfo fsinfo;
4748 NTSTATUS status;
4749 bool ok = true;
4750 const char *info_plist =
4751 "<dict>\n"
4752 " <key>band-size</key>\n"
4753 " <integer>8192</integer>\n"
4754 "</dict>\n";
4756 smb2_deltree(tree, "test.sparsebundle");
4758 ok = enable_aapl(tctx, tree);
4759 torture_assert_goto(tctx, ok, ok, done, "enable_aapl failed");
4761 status = smb2_util_mkdir(tree, "test.sparsebundle");
4762 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
4763 "smb2_util_mkdir\n");
4765 ok = write_stream(tree, __location__, tctx, mem_ctx,
4766 "test.sparsebundle/Info.plist", NULL,
4767 0, strlen(info_plist), info_plist);
4768 torture_assert_goto(tctx, ok, ok, done, "write_stream failed\n");
4770 status = smb2_util_mkdir(tree, "test.sparsebundle/bands");
4771 torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
4772 "smb2_util_mkdir\n");
4774 ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/1", false);
4775 torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
4777 ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/2", false);
4778 torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
4780 status = smb2_util_roothandle(tree, &h);
4781 torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
4783 ZERO_STRUCT(fsinfo);
4784 fsinfo.generic.level = RAW_QFS_SIZE_INFORMATION;
4785 fsinfo.generic.handle = h;
4787 status = smb2_getinfo_fs(tree, tree, &fsinfo);
4788 torture_assert_ntstatus_ok(tctx, status, "smb2_getinfo_fs failed");
4790 torture_comment(tctx, "sectors_per_unit: %" PRIu32"\n"
4791 "bytes_per_sector: %" PRIu32"\n"
4792 "total_alloc_units: %" PRIu64"\n"
4793 "avail_alloc_units: %" PRIu64"\n",
4794 fsinfo.size_info.out.sectors_per_unit,
4795 fsinfo.size_info.out.bytes_per_sector,
4796 fsinfo.size_info.out.total_alloc_units,
4797 fsinfo.size_info.out.avail_alloc_units);
4800 * Let me explain the numbers:
4802 * - the share is set to "fruit:time machine max size = 32K"
4803 * - we've faked a bandsize of 8 K in the Info.plist file
4804 * - we've created two bands files
4805 * - one allocation unit is made of two sectors with 512 B each
4806 * => we've consumed 16 allocation units, there should be 16 free
4809 torture_assert_goto(tctx, fsinfo.size_info.out.sectors_per_unit == 2,
4810 ok, done, "Bad sectors_per_unit");
4812 torture_assert_goto(tctx, fsinfo.size_info.out.bytes_per_sector == 512,
4813 ok, done, "Bad bytes_per_sector");
4815 torture_assert_goto(tctx, fsinfo.size_info.out.total_alloc_units == 32,
4816 ok, done, "Bad total_alloc_units");
4818 torture_assert_goto(tctx, fsinfo.size_info.out.avail_alloc_units == 16,
4819 ok, done, "Bad avail_alloc_units");
4821 done:
4822 if (!smb2_util_handle_empty(h)) {
4823 smb2_util_close(tree, h);
4825 smb2_deltree(tree, "test.sparsebundle");
4826 talloc_free(mem_ctx);
4827 return ok;
4830 struct torture_suite *torture_vfs_fruit_timemachine(TALLOC_CTX *ctx)
4832 struct torture_suite *suite = torture_suite_create(
4833 ctx, "fruit_timemachine");
4835 suite->description = talloc_strdup(
4836 suite, "vfs_fruit tests for TimeMachine");
4838 torture_suite_add_1smb2_test(suite, "Timemachine-volsize",
4839 test_timemachine_volsize);
4841 return suite;