s4:torture:vfs: fix Invalid read of size 8 valgrind valgrind error (and segv)
[metze/samba/wip.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, 3, "AFP");
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, 2);
1325
1326         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1327                           AFPINFO_STREAM, 60, 1);
1328         CHECK_VALUE(len, 1);
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_read_afpinfo(struct torture_context *tctx,
1341                               struct smb2_tree *tree)
1342 {
1343         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1344         const char *fname = BASEDIR "\\torture_read_metadata";
1345         NTSTATUS status;
1346         struct smb2_handle testdirh;
1347         bool ret = true;
1348         ssize_t len;
1349         AfpInfo *info;
1350         const char *type_creator = "SMB,OLE!";
1351
1352         torture_comment(tctx, "Checking metadata access\n");
1353
1354         smb2_util_unlink(tree, fname);
1355
1356         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1357         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
1358         smb2_util_close(tree, testdirh);
1359
1360         ret = torture_setup_file(mem_ctx, tree, fname, false);
1361         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
1362
1363         info = torture_afpinfo_new(mem_ctx);
1364         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
1365
1366         memcpy(info->afpi_FinderInfo, type_creator, 8);
1367         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1368         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
1369
1370         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1371                            0, 60, 0, 4, "AFP");
1372         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1373
1374         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1375                            0, 60, 16, 8, type_creator);
1376         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1377
1378         /*
1379          * OS X ignores offset <= 60 and treats the as
1380          * offset=0. Reading from offsets > 60 returns EOF=0.
1381          */
1382
1383         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1384                            16, 8, 0, 8, "AFP\0\0\0\001\0");
1385         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1386
1387         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1388                           AFPINFO_STREAM, 0, 61);
1389         torture_assert_goto(tctx, len == 60, ret, done, "read_stream failed");
1390
1391         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1392                           AFPINFO_STREAM, 59, 2);
1393         torture_assert_goto(tctx, len == 2, ret, done, "read_stream failed");
1394
1395         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1396                            59, 2, 0, 2, "AF");
1397         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1398
1399         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1400                           AFPINFO_STREAM, 60, 1);
1401         torture_assert_goto(tctx, len == 1, ret, done, "read_stream failed");
1402
1403         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1404                            60, 1, 0, 1, "A");
1405         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
1406
1407         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
1408                           AFPINFO_STREAM, 61, 1);
1409         torture_assert_goto(tctx, len == 0, ret, done, "read_stream failed");
1410
1411 done:
1412         smb2_util_unlink(tree, fname);
1413         smb2_deltree(tree, BASEDIR);
1414         talloc_free(mem_ctx);
1415         return ret;
1416 }
1417
1418 static bool test_write_atalk_metadata(struct torture_context *tctx,
1419                                       struct smb2_tree *tree)
1420 {
1421         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1422         const char *fname = BASEDIR "\\torture_write_metadata";
1423         const char *type_creator = "SMB,OLE!";
1424         NTSTATUS status;
1425         struct smb2_handle testdirh;
1426         bool ret = true;
1427         AfpInfo *info;
1428
1429         smb2_deltree(tree, BASEDIR);
1430         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1431         CHECK_STATUS(status, NT_STATUS_OK);
1432         smb2_util_close(tree, testdirh);
1433
1434         ret = torture_setup_file(mem_ctx, tree, fname, false);
1435         if (ret == false) {
1436                 goto done;
1437         }
1438
1439         info = torture_afpinfo_new(mem_ctx);
1440         if (info == NULL) {
1441                 goto done;
1442         }
1443
1444         memcpy(info->afpi_FinderInfo, type_creator, 8);
1445         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
1446         ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
1447                             0, 60, 16, 8, type_creator);
1448
1449 done:
1450         smb2_util_unlink(tree, fname);
1451         smb2_deltree(tree, BASEDIR);
1452         talloc_free(mem_ctx);
1453         return ret;
1454 }
1455
1456 static bool test_write_atalk_rfork_io(struct torture_context *tctx,
1457                                       struct smb2_tree *tree)
1458 {
1459         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1460         const char *fname = BASEDIR "\\torture_write_rfork_io";
1461         const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
1462         const char *rfork_content = "1234567890";
1463         NTSTATUS status;
1464         struct smb2_handle testdirh;
1465         bool ret = true;
1466
1467         union smb_open io;
1468         struct smb2_handle filehandle;
1469         union smb_fileinfo finfo;
1470         union smb_setfileinfo sinfo;
1471
1472         smb2_util_unlink(tree, fname);
1473
1474         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1475         CHECK_STATUS(status, NT_STATUS_OK);
1476         smb2_util_close(tree, testdirh);
1477
1478         ret = torture_setup_file(mem_ctx, tree, fname, false);
1479         if (ret == false) {
1480                 goto done;
1481         }
1482
1483         torture_comment(tctx, "(%s) writing to resource fork\n",
1484             __location__);
1485
1486         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1487                             fname, AFPRESOURCE_STREAM_NAME,
1488                             10, 10, rfork_content);
1489
1490         ret &= check_stream(tree, __location__, tctx, mem_ctx,
1491                             fname, AFPRESOURCE_STREAM_NAME,
1492                             0, 20, 10, 10, rfork_content);
1493
1494         /* Check size after write */
1495
1496         ZERO_STRUCT(io);
1497         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1498         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1499                 SEC_FILE_WRITE_ATTRIBUTE;
1500         io.smb2.in.fname = rfork;
1501         status = smb2_create(tree, mem_ctx, &(io.smb2));
1502         CHECK_STATUS(status, NT_STATUS_OK);
1503         filehandle = io.smb2.out.file.handle;
1504
1505         torture_comment(tctx, "(%s) check resource fork size after write\n",
1506             __location__);
1507
1508         ZERO_STRUCT(finfo);
1509         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1510         finfo.generic.in.file.handle = filehandle;
1511         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1512         CHECK_STATUS(status, NT_STATUS_OK);
1513         if (finfo.all_info.out.size != 20) {
1514                 torture_result(tctx, TORTURE_FAIL,
1515                                "(%s) Incorrect resource fork size\n",
1516                                __location__);
1517                 ret = false;
1518                 smb2_util_close(tree, filehandle);
1519                 goto done;
1520         }
1521         smb2_util_close(tree, filehandle);
1522
1523         /* Write at large offset */
1524
1525         torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
1526                         __location__);
1527
1528         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1529                             fname, AFPRESOURCE_STREAM_NAME,
1530                             (off_t)1<<32, 10, rfork_content);
1531
1532         ret &= check_stream(tree, __location__, tctx, mem_ctx,
1533                             fname, AFPRESOURCE_STREAM_NAME,
1534                             (off_t)1<<32, 10, 0, 10, rfork_content);
1535
1536         /* Truncate back to size of 1 byte */
1537
1538         torture_comment(tctx, "(%s) truncate resource fork and check size\n",
1539                         __location__);
1540
1541         ZERO_STRUCT(io);
1542         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1543         io.smb2.in.desired_access = SEC_FILE_ALL;
1544         io.smb2.in.fname = rfork;
1545         status = smb2_create(tree, mem_ctx, &(io.smb2));
1546         CHECK_STATUS(status, NT_STATUS_OK);
1547         filehandle = io.smb2.out.file.handle;
1548
1549         ZERO_STRUCT(sinfo);
1550         sinfo.end_of_file_info.level =
1551                 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1552         sinfo.end_of_file_info.in.file.handle = filehandle;
1553         sinfo.end_of_file_info.in.size = 1;
1554         status = smb2_setinfo_file(tree, &sinfo);
1555         CHECK_STATUS(status, NT_STATUS_OK);
1556
1557         smb2_util_close(tree, filehandle);
1558
1559         /* Now check size */
1560         ZERO_STRUCT(io);
1561         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
1562         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
1563                 SEC_FILE_WRITE_ATTRIBUTE;
1564         io.smb2.in.fname = rfork;
1565         status = smb2_create(tree, mem_ctx, &(io.smb2));
1566         CHECK_STATUS(status, NT_STATUS_OK);
1567         filehandle = io.smb2.out.file.handle;
1568
1569         ZERO_STRUCT(finfo);
1570         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1571         finfo.generic.in.file.handle = filehandle;
1572         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1573         CHECK_STATUS(status, NT_STATUS_OK);
1574         if (finfo.all_info.out.size != 1) {
1575                 torture_result(tctx, TORTURE_FAIL,
1576                                "(%s) Incorrect resource fork size\n",
1577                                __location__);
1578                 ret = false;
1579                 smb2_util_close(tree, filehandle);
1580                 goto done;
1581         }
1582         smb2_util_close(tree, filehandle);
1583
1584 done:
1585         smb2_util_unlink(tree, fname);
1586         smb2_deltree(tree, BASEDIR);
1587         talloc_free(mem_ctx);
1588         return ret;
1589 }
1590
1591 static bool test_rfork_truncate(struct torture_context *tctx,
1592                                 struct smb2_tree *tree)
1593 {
1594         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1595         const char *fname = BASEDIR "\\torture_rfork_truncate";
1596         const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
1597         const char *rfork_content = "1234567890";
1598         NTSTATUS status;
1599         struct smb2_handle testdirh;
1600         bool ret = true;
1601         struct smb2_create create;
1602         struct smb2_handle fh1, fh2, fh3;
1603         union smb_setfileinfo sinfo;
1604
1605         smb2_util_unlink(tree, fname);
1606
1607         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1608         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1609         smb2_util_close(tree, testdirh);
1610
1611         ret = torture_setup_file(mem_ctx, tree, fname, false);
1612         if (ret == false) {
1613                 goto done;
1614         }
1615
1616         ret &= write_stream(tree, __location__, tctx, mem_ctx,
1617                             fname, AFPRESOURCE_STREAM,
1618                             10, 10, rfork_content);
1619
1620         /* Truncate back to size 0, further access MUST return ENOENT */
1621
1622         torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
1623                         __location__);
1624
1625         ZERO_STRUCT(create);
1626         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1627         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1628         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1629         create.in.fname               = fname;
1630         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1631                 NTCREATEX_SHARE_ACCESS_READ |
1632                 NTCREATEX_SHARE_ACCESS_WRITE;
1633         status = smb2_create(tree, mem_ctx, &create);
1634         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1635         fh1 = create.out.file.handle;
1636
1637         ZERO_STRUCT(create);
1638         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1639         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1640         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1641         create.in.fname               = rfork;
1642         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1643                 NTCREATEX_SHARE_ACCESS_READ |
1644                 NTCREATEX_SHARE_ACCESS_WRITE;
1645         status = smb2_create(tree, mem_ctx, &create);
1646         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1647         fh2 = create.out.file.handle;
1648
1649         ZERO_STRUCT(sinfo);
1650         sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1651         sinfo.end_of_file_info.in.file.handle = fh2;
1652         sinfo.end_of_file_info.in.size = 0;
1653         status = smb2_setinfo_file(tree, &sinfo);
1654         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
1655
1656         /*
1657          * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
1658          */
1659         ZERO_STRUCT(create);
1660         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1661         create.in.desired_access      = 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         /*
1671          * Do another open on the rfork and write to the new handle. A
1672          * naive server might unlink the AppleDouble resource fork
1673          * file when its truncated to 0 bytes above, so in case both
1674          * open handles share the same underlying fd, the unlink would
1675          * cause the below write to be lost.
1676          */
1677         ZERO_STRUCT(create);
1678         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1679         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1680         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1681         create.in.fname               = rfork;
1682         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1683                 NTCREATEX_SHARE_ACCESS_READ |
1684                 NTCREATEX_SHARE_ACCESS_WRITE;
1685         status = smb2_create(tree, mem_ctx, &create);
1686         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1687         fh3 = create.out.file.handle;
1688
1689         status = smb2_util_write(tree, fh3, "foo", 0, 3);
1690         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
1691
1692         smb2_util_close(tree, fh3);
1693         smb2_util_close(tree, fh2);
1694         smb2_util_close(tree, fh1);
1695
1696         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
1697                            0, 3, 0, 3, "foo");
1698         torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
1699
1700 done:
1701         smb2_util_unlink(tree, fname);
1702         smb2_deltree(tree, BASEDIR);
1703         talloc_free(mem_ctx);
1704         return ret;
1705 }
1706
1707 static bool test_rfork_create(struct torture_context *tctx,
1708                               struct smb2_tree *tree)
1709 {
1710         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1711         const char *fname = BASEDIR "\\torture_rfork_create";
1712         const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
1713         NTSTATUS status;
1714         struct smb2_handle testdirh;
1715         bool ret = true;
1716         struct smb2_create create;
1717         struct smb2_handle fh1;
1718         const char *streams[] = {
1719                 "::$DATA"
1720         };
1721         union smb_fileinfo finfo;
1722
1723         smb2_util_unlink(tree, fname);
1724
1725         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1726         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
1727         smb2_util_close(tree, testdirh);
1728
1729         ret = torture_setup_file(mem_ctx, tree, fname, false);
1730         if (ret == false) {
1731                 goto done;
1732         }
1733
1734         torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
1735                         __location__);
1736
1737         ZERO_STRUCT(create);
1738         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1739         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1740         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1741         create.in.fname               = rfork;
1742         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1743                 NTCREATEX_SHARE_ACCESS_READ |
1744                 NTCREATEX_SHARE_ACCESS_WRITE;
1745         status = smb2_create(tree, mem_ctx, &create);
1746         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1747
1748         torture_comment(tctx, "(%s) create resource fork\n", __location__);
1749
1750         ZERO_STRUCT(create);
1751         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
1752         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1753         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1754         create.in.fname               = rfork;
1755         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1756                 NTCREATEX_SHARE_ACCESS_READ |
1757                 NTCREATEX_SHARE_ACCESS_WRITE;
1758         status = smb2_create(tree, mem_ctx, &create);
1759         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
1760         fh1 = create.out.file.handle;
1761
1762         torture_comment(tctx, "(%s) getinfo on create handle\n",
1763                         __location__);
1764
1765         ZERO_STRUCT(finfo);
1766         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1767         finfo.generic.in.file.handle = fh1;
1768         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
1769         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
1770         if (finfo.all_info.out.size != 0) {
1771                 torture_result(tctx, TORTURE_FAIL,
1772                                "(%s) Incorrect resource fork size\n",
1773                                __location__);
1774                 ret = false;
1775                 smb2_util_close(tree, fh1);
1776                 goto done;
1777         }
1778
1779         torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
1780                         __location__);
1781
1782         ZERO_STRUCT(create);
1783         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1784         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1785         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1786         create.in.fname               = rfork;
1787         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1788                 NTCREATEX_SHARE_ACCESS_READ |
1789                 NTCREATEX_SHARE_ACCESS_WRITE;
1790         status = smb2_create(tree, mem_ctx, &create);
1791         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1792
1793         ret = check_stream_list(tree, tctx, fname, 1, streams, false);
1794         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
1795
1796         torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
1797                         __location__);
1798
1799         ZERO_STRUCT(create);
1800         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
1801         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
1802         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
1803         create.in.fname               = rfork;
1804         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
1805                 NTCREATEX_SHARE_ACCESS_READ |
1806                 NTCREATEX_SHARE_ACCESS_WRITE;
1807         status = smb2_create(tree, mem_ctx, &create);
1808         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
1809
1810 done:
1811         smb2_util_unlink(tree, fname);
1812         smb2_deltree(tree, BASEDIR);
1813         talloc_free(mem_ctx);
1814         return ret;
1815 }
1816
1817 static bool test_adouble_conversion(struct torture_context *tctx,
1818                                     struct smb2_tree *tree)
1819 {
1820         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1821         const char *fname = BASEDIR "\\test_adouble_conversion";
1822         const char *fname_local = BASEDIR "/test_adouble_conversion";
1823         const char *adname_local = BASEDIR "/._test_adouble_conversion";
1824         NTSTATUS status;
1825         struct smb2_handle testdirh;
1826         bool ret = true;
1827         const char *data = "This resource fork intentionally left blank";
1828         size_t datalen = strlen(data);
1829         const char *localdir = NULL;
1830
1831         localdir = torture_setting_string(tctx, "localdir", NULL);
1832         if (localdir == NULL) {
1833                 torture_skip(tctx, "Need localdir for test");
1834         }
1835
1836         smb2_util_unlink(tree, fname);
1837
1838         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1839         CHECK_STATUS(status, NT_STATUS_OK);
1840         smb2_util_close(tree, testdirh);
1841
1842         ret = torture_setup_local_file(tctx, "localdir", fname_local,
1843                                        NULL, 0);
1844         if (ret == false) {
1845                 goto done;
1846         }
1847
1848         ret = torture_setup_local_file(tctx, "localdir", adname_local,
1849                                        osx_adouble_w_xattr,
1850                                        sizeof(osx_adouble_w_xattr));
1851         if (ret == false) {
1852                 goto done;
1853         }
1854
1855         torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
1856             __location__);
1857
1858         ret &= check_stream(tree, __location__, tctx, mem_ctx,
1859                             fname, AFPRESOURCE_STREAM,
1860                             16, datalen, 0, datalen, data);
1861
1862 done:
1863         smb2_deltree(tree, BASEDIR);
1864         talloc_free(mem_ctx);
1865         return ret;
1866 }
1867
1868 static bool test_aapl(struct torture_context *tctx,
1869                       struct smb2_tree *tree)
1870 {
1871         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1872         const char *fname = BASEDIR "\\test_aapl";
1873         NTSTATUS status;
1874         struct smb2_handle testdirh;
1875         bool ret = true;
1876         struct smb2_create io;
1877         DATA_BLOB data;
1878         struct smb2_create_blob *aapl = NULL;
1879         AfpInfo *info;
1880         const char *type_creator = "SMB,OLE!";
1881         char type_creator_buf[9];
1882         uint32_t aapl_cmd;
1883         uint32_t aapl_reply_bitmap;
1884         uint32_t aapl_server_caps;
1885         uint32_t aapl_vol_caps;
1886         char *model;
1887         struct smb2_find f;
1888         unsigned int count;
1889         union smb_search_data *d;
1890         uint64_t rfork_len;
1891
1892         smb2_deltree(tree, BASEDIR);
1893
1894         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
1895         CHECK_STATUS(status, NT_STATUS_OK);
1896         smb2_util_close(tree, testdirh);
1897
1898         ZERO_STRUCT(io);
1899         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
1900         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
1901         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1902         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
1903                               NTCREATEX_SHARE_ACCESS_READ |
1904                               NTCREATEX_SHARE_ACCESS_WRITE);
1905         io.in.fname = fname;
1906
1907         /*
1908          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
1909          * controls behaviour of Apple's SMB2 extensions for the whole
1910          * session!
1911          */
1912
1913         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
1914         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
1915         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1916                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1917                              SMB2_CRTCTX_AAPL_MODEL_INFO));
1918         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1919                               SMB2_CRTCTX_AAPL_UNIX_BASED |
1920                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
1921
1922         torture_comment(tctx, "Testing SMB2 create context AAPL\n");
1923         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
1924         CHECK_STATUS(status, NT_STATUS_OK);
1925
1926         status = smb2_create(tree, tctx, &io);
1927         CHECK_STATUS(status, NT_STATUS_OK);
1928         status = smb2_util_close(tree, io.out.file.handle);
1929         CHECK_STATUS(status, NT_STATUS_OK);
1930
1931         /*
1932          * Now check returned AAPL context
1933          */
1934         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
1935
1936         aapl = smb2_create_blob_find(&io.out.blobs,
1937                                      SMB2_CREATE_TAG_AAPL);
1938
1939         if (aapl == NULL) {
1940                 torture_result(tctx, TORTURE_FAIL,
1941                                "(%s) unexpectedly no AAPL capabilities were returned.",
1942                                __location__);
1943                 ret = false;
1944                 goto done;
1945         }
1946
1947         if (aapl->data.length != 50) {
1948                 /*
1949                  * uint32_t CommandCode = kAAPL_SERVER_QUERY
1950                  * uint32_t Reserved = 0;
1951                  * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
1952                  *                        kAAPL_VOLUME_CAPS |
1953                  *                        kAAPL_MODEL_INFO;
1954                  * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
1955                  *                       kAAPL_SUPPORTS_OSX_COPYFILE;
1956                  * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
1957                  *                       kAAPL_CASE_SENSITIVE;
1958                  * uint32_t Pad2 = 0;
1959                  * uint32_t ModelStringLen = 10;
1960                  * ucs2_t ModelString[5] = "Samba";
1961                  */
1962                 torture_warning(tctx,
1963                                 "(%s) unexpected AAPL context length: %zd, expected 50",
1964                                 __location__, aapl->data.length);
1965         }
1966
1967         aapl_cmd = IVAL(aapl->data.data, 0);
1968         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
1969                 torture_result(tctx, TORTURE_FAIL,
1970                                "(%s) unexpected cmd: %d",
1971                                __location__, (int)aapl_cmd);
1972                 ret = false;
1973                 goto done;
1974         }
1975
1976         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
1977         if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
1978                                   SMB2_CRTCTX_AAPL_VOLUME_CAPS |
1979                                   SMB2_CRTCTX_AAPL_MODEL_INFO)) {
1980                 torture_result(tctx, TORTURE_FAIL,
1981                                "(%s) unexpected reply_bitmap: %d",
1982                                __location__, (int)aapl_reply_bitmap);
1983                 ret = false;
1984                 goto done;
1985         }
1986
1987         aapl_server_caps = BVAL(aapl->data.data, 16);
1988         if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
1989                                  SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
1990                                  SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
1991                                  SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
1992                 torture_result(tctx, TORTURE_FAIL,
1993                                "(%s) unexpected server_caps: %d",
1994                                __location__, (int)aapl_server_caps);
1995                 ret = false;
1996                 goto done;
1997         }
1998
1999         aapl_vol_caps = BVAL(aapl->data.data, 24);
2000         if (aapl_vol_caps != SMB2_CRTCTX_AAPL_CASE_SENSITIVE) {
2001                 /* this will fail on a case insensitive fs ... */
2002                 torture_warning(tctx,
2003                                 "(%s) unexpected vol_caps: %d",
2004                                 __location__, (int)aapl_vol_caps);
2005         }
2006
2007         ret = convert_string_talloc(mem_ctx,
2008                                     CH_UTF16LE, CH_UNIX,
2009                                     aapl->data.data + 40, 10,
2010                                     &model, NULL);
2011         if (ret == false) {
2012                 torture_result(tctx, TORTURE_FAIL,
2013                                "(%s) convert_string_talloc() failed",
2014                                __location__);
2015                 goto done;
2016         }
2017         torture_comment(tctx, "Got server model: \"%s\"\n", model);
2018
2019         /*
2020          * Now that Requested AAPL extensions are enabled, setup some
2021          * Mac files with metadata and resource fork
2022          */
2023         ret = torture_setup_file(mem_ctx, tree, fname, false);
2024         if (ret == false) {
2025                 torture_result(tctx, TORTURE_FAIL,
2026                                "(%s) torture_setup_file() failed",
2027                                __location__);
2028                 goto done;
2029         }
2030
2031         info = torture_afpinfo_new(mem_ctx);
2032         if (info == NULL) {
2033                 torture_result(tctx, TORTURE_FAIL,
2034                                "(%s) torture_afpinfo_new() failed",
2035                                __location__);
2036                 ret = false;
2037                 goto done;
2038         }
2039
2040         memcpy(info->afpi_FinderInfo, type_creator, 8);
2041         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2042         if (ret == false) {
2043                 torture_result(tctx, TORTURE_FAIL,
2044                                "(%s) torture_write_afpinfo() failed",
2045                                __location__);
2046                 goto done;
2047         }
2048
2049         ret = write_stream(tree, __location__, tctx, mem_ctx,
2050                            fname, AFPRESOURCE_STREAM_NAME,
2051                            0, 3, "foo");
2052         if (ret == false) {
2053                 torture_result(tctx, TORTURE_FAIL,
2054                                "(%s) write_stream() failed",
2055                                __location__);
2056                 goto done;
2057         }
2058
2059         /*
2060          * Ok, file is prepared, now call smb2/find
2061          */
2062
2063         ZERO_STRUCT(io);
2064         io.in.desired_access = SEC_RIGHTS_DIR_READ;
2065         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2066         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2067         io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
2068                               NTCREATEX_SHARE_ACCESS_WRITE |
2069                               NTCREATEX_SHARE_ACCESS_DELETE);
2070         io.in.create_disposition = NTCREATEX_DISP_OPEN;
2071         io.in.fname = BASEDIR;
2072         status = smb2_create(tree, tctx, &io);
2073         CHECK_STATUS(status, NT_STATUS_OK);
2074
2075         ZERO_STRUCT(f);
2076         f.in.file.handle        = io.out.file.handle;
2077         f.in.pattern            = "test_aapl";
2078         f.in.continue_flags     = SMB2_CONTINUE_FLAG_SINGLE;
2079         f.in.max_response_size  = 0x1000;
2080         f.in.level              = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
2081
2082         status = smb2_find_level(tree, tree, &f, &count, &d);
2083         CHECK_STATUS(status, NT_STATUS_OK);
2084
2085         status = smb2_util_close(tree, io.out.file.handle);
2086         CHECK_STATUS(status, NT_STATUS_OK);
2087
2088         if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
2089                 torture_result(tctx, TORTURE_FAIL,
2090                                "(%s) write_stream() failed",
2091                                __location__);
2092                 ret = false;
2093                 goto done;
2094         }
2095
2096         if (d[0].id_both_directory_info.short_name.private_length != 24) {
2097                 torture_result(tctx, TORTURE_FAIL,
2098                                "(%s) bad short_name length %" PRIu32 ", expected 24",
2099                                __location__, d[0].id_both_directory_info.short_name.private_length);
2100                 ret = false;
2101                 goto done;
2102         }
2103
2104         torture_comment(tctx, "short_name buffer:\n");
2105         dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
2106
2107         /*
2108          * Extract data as specified by the AAPL extension:
2109          * - ea_size contains max_access
2110          * - short_name contains resource fork length + FinderInfo
2111          * - reserved2 contains the unix mode
2112          */
2113         torture_comment(tctx, "mac_access: %" PRIx32 "\n",
2114                         d[0].id_both_directory_info.ea_size);
2115
2116         rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
2117         if (rfork_len != 3) {
2118                 torture_result(tctx, TORTURE_FAIL,
2119                                "(%s) expected resource fork length 3, got: %" PRIu64,
2120                                __location__, rfork_len);
2121                 ret = false;
2122                 goto done;
2123         }
2124
2125         memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
2126         type_creator_buf[8] = 0;
2127         if (strcmp(type_creator, type_creator_buf) != 0) {
2128                 torture_result(tctx, TORTURE_FAIL,
2129                                "(%s) expected type/creator \"%s\" , got: %s",
2130                                __location__, type_creator, type_creator_buf);
2131                 ret = false;
2132                 goto done;
2133         }
2134
2135 done:
2136         smb2_util_unlink(tree, fname);
2137         smb2_deltree(tree, BASEDIR);
2138         talloc_free(mem_ctx);
2139         return ret;
2140 }
2141
2142 static uint64_t patt_hash(uint64_t off)
2143 {
2144         return off;
2145 }
2146
2147 static bool write_pattern(struct torture_context *torture,
2148                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2149                           struct smb2_handle h, uint64_t off, uint64_t len,
2150                           uint64_t patt_off)
2151 {
2152         NTSTATUS status;
2153         uint64_t i;
2154         uint8_t *buf;
2155         uint64_t io_sz = MIN(1024 * 64, len);
2156
2157         if (len == 0) {
2158                 return true;
2159         }
2160
2161         torture_assert(torture, (len % 8) == 0, "invalid write len");
2162
2163         buf = talloc_zero_size(mem_ctx, io_sz);
2164         torture_assert(torture, (buf != NULL), "no memory for file data buf");
2165
2166         while (len > 0) {
2167                 for (i = 0; i <= io_sz - 8; i += 8) {
2168                         SBVAL(buf, i, patt_hash(patt_off));
2169                         patt_off += 8;
2170                 }
2171
2172                 status = smb2_util_write(tree, h,
2173                                          buf, off, io_sz);
2174                 torture_assert_ntstatus_ok(torture, status, "file write");
2175
2176                 len -= io_sz;
2177                 off += io_sz;
2178         }
2179
2180         talloc_free(buf);
2181
2182         return true;
2183 }
2184
2185 static bool check_pattern(struct torture_context *torture,
2186                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2187                           struct smb2_handle h, uint64_t off, uint64_t len,
2188                           uint64_t patt_off)
2189 {
2190         if (len == 0) {
2191                 return true;
2192         }
2193
2194         torture_assert(torture, (len % 8) == 0, "invalid read len");
2195
2196         while (len > 0) {
2197                 uint64_t i;
2198                 struct smb2_read r;
2199                 NTSTATUS status;
2200                 uint64_t io_sz = MIN(1024 * 64, len);
2201
2202                 ZERO_STRUCT(r);
2203                 r.in.file.handle = h;
2204                 r.in.length      = io_sz;
2205                 r.in.offset      = off;
2206                 status = smb2_read(tree, mem_ctx, &r);
2207                 torture_assert_ntstatus_ok(torture, status, "read");
2208
2209                 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
2210                                          "read data len mismatch");
2211
2212                 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
2213                         uint64_t data = BVAL(r.out.data.data, i);
2214                         torture_assert_u64_equal(torture, data, patt_hash(patt_off),
2215                                                  talloc_asprintf(torture, "read data "
2216                                                                  "pattern bad at %llu\n",
2217                                                                  (unsigned long long)off + i));
2218                 }
2219                 talloc_free(r.out.data.data);
2220                 len -= io_sz;
2221                 off += io_sz;
2222         }
2223
2224         return true;
2225 }
2226
2227 static bool test_setup_open(struct torture_context *torture,
2228                             struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2229                             const char *fname,
2230                             struct smb2_handle *fh,
2231                             uint32_t desired_access,
2232                             uint32_t file_attributes)
2233 {
2234         struct smb2_create io;
2235         NTSTATUS status;
2236
2237         ZERO_STRUCT(io);
2238         io.in.desired_access = desired_access;
2239         io.in.file_attributes = file_attributes;
2240         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
2241         io.in.share_access =
2242                 NTCREATEX_SHARE_ACCESS_DELETE|
2243                 NTCREATEX_SHARE_ACCESS_READ|
2244                 NTCREATEX_SHARE_ACCESS_WRITE;
2245         if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
2246                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2247         }
2248         io.in.fname = fname;
2249
2250         status = smb2_create(tree, mem_ctx, &io);
2251         torture_assert_ntstatus_ok(torture, status, "file create");
2252
2253         *fh = io.out.file.handle;
2254
2255         return true;
2256 }
2257
2258 static bool test_setup_create_fill(struct torture_context *torture,
2259                                    struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2260                                    const char *fname,
2261                                    struct smb2_handle *fh,
2262                                    uint64_t size,
2263                                    uint32_t desired_access,
2264                                    uint32_t file_attributes)
2265 {
2266         bool ok;
2267
2268         ok = test_setup_open(torture, tree, mem_ctx,
2269                              fname,
2270                              fh,
2271                              desired_access,
2272                              file_attributes);
2273         torture_assert(torture, ok, "file open");
2274
2275         if (size > 0) {
2276                 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
2277                 torture_assert(torture, ok, "write pattern");
2278         }
2279         return true;
2280 }
2281
2282 static bool test_setup_copy_chunk(struct torture_context *torture,
2283                                   struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
2284                                   uint32_t nchunks,
2285                                   struct smb2_handle *src_h,
2286                                   uint64_t src_size,
2287                                   uint32_t src_desired_access,
2288                                   struct smb2_handle *dest_h,
2289                                   uint64_t dest_size,
2290                                   uint32_t dest_desired_access,
2291                                   struct srv_copychunk_copy *cc_copy,
2292                                   union smb_ioctl *io)
2293 {
2294         struct req_resume_key_rsp res_key;
2295         bool ok;
2296         NTSTATUS status;
2297         enum ndr_err_code ndr_ret;
2298
2299         ok = test_setup_create_fill(torture, tree, mem_ctx, FNAME_CC_SRC,
2300                                     src_h, src_size, src_desired_access,
2301                                     FILE_ATTRIBUTE_NORMAL);
2302         torture_assert(torture, ok, "src file create fill");
2303
2304         ok = test_setup_create_fill(torture, tree, mem_ctx, FNAME_CC_DST,
2305                                     dest_h, dest_size, dest_desired_access,
2306                                     FILE_ATTRIBUTE_NORMAL);
2307         torture_assert(torture, ok, "dest file create fill");
2308
2309         ZERO_STRUCTPN(io);
2310         io->smb2.level = RAW_IOCTL_SMB2;
2311         io->smb2.in.file.handle = *src_h;
2312         io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
2313         /* Allow for Key + ContextLength + Context */
2314         io->smb2.in.max_response_size = 32;
2315         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2316
2317         status = smb2_ioctl(tree, mem_ctx, &io->smb2);
2318         torture_assert_ntstatus_ok(torture, status,
2319                                    "FSCTL_SRV_REQUEST_RESUME_KEY");
2320
2321         ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
2322                         (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
2323
2324         torture_assert_ndr_success(torture, ndr_ret,
2325                                    "ndr_pull_req_resume_key_rsp");
2326
2327         ZERO_STRUCTPN(io);
2328         io->smb2.level = RAW_IOCTL_SMB2;
2329         io->smb2.in.file.handle = *dest_h;
2330         io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
2331         io->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
2332         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
2333
2334         ZERO_STRUCTPN(cc_copy);
2335         memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
2336         cc_copy->chunk_count = nchunks;
2337         cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
2338         torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
2339
2340         return true;
2341 }
2342
2343
2344 static bool check_copy_chunk_rsp(struct torture_context *torture,
2345                                  struct srv_copychunk_rsp *cc_rsp,
2346                                  uint32_t ex_chunks_written,
2347                                  uint32_t ex_chunk_bytes_written,
2348                                  uint32_t ex_total_bytes_written)
2349 {
2350         torture_assert_int_equal(torture, cc_rsp->chunks_written,
2351                                  ex_chunks_written, "num chunks");
2352         torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
2353                                  ex_chunk_bytes_written, "chunk bytes written");
2354         torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
2355                                  ex_total_bytes_written, "chunk total bytes");
2356         return true;
2357 }
2358
2359 static bool neg_aapl_copyfile(struct torture_context *tctx,
2360                               struct smb2_tree *tree,
2361                               uint64_t flags)
2362 {
2363         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2364         const char *fname = "aapl";
2365         NTSTATUS status;
2366         struct smb2_create io;
2367         DATA_BLOB data;
2368         struct smb2_create_blob *aapl = NULL;
2369         uint32_t aapl_cmd;
2370         uint32_t aapl_reply_bitmap;
2371         uint32_t aapl_server_caps;
2372         bool ret = true;
2373
2374         ZERO_STRUCT(io);
2375         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
2376         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
2377         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
2378         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
2379                               NTCREATEX_SHARE_ACCESS_READ |
2380                               NTCREATEX_SHARE_ACCESS_WRITE);
2381         io.in.fname = fname;
2382
2383         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
2384         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
2385         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
2386         SBVAL(data.data, 16, flags);
2387
2388         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
2389         CHECK_STATUS(status, NT_STATUS_OK);
2390
2391         status = smb2_create(tree, tctx, &io);
2392         CHECK_STATUS(status, NT_STATUS_OK);
2393
2394         aapl = smb2_create_blob_find(&io.out.blobs,
2395                                      SMB2_CREATE_TAG_AAPL);
2396         if (aapl == NULL) {
2397                 ret = false;
2398                 goto done;
2399
2400         }
2401         if (aapl->data.length < 24) {
2402                 ret = false;
2403                 goto done;
2404         }
2405
2406         aapl_cmd = IVAL(aapl->data.data, 0);
2407         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
2408                 torture_result(tctx, TORTURE_FAIL,
2409                                "(%s) unexpected cmd: %d",
2410                                __location__, (int)aapl_cmd);
2411                 ret = false;
2412                 goto done;
2413         }
2414
2415         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
2416         if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
2417                 torture_result(tctx, TORTURE_FAIL,
2418                                "(%s) unexpected reply_bitmap: %d",
2419                                __location__, (int)aapl_reply_bitmap);
2420                 ret = false;
2421                 goto done;
2422         }
2423
2424         aapl_server_caps = BVAL(aapl->data.data, 16);
2425         if (!(aapl_server_caps & flags)) {
2426                 torture_result(tctx, TORTURE_FAIL,
2427                                "(%s) unexpected server_caps: %d",
2428                                __location__, (int)aapl_server_caps);
2429                 ret = false;
2430                 goto done;
2431         }
2432
2433 done:
2434         status = smb2_util_close(tree, io.out.file.handle);
2435         CHECK_STATUS(status, NT_STATUS_OK);
2436
2437         smb2_util_unlink(tree, "aapl");
2438         talloc_free(mem_ctx);
2439         return ret;
2440 }
2441
2442 static bool test_copyfile(struct torture_context *torture,
2443                           struct smb2_tree *tree)
2444 {
2445         struct smb2_handle src_h;
2446         struct smb2_handle dest_h;
2447         NTSTATUS status;
2448         union smb_ioctl io;
2449         TALLOC_CTX *tmp_ctx = talloc_new(tree);
2450         struct srv_copychunk_copy cc_copy;
2451         struct srv_copychunk_rsp cc_rsp;
2452         enum ndr_err_code ndr_ret;
2453         bool ok;
2454
2455         /*
2456          * First test a copy_chunk with a 0 chunk count without having
2457          * enabled this via AAPL. The request must not fail and the
2458          * copied length in the response must be 0. This is verified
2459          * against Windows 2008r2.
2460          */
2461
2462         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2463                                    0, /* 0 chunks, copyfile semantics */
2464                                    &src_h, 4096, /* fill 4096 byte src file */
2465                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2466                                    &dest_h, 0,  /* 0 byte dest file */
2467                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2468                                    &cc_copy,
2469                                    &io);
2470         if (!ok) {
2471                 torture_fail_goto(torture, done, "setup copy chunk error");
2472         }
2473
2474         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2475                                        &cc_copy,
2476                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2477         torture_assert_ndr_success(torture, ndr_ret,
2478                                    "ndr_push_srv_copychunk_copy");
2479
2480         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2481         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2482
2483         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2484                                        &cc_rsp,
2485                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2486         torture_assert_ndr_success(torture, ndr_ret,
2487                                    "ndr_pull_srv_copychunk_rsp");
2488
2489         ok = check_copy_chunk_rsp(torture, &cc_rsp,
2490                                   0,    /* chunks written */
2491                                   0,    /* chunk bytes unsuccessfully written */
2492                                   0); /* total bytes written */
2493         if (!ok) {
2494                 torture_fail_goto(torture, done, "bad copy chunk response data");
2495         }
2496
2497         /*
2498          * Now enable AAPL copyfile and test again, the file and the
2499          * stream must be copied by the server.
2500          */
2501         ok = neg_aapl_copyfile(torture, tree,
2502                                SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
2503         if (!ok) {
2504                 torture_skip_goto(torture, done, "missing AAPL copyfile");
2505                 goto done;
2506         }
2507
2508         smb2_util_close(tree, src_h);
2509         smb2_util_close(tree, dest_h);
2510         smb2_util_unlink(tree, FNAME_CC_SRC);
2511         smb2_util_unlink(tree, FNAME_CC_DST);
2512
2513         ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
2514         if (!ok) {
2515                 torture_fail(torture, "setup file error");
2516         }
2517         ok = write_stream(tree, __location__, torture, tmp_ctx,
2518                             FNAME_CC_SRC, AFPRESOURCE_STREAM,
2519                             10, 10, "1234567890");
2520         if (!ok) {
2521                 torture_fail(torture, "setup stream error");
2522         }
2523
2524         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
2525                                    0, /* 0 chunks, copyfile semantics */
2526                                    &src_h, 4096, /* fill 4096 byte src file */
2527                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2528                                    &dest_h, 0,  /* 0 byte dest file */
2529                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
2530                                    &cc_copy,
2531                                    &io);
2532         if (!ok) {
2533                 torture_fail_goto(torture, done, "setup copy chunk error");
2534         }
2535
2536         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
2537                                        &cc_copy,
2538                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
2539         torture_assert_ndr_success(torture, ndr_ret,
2540                                    "ndr_push_srv_copychunk_copy");
2541
2542         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
2543         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
2544
2545         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
2546                                        &cc_rsp,
2547                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
2548         torture_assert_ndr_success(torture, ndr_ret,
2549                                    "ndr_pull_srv_copychunk_rsp");
2550
2551         ok = check_copy_chunk_rsp(torture, &cc_rsp,
2552                                   0,    /* chunks written */
2553                                   0,    /* chunk bytes unsuccessfully written */
2554                                   4096); /* total bytes written */
2555         if (!ok) {
2556                 torture_fail_goto(torture, done, "bad copy chunk response data");
2557         }
2558
2559         ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
2560                              SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
2561         if (!ok) {
2562                 torture_fail_goto(torture, done,"open failed");
2563         }
2564         ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
2565         if (!ok) {
2566                 torture_fail_goto(torture, done, "inconsistent file data");
2567         }
2568
2569         ok = check_stream(tree, __location__, torture, tmp_ctx,
2570                             FNAME_CC_DST, AFPRESOURCE_STREAM,
2571                             0, 20, 10, 10, "1234567890");
2572         if (!ok) {
2573                 torture_fail_goto(torture, done, "inconsistent stream data");
2574         }
2575
2576 done:
2577         smb2_util_close(tree, src_h);
2578         smb2_util_close(tree, dest_h);
2579         smb2_util_unlink(tree, FNAME_CC_SRC);
2580         smb2_util_unlink(tree, FNAME_CC_DST);
2581         talloc_free(tmp_ctx);
2582         return true;
2583 }
2584
2585 static bool check_stream_list(struct smb2_tree *tree,
2586                               struct torture_context *tctx,
2587                               const char *fname,
2588                               int num_exp,
2589                               const char **exp,
2590                               bool is_dir)
2591 {
2592         bool ret = true;
2593         union smb_fileinfo finfo;
2594         NTSTATUS status;
2595         int i;
2596         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
2597         char **exp_sort;
2598         struct stream_struct *stream_sort;
2599         struct smb2_create create;
2600         struct smb2_handle h;
2601
2602         ZERO_STRUCT(h);
2603         torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
2604
2605         ZERO_STRUCT(create);
2606         create.in.fname = fname;
2607         create.in.create_disposition = NTCREATEX_DISP_OPEN;
2608         create.in.desired_access = SEC_FILE_ALL;
2609         create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
2610         create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
2611         status = smb2_create(tree, tmp_ctx, &create);
2612         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
2613         h = create.out.file.handle;
2614
2615         finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
2616         finfo.generic.in.file.handle = h;
2617
2618         status = smb2_getinfo_file(tree, tctx, &finfo);
2619         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
2620
2621         smb2_util_close(tree, h);
2622
2623         torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
2624                                       ret, done, "stream count");
2625
2626         if (num_exp == 0) {
2627                 TALLOC_FREE(tmp_ctx);
2628                 goto done;
2629         }
2630
2631         exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
2632         torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
2633
2634         TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
2635
2636         stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
2637                                     finfo.stream_info.out.num_streams *
2638                                     sizeof(*stream_sort));
2639         torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
2640
2641         TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
2642
2643         for (i=0; i<num_exp; i++) {
2644                 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
2645                                 i, exp_sort[i], stream_sort[i].stream_name.s);
2646                 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
2647                                               ret, done, "stream name");
2648         }
2649
2650 done:
2651         TALLOC_FREE(tmp_ctx);
2652         return ret;
2653 }
2654
2655 /*
2656   test stream names
2657 */
2658 static bool test_stream_names(struct torture_context *tctx,
2659                               struct smb2_tree *tree)
2660 {
2661         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2662         NTSTATUS status;
2663         struct smb2_create create;
2664         struct smb2_handle h;
2665         const char *fname = BASEDIR "\\stream_names.txt";
2666         const char *sname1;
2667         bool ret;
2668         /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
2669         const char *streams[] = {
2670                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
2671                 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
2672                 "::$DATA"
2673         };
2674         const char *localdir = NULL;
2675
2676         localdir = torture_setting_string(tctx, "localdir", NULL);
2677         if (localdir == NULL) {
2678                 torture_skip(tctx, "Need localdir for test");
2679         }
2680
2681         sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
2682
2683         /* clean slate ...*/
2684         smb2_util_unlink(tree, fname);
2685         smb2_deltree(tree, fname);
2686         smb2_deltree(tree, BASEDIR);
2687
2688         status = torture_smb2_testdir(tree, BASEDIR, &h);
2689         CHECK_STATUS(status, NT_STATUS_OK);
2690         smb2_util_close(tree, h);
2691
2692         torture_comment(tctx, "(%s) testing stream names\n", __location__);
2693         ZERO_STRUCT(create);
2694         create.in.desired_access = SEC_FILE_WRITE_DATA;
2695         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2696         create.in.share_access =
2697                 NTCREATEX_SHARE_ACCESS_DELETE|
2698                 NTCREATEX_SHARE_ACCESS_READ|
2699                 NTCREATEX_SHARE_ACCESS_WRITE;
2700         create.in.create_disposition = NTCREATEX_DISP_CREATE;
2701         create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2702         create.in.fname = sname1;
2703
2704         status = smb2_create(tree, mem_ctx, &create);
2705         CHECK_STATUS(status, NT_STATUS_OK);
2706         smb2_util_close(tree, create.out.file.handle);
2707
2708         ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
2709                                         "user.DosStream.bar:baz:$DATA",
2710                                         "data", strlen("data"));
2711         CHECK_VALUE(ret, true);
2712
2713         ret = check_stream_list(tree, tctx, fname, 3, streams, false);
2714         CHECK_VALUE(ret, true);
2715
2716 done:
2717         status = smb2_util_unlink(tree, fname);
2718         smb2_deltree(tree, BASEDIR);
2719         talloc_free(mem_ctx);
2720
2721         return ret;
2722 }
2723
2724 /* Renaming a directory with open file, should work for OS X AAPL clients */
2725 static bool test_rename_dir_openfile(struct torture_context *torture,
2726                                      struct smb2_tree *tree)
2727 {
2728         bool ret = true;
2729         NTSTATUS status;
2730         union smb_open io;
2731         union smb_close cl;
2732         union smb_setfileinfo sinfo;
2733         struct smb2_handle d1, h1;
2734         const char *renamedir = BASEDIR "-new";
2735         bool server_is_osx = torture_setting_bool(torture, "osx", false);
2736
2737         smb2_deltree(tree, BASEDIR);
2738         smb2_util_rmdir(tree, BASEDIR);
2739         smb2_deltree(tree, renamedir);
2740
2741         ZERO_STRUCT(io.smb2);
2742         io.generic.level = RAW_OPEN_SMB2;
2743         io.smb2.in.create_flags = 0;
2744         io.smb2.in.desired_access = 0x0017019f;
2745         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2746         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2747         io.smb2.in.share_access = 0;
2748         io.smb2.in.alloc_size = 0;
2749         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2750         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2751         io.smb2.in.security_flags = 0;
2752         io.smb2.in.fname = BASEDIR;
2753
2754         status = smb2_create(tree, torture, &(io.smb2));
2755         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2756         d1 = io.smb2.out.file.handle;
2757
2758         ZERO_STRUCT(io.smb2);
2759         io.generic.level = RAW_OPEN_SMB2;
2760         io.smb2.in.create_flags = 0;
2761         io.smb2.in.desired_access = 0x0017019f;
2762         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2763         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2764         io.smb2.in.share_access = 0;
2765         io.smb2.in.alloc_size = 0;
2766         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
2767         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2768         io.smb2.in.security_flags = 0;
2769         io.smb2.in.fname = BASEDIR "\\file.txt";
2770
2771         status = smb2_create(tree, torture, &(io.smb2));
2772         torture_assert_ntstatus_ok(torture, status, "smb2_create file");
2773         h1 = io.smb2.out.file.handle;
2774
2775         if (!server_is_osx) {
2776                 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
2777
2778                 ZERO_STRUCT(sinfo);
2779                 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2780                 sinfo.rename_information.in.file.handle = d1;
2781                 sinfo.rename_information.in.overwrite = 0;
2782                 sinfo.rename_information.in.root_fid = 0;
2783                 sinfo.rename_information.in.new_name = renamedir;
2784                 status = smb2_setinfo_file(tree, &sinfo);
2785
2786                 torture_assert_ntstatus_equal(torture, status,
2787                                               NT_STATUS_ACCESS_DENIED,
2788                                               "smb2_setinfo_file");
2789
2790                 ZERO_STRUCT(cl.smb2);
2791                 cl.smb2.level = RAW_CLOSE_SMB2;
2792                 cl.smb2.in.file.handle = d1;
2793                 status = smb2_close(tree, &(cl.smb2));
2794                 torture_assert_ntstatus_ok(torture, status, "smb2_close");
2795                 ZERO_STRUCT(d1);
2796         }
2797
2798         torture_comment(torture, "Enabling AAPL\n");
2799
2800         ret = enable_aapl(torture, tree);
2801         torture_assert(torture, ret == true, "enable_aapl failed");
2802
2803         torture_comment(torture, "Renaming directory with AAPL\n");
2804
2805         ZERO_STRUCT(io.smb2);
2806         io.generic.level = RAW_OPEN_SMB2;
2807         io.smb2.in.desired_access = 0x0017019f;
2808         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
2809         io.smb2.in.share_access = 0;
2810         io.smb2.in.alloc_size = 0;
2811         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
2812         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
2813         io.smb2.in.security_flags = 0;
2814         io.smb2.in.fname = BASEDIR;
2815
2816         status = smb2_create(tree, torture, &(io.smb2));
2817         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
2818         d1 = io.smb2.out.file.handle;
2819
2820         ZERO_STRUCT(sinfo);
2821         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
2822         sinfo.rename_information.in.file.handle = d1;
2823         sinfo.rename_information.in.overwrite = 0;
2824         sinfo.rename_information.in.root_fid = 0;
2825         sinfo.rename_information.in.new_name = renamedir;
2826
2827         status = smb2_setinfo_file(tree, &sinfo);
2828         torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
2829
2830         ZERO_STRUCT(cl.smb2);
2831         cl.smb2.level = RAW_CLOSE_SMB2;
2832         cl.smb2.in.file.handle = d1;
2833         status = smb2_close(tree, &(cl.smb2));
2834         torture_assert_ntstatus_ok(torture, status, "smb2_close");
2835         ZERO_STRUCT(d1);
2836
2837         cl.smb2.in.file.handle = h1;
2838         status = smb2_close(tree, &(cl.smb2));
2839         torture_assert_ntstatus_ok(torture, status, "smb2_close");
2840         ZERO_STRUCT(h1);
2841
2842         torture_comment(torture, "Cleaning up\n");
2843
2844         if (h1.data) {
2845                 ZERO_STRUCT(cl.smb2);
2846                 cl.smb2.level = RAW_CLOSE_SMB2;
2847                 cl.smb2.in.file.handle = h1;
2848                 status = smb2_close(tree, &(cl.smb2));
2849         }
2850
2851         smb2_util_unlink(tree, BASEDIR "\\file.txt");
2852         smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
2853         smb2_deltree(tree, renamedir);
2854         smb2_deltree(tree, BASEDIR);
2855         return ret;
2856 }
2857
2858 static bool test_afpinfo_enoent(struct torture_context *tctx,
2859                                 struct smb2_tree *tree)
2860 {
2861         bool ret = true;
2862         NTSTATUS status;
2863         struct smb2_create create;
2864         struct smb2_handle h1;
2865         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2866         const char *fname = BASEDIR "\\file";
2867         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
2868
2869         torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
2870
2871         smb2_deltree(tree, BASEDIR);
2872         status = torture_smb2_testdir(tree, BASEDIR, &h1);
2873         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
2874         smb2_util_close(tree, h1);
2875         ret = torture_setup_file(mem_ctx, tree, fname, false);
2876         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
2877
2878         torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
2879
2880         ZERO_STRUCT(create);
2881         create.in.create_disposition = NTCREATEX_DISP_OPEN;
2882         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
2883         create.in.fname = sname;
2884
2885         status = smb2_create(tree, mem_ctx, &create);
2886         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
2887                                            ret, done, "Got unexpected AFP_AfpInfo stream");
2888
2889 done:
2890         smb2_util_unlink(tree, fname);
2891         smb2_util_rmdir(tree, BASEDIR);
2892         return ret;
2893 }
2894
2895 static bool test_create_delete_on_close(struct torture_context *tctx,
2896                                         struct smb2_tree *tree)
2897 {
2898         bool ret = true;
2899         NTSTATUS status;
2900         struct smb2_create create;
2901         struct smb2_handle h1;
2902         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2903         const char *fname = BASEDIR "\\file";
2904         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
2905         const char *type_creator = "SMB,OLE!";
2906         AfpInfo *info = NULL;
2907         const char *streams_basic[] = {
2908                 "::$DATA"
2909         };
2910         const char *streams_afpinfo[] = {
2911                 "::$DATA",
2912                 AFPINFO_STREAM
2913         };
2914
2915         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
2916
2917         torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
2918
2919         smb2_deltree(tree, BASEDIR);
2920         status = torture_smb2_testdir(tree, BASEDIR, &h1);
2921         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
2922         smb2_util_close(tree, h1);
2923         ret = torture_setup_file(mem_ctx, tree, fname, false);
2924         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
2925
2926         torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
2927
2928         ZERO_STRUCT(create);
2929         create.in.create_disposition = NTCREATEX_DISP_OPEN;
2930         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
2931         create.in.fname = sname;
2932
2933         status = smb2_create(tree, mem_ctx, &create);
2934         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
2935                                            ret, done, "Got unexpected AFP_AfpInfo stream");
2936
2937         ZERO_STRUCT(create);
2938         create.in.create_disposition = NTCREATEX_DISP_OPEN;
2939         create.in.desired_access = SEC_FILE_ALL;
2940         create.in.fname = sname;
2941
2942         status = smb2_create(tree, mem_ctx, &create);
2943         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
2944                                            ret, done, "Got unexpected AFP_AfpInfo stream");
2945
2946         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
2947         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
2948
2949         torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
2950
2951         info = torture_afpinfo_new(mem_ctx);
2952         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
2953
2954         memcpy(info->afpi_FinderInfo, type_creator, 8);
2955         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
2956         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
2957
2958         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
2959                            0, 60, 16, 8, type_creator);
2960         torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
2961
2962         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
2963         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
2964
2965         ZERO_STRUCT(create);
2966         create.in.create_disposition = NTCREATEX_DISP_OPEN;
2967         create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
2968         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
2969         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
2970         create.in.fname = sname;
2971         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2972
2973         status = smb2_create(tree, mem_ctx, &create);
2974         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
2975
2976         h1 = create.out.file.handle;
2977         smb2_util_close(tree, h1);
2978
2979         ZERO_STRUCT(create);
2980         create.in.create_disposition = NTCREATEX_DISP_OPEN;
2981         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
2982         create.in.fname = sname;
2983         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2984         status = smb2_create(tree, mem_ctx, &create);
2985         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
2986                                            ret, done, "Got unexpected AFP_AfpInfo stream");
2987
2988         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
2989         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
2990
2991 done:
2992         smb2_util_unlink(tree, fname);
2993         smb2_util_rmdir(tree, BASEDIR);
2994         return ret;
2995 }
2996
2997 static bool test_setinfo_delete_on_close(struct torture_context *tctx,
2998                                          struct smb2_tree *tree)
2999 {
3000         bool ret = true;
3001         NTSTATUS status;
3002         struct smb2_create create;
3003         union smb_setfileinfo sfinfo;
3004         struct smb2_handle h1;
3005         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3006         const char *fname = BASEDIR "\\file";
3007         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3008         const char *type_creator = "SMB,OLE!";
3009         AfpInfo *info = NULL;
3010         const char *streams_basic[] = {
3011                 "::$DATA"
3012         };
3013
3014         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3015
3016         torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
3017
3018         smb2_deltree(tree, BASEDIR);
3019         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3020         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3021         smb2_util_close(tree, h1);
3022         ret = torture_setup_file(mem_ctx, tree, fname, false);
3023         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3024
3025         info = torture_afpinfo_new(mem_ctx);
3026         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3027         memcpy(info->afpi_FinderInfo, type_creator, 8);
3028         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3029         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3030
3031         ZERO_STRUCT(create);
3032         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3033         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3034         create.in.fname = sname;
3035         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3036         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3037
3038         status = smb2_create(tree, mem_ctx, &create);
3039         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3040
3041         h1 = create.out.file.handle;
3042
3043         /* Delete stream via setinfo delete-on-close */
3044         ZERO_STRUCT(sfinfo);
3045         sfinfo.disposition_info.in.delete_on_close = 1;
3046         sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3047         sfinfo.generic.in.file.handle = h1;
3048         status = smb2_setinfo_file(tree, &sfinfo);
3049         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3050
3051         smb2_util_close(tree, h1);
3052
3053         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3054         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3055
3056         ZERO_STRUCT(create);
3057         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3058         create.in.desired_access = SEC_FILE_ALL;
3059         create.in.fname = sname;
3060         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3061         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3062         status = smb2_create(tree, mem_ctx, &create);
3063         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3064                                            ret, done, "Got unexpected AFP_AfpInfo stream");
3065
3066 done:
3067         smb2_util_unlink(tree, fname);
3068         smb2_util_rmdir(tree, BASEDIR);
3069         return ret;
3070 }
3071
3072 static bool test_setinfo_eof(struct torture_context *tctx,
3073                              struct smb2_tree *tree)
3074 {
3075         bool ret = true;
3076         NTSTATUS status;
3077         struct smb2_create create;
3078         union smb_setfileinfo sfinfo;
3079         struct smb2_handle h1;
3080         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3081         const char *fname = BASEDIR "\\file";
3082         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
3083         const char *type_creator = "SMB,OLE!";
3084         AfpInfo *info = NULL;
3085         const char *streams_afpinfo[] = {
3086                 "::$DATA",
3087                 AFPINFO_STREAM
3088         };
3089
3090         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3091
3092         torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
3093
3094         smb2_deltree(tree, BASEDIR);
3095         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3096         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3097         smb2_util_close(tree, h1);
3098         ret = torture_setup_file(mem_ctx, tree, fname, false);
3099         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3100
3101         info = torture_afpinfo_new(mem_ctx);
3102         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3103         memcpy(info->afpi_FinderInfo, type_creator, 8);
3104         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3105         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3106
3107         ZERO_STRUCT(create);
3108         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3109         create.in.desired_access = SEC_FILE_ALL;
3110         create.in.fname = sname;
3111         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3112         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3113
3114         status = smb2_create(tree, mem_ctx, &create);
3115         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3116
3117         h1 = create.out.file.handle;
3118
3119         torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
3120
3121         /* Test setinfo end-of-file info */
3122         ZERO_STRUCT(sfinfo);
3123         sfinfo.generic.in.file.handle = h1;
3124         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3125         sfinfo.position_information.in.position = 61;
3126         status = smb2_setinfo_file(tree, &sfinfo);
3127         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
3128                                            ret, done, "set eof 61 failed");
3129
3130         torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
3131
3132         /* Truncation returns success, but has no effect */
3133         ZERO_STRUCT(sfinfo);
3134         sfinfo.generic.in.file.handle = h1;
3135         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3136         sfinfo.position_information.in.position = 1;
3137         status = smb2_setinfo_file(tree, &sfinfo);
3138         torture_assert_ntstatus_ok_goto(tctx, status,
3139                                         ret, done, "set eof 1 failed");
3140         smb2_util_close(tree, h1);
3141
3142         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3143         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3144
3145         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3146                            0, 60, 16, 8, type_creator);
3147         torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3148
3149         ZERO_STRUCT(create);
3150         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3151         create.in.desired_access = SEC_FILE_ALL;
3152         create.in.fname = sname;
3153         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3154         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3155
3156         status = smb2_create(tree, mem_ctx, &create);
3157         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3158
3159         h1 = create.out.file.handle;
3160
3161         /*
3162          * Delete stream via setinfo end-of-file info to 0, should
3163          * return success but stream MUST NOT deleted
3164          */
3165         ZERO_STRUCT(sfinfo);
3166         sfinfo.generic.in.file.handle = h1;
3167         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3168         sfinfo.position_information.in.position = 0;
3169         status = smb2_setinfo_file(tree, &sfinfo);
3170         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3171
3172         smb2_util_close(tree, h1);
3173
3174         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3175         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3176
3177         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
3178                            0, 60, 16, 8, type_creator);
3179         torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
3180
3181 done:
3182         smb2_util_unlink(tree, fname);
3183         smb2_util_rmdir(tree, BASEDIR);
3184         return ret;
3185 }
3186
3187 static bool test_afpinfo_all0(struct torture_context *tctx,
3188                               struct smb2_tree *tree)
3189 {
3190         bool ret = true;
3191         NTSTATUS status;
3192         struct smb2_handle h1;
3193         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3194         const char *fname = BASEDIR "\\file";
3195         const char *type_creator = "SMB,OLE!";
3196         AfpInfo *info = NULL;
3197         const char *streams_basic[] = {
3198                 "::$DATA"
3199         };
3200         const char *streams_afpinfo[] = {
3201                 "::$DATA",
3202                 AFPINFO_STREAM
3203         };
3204
3205         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3206
3207         torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
3208
3209         smb2_deltree(tree, BASEDIR);
3210         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3211         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3212         smb2_util_close(tree, h1);
3213         ret = torture_setup_file(mem_ctx, tree, fname, false);
3214         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3215
3216         info = torture_afpinfo_new(mem_ctx);
3217         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
3218         memcpy(info->afpi_FinderInfo, type_creator, 8);
3219         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3220         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3221
3222         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
3223         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3224
3225         /* Write all 0 to AFP_AfpInfo */
3226         memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
3227         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
3228         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
3229
3230         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3231         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3232
3233 done:
3234         smb2_util_unlink(tree, fname);
3235         smb2_util_rmdir(tree, BASEDIR);
3236         return ret;
3237 }
3238
3239 static bool test_create_delete_on_close_resource(struct torture_context *tctx,
3240                                                  struct smb2_tree *tree)
3241 {
3242         bool ret = true;
3243         NTSTATUS status;
3244         struct smb2_create create;
3245         struct smb2_handle h1;
3246         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3247         const char *fname = BASEDIR "\\file";
3248         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3249         const char *streams_basic[] = {
3250                 "::$DATA"
3251         };
3252         const char *streams_afpresource[] = {
3253                 "::$DATA",
3254                 AFPRESOURCE_STREAM
3255         };
3256
3257         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3258
3259         torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
3260
3261         smb2_deltree(tree, BASEDIR);
3262         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3263         torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
3264         smb2_util_close(tree, h1);
3265         ret = torture_setup_file(mem_ctx, tree, fname, false);
3266         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3267
3268         torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
3269
3270         ZERO_STRUCT(create);
3271         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3272         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
3273         create.in.fname = sname;
3274
3275         status = smb2_create(tree, mem_ctx, &create);
3276         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3277                                            ret, done, "Got unexpected AFP_AfpResource stream");
3278
3279         ZERO_STRUCT(create);
3280         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3281         create.in.desired_access = SEC_FILE_ALL;
3282         create.in.fname = sname;
3283
3284         status = smb2_create(tree, mem_ctx, &create);
3285         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3286                                            ret, done, "Got unexpected AFP_AfpResource stream");
3287
3288         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3289         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3290
3291         torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
3292
3293         ret = write_stream(tree, __location__, tctx, mem_ctx,
3294                            fname, AFPRESOURCE_STREAM_NAME,
3295                            0, 10, "1234567890");
3296         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3297
3298         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3299                            0, 10, 0, 10, "1234567890");
3300         torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3301
3302         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3303         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3304
3305         ZERO_STRUCT(create);
3306         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3307         create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
3308         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3309         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3310         create.in.fname = sname;
3311         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3312
3313         status = smb2_create(tree, mem_ctx, &create);
3314         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3315
3316         h1 = create.out.file.handle;
3317         smb2_util_close(tree, h1);
3318
3319         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3320         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3321
3322         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
3323                            0, 10, 0, 10, "1234567890");
3324         torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
3325
3326 done:
3327         smb2_util_unlink(tree, fname);
3328         smb2_util_rmdir(tree, BASEDIR);
3329         return ret;
3330 }
3331
3332 static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
3333                                                   struct smb2_tree *tree)
3334 {
3335         bool ret = true;
3336         NTSTATUS status;
3337         struct smb2_create create;
3338         union smb_setfileinfo sfinfo;
3339         struct smb2_handle h1;
3340         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3341         const char *fname = BASEDIR "\\file";
3342         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3343         const char *streams_afpresource[] = {
3344                 "::$DATA",
3345                 AFPRESOURCE_STREAM
3346         };
3347
3348         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3349
3350         torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
3351
3352         smb2_deltree(tree, BASEDIR);
3353         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3354         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3355         smb2_util_close(tree, h1);
3356         ret = torture_setup_file(mem_ctx, tree, fname, false);
3357         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3358
3359         ret = write_stream(tree, __location__, tctx, mem_ctx,
3360                            fname, AFPRESOURCE_STREAM_NAME,
3361                            10, 10, "1234567890");
3362         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3363
3364         ZERO_STRUCT(create);
3365         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3366         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
3367         create.in.fname = sname;
3368         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3369         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3370
3371         status = smb2_create(tree, mem_ctx, &create);
3372         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3373
3374         h1 = create.out.file.handle;
3375
3376         /* Try to delete stream via setinfo delete-on-close */
3377         ZERO_STRUCT(sfinfo);
3378         sfinfo.disposition_info.in.delete_on_close = 1;
3379         sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
3380         sfinfo.generic.in.file.handle = h1;
3381         status = smb2_setinfo_file(tree, &sfinfo);
3382         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
3383
3384         smb2_util_close(tree, h1);
3385
3386         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
3387         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3388
3389         ZERO_STRUCT(create);
3390         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3391         create.in.desired_access = SEC_FILE_ALL;
3392         create.in.fname = sname;
3393         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3394         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3395         status = smb2_create(tree, mem_ctx, &create);
3396         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
3397                                         "Got unexpected AFP_AfpResource stream");
3398
3399 done:
3400         smb2_util_unlink(tree, fname);
3401         smb2_util_rmdir(tree, BASEDIR);
3402         return ret;
3403 }
3404
3405 static bool test_setinfo_eof_resource(struct torture_context *tctx,
3406                                       struct smb2_tree *tree)
3407 {
3408         bool ret = true;
3409         NTSTATUS status;
3410         struct smb2_create create;
3411         union smb_setfileinfo sfinfo;
3412         union smb_fileinfo finfo;
3413         struct smb2_handle h1;
3414         TALLOC_CTX *mem_ctx = talloc_new(tctx);
3415         const char *fname = BASEDIR "\\file";
3416         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
3417         const char *streams_basic[] = {
3418                 "::$DATA"
3419         };
3420
3421         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
3422
3423         torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
3424
3425         smb2_deltree(tree, BASEDIR);
3426         status = torture_smb2_testdir(tree, BASEDIR, &h1);
3427         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
3428         smb2_util_close(tree, h1);
3429         ret = torture_setup_file(mem_ctx, tree, fname, false);
3430         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
3431
3432         ret = write_stream(tree, __location__, tctx, mem_ctx,
3433                            fname, AFPRESOURCE_STREAM_NAME,
3434                            10, 10, "1234567890");
3435         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
3436
3437         ZERO_STRUCT(create);
3438         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3439         create.in.desired_access = SEC_FILE_ALL;
3440         create.in.fname = sname;
3441         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3442         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3443
3444         status = smb2_create(tree, mem_ctx, &create);
3445         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3446
3447         h1 = create.out.file.handle;
3448
3449         torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
3450
3451         /* Test setinfo end-of-file info */
3452         ZERO_STRUCT(sfinfo);
3453         sfinfo.generic.in.file.handle = h1;
3454         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3455         sfinfo.position_information.in.position = 1;
3456         status = smb2_setinfo_file(tree, &sfinfo);
3457         torture_assert_ntstatus_ok_goto(tctx, status,
3458                                         ret, done, "set eof 1 failed");
3459
3460         smb2_util_close(tree, h1);
3461
3462         /* Check size == 1 */
3463         ZERO_STRUCT(create);
3464         create.in.fname = sname;
3465         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3466         create.in.desired_access = SEC_FILE_ALL;
3467         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3468         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3469         status = smb2_create(tree, mem_ctx, &create);
3470         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3471
3472         h1 = create.out.file.handle;
3473
3474         ZERO_STRUCT(finfo);
3475         finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
3476         finfo.generic.in.file.handle = h1;
3477         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
3478         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
3479
3480         smb2_util_close(tree, h1);
3481
3482         torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
3483
3484         ZERO_STRUCT(create);
3485         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3486         create.in.desired_access = SEC_FILE_ALL;
3487         create.in.fname = sname;
3488         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3489         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3490
3491         status = smb2_create(tree, mem_ctx, &create);
3492         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
3493
3494         h1 = create.out.file.handle;
3495
3496         /*
3497          * Delete stream via setinfo end-of-file info to 0, this
3498          * should delete the stream.
3499          */
3500         ZERO_STRUCT(sfinfo);
3501         sfinfo.generic.in.file.handle = h1;
3502         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
3503         sfinfo.position_information.in.position = 0;
3504         status = smb2_setinfo_file(tree, &sfinfo);
3505         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
3506
3507         smb2_util_close(tree, h1);
3508
3509         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
3510         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
3511
3512         ZERO_STRUCT(create);
3513         create.in.create_disposition = NTCREATEX_DISP_OPEN;
3514         create.in.desired_access = SEC_FILE_ALL;
3515         create.in.fname = sname;
3516         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
3517         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
3518
3519         status = smb2_create(tree, mem_ctx, &create);
3520         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3521                                            ret, done, "smb2_create failed");
3522
3523 done:
3524         smb2_util_unlink(tree, fname);
3525         smb2_util_rmdir(tree, BASEDIR);
3526         return ret;
3527 }
3528
3529 /*
3530  * Note: This test depends on "vfs objects = catia fruit streams_xattr".  For
3531  * some tests torture must be run on the host it tests and takes an additional
3532  * argument with the local path to the share:
3533  * "--option=torture:localdir=<SHAREPATH>".
3534  *
3535  * When running against an OS X SMB server add "--option=torture:osx=true"
3536  */
3537 struct torture_suite *torture_vfs_fruit(void)
3538 {
3539         struct torture_suite *suite = torture_suite_create(
3540                 talloc_autofree_context(), "fruit");
3541
3542         suite->description = talloc_strdup(suite, "vfs_fruit tests");
3543
3544         torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
3545         torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
3546         torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
3547         torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
3548         torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
3549         torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
3550         torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
3551         torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
3552         torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
3553         torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
3554         torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
3555         torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
3556         torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
3557         torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
3558         torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
3559         torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
3560         torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
3561         torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
3562         torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
3563
3564         return suite;
3565 }