s4:torture:vfs_fruit: skip test_adouble_conversion() without "localdir"
[kai/samba-autobuild/.git] / source4 / torture / vfs / fruit.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    vfs_fruit tests
5
6    Copyright (C) Ralph Boehme 2014
7
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.
12
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.
17
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/>.
20 */
21
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"
33
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
40 #define BASEDIR "vfs_fruit_dir"
41 #define FNAME_CC_SRC "testfsctl.dat"
42 #define FNAME_CC_DST "testfsctl2.dat"
43
44 #define CHECK_STATUS(status, correct) do { \
45         if (!NT_STATUS_EQUAL(status, correct)) { \
46                 torture_result(tctx, TORTURE_FAIL, \
47                     "(%s) Incorrect status %s - should be %s\n", \
48                     __location__, nt_errstr(status), nt_errstr(correct)); \
49                 ret = false; \
50                 goto done; \
51         }} while (0)
52
53 #define CHECK_VALUE(v, correct) do { \
54         if ((v) != (correct)) { \
55                 torture_result(tctx, TORTURE_FAIL, \
56                                "(%s) Incorrect value %s=%u - should be %u\n", \
57                                __location__, #v, (unsigned)v, (unsigned)correct); \
58                 ret = false; \
59                 goto done; \
60         }} while (0)
61
62 static bool check_stream_list(struct smb2_tree *tree,
63                               struct torture_context *tctx,
64                               const char *fname,
65                               int num_exp,
66                               const char **exp,
67                               bool is_dir);
68
69 static int qsort_string(char * const *s1, char * const *s2)
70 {
71         return strcmp(*s1, *s2);
72 }
73
74 static int qsort_stream(const struct stream_struct * s1, const struct stream_struct *s2)
75 {
76         return strcmp(s1->stream_name.s, s2->stream_name.s);
77 }
78
79 /*
80  * REVIEW:
81  * This is hokey, but what else can we do?
82  */
83 #if defined(HAVE_ATTROPEN) || defined(FREEBSD)
84 #define AFPINFO_EA_NETATALK "org.netatalk.Metadata"
85 #define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork"
86 #else
87 #define AFPINFO_EA_NETATALK "user.org.netatalk.Metadata"
88 #define AFPRESOURCE_EA_NETATALK "user.org.netatalk.ResourceFork"
89 #endif
90
91 /*
92 The metadata xattr char buf below contains the following attributes:
93
94 -------------------------------------------------------------------------------
95 Entry ID   : 00000008 : File Dates Info
96 Offset     : 00000162 : 354
97 Length     : 00000010 : 16
98
99 -DATE------:          : (GMT)                    : (Local)
100 create     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
101 modify     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
102 backup     : 80000000 : Unknown or Initial
103 access     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
104
105 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
106 00000000   : 1B 44 21 69 1B 44 21 69 80 00 00 00 1B 44 21 69 : .D!i.D!i.....D!i
107
108 -------------------------------------------------------------------------------
109 Entry ID   : 00000009 : Finder Info
110 Offset     : 0000007A : 122
111 Length     : 00000020 : 32
112
113 -FInfo-----:
114 Type       : 42415252 : BARR
115 Creator    : 464F4F4F : FOOO
116 isAlias    : 0
117 Invisible  : 1
118 hasBundle  : 0
119 nameLocked : 0
120 Stationery : 0
121 CustomIcon : 0
122 Reserved   : 0
123 Inited     : 0
124 NoINITS    : 0
125 Shared     : 0
126 SwitchLaunc: 0
127 Hidden Ext : 0
128 color      : 000      : none
129 isOnDesk   : 0
130 Location v : 0000     : 0
131 Location h : 0000     : 0
132 Fldr       : 0000     : ..
133
134 -FXInfo----:
135 Rsvd|IconID: 0000     : 0
136 Rsvd       : 0000     : ..
137 Rsvd       : 0000     : ..
138 Rsvd       : 0000     : ..
139 AreInvalid : 0
140 unknown bit: 0
141 unknown bit: 0
142 unknown bit: 0
143 unknown bit: 0
144 unknown bit: 0
145 unknown bit: 0
146 CustomBadge: 0
147 ObjctIsBusy: 0
148 unknown bit: 0
149 unknown bit: 0
150 unknown bit: 0
151 unknown bit: 0
152 RoutingInfo: 0
153 unknown bit: 0
154 unknown bit: 0
155 Rsvd|commnt: 0000     : 0
156 PutAway    : 00000000 : 0
157
158 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
159 00000000   : 42 41 52 52 46 4F 4F 4F 40 00 00 00 00 00 00 00 : BARRFOOO@.......
160 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
161
162 -------------------------------------------------------------------------------
163 Entry ID   : 0000000E : AFP File Info
164 Offset     : 00000172 : 370
165 Length     : 00000004 : 4
166
167 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
168 00000000   : 00 00 01 A1                                     : ....
169  */
170
171 char metadata_xattr[] = {
172         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
173         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175         0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
176         0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177         0x00, 0x08, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00,
178         0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
179         0x00, 0x7a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
180         0x00, 0x0e, 0x00, 0x00, 0x01, 0x72, 0x00, 0x00,
181         0x00, 0x04, 0x80, 0x44, 0x45, 0x56, 0x00, 0x00,
182         0x01, 0x76, 0x00, 0x00, 0x00, 0x08, 0x80, 0x49,
183         0x4e, 0x4f, 0x00, 0x00, 0x01, 0x7e, 0x00, 0x00,
184         0x00, 0x08, 0x80, 0x53, 0x59, 0x4e, 0x00, 0x00,
185         0x01, 0x86, 0x00, 0x00, 0x00, 0x08, 0x80, 0x53,
186         0x56, 0x7e, 0x00, 0x00, 0x01, 0x8e, 0x00, 0x00,
187         0x00, 0x04, 0x42, 0x41, 0x52, 0x52, 0x46, 0x4f,
188         0x4f, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
189         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216         0x00, 0x00, 0x1b, 0x44, 0x21, 0x69, 0x1b, 0x44,
217         0x21, 0x69, 0x80, 0x00, 0x00, 0x00, 0x1b, 0x44,
218         0x21, 0x69, 0x00, 0x00, 0x01, 0xa1, 0x00, 0xfd,
219         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x20,
220         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xe3,
221         0x86, 0x53, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x01,
222         0x00, 0x00
223 };
224
225 /*
226 The buf below contains the following AppleDouble encoded data:
227
228 -------------------------------------------------------------------------------
229 MagicNumber: 00051607                                        : AppleDouble
230 Version    : 00020000                                        : Version 2
231 Filler     : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
232 Num. of ent: 0002                                            : 2
233
234 -------------------------------------------------------------------------------
235 Entry ID   : 00000009 : Finder Info
236 Offset     : 00000032 : 50
237 Length     : 00000EB0 : 3760
238
239 -FInfo-----:
240 Type       : 54455854 : TEXT
241 Creator    : 21526368 : !Rch
242 ...
243
244 -EA--------:
245 pad        : 0000     : ..
246 magic      : 41545452 : ATTR
247 debug_tag  : 0007F98E : 522638
248 total_size : 00000EE2 : 3810
249 data_start : 00000078 : 120
250 data_length: 00000000 : 0
251 reserved[0]: 00000000 : ....
252 reserved[1]: 00000000 : ....
253 reserved[2]: 00000000 : ....
254 flags      : 0000     : ..
255 num_attrs  : 0000     : 0
256
257 -------------------------------------------------------------------------------
258 Entry ID   : 00000002 : Resource Fork
259 Offset     : 00000EE2 : 3810
260 Length     : 0000011E : 286
261
262 -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
263 00000000   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
264 00000010   : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo
265 00000020   : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
266 00000030   : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 :  left blank   ..
267 ...
268 00000110   : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF       : ..............
269 */
270 static char osx_adouble_w_xattr[] = {
271         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
272         0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
273         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
274         0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
275         0x00, 0x32, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00,
276         0x00, 0x02, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00,
277         0x01, 0x1e, 0x54, 0x45, 0x58, 0x54, 0x21, 0x52,
278         0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
281         0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
282         0x00, 0x07, 0xf9, 0x8e, 0x00, 0x00, 0x0e, 0xe2,
283         0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
284         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382         0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00,
386         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
418         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
431         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
432         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
439         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
445         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
446         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
457         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
483         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
484         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
487         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
493         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
494         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
509         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
514         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
516         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
523         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
524         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
525         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
529         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
530         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
533         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
549         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
614         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
660         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
677         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
679         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
684         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
706         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
707         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
708         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
721         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
729         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
731         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
733         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
734         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
735         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
736         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
737         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
744         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
745         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
746         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
747         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
748         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
749         0x00, 0x1e, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72,
750         0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20,
751         0x66, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
752         0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
753         0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
754         0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
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, 0x01, 0x00, 0x00, 0x00,
780         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
782         0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
783 };
784
785 /**
786  * talloc and intialize an AfpInfo
787  **/
788 static AfpInfo *torture_afpinfo_new(TALLOC_CTX *mem_ctx)
789 {
790         AfpInfo *info;
791
792         info = talloc_zero(mem_ctx, AfpInfo);
793         if (info == NULL) {
794                 return NULL;
795         }
796
797         info->afpi_Signature = AFP_Signature;
798         info->afpi_Version = AFP_Version;
799         info->afpi_BackupTime = AFP_BackupTime;
800
801         return info;
802 }
803
804 /**
805  * Pack AfpInfo into a talloced buffer
806  **/
807 static char *torture_afpinfo_pack(TALLOC_CTX *mem_ctx,
808                                   AfpInfo *info)
809 {
810         char *buf;
811
812         buf = talloc_array(mem_ctx, char, AFP_INFO_SIZE);
813         if (buf == NULL) {
814                 return NULL;
815         }
816
817         RSIVAL(buf, 0, info->afpi_Signature);
818         RSIVAL(buf, 4, info->afpi_Version);
819         RSIVAL(buf, 12, info->afpi_BackupTime);
820         memcpy(buf + 16, info->afpi_FinderInfo, sizeof(info->afpi_FinderInfo));
821
822         return buf;
823 }
824
825 /**
826  * Unpack AfpInfo
827  **/
828 #if 0
829 static void torture_afpinfo_unpack(AfpInfo *info, char *data)
830 {
831         info->afpi_Signature = RIVAL(data, 0);
832         info->afpi_Version = RIVAL(data, 4);
833         info->afpi_BackupTime = RIVAL(data, 12);
834         memcpy(info->afpi_FinderInfo, (const char *)data + 16,
835                sizeof(info->afpi_FinderInfo));
836 }
837 #endif
838
839 static bool torture_write_afpinfo(struct smb2_tree *tree,
840                                   struct torture_context *tctx,
841                                   TALLOC_CTX *mem_ctx,
842                                   const char *fname,
843                                   AfpInfo *info)
844 {
845         struct smb2_handle handle;
846         struct smb2_create io;
847         NTSTATUS status;
848         const char *full_name;
849         char *infobuf;
850         bool ret = true;
851
852         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, AFPINFO_STREAM_NAME);
853         if (full_name == NULL) {
854             torture_comment(tctx, "talloc_asprintf error\n");
855             return false;
856         }
857         ZERO_STRUCT(io);
858         io.in.desired_access = SEC_FILE_WRITE_DATA;
859         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
860         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
861         io.in.create_options = 0;
862         io.in.fname = full_name;
863
864         status = smb2_create(tree, mem_ctx, &io);
865         CHECK_STATUS(status, NT_STATUS_OK);
866
867         handle = io.out.file.handle;
868
869         infobuf = torture_afpinfo_pack(mem_ctx, info);
870         if (infobuf == NULL) {
871                 return false;
872         }
873
874         status = smb2_util_write(tree, handle, infobuf, 0, AFP_INFO_SIZE);
875         CHECK_STATUS(status, NT_STATUS_OK);
876
877         smb2_util_close(tree, handle);
878
879 done:
880         return ret;
881 }
882
883 /**
884  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
885  * compare against buffer 'value'
886  **/
887 static bool check_stream(struct smb2_tree *tree,
888                          const char *location,
889                          struct torture_context *tctx,
890                          TALLOC_CTX *mem_ctx,
891                          const char *fname,
892                          const char *sname,
893                          off_t read_offset,
894                          size_t read_count,
895                          off_t comp_offset,
896                          size_t comp_count,
897                          const char *value)
898 {
899         struct smb2_handle handle;
900         struct smb2_create create;
901         struct smb2_read r;
902         NTSTATUS status;
903         char *full_name;
904         bool ret = true;
905
906         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
907         if (full_name == NULL) {
908             torture_comment(tctx, "talloc_asprintf error\n");
909             return false;
910         }
911         ZERO_STRUCT(create);
912         create.in.desired_access = SEC_FILE_READ_DATA;
913         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
914         create.in.create_disposition = NTCREATEX_DISP_OPEN;
915         create.in.fname = full_name;
916
917         torture_comment(tctx, "Open stream %s\n", full_name);
918
919         status = smb2_create(tree, mem_ctx, &create);
920         if (!NT_STATUS_IS_OK(status)) {
921                 TALLOC_FREE(full_name);
922                 if (value == NULL) {
923                         return true;
924                 }
925                 torture_comment(tctx, "Unable to open stream %s\n", full_name);
926                 return false;
927         }
928
929         handle = create.out.file.handle;
930         if (value == NULL) {
931                 TALLOC_FREE(full_name);
932                 smb2_util_close(tree, handle);
933                 return true;
934         }
935
936         ZERO_STRUCT(r);
937         r.in.file.handle = handle;
938         r.in.length      = read_count;
939         r.in.offset      = read_offset;
940
941         status = smb2_read(tree, tree, &r);
942
943         torture_assert_ntstatus_ok_goto(
944                 tctx, status, ret, done,
945                 talloc_asprintf(tctx, "(%s) Failed to read %lu bytes from stream '%s'\n",
946                                 location, (long)strlen(value), full_name));
947
948         torture_assert_goto(tctx, r.out.data.length == read_count, ret, done,
949                             talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected %jd\n",
950                                             (intmax_t)r.out.data.length, (intmax_t)read_count));
951
952         torture_assert_goto(
953                 tctx, memcmp(r.out.data.data + comp_offset, value, comp_count) == 0,
954                 ret, done,
955                 talloc_asprintf(tctx, "(%s) Bad data in stream\n", location));
956
957 done:
958         TALLOC_FREE(full_name);
959         smb2_util_close(tree, handle);
960         return ret;
961 }
962
963 /**
964  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
965  * compare against buffer 'value'
966  **/
967 static ssize_t read_stream(struct smb2_tree *tree,
968                            const char *location,
969                            struct torture_context *tctx,
970                            TALLOC_CTX *mem_ctx,
971                            const char *fname,
972                            const char *sname,
973                            off_t read_offset,
974                            size_t read_count)
975 {
976         struct smb2_handle handle;
977         struct smb2_create create;
978         struct smb2_read r;
979         NTSTATUS status;
980         const char *full_name;
981         bool ret = true;
982
983         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
984         if (full_name == NULL) {
985             torture_comment(tctx, "talloc_asprintf error\n");
986             return -1;
987         }
988         ZERO_STRUCT(create);
989         create.in.desired_access = SEC_FILE_READ_DATA;
990         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
991         create.in.create_disposition = NTCREATEX_DISP_OPEN;
992         create.in.fname = full_name;
993
994         torture_comment(tctx, "Open stream %s\n", full_name);
995
996         status = smb2_create(tree, mem_ctx, &create);
997         if (!NT_STATUS_IS_OK(status)) {
998                 torture_comment(tctx, "Unable to open stream %s\n",
999                                 full_name);
1000                 return -1;
1001         }
1002
1003         handle = create.out.file.handle;
1004
1005         ZERO_STRUCT(r);
1006         r.in.file.handle = handle;
1007         r.in.length      = read_count;
1008         r.in.offset      = read_offset;
1009
1010         status = smb2_read(tree, tree, &r);
1011         if (!NT_STATUS_IS_OK(status)) {
1012                 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
1013         }
1014
1015         smb2_util_close(tree, handle);
1016
1017 done:
1018         if (ret == false) {
1019                 return -1;
1020         }
1021         return r.out.data.length;
1022 }
1023
1024 /**
1025  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
1026  * compare against buffer 'value'
1027  **/
1028 static bool write_stream(struct smb2_tree *tree,
1029                          const char *location,
1030                          struct torture_context *tctx,
1031                          TALLOC_CTX *mem_ctx,
1032                          const char *fname,
1033                          const char *sname,
1034                          off_t offset,
1035                          size_t size,
1036                          const char *value)
1037 {
1038         struct smb2_handle handle;
1039         struct smb2_create create;
1040         NTSTATUS status;
1041         const char *full_name;
1042
1043         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
1044         if (full_name == NULL) {
1045             torture_comment(tctx, "talloc_asprintf error\n");
1046             return false;
1047         }
1048         ZERO_STRUCT(create);
1049         create.in.desired_access = SEC_FILE_WRITE_DATA;
1050         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
1051         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
1052         create.in.fname = full_name;
1053
1054         status = smb2_create(tree, mem_ctx, &create);
1055         if (!NT_STATUS_IS_OK(status)) {
1056                 if (value == NULL) {
1057                         return true;
1058                 } else {
1059                         torture_comment(tctx, "Unable to open stream %s\n",
1060                             full_name);
1061                         sleep(10000000);
1062                         return false;
1063                 }
1064         }
1065
1066         handle = create.out.file.handle;
1067         if (value == NULL) {
1068                 return true;
1069         }
1070
1071         status = smb2_util_write(tree, handle, value, offset, size);
1072
1073         if (!NT_STATUS_IS_OK(status)) {
1074                 torture_comment(tctx, "(%s) Failed to write %lu bytes to "
1075                     "stream '%s'\n", location, (long)size, full_name);
1076                 return false;
1077         }
1078
1079         smb2_util_close(tree, handle);
1080         return true;
1081 }
1082
1083 static bool torture_setup_local_xattr(struct torture_context *tctx,
1084                                       const char *path_option,
1085                                       const char *name,
1086                                       const char *xattr,
1087                                       const char *metadata,
1088                                       size_t size)
1089 {
1090         int ret = true;
1091         int result;
1092         const char *spath;
1093         char *path;
1094
1095         spath = torture_setting_string(tctx, path_option, NULL);
1096         if (spath == NULL) {
1097                 printf("No sharepath for option %s\n", path_option);
1098                 return false;
1099         }
1100
1101         path = talloc_asprintf(tctx, "%s/%s", spath, name);
1102
1103         result = setxattr(path, xattr, metadata, size, 0);
1104         if (result != 0) {
1105                 ret = false;
1106         }
1107
1108         TALLOC_FREE(path);
1109
1110         return ret;
1111 }
1112
1113 static bool torture_setup_local_file(struct torture_context *tctx,
1114                                      const char *path_option,
1115                                      const char *name,
1116                                      const char *buf,
1117                                      size_t size)
1118 {
1119         int fd;
1120         const char *spath;
1121         char *path;
1122         ssize_t rsize;
1123
1124         spath = torture_setting_string(tctx, path_option, NULL);
1125         if (spath == NULL) {
1126                 printf("No sharepath for option %s\n", path_option);
1127                 return false;
1128         }
1129
1130         path = talloc_asprintf(tctx, "%s/%s", spath, name);
1131         if (path == NULL) {
1132                 return false;
1133         }
1134
1135         fd = creat(path, S_IRWXU);
1136         TALLOC_FREE(path);
1137         if (fd == -1) {
1138                 return false;
1139         }
1140
1141         if ((buf == NULL) || (size == 0)) {
1142                 close(fd);
1143                 return true;
1144         }
1145
1146         rsize = write(fd, buf, size);
1147         if (rsize != size) {
1148                 return false;
1149         }
1150
1151         close(fd);
1152
1153         return true;
1154 }
1155
1156 /**
1157  * Create a file or directory
1158  **/
1159 static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree,
1160                                const char *name, bool dir)
1161 {
1162         struct smb2_create io;
1163         NTSTATUS status;
1164
1165         smb2_util_unlink(tree, name);
1166         ZERO_STRUCT(io);
1167         io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
1168         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
1169         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1170         io.in.share_access =
1171                 NTCREATEX_SHARE_ACCESS_DELETE|
1172                 NTCREATEX_SHARE_ACCESS_READ|
1173                 NTCREATEX_SHARE_ACCESS_WRITE;
1174         io.in.create_options = 0;
1175         io.in.fname = name;
1176         if (dir) {
1177                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1178                 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
1179                 io.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
1180                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
1181         }
1182
1183         status = smb2_create(tree, mem_ctx, &io);
1184         if (!NT_STATUS_IS_OK(status)) {
1185                 return false;
1186         }
1187
1188         status = smb2_util_close(tree, io.out.file.handle);
1189         if (!NT_STATUS_IS_OK(status)) {
1190                 return false;
1191         }
1192
1193         return true;
1194 }
1195
1196 static bool enable_aapl(struct torture_context *tctx,
1197                         struct smb2_tree *tree)
1198 {
1199         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1200         NTSTATUS status;
1201         bool ret = true;
1202         struct smb2_create io;
1203         DATA_BLOB data;
1204         struct smb2_create_blob *aapl = NULL;
1205         uint32_t aapl_server_caps;
1206         uint32_t expexted_scaps = (SMB2_CRTCTX_AAPL_UNIX_BASED |
1207                                    SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1208                                    SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1209                                    SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
1210         bool is_osx_server = torture_setting_bool(tctx, "osx", false);
1211
1212         ZERO_STRUCT(io);
1213         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
1214         io.in.file_attributes    = FILE_ATTRIBUTE_DIRECTORY;
1215         io.in.create_disposition = NTCREATEX_DISP_OPEN;
1216         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1217                               NTCREATEX_SHARE_ACCESS_READ |
1218                               NTCREATEX_SHARE_ACCESS_WRITE);
1219         io.in.fname = "";
1220
1221         /*
1222          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1223          * controls behaviour of Apple's SMB2 extensions for the whole
1224          * session!
1225          */
1226
1227         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1228         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1229         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1230                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1231                              SMB2_CRTCTX_AAPL_MODEL_INFO));
1232         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1233                               SMB2_CRTCTX_AAPL_UNIX_BASED |
1234                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1235
1236         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1237         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_blob_add");
1238
1239         status = smb2_create(tree, tctx, &io);
1240         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1241
1242         status = smb2_util_close(tree, io.out.file.handle);
1243         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close");
1244
1245         /*
1246          * Now check returned AAPL context
1247          */
1248         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1249
1250         aapl = smb2_create_blob_find(&io.out.blobs,
1251                                      SMB2_CREATE_TAG_AAPL);
1252         torture_assert_goto(tctx, aapl != NULL, ret, done, "missing AAPL context");
1253
1254         if (!is_osx_server) {
1255                 torture_assert_goto(tctx, aapl->data.length == 50, ret, done, "bad AAPL size");
1256         }
1257
1258         aapl_server_caps = BVAL(aapl->data.data, 16);
1259         torture_assert_goto(tctx, aapl_server_caps == expexted_scaps,
1260                             ret, done, "bad AAPL caps");
1261
1262 done:
1263         talloc_free(mem_ctx);
1264         return ret;
1265 }
1266
1267 static bool test_read_netatalk_metadata(struct torture_context *tctx,
1268                                         struct smb2_tree *tree)
1269 {
1270         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1271         const char *fname = BASEDIR "\\torture_read_metadata";
1272         NTSTATUS status;
1273         struct smb2_handle testdirh;
1274         bool ret = true;
1275         ssize_t len;
1276         const char *localdir = NULL;
1277
1278         torture_comment(tctx, "Checking metadata access\n");
1279
1280         localdir = torture_setting_string(tctx, "localdir", NULL);
1281         if (localdir == NULL) {
1282                 torture_skip(tctx, "Need localdir for test");
1283         }
1284
1285         smb2_util_unlink(tree, fname);
1286
1287         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1288         CHECK_STATUS(status, NT_STATUS_OK);
1289         smb2_util_close(tree, testdirh);
1290
1291         ret = torture_setup_file(mem_ctx, tree, fname, false);
1292         if (ret == false) {
1293                 goto done;
1294         }
1295
1296         ret = torture_setup_local_xattr(tctx, "localdir",
1297                                         BASEDIR "/torture_read_metadata",
1298                                         AFPINFO_EA_NETATALK,
1299                                         metadata_xattr, sizeof(metadata_xattr));
1300         if (ret == false) {
1301                 goto done;
1302         }
1303
1304         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1305                            0, 60, 0, 4, "AFP");
1306         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1307
1308         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1309                            0, 60, 16, 8, "BARRFOOO");
1310         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1311
1312         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1313                            16, 8, 0, 8, "BARRFOOO");
1314         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1315
1316         /* Check reading offset and read size > sizeof(AFPINFO_STREAM) */
1317
1318         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1319                           AFPINFO_STREAM, 0, 61);
1320         CHECK_VALUE(len, 60);
1321
1322         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1323                           AFPINFO_STREAM, 59, 2);
1324         CHECK_VALUE(len, 1);
1325
1326         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1327                           AFPINFO_STREAM, 60, 1);
1328         CHECK_VALUE(len, 0);
1329
1330         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1331                           AFPINFO_STREAM, 61, 1);
1332         CHECK_VALUE(len, 0);
1333
1334 done:
1335         smb2_deltree(tree, BASEDIR);
1336         talloc_free(mem_ctx);
1337         return ret;
1338 }
1339
1340 static bool test_write_atalk_metadata(struct torture_context *tctx,
1341                                       struct smb2_tree *tree)
1342 {
1343         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1344         const char *fname = BASEDIR "\\torture_write_metadata";
1345         const char *type_creator = "SMB,OLE!";
1346         NTSTATUS status;
1347         struct smb2_handle testdirh;
1348         bool ret = true;
1349         AfpInfo *info;
1350
1351         smb2_deltree(tree, BASEDIR);
1352         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1353         CHECK_STATUS(status, NT_STATUS_OK);
1354         smb2_util_close(tree, testdirh);
1355
1356         ret = torture_setup_file(mem_ctx, tree, fname, false);
1357         if (ret == false) {
1358                 goto done;
1359         }
1360
1361         info = torture_afpinfo_new(mem_ctx);
1362         if (info == NULL) {
1363                 goto done;
1364         }
1365
1366         memcpy(info->afpi_FinderInfo, type_creator, 8);
1367         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1368         ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1369                             0, 60, 16, 8, type_creator);
1370
1371 done:
1372         smb2_util_unlink(tree, fname);
1373         smb2_deltree(tree, BASEDIR);
1374         talloc_free(mem_ctx);
1375         return ret;
1376 }
1377
1378 static bool test_write_atalk_rfork_io(struct torture_context *tctx,
1379                                       struct smb2_tree *tree)
1380 {
1381         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1382         const char *fname = BASEDIR "\\torture_write_rfork_io";
1383         const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
1384         const char *rfork_content = "1234567890";
1385         NTSTATUS status;
1386         struct smb2_handle testdirh;
1387         bool ret = true;
1388
1389         union smb_open io;
1390         struct smb2_handle filehandle;
1391         union smb_fileinfo finfo;
1392         union smb_setfileinfo sinfo;
1393
1394         smb2_util_unlink(tree, fname);
1395
1396         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1397         CHECK_STATUS(status, NT_STATUS_OK);
1398         smb2_util_close(tree, testdirh);
1399
1400         ret = torture_setup_file(mem_ctx, tree, fname, false);
1401         if (ret == false) {
1402                 goto done;
1403         }
1404
1405         torture_comment(tctx, "(%s) writing to resource fork\n",
1406             __location__);
1407
1408         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1409                             fname, AFPRESOURCE_STREAM_NAME,
1410                             10, 10, rfork_content);
1411
1412         ret &= check_stream(tree, __location__, tctx, mem_ctx,
1413                             fname, AFPRESOURCE_STREAM_NAME,
1414                             0, 20, 10, 10, rfork_content);
1415
1416         /* Check size after write */
1417
1418         ZERO_STRUCT(io);
1419         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1420         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1421                 SEC_FILE_WRITE_ATTRIBUTE;
1422         io.smb2.in.fname = rfork;
1423         status = smb2_create(tree, mem_ctx, &(io.smb2));
1424         CHECK_STATUS(status, NT_STATUS_OK);
1425         filehandle = io.smb2.out.file.handle;
1426
1427         torture_comment(tctx, "(%s) check resource fork size after write\n",
1428             __location__);
1429
1430         ZERO_STRUCT(finfo);
1431         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1432         finfo.generic.in.file.handle = filehandle;
1433         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1434         CHECK_STATUS(status, NT_STATUS_OK);
1435         if (finfo.all_info.out.size != 20) {
1436                 torture_result(tctx, TORTURE_FAIL,
1437                                "(%s) Incorrect resource fork size\n",
1438                                __location__);
1439                 ret = false;
1440                 smb2_util_close(tree, filehandle);
1441                 goto done;
1442         }
1443         smb2_util_close(tree, filehandle);
1444
1445         /* Write at large offset */
1446
1447         torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
1448                         __location__);
1449
1450         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1451                             fname, AFPRESOURCE_STREAM_NAME,
1452                             (off_t)1<<32, 10, rfork_content);
1453
1454         ret &= check_stream(tree, __location__, tctx, mem_ctx,
1455                             fname, AFPRESOURCE_STREAM_NAME,
1456                             (off_t)1<<32, 10, 0, 10, rfork_content);
1457
1458         /* Truncate back to size of 1 byte */
1459
1460         torture_comment(tctx, "(%s) truncate resource fork and check size\n",
1461                         __location__);
1462
1463         ZERO_STRUCT(io);
1464         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1465         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1466                 SEC_FILE_WRITE_ATTRIBUTE;
1467         io.smb2.in.fname = rfork;
1468         status = smb2_create(tree, mem_ctx, &(io.smb2));
1469         CHECK_STATUS(status, NT_STATUS_OK);
1470         filehandle = io.smb2.out.file.handle;
1471
1472         ZERO_STRUCT(sinfo);
1473         sinfo.end_of_file_info.level =
1474                 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1475         sinfo.end_of_file_info.in.file.handle = filehandle;
1476         sinfo.end_of_file_info.in.size = 1;
1477         status = smb2_setinfo_file(tree, &sinfo);
1478         CHECK_STATUS(status, NT_STATUS_OK);
1479
1480         smb2_util_close(tree, filehandle);
1481
1482         /* Now check size */
1483         ZERO_STRUCT(io);
1484         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1485         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1486                 SEC_FILE_WRITE_ATTRIBUTE;
1487         io.smb2.in.fname = rfork;
1488         status = smb2_create(tree, mem_ctx, &(io.smb2));
1489         CHECK_STATUS(status, NT_STATUS_OK);
1490         filehandle = io.smb2.out.file.handle;
1491
1492         ZERO_STRUCT(finfo);
1493         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1494         finfo.generic.in.file.handle = filehandle;
1495         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1496         CHECK_STATUS(status, NT_STATUS_OK);
1497         if (finfo.all_info.out.size != 1) {
1498                 torture_result(tctx, TORTURE_FAIL,
1499                                "(%s) Incorrect resource fork size\n",
1500                                __location__);
1501                 ret = false;
1502                 smb2_util_close(tree, filehandle);
1503                 goto done;
1504         }
1505         smb2_util_close(tree, filehandle);
1506
1507 done:
1508         smb2_util_unlink(tree, fname);
1509         smb2_deltree(tree, BASEDIR);
1510         talloc_free(mem_ctx);
1511         return ret;
1512 }
1513
1514 static bool test_rfork_truncate(struct torture_context *tctx,
1515                                 struct smb2_tree *tree)
1516 {
1517         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1518         const char *fname = BASEDIR "\\torture_rfork_truncate";
1519         const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
1520         const char *rfork_content = "1234567890";
1521         NTSTATUS status;
1522         struct smb2_handle testdirh;
1523         bool ret = true;
1524         struct smb2_create create;
1525         struct smb2_handle fh1, fh2, fh3;
1526         union smb_setfileinfo sinfo;
1527
1528         smb2_util_unlink(tree, fname);
1529
1530         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1531         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1532         smb2_util_close(tree, testdirh);
1533
1534         ret = torture_setup_file(mem_ctx, tree, fname, false);
1535         if (ret == false) {
1536                 goto done;
1537         }
1538
1539         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1540                             fname, AFPRESOURCE_STREAM,
1541                             10, 10, rfork_content);
1542
1543         /* Truncate back to size 0, further access MUST return ENOENT */
1544
1545         torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
1546                         __location__);
1547
1548         ZERO_STRUCT(create);
1549         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1550         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1551         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1552         create.in.fname               = fname;
1553         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1554                 NTCREATEX_SHARE_ACCESS_READ |
1555                 NTCREATEX_SHARE_ACCESS_WRITE;
1556         status = smb2_create(tree, mem_ctx, &create);
1557         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1558         fh1 = create.out.file.handle;
1559
1560         ZERO_STRUCT(create);
1561         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1562         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1563         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1564         create.in.fname               = rfork;
1565         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1566                 NTCREATEX_SHARE_ACCESS_READ |
1567                 NTCREATEX_SHARE_ACCESS_WRITE;
1568         status = smb2_create(tree, mem_ctx, &create);
1569         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1570         fh2 = create.out.file.handle;
1571
1572         ZERO_STRUCT(sinfo);
1573         sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1574         sinfo.end_of_file_info.in.file.handle = fh2;
1575         sinfo.end_of_file_info.in.size = 0;
1576         status = smb2_setinfo_file(tree, &sinfo);
1577         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
1578
1579         /*
1580          * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
1581          */
1582         ZERO_STRUCT(create);
1583         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1584         create.in.desired_access      = SEC_FILE_ALL;
1585         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1586         create.in.fname               = rfork;
1587         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1588                 NTCREATEX_SHARE_ACCESS_READ |
1589                 NTCREATEX_SHARE_ACCESS_WRITE;
1590         status = smb2_create(tree, mem_ctx, &create);
1591         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1592
1593         /*
1594          * Do another open on the rfork and write to the new handle. A
1595          * naive server might unlink the AppleDouble resource fork
1596          * file when its truncated to 0 bytes above, so in case both
1597          * open handles share the same underlying fd, the unlink would
1598          * cause the below write to be lost.
1599          */
1600         ZERO_STRUCT(create);
1601         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1602         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1603         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1604         create.in.fname               = rfork;
1605         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1606                 NTCREATEX_SHARE_ACCESS_READ |
1607                 NTCREATEX_SHARE_ACCESS_WRITE;
1608         status = smb2_create(tree, mem_ctx, &create);
1609         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1610         fh3 = create.out.file.handle;
1611
1612         status = smb2_util_write(tree, fh3, "foo", 0, 3);
1613         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
1614
1615         smb2_util_close(tree, fh3);
1616         smb2_util_close(tree, fh2);
1617         smb2_util_close(tree, fh1);
1618
1619         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
1620                            0, 3, 0, 3, "foo");
1621         torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1622
1623 done:
1624         smb2_util_unlink(tree, fname);
1625         smb2_deltree(tree, BASEDIR);
1626         talloc_free(mem_ctx);
1627         return ret;
1628 }
1629
1630 static bool test_rfork_create(struct torture_context *tctx,
1631                               struct smb2_tree *tree)
1632 {
1633         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1634         const char *fname = BASEDIR "\\torture_rfork_create";
1635         const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1636         NTSTATUS status;
1637         struct smb2_handle testdirh;
1638         bool ret = true;
1639         struct smb2_create create;
1640         struct smb2_handle fh1;
1641         const char *streams[] = {
1642                 "::$DATA"
1643         };
1644         union smb_fileinfo finfo;
1645
1646         smb2_util_unlink(tree, fname);
1647
1648         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1649         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1650         smb2_util_close(tree, testdirh);
1651
1652         ret = torture_setup_file(mem_ctx, tree, fname, false);
1653         if (ret == false) {
1654                 goto done;
1655         }
1656
1657         torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
1658                         __location__);
1659
1660         ZERO_STRUCT(create);
1661         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1662         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1663         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1664         create.in.fname               = rfork;
1665         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1666                 NTCREATEX_SHARE_ACCESS_READ |
1667                 NTCREATEX_SHARE_ACCESS_WRITE;
1668         status = smb2_create(tree, mem_ctx, &create);
1669         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1670
1671         torture_comment(tctx, "(%s) create resource fork\n", __location__);
1672
1673         ZERO_STRUCT(create);
1674         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1675         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1676         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1677         create.in.fname               = rfork;
1678         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1679                 NTCREATEX_SHARE_ACCESS_READ |
1680                 NTCREATEX_SHARE_ACCESS_WRITE;
1681         status = smb2_create(tree, mem_ctx, &create);
1682         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1683         fh1 = create.out.file.handle;
1684
1685         torture_comment(tctx, "(%s) getinfo on create handle\n",
1686                         __location__);
1687
1688         ZERO_STRUCT(finfo);
1689         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1690         finfo.generic.in.file.handle = fh1;
1691         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1692         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
1693         if (finfo.all_info.out.size != 0) {
1694                 torture_result(tctx, TORTURE_FAIL,
1695                                "(%s) Incorrect resource fork size\n",
1696                                __location__);
1697                 ret = false;
1698                 smb2_util_close(tree, fh1);
1699                 goto done;
1700         }
1701
1702         torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
1703                         __location__);
1704
1705         ZERO_STRUCT(create);
1706         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1707         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1708         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1709         create.in.fname               = rfork;
1710         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1711                 NTCREATEX_SHARE_ACCESS_READ |
1712                 NTCREATEX_SHARE_ACCESS_WRITE;
1713         status = smb2_create(tree, mem_ctx, &create);
1714         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1715
1716         ret = check_stream_list(tree, tctx, fname, 1, streams, false);
1717         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
1718
1719         torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
1720                         __location__);
1721
1722         ZERO_STRUCT(create);
1723         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1724         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1725         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1726         create.in.fname               = rfork;
1727         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1728                 NTCREATEX_SHARE_ACCESS_READ |
1729                 NTCREATEX_SHARE_ACCESS_WRITE;
1730         status = smb2_create(tree, mem_ctx, &create);
1731         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1732
1733 done:
1734         smb2_util_unlink(tree, fname);
1735         smb2_deltree(tree, BASEDIR);
1736         talloc_free(mem_ctx);
1737         return ret;
1738 }
1739
1740 static bool test_adouble_conversion(struct torture_context *tctx,
1741                                     struct smb2_tree *tree)
1742 {
1743         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1744         const char *fname = BASEDIR "\\test_adouble_conversion";
1745         const char *fname_local = BASEDIR "/test_adouble_conversion";
1746         const char *adname_local = BASEDIR "/._test_adouble_conversion";
1747         NTSTATUS status;
1748         struct smb2_handle testdirh;
1749         bool ret = true;
1750         const char *data = "This resource fork intentionally left blank";
1751         size_t datalen = strlen(data);
1752         const char *localdir = NULL;
1753
1754         localdir = torture_setting_string(tctx, "localdir", NULL);
1755         if (localdir == NULL) {
1756                 torture_skip(tctx, "Need localdir for test");
1757         }
1758
1759         smb2_util_unlink(tree, fname);
1760
1761         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1762         CHECK_STATUS(status, NT_STATUS_OK);
1763         smb2_util_close(tree, testdirh);
1764
1765         ret = torture_setup_local_file(tctx, "localdir", fname_local,
1766                                        NULL, 0);
1767         if (ret == false) {
1768                 goto done;
1769         }
1770
1771         ret = torture_setup_local_file(tctx, "localdir", adname_local,
1772                                        osx_adouble_w_xattr,
1773                                        sizeof(osx_adouble_w_xattr));
1774         if (ret == false) {
1775                 goto done;
1776         }
1777
1778         torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
1779             __location__);
1780
1781         ret &= check_stream(tree, __location__, tctx, mem_ctx,
1782                             fname, AFPRESOURCE_STREAM,
1783                             16, datalen, 0, datalen, data);
1784
1785 done:
1786         smb2_deltree(tree, BASEDIR);
1787         talloc_free(mem_ctx);
1788         return ret;
1789 }
1790
1791 static bool test_aapl(struct torture_context *tctx,
1792                       struct smb2_tree *tree)
1793 {
1794         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1795         const char *fname = BASEDIR "\\test_aapl";
1796         NTSTATUS status;
1797         struct smb2_handle testdirh;
1798         bool ret = true;
1799         struct smb2_create io;
1800         DATA_BLOB data;
1801         struct smb2_create_blob *aapl = NULL;
1802         AfpInfo *info;
1803         const char *type_creator = "SMB,OLE!";
1804         char type_creator_buf[9];
1805         uint32_t aapl_cmd;
1806         uint32_t aapl_reply_bitmap;
1807         uint32_t aapl_server_caps;
1808         uint32_t aapl_vol_caps;
1809         char *model;
1810         struct smb2_find f;
1811         unsigned int count;
1812         union smb_search_data *d;
1813         uint64_t rfork_len;
1814
1815         smb2_deltree(tree, BASEDIR);
1816
1817         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1818         CHECK_STATUS(status, NT_STATUS_OK);
1819         smb2_util_close(tree, testdirh);
1820
1821         ZERO_STRUCT(io);
1822         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
1823         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
1824         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1825         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1826                               NTCREATEX_SHARE_ACCESS_READ |
1827                               NTCREATEX_SHARE_ACCESS_WRITE);
1828         io.in.fname = fname;
1829
1830         /*
1831          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1832          * controls behaviour of Apple's SMB2 extensions for the whole
1833          * session!
1834          */
1835
1836         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1837         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1838         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1839                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1840                              SMB2_CRTCTX_AAPL_MODEL_INFO));
1841         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1842                               SMB2_CRTCTX_AAPL_UNIX_BASED |
1843                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1844
1845         torture_comment(tctx, "Testing SMB2 create context AAPL\n");
1846         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1847         CHECK_STATUS(status, NT_STATUS_OK);
1848
1849         status = smb2_create(tree, tctx, &io);
1850         CHECK_STATUS(status, NT_STATUS_OK);
1851         status = smb2_util_close(tree, io.out.file.handle);
1852         CHECK_STATUS(status, NT_STATUS_OK);
1853
1854         /*
1855          * Now check returned AAPL context
1856          */
1857         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1858
1859         aapl = smb2_create_blob_find(&io.out.blobs,
1860                                      SMB2_CREATE_TAG_AAPL);
1861
1862         if (aapl->data.length != 50) {
1863                 /*
1864                  * uint32_t CommandCode = kAAPL_SERVER_QUERY
1865                  * uint32_t Reserved = 0;
1866                  * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
1867                  *                        kAAPL_VOLUME_CAPS |
1868                  *                        kAAPL_MODEL_INFO;
1869                  * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
1870                  *                       kAAPL_SUPPORTS_OSX_COPYFILE;
1871                  * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
1872                  *                       kAAPL_CASE_SENSITIVE;
1873                  * uint32_t Pad2 = 0;
1874                  * uint32_t ModelStringLen = 10;
1875                  * ucs2_t ModelString[5] = "Samba";
1876                  */
1877                 ret = false;
1878                 goto done;
1879         }
1880
1881         aapl_cmd = IVAL(aapl->data.data, 0);
1882         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
1883                 torture_result(tctx, TORTURE_FAIL,
1884                                "(%s) unexpected cmd: %d",
1885                                __location__, (int)aapl_cmd);
1886                 ret = false;
1887                 goto done;
1888         }
1889
1890         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
1891         if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1892                                   SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1893                                   SMB2_CRTCTX_AAPL_MODEL_INFO)) {
1894                 torture_result(tctx, TORTURE_FAIL,
1895                                "(%s) unexpected reply_bitmap: %d",
1896                                __location__, (int)aapl_reply_bitmap);
1897                 ret = false;
1898                 goto done;
1899         }
1900
1901         aapl_server_caps = BVAL(aapl->data.data, 16);
1902         if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
1903                                  SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1904                                  SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1905                                  SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
1906                 torture_result(tctx, TORTURE_FAIL,
1907                                "(%s) unexpected server_caps: %d",
1908                                __location__, (int)aapl_server_caps);
1909                 ret = false;
1910                 goto done;
1911         }
1912
1913         aapl_vol_caps = BVAL(aapl->data.data, 24);
1914         if (aapl_vol_caps != SMB2_CRTCTX_AAPL_CASE_SENSITIVE) {
1915                 /* this will fail on a case insensitive fs ... */
1916                 torture_result(tctx, TORTURE_FAIL,
1917                                "(%s) unexpected vol_caps: %d",
1918                                __location__, (int)aapl_vol_caps);
1919                 ret = false;
1920                 goto done;
1921         }
1922
1923         ret = convert_string_talloc(mem_ctx,
1924                                     CH_UTF16LE, CH_UNIX,
1925                                     aapl->data.data + 40, 10,
1926                                     &model, NULL);
1927         if (ret == false) {
1928                 torture_result(tctx, TORTURE_FAIL,
1929                                "(%s) convert_string_talloc() failed",
1930                                __location__);
1931                 goto done;
1932         }
1933         torture_comment(tctx, "Got server model: \"%s\"\n", model);
1934
1935         /*
1936          * Now that Requested AAPL extensions are enabled, setup some
1937          * Mac files with metadata and resource fork
1938          */
1939         ret = torture_setup_file(mem_ctx, tree, fname, false);
1940         if (ret == false) {
1941                 torture_result(tctx, TORTURE_FAIL,
1942                                "(%s) torture_setup_file() failed",
1943                                __location__);
1944                 goto done;
1945         }
1946
1947         info = torture_afpinfo_new(mem_ctx);
1948         if (info == NULL) {
1949                 torture_result(tctx, TORTURE_FAIL,
1950                                "(%s) torture_afpinfo_new() failed",
1951                                __location__);
1952                 ret = false;
1953                 goto done;
1954         }
1955
1956         memcpy(info->afpi_FinderInfo, type_creator, 8);
1957         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1958         if (ret == false) {
1959                 torture_result(tctx, TORTURE_FAIL,
1960                                "(%s) torture_write_afpinfo() failed",
1961                                __location__);
1962                 goto done;
1963         }
1964
1965         ret = write_stream(tree, __location__, tctx, mem_ctx,
1966                            fname, AFPRESOURCE_STREAM_NAME,
1967                            0, 3, "foo");
1968         if (ret == false) {
1969                 torture_result(tctx, TORTURE_FAIL,
1970                                "(%s) write_stream() failed",
1971                                __location__);
1972                 goto done;
1973         }
1974
1975         /*
1976          * Ok, file is prepared, now call smb2/find
1977          */
1978
1979         ZERO_STRUCT(io);
1980         io.in.desired_access = SEC_RIGHTS_DIR_ALL;
1981         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1982         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1983         io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
1984                               NTCREATEX_SHARE_ACCESS_WRITE |
1985                               NTCREATEX_SHARE_ACCESS_DELETE);
1986         io.in.create_disposition = NTCREATEX_DISP_OPEN;
1987         io.in.fname = BASEDIR;
1988         status = smb2_create(tree, tctx, &io);
1989         CHECK_STATUS(status, NT_STATUS_OK);
1990
1991         ZERO_STRUCT(f);
1992         f.in.file.handle        = io.out.file.handle;
1993         f.in.pattern            = "test_aapl";
1994         f.in.continue_flags     = SMB2_CONTINUE_FLAG_SINGLE;
1995         f.in.max_response_size  = 0x1000;
1996         f.in.level              = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
1997
1998         status = smb2_find_level(tree, tree, &f, &count, &d);
1999         CHECK_STATUS(status, NT_STATUS_OK);
2000
2001         status = smb2_util_close(tree, io.out.file.handle);
2002         CHECK_STATUS(status, NT_STATUS_OK);
2003
2004         if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2005                 torture_result(tctx, TORTURE_FAIL,
2006                                "(%s) write_stream() failed",
2007                                __location__);
2008                 ret = false;
2009                 goto done;
2010         }
2011
2012         if (d[0].id_both_directory_info.short_name.private_length != 24) {
2013                 torture_result(tctx, TORTURE_FAIL,
2014                                "(%s) bad short_name length %" PRIu32 ", expected 24",
2015                                __location__, d[0].id_both_directory_info.short_name.private_length);
2016                 ret = false;
2017                 goto done;
2018         }
2019
2020         torture_comment(tctx, "short_name buffer:\n");
2021         dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2022
2023         /*
2024          * Extract data as specified by the AAPL extension:
2025          * - ea_size contains max_access
2026          * - short_name contains resource fork length + FinderInfo
2027          * - reserved2 contains the unix mode
2028          */
2029         torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2030                         d[0].id_both_directory_info.ea_size);
2031
2032         rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2033         if (rfork_len != 3) {
2034                 torture_result(tctx, TORTURE_FAIL,
2035                                "(%s) expected resource fork length 3, got: %" PRIu64,
2036                                __location__, rfork_len);
2037                 ret = false;
2038                 goto done;
2039         }
2040
2041         memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2042         type_creator_buf[8] = 0;
2043         if (strcmp(type_creator, type_creator_buf) != 0) {
2044                 torture_result(tctx, TORTURE_FAIL,
2045                                "(%s) expected type/creator \"%s\" , got: %s",
2046                                __location__, type_creator, type_creator_buf);
2047                 ret = false;
2048                 goto done;
2049         }
2050
2051 done:
2052         smb2_util_unlink(tree, fname);
2053         smb2_deltree(tree, BASEDIR);
2054         talloc_free(mem_ctx);
2055         return ret;
2056 }
2057
2058 static uint64_t patt_hash(uint64_t off)
2059 {
2060         return off;
2061 }
2062
2063 static bool write_pattern(struct torture_context *torture,
2064                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2065                           struct smb2_handle h, uint64_t off, uint64_t len,
2066                           uint64_t patt_off)
2067 {
2068         NTSTATUS status;
2069         uint64_t i;
2070         uint8_t *buf;
2071         uint64_t io_sz = MIN(1024 * 64, len);
2072
2073         if (len == 0) {
2074                 return true;
2075         }
2076
2077         torture_assert(torture, (len % 8) == 0, "invalid write len");
2078
2079         buf = talloc_zero_size(mem_ctx, io_sz);
2080         torture_assert(torture, (buf != NULL), "no memory for file data buf");
2081
2082         while (len > 0) {
2083                 for (i = 0; i <= io_sz - 8; i += 8) {
2084                         SBVAL(buf, i, patt_hash(patt_off));
2085                         patt_off += 8;
2086                 }
2087
2088                 status = smb2_util_write(tree, h,
2089                                          buf, off, io_sz);
2090                 torture_assert_ntstatus_ok(torture, status, "file write");
2091
2092                 len -= io_sz;
2093                 off += io_sz;
2094         }
2095
2096         talloc_free(buf);
2097
2098         return true;
2099 }
2100
2101 static bool check_pattern(struct torture_context *torture,
2102                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2103                           struct smb2_handle h, uint64_t off, uint64_t len,
2104                           uint64_t patt_off)
2105 {
2106         if (len == 0) {
2107                 return true;
2108         }
2109
2110         torture_assert(torture, (len % 8) == 0, "invalid read len");
2111
2112         while (len > 0) {
2113                 uint64_t i;
2114                 struct smb2_read r;
2115                 NTSTATUS status;
2116                 uint64_t io_sz = MIN(1024 * 64, len);
2117
2118                 ZERO_STRUCT(r);
2119                 r.in.file.handle = h;
2120                 r.in.length      = io_sz;
2121                 r.in.offset      = off;
2122                 status = smb2_read(tree, mem_ctx, &r);
2123                 torture_assert_ntstatus_ok(torture, status, "read");
2124
2125                 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2126                                          "read data len mismatch");
2127
2128                 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2129                         uint64_t data = BVAL(r.out.data.data, i);
2130                         torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2131                                                  talloc_asprintf(torture, "read data "
2132                                                                  "pattern bad at %llu\n",
2133                                                                  (unsigned long long)off + i));
2134                 }
2135                 talloc_free(r.out.data.data);
2136                 len -= io_sz;
2137                 off += io_sz;
2138         }
2139
2140         return true;
2141 }
2142
2143 static bool test_setup_open(struct torture_context *torture,
2144                             struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2145                             const char *fname,
2146                             struct smb2_handle *fh,
2147                             uint32_t desired_access,
2148                             uint32_t file_attributes)
2149 {
2150         struct smb2_create io;
2151         NTSTATUS status;
2152
2153         ZERO_STRUCT(io);
2154         io.in.desired_access = desired_access;
2155         io.in.file_attributes = file_attributes;
2156         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2157         io.in.share_access =
2158                 NTCREATEX_SHARE_ACCESS_DELETE|
2159                 NTCREATEX_SHARE_ACCESS_READ|
2160                 NTCREATEX_SHARE_ACCESS_WRITE;
2161         if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2162                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2163         }
2164         io.in.fname = fname;
2165
2166         status = smb2_create(tree, mem_ctx, &io);
2167         torture_assert_ntstatus_ok(torture, status, "file create");
2168
2169         *fh = io.out.file.handle;
2170
2171         return true;
2172 }
2173
2174 static bool test_setup_create_fill(struct torture_context *torture,
2175                                    struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2176                                    const char *fname,
2177                                    struct smb2_handle *fh,
2178                                    uint64_t size,
2179                                    uint32_t desired_access,
2180                                    uint32_t file_attributes)
2181 {
2182         bool ok;
2183
2184         ok = test_setup_open(torture, tree, mem_ctx,
2185                              fname,
2186                              fh,
2187                              desired_access,
2188                              file_attributes);
2189         torture_assert(torture, ok, "file open");
2190
2191         if (size > 0) {
2192                 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2193                 torture_assert(torture, ok, "write pattern");
2194         }
2195         return true;
2196 }
2197
2198 static bool test_setup_copy_chunk(struct torture_context *torture,
2199                                   struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2200                                   uint32_t nchunks,
2201                                   struct smb2_handle *src_h,
2202                                   uint64_t src_size,
2203                                   uint32_t src_desired_access,
2204                                   struct smb2_handle *dest_h,
2205                                   uint64_t dest_size,
2206                                   uint32_t dest_desired_access,
2207                                   struct srv_copychunk_copy *cc_copy,
2208                                   union smb_ioctl *io)
2209 {
2210         struct req_resume_key_rsp res_key;
2211         bool ok;
2212         NTSTATUS status;
2213         enum ndr_err_code ndr_ret;
2214
2215         ok = test_setup_create_fill(torture, tree, mem_ctx, FNAME_CC_SRC,
2216                                     src_h, src_size, src_desired_access,
2217                                     FILE_ATTRIBUTE_NORMAL);
2218         torture_assert(torture, ok, "src file create fill");
2219
2220         ok = test_setup_create_fill(torture, tree, mem_ctx, FNAME_CC_DST,
2221                                     dest_h, dest_size, dest_desired_access,
2222                                     FILE_ATTRIBUTE_NORMAL);
2223         torture_assert(torture, ok, "dest file create fill");
2224
2225         ZERO_STRUCTPN(io);
2226         io->smb2.level = RAW_IOCTL_SMB2;
2227         io->smb2.in.file.handle = *src_h;
2228         io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2229         /* Allow for Key + ContextLength + Context */
2230         io->smb2.in.max_response_size = 32;
2231         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2232
2233         status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2234         torture_assert_ntstatus_ok(torture, status,
2235                                    "FSCTL_SRV_REQUEST_RESUME_KEY");
2236
2237         ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2238                         (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2239
2240         torture_assert_ndr_success(torture, ndr_ret,
2241                                    "ndr_pull_req_resume_key_rsp");
2242
2243         ZERO_STRUCTPN(io);
2244         io->smb2.level = RAW_IOCTL_SMB2;
2245         io->smb2.in.file.handle = *dest_h;
2246         io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2247         io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2248         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2249
2250         ZERO_STRUCTPN(cc_copy);
2251         memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2252         cc_copy->chunk_count = nchunks;
2253         cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2254         torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2255
2256         return true;
2257 }
2258
2259
2260 static bool check_copy_chunk_rsp(struct torture_context *torture,
2261                                  struct srv_copychunk_rsp *cc_rsp,
2262                                  uint32_t ex_chunks_written,
2263                                  uint32_t ex_chunk_bytes_written,
2264                                  uint32_t ex_total_bytes_written)
2265 {
2266         torture_assert_int_equal(torture, cc_rsp->chunks_written,
2267                                  ex_chunks_written, "num chunks");
2268         torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2269                                  ex_chunk_bytes_written, "chunk bytes written");
2270         torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2271                                  ex_total_bytes_written, "chunk total bytes");
2272         return true;
2273 }
2274
2275 static bool neg_aapl_copyfile(struct torture_context *tctx,
2276                               struct smb2_tree *tree,
2277                               uint64_t flags)
2278 {
2279         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2280         const char *fname = "aapl";
2281         NTSTATUS status;
2282         struct smb2_create io;
2283         DATA_BLOB data;
2284         struct smb2_create_blob *aapl = NULL;
2285         uint32_t aapl_cmd;
2286         uint32_t aapl_reply_bitmap;
2287         uint32_t aapl_server_caps;
2288         bool ret = true;
2289
2290         ZERO_STRUCT(io);
2291         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
2292         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
2293         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2294         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2295                               NTCREATEX_SHARE_ACCESS_READ |
2296                               NTCREATEX_SHARE_ACCESS_WRITE);
2297         io.in.fname = fname;
2298
2299         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2300         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2301         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2302         SBVAL(data.data, 16, flags);
2303
2304         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2305         CHECK_STATUS(status, NT_STATUS_OK);
2306
2307         status = smb2_create(tree, tctx, &io);
2308         CHECK_STATUS(status, NT_STATUS_OK);
2309
2310         aapl = smb2_create_blob_find(&io.out.blobs,
2311                                      SMB2_CREATE_TAG_AAPL);
2312         if (aapl == NULL) {
2313                 ret = false;
2314                 goto done;
2315
2316         }
2317         if (aapl->data.length < 24) {
2318                 ret = false;
2319                 goto done;
2320         }
2321
2322         aapl_cmd = IVAL(aapl->data.data, 0);
2323         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2324                 torture_result(tctx, TORTURE_FAIL,
2325                                "(%s) unexpected cmd: %d",
2326                                __location__, (int)aapl_cmd);
2327                 ret = false;
2328                 goto done;
2329         }
2330
2331         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2332         if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2333                 torture_result(tctx, TORTURE_FAIL,
2334                                "(%s) unexpected reply_bitmap: %d",
2335                                __location__, (int)aapl_reply_bitmap);
2336                 ret = false;
2337                 goto done;
2338         }
2339
2340         aapl_server_caps = BVAL(aapl->data.data, 16);
2341         if (!(aapl_server_caps & flags)) {
2342                 torture_result(tctx, TORTURE_FAIL,
2343                                "(%s) unexpected server_caps: %d",
2344                                __location__, (int)aapl_server_caps);
2345                 ret = false;
2346                 goto done;
2347         }
2348
2349 done:
2350         status = smb2_util_close(tree, io.out.file.handle);
2351         CHECK_STATUS(status, NT_STATUS_OK);
2352
2353         smb2_util_unlink(tree, "aapl");
2354         talloc_free(mem_ctx);
2355         return ret;
2356 }
2357
2358 static bool test_copyfile(struct torture_context *torture,
2359                           struct smb2_tree *tree)
2360 {
2361         struct smb2_handle src_h;
2362         struct smb2_handle dest_h;
2363         NTSTATUS status;
2364         union smb_ioctl io;
2365         TALLOC_CTX *tmp_ctx = talloc_new(tree);
2366         struct srv_copychunk_copy cc_copy;
2367         struct srv_copychunk_rsp cc_rsp;
2368         enum ndr_err_code ndr_ret;
2369         bool ok;
2370
2371         /*
2372          * First test a copy_chunk with a 0 chunk count without having
2373          * enabled this via AAPL. The request must not fail and the
2374          * copied length in the response must be 0. This is verified
2375          * against Windows 2008r2.
2376          */
2377
2378         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2379                                    0, /* 0 chunks, copyfile semantics */
2380                                    &src_h, 4096, /* fill 4096 byte src file */
2381                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2382                                    &dest_h, 0,  /* 0 byte dest file */
2383                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2384                                    &cc_copy,
2385                                    &io);
2386         if (!ok) {
2387                 torture_fail_goto(torture, done, "setup copy chunk error");
2388         }
2389
2390         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2391                                        &cc_copy,
2392                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2393         torture_assert_ndr_success(torture, ndr_ret,
2394                                    "ndr_push_srv_copychunk_copy");
2395
2396         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2397         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2398
2399         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2400                                        &cc_rsp,
2401                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2402         torture_assert_ndr_success(torture, ndr_ret,
2403                                    "ndr_pull_srv_copychunk_rsp");
2404
2405         ok = check_copy_chunk_rsp(torture, &cc_rsp,
2406                                   0,    /* chunks written */
2407                                   0,    /* chunk bytes unsuccessfully written */
2408                                   0); /* total bytes written */
2409         if (!ok) {
2410                 torture_fail_goto(torture, done, "bad copy chunk response data");
2411         }
2412
2413         /*
2414          * Now enable AAPL copyfile and test again, the file and the
2415          * stream must be copied by the server.
2416          */
2417         ok = neg_aapl_copyfile(torture, tree,
2418                                SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2419         if (!ok) {
2420                 torture_skip_goto(torture, done, "missing AAPL copyfile");
2421                 goto done;
2422         }
2423
2424         smb2_util_close(tree, src_h);
2425         smb2_util_close(tree, dest_h);
2426         smb2_util_unlink(tree, FNAME_CC_SRC);
2427         smb2_util_unlink(tree, FNAME_CC_DST);
2428
2429         ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2430         if (!ok) {
2431                 torture_fail(torture, "setup file error");
2432         }
2433         ok = write_stream(tree, __location__, torture, tmp_ctx,
2434                             FNAME_CC_SRC, AFPRESOURCE_STREAM,
2435                             10, 10, "1234567890");
2436         if (!ok) {
2437                 torture_fail(torture, "setup stream error");
2438         }
2439
2440         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2441                                    0, /* 0 chunks, copyfile semantics */
2442                                    &src_h, 4096, /* fill 4096 byte src file */
2443                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2444                                    &dest_h, 0,  /* 0 byte dest file */
2445                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2446                                    &cc_copy,
2447                                    &io);
2448         if (!ok) {
2449                 torture_fail_goto(torture, done, "setup copy chunk error");
2450         }
2451
2452         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2453                                        &cc_copy,
2454                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2455         torture_assert_ndr_success(torture, ndr_ret,
2456                                    "ndr_push_srv_copychunk_copy");
2457
2458         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2459         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2460
2461         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2462                                        &cc_rsp,
2463                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2464         torture_assert_ndr_success(torture, ndr_ret,
2465                                    "ndr_pull_srv_copychunk_rsp");
2466
2467         ok = check_copy_chunk_rsp(torture, &cc_rsp,
2468                                   0,    /* chunks written */
2469                                   0,    /* chunk bytes unsuccessfully written */
2470                                   4096); /* total bytes written */
2471         if (!ok) {
2472                 torture_fail_goto(torture, done, "bad copy chunk response data");
2473         }
2474
2475         ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
2476                              SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
2477         if (!ok) {
2478                 torture_fail_goto(torture, done,"open failed");
2479         }
2480         ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
2481         if (!ok) {
2482                 torture_fail_goto(torture, done, "inconsistent file data");
2483         }
2484
2485         ok = check_stream(tree, __location__, torture, tmp_ctx,
2486                             FNAME_CC_DST, AFPRESOURCE_STREAM,
2487                             0, 20, 10, 10, "1234567890");
2488         if (!ok) {
2489                 torture_fail_goto(torture, done, "inconsistent stream data");
2490         }
2491
2492 done:
2493         smb2_util_close(tree, src_h);
2494         smb2_util_close(tree, dest_h);
2495         smb2_util_unlink(tree, FNAME_CC_SRC);
2496         smb2_util_unlink(tree, FNAME_CC_DST);
2497         talloc_free(tmp_ctx);
2498         return true;
2499 }
2500
2501 static bool check_stream_list(struct smb2_tree *tree,
2502                               struct torture_context *tctx,
2503                               const char *fname,
2504                               int num_exp,
2505                               const char **exp,
2506                               bool is_dir)
2507 {
2508         bool ret = true;
2509         union smb_fileinfo finfo;
2510         NTSTATUS status;
2511         int i;
2512         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
2513         char **exp_sort;
2514         struct stream_struct *stream_sort;
2515         struct smb2_create create;
2516         struct smb2_handle h;
2517
2518         ZERO_STRUCT(h);
2519         torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
2520
2521         ZERO_STRUCT(create);
2522         create.in.fname = fname;
2523         create.in.create_disposition = NTCREATEX_DISP_OPEN;
2524         create.in.desired_access = SEC_FILE_ALL;
2525         create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
2526         create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
2527         status = smb2_create(tree, tmp_ctx, &create);
2528         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2529         h = create.out.file.handle;
2530
2531         finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
2532         finfo.generic.in.file.handle = h;
2533
2534         status = smb2_getinfo_file(tree, tctx, &finfo);
2535         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
2536
2537         smb2_util_close(tree, h);
2538
2539         torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
2540                                       ret, done, "stream count");
2541
2542         if (num_exp == 0) {
2543                 TALLOC_FREE(tmp_ctx);
2544                 goto done;
2545         }
2546
2547         exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
2548         torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
2549
2550         TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
2551
2552         stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
2553                                     finfo.stream_info.out.num_streams *
2554                                     sizeof(*stream_sort));
2555         torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
2556
2557         TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
2558
2559         for (i=0; i<num_exp; i++) {
2560                 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
2561                                 i, exp_sort[i], stream_sort[i].stream_name.s);
2562                 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
2563                                               ret, done, "stream name");
2564         }
2565
2566 done:
2567         TALLOC_FREE(tmp_ctx);
2568         return ret;
2569 }
2570
2571 /*
2572   test stream names
2573 */
2574 static bool test_stream_names(struct torture_context *tctx,
2575                               struct smb2_tree *tree)
2576 {
2577         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2578         NTSTATUS status;
2579         struct smb2_create create;
2580         struct smb2_handle h;
2581         const char *fname = BASEDIR "\\stream_names.txt";
2582         const char *sname1;
2583         bool ret;
2584         /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
2585         const char *streams[] = {
2586                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2587                 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
2588                 "::$DATA"
2589         };
2590
2591         sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
2592
2593         /* clean slate ...*/
2594         smb2_util_unlink(tree, fname);
2595         smb2_deltree(tree, fname);
2596         smb2_deltree(tree, BASEDIR);
2597
2598         status = torture_smb2_testdir(tree, BASEDIR, &h);
2599         CHECK_STATUS(status, NT_STATUS_OK);
2600         smb2_util_close(tree, h);
2601
2602         torture_comment(tctx, "(%s) testing stream names\n", __location__);
2603         ZERO_STRUCT(create);
2604         create.in.desired_access = SEC_FILE_WRITE_DATA;
2605         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2606         create.in.share_access =
2607                 NTCREATEX_SHARE_ACCESS_DELETE|
2608                 NTCREATEX_SHARE_ACCESS_READ|
2609                 NTCREATEX_SHARE_ACCESS_WRITE;
2610         create.in.create_disposition = NTCREATEX_DISP_CREATE;
2611         create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2612         create.in.fname = sname1;
2613
2614         status = smb2_create(tree, mem_ctx, &create);
2615         CHECK_STATUS(status, NT_STATUS_OK);
2616         smb2_util_close(tree, create.out.file.handle);
2617
2618         ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
2619                                         "user.DosStream.bar:baz:$DATA",
2620                                         "data", strlen("data"));
2621         CHECK_VALUE(ret, true);
2622
2623         ret = check_stream_list(tree, tctx, fname, 3, streams, false);
2624         CHECK_VALUE(ret, true);
2625
2626 done:
2627         status = smb2_util_unlink(tree, fname);
2628         smb2_deltree(tree, BASEDIR);
2629         talloc_free(mem_ctx);
2630
2631         return ret;
2632 }
2633
2634 /* Renaming a directory with open file, should work for OS X AAPL clients */
2635 static bool test_rename_dir_openfile(struct torture_context *torture,
2636                                      struct smb2_tree *tree)
2637 {
2638         bool ret = true;
2639         NTSTATUS status;
2640         union smb_open io;
2641         union smb_close cl;
2642         union smb_setfileinfo sinfo;
2643         struct smb2_handle d1, h1;
2644         const char *renamedir = BASEDIR "-new";
2645
2646         smb2_deltree(tree, BASEDIR);
2647         smb2_util_rmdir(tree, BASEDIR);
2648         smb2_deltree(tree, renamedir);
2649
2650         ZERO_STRUCT(io.smb2);
2651         io.generic.level = RAW_OPEN_SMB2;
2652         io.smb2.in.create_flags = 0;
2653         io.smb2.in.desired_access = 0x0017019f;
2654         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2655         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2656         io.smb2.in.share_access = 0;
2657         io.smb2.in.alloc_size = 0;
2658         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2659         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2660         io.smb2.in.security_flags = 0;
2661         io.smb2.in.fname = BASEDIR;
2662
2663         status = smb2_create(tree, torture, &(io.smb2));
2664         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2665         d1 = io.smb2.out.file.handle;
2666
2667         ZERO_STRUCT(io.smb2);
2668         io.generic.level = RAW_OPEN_SMB2;
2669         io.smb2.in.create_flags = 0;
2670         io.smb2.in.desired_access = 0x0017019f;
2671         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2672         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2673         io.smb2.in.share_access = 0;
2674         io.smb2.in.alloc_size = 0;
2675         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2676         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2677         io.smb2.in.security_flags = 0;
2678         io.smb2.in.fname = BASEDIR "\\file.txt";
2679
2680         status = smb2_create(tree, torture, &(io.smb2));
2681         torture_assert_ntstatus_ok(torture, status, "smb2_create file");
2682         h1 = io.smb2.out.file.handle;
2683
2684         torture_comment(torture, "Renaming directory without AAPL, must fail\n");
2685
2686         ZERO_STRUCT(sinfo);
2687         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2688         sinfo.rename_information.in.file.handle = d1;
2689         sinfo.rename_information.in.overwrite = 0;
2690         sinfo.rename_information.in.root_fid = 0;
2691         sinfo.rename_information.in.new_name = renamedir;
2692         status = smb2_setinfo_file(tree, &sinfo);
2693         torture_assert_ntstatus_equal(torture, status, NT_STATUS_ACCESS_DENIED,
2694                                       "smb2_setinfo_file");
2695
2696         ZERO_STRUCT(cl.smb2);
2697         cl.smb2.level = RAW_CLOSE_SMB2;
2698         cl.smb2.in.file.handle = d1;
2699         status = smb2_close(tree, &(cl.smb2));
2700         torture_assert_ntstatus_ok(torture, status, "smb2_close");
2701         ZERO_STRUCT(d1);
2702
2703         torture_comment(torture, "Enabling AAPL\n");
2704
2705         ret = enable_aapl(torture, tree);
2706         torture_assert(torture, ret == true, "enable_aapl failed");
2707
2708         torture_comment(torture, "Renaming directory with AAPL\n");
2709
2710         ZERO_STRUCT(io.smb2);
2711         io.generic.level = RAW_OPEN_SMB2;
2712         io.smb2.in.desired_access = 0x0017019f;
2713         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2714         io.smb2.in.share_access = 0;
2715         io.smb2.in.alloc_size = 0;
2716         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
2717         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2718         io.smb2.in.security_flags = 0;
2719         io.smb2.in.fname = BASEDIR;
2720
2721         status = smb2_create(tree, torture, &(io.smb2));
2722         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2723         d1 = io.smb2.out.file.handle;
2724
2725         ZERO_STRUCT(io.smb2);
2726         io.generic.level = RAW_OPEN_SMB2;
2727         io.smb2.in.desired_access = 0x0017019f;
2728         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2729         io.smb2.in.share_access = 0;
2730         io.smb2.in.alloc_size = 0;
2731         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
2732         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2733         io.smb2.in.security_flags = 0;
2734         io.smb2.in.fname = BASEDIR;
2735         sinfo.rename_information.in.file.handle = d1;
2736
2737         status = smb2_setinfo_file(tree, &sinfo);
2738         torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
2739
2740         ZERO_STRUCT(cl.smb2);
2741         cl.smb2.level = RAW_CLOSE_SMB2;
2742         cl.smb2.in.file.handle = d1;
2743         status = smb2_close(tree, &(cl.smb2));
2744         torture_assert_ntstatus_ok(torture, status, "smb2_close");
2745         ZERO_STRUCT(d1);
2746
2747         cl.smb2.in.file.handle = h1;
2748         status = smb2_close(tree, &(cl.smb2));
2749         torture_assert_ntstatus_ok(torture, status, "smb2_close");
2750         ZERO_STRUCT(h1);
2751
2752         torture_comment(torture, "Cleaning up\n");
2753
2754         if (h1.data) {
2755                 ZERO_STRUCT(cl.smb2);
2756                 cl.smb2.level = RAW_CLOSE_SMB2;
2757                 cl.smb2.in.file.handle = h1;
2758                 status = smb2_close(tree, &(cl.smb2));
2759         }
2760
2761         smb2_util_unlink(tree, BASEDIR "\\file.txt");
2762         smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
2763         smb2_deltree(tree, renamedir);
2764         smb2_deltree(tree, BASEDIR);
2765         return ret;
2766 }
2767
2768 /*
2769  * Note: This test depends on "vfs objects = catia fruit streams_xattr".  For
2770  * some tests torture must be run on the host it tests and takes an additional
2771  * argument with the local path to the share:
2772  * "--option=torture:localdir=<SHAREPATH>".
2773  *
2774  * When running against an OS X SMB server add "--option=torture:osx=true"
2775  */
2776 struct torture_suite *torture_vfs_fruit(void)
2777 {
2778         struct torture_suite *suite = torture_suite_create(
2779                 talloc_autofree_context(), "fruit");
2780
2781         suite->description = talloc_strdup(suite, "vfs_fruit tests");
2782
2783         torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
2784         torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
2785         torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
2786         torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
2787         torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
2788         torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
2789         torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
2790         torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
2791         torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
2792         torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
2793
2794         return suite;
2795 }