07124769c88b905871d2f8a186a9f93f0fa59af4
[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_ALL;
1466         io.smb2.in.fname = rfork;
1467         status = smb2_create(tree, mem_ctx, &(io.smb2));
1468         CHECK_STATUS(status, NT_STATUS_OK);
1469         filehandle = io.smb2.out.file.handle;
1470
1471         ZERO_STRUCT(sinfo);
1472         sinfo.end_of_file_info.level =
1473                 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1474         sinfo.end_of_file_info.in.file.handle = filehandle;
1475         sinfo.end_of_file_info.in.size = 1;
1476         status = smb2_setinfo_file(tree, &sinfo);
1477         CHECK_STATUS(status, NT_STATUS_OK);
1478
1479         smb2_util_close(tree, filehandle);
1480
1481         /* Now check size */
1482         ZERO_STRUCT(io);
1483         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1484         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1485                 SEC_FILE_WRITE_ATTRIBUTE;
1486         io.smb2.in.fname = rfork;
1487         status = smb2_create(tree, mem_ctx, &(io.smb2));
1488         CHECK_STATUS(status, NT_STATUS_OK);
1489         filehandle = io.smb2.out.file.handle;
1490
1491         ZERO_STRUCT(finfo);
1492         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1493         finfo.generic.in.file.handle = filehandle;
1494         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1495         CHECK_STATUS(status, NT_STATUS_OK);
1496         if (finfo.all_info.out.size != 1) {
1497                 torture_result(tctx, TORTURE_FAIL,
1498                                "(%s) Incorrect resource fork size\n",
1499                                __location__);
1500                 ret = false;
1501                 smb2_util_close(tree, filehandle);
1502                 goto done;
1503         }
1504         smb2_util_close(tree, filehandle);
1505
1506 done:
1507         smb2_util_unlink(tree, fname);
1508         smb2_deltree(tree, BASEDIR);
1509         talloc_free(mem_ctx);
1510         return ret;
1511 }
1512
1513 static bool test_rfork_truncate(struct torture_context *tctx,
1514                                 struct smb2_tree *tree)
1515 {
1516         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1517         const char *fname = BASEDIR "\\torture_rfork_truncate";
1518         const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
1519         const char *rfork_content = "1234567890";
1520         NTSTATUS status;
1521         struct smb2_handle testdirh;
1522         bool ret = true;
1523         struct smb2_create create;
1524         struct smb2_handle fh1, fh2, fh3;
1525         union smb_setfileinfo sinfo;
1526
1527         smb2_util_unlink(tree, fname);
1528
1529         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1530         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1531         smb2_util_close(tree, testdirh);
1532
1533         ret = torture_setup_file(mem_ctx, tree, fname, false);
1534         if (ret == false) {
1535                 goto done;
1536         }
1537
1538         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1539                             fname, AFPRESOURCE_STREAM,
1540                             10, 10, rfork_content);
1541
1542         /* Truncate back to size 0, further access MUST return ENOENT */
1543
1544         torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
1545                         __location__);
1546
1547         ZERO_STRUCT(create);
1548         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1549         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1550         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1551         create.in.fname               = fname;
1552         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1553                 NTCREATEX_SHARE_ACCESS_READ |
1554                 NTCREATEX_SHARE_ACCESS_WRITE;
1555         status = smb2_create(tree, mem_ctx, &create);
1556         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1557         fh1 = create.out.file.handle;
1558
1559         ZERO_STRUCT(create);
1560         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1561         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1562         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1563         create.in.fname               = rfork;
1564         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1565                 NTCREATEX_SHARE_ACCESS_READ |
1566                 NTCREATEX_SHARE_ACCESS_WRITE;
1567         status = smb2_create(tree, mem_ctx, &create);
1568         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1569         fh2 = create.out.file.handle;
1570
1571         ZERO_STRUCT(sinfo);
1572         sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1573         sinfo.end_of_file_info.in.file.handle = fh2;
1574         sinfo.end_of_file_info.in.size = 0;
1575         status = smb2_setinfo_file(tree, &sinfo);
1576         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
1577
1578         /*
1579          * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
1580          */
1581         ZERO_STRUCT(create);
1582         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1583         create.in.desired_access      = SEC_FILE_ALL;
1584         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1585         create.in.fname               = rfork;
1586         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1587                 NTCREATEX_SHARE_ACCESS_READ |
1588                 NTCREATEX_SHARE_ACCESS_WRITE;
1589         status = smb2_create(tree, mem_ctx, &create);
1590         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1591
1592         /*
1593          * Do another open on the rfork and write to the new handle. A
1594          * naive server might unlink the AppleDouble resource fork
1595          * file when its truncated to 0 bytes above, so in case both
1596          * open handles share the same underlying fd, the unlink would
1597          * cause the below write to be lost.
1598          */
1599         ZERO_STRUCT(create);
1600         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1601         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1602         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1603         create.in.fname               = rfork;
1604         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1605                 NTCREATEX_SHARE_ACCESS_READ |
1606                 NTCREATEX_SHARE_ACCESS_WRITE;
1607         status = smb2_create(tree, mem_ctx, &create);
1608         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1609         fh3 = create.out.file.handle;
1610
1611         status = smb2_util_write(tree, fh3, "foo", 0, 3);
1612         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
1613
1614         smb2_util_close(tree, fh3);
1615         smb2_util_close(tree, fh2);
1616         smb2_util_close(tree, fh1);
1617
1618         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
1619                            0, 3, 0, 3, "foo");
1620         torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1621
1622 done:
1623         smb2_util_unlink(tree, fname);
1624         smb2_deltree(tree, BASEDIR);
1625         talloc_free(mem_ctx);
1626         return ret;
1627 }
1628
1629 static bool test_rfork_create(struct torture_context *tctx,
1630                               struct smb2_tree *tree)
1631 {
1632         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1633         const char *fname = BASEDIR "\\torture_rfork_create";
1634         const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1635         NTSTATUS status;
1636         struct smb2_handle testdirh;
1637         bool ret = true;
1638         struct smb2_create create;
1639         struct smb2_handle fh1;
1640         const char *streams[] = {
1641                 "::$DATA"
1642         };
1643         union smb_fileinfo finfo;
1644
1645         smb2_util_unlink(tree, fname);
1646
1647         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1648         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1649         smb2_util_close(tree, testdirh);
1650
1651         ret = torture_setup_file(mem_ctx, tree, fname, false);
1652         if (ret == false) {
1653                 goto done;
1654         }
1655
1656         torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
1657                         __location__);
1658
1659         ZERO_STRUCT(create);
1660         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1661         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1662         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1663         create.in.fname               = rfork;
1664         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1665                 NTCREATEX_SHARE_ACCESS_READ |
1666                 NTCREATEX_SHARE_ACCESS_WRITE;
1667         status = smb2_create(tree, mem_ctx, &create);
1668         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1669
1670         torture_comment(tctx, "(%s) create resource fork\n", __location__);
1671
1672         ZERO_STRUCT(create);
1673         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1674         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1675         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1676         create.in.fname               = rfork;
1677         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1678                 NTCREATEX_SHARE_ACCESS_READ |
1679                 NTCREATEX_SHARE_ACCESS_WRITE;
1680         status = smb2_create(tree, mem_ctx, &create);
1681         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1682         fh1 = create.out.file.handle;
1683
1684         torture_comment(tctx, "(%s) getinfo on create handle\n",
1685                         __location__);
1686
1687         ZERO_STRUCT(finfo);
1688         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1689         finfo.generic.in.file.handle = fh1;
1690         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1691         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
1692         if (finfo.all_info.out.size != 0) {
1693                 torture_result(tctx, TORTURE_FAIL,
1694                                "(%s) Incorrect resource fork size\n",
1695                                __location__);
1696                 ret = false;
1697                 smb2_util_close(tree, fh1);
1698                 goto done;
1699         }
1700
1701         torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
1702                         __location__);
1703
1704         ZERO_STRUCT(create);
1705         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1706         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1707         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1708         create.in.fname               = rfork;
1709         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1710                 NTCREATEX_SHARE_ACCESS_READ |
1711                 NTCREATEX_SHARE_ACCESS_WRITE;
1712         status = smb2_create(tree, mem_ctx, &create);
1713         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1714
1715         ret = check_stream_list(tree, tctx, fname, 1, streams, false);
1716         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
1717
1718         torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
1719                         __location__);
1720
1721         ZERO_STRUCT(create);
1722         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1723         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1724         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1725         create.in.fname               = rfork;
1726         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1727                 NTCREATEX_SHARE_ACCESS_READ |
1728                 NTCREATEX_SHARE_ACCESS_WRITE;
1729         status = smb2_create(tree, mem_ctx, &create);
1730         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1731
1732 done:
1733         smb2_util_unlink(tree, fname);
1734         smb2_deltree(tree, BASEDIR);
1735         talloc_free(mem_ctx);
1736         return ret;
1737 }
1738
1739 static bool test_adouble_conversion(struct torture_context *tctx,
1740                                     struct smb2_tree *tree)
1741 {
1742         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1743         const char *fname = BASEDIR "\\test_adouble_conversion";
1744         const char *fname_local = BASEDIR "/test_adouble_conversion";
1745         const char *adname_local = BASEDIR "/._test_adouble_conversion";
1746         NTSTATUS status;
1747         struct smb2_handle testdirh;
1748         bool ret = true;
1749         const char *data = "This resource fork intentionally left blank";
1750         size_t datalen = strlen(data);
1751         const char *localdir = NULL;
1752
1753         localdir = torture_setting_string(tctx, "localdir", NULL);
1754         if (localdir == NULL) {
1755                 torture_skip(tctx, "Need localdir for test");
1756         }
1757
1758         smb2_util_unlink(tree, fname);
1759
1760         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1761         CHECK_STATUS(status, NT_STATUS_OK);
1762         smb2_util_close(tree, testdirh);
1763
1764         ret = torture_setup_local_file(tctx, "localdir", fname_local,
1765                                        NULL, 0);
1766         if (ret == false) {
1767                 goto done;
1768         }
1769
1770         ret = torture_setup_local_file(tctx, "localdir", adname_local,
1771                                        osx_adouble_w_xattr,
1772                                        sizeof(osx_adouble_w_xattr));
1773         if (ret == false) {
1774                 goto done;
1775         }
1776
1777         torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
1778             __location__);
1779
1780         ret &= check_stream(tree, __location__, tctx, mem_ctx,
1781                             fname, AFPRESOURCE_STREAM,
1782                             16, datalen, 0, datalen, data);
1783
1784 done:
1785         smb2_deltree(tree, BASEDIR);
1786         talloc_free(mem_ctx);
1787         return ret;
1788 }
1789
1790 static bool test_aapl(struct torture_context *tctx,
1791                       struct smb2_tree *tree)
1792 {
1793         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1794         const char *fname = BASEDIR "\\test_aapl";
1795         NTSTATUS status;
1796         struct smb2_handle testdirh;
1797         bool ret = true;
1798         struct smb2_create io;
1799         DATA_BLOB data;
1800         struct smb2_create_blob *aapl = NULL;
1801         AfpInfo *info;
1802         const char *type_creator = "SMB,OLE!";
1803         char type_creator_buf[9];
1804         uint32_t aapl_cmd;
1805         uint32_t aapl_reply_bitmap;
1806         uint32_t aapl_server_caps;
1807         uint32_t aapl_vol_caps;
1808         char *model;
1809         struct smb2_find f;
1810         unsigned int count;
1811         union smb_search_data *d;
1812         uint64_t rfork_len;
1813
1814         smb2_deltree(tree, BASEDIR);
1815
1816         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1817         CHECK_STATUS(status, NT_STATUS_OK);
1818         smb2_util_close(tree, testdirh);
1819
1820         ZERO_STRUCT(io);
1821         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
1822         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
1823         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1824         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1825                               NTCREATEX_SHARE_ACCESS_READ |
1826                               NTCREATEX_SHARE_ACCESS_WRITE);
1827         io.in.fname = fname;
1828
1829         /*
1830          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1831          * controls behaviour of Apple's SMB2 extensions for the whole
1832          * session!
1833          */
1834
1835         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1836         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1837         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1838                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1839                              SMB2_CRTCTX_AAPL_MODEL_INFO));
1840         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1841                               SMB2_CRTCTX_AAPL_UNIX_BASED |
1842                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1843
1844         torture_comment(tctx, "Testing SMB2 create context AAPL\n");
1845         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1846         CHECK_STATUS(status, NT_STATUS_OK);
1847
1848         status = smb2_create(tree, tctx, &io);
1849         CHECK_STATUS(status, NT_STATUS_OK);
1850         status = smb2_util_close(tree, io.out.file.handle);
1851         CHECK_STATUS(status, NT_STATUS_OK);
1852
1853         /*
1854          * Now check returned AAPL context
1855          */
1856         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1857
1858         aapl = smb2_create_blob_find(&io.out.blobs,
1859                                      SMB2_CREATE_TAG_AAPL);
1860
1861         if (aapl->data.length != 50) {
1862                 /*
1863                  * uint32_t CommandCode = kAAPL_SERVER_QUERY
1864                  * uint32_t Reserved = 0;
1865                  * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
1866                  *                        kAAPL_VOLUME_CAPS |
1867                  *                        kAAPL_MODEL_INFO;
1868                  * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
1869                  *                       kAAPL_SUPPORTS_OSX_COPYFILE;
1870                  * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
1871                  *                       kAAPL_CASE_SENSITIVE;
1872                  * uint32_t Pad2 = 0;
1873                  * uint32_t ModelStringLen = 10;
1874                  * ucs2_t ModelString[5] = "Samba";
1875                  */
1876                 torture_warning(tctx,
1877                                 "(%s) unexpected AAPL context length: %zd, expected 50",
1878                                 __location__, aapl->data.length);
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_warning(tctx,
1917                                 "(%s) unexpected vol_caps: %d",
1918                                 __location__, (int)aapl_vol_caps);
1919         }
1920
1921         ret = convert_string_talloc(mem_ctx,
1922                                     CH_UTF16LE, CH_UNIX,
1923                                     aapl->data.data + 40, 10,
1924                                     &model, NULL);
1925         if (ret == false) {
1926                 torture_result(tctx, TORTURE_FAIL,
1927                                "(%s) convert_string_talloc() failed",
1928                                __location__);
1929                 goto done;
1930         }
1931         torture_comment(tctx, "Got server model: \"%s\"\n", model);
1932
1933         /*
1934          * Now that Requested AAPL extensions are enabled, setup some
1935          * Mac files with metadata and resource fork
1936          */
1937         ret = torture_setup_file(mem_ctx, tree, fname, false);
1938         if (ret == false) {
1939                 torture_result(tctx, TORTURE_FAIL,
1940                                "(%s) torture_setup_file() failed",
1941                                __location__);
1942                 goto done;
1943         }
1944
1945         info = torture_afpinfo_new(mem_ctx);
1946         if (info == NULL) {
1947                 torture_result(tctx, TORTURE_FAIL,
1948                                "(%s) torture_afpinfo_new() failed",
1949                                __location__);
1950                 ret = false;
1951                 goto done;
1952         }
1953
1954         memcpy(info->afpi_FinderInfo, type_creator, 8);
1955         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1956         if (ret == false) {
1957                 torture_result(tctx, TORTURE_FAIL,
1958                                "(%s) torture_write_afpinfo() failed",
1959                                __location__);
1960                 goto done;
1961         }
1962
1963         ret = write_stream(tree, __location__, tctx, mem_ctx,
1964                            fname, AFPRESOURCE_STREAM_NAME,
1965                            0, 3, "foo");
1966         if (ret == false) {
1967                 torture_result(tctx, TORTURE_FAIL,
1968                                "(%s) write_stream() failed",
1969                                __location__);
1970                 goto done;
1971         }
1972
1973         /*
1974          * Ok, file is prepared, now call smb2/find
1975          */
1976
1977         ZERO_STRUCT(io);
1978         io.in.desired_access = SEC_RIGHTS_DIR_READ;
1979         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1980         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
1981         io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
1982                               NTCREATEX_SHARE_ACCESS_WRITE |
1983                               NTCREATEX_SHARE_ACCESS_DELETE);
1984         io.in.create_disposition = NTCREATEX_DISP_OPEN;
1985         io.in.fname = BASEDIR;
1986         status = smb2_create(tree, tctx, &io);
1987         CHECK_STATUS(status, NT_STATUS_OK);
1988
1989         ZERO_STRUCT(f);
1990         f.in.file.handle        = io.out.file.handle;
1991         f.in.pattern            = "test_aapl";
1992         f.in.continue_flags     = SMB2_CONTINUE_FLAG_SINGLE;
1993         f.in.max_response_size  = 0x1000;
1994         f.in.level              = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
1995
1996         status = smb2_find_level(tree, tree, &f, &count, &d);
1997         CHECK_STATUS(status, NT_STATUS_OK);
1998
1999         status = smb2_util_close(tree, io.out.file.handle);
2000         CHECK_STATUS(status, NT_STATUS_OK);
2001
2002         if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2003                 torture_result(tctx, TORTURE_FAIL,
2004                                "(%s) write_stream() failed",
2005                                __location__);
2006                 ret = false;
2007                 goto done;
2008         }
2009
2010         if (d[0].id_both_directory_info.short_name.private_length != 24) {
2011                 torture_result(tctx, TORTURE_FAIL,
2012                                "(%s) bad short_name length %" PRIu32 ", expected 24",
2013                                __location__, d[0].id_both_directory_info.short_name.private_length);
2014                 ret = false;
2015                 goto done;
2016         }
2017
2018         torture_comment(tctx, "short_name buffer:\n");
2019         dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2020
2021         /*
2022          * Extract data as specified by the AAPL extension:
2023          * - ea_size contains max_access
2024          * - short_name contains resource fork length + FinderInfo
2025          * - reserved2 contains the unix mode
2026          */
2027         torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2028                         d[0].id_both_directory_info.ea_size);
2029
2030         rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2031         if (rfork_len != 3) {
2032                 torture_result(tctx, TORTURE_FAIL,
2033                                "(%s) expected resource fork length 3, got: %" PRIu64,
2034                                __location__, rfork_len);
2035                 ret = false;
2036                 goto done;
2037         }
2038
2039         memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2040         type_creator_buf[8] = 0;
2041         if (strcmp(type_creator, type_creator_buf) != 0) {
2042                 torture_result(tctx, TORTURE_FAIL,
2043                                "(%s) expected type/creator \"%s\" , got: %s",
2044                                __location__, type_creator, type_creator_buf);
2045                 ret = false;
2046                 goto done;
2047         }
2048
2049 done:
2050         smb2_util_unlink(tree, fname);
2051         smb2_deltree(tree, BASEDIR);
2052         talloc_free(mem_ctx);
2053         return ret;
2054 }
2055
2056 static uint64_t patt_hash(uint64_t off)
2057 {
2058         return off;
2059 }
2060
2061 static bool write_pattern(struct torture_context *torture,
2062                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2063                           struct smb2_handle h, uint64_t off, uint64_t len,
2064                           uint64_t patt_off)
2065 {
2066         NTSTATUS status;
2067         uint64_t i;
2068         uint8_t *buf;
2069         uint64_t io_sz = MIN(1024 * 64, len);
2070
2071         if (len == 0) {
2072                 return true;
2073         }
2074
2075         torture_assert(torture, (len % 8) == 0, "invalid write len");
2076
2077         buf = talloc_zero_size(mem_ctx, io_sz);
2078         torture_assert(torture, (buf != NULL), "no memory for file data buf");
2079
2080         while (len > 0) {
2081                 for (i = 0; i <= io_sz - 8; i += 8) {
2082                         SBVAL(buf, i, patt_hash(patt_off));
2083                         patt_off += 8;
2084                 }
2085
2086                 status = smb2_util_write(tree, h,
2087                                          buf, off, io_sz);
2088                 torture_assert_ntstatus_ok(torture, status, "file write");
2089
2090                 len -= io_sz;
2091                 off += io_sz;
2092         }
2093
2094         talloc_free(buf);
2095
2096         return true;
2097 }
2098
2099 static bool check_pattern(struct torture_context *torture,
2100                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2101                           struct smb2_handle h, uint64_t off, uint64_t len,
2102                           uint64_t patt_off)
2103 {
2104         if (len == 0) {
2105                 return true;
2106         }
2107
2108         torture_assert(torture, (len % 8) == 0, "invalid read len");
2109
2110         while (len > 0) {
2111                 uint64_t i;
2112                 struct smb2_read r;
2113                 NTSTATUS status;
2114                 uint64_t io_sz = MIN(1024 * 64, len);
2115
2116                 ZERO_STRUCT(r);
2117                 r.in.file.handle = h;
2118                 r.in.length      = io_sz;
2119                 r.in.offset      = off;
2120                 status = smb2_read(tree, mem_ctx, &r);
2121                 torture_assert_ntstatus_ok(torture, status, "read");
2122
2123                 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2124                                          "read data len mismatch");
2125
2126                 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2127                         uint64_t data = BVAL(r.out.data.data, i);
2128                         torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2129                                                  talloc_asprintf(torture, "read data "
2130                                                                  "pattern bad at %llu\n",
2131                                                                  (unsigned long long)off + i));
2132                 }
2133                 talloc_free(r.out.data.data);
2134                 len -= io_sz;
2135                 off += io_sz;
2136         }
2137
2138         return true;
2139 }
2140
2141 static bool test_setup_open(struct torture_context *torture,
2142                             struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2143                             const char *fname,
2144                             struct smb2_handle *fh,
2145                             uint32_t desired_access,
2146                             uint32_t file_attributes)
2147 {
2148         struct smb2_create io;
2149         NTSTATUS status;
2150
2151         ZERO_STRUCT(io);
2152         io.in.desired_access = desired_access;
2153         io.in.file_attributes = file_attributes;
2154         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2155         io.in.share_access =
2156                 NTCREATEX_SHARE_ACCESS_DELETE|
2157                 NTCREATEX_SHARE_ACCESS_READ|
2158                 NTCREATEX_SHARE_ACCESS_WRITE;
2159         if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2160                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2161         }
2162         io.in.fname = fname;
2163
2164         status = smb2_create(tree, mem_ctx, &io);
2165         torture_assert_ntstatus_ok(torture, status, "file create");
2166
2167         *fh = io.out.file.handle;
2168
2169         return true;
2170 }
2171
2172 static bool test_setup_create_fill(struct torture_context *torture,
2173                                    struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2174                                    const char *fname,
2175                                    struct smb2_handle *fh,
2176                                    uint64_t size,
2177                                    uint32_t desired_access,
2178                                    uint32_t file_attributes)
2179 {
2180         bool ok;
2181
2182         ok = test_setup_open(torture, tree, mem_ctx,
2183                              fname,
2184                              fh,
2185                              desired_access,
2186                              file_attributes);
2187         torture_assert(torture, ok, "file open");
2188
2189         if (size > 0) {
2190                 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2191                 torture_assert(torture, ok, "write pattern");
2192         }
2193         return true;
2194 }
2195
2196 static bool test_setup_copy_chunk(struct torture_context *torture,
2197                                   struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2198                                   uint32_t nchunks,
2199                                   struct smb2_handle *src_h,
2200                                   uint64_t src_size,
2201                                   uint32_t src_desired_access,
2202                                   struct smb2_handle *dest_h,
2203                                   uint64_t dest_size,
2204                                   uint32_t dest_desired_access,
2205                                   struct srv_copychunk_copy *cc_copy,
2206                                   union smb_ioctl *io)
2207 {
2208         struct req_resume_key_rsp res_key;
2209         bool ok;
2210         NTSTATUS status;
2211         enum ndr_err_code ndr_ret;
2212
2213         ok = test_setup_create_fill(torture, tree, mem_ctx, FNAME_CC_SRC,
2214                                     src_h, src_size, src_desired_access,
2215                                     FILE_ATTRIBUTE_NORMAL);
2216         torture_assert(torture, ok, "src file create fill");
2217
2218         ok = test_setup_create_fill(torture, tree, mem_ctx, FNAME_CC_DST,
2219                                     dest_h, dest_size, dest_desired_access,
2220                                     FILE_ATTRIBUTE_NORMAL);
2221         torture_assert(torture, ok, "dest file create fill");
2222
2223         ZERO_STRUCTPN(io);
2224         io->smb2.level = RAW_IOCTL_SMB2;
2225         io->smb2.in.file.handle = *src_h;
2226         io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2227         /* Allow for Key + ContextLength + Context */
2228         io->smb2.in.max_response_size = 32;
2229         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2230
2231         status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2232         torture_assert_ntstatus_ok(torture, status,
2233                                    "FSCTL_SRV_REQUEST_RESUME_KEY");
2234
2235         ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2236                         (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2237
2238         torture_assert_ndr_success(torture, ndr_ret,
2239                                    "ndr_pull_req_resume_key_rsp");
2240
2241         ZERO_STRUCTPN(io);
2242         io->smb2.level = RAW_IOCTL_SMB2;
2243         io->smb2.in.file.handle = *dest_h;
2244         io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2245         io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2246         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2247
2248         ZERO_STRUCTPN(cc_copy);
2249         memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2250         cc_copy->chunk_count = nchunks;
2251         cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2252         torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2253
2254         return true;
2255 }
2256
2257
2258 static bool check_copy_chunk_rsp(struct torture_context *torture,
2259                                  struct srv_copychunk_rsp *cc_rsp,
2260                                  uint32_t ex_chunks_written,
2261                                  uint32_t ex_chunk_bytes_written,
2262                                  uint32_t ex_total_bytes_written)
2263 {
2264         torture_assert_int_equal(torture, cc_rsp->chunks_written,
2265                                  ex_chunks_written, "num chunks");
2266         torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2267                                  ex_chunk_bytes_written, "chunk bytes written");
2268         torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2269                                  ex_total_bytes_written, "chunk total bytes");
2270         return true;
2271 }
2272
2273 static bool neg_aapl_copyfile(struct torture_context *tctx,
2274                               struct smb2_tree *tree,
2275                               uint64_t flags)
2276 {
2277         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2278         const char *fname = "aapl";
2279         NTSTATUS status;
2280         struct smb2_create io;
2281         DATA_BLOB data;
2282         struct smb2_create_blob *aapl = NULL;
2283         uint32_t aapl_cmd;
2284         uint32_t aapl_reply_bitmap;
2285         uint32_t aapl_server_caps;
2286         bool ret = true;
2287
2288         ZERO_STRUCT(io);
2289         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
2290         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
2291         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2292         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2293                               NTCREATEX_SHARE_ACCESS_READ |
2294                               NTCREATEX_SHARE_ACCESS_WRITE);
2295         io.in.fname = fname;
2296
2297         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2298         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2299         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2300         SBVAL(data.data, 16, flags);
2301
2302         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2303         CHECK_STATUS(status, NT_STATUS_OK);
2304
2305         status = smb2_create(tree, tctx, &io);
2306         CHECK_STATUS(status, NT_STATUS_OK);
2307
2308         aapl = smb2_create_blob_find(&io.out.blobs,
2309                                      SMB2_CREATE_TAG_AAPL);
2310         if (aapl == NULL) {
2311                 ret = false;
2312                 goto done;
2313
2314         }
2315         if (aapl->data.length < 24) {
2316                 ret = false;
2317                 goto done;
2318         }
2319
2320         aapl_cmd = IVAL(aapl->data.data, 0);
2321         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2322                 torture_result(tctx, TORTURE_FAIL,
2323                                "(%s) unexpected cmd: %d",
2324                                __location__, (int)aapl_cmd);
2325                 ret = false;
2326                 goto done;
2327         }
2328
2329         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2330         if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2331                 torture_result(tctx, TORTURE_FAIL,
2332                                "(%s) unexpected reply_bitmap: %d",
2333                                __location__, (int)aapl_reply_bitmap);
2334                 ret = false;
2335                 goto done;
2336         }
2337
2338         aapl_server_caps = BVAL(aapl->data.data, 16);
2339         if (!(aapl_server_caps & flags)) {
2340                 torture_result(tctx, TORTURE_FAIL,
2341                                "(%s) unexpected server_caps: %d",
2342                                __location__, (int)aapl_server_caps);
2343                 ret = false;
2344                 goto done;
2345         }
2346
2347 done:
2348         status = smb2_util_close(tree, io.out.file.handle);
2349         CHECK_STATUS(status, NT_STATUS_OK);
2350
2351         smb2_util_unlink(tree, "aapl");
2352         talloc_free(mem_ctx);
2353         return ret;
2354 }
2355
2356 static bool test_copyfile(struct torture_context *torture,
2357                           struct smb2_tree *tree)
2358 {
2359         struct smb2_handle src_h;
2360         struct smb2_handle dest_h;
2361         NTSTATUS status;
2362         union smb_ioctl io;
2363         TALLOC_CTX *tmp_ctx = talloc_new(tree);
2364         struct srv_copychunk_copy cc_copy;
2365         struct srv_copychunk_rsp cc_rsp;
2366         enum ndr_err_code ndr_ret;
2367         bool ok;
2368
2369         /*
2370          * First test a copy_chunk with a 0 chunk count without having
2371          * enabled this via AAPL. The request must not fail and the
2372          * copied length in the response must be 0. This is verified
2373          * against Windows 2008r2.
2374          */
2375
2376         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2377                                    0, /* 0 chunks, copyfile semantics */
2378                                    &src_h, 4096, /* fill 4096 byte src file */
2379                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2380                                    &dest_h, 0,  /* 0 byte dest file */
2381                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2382                                    &cc_copy,
2383                                    &io);
2384         if (!ok) {
2385                 torture_fail_goto(torture, done, "setup copy chunk error");
2386         }
2387
2388         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2389                                        &cc_copy,
2390                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2391         torture_assert_ndr_success(torture, ndr_ret,
2392                                    "ndr_push_srv_copychunk_copy");
2393
2394         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2395         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2396
2397         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2398                                        &cc_rsp,
2399                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2400         torture_assert_ndr_success(torture, ndr_ret,
2401                                    "ndr_pull_srv_copychunk_rsp");
2402
2403         ok = check_copy_chunk_rsp(torture, &cc_rsp,
2404                                   0,    /* chunks written */
2405                                   0,    /* chunk bytes unsuccessfully written */
2406                                   0); /* total bytes written */
2407         if (!ok) {
2408                 torture_fail_goto(torture, done, "bad copy chunk response data");
2409         }
2410
2411         /*
2412          * Now enable AAPL copyfile and test again, the file and the
2413          * stream must be copied by the server.
2414          */
2415         ok = neg_aapl_copyfile(torture, tree,
2416                                SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2417         if (!ok) {
2418                 torture_skip_goto(torture, done, "missing AAPL copyfile");
2419                 goto done;
2420         }
2421
2422         smb2_util_close(tree, src_h);
2423         smb2_util_close(tree, dest_h);
2424         smb2_util_unlink(tree, FNAME_CC_SRC);
2425         smb2_util_unlink(tree, FNAME_CC_DST);
2426
2427         ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2428         if (!ok) {
2429                 torture_fail(torture, "setup file error");
2430         }
2431         ok = write_stream(tree, __location__, torture, tmp_ctx,
2432                             FNAME_CC_SRC, AFPRESOURCE_STREAM,
2433                             10, 10, "1234567890");
2434         if (!ok) {
2435                 torture_fail(torture, "setup stream error");
2436         }
2437
2438         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2439                                    0, /* 0 chunks, copyfile semantics */
2440                                    &src_h, 4096, /* fill 4096 byte src file */
2441                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2442                                    &dest_h, 0,  /* 0 byte dest file */
2443                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2444                                    &cc_copy,
2445                                    &io);
2446         if (!ok) {
2447                 torture_fail_goto(torture, done, "setup copy chunk error");
2448         }
2449
2450         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2451                                        &cc_copy,
2452                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2453         torture_assert_ndr_success(torture, ndr_ret,
2454                                    "ndr_push_srv_copychunk_copy");
2455
2456         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2457         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2458
2459         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2460                                        &cc_rsp,
2461                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2462         torture_assert_ndr_success(torture, ndr_ret,
2463                                    "ndr_pull_srv_copychunk_rsp");
2464
2465         ok = check_copy_chunk_rsp(torture, &cc_rsp,
2466                                   0,    /* chunks written */
2467                                   0,    /* chunk bytes unsuccessfully written */
2468                                   4096); /* total bytes written */
2469         if (!ok) {
2470                 torture_fail_goto(torture, done, "bad copy chunk response data");
2471         }
2472
2473         ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
2474                              SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
2475         if (!ok) {
2476                 torture_fail_goto(torture, done,"open failed");
2477         }
2478         ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
2479         if (!ok) {
2480                 torture_fail_goto(torture, done, "inconsistent file data");
2481         }
2482
2483         ok = check_stream(tree, __location__, torture, tmp_ctx,
2484                             FNAME_CC_DST, AFPRESOURCE_STREAM,
2485                             0, 20, 10, 10, "1234567890");
2486         if (!ok) {
2487                 torture_fail_goto(torture, done, "inconsistent stream data");
2488         }
2489
2490 done:
2491         smb2_util_close(tree, src_h);
2492         smb2_util_close(tree, dest_h);
2493         smb2_util_unlink(tree, FNAME_CC_SRC);
2494         smb2_util_unlink(tree, FNAME_CC_DST);
2495         talloc_free(tmp_ctx);
2496         return true;
2497 }
2498
2499 static bool check_stream_list(struct smb2_tree *tree,
2500                               struct torture_context *tctx,
2501                               const char *fname,
2502                               int num_exp,
2503                               const char **exp,
2504                               bool is_dir)
2505 {
2506         bool ret = true;
2507         union smb_fileinfo finfo;
2508         NTSTATUS status;
2509         int i;
2510         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
2511         char **exp_sort;
2512         struct stream_struct *stream_sort;
2513         struct smb2_create create;
2514         struct smb2_handle h;
2515
2516         ZERO_STRUCT(h);
2517         torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
2518
2519         ZERO_STRUCT(create);
2520         create.in.fname = fname;
2521         create.in.create_disposition = NTCREATEX_DISP_OPEN;
2522         create.in.desired_access = SEC_FILE_ALL;
2523         create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
2524         create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
2525         status = smb2_create(tree, tmp_ctx, &create);
2526         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2527         h = create.out.file.handle;
2528
2529         finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
2530         finfo.generic.in.file.handle = h;
2531
2532         status = smb2_getinfo_file(tree, tctx, &finfo);
2533         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
2534
2535         smb2_util_close(tree, h);
2536
2537         torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
2538                                       ret, done, "stream count");
2539
2540         if (num_exp == 0) {
2541                 TALLOC_FREE(tmp_ctx);
2542                 goto done;
2543         }
2544
2545         exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
2546         torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
2547
2548         TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
2549
2550         stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
2551                                     finfo.stream_info.out.num_streams *
2552                                     sizeof(*stream_sort));
2553         torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
2554
2555         TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
2556
2557         for (i=0; i<num_exp; i++) {
2558                 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
2559                                 i, exp_sort[i], stream_sort[i].stream_name.s);
2560                 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
2561                                               ret, done, "stream name");
2562         }
2563
2564 done:
2565         TALLOC_FREE(tmp_ctx);
2566         return ret;
2567 }
2568
2569 /*
2570   test stream names
2571 */
2572 static bool test_stream_names(struct torture_context *tctx,
2573                               struct smb2_tree *tree)
2574 {
2575         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2576         NTSTATUS status;
2577         struct smb2_create create;
2578         struct smb2_handle h;
2579         const char *fname = BASEDIR "\\stream_names.txt";
2580         const char *sname1;
2581         bool ret;
2582         /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
2583         const char *streams[] = {
2584                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2585                 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
2586                 "::$DATA"
2587         };
2588         const char *localdir = NULL;
2589
2590         localdir = torture_setting_string(tctx, "localdir", NULL);
2591         if (localdir == NULL) {
2592                 torture_skip(tctx, "Need localdir for test");
2593         }
2594
2595         sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
2596
2597         /* clean slate ...*/
2598         smb2_util_unlink(tree, fname);
2599         smb2_deltree(tree, fname);
2600         smb2_deltree(tree, BASEDIR);
2601
2602         status = torture_smb2_testdir(tree, BASEDIR, &h);
2603         CHECK_STATUS(status, NT_STATUS_OK);
2604         smb2_util_close(tree, h);
2605
2606         torture_comment(tctx, "(%s) testing stream names\n", __location__);
2607         ZERO_STRUCT(create);
2608         create.in.desired_access = SEC_FILE_WRITE_DATA;
2609         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2610         create.in.share_access =
2611                 NTCREATEX_SHARE_ACCESS_DELETE|
2612                 NTCREATEX_SHARE_ACCESS_READ|
2613                 NTCREATEX_SHARE_ACCESS_WRITE;
2614         create.in.create_disposition = NTCREATEX_DISP_CREATE;
2615         create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2616         create.in.fname = sname1;
2617
2618         status = smb2_create(tree, mem_ctx, &create);
2619         CHECK_STATUS(status, NT_STATUS_OK);
2620         smb2_util_close(tree, create.out.file.handle);
2621
2622         ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
2623                                         "user.DosStream.bar:baz:$DATA",
2624                                         "data", strlen("data"));
2625         CHECK_VALUE(ret, true);
2626
2627         ret = check_stream_list(tree, tctx, fname, 3, streams, false);
2628         CHECK_VALUE(ret, true);
2629
2630 done:
2631         status = smb2_util_unlink(tree, fname);
2632         smb2_deltree(tree, BASEDIR);
2633         talloc_free(mem_ctx);
2634
2635         return ret;
2636 }
2637
2638 /* Renaming a directory with open file, should work for OS X AAPL clients */
2639 static bool test_rename_dir_openfile(struct torture_context *torture,
2640                                      struct smb2_tree *tree)
2641 {
2642         bool ret = true;
2643         NTSTATUS status;
2644         union smb_open io;
2645         union smb_close cl;
2646         union smb_setfileinfo sinfo;
2647         struct smb2_handle d1, h1;
2648         const char *renamedir = BASEDIR "-new";
2649         bool server_is_osx = torture_setting_bool(torture, "osx", false);
2650
2651         smb2_deltree(tree, BASEDIR);
2652         smb2_util_rmdir(tree, BASEDIR);
2653         smb2_deltree(tree, renamedir);
2654
2655         ZERO_STRUCT(io.smb2);
2656         io.generic.level = RAW_OPEN_SMB2;
2657         io.smb2.in.create_flags = 0;
2658         io.smb2.in.desired_access = 0x0017019f;
2659         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2660         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2661         io.smb2.in.share_access = 0;
2662         io.smb2.in.alloc_size = 0;
2663         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2664         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2665         io.smb2.in.security_flags = 0;
2666         io.smb2.in.fname = BASEDIR;
2667
2668         status = smb2_create(tree, torture, &(io.smb2));
2669         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2670         d1 = io.smb2.out.file.handle;
2671
2672         ZERO_STRUCT(io.smb2);
2673         io.generic.level = RAW_OPEN_SMB2;
2674         io.smb2.in.create_flags = 0;
2675         io.smb2.in.desired_access = 0x0017019f;
2676         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2677         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2678         io.smb2.in.share_access = 0;
2679         io.smb2.in.alloc_size = 0;
2680         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2681         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2682         io.smb2.in.security_flags = 0;
2683         io.smb2.in.fname = BASEDIR "\\file.txt";
2684
2685         status = smb2_create(tree, torture, &(io.smb2));
2686         torture_assert_ntstatus_ok(torture, status, "smb2_create file");
2687         h1 = io.smb2.out.file.handle;
2688
2689         if (!server_is_osx) {
2690                 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
2691
2692                 ZERO_STRUCT(sinfo);
2693                 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2694                 sinfo.rename_information.in.file.handle = d1;
2695                 sinfo.rename_information.in.overwrite = 0;
2696                 sinfo.rename_information.in.root_fid = 0;
2697                 sinfo.rename_information.in.new_name = renamedir;
2698                 status = smb2_setinfo_file(tree, &sinfo);
2699
2700                 torture_assert_ntstatus_equal(torture, status,
2701                                               NT_STATUS_ACCESS_DENIED,
2702                                               "smb2_setinfo_file");
2703
2704                 ZERO_STRUCT(cl.smb2);
2705                 cl.smb2.level = RAW_CLOSE_SMB2;
2706                 cl.smb2.in.file.handle = d1;
2707                 status = smb2_close(tree, &(cl.smb2));
2708                 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2709                 ZERO_STRUCT(d1);
2710         }
2711
2712         torture_comment(torture, "Enabling AAPL\n");
2713
2714         ret = enable_aapl(torture, tree);
2715         torture_assert(torture, ret == true, "enable_aapl failed");
2716
2717         torture_comment(torture, "Renaming directory with AAPL\n");
2718
2719         ZERO_STRUCT(io.smb2);
2720         io.generic.level = RAW_OPEN_SMB2;
2721         io.smb2.in.desired_access = 0x0017019f;
2722         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2723         io.smb2.in.share_access = 0;
2724         io.smb2.in.alloc_size = 0;
2725         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
2726         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2727         io.smb2.in.security_flags = 0;
2728         io.smb2.in.fname = BASEDIR;
2729
2730         status = smb2_create(tree, torture, &(io.smb2));
2731         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2732         d1 = io.smb2.out.file.handle;
2733
2734         ZERO_STRUCT(sinfo);
2735         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2736         sinfo.rename_information.in.file.handle = d1;
2737         sinfo.rename_information.in.overwrite = 0;
2738         sinfo.rename_information.in.root_fid = 0;
2739         sinfo.rename_information.in.new_name = renamedir;
2740
2741         status = smb2_setinfo_file(tree, &sinfo);
2742         torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
2743
2744         ZERO_STRUCT(cl.smb2);
2745         cl.smb2.level = RAW_CLOSE_SMB2;
2746         cl.smb2.in.file.handle = d1;
2747         status = smb2_close(tree, &(cl.smb2));
2748         torture_assert_ntstatus_ok(torture, status, "smb2_close");
2749         ZERO_STRUCT(d1);
2750
2751         cl.smb2.in.file.handle = h1;
2752         status = smb2_close(tree, &(cl.smb2));
2753         torture_assert_ntstatus_ok(torture, status, "smb2_close");
2754         ZERO_STRUCT(h1);
2755
2756         torture_comment(torture, "Cleaning up\n");
2757
2758         if (h1.data) {
2759                 ZERO_STRUCT(cl.smb2);
2760                 cl.smb2.level = RAW_CLOSE_SMB2;
2761                 cl.smb2.in.file.handle = h1;
2762                 status = smb2_close(tree, &(cl.smb2));
2763         }
2764
2765         smb2_util_unlink(tree, BASEDIR "\\file.txt");
2766         smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
2767         smb2_deltree(tree, renamedir);
2768         smb2_deltree(tree, BASEDIR);
2769         return ret;
2770 }
2771
2772 /*
2773  * Note: This test depends on "vfs objects = catia fruit streams_xattr".  For
2774  * some tests torture must be run on the host it tests and takes an additional
2775  * argument with the local path to the share:
2776  * "--option=torture:localdir=<SHAREPATH>".
2777  *
2778  * When running against an OS X SMB server add "--option=torture:osx=true"
2779  */
2780 struct torture_suite *torture_vfs_fruit(void)
2781 {
2782         struct torture_suite *suite = torture_suite_create(
2783                 talloc_autofree_context(), "fruit");
2784
2785         suite->description = talloc_strdup(suite, "vfs_fruit tests");
2786
2787         torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
2788         torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
2789         torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
2790         torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
2791         torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
2792         torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
2793         torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
2794         torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
2795         torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
2796         torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
2797
2798         return suite;
2799 }