LCOV - code coverage report
Current view: top level - source4/torture/vfs - fruit.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 2588 2740 94.5 %
Date: 2021-09-23 10:06:22 Functions: 69 71 97.2 %

          Line data    Source code
       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/cmdline.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             : #include "libcli/security/dom_sid.h"
      40             : #include "../librpc/gen_ndr/ndr_security.h"
      41             : #include "libcli/security/secace.h"
      42             : #include "libcli/security/security_descriptor.h"
      43             : 
      44             : #define BASEDIR "vfs_fruit_dir"
      45             : #define FNAME_CC_SRC "testfsctl.dat"
      46             : #define FNAME_CC_DST "testfsctl2.dat"
      47             : 
      48             : #define CHECK_STATUS(status, correct) do { \
      49             :         if (!NT_STATUS_EQUAL(status, correct)) { \
      50             :                 torture_result(tctx, TORTURE_FAIL, \
      51             :                     "(%s) Incorrect status %s - should be %s\n", \
      52             :                     __location__, nt_errstr(status), nt_errstr(correct)); \
      53             :                 ret = false; \
      54             :                 goto done; \
      55             :         }} while (0)
      56             : 
      57             : #define CHECK_VALUE(v, correct) do { \
      58             :         if ((v) != (correct)) { \
      59             :                 torture_result(tctx, TORTURE_FAIL, \
      60             :                                "(%s) Incorrect value %s=%u - should be %u\n", \
      61             :                                __location__, #v, (unsigned)v, (unsigned)correct); \
      62             :                 ret = false; \
      63             :                 goto done; \
      64             :         }} while (0)
      65             : 
      66             : static bool check_stream_list(struct smb2_tree *tree,
      67             :                               struct torture_context *tctx,
      68             :                               const char *fname,
      69             :                               int num_exp,
      70             :                               const char **exp,
      71             :                               bool is_dir);
      72             : 
      73        1170 : static int qsort_string(char * const *s1, char * const *s2)
      74             : {
      75        1170 :         return strcmp(*s1, *s2);
      76             : }
      77             : 
      78        1184 : static int qsort_stream(const struct stream_struct * s1, const struct stream_struct *s2)
      79             : {
      80        1184 :         return strcmp(s1->stream_name.s, s2->stream_name.s);
      81             : }
      82             : 
      83             : /*
      84             :  * REVIEW:
      85             :  * This is hokey, but what else can we do?
      86             :  */
      87             : #if defined(HAVE_ATTROPEN) || defined(FREEBSD)
      88             : #define AFPINFO_EA_NETATALK "org.netatalk.Metadata"
      89             : #define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork"
      90             : #else
      91             : #define AFPINFO_EA_NETATALK "user.org.netatalk.Metadata"
      92             : #define AFPRESOURCE_EA_NETATALK "user.org.netatalk.ResourceFork"
      93             : #endif
      94             : 
      95             : /*
      96             : The metadata xattr char buf below contains the following attributes:
      97             : 
      98             : -------------------------------------------------------------------------------
      99             : Entry ID   : 00000008 : File Dates Info
     100             : Offset     : 00000162 : 354
     101             : Length     : 00000010 : 16
     102             : 
     103             : -DATE------:          : (GMT)                    : (Local)
     104             : create     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
     105             : modify     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
     106             : backup     : 80000000 : Unknown or Initial
     107             : access     : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014
     108             : 
     109             : -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
     110             : 00000000   : 1B 44 21 69 1B 44 21 69 80 00 00 00 1B 44 21 69 : .D!i.D!i.....D!i
     111             : 
     112             : -------------------------------------------------------------------------------
     113             : Entry ID   : 00000009 : Finder Info
     114             : Offset     : 0000007A : 122
     115             : Length     : 00000020 : 32
     116             : 
     117             : -FInfo-----:
     118             : Type       : 42415252 : BARR
     119             : Creator    : 464F4F4F : FOOO
     120             : isAlias    : 0
     121             : Invisible  : 1
     122             : hasBundle  : 0
     123             : nameLocked : 0
     124             : Stationery : 0
     125             : CustomIcon : 0
     126             : Reserved   : 0
     127             : Inited     : 0
     128             : NoINITS    : 0
     129             : Shared     : 0
     130             : SwitchLaunc: 0
     131             : Hidden Ext : 0
     132             : color      : 000      : none
     133             : isOnDesk   : 0
     134             : Location v : 0000     : 0
     135             : Location h : 0000     : 0
     136             : Fldr       : 0000     : ..
     137             : 
     138             : -FXInfo----:
     139             : Rsvd|IconID: 0000     : 0
     140             : Rsvd       : 0000     : ..
     141             : Rsvd       : 0000     : ..
     142             : Rsvd       : 0000     : ..
     143             : AreInvalid : 0
     144             : unknown bit: 0
     145             : unknown bit: 0
     146             : unknown bit: 0
     147             : unknown bit: 0
     148             : unknown bit: 0
     149             : unknown bit: 0
     150             : CustomBadge: 0
     151             : ObjctIsBusy: 0
     152             : unknown bit: 0
     153             : unknown bit: 0
     154             : unknown bit: 0
     155             : unknown bit: 0
     156             : RoutingInfo: 0
     157             : unknown bit: 0
     158             : unknown bit: 0
     159             : Rsvd|commnt: 0000     : 0
     160             : PutAway    : 00000000 : 0
     161             : 
     162             : -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
     163             : 00000000   : 42 41 52 52 46 4F 4F 4F 40 00 00 00 00 00 00 00 : BARRFOOO@.......
     164             : 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     165             : 
     166             : -------------------------------------------------------------------------------
     167             : Entry ID   : 0000000E : AFP File Info
     168             : Offset     : 00000172 : 370
     169             : Length     : 00000004 : 4
     170             : 
     171             : -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
     172             : 00000000   : 00 00 01 A1                                     : ....
     173             :  */
     174             : 
     175             : char metadata_xattr[] = {
     176             :         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
     177             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     178             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     179             :         0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
     180             :         0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     181             :         0x00, 0x08, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00,
     182             :         0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
     183             :         0x00, 0x7a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
     184             :         0x00, 0x0e, 0x00, 0x00, 0x01, 0x72, 0x00, 0x00,
     185             :         0x00, 0x04, 0x80, 0x44, 0x45, 0x56, 0x00, 0x00,
     186             :         0x01, 0x76, 0x00, 0x00, 0x00, 0x08, 0x80, 0x49,
     187             :         0x4e, 0x4f, 0x00, 0x00, 0x01, 0x7e, 0x00, 0x00,
     188             :         0x00, 0x08, 0x80, 0x53, 0x59, 0x4e, 0x00, 0x00,
     189             :         0x01, 0x86, 0x00, 0x00, 0x00, 0x08, 0x80, 0x53,
     190             :         0x56, 0x7e, 0x00, 0x00, 0x01, 0x8e, 0x00, 0x00,
     191             :         0x00, 0x04, 0x42, 0x41, 0x52, 0x52, 0x46, 0x4f,
     192             :         0x4f, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
     193             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     194             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     195             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     196             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     197             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     198             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     199             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     200             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     201             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     202             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     203             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     204             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     205             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     206             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     207             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     208             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     209             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     210             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     211             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     212             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     213             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     214             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     215             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     216             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     217             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     218             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     219             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     220             :         0x00, 0x00, 0x1b, 0x44, 0x21, 0x69, 0x1b, 0x44,
     221             :         0x21, 0x69, 0x80, 0x00, 0x00, 0x00, 0x1b, 0x44,
     222             :         0x21, 0x69, 0x00, 0x00, 0x01, 0xa1, 0x00, 0xfd,
     223             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x20,
     224             :         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xe3,
     225             :         0x86, 0x53, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x01,
     226             :         0x00, 0x00
     227             : };
     228             : 
     229             : /*
     230             : The buf below contains the following AppleDouble encoded data:
     231             : 
     232             : -------------------------------------------------------------------------------
     233             : MagicNumber: 00051607                                        : AppleDouble
     234             : Version    : 00020000                                        : Version 2
     235             : Filler     : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
     236             : Num. of ent: 0002                                            : 2
     237             : 
     238             : -------------------------------------------------------------------------------
     239             : Entry ID   : 00000009 : Finder Info
     240             : Offset     : 00000032 : 50
     241             : Length     : 00000EB0 : 3760
     242             : 
     243             : -FInfo-----:
     244             : Type       : 54455354 : TEST
     245             : Creator    : 534C4F57 : SLOW
     246             : isAlias    : 0
     247             : Invisible  : 0
     248             : hasBundle  : 0
     249             : nameLocked : 0
     250             : Stationery : 0
     251             : CustomIcon : 0
     252             : Reserved   : 0
     253             : Inited     : 0
     254             : NoINITS    : 0
     255             : Shared     : 0
     256             : SwitchLaunc: 0
     257             : Hidden Ext : 0
     258             : color      : 100      : blue
     259             : isOnDesk   : 0
     260             : Location v : 0000     : 0
     261             : Location h : 0000     : 0
     262             : Fldr       : 0000     : ..
     263             : 
     264             : -FXInfo----:
     265             : Rsvd|IconID: 0000     : 0
     266             : Rsvd       : 0000     : ..
     267             : Rsvd       : 0000     : ..
     268             : Rsvd       : 0000     : ..
     269             : AreInvalid : 0
     270             : unknown bit: 0
     271             : unknown bit: 0
     272             : unknown bit: 0
     273             : unknown bit: 0
     274             : unknown bit: 0
     275             : unknown bit: 0
     276             : CustomBadge: 0
     277             : ObjctIsBusy: 0
     278             : unknown bit: 0
     279             : unknown bit: 0
     280             : unknown bit: 0
     281             : unknown bit: 0
     282             : RoutingInfo: 0
     283             : unknown bit: 0
     284             : unknown bit: 0
     285             : Rsvd|commnt: 0000     : 0
     286             : PutAway    : 00000000 : 0
     287             : 
     288             : -EA--------:
     289             : pad        : 0000     : ..
     290             : magic      : 41545452 : ATTR
     291             : debug_tag  : 53D4580C : 1406425100
     292             : total_size : 00000EE2 : 3810
     293             : data_start : 000000BC : 188
     294             : data_length: 0000005E : 94
     295             : reserved[0]: 00000000 : ....
     296             : reserved[1]: 00000000 : ....
     297             : reserved[2]: 00000000 : ....
     298             : flags      : 0000     : ..
     299             : num_attrs  : 0002     : 2
     300             : -EA ENTRY--:
     301             : offset     : 000000BC : 188
     302             : length     : 0000005B : 91
     303             : flags      : 0000     : ..
     304             : namelen    : 24       : 36
     305             : -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
     306             : 00000000   : 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 61 : com.apple.metada
     307             : 00000010   : 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 54 : ta:_kMDItemUserT
     308             : 00000020   : 61 67 73 00                                     : ags.
     309             : -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
     310             : 00000000   : 62 70 6C 69 73 74 30 30 A5 01 02 03 04 05 54 74 : bplist00......Tt
     311             : 00000010   : 65 73 74 66 00 47 00 72 00 FC 00 6E 00 0A 00 32 : estf.G.r...n...2
     312             : 00000020   : 56 4C 69 6C 61 0A 33 56 47 65 6C 62 0A 35 56 42 : VLila.3VGelb.5VB
     313             : 00000030   : 6C 61 75 0A 34 08 0E 13 20 27 2E 00 00 00 00 00 : lau.4... '......
     314             : 00000040   : 00 01 01 00 00 00 00 00 00 00 06 00 00 00 00 00 : ................
     315             : 00000050   : 00 00 00 00 00 00 00 00 00 00 35                : ..........5
     316             : -EA ENTRY--:
     317             : offset     : 00000117 : 279
     318             : length     : 00000003 : 3
     319             : flags      : 0000     : ..
     320             : namelen    : 08       : 8
     321             : -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
     322             : 00000000   : 66 6F 6F 3A 62 61 72 00                         : foo:bar.
     323             : -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
     324             : 00000000   : 62 61 7A                                        : baz
     325             : 
     326             : -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
     327             : 00000000   : 54 45 53 54 53 4C 4F 57 00 08 00 00 00 00 00 00 : TESTSLOW........
     328             : 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     329             : 00000020   : 00 00 41 54 54 52 53 D4 58 0C 00 00 0E E2 00 00 : ..ATTRS.X.......
     330             : 00000030   : 00 BC 00 00 00 5E 00 00 00 00 00 00 00 00 00 00 : .....^..........
     331             : 00000040   : 00 00 00 00 00 02 00 00 00 BC 00 00 00 5B 00 00 : .............[..
     332             : 00000050   : 24 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 : $com.apple.metad
     333             : 00000060   : 61 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 : ata:_kMDItemUser
     334             : 00000070   : 54 61 67 73 00 00 00 00 01 17 00 00 00 03 00 00 : Tags............
     335             : 00000080   : 08 66 6F 6F 3A 62 61 72 00 66 62 70 6C 69 73 74 : .foo:bar.fbplist
     336             : 00000090   : 30 30 A5 01 02 03 04 05 54 74 65 73 74 66 00 47 : 00......Ttestf.G
     337             : 000000A0   : 00 72 00 FC 00 6E 00 0A 00 32 56 4C 69 6C 61 0A : .r...n...2VLila.
     338             : 000000B0   : 33 56 47 65 6C 62 0A 35 56 42 6C 61 75 0A 34 08 : 3VGelb.5VBlau.4.
     339             : 000000C0   : 0E 13 20 27 2E 00 00 00 00 00 00 01 01 00 00 00 : .. '............
     340             : 000000D0   : 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 : ................
     341             : 000000E0   : 00 00 00 00 35 62 61 7A 00 00 00 00 00 00 00 00 : ....5baz........
     342             : 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     343             : ... all zeroes ...
     344             : 00000EA0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     345             : 
     346             : -------------------------------------------------------------------------------
     347             : Entry ID   : 00000002 : Resource Fork
     348             : Offset     : 00000EE2 : 3810
     349             : Length     : 0000011E : 286
     350             : 
     351             : -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
     352             : 00000000   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
     353             : 00000010   : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo
     354             : 00000020   : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
     355             : 00000030   : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 :  left blank   ..
     356             : 00000040   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     357             : 00000050   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     358             : 00000060   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     359             : 00000070   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     360             : 00000080   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     361             : 00000090   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     362             : 000000A0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     363             : 000000B0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     364             : 000000C0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     365             : 000000D0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     366             : 000000E0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     367             : 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     368             : 00000100   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
     369             : 00000110   : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF       : ..............
     370             : 
     371             : It was created with:
     372             : $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
     373             : */
     374             : static char osx_adouble_w_xattr[] = {
     375             :         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
     376             :         0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
     377             :         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
     378             :         0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
     379             :         0x00, 0x32, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00,
     380             :         0x00, 0x02, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00,
     381             :         0x01, 0x1e, 0x54, 0x45, 0x53, 0x54, 0x53, 0x4c,
     382             :         0x4f, 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
     383             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     384             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     385             :         0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
     386             :         0x53, 0xd4, 0x58, 0x0c, 0x00, 0x00, 0x0e, 0xe2,
     387             :         0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5e,
     388             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     389             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
     390             :         0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5b,
     391             :         0x00, 0x00, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
     392             :         0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x65, 0x74,
     393             :         0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x5f, 0x6b,
     394             :         0x4d, 0x44, 0x49, 0x74, 0x65, 0x6d, 0x55, 0x73,
     395             :         0x65, 0x72, 0x54, 0x61, 0x67, 0x73, 0x00, 0x00,
     396             :         0x00, 0x00, 0x01, 0x17, 0x00, 0x00, 0x00, 0x03,
     397             :         0x00, 0x00, 0x08, 0x66, 0x6f, 0x6f, 0x3a, 0x62,
     398             :         0x61, 0x72, 0x00, 0x66, 0x62, 0x70, 0x6c, 0x69,
     399             :         0x73, 0x74, 0x30, 0x30, 0xa5, 0x01, 0x02, 0x03,
     400             :         0x04, 0x05, 0x54, 0x74, 0x65, 0x73, 0x74, 0x66,
     401             :         0x00, 0x47, 0x00, 0x72, 0x00, 0xfc, 0x00, 0x6e,
     402             :         0x00, 0x0a, 0x00, 0x32, 0x56, 0x4c, 0x69, 0x6c,
     403             :         0x61, 0x0a, 0x33, 0x56, 0x47, 0x65, 0x6c, 0x62,
     404             :         0x0a, 0x35, 0x56, 0x42, 0x6c, 0x61, 0x75, 0x0a,
     405             :         0x34, 0x08, 0x0e, 0x13, 0x20, 0x27, 0x2e, 0x00,
     406             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
     407             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
     408             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     409             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x62,
     410             :         0x61, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     411             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     412             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     413             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     414             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     415             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     416             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     417             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     418             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     419             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     420             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     421             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     422             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     423             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     424             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     425             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     426             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     427             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     428             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     429             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     430             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     431             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     432             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     433             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     434             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     435             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     436             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     437             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     438             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     439             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     440             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     441             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     442             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     443             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     444             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     445             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     446             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     447             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     448             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     449             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     450             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     451             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     452             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     453             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     454             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     455             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     456             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     457             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     458             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     459             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     460             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     461             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     462             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     463             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     464             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     465             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     466             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     467             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     468             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     469             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     470             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     471             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     472             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     473             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     474             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     475             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     476             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     477             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     478             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     479             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     480             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     481             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     482             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     483             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     484             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     485             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     486             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     487             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     488             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     489             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     490             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     491             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     492             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     493             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     494             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     495             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     496             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     497             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     498             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     499             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     500             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     501             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     502             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     503             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     504             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     505             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     506             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     507             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     508             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     509             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     510             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     511             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     512             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     513             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     514             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     515             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     516             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     517             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     518             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     519             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     520             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     521             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     522             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     523             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     524             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     525             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     526             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     527             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     528             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     529             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     530             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     531             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     532             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     533             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     534             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     535             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     536             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     537             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     538             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     539             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     540             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     541             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     542             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     543             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     544             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     545             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     546             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     547             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     548             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     549             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     550             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     551             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     552             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     553             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     554             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     555             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     556             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     557             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     558             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     559             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     560             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     561             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     562             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     563             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     564             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     565             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     566             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     567             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     568             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     569             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     570             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     571             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     572             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     573             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     574             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     575             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     576             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     577             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     578             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     579             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     580             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     581             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     582             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     583             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     584             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     585             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     586             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     587             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     588             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     589             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     590             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     591             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     592             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     593             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     594             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     595             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     596             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     597             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     598             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     599             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     600             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     601             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     602             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     603             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     604             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     605             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     606             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     607             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     608             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     609             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     610             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     611             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     612             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     613             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     614             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     615             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     616             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     617             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     618             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     619             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     620             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     621             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     622             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     623             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     624             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     625             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     626             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     627             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     628             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     629             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     630             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     631             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     632             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     633             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     634             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     635             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     636             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     637             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     638             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     639             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     640             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     641             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     642             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     643             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     644             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     645             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     646             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     647             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     648             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     649             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     650             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     651             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     652             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     653             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     654             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     655             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     656             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     657             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     658             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     659             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     660             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     661             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     662             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     663             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     664             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     665             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     666             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     667             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     668             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     669             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     670             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     671             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     672             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     673             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     674             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     675             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     676             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     677             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     678             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     679             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     680             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     681             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     682             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     683             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     684             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     685             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     686             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     687             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     688             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     689             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     690             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     691             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     692             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     693             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     694             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     695             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     696             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     697             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     698             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     699             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     700             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     701             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     702             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     703             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     704             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     705             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     706             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     707             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     708             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     709             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     710             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     711             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     712             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     713             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     714             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     715             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     716             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     717             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     718             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     719             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     720             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     721             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     722             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     723             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     724             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     725             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     726             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     727             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     728             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     729             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     730             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     731             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     732             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     733             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     734             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     735             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     736             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     737             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     738             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     739             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     740             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     741             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     742             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     743             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     744             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     745             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     746             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     747             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     748             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     749             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     750             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     751             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     752             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     753             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     754             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     755             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     756             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     757             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     758             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     759             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     760             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     761             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     762             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     763             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     764             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     765             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     766             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     767             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     768             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     769             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     770             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     771             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     772             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     773             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     774             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     775             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     776             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     777             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     778             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     779             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     780             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     781             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     782             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     783             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     784             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     785             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     786             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     787             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     788             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     789             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     790             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     791             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     792             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     793             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     794             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     795             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     796             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     797             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     798             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     799             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     800             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     801             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     802             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     803             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     804             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     805             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     806             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     807             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     808             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     809             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     810             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     811             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     812             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     813             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     814             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     815             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     816             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     817             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     818             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     819             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     820             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     821             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     822             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     823             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     824             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     825             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     826             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     827             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     828             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     829             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     830             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     831             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     832             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     833             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     834             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     835             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     836             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     837             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     838             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     839             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     840             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     841             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     842             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     843             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     844             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     845             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     846             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     847             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     848             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     849             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     850             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     851             :         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
     852             :         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     853             :         0x00, 0x1e, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72,
     854             :         0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20,
     855             :         0x66, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
     856             :         0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
     857             :         0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
     858             :         0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
     859             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     860             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     861             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     862             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     863             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     864             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     865             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     866             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     867             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     868             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     869             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     870             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     871             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     872             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     873             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     874             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     875             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     876             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     877             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     878             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     879             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     880             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     881             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     882             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     883             :         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
     884             :         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     885             :         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     886             :         0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
     887             : };
     888             : 
     889             : /*
     890             :  * The buf below contains the following AppleDouble encoded data:
     891             :  *
     892             :  * -------------------------------------------------------------------------------
     893             :  * MagicNumber: 00051607                                        : AppleDouble
     894             :  * Version    : 00020000                                        : Version 2
     895             :  * Filler     : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
     896             :  * Num. of ent: 0002                                            : 2
     897             :  *
     898             :  * -------------------------------------------------------------------------------
     899             :  * Entry ID   : 00000002 : Resource Fork
     900             :  * Offset     : 00000052 : 82
     901             :  * Length     : 0000011E : 286
     902             :  *
     903             :  * -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
     904             :  * 00000000   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
     905             :  * 00000010   : F0 F1 F2 F3 F5 F5 F6 F7 F8 F9 FA FB FC FD FE FF : ................
     906             :  * 00000020   : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
     907             :  * 00000030   : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 :  left blank   ..
     908             :  * 00000040   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     909             :  * 00000050   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     910             :  * 00000060   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     911             :  * 00000070   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     912             :  * 00000080   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     913             :  * 00000090   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     914             :  * 000000A0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     915             :  * 000000B0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     916             :  * 000000C0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     917             :  * 000000D0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     918             :  * 000000E0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     919             :  * 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     920             :  * 00000100   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
     921             :  * 00000110   : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF       : ..............
     922             :  *
     923             :  * Entry ID   : 00000009 : Finder Info
     924             :  * Offset     : 00000032 : 50
     925             :  * Length     : 00000020 : 32
     926             :  *
     927             :  * -NOTE------: cannot detect whether FInfo or DInfo. assume FInfo.
     928             :  *
     929             :  * -FInfo-----:
     930             :  * Type       : 57415645 : WAVE
     931             :  * Creator    : 5054756C : PTul
     932             :  * isAlias    : 0
     933             :  * Invisible  : 0
     934             :  * hasBundle  : 0
     935             :  * nameLocked : 0
     936             :  * Stationery : 0
     937             :  * CustomIcon : 0
     938             :  * Reserved   : 0
     939             :  * Inited     : 0
     940             :  * NoINITS    : 0
     941             :  * Shared     : 0
     942             :  * SwitchLaunc: 0
     943             :  * Hidden Ext : 0
     944             :  * color      : 000      : none
     945             :  * isOnDesk   : 0
     946             :  * Location v : 0000     : 0
     947             :  * Location h : 0000     : 0
     948             :  * Fldr       : 0000     : ..
     949             :  *
     950             :  * -FXInfo----:
     951             :  * Rsvd|IconID: 0000     : 0
     952             :  * Rsvd       : 0000     : ..
     953             :  * Rsvd       : 0000     : ..
     954             :  * Rsvd       : 0000     : ..
     955             :  * AreInvalid : 0
     956             :  * unknown bit: 0
     957             :  * unknown bit: 0
     958             :  * unknown bit: 0
     959             :  * unknown bit: 0
     960             :  * unknown bit: 0
     961             :  * unknown bit: 0
     962             :  * CustomBadge: 0
     963             :  * ObjctIsBusy: 0
     964             :  * unknown bit: 0
     965             :  * unknown bit: 0
     966             :  * unknown bit: 0
     967             :  * unknown bit: 0
     968             :  * RoutingInfo: 0
     969             :  * unknown bit: 0
     970             :  * unknown bit: 0
     971             :  * Rsvd|commnt: 0000     : 0
     972             :  * PutAway    : 00000000 : 0
     973             :  *
     974             :  * -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
     975             :  * 00000000   : 57 41 56 45 50 54 75 6C 00 00 00 00 00 00 00 00 : WAVEPTul........
     976             :  * 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
     977             :  *  *
     978             :  * It was created with:
     979             :  * $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
     980             :  */
     981             : static char osx_adouble_without_xattr[] = {
     982             :         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
     983             :         0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
     984             :         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
     985             :         0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
     986             :         0x00, 0x52, 0x00, 0x00, 0x01, 0x1e, 0x00, 0x00,
     987             :         0x00, 0x09, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00,
     988             :         0x00, 0x20, 0x57, 0x41, 0x56, 0x45, 0x50, 0x54,
     989             :         0x75, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     990             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     991             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     992             :         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
     993             :         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     994             :         0x00, 0x1e, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
     995             :         0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd,
     996             :         0xfe, 0xff, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
     997             :         0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
     998             :         0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
     999             :         0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
    1000             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1001             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1002             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1003             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1004             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1005             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1006             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1007             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1008             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1009             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1010             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1011             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1012             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1013             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1014             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1015             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1016             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1017             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1018             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1019             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1020             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1021             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1022             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1023             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1024             :         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    1025             :         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1026             :         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1027             :         0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
    1028             : };
    1029             : 
    1030             : /*
    1031             : The buf below contains the following AppleDouble encoded data:
    1032             : 
    1033             : -------------------------------------------------------------------------------
    1034             : MagicNumber: 00051607                                        : AppleDouble
    1035             : Version    : 00020000                                        : Version 2
    1036             : Filler     : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
    1037             : Num. of ent: 0002                                            : 2
    1038             : 
    1039             : -------------------------------------------------------------------------------
    1040             : Entry ID   : 00000009 : Finder Info
    1041             : Offset     : 00000032 : 50
    1042             : Length     : 00000EB0 : 3760
    1043             : 
    1044             : -FInfo-----:
    1045             : Type       : 54455354 : TEST
    1046             : Creator    : 534C4F57 : SLOW
    1047             : isAlias    : 0
    1048             : Invisible  : 0
    1049             : hasBundle  : 0
    1050             : nameLocked : 0
    1051             : Stationery : 0
    1052             : CustomIcon : 0
    1053             : Reserved   : 0
    1054             : Inited     : 0
    1055             : NoINITS    : 0
    1056             : Shared     : 0
    1057             : SwitchLaunc: 0
    1058             : Hidden Ext : 0
    1059             : color      : 100      : blue
    1060             : isOnDesk   : 0
    1061             : Location v : 0000     : 0
    1062             : Location h : 0000     : 0
    1063             : Fldr       : 0000     : ..
    1064             : 
    1065             : -FXInfo----:
    1066             : Rsvd|IconID: 0000     : 0
    1067             : Rsvd       : 0000     : ..
    1068             : Rsvd       : 0000     : ..
    1069             : Rsvd       : 0000     : ..
    1070             : AreInvalid : 0
    1071             : unknown bit: 0
    1072             : unknown bit: 0
    1073             : unknown bit: 0
    1074             : unknown bit: 0
    1075             : unknown bit: 0
    1076             : unknown bit: 0
    1077             : CustomBadge: 0
    1078             : ObjctIsBusy: 0
    1079             : unknown bit: 0
    1080             : unknown bit: 0
    1081             : unknown bit: 0
    1082             : unknown bit: 0
    1083             : RoutingInfo: 0
    1084             : unknown bit: 0
    1085             : unknown bit: 0
    1086             : Rsvd|commnt: 0000     : 0
    1087             : PutAway    : 00000000 : 0
    1088             : 
    1089             : -EA--------:
    1090             : pad        : 0000     : ..
    1091             : magic      : 41545452 : ATTR
    1092             : debug_tag  : 53D4580C : 1406425100
    1093             : total_size : 00000EE2 : 3810
    1094             : data_start : 000000BC : 188
    1095             : data_length: 0000005E : 94
    1096             : reserved[0]: 00000000 : ....
    1097             : reserved[1]: 00000000 : ....
    1098             : reserved[2]: 00000000 : ....
    1099             : flags      : 0000     : ..
    1100             : num_attrs  : 0002     : 2
    1101             : -EA ENTRY--:
    1102             : offset     : 000000BC : 188
    1103             : length     : 0000005B : 91
    1104             : flags      : 0000     : ..
    1105             : namelen    : 24       : 36
    1106             : -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
    1107             : 00000000   : 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 61 : com.apple.metada
    1108             : 00000010   : 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 54 : ta:_kMDItemUserT
    1109             : 00000020   : 61 67 73 00                                     : ags.
    1110             : -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
    1111             : 00000000   : 62 70 6C 69 73 74 30 30 A5 01 02 03 04 05 54 74 : bplist00......Tt
    1112             : 00000010   : 65 73 74 66 00 47 00 72 00 FC 00 6E 00 0A 00 32 : estf.G.r...n...2
    1113             : 00000020   : 56 4C 69 6C 61 0A 33 56 47 65 6C 62 0A 35 56 42 : VLila.3VGelb.5VB
    1114             : 00000030   : 6C 61 75 0A 34 08 0E 13 20 27 2E 00 00 00 00 00 : lau.4... '......
    1115             : 00000040   : 00 01 01 00 00 00 00 00 00 00 06 00 00 00 00 00 : ................
    1116             : 00000050   : 00 00 00 00 00 00 00 00 00 00 35                : ..........5
    1117             : -EA ENTRY--:
    1118             : offset     : 00000117 : 279
    1119             : length     : 00000003 : 3
    1120             : flags      : 0000     : ..
    1121             : namelen    : 08       : 8
    1122             : -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
    1123             : 00000000   : 66 6F 6F 3A 62 61 72 00                         : foo:bar.
    1124             : -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
    1125             : 00000000   : 62 61 7A                                        : baz
    1126             : 
    1127             : -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
    1128             : 00000000   : 54 45 53 54 53 4C 4F 57 00 08 00 00 00 00 00 00 : TESTSLOW........
    1129             : 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1130             : 00000020   : 00 00 41 54 54 52 53 D4 58 0C 00 00 0E E2 00 00 : ..ATTRS.X.......
    1131             : 00000030   : 00 BC 00 00 00 5E 00 00 00 00 00 00 00 00 00 00 : .....^..........
    1132             : 00000040   : 00 00 00 00 00 02 00 00 00 BC 00 00 00 5B 00 00 : .............[..
    1133             : 00000050   : 24 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 74 61 64 : $com.apple.metad
    1134             : 00000060   : 61 74 61 3A 5F 6B 4D 44 49 74 65 6D 55 73 65 72 : ata:_kMDItemUser
    1135             : 00000070   : 54 61 67 73 00 00 00 00 01 17 00 00 00 03 00 00 : Tags............
    1136             : 00000080   : 08 66 6F 6F 3A 62 61 72 00 66 62 70 6C 69 73 74 : .foo:bar.fbplist
    1137             : 00000090   : 30 30 A5 01 02 03 04 05 54 74 65 73 74 66 00 47 : 00......Ttestf.G
    1138             : 000000A0   : 00 72 00 FC 00 6E 00 0A 00 32 56 4C 69 6C 61 0A : .r...n...2VLila.
    1139             : 000000B0   : 33 56 47 65 6C 62 0A 35 56 42 6C 61 75 0A 34 08 : 3VGelb.5VBlau.4.
    1140             : 000000C0   : 0E 13 20 27 2E 00 00 00 00 00 00 01 01 00 00 00 : .. '............
    1141             : 000000D0   : 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 : ................
    1142             : 000000E0   : 00 00 00 00 35 62 61 7A 00 00 00 00 00 00 00 00 : ....5baz........
    1143             : 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1144             : ... all zeroes ...
    1145             : 00000EA0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1146             : 
    1147             : -------------------------------------------------------------------------------
    1148             : Entry ID   : 00000002 : Resource Fork
    1149             : Offset     : 00000EE2 : 3810
    1150             : Length     : 0000011E : 286
    1151             : 
    1152             : -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
    1153             : 00000000   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
    1154             : 00000010   : F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF : This resource fo
    1155             : 00000020   : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
    1156             : 00000030   : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 :  left blank   ..
    1157             : 00000040   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1158             : 00000050   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1159             : 00000060   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1160             : 00000070   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1161             : 00000080   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1162             : 00000090   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1163             : 000000A0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1164             : 000000B0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1165             : 000000C0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1166             : 000000D0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1167             : 000000E0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1168             : 000000F0   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    1169             : 00000100   : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
    1170             : 00000110   : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF       : ..............
    1171             : 
    1172             : It was created with:
    1173             : $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
    1174             : */
    1175             : static char osx_adouble_non_empty_rfork_w_xattr[] = {
    1176             :         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
    1177             :         0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
    1178             :         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    1179             :         0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
    1180             :         0x00, 0x32, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00,
    1181             :         0x00, 0x02, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00,
    1182             :         0x01, 0x1e, 0x54, 0x45, 0x53, 0x54, 0x53, 0x4c,
    1183             :         0x4f, 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
    1184             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1185             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1186             :         0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
    1187             :         0x53, 0xd4, 0x58, 0x0c, 0x00, 0x00, 0x0e, 0xe2,
    1188             :         0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5e,
    1189             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1190             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
    1191             :         0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x5b,
    1192             :         0x00, 0x00, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
    1193             :         0x70, 0x70, 0x6c, 0x65, 0x2e, 0x6d, 0x65, 0x74,
    1194             :         0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x5f, 0x6b,
    1195             :         0x4d, 0x44, 0x49, 0x74, 0x65, 0x6d, 0x55, 0x73,
    1196             :         0x65, 0x72, 0x54, 0x61, 0x67, 0x73, 0x00, 0x00,
    1197             :         0x00, 0x00, 0x01, 0x17, 0x00, 0x00, 0x00, 0x03,
    1198             :         0x00, 0x00, 0x08, 0x66, 0x6f, 0x6f, 0x3a, 0x62,
    1199             :         0x61, 0x72, 0x00, 0x66, 0x62, 0x70, 0x6c, 0x69,
    1200             :         0x73, 0x74, 0x30, 0x30, 0xa5, 0x01, 0x02, 0x03,
    1201             :         0x04, 0x05, 0x54, 0x74, 0x65, 0x73, 0x74, 0x66,
    1202             :         0x00, 0x47, 0x00, 0x72, 0x00, 0xfc, 0x00, 0x6e,
    1203             :         0x00, 0x0a, 0x00, 0x32, 0x56, 0x4c, 0x69, 0x6c,
    1204             :         0x61, 0x0a, 0x33, 0x56, 0x47, 0x65, 0x6c, 0x62,
    1205             :         0x0a, 0x35, 0x56, 0x42, 0x6c, 0x61, 0x75, 0x0a,
    1206             :         0x34, 0x08, 0x0e, 0x13, 0x20, 0x27, 0x2e, 0x00,
    1207             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
    1208             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
    1209             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1210             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x62,
    1211             :         0x61, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1212             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1213             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1214             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1215             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1216             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1217             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1218             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1219             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1220             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1221             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1222             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1223             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1224             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1225             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1226             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1227             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1228             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1229             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1230             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1231             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1232             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1233             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1234             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1235             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1236             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1237             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1238             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1239             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1240             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1241             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1242             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1243             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1244             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1245             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1246             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1247             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1248             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1249             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1250             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1251             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1252             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1253             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1254             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1255             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1256             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1257             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1258             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1259             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1260             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1261             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1262             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1263             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1264             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1265             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1266             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1267             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1268             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1269             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1270             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1271             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1272             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1273             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1274             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1275             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1276             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1277             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1278             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1279             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1280             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1281             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1282             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1283             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1284             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1285             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1286             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1287             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1288             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1289             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1290             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1291             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1292             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1293             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1294             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1295             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1296             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1297             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1298             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1299             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1300             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1301             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1302             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1303             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1304             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1305             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1306             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1307             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1308             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1309             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1310             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1311             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1312             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1313             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1314             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1315             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1316             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1317             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1318             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1319             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1320             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1321             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1322             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1323             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1324             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1325             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1326             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1327             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1328             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1329             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1330             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1331             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1332             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1333             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1334             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1335             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1336             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1337             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1338             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1339             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1340             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1341             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1342             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1343             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1344             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1345             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1346             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1347             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1348             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1349             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1350             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1351             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1352             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1353             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1354             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1355             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1356             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1357             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1358             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1359             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1360             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1361             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1362             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1363             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1364             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1365             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1366             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1367             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1368             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1369             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1370             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1371             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1372             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1373             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1374             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1375             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1376             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1377             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1378             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1379             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1380             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1381             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1382             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1383             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1384             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1385             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1386             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1387             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1388             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1389             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1390             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1391             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1392             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1393             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1394             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1395             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1396             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1397             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1398             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1399             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1400             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1401             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1402             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1403             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1404             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1405             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1406             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1407             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1408             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1409             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1410             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1411             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1412             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1413             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1414             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1415             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1416             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1417             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1418             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1419             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1420             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1421             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1422             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1423             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1424             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1425             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1426             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1427             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1428             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1429             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1430             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1431             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1432             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1433             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1434             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1435             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1436             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1437             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1438             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1439             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1440             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1441             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1442             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1443             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1444             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1445             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1446             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1447             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1448             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1449             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1450             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1451             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1452             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1453             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1454             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1455             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1456             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1457             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1458             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1459             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1460             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1461             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1462             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1463             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1464             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1465             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1466             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1467             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1468             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1469             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1470             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1471             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1472             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1473             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1474             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1475             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1476             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1477             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1478             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1479             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1480             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1481             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1482             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1483             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1484             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1485             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1486             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1487             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1488             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1489             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1490             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1491             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1492             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1493             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1494             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1495             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1496             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1497             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1498             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1499             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1500             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1501             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1502             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1503             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1504             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1505             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1506             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1507             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1508             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1509             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1510             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1511             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1512             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1513             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1514             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1515             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1516             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1517             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1518             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1519             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1520             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1521             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1522             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1523             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1524             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1525             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1526             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1527             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1528             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1529             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1530             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1531             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1532             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1533             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1534             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1535             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1536             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1537             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1538             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1539             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1540             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1541             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1542             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1543             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1544             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1545             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1546             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1547             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1548             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1549             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1550             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1551             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1552             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1553             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1554             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1555             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1556             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1557             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1558             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1559             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1560             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1561             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1562             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1563             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1564             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1565             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1566             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1567             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1568             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1569             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1570             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1571             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1572             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1573             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1574             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1575             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1576             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1577             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1578             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1579             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1580             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1581             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1582             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1583             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1584             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1585             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1586             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1587             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1588             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1589             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1590             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1591             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1592             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1593             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1594             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1595             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1596             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1597             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1598             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1599             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1600             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1601             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1602             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1603             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1604             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1605             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1606             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1607             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1608             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1609             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1610             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1611             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1612             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1613             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1614             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1615             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1616             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1617             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1618             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1619             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1620             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1621             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1622             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1623             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1624             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1625             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1626             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1627             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1628             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1629             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1630             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1631             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1632             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1633             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1634             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1635             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1636             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1637             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1638             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1639             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1640             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1641             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1642             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1643             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1644             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1645             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1646             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1647             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1648             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1649             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1650             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1651             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1652             :         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    1653             :         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1654             :         0x00, 0x1e, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
    1655             :         0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd,
    1656             :         0xfe, 0xff, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74,
    1657             :         0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
    1658             :         0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20,
    1659             :         0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20,
    1660             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1661             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1662             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1663             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1664             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1665             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1666             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1667             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1668             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1669             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1670             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1671             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1672             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1673             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1674             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1675             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1676             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1677             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1678             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1679             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1680             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1681             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1682             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1683             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1684             :         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    1685             :         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1686             :         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1687             :         0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff
    1688             : };
    1689             : 
    1690             : /**
    1691             :  * talloc and intialize an AfpInfo
    1692             :  **/
    1693          94 : static AfpInfo *torture_afpinfo_new(TALLOC_CTX *mem_ctx)
    1694             : {
    1695             :         AfpInfo *info;
    1696             : 
    1697          94 :         info = talloc_zero(mem_ctx, AfpInfo);
    1698          94 :         if (info == NULL) {
    1699           0 :                 return NULL;
    1700             :         }
    1701             : 
    1702          94 :         info->afpi_Signature = AFP_Signature;
    1703          94 :         info->afpi_Version = AFP_Version;
    1704          94 :         info->afpi_BackupTime = AFP_BackupTime;
    1705             : 
    1706          94 :         return info;
    1707             : }
    1708             : 
    1709             : /**
    1710             :  * Pack AfpInfo into a talloced buffer
    1711             :  **/
    1712         110 : static char *torture_afpinfo_pack(TALLOC_CTX *mem_ctx,
    1713             :                                   AfpInfo *info)
    1714             : {
    1715             :         char *buf;
    1716             : 
    1717         110 :         buf = talloc_zero_array(mem_ctx, char, AFP_INFO_SIZE);
    1718         110 :         if (buf == NULL) {
    1719           0 :                 return NULL;
    1720             :         }
    1721             : 
    1722         110 :         RSIVAL(buf, 0, info->afpi_Signature);
    1723         110 :         RSIVAL(buf, 4, info->afpi_Version);
    1724         110 :         RSIVAL(buf, 12, info->afpi_BackupTime);
    1725         110 :         memcpy(buf + 16, info->afpi_FinderInfo, sizeof(info->afpi_FinderInfo));
    1726             : 
    1727         110 :         return buf;
    1728             : }
    1729             : 
    1730             : /**
    1731             :  * Unpack AfpInfo
    1732             :  **/
    1733             : #if 0
    1734             : static void torture_afpinfo_unpack(AfpInfo *info, char *data)
    1735             : {
    1736             :         info->afpi_Signature = RIVAL(data, 0);
    1737             :         info->afpi_Version = RIVAL(data, 4);
    1738             :         info->afpi_BackupTime = RIVAL(data, 12);
    1739             :         memcpy(info->afpi_FinderInfo, (const char *)data + 16,
    1740             :                sizeof(info->afpi_FinderInfo));
    1741             : }
    1742             : #endif
    1743             : 
    1744          78 : static bool torture_write_afpinfo(struct smb2_tree *tree,
    1745             :                                   struct torture_context *tctx,
    1746             :                                   TALLOC_CTX *mem_ctx,
    1747             :                                   const char *fname,
    1748             :                                   AfpInfo *info)
    1749             : {
    1750             :         struct smb2_handle handle;
    1751             :         struct smb2_create io;
    1752             :         NTSTATUS status;
    1753             :         const char *full_name;
    1754             :         char *infobuf;
    1755          78 :         bool ret = true;
    1756             : 
    1757          78 :         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, AFPINFO_STREAM_NAME);
    1758          78 :         if (full_name == NULL) {
    1759           0 :             torture_comment(tctx, "talloc_asprintf error\n");
    1760           0 :             return false;
    1761             :         }
    1762          78 :         ZERO_STRUCT(io);
    1763          78 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1764          78 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1765          78 :         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    1766          78 :         io.in.create_options = 0;
    1767          78 :         io.in.fname = full_name;
    1768             : 
    1769          78 :         status = smb2_create(tree, mem_ctx, &io);
    1770          78 :         CHECK_STATUS(status, NT_STATUS_OK);
    1771             : 
    1772          78 :         handle = io.out.file.handle;
    1773             : 
    1774          78 :         infobuf = torture_afpinfo_pack(mem_ctx, info);
    1775          78 :         if (infobuf == NULL) {
    1776           0 :                 return false;
    1777             :         }
    1778             : 
    1779          78 :         status = smb2_util_write(tree, handle, infobuf, 0, AFP_INFO_SIZE);
    1780          78 :         CHECK_STATUS(status, NT_STATUS_OK);
    1781             : 
    1782          78 :         smb2_util_close(tree, handle);
    1783             : 
    1784          78 : done:
    1785          78 :         return ret;
    1786             : }
    1787             : 
    1788             : /**
    1789             :  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
    1790             :  * compare against buffer 'value'
    1791             :  **/
    1792         540 : static bool check_stream(struct smb2_tree *tree,
    1793             :                          const char *location,
    1794             :                          struct torture_context *tctx,
    1795             :                          TALLOC_CTX *mem_ctx,
    1796             :                          const char *fname,
    1797             :                          const char *sname,
    1798             :                          off_t read_offset,
    1799             :                          size_t read_count,
    1800             :                          off_t comp_offset,
    1801             :                          size_t comp_count,
    1802             :                          const char *value)
    1803             : {
    1804             :         struct smb2_handle handle;
    1805             :         struct smb2_create create;
    1806             :         struct smb2_read r;
    1807             :         NTSTATUS status;
    1808             :         char *full_name;
    1809         540 :         bool ret = true;
    1810             : 
    1811         540 :         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
    1812         540 :         if (full_name == NULL) {
    1813           0 :             torture_comment(tctx, "talloc_asprintf error\n");
    1814           0 :             return false;
    1815             :         }
    1816         540 :         ZERO_STRUCT(create);
    1817         540 :         create.in.desired_access = SEC_FILE_READ_DATA;
    1818         540 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1819         540 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    1820         540 :         create.in.fname = full_name;
    1821             : 
    1822         540 :         torture_comment(tctx, "Open stream %s\n", full_name);
    1823             : 
    1824         540 :         status = smb2_create(tree, mem_ctx, &create);
    1825         540 :         if (!NT_STATUS_IS_OK(status)) {
    1826           2 :                 if (value == NULL) {
    1827           0 :                         TALLOC_FREE(full_name);
    1828           0 :                         return true;
    1829             :                 }
    1830           2 :                 torture_comment(tctx, "Unable to open stream %s: %s\n",
    1831             :                         full_name, nt_errstr(status));
    1832           2 :                 TALLOC_FREE(full_name);
    1833           2 :                 return false;
    1834             :         }
    1835             : 
    1836         538 :         handle = create.out.file.handle;
    1837         538 :         if (value == NULL) {
    1838           0 :                 TALLOC_FREE(full_name);
    1839           0 :                 smb2_util_close(tree, handle);
    1840           0 :                 return true;
    1841             :         }
    1842             : 
    1843         538 :         ZERO_STRUCT(r);
    1844         538 :         r.in.file.handle = handle;
    1845         538 :         r.in.length      = read_count;
    1846         538 :         r.in.offset      = read_offset;
    1847             : 
    1848         538 :         status = smb2_read(tree, tree, &r);
    1849             : 
    1850         538 :         torture_assert_ntstatus_ok_goto(
    1851             :                 tctx, status, ret, done,
    1852             :                 talloc_asprintf(tctx, "(%s) Failed to read %lu bytes from stream '%s'\n",
    1853             :                                 location, (long)strlen(value), full_name));
    1854             : 
    1855         538 :         torture_assert_goto(tctx, r.out.data.length == read_count, ret, done,
    1856             :                             talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected %jd\n",
    1857             :                                             (intmax_t)r.out.data.length, (intmax_t)read_count));
    1858             : 
    1859         538 :         torture_assert_goto(
    1860             :                 tctx, memcmp(r.out.data.data + comp_offset, value, comp_count) == 0,
    1861             :                 ret, done,
    1862             :                 talloc_asprintf(tctx, "(%s) Bad data in stream\n", location));
    1863             : 
    1864        1076 : done:
    1865         538 :         TALLOC_FREE(full_name);
    1866         538 :         smb2_util_close(tree, handle);
    1867         538 :         return ret;
    1868             : }
    1869             : 
    1870             : /**
    1871             :  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
    1872             :  * compare against buffer 'value'
    1873             :  **/
    1874          40 : static ssize_t read_stream(struct smb2_tree *tree,
    1875             :                            const char *location,
    1876             :                            struct torture_context *tctx,
    1877             :                            TALLOC_CTX *mem_ctx,
    1878             :                            const char *fname,
    1879             :                            const char *sname,
    1880             :                            off_t read_offset,
    1881             :                            size_t read_count)
    1882             : {
    1883             :         struct smb2_handle handle;
    1884             :         struct smb2_create create;
    1885             :         struct smb2_read r;
    1886             :         NTSTATUS status;
    1887             :         const char *full_name;
    1888          40 :         bool ret = true;
    1889             : 
    1890          40 :         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
    1891          40 :         if (full_name == NULL) {
    1892           0 :             torture_comment(tctx, "talloc_asprintf error\n");
    1893           0 :             return -1;
    1894             :         }
    1895          40 :         ZERO_STRUCT(create);
    1896          40 :         create.in.desired_access = SEC_FILE_READ_DATA;
    1897          40 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1898          40 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    1899          40 :         create.in.fname = full_name;
    1900             : 
    1901          40 :         torture_comment(tctx, "Open stream %s\n", full_name);
    1902             : 
    1903          40 :         status = smb2_create(tree, mem_ctx, &create);
    1904          40 :         if (!NT_STATUS_IS_OK(status)) {
    1905           0 :                 torture_comment(tctx, "Unable to open stream %s: %s\n",
    1906             :                                 full_name, nt_errstr(status));
    1907           0 :                 return -1;
    1908             :         }
    1909             : 
    1910          40 :         handle = create.out.file.handle;
    1911             : 
    1912          40 :         ZERO_STRUCT(r);
    1913          40 :         r.in.file.handle = handle;
    1914          40 :         r.in.length      = read_count;
    1915          40 :         r.in.offset      = read_offset;
    1916             : 
    1917          40 :         status = smb2_read(tree, tree, &r);
    1918          40 :         if (!NT_STATUS_IS_OK(status)) {
    1919          10 :                 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
    1920             :         }
    1921             : 
    1922          40 :         smb2_util_close(tree, handle);
    1923             : 
    1924          40 : done:
    1925          40 :         if (ret == false) {
    1926           0 :                 return -1;
    1927             :         }
    1928          40 :         return r.out.data.length;
    1929             : }
    1930             : 
    1931             : /**
    1932             :  * Read 'count' bytes at 'offset' from stream 'fname:sname' and
    1933             :  * compare against buffer 'value'
    1934             :  **/
    1935         138 : static bool write_stream(struct smb2_tree *tree,
    1936             :                          const char *location,
    1937             :                          struct torture_context *tctx,
    1938             :                          TALLOC_CTX *mem_ctx,
    1939             :                          const char *fname,
    1940             :                          const char *sname,
    1941             :                          off_t offset,
    1942             :                          size_t size,
    1943             :                          const char *value)
    1944             : {
    1945             :         struct smb2_handle handle;
    1946             :         struct smb2_create create;
    1947             :         NTSTATUS status;
    1948             :         const char *full_name;
    1949             : 
    1950         138 :         full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname ? sname : "");
    1951         138 :         if (full_name == NULL) {
    1952           0 :             torture_comment(tctx, "talloc_asprintf error\n");
    1953           0 :             return false;
    1954             :         }
    1955         138 :         ZERO_STRUCT(create);
    1956         138 :         create.in.desired_access = SEC_FILE_WRITE_DATA;
    1957         138 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1958         138 :         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    1959         138 :         create.in.fname = full_name;
    1960             : 
    1961         138 :         status = smb2_create(tree, mem_ctx, &create);
    1962         138 :         if (!NT_STATUS_IS_OK(status)) {
    1963           0 :                 if (value == NULL) {
    1964           0 :                         return true;
    1965             :                 } else {
    1966           0 :                         torture_comment(tctx, "Unable to open stream %s: %s\n",
    1967             :                             full_name, nt_errstr(status));
    1968           0 :                         return false;
    1969             :                 }
    1970             :         }
    1971             : 
    1972         138 :         handle = create.out.file.handle;
    1973         138 :         if (value == NULL) {
    1974           0 :                 return true;
    1975             :         }
    1976             : 
    1977         138 :         status = smb2_util_write(tree, handle, value, offset, size);
    1978             : 
    1979         138 :         if (!NT_STATUS_IS_OK(status)) {
    1980           0 :                 torture_comment(tctx, "(%s) Failed to write %lu bytes to "
    1981             :                     "stream '%s'\n", location, (long)size, full_name);
    1982           0 :                 return false;
    1983             :         }
    1984             : 
    1985         138 :         smb2_util_close(tree, handle);
    1986         138 :         return true;
    1987             : }
    1988             : 
    1989           4 : static bool torture_setup_local_xattr(struct torture_context *tctx,
    1990             :                                       const char *path_option,
    1991             :                                       const char *name,
    1992             :                                       const char *xattr,
    1993             :                                       const char *metadata,
    1994             :                                       size_t size)
    1995             : {
    1996           4 :         int ret = true;
    1997             :         int result;
    1998             :         const char *spath;
    1999             :         char *path;
    2000             : 
    2001           4 :         spath = torture_setting_string(tctx, path_option, NULL);
    2002           4 :         if (spath == NULL) {
    2003           0 :                 printf("No sharepath for option %s\n", path_option);
    2004           0 :                 return false;
    2005             :         }
    2006             : 
    2007           4 :         path = talloc_asprintf(tctx, "%s/%s", spath, name);
    2008             : 
    2009           4 :         result = setxattr(path, xattr, metadata, size, 0);
    2010           4 :         if (result != 0) {
    2011           0 :                 ret = false;
    2012             :         }
    2013             : 
    2014           4 :         TALLOC_FREE(path);
    2015             : 
    2016           4 :         return ret;
    2017             : }
    2018             : 
    2019             : /**
    2020             :  * Create a file or directory
    2021             :  **/
    2022         302 : static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree,
    2023             :                                const char *name, bool dir)
    2024             : {
    2025             :         struct smb2_create io;
    2026             :         NTSTATUS status;
    2027             : 
    2028         302 :         smb2_util_unlink(tree, name);
    2029         302 :         ZERO_STRUCT(io);
    2030         302 :         io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
    2031         302 :         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
    2032         302 :         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    2033         302 :         io.in.share_access =
    2034             :                 NTCREATEX_SHARE_ACCESS_DELETE|
    2035             :                 NTCREATEX_SHARE_ACCESS_READ|
    2036             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    2037         302 :         io.in.create_options = 0;
    2038         302 :         io.in.fname = name;
    2039         302 :         if (dir) {
    2040           0 :                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    2041           0 :                 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
    2042           0 :                 io.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
    2043           0 :                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
    2044             :         }
    2045             : 
    2046         302 :         status = smb2_create(tree, mem_ctx, &io);
    2047         302 :         if (!NT_STATUS_IS_OK(status)) {
    2048           0 :                 return false;
    2049             :         }
    2050             : 
    2051         302 :         status = smb2_util_close(tree, io.out.file.handle);
    2052         302 :         if (!NT_STATUS_IS_OK(status)) {
    2053           0 :                 return false;
    2054             :         }
    2055             : 
    2056         302 :         return true;
    2057             : }
    2058             : 
    2059         104 : static bool enable_aapl(struct torture_context *tctx,
    2060             :                         struct smb2_tree *tree)
    2061             : {
    2062         104 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2063             :         NTSTATUS status;
    2064         104 :         bool ret = true;
    2065             :         struct smb2_create io;
    2066             :         DATA_BLOB data;
    2067         104 :         struct smb2_create_blob *aapl = NULL;
    2068             :         uint32_t aapl_server_caps;
    2069         104 :         uint32_t expected_scaps = (SMB2_CRTCTX_AAPL_UNIX_BASED |
    2070             :                                    SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
    2071             :                                    SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
    2072             :                                    SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
    2073         104 :         bool is_osx_server = torture_setting_bool(tctx, "osx", false);
    2074             : 
    2075         104 :         ZERO_STRUCT(io);
    2076         104 :         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
    2077         104 :         io.in.file_attributes    = FILE_ATTRIBUTE_DIRECTORY;
    2078         104 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    2079         104 :         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
    2080             :                               NTCREATEX_SHARE_ACCESS_READ |
    2081             :                               NTCREATEX_SHARE_ACCESS_WRITE);
    2082         104 :         io.in.fname = "";
    2083             : 
    2084             :         /*
    2085             :          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
    2086             :          * controls behaviour of Apple's SMB2 extensions for the whole
    2087             :          * session!
    2088             :          */
    2089             : 
    2090         104 :         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
    2091         104 :         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
    2092         104 :         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
    2093             :                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
    2094             :                              SMB2_CRTCTX_AAPL_MODEL_INFO));
    2095         104 :         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
    2096             :                               SMB2_CRTCTX_AAPL_UNIX_BASED |
    2097             :                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
    2098             : 
    2099         104 :         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
    2100         104 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_blob_add");
    2101             : 
    2102         104 :         status = smb2_create(tree, tctx, &io);
    2103         104 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
    2104             : 
    2105         104 :         status = smb2_util_close(tree, io.out.file.handle);
    2106         104 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close");
    2107             : 
    2108             :         /*
    2109             :          * Now check returned AAPL context
    2110             :          */
    2111         104 :         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
    2112             : 
    2113         104 :         aapl = smb2_create_blob_find(&io.out.blobs,
    2114             :                                      SMB2_CREATE_TAG_AAPL);
    2115         104 :         torture_assert_goto(tctx, aapl != NULL, ret, done, "missing AAPL context");
    2116             : 
    2117         104 :         if (!is_osx_server) {
    2118             :                 size_t expected_aapl_ctx_size;
    2119             : 
    2120         104 :                 expected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
    2121             : 
    2122         104 :                 torture_assert_goto(
    2123             :                         tctx, aapl->data.length == expected_aapl_ctx_size,
    2124             :                         ret, done, "bad AAPL size");
    2125             :         }
    2126             : 
    2127         104 :         aapl_server_caps = BVAL(aapl->data.data, 16);
    2128         104 :         torture_assert_goto(tctx, aapl_server_caps == expected_scaps,
    2129             :                             ret, done, "bad AAPL caps");
    2130             : 
    2131         208 : done:
    2132         104 :         talloc_free(mem_ctx);
    2133         104 :         return ret;
    2134             : }
    2135             : 
    2136           2 : static bool test_read_netatalk_metadata(struct torture_context *tctx,
    2137             :                                         struct smb2_tree *tree)
    2138             : {
    2139           2 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2140           2 :         const char *fname = BASEDIR "\\torture_read_metadata";
    2141             :         NTSTATUS status;
    2142             :         struct smb2_handle testdirh;
    2143           2 :         bool ret = true;
    2144             :         ssize_t len;
    2145           2 :         const char *localdir = NULL;
    2146             : 
    2147           2 :         torture_comment(tctx, "Checking metadata access\n");
    2148             : 
    2149           2 :         localdir = torture_setting_string(tctx, "localdir", NULL);
    2150           2 :         if (localdir == NULL) {
    2151           0 :                 torture_skip(tctx, "Need localdir for test");
    2152             :         }
    2153             : 
    2154           2 :         smb2_util_unlink(tree, fname);
    2155             : 
    2156           2 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    2157           2 :         CHECK_STATUS(status, NT_STATUS_OK);
    2158           2 :         smb2_util_close(tree, testdirh);
    2159             : 
    2160           2 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    2161           2 :         if (ret == false) {
    2162           0 :                 goto done;
    2163             :         }
    2164             : 
    2165           2 :         ret = torture_setup_local_xattr(tctx, "localdir",
    2166             :                                         BASEDIR "/torture_read_metadata",
    2167             :                                         AFPINFO_EA_NETATALK,
    2168             :                                         metadata_xattr, sizeof(metadata_xattr));
    2169           2 :         if (ret == false) {
    2170           0 :                 goto done;
    2171             :         }
    2172             : 
    2173           2 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    2174             :                            0, 60, 0, 4, "AFP");
    2175           2 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
    2176             : 
    2177           2 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    2178             :                            0, 60, 16, 8, "BARRFOOO");
    2179           2 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
    2180             : 
    2181           2 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    2182             :                            16, 8, 0, 3, "AFP");
    2183           2 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
    2184             : 
    2185             :         /* Check reading offset and read size > sizeof(AFPINFO_STREAM) */
    2186             : 
    2187           2 :         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
    2188             :                           AFPINFO_STREAM, 0, 61);
    2189           2 :         CHECK_VALUE(len, 60);
    2190             : 
    2191           2 :         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
    2192             :                           AFPINFO_STREAM, 59, 2);
    2193           2 :         CHECK_VALUE(len, 2);
    2194             : 
    2195           2 :         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
    2196             :                           AFPINFO_STREAM, 60, 1);
    2197           2 :         CHECK_VALUE(len, 1);
    2198             : 
    2199           2 :         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
    2200             :                           AFPINFO_STREAM, 61, 1);
    2201           2 :         CHECK_VALUE(len, 0);
    2202             : 
    2203           4 : done:
    2204           2 :         smb2_deltree(tree, BASEDIR);
    2205           2 :         talloc_free(mem_ctx);
    2206           2 :         return ret;
    2207             : }
    2208             : 
    2209           8 : static bool test_read_afpinfo(struct torture_context *tctx,
    2210             :                               struct smb2_tree *tree)
    2211             : {
    2212           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2213           8 :         const char *fname = BASEDIR "\\torture_read_metadata";
    2214             :         NTSTATUS status;
    2215             :         struct smb2_handle testdirh;
    2216           8 :         bool ret = true;
    2217             :         ssize_t len;
    2218             :         AfpInfo *info;
    2219           8 :         const char *type_creator = "SMB,OLE!";
    2220             : 
    2221           8 :         torture_comment(tctx, "Checking metadata access\n");
    2222             : 
    2223           8 :         smb2_util_unlink(tree, fname);
    2224             : 
    2225           8 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    2226           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
    2227           8 :         smb2_util_close(tree, testdirh);
    2228             : 
    2229           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    2230           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
    2231             : 
    2232           8 :         info = torture_afpinfo_new(mem_ctx);
    2233           8 :         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
    2234             : 
    2235           8 :         memcpy(info->afpi_FinderInfo, type_creator, 8);
    2236           8 :         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
    2237           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
    2238             : 
    2239           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    2240             :                            0, 60, 0, 4, "AFP");
    2241           8 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
    2242             : 
    2243           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    2244             :                            0, 60, 16, 8, type_creator);
    2245           8 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
    2246             : 
    2247             :         /*
    2248             :          * OS X ignores offset <= 60 and treats the as
    2249             :          * offset=0. Reading from offsets > 60 returns EOF=0.
    2250             :          */
    2251             : 
    2252           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    2253             :                            16, 8, 0, 8, "AFP\0\0\0\001\0");
    2254           8 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
    2255             : 
    2256           8 :         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
    2257             :                           AFPINFO_STREAM, 0, 61);
    2258           8 :         torture_assert_goto(tctx, len == 60, ret, done, "read_stream failed");
    2259             : 
    2260           8 :         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
    2261             :                           AFPINFO_STREAM, 59, 2);
    2262           8 :         torture_assert_goto(tctx, len == 2, ret, done, "read_stream failed");
    2263             : 
    2264           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    2265             :                            59, 2, 0, 2, "AF");
    2266           8 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
    2267             : 
    2268           8 :         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
    2269             :                           AFPINFO_STREAM, 60, 1);
    2270           8 :         torture_assert_goto(tctx, len == 1, ret, done, "read_stream failed");
    2271             : 
    2272           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    2273             :                            60, 1, 0, 1, "A");
    2274           8 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
    2275             : 
    2276           8 :         len = read_stream(tree, __location__, tctx, mem_ctx, fname,
    2277             :                           AFPINFO_STREAM, 61, 1);
    2278           8 :         torture_assert_goto(tctx, len == 0, ret, done, "read_stream failed");
    2279             : 
    2280          16 : done:
    2281           8 :         smb2_util_unlink(tree, fname);
    2282           8 :         smb2_deltree(tree, BASEDIR);
    2283           8 :         talloc_free(mem_ctx);
    2284           8 :         return ret;
    2285             : }
    2286             : 
    2287           8 : static bool test_write_atalk_metadata(struct torture_context *tctx,
    2288             :                                       struct smb2_tree *tree)
    2289             : {
    2290           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2291           8 :         const char *fname = BASEDIR "\\torture_write_metadata";
    2292           8 :         const char *type_creator = "SMB,OLE!";
    2293             :         NTSTATUS status;
    2294             :         struct smb2_handle testdirh;
    2295           8 :         bool ret = true;
    2296             :         AfpInfo *info;
    2297             : 
    2298           8 :         smb2_deltree(tree, BASEDIR);
    2299           8 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    2300           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2301           8 :         smb2_util_close(tree, testdirh);
    2302             : 
    2303           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    2304           8 :         if (ret == false) {
    2305           0 :                 goto done;
    2306             :         }
    2307             : 
    2308           8 :         info = torture_afpinfo_new(mem_ctx);
    2309           8 :         if (info == NULL) {
    2310           0 :                 goto done;
    2311             :         }
    2312             : 
    2313           8 :         memcpy(info->afpi_FinderInfo, type_creator, 8);
    2314           8 :         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
    2315           8 :         ret &= check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    2316             :                             0, 60, 16, 8, type_creator);
    2317             : 
    2318           8 : done:
    2319           8 :         smb2_util_unlink(tree, fname);
    2320           8 :         smb2_deltree(tree, BASEDIR);
    2321           8 :         talloc_free(mem_ctx);
    2322           8 :         return ret;
    2323             : }
    2324             : 
    2325           8 : static bool test_write_atalk_rfork_io(struct torture_context *tctx,
    2326             :                                       struct smb2_tree *tree)
    2327             : {
    2328           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2329           8 :         const char *fname = BASEDIR "\\torture_write_rfork_io";
    2330           8 :         const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM_NAME;
    2331           8 :         const char *rfork_content = "1234567890";
    2332             :         NTSTATUS status;
    2333             :         struct smb2_handle testdirh;
    2334           8 :         bool ret = true;
    2335             : 
    2336             :         union smb_open io;
    2337             :         struct smb2_handle filehandle;
    2338             :         union smb_fileinfo finfo;
    2339             :         union smb_setfileinfo sinfo;
    2340             : 
    2341           8 :         smb2_util_unlink(tree, fname);
    2342             : 
    2343           8 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    2344           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2345           8 :         smb2_util_close(tree, testdirh);
    2346             : 
    2347           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    2348           8 :         if (ret == false) {
    2349           0 :                 goto done;
    2350             :         }
    2351             : 
    2352           8 :         torture_comment(tctx, "(%s) writing to resource fork\n",
    2353             :             __location__);
    2354             : 
    2355           8 :         ret &= write_stream(tree, __location__, tctx, mem_ctx,
    2356             :                             fname, AFPRESOURCE_STREAM_NAME,
    2357             :                             10, 10, rfork_content);
    2358             : 
    2359           8 :         ret &= check_stream(tree, __location__, tctx, mem_ctx,
    2360             :                             fname, AFPRESOURCE_STREAM_NAME,
    2361             :                             0, 20, 10, 10, rfork_content);
    2362             : 
    2363             :         /* Check size after write */
    2364             : 
    2365           8 :         ZERO_STRUCT(io);
    2366           8 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
    2367           8 :         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
    2368             :                 SEC_FILE_WRITE_ATTRIBUTE;
    2369           8 :         io.smb2.in.fname = rfork;
    2370           8 :         status = smb2_create(tree, mem_ctx, &(io.smb2));
    2371           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2372           8 :         filehandle = io.smb2.out.file.handle;
    2373             : 
    2374           8 :         torture_comment(tctx, "(%s) check resource fork size after write\n",
    2375             :             __location__);
    2376             : 
    2377           8 :         ZERO_STRUCT(finfo);
    2378           8 :         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    2379           8 :         finfo.generic.in.file.handle = filehandle;
    2380           8 :         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
    2381           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2382           8 :         if (finfo.all_info.out.size != 20) {
    2383           0 :                 torture_result(tctx, TORTURE_FAIL,
    2384             :                                "(%s) Incorrect resource fork size\n",
    2385             :                                __location__);
    2386           0 :                 ret = false;
    2387           0 :                 smb2_util_close(tree, filehandle);
    2388           0 :                 goto done;
    2389             :         }
    2390           8 :         smb2_util_close(tree, filehandle);
    2391             : 
    2392             :         /* Write at large offset */
    2393             : 
    2394           8 :         torture_comment(tctx, "(%s) writing to resource fork at large offset\n",
    2395             :                         __location__);
    2396             : 
    2397           8 :         ret &= write_stream(tree, __location__, tctx, mem_ctx,
    2398             :                             fname, AFPRESOURCE_STREAM_NAME,
    2399             :                             (off_t)64*1024*1024, 10, rfork_content);
    2400             : 
    2401             :         /* Check size after write */
    2402             : 
    2403           8 :         ZERO_STRUCT(io);
    2404           8 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
    2405           8 :         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
    2406             :                 SEC_FILE_WRITE_ATTRIBUTE;
    2407           8 :         io.smb2.in.fname = rfork;
    2408           8 :         status = smb2_create(tree, mem_ctx, &(io.smb2));
    2409           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2410           8 :         filehandle = io.smb2.out.file.handle;
    2411             : 
    2412           8 :         torture_comment(tctx, "(%s) check resource fork size after write\n",
    2413             :             __location__);
    2414             : 
    2415           8 :         ZERO_STRUCT(finfo);
    2416           8 :         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    2417           8 :         finfo.generic.in.file.handle = filehandle;
    2418           8 :         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
    2419           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2420           8 :         if (finfo.all_info.out.size != 64*1024*1024 + 10) {
    2421           0 :                 torture_result(tctx, TORTURE_FAIL,
    2422             :                                "(%s) Incorrect resource fork size\n",
    2423             :                                __location__);
    2424           0 :                 ret = false;
    2425           0 :                 smb2_util_close(tree, filehandle);
    2426           0 :                 goto done;
    2427             :         }
    2428           8 :         smb2_util_close(tree, filehandle);
    2429             : 
    2430           8 :         ret &= check_stream(tree, __location__, tctx, mem_ctx,
    2431             :                             fname, AFPRESOURCE_STREAM_NAME,
    2432             :                             (off_t)64*1024*1024, 10, 0, 10, rfork_content);
    2433             : 
    2434             :         /* Truncate back to size of 1 byte */
    2435             : 
    2436           8 :         torture_comment(tctx, "(%s) truncate resource fork and check size\n",
    2437             :                         __location__);
    2438             : 
    2439           8 :         ZERO_STRUCT(io);
    2440           8 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
    2441           8 :         io.smb2.in.desired_access = SEC_FILE_ALL;
    2442           8 :         io.smb2.in.fname = rfork;
    2443           8 :         status = smb2_create(tree, mem_ctx, &(io.smb2));
    2444           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2445           8 :         filehandle = io.smb2.out.file.handle;
    2446             : 
    2447           8 :         ZERO_STRUCT(sinfo);
    2448           8 :         sinfo.end_of_file_info.level =
    2449             :                 RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    2450           8 :         sinfo.end_of_file_info.in.file.handle = filehandle;
    2451           8 :         sinfo.end_of_file_info.in.size = 1;
    2452           8 :         status = smb2_setinfo_file(tree, &sinfo);
    2453           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2454             : 
    2455           8 :         smb2_util_close(tree, filehandle);
    2456             : 
    2457             :         /* Now check size */
    2458           8 :         ZERO_STRUCT(io);
    2459           8 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
    2460           8 :         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
    2461             :                 SEC_FILE_WRITE_ATTRIBUTE;
    2462           8 :         io.smb2.in.fname = rfork;
    2463           8 :         status = smb2_create(tree, mem_ctx, &(io.smb2));
    2464           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2465           8 :         filehandle = io.smb2.out.file.handle;
    2466             : 
    2467           8 :         ZERO_STRUCT(finfo);
    2468           8 :         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    2469           8 :         finfo.generic.in.file.handle = filehandle;
    2470           8 :         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
    2471           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2472           8 :         if (finfo.all_info.out.size != 1) {
    2473           0 :                 torture_result(tctx, TORTURE_FAIL,
    2474             :                                "(%s) Incorrect resource fork size\n",
    2475             :                                __location__);
    2476           0 :                 ret = false;
    2477           0 :                 smb2_util_close(tree, filehandle);
    2478           0 :                 goto done;
    2479             :         }
    2480           8 :         smb2_util_close(tree, filehandle);
    2481             : 
    2482           8 : done:
    2483           8 :         smb2_util_unlink(tree, fname);
    2484           8 :         smb2_deltree(tree, BASEDIR);
    2485           8 :         talloc_free(mem_ctx);
    2486           8 :         return ret;
    2487             : }
    2488             : 
    2489           8 : static bool test_rfork_truncate(struct torture_context *tctx,
    2490             :                                 struct smb2_tree *tree)
    2491             : {
    2492           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2493           8 :         const char *fname = BASEDIR "\\torture_rfork_truncate";
    2494           8 :         const char *rfork = BASEDIR "\\torture_rfork_truncate" AFPRESOURCE_STREAM;
    2495           8 :         const char *rfork_content = "1234567890";
    2496             :         NTSTATUS status;
    2497             :         struct smb2_handle testdirh;
    2498           8 :         bool ret = true;
    2499             :         struct smb2_create create;
    2500             :         struct smb2_handle fh1, fh2, fh3;
    2501             :         union smb_setfileinfo sinfo;
    2502             : 
    2503           8 :         ret = enable_aapl(tctx, tree);
    2504           8 :         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
    2505             : 
    2506           8 :         smb2_util_unlink(tree, fname);
    2507             : 
    2508           8 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    2509           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
    2510           8 :         smb2_util_close(tree, testdirh);
    2511             : 
    2512           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    2513           8 :         if (ret == false) {
    2514           0 :                 goto done;
    2515             :         }
    2516             : 
    2517           8 :         ret &= write_stream(tree, __location__, tctx, mem_ctx,
    2518             :                             fname, AFPRESOURCE_STREAM,
    2519             :                             10, 10, rfork_content);
    2520             : 
    2521             :         /* Truncate back to size 0, further access MUST return ENOENT */
    2522             : 
    2523           8 :         torture_comment(tctx, "(%s) truncate resource fork to size 0\n",
    2524             :                         __location__);
    2525             : 
    2526           8 :         ZERO_STRUCT(create);
    2527           8 :         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
    2528           8 :         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
    2529           8 :         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
    2530           8 :         create.in.fname               = fname;
    2531           8 :         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
    2532             :                 NTCREATEX_SHARE_ACCESS_READ |
    2533             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    2534           8 :         status = smb2_create(tree, mem_ctx, &create);
    2535           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
    2536           8 :         fh1 = create.out.file.handle;
    2537             : 
    2538           8 :         ZERO_STRUCT(create);
    2539           8 :         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
    2540           8 :         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
    2541           8 :         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
    2542           8 :         create.in.fname               = rfork;
    2543           8 :         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
    2544             :                 NTCREATEX_SHARE_ACCESS_READ |
    2545             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    2546           8 :         status = smb2_create(tree, mem_ctx, &create);
    2547           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
    2548           8 :         fh2 = create.out.file.handle;
    2549             : 
    2550           8 :         ZERO_STRUCT(sinfo);
    2551           8 :         sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    2552           8 :         sinfo.end_of_file_info.in.file.handle = fh2;
    2553           8 :         sinfo.end_of_file_info.in.size = 0;
    2554           8 :         status = smb2_setinfo_file(tree, &sinfo);
    2555           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file");
    2556             : 
    2557             :         /*
    2558             :          * Now check size, we should get OBJECT_NAME_NOT_FOUND (!)
    2559             :          */
    2560           8 :         ZERO_STRUCT(create);
    2561           8 :         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
    2562           8 :         create.in.desired_access      = SEC_FILE_ALL;
    2563           8 :         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
    2564           8 :         create.in.fname               = rfork;
    2565           8 :         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
    2566             :                 NTCREATEX_SHARE_ACCESS_READ |
    2567             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    2568           8 :         status = smb2_create(tree, mem_ctx, &create);
    2569           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
    2570             : 
    2571             :         /*
    2572             :          * Do another open on the rfork and write to the new handle. A
    2573             :          * naive server might unlink the AppleDouble resource fork
    2574             :          * file when its truncated to 0 bytes above, so in case both
    2575             :          * open handles share the same underlying fd, the unlink would
    2576             :          * cause the below write to be lost.
    2577             :          */
    2578           8 :         ZERO_STRUCT(create);
    2579           8 :         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
    2580           8 :         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
    2581           8 :         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
    2582           8 :         create.in.fname               = rfork;
    2583           8 :         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
    2584             :                 NTCREATEX_SHARE_ACCESS_READ |
    2585             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    2586           8 :         status = smb2_create(tree, mem_ctx, &create);
    2587           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
    2588           8 :         fh3 = create.out.file.handle;
    2589             : 
    2590           8 :         status = smb2_util_write(tree, fh3, "foo", 0, 3);
    2591           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write");
    2592             : 
    2593           8 :         smb2_util_close(tree, fh3);
    2594           8 :         smb2_util_close(tree, fh2);
    2595           8 :         smb2_util_close(tree, fh1);
    2596             : 
    2597           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM,
    2598             :                            0, 3, 0, 3, "foo");
    2599           8 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream");
    2600             : 
    2601          16 : done:
    2602           8 :         smb2_util_unlink(tree, fname);
    2603           8 :         smb2_deltree(tree, BASEDIR);
    2604           8 :         talloc_free(mem_ctx);
    2605           8 :         return ret;
    2606             : }
    2607             : 
    2608           8 : static bool test_rfork_create(struct torture_context *tctx,
    2609             :                               struct smb2_tree *tree)
    2610             : {
    2611           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2612           8 :         const char *fname = BASEDIR "\\torture_rfork_create";
    2613           8 :         const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
    2614             :         NTSTATUS status;
    2615             :         struct smb2_handle testdirh;
    2616           8 :         bool ret = true;
    2617             :         struct smb2_create create;
    2618             :         struct smb2_handle fh1;
    2619           8 :         const char *streams[] = {
    2620             :                 "::$DATA"
    2621             :         };
    2622             :         union smb_fileinfo finfo;
    2623             : 
    2624           8 :         ret = enable_aapl(tctx, tree);
    2625           8 :         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
    2626             : 
    2627           8 :         smb2_util_unlink(tree, fname);
    2628             : 
    2629           8 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    2630           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
    2631           8 :         smb2_util_close(tree, testdirh);
    2632             : 
    2633           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    2634           8 :         if (ret == false) {
    2635           0 :                 goto done;
    2636             :         }
    2637             : 
    2638           8 :         torture_comment(tctx, "(%s) open rfork, should return ENOENT\n",
    2639             :                         __location__);
    2640             : 
    2641           8 :         ZERO_STRUCT(create);
    2642           8 :         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
    2643           8 :         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
    2644           8 :         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
    2645           8 :         create.in.fname               = rfork;
    2646           8 :         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
    2647             :                 NTCREATEX_SHARE_ACCESS_READ |
    2648             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    2649           8 :         status = smb2_create(tree, mem_ctx, &create);
    2650           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
    2651             : 
    2652           8 :         torture_comment(tctx, "(%s) create resource fork\n", __location__);
    2653             : 
    2654           8 :         ZERO_STRUCT(create);
    2655           8 :         create.in.create_disposition  = NTCREATEX_DISP_OPEN_IF;
    2656           8 :         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
    2657           8 :         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
    2658           8 :         create.in.fname               = rfork;
    2659           8 :         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
    2660             :                 NTCREATEX_SHARE_ACCESS_READ |
    2661             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    2662           8 :         status = smb2_create(tree, mem_ctx, &create);
    2663           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
    2664           8 :         fh1 = create.out.file.handle;
    2665             : 
    2666           8 :         torture_comment(tctx, "(%s) getinfo on create handle\n",
    2667             :                         __location__);
    2668             : 
    2669           8 :         ZERO_STRUCT(finfo);
    2670           8 :         finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION;
    2671           8 :         finfo.generic.in.file.handle = fh1;
    2672           8 :         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
    2673           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file");
    2674           8 :         if (finfo.all_info.out.size != 0) {
    2675           0 :                 torture_result(tctx, TORTURE_FAIL,
    2676             :                                "(%s) Incorrect resource fork size\n",
    2677             :                                __location__);
    2678           0 :                 ret = false;
    2679           0 :                 smb2_util_close(tree, fh1);
    2680           0 :                 goto done;
    2681             :         }
    2682             : 
    2683           8 :         torture_comment(tctx, "(%s) open rfork, should still return ENOENT\n",
    2684             :                         __location__);
    2685             : 
    2686           8 :         ZERO_STRUCT(create);
    2687           8 :         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
    2688           8 :         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
    2689           8 :         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
    2690           8 :         create.in.fname               = rfork;
    2691           8 :         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
    2692             :                 NTCREATEX_SHARE_ACCESS_READ |
    2693             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    2694           8 :         status = smb2_create(tree, mem_ctx, &create);
    2695           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
    2696             : 
    2697           8 :         ret = check_stream_list(tree, tctx, fname, 1, streams, false);
    2698           8 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
    2699             : 
    2700           8 :         torture_comment(tctx, "(%s) close empty created rfork, open should return ENOENT\n",
    2701             :                         __location__);
    2702             : 
    2703           8 :         ZERO_STRUCT(create);
    2704           8 :         create.in.create_disposition  = NTCREATEX_DISP_OPEN;
    2705           8 :         create.in.desired_access      = SEC_STD_READ_CONTROL | SEC_FILE_ALL;
    2706           8 :         create.in.file_attributes     = FILE_ATTRIBUTE_NORMAL;
    2707           8 :         create.in.fname               = rfork;
    2708           8 :         create.in.share_access        = NTCREATEX_SHARE_ACCESS_DELETE |
    2709             :                 NTCREATEX_SHARE_ACCESS_READ |
    2710             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    2711           8 :         status = smb2_create(tree, mem_ctx, &create);
    2712           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done, "smb2_create");
    2713             : 
    2714           8 : done:
    2715           8 :         smb2_util_unlink(tree, fname);
    2716           8 :         smb2_deltree(tree, BASEDIR);
    2717           8 :         talloc_free(mem_ctx);
    2718           8 :         return ret;
    2719             : }
    2720             : 
    2721           8 : static bool test_rfork_create_ro(struct torture_context *tctx,
    2722             :                                  struct smb2_tree *tree)
    2723             : {
    2724           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2725           8 :         const char *fname = BASEDIR "\\torture_rfork_create";
    2726           8 :         const char *rfork = BASEDIR "\\torture_rfork_create" AFPRESOURCE_STREAM;
    2727             :         NTSTATUS status;
    2728             :         struct smb2_handle testdirh;
    2729           8 :         bool ret = true;
    2730             :         struct smb2_create create;
    2731             : 
    2732           8 :         smb2_util_unlink(tree, fname);
    2733           8 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    2734           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2735             :                 "torture_smb2_testdir\n");
    2736           8 :         smb2_util_close(tree, testdirh);
    2737             : 
    2738           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    2739           8 :         if (ret == false) {
    2740           0 :                 goto done;
    2741             :         }
    2742             : 
    2743           8 :         torture_comment(tctx, "(%s) Try opening read-only with "
    2744             :                         "open_if create disposition, should work\n",
    2745             :                         __location__);
    2746             : 
    2747           8 :         ZERO_STRUCT(create);
    2748           8 :         create.in.fname = rfork;
    2749           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    2750           8 :         create.in.desired_access = SEC_FILE_READ_DATA | SEC_STD_READ_CONTROL;
    2751           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    2752           8 :         create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
    2753           8 :         status = smb2_create(tree, mem_ctx, &(create));
    2754           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2755             :                 "smb2_create failed\n");
    2756             : 
    2757           8 :         smb2_util_close(tree, create.out.file.handle);
    2758             : 
    2759           8 : done:
    2760           8 :         smb2_util_unlink(tree, fname);
    2761           8 :         smb2_deltree(tree, BASEDIR);
    2762           8 :         talloc_free(mem_ctx);
    2763           8 :         return ret;
    2764             : }
    2765             : 
    2766           8 : static bool test_adouble_conversion(struct torture_context *tctx,
    2767             :                                     struct smb2_tree *tree)
    2768             : {
    2769           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2770           8 :         const char *fname = BASEDIR "\\test_adouble_conversion";
    2771           8 :         const char *adname = BASEDIR "/._test_adouble_conversion";
    2772             :         NTSTATUS status;
    2773             :         struct smb2_handle testdirh;
    2774           8 :         bool ret = true;
    2775           8 :         const char data[] = {
    2776             :                 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
    2777             :                 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
    2778             :         };
    2779           8 :         size_t datalen = sizeof(data);
    2780           8 :         const char *streams[] = {
    2781             :                 "::$DATA",
    2782             :                 AFPINFO_STREAM,
    2783             :                 AFPRESOURCE_STREAM,
    2784             :                 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
    2785             :                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
    2786             :         };
    2787           8 :         bool is_osx = torture_setting_bool(tctx, "osx", false);
    2788             : 
    2789           8 :         if (is_osx) {
    2790           0 :                 torture_skip(tctx, "Test only works with Samba\n");
    2791             :         }
    2792             : 
    2793           8 :         smb2_deltree(tree, BASEDIR);
    2794             : 
    2795           8 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    2796           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2797           8 :         smb2_util_close(tree, testdirh);
    2798             : 
    2799           8 :         ret = torture_setup_file(tctx, tree, fname, false);
    2800           8 :         torture_assert_goto(tctx, ret == true, ret, done,
    2801             :                             "torture_setup_file failed\n");
    2802             : 
    2803           8 :         ret = torture_setup_file(tctx, tree, adname, false);
    2804           8 :         torture_assert_goto(tctx, ret == true, ret, done,
    2805             :                             "torture_setup_file failed\n");
    2806             : 
    2807           8 :         ret = write_stream(tree, __location__, tctx, mem_ctx,
    2808             :                            adname, NULL,
    2809             :                            0,
    2810             :                            sizeof(osx_adouble_non_empty_rfork_w_xattr),
    2811             :                            osx_adouble_non_empty_rfork_w_xattr);
    2812           8 :         torture_assert_goto(tctx, ret == true, ret, done,
    2813             :                             "write_stream failed\n");
    2814             : 
    2815           8 :         torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
    2816             :             __location__);
    2817             : 
    2818           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx,
    2819             :                            fname, AFPRESOURCE_STREAM,
    2820             :                            16, datalen, 0, datalen, data);
    2821           8 :         torture_assert_goto(tctx, ret == true, ret, done,
    2822             :                             "check AFPRESOURCE_STREAM failed\n");
    2823             : 
    2824           6 :         ret = check_stream(tree, __location__, tctx, mem_ctx,
    2825             :                            fname, AFPINFO_STREAM,
    2826             :                            0, 60, 16, 8, "TESTSLOW");
    2827           6 :         torture_assert_goto(tctx, ret == true, ret, done,
    2828             :                             "check AFPINFO_STREAM failed\n");
    2829             : 
    2830           6 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname,
    2831             :                            ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
    2832             :                            0, 3, 0, 3, "baz");
    2833           6 :         torture_assert_goto(tctx, ret == true, ret, done,
    2834             :                             "check foo:bar stream failed\n");
    2835             : 
    2836           6 :         ret = check_stream_list(tree, tctx, fname, 5, streams, false);
    2837           6 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
    2838             : 
    2839          14 : done:
    2840           8 :         smb2_deltree(tree, BASEDIR);
    2841           8 :         talloc_free(mem_ctx);
    2842           8 :         return ret;
    2843             : }
    2844             : 
    2845             : /*
    2846             :  * Test conversion of AppleDouble file without embedded xattr data
    2847             :  */
    2848           8 : static bool test_adouble_conversion_wo_xattr(struct torture_context *tctx,
    2849             :                                              struct smb2_tree *tree)
    2850             : {
    2851           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2852           8 :         const char *fname = BASEDIR "\\test_adouble_conversion";
    2853           8 :         const char *adname = BASEDIR "/._test_adouble_conversion";
    2854             :         NTSTATUS status;
    2855             :         struct smb2_handle testdirh;
    2856           8 :         bool ret = true;
    2857           8 :         const char *streams[] = {
    2858             :                 "::$DATA",
    2859             :                 AFPINFO_STREAM,
    2860             :                 AFPRESOURCE_STREAM
    2861             :         };
    2862             :         struct smb2_create create;
    2863             :         struct smb2_find find;
    2864             :         unsigned int count;
    2865             :         union smb_search_data *d;
    2866           8 :         const char data[] = {
    2867             :                 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
    2868             :                 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
    2869             :         };
    2870           8 :         size_t datalen = sizeof(data);
    2871           8 :         bool is_osx = torture_setting_bool(tctx, "osx", false);
    2872             : 
    2873           8 :         if (is_osx) {
    2874           0 :                 torture_skip(tctx, "Test only works with Samba\n");
    2875             :         }
    2876             : 
    2877           8 :         smb2_deltree(tree, BASEDIR);
    2878             : 
    2879           8 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    2880           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2881             :                                         "torture_smb2_testdir failed\n");
    2882           8 :         smb2_util_close(tree, testdirh);
    2883             : 
    2884           8 :         ret = torture_setup_file(tctx, tree, fname, false);
    2885           8 :         torture_assert_goto(tctx, ret == true, ret, done,
    2886             :                             "torture_setup_file failed\n");
    2887             : 
    2888           8 :         ret = torture_setup_file(tctx, tree, adname, false);
    2889           8 :         torture_assert_goto(tctx, ret == true, ret, done,
    2890             :                             "torture_setup_file failed\n");
    2891             : 
    2892           8 :         ret = write_stream(tree, __location__, tctx, mem_ctx,
    2893             :                            adname, NULL, 0,
    2894             :                            sizeof(osx_adouble_without_xattr),
    2895             :                            osx_adouble_without_xattr);
    2896           8 :         torture_assert_goto(tctx, ret == true, ret, done,
    2897             :                             "write_stream failed\n");
    2898             : 
    2899           8 :         ret = enable_aapl(tctx, tree);
    2900           8 :         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
    2901             : 
    2902             :         /*
    2903             :          * Issue a smb2_find(), this triggers the server-side conversion
    2904             :          */
    2905             : 
    2906           8 :         create = (struct smb2_create) {
    2907             :                 .in.desired_access = SEC_RIGHTS_DIR_READ,
    2908             :                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
    2909             :                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
    2910             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
    2911             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    2912             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
    2913             :                 .in.fname = BASEDIR,
    2914             :         };
    2915             : 
    2916           8 :         status = smb2_create(tree, tctx, &create);
    2917           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2918             :                                         "smb2_create failed\n");
    2919             : 
    2920           8 :         find = (struct smb2_find) {
    2921             :                 .in.file.handle = create.out.file.handle,
    2922             :                 .in.pattern = "*",
    2923             :                 .in.max_response_size = 0x1000,
    2924             :                 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
    2925             :         };
    2926             : 
    2927           8 :         status = smb2_find_level(tree, tree, &find, &count, &d);
    2928           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2929             :                                         "smb2_find_level failed\n");
    2930             : 
    2931           8 :         status = smb2_util_close(tree, create.out.file.handle);
    2932           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2933             :                                         "smb2_util_close failed");
    2934             : 
    2935             :         /*
    2936             :          * Check number of streams
    2937             :          */
    2938             : 
    2939           8 :         ret = check_stream_list(tree, tctx, fname, 3, streams, false);
    2940           8 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
    2941             : 
    2942             : 
    2943             :         /*
    2944             :          * Check Resourcefork data can be read.
    2945             :          */
    2946             : 
    2947           6 :         ret = check_stream(tree, __location__, tctx, mem_ctx,
    2948             :                            fname, AFPRESOURCE_STREAM,
    2949             :                            16, datalen, 0, datalen, data);
    2950           6 :         torture_assert_goto(tctx, ret == true, ret, done,
    2951             :                             "check AFPRESOURCE_STREAM failed\n");
    2952             : 
    2953             :         /*
    2954             :          * Check FinderInfo data has been migrated to stream.
    2955             :          */
    2956             : 
    2957           6 :         ret = check_stream(tree, __location__, tctx, mem_ctx,
    2958             :                            fname, AFPINFO_STREAM,
    2959             :                            0, 60, 16, 8, "WAVEPTul");
    2960           6 :         torture_assert_goto(tctx, ret == true, ret, done,
    2961             :                             "check AFPINFO_STREAM failed\n");
    2962             : 
    2963          14 : done:
    2964           8 :         smb2_deltree(tree, BASEDIR);
    2965           8 :         talloc_free(mem_ctx);
    2966           8 :         return ret;
    2967             : }
    2968             : 
    2969           8 : static bool test_aapl(struct torture_context *tctx,
    2970             :                       struct smb2_tree *tree)
    2971             : {
    2972           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2973           8 :         const char *fname = BASEDIR "\\test_aapl";
    2974             :         NTSTATUS status;
    2975             :         struct smb2_handle testdirh;
    2976           8 :         bool ret = true;
    2977             :         struct smb2_create io;
    2978             :         DATA_BLOB data;
    2979           8 :         struct smb2_create_blob *aapl = NULL;
    2980             :         AfpInfo *info;
    2981           8 :         const char *type_creator = "SMB,OLE!";
    2982             :         char type_creator_buf[9];
    2983             :         uint32_t aapl_cmd;
    2984             :         uint32_t aapl_reply_bitmap;
    2985             :         uint32_t aapl_server_caps;
    2986             :         uint32_t aapl_vol_caps;
    2987           8 :         uint32_t expected_vol_caps = 0;
    2988             :         char *model;
    2989             :         struct smb2_find f;
    2990             :         unsigned int count;
    2991             :         union smb_search_data *d;
    2992             :         uint64_t rfork_len;
    2993           8 :         bool is_osx_server = torture_setting_bool(tctx, "osx", false);
    2994             : 
    2995           8 :         smb2_deltree(tree, BASEDIR);
    2996             : 
    2997           8 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    2998           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    2999           8 :         smb2_util_close(tree, testdirh);
    3000             : 
    3001           8 :         ZERO_STRUCT(io);
    3002           8 :         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
    3003           8 :         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
    3004           8 :         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    3005           8 :         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
    3006             :                               NTCREATEX_SHARE_ACCESS_READ |
    3007             :                               NTCREATEX_SHARE_ACCESS_WRITE);
    3008           8 :         io.in.fname = fname;
    3009             : 
    3010             :         /*
    3011             :          * Issuing an SMB2/CREATE with a suitably formed AAPL context,
    3012             :          * controls behaviour of Apple's SMB2 extensions for the whole
    3013             :          * session!
    3014             :          */
    3015             : 
    3016           8 :         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
    3017           8 :         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
    3018           8 :         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS |
    3019             :                              SMB2_CRTCTX_AAPL_VOLUME_CAPS |
    3020             :                              SMB2_CRTCTX_AAPL_MODEL_INFO));
    3021           8 :         SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
    3022             :                               SMB2_CRTCTX_AAPL_UNIX_BASED |
    3023             :                               SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE));
    3024             : 
    3025           8 :         torture_comment(tctx, "Testing SMB2 create context AAPL\n");
    3026           8 :         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
    3027           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    3028             : 
    3029           8 :         status = smb2_create(tree, tctx, &io);
    3030           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    3031           8 :         status = smb2_util_close(tree, io.out.file.handle);
    3032           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    3033             : 
    3034             :         /*
    3035             :          * Now check returned AAPL context
    3036             :          */
    3037           8 :         torture_comment(tctx, "Comparing returned AAPL capabilities\n");
    3038             : 
    3039           8 :         aapl = smb2_create_blob_find(&io.out.blobs,
    3040             :                                      SMB2_CREATE_TAG_AAPL);
    3041             : 
    3042           8 :         if (aapl == NULL) {
    3043           0 :                 torture_result(tctx, TORTURE_FAIL,
    3044             :                                "(%s) unexpectedly no AAPL capabilities were returned.",
    3045             :                                __location__);
    3046           0 :                 ret = false;
    3047           0 :                 goto done;
    3048             :         }
    3049             : 
    3050           8 :         if (!is_osx_server) {
    3051             :                 size_t expected_aapl_ctx_size;
    3052             :                 bool size_ok;
    3053             : 
    3054             :                 /*
    3055             :                  * uint32_t CommandCode = kAAPL_SERVER_QUERY
    3056             :                  * uint32_t Reserved = 0;
    3057             :                  * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS |
    3058             :                  *                        kAAPL_VOLUME_CAPS |
    3059             :                  *                        kAAPL_MODEL_INFO;
    3060             :                  * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR |
    3061             :                  *                       kAAPL_SUPPORTS_OSX_COPYFILE;
    3062             :                  * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID |
    3063             :                  *                       kAAPL_CASE_SENSITIVE;
    3064             :                  * uint32_t Pad2 = 0;
    3065             :                  * uint32_t ModelStringLen = 10;
    3066             :                  * ucs2_t ModelString[5] = "MacSamba";
    3067             :                  */
    3068           8 :                 expected_aapl_ctx_size = strlen("MacSamba") * 2 + 40;
    3069             : 
    3070           8 :                 size_ok = aapl->data.length == expected_aapl_ctx_size;
    3071           8 :                 torture_assert_goto(tctx, size_ok, ret, done, "bad AAPL size");
    3072             :         }
    3073             : 
    3074           8 :         aapl_cmd = IVAL(aapl->data.data, 0);
    3075           8 :         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
    3076           0 :                 torture_result(tctx, TORTURE_FAIL,
    3077             :                                "(%s) unexpected cmd: %d",
    3078             :                                __location__, (int)aapl_cmd);
    3079           0 :                 ret = false;
    3080           0 :                 goto done;
    3081             :         }
    3082             : 
    3083           8 :         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
    3084           8 :         if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS |
    3085             :                                   SMB2_CRTCTX_AAPL_VOLUME_CAPS |
    3086             :                                   SMB2_CRTCTX_AAPL_MODEL_INFO)) {
    3087           0 :                 torture_result(tctx, TORTURE_FAIL,
    3088             :                                "(%s) unexpected reply_bitmap: %d",
    3089             :                                __location__, (int)aapl_reply_bitmap);
    3090           0 :                 ret = false;
    3091           0 :                 goto done;
    3092             :         }
    3093             : 
    3094           8 :         aapl_server_caps = BVAL(aapl->data.data, 16);
    3095           8 :         if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED |
    3096             :                                  SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR |
    3097             :                                  SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE |
    3098             :                                  SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE)) {
    3099           0 :                 torture_result(tctx, TORTURE_FAIL,
    3100             :                                "(%s) unexpected server_caps: %d",
    3101             :                                __location__, (int)aapl_server_caps);
    3102           0 :                 ret = false;
    3103           0 :                 goto done;
    3104             :         }
    3105             : 
    3106           8 :         if (is_osx_server) {
    3107           0 :                 expected_vol_caps = 5;
    3108             :         }
    3109           8 :         aapl_vol_caps = BVAL(aapl->data.data, 24);
    3110           8 :         if (aapl_vol_caps != expected_vol_caps) {
    3111             :                 /* this will fail on a case insensitive fs ... */
    3112           0 :                 torture_result(tctx, TORTURE_FAIL,
    3113             :                                 "(%s) unexpected vol_caps: %d",
    3114             :                                 __location__, (int)aapl_vol_caps);
    3115             :         }
    3116             : 
    3117           8 :         ret = convert_string_talloc(mem_ctx,
    3118             :                                     CH_UTF16LE, CH_UNIX,
    3119           8 :                                     aapl->data.data + 40, 10,
    3120             :                                     &model, NULL);
    3121           8 :         if (ret == false) {
    3122           0 :                 torture_result(tctx, TORTURE_FAIL,
    3123             :                                "(%s) convert_string_talloc() failed",
    3124             :                                __location__);
    3125           0 :                 goto done;
    3126             :         }
    3127           8 :         torture_comment(tctx, "Got server model: \"%s\"\n", model);
    3128             : 
    3129             :         /*
    3130             :          * Now that Requested AAPL extensions are enabled, setup some
    3131             :          * Mac files with metadata and resource fork
    3132             :          */
    3133           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    3134           8 :         if (ret == false) {
    3135           0 :                 torture_result(tctx, TORTURE_FAIL,
    3136             :                                "(%s) torture_setup_file() failed",
    3137             :                                __location__);
    3138           0 :                 goto done;
    3139             :         }
    3140             : 
    3141           8 :         info = torture_afpinfo_new(mem_ctx);
    3142           8 :         if (info == NULL) {
    3143           0 :                 torture_result(tctx, TORTURE_FAIL,
    3144             :                                "(%s) torture_afpinfo_new() failed",
    3145             :                                __location__);
    3146           0 :                 ret = false;
    3147           0 :                 goto done;
    3148             :         }
    3149             : 
    3150           8 :         memcpy(info->afpi_FinderInfo, type_creator, 8);
    3151           8 :         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
    3152           8 :         if (ret == false) {
    3153           0 :                 torture_result(tctx, TORTURE_FAIL,
    3154             :                                "(%s) torture_write_afpinfo() failed",
    3155             :                                __location__);
    3156           0 :                 goto done;
    3157             :         }
    3158             : 
    3159           8 :         ret = write_stream(tree, __location__, tctx, mem_ctx,
    3160             :                            fname, AFPRESOURCE_STREAM_NAME,
    3161             :                            0, 3, "foo");
    3162           8 :         if (ret == false) {
    3163           0 :                 torture_result(tctx, TORTURE_FAIL,
    3164             :                                "(%s) write_stream() failed",
    3165             :                                __location__);
    3166           0 :                 goto done;
    3167             :         }
    3168             : 
    3169             :         /*
    3170             :          * Ok, file is prepared, now call smb2/find
    3171             :          */
    3172             : 
    3173           8 :         ZERO_STRUCT(io);
    3174           8 :         io.in.desired_access = SEC_RIGHTS_DIR_READ;
    3175           8 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    3176           8 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    3177           8 :         io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
    3178             :                               NTCREATEX_SHARE_ACCESS_WRITE |
    3179             :                               NTCREATEX_SHARE_ACCESS_DELETE);
    3180           8 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    3181           8 :         io.in.fname = BASEDIR;
    3182           8 :         status = smb2_create(tree, tctx, &io);
    3183           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    3184             : 
    3185           8 :         ZERO_STRUCT(f);
    3186           8 :         f.in.file.handle        = io.out.file.handle;
    3187           8 :         f.in.pattern            = "test_aapl";
    3188           8 :         f.in.continue_flags     = SMB2_CONTINUE_FLAG_SINGLE;
    3189           8 :         f.in.max_response_size  = 0x1000;
    3190           8 :         f.in.level              = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
    3191             : 
    3192           8 :         status = smb2_find_level(tree, tree, &f, &count, &d);
    3193           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    3194             : 
    3195           8 :         status = smb2_util_close(tree, io.out.file.handle);
    3196           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    3197             : 
    3198           8 :         if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) {
    3199           0 :                 torture_result(tctx, TORTURE_FAIL,
    3200             :                                "(%s) write_stream() failed",
    3201             :                                __location__);
    3202           0 :                 ret = false;
    3203           0 :                 goto done;
    3204             :         }
    3205             : 
    3206           8 :         if (d[0].id_both_directory_info.short_name.private_length != 24) {
    3207           0 :                 torture_result(tctx, TORTURE_FAIL,
    3208             :                                "(%s) bad short_name length %" PRIu32 ", expected 24",
    3209           0 :                                __location__, d[0].id_both_directory_info.short_name.private_length);
    3210           0 :                 ret = false;
    3211           0 :                 goto done;
    3212             :         }
    3213             : 
    3214           8 :         torture_comment(tctx, "short_name buffer:\n");
    3215           8 :         dump_data(0, d[0].id_both_directory_info.short_name_buf, 24);
    3216             : 
    3217             :         /*
    3218             :          * Extract data as specified by the AAPL extension:
    3219             :          * - ea_size contains max_access
    3220             :          * - short_name contains resource fork length + FinderInfo
    3221             :          * - reserved2 contains the unix mode
    3222             :          */
    3223           8 :         torture_comment(tctx, "mac_access: %" PRIx32 "\n",
    3224           8 :                         d[0].id_both_directory_info.ea_size);
    3225             : 
    3226           8 :         rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0);
    3227           8 :         if (rfork_len != 3) {
    3228           0 :                 torture_result(tctx, TORTURE_FAIL,
    3229             :                                "(%s) expected resource fork length 3, got: %" PRIu64,
    3230             :                                __location__, rfork_len);
    3231           0 :                 ret = false;
    3232           0 :                 goto done;
    3233             :         }
    3234             : 
    3235           8 :         memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8);
    3236           8 :         type_creator_buf[8] = 0;
    3237           8 :         if (strcmp(type_creator, type_creator_buf) != 0) {
    3238           0 :                 torture_result(tctx, TORTURE_FAIL,
    3239             :                                "(%s) expected type/creator \"%s\" , got: %s",
    3240             :                                __location__, type_creator, type_creator_buf);
    3241           0 :                 ret = false;
    3242           0 :                 goto done;
    3243             :         }
    3244             : 
    3245          16 : done:
    3246           8 :         smb2_util_unlink(tree, fname);
    3247           8 :         smb2_deltree(tree, BASEDIR);
    3248           8 :         talloc_free(mem_ctx);
    3249           8 :         return ret;
    3250             : }
    3251             : 
    3252       74240 : static uint64_t patt_hash(uint64_t off)
    3253             : {
    3254       74240 :         return off;
    3255             : }
    3256             : 
    3257          32 : static bool write_pattern(struct torture_context *torture,
    3258             :                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
    3259             :                           struct smb2_handle h, uint64_t off, uint64_t len,
    3260             :                           uint64_t patt_off)
    3261             : {
    3262             :         NTSTATUS status;
    3263             :         uint64_t i;
    3264             :         uint8_t *buf;
    3265          32 :         uint64_t io_sz = MIN(1024 * 64, len);
    3266             : 
    3267          32 :         if (len == 0) {
    3268           0 :                 return true;
    3269             :         }
    3270             : 
    3271          32 :         torture_assert(torture, (len % 8) == 0, "invalid write len");
    3272             : 
    3273          32 :         buf = talloc_zero_size(mem_ctx, io_sz);
    3274          32 :         torture_assert(torture, (buf != NULL), "no memory for file data buf");
    3275             : 
    3276          96 :         while (len > 0) {
    3277        8736 :                 for (i = 0; i <= io_sz - 8; i += 8) {
    3278        8704 :                         SBVAL(buf, i, patt_hash(patt_off));
    3279        8704 :                         patt_off += 8;
    3280             :                 }
    3281             : 
    3282          32 :                 status = smb2_util_write(tree, h,
    3283             :                                          buf, off, io_sz);
    3284          32 :                 torture_assert_ntstatus_ok(torture, status, "file write");
    3285             : 
    3286          32 :                 len -= io_sz;
    3287          32 :                 off += io_sz;
    3288             :         }
    3289             : 
    3290          32 :         talloc_free(buf);
    3291             : 
    3292          32 :         return true;
    3293             : }
    3294             : 
    3295          24 : static bool check_pattern(struct torture_context *torture,
    3296             :                           struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
    3297             :                           struct smb2_handle h, uint64_t off, uint64_t len,
    3298             :                           uint64_t patt_off)
    3299             : {
    3300          24 :         if (len == 0) {
    3301           0 :                 return true;
    3302             :         }
    3303             : 
    3304          24 :         torture_assert(torture, (len % 8) == 0, "invalid read len");
    3305             : 
    3306          72 :         while (len > 0) {
    3307             :                 uint64_t i;
    3308             :                 struct smb2_read r;
    3309             :                 NTSTATUS status;
    3310          24 :                 uint64_t io_sz = MIN(1024 * 64, len);
    3311             : 
    3312          24 :                 ZERO_STRUCT(r);
    3313          24 :                 r.in.file.handle = h;
    3314          24 :                 r.in.length      = io_sz;
    3315          24 :                 r.in.offset      = off;
    3316          24 :                 status = smb2_read(tree, mem_ctx, &r);
    3317          24 :                 torture_assert_ntstatus_ok(torture, status, "read");
    3318             : 
    3319          24 :                 torture_assert_u64_equal(torture, r.out.data.length, io_sz,
    3320             :                                          "read data len mismatch");
    3321             : 
    3322        4632 :                 for (i = 0; i <= io_sz - 8; i += 8, patt_off += 8) {
    3323        4608 :                         uint64_t data = BVAL(r.out.data.data, i);
    3324        4608 :                         torture_assert_u64_equal(torture, data, patt_hash(patt_off),
    3325             :                                                  talloc_asprintf(torture, "read data "
    3326             :                                                                  "pattern bad at %llu\n",
    3327             :                                                                  (unsigned long long)off + i));
    3328             :                 }
    3329          24 :                 talloc_free(r.out.data.data);
    3330          24 :                 len -= io_sz;
    3331          24 :                 off += io_sz;
    3332             :         }
    3333             : 
    3334          24 :         return true;
    3335             : }
    3336             : 
    3337          88 : static bool test_setup_open(struct torture_context *torture,
    3338             :                             struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
    3339             :                             const char *fname,
    3340             :                             struct smb2_handle *fh,
    3341             :                             uint32_t desired_access,
    3342             :                             uint32_t file_attributes)
    3343             : {
    3344             :         struct smb2_create io;
    3345             :         NTSTATUS status;
    3346             : 
    3347          88 :         ZERO_STRUCT(io);
    3348          88 :         io.in.desired_access = desired_access;
    3349          88 :         io.in.file_attributes = file_attributes;
    3350          88 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    3351          88 :         io.in.share_access =
    3352             :                 NTCREATEX_SHARE_ACCESS_DELETE|
    3353             :                 NTCREATEX_SHARE_ACCESS_READ|
    3354             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    3355          88 :         if (file_attributes & FILE_ATTRIBUTE_DIRECTORY) {
    3356           0 :                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    3357             :         }
    3358          88 :         io.in.fname = fname;
    3359             : 
    3360          88 :         status = smb2_create(tree, mem_ctx, &io);
    3361          88 :         torture_assert_ntstatus_ok(torture, status, "file create");
    3362             : 
    3363          88 :         *fh = io.out.file.handle;
    3364             : 
    3365          88 :         return true;
    3366             : }
    3367             : 
    3368          80 : static bool test_setup_create_fill(struct torture_context *torture,
    3369             :                                    struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
    3370             :                                    const char *fname,
    3371             :                                    struct smb2_handle *fh,
    3372             :                                    uint64_t size,
    3373             :                                    uint32_t desired_access,
    3374             :                                    uint32_t file_attributes)
    3375             : {
    3376             :         bool ok;
    3377             : 
    3378          80 :         ok = test_setup_open(torture, tree, mem_ctx,
    3379             :                              fname,
    3380             :                              fh,
    3381             :                              desired_access,
    3382             :                              file_attributes);
    3383          80 :         torture_assert(torture, ok, "file open");
    3384             : 
    3385          80 :         if (size > 0) {
    3386          32 :                 ok = write_pattern(torture, tree, mem_ctx, *fh, 0, size, 0);
    3387          32 :                 torture_assert(torture, ok, "write pattern");
    3388             :         }
    3389          80 :         return true;
    3390             : }
    3391             : 
    3392          40 : static bool test_setup_copy_chunk(struct torture_context *torture,
    3393             :                                   struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
    3394             :                                   uint32_t nchunks,
    3395             :                                   const char *src_name,
    3396             :                                   struct smb2_handle *src_h,
    3397             :                                   uint64_t src_size,
    3398             :                                   uint32_t src_desired_access,
    3399             :                                   const char *dst_name,
    3400             :                                   struct smb2_handle *dest_h,
    3401             :                                   uint64_t dest_size,
    3402             :                                   uint32_t dest_desired_access,
    3403             :                                   struct srv_copychunk_copy *cc_copy,
    3404             :                                   union smb_ioctl *io)
    3405             : {
    3406             :         struct req_resume_key_rsp res_key;
    3407             :         bool ok;
    3408             :         NTSTATUS status;
    3409             :         enum ndr_err_code ndr_ret;
    3410             : 
    3411          40 :         ok = test_setup_create_fill(torture, tree, mem_ctx, src_name,
    3412             :                                     src_h, src_size, src_desired_access,
    3413             :                                     FILE_ATTRIBUTE_NORMAL);
    3414          40 :         torture_assert(torture, ok, "src file create fill");
    3415             : 
    3416          40 :         ok = test_setup_create_fill(torture, tree, mem_ctx, dst_name,
    3417             :                                     dest_h, dest_size, dest_desired_access,
    3418             :                                     FILE_ATTRIBUTE_NORMAL);
    3419          40 :         torture_assert(torture, ok, "dest file create fill");
    3420             : 
    3421          40 :         ZERO_STRUCTPN(io);
    3422          40 :         io->smb2.level = RAW_IOCTL_SMB2;
    3423          40 :         io->smb2.in.file.handle = *src_h;
    3424          40 :         io->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
    3425             :         /* Allow for Key + ContextLength + Context */
    3426          40 :         io->smb2.in.max_output_response = 32;
    3427          40 :         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
    3428             : 
    3429          40 :         status = smb2_ioctl(tree, mem_ctx, &io->smb2);
    3430          40 :         torture_assert_ntstatus_ok(torture, status,
    3431             :                                    "FSCTL_SRV_REQUEST_RESUME_KEY");
    3432             : 
    3433          40 :         ndr_ret = ndr_pull_struct_blob(&io->smb2.out.out, mem_ctx, &res_key,
    3434             :                         (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
    3435             : 
    3436          40 :         torture_assert_ndr_success(torture, ndr_ret,
    3437             :                                    "ndr_pull_req_resume_key_rsp");
    3438             : 
    3439          40 :         ZERO_STRUCTPN(io);
    3440          40 :         io->smb2.level = RAW_IOCTL_SMB2;
    3441          40 :         io->smb2.in.file.handle = *dest_h;
    3442          40 :         io->smb2.in.function = FSCTL_SRV_COPYCHUNK;
    3443          40 :         io->smb2.in.max_output_response = sizeof(struct srv_copychunk_rsp);
    3444          40 :         io->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
    3445             : 
    3446          40 :         ZERO_STRUCTPN(cc_copy);
    3447          40 :         memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
    3448          40 :         cc_copy->chunk_count = nchunks;
    3449          40 :         cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
    3450          40 :         torture_assert(torture, (cc_copy->chunks != NULL), "no memory for chunks");
    3451             : 
    3452          40 :         return true;
    3453             : }
    3454             : 
    3455             : 
    3456          40 : static bool check_copy_chunk_rsp(struct torture_context *torture,
    3457             :                                  struct srv_copychunk_rsp *cc_rsp,
    3458             :                                  uint32_t ex_chunks_written,
    3459             :                                  uint32_t ex_chunk_bytes_written,
    3460             :                                  uint32_t ex_total_bytes_written)
    3461             : {
    3462          40 :         torture_assert_int_equal(torture, cc_rsp->chunks_written,
    3463             :                                  ex_chunks_written, "num chunks");
    3464          40 :         torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
    3465             :                                  ex_chunk_bytes_written, "chunk bytes written");
    3466          40 :         torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
    3467             :                                  ex_total_bytes_written, "chunk total bytes");
    3468          40 :         return true;
    3469             : }
    3470             : 
    3471           8 : static bool neg_aapl_copyfile(struct torture_context *tctx,
    3472             :                               struct smb2_tree *tree,
    3473             :                               uint64_t flags)
    3474             : {
    3475           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    3476           8 :         const char *fname = "aapl";
    3477             :         NTSTATUS status;
    3478             :         struct smb2_create io;
    3479             :         DATA_BLOB data;
    3480           8 :         struct smb2_create_blob *aapl = NULL;
    3481             :         uint32_t aapl_cmd;
    3482             :         uint32_t aapl_reply_bitmap;
    3483             :         uint32_t aapl_server_caps;
    3484           8 :         bool ret = true;
    3485             : 
    3486           8 :         ZERO_STRUCT(io);
    3487           8 :         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
    3488           8 :         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
    3489           8 :         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    3490           8 :         io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE |
    3491             :                               NTCREATEX_SHARE_ACCESS_READ |
    3492             :                               NTCREATEX_SHARE_ACCESS_WRITE);
    3493           8 :         io.in.fname = fname;
    3494             : 
    3495           8 :         data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t));
    3496           8 :         SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY);
    3497           8 :         SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS));
    3498           8 :         SBVAL(data.data, 16, flags);
    3499             : 
    3500           8 :         status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data);
    3501           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    3502             : 
    3503           8 :         status = smb2_create(tree, tctx, &io);
    3504           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    3505             : 
    3506           8 :         aapl = smb2_create_blob_find(&io.out.blobs,
    3507             :                                      SMB2_CREATE_TAG_AAPL);
    3508           8 :         if (aapl == NULL) {
    3509           0 :                 ret = false;
    3510           0 :                 goto done;
    3511             : 
    3512             :         }
    3513           8 :         if (aapl->data.length < 24) {
    3514           0 :                 ret = false;
    3515           0 :                 goto done;
    3516             :         }
    3517             : 
    3518           8 :         aapl_cmd = IVAL(aapl->data.data, 0);
    3519           8 :         if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) {
    3520           0 :                 torture_result(tctx, TORTURE_FAIL,
    3521             :                                "(%s) unexpected cmd: %d",
    3522             :                                __location__, (int)aapl_cmd);
    3523           0 :                 ret = false;
    3524           0 :                 goto done;
    3525             :         }
    3526             : 
    3527           8 :         aapl_reply_bitmap = BVAL(aapl->data.data, 8);
    3528           8 :         if (!(aapl_reply_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS)) {
    3529           0 :                 torture_result(tctx, TORTURE_FAIL,
    3530             :                                "(%s) unexpected reply_bitmap: %d",
    3531             :                                __location__, (int)aapl_reply_bitmap);
    3532           0 :                 ret = false;
    3533           0 :                 goto done;
    3534             :         }
    3535             : 
    3536           8 :         aapl_server_caps = BVAL(aapl->data.data, 16);
    3537           8 :         if (!(aapl_server_caps & flags)) {
    3538           0 :                 torture_result(tctx, TORTURE_FAIL,
    3539             :                                "(%s) unexpected server_caps: %d",
    3540             :                                __location__, (int)aapl_server_caps);
    3541           0 :                 ret = false;
    3542           0 :                 goto done;
    3543             :         }
    3544             : 
    3545          16 : done:
    3546           8 :         status = smb2_util_close(tree, io.out.file.handle);
    3547           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    3548             : 
    3549           8 :         smb2_util_unlink(tree, "aapl");
    3550           8 :         talloc_free(mem_ctx);
    3551           8 :         return ret;
    3552             : }
    3553             : 
    3554           8 : static bool test_copyfile(struct torture_context *torture,
    3555             :                           struct smb2_tree *tree)
    3556             : {
    3557             :         struct smb2_handle src_h;
    3558             :         struct smb2_handle dest_h;
    3559             :         NTSTATUS status;
    3560             :         union smb_ioctl io;
    3561           8 :         TALLOC_CTX *tmp_ctx = talloc_new(tree);
    3562             :         struct srv_copychunk_copy cc_copy;
    3563             :         struct srv_copychunk_rsp cc_rsp;
    3564             :         enum ndr_err_code ndr_ret;
    3565             :         bool ok;
    3566           8 :         const char *sname = ":foo" "\xef\x80\xa2" "bar:$DATA";
    3567             : 
    3568             :         /*
    3569             :          * First test a copy_chunk with a 0 chunk count without having
    3570             :          * enabled this via AAPL. The request must not fail and the
    3571             :          * copied length in the response must be 0. This is verified
    3572             :          * against Windows 2008r2.
    3573             :          */
    3574             : 
    3575           8 :         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
    3576             :                                    0, /* 0 chunks, copyfile semantics */
    3577             :                                    FNAME_CC_SRC,
    3578             :                                    &src_h, 4096, /* fill 4096 byte src file */
    3579             :                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
    3580             :                                    FNAME_CC_DST,
    3581             :                                    &dest_h, 0,      /* 0 byte dest file */
    3582             :                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
    3583             :                                    &cc_copy,
    3584             :                                    &io);
    3585           8 :         if (!ok) {
    3586           0 :                 torture_fail_goto(torture, done, "setup copy chunk error");
    3587             :         }
    3588             : 
    3589           8 :         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
    3590             :                                        &cc_copy,
    3591             :                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
    3592           8 :         torture_assert_ndr_success(torture, ndr_ret,
    3593             :                                    "ndr_push_srv_copychunk_copy");
    3594             : 
    3595           8 :         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
    3596           8 :         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
    3597             : 
    3598           8 :         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
    3599             :                                        &cc_rsp,
    3600             :                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
    3601           8 :         torture_assert_ndr_success(torture, ndr_ret,
    3602             :                                    "ndr_pull_srv_copychunk_rsp");
    3603             : 
    3604           8 :         ok = check_copy_chunk_rsp(torture, &cc_rsp,
    3605             :                                   0,    /* chunks written */
    3606             :                                   0,    /* chunk bytes unsuccessfully written */
    3607             :                                   0); /* total bytes written */
    3608           8 :         if (!ok) {
    3609           0 :                 torture_fail_goto(torture, done, "bad copy chunk response data");
    3610             :         }
    3611             : 
    3612             :         /*
    3613             :          * Now enable AAPL copyfile and test again, the file and the
    3614             :          * stream must be copied by the server.
    3615             :          */
    3616           8 :         ok = neg_aapl_copyfile(torture, tree,
    3617             :                                SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE);
    3618           8 :         if (!ok) {
    3619           0 :                 torture_skip_goto(torture, done, "missing AAPL copyfile");
    3620             :                 goto done;
    3621             :         }
    3622             : 
    3623           8 :         smb2_util_close(tree, src_h);
    3624           8 :         smb2_util_close(tree, dest_h);
    3625           8 :         smb2_util_unlink(tree, FNAME_CC_SRC);
    3626           8 :         smb2_util_unlink(tree, FNAME_CC_DST);
    3627             : 
    3628           8 :         ok = torture_setup_file(tmp_ctx, tree, FNAME_CC_SRC, false);
    3629           8 :         if (!ok) {
    3630           0 :                 torture_fail(torture, "setup file error");
    3631             :         }
    3632           8 :         ok = write_stream(tree, __location__, torture, tmp_ctx,
    3633             :                             FNAME_CC_SRC, AFPRESOURCE_STREAM,
    3634             :                             10, 10, "1234567890");
    3635           8 :         if (!ok) {
    3636           0 :                 torture_fail(torture, "setup stream error");
    3637             :         }
    3638             : 
    3639           8 :         ok = write_stream(tree, __location__, torture, tmp_ctx,
    3640             :                             FNAME_CC_SRC, sname,
    3641             :                             10, 10, "abcdefghij");
    3642           8 :         torture_assert_goto(torture, ok == true, ok, done, "write_stream failed\n");
    3643             : 
    3644           8 :         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
    3645             :                                    0, /* 0 chunks, copyfile semantics */
    3646             :                                    FNAME_CC_SRC,
    3647             :                                    &src_h, 4096, /* fill 4096 byte src file */
    3648             :                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
    3649             :                                    FNAME_CC_DST,
    3650             :                                    &dest_h, 0,      /* 0 byte dest file */
    3651             :                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
    3652             :                                    &cc_copy,
    3653             :                                    &io);
    3654           8 :         if (!ok) {
    3655           0 :                 torture_fail_goto(torture, done, "setup copy chunk error");
    3656             :         }
    3657             : 
    3658           8 :         ndr_ret = ndr_push_struct_blob(&io.smb2.in.out, tmp_ctx,
    3659             :                                        &cc_copy,
    3660             :                         (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
    3661           8 :         torture_assert_ndr_success(torture, ndr_ret,
    3662             :                                    "ndr_push_srv_copychunk_copy");
    3663             : 
    3664           8 :         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
    3665           8 :         torture_assert_ntstatus_ok_goto(torture, status, ok, done, "FSCTL_SRV_COPYCHUNK");
    3666             : 
    3667           8 :         ndr_ret = ndr_pull_struct_blob(&io.smb2.out.out, tmp_ctx,
    3668             :                                        &cc_rsp,
    3669             :                         (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
    3670           8 :         torture_assert_ndr_success(torture, ndr_ret,
    3671             :                                    "ndr_pull_srv_copychunk_rsp");
    3672             : 
    3673           8 :         ok = check_copy_chunk_rsp(torture, &cc_rsp,
    3674             :                                   0,    /* chunks written */
    3675             :                                   0,    /* chunk bytes unsuccessfully written */
    3676             :                                   4096); /* total bytes written */
    3677           8 :         if (!ok) {
    3678           0 :                 torture_fail_goto(torture, done, "bad copy chunk response data");
    3679             :         }
    3680             : 
    3681           8 :         ok = test_setup_open(torture, tree, tmp_ctx, FNAME_CC_DST, &dest_h,
    3682             :                              SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL);
    3683           8 :         if (!ok) {
    3684           0 :                 torture_fail_goto(torture, done,"open failed");
    3685             :         }
    3686           8 :         ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
    3687           8 :         if (!ok) {
    3688           0 :                 torture_fail_goto(torture, done, "inconsistent file data");
    3689             :         }
    3690             : 
    3691           8 :         ok = check_stream(tree, __location__, torture, tmp_ctx,
    3692             :                             FNAME_CC_DST, AFPRESOURCE_STREAM,
    3693             :                             0, 20, 10, 10, "1234567890");
    3694           8 :         if (!ok) {
    3695           0 :                 torture_fail_goto(torture, done, "inconsistent stream data");
    3696             :         }
    3697             : 
    3698           8 :         ok = check_stream(tree, __location__, torture, tmp_ctx,
    3699             :                             FNAME_CC_DST, sname,
    3700             :                             0, 20, 10, 10, "abcdefghij");
    3701           8 :         torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
    3702             : 
    3703          16 : done:
    3704           8 :         smb2_util_close(tree, src_h);
    3705           8 :         smb2_util_close(tree, dest_h);
    3706           8 :         smb2_util_unlink(tree, FNAME_CC_SRC);
    3707           8 :         smb2_util_unlink(tree, FNAME_CC_DST);
    3708           8 :         talloc_free(tmp_ctx);
    3709           8 :         return true;
    3710             : }
    3711             : 
    3712        1492 : static bool check_stream_list(struct smb2_tree *tree,
    3713             :                               struct torture_context *tctx,
    3714             :                               const char *fname,
    3715             :                               int num_exp,
    3716             :                               const char **exp,
    3717             :                               bool is_dir)
    3718             : {
    3719        1492 :         bool ret = true;
    3720             :         union smb_fileinfo finfo;
    3721             :         NTSTATUS status;
    3722             :         int i;
    3723        1492 :         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
    3724             :         char **exp_sort;
    3725             :         struct stream_struct *stream_sort;
    3726             :         struct smb2_create create;
    3727             :         struct smb2_handle h;
    3728             : 
    3729        1492 :         ZERO_STRUCT(h);
    3730        1492 :         torture_assert_goto(tctx, tmp_ctx != NULL, ret, done, "talloc_new failed");
    3731             : 
    3732        1492 :         ZERO_STRUCT(create);
    3733        1492 :         create.in.fname = fname;
    3734        1492 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    3735        1492 :         create.in.desired_access = SEC_FILE_ALL;
    3736        1492 :         create.in.create_options = is_dir ? NTCREATEX_OPTIONS_DIRECTORY : 0;
    3737        1492 :         create.in.file_attributes = is_dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
    3738        1492 :         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    3739        1492 :         status = smb2_create(tree, tmp_ctx, &create);
    3740        1492 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create");
    3741        1492 :         h = create.out.file.handle;
    3742             : 
    3743        1492 :         finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
    3744        1492 :         finfo.generic.in.file.handle = h;
    3745             : 
    3746        1492 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    3747        1492 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "get stream info");
    3748             : 
    3749        1492 :         smb2_util_close(tree, h);
    3750             : 
    3751        1492 :         torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams, num_exp,
    3752             :                                       ret, done, "stream count");
    3753             : 
    3754        1490 :         if (num_exp == 0) {
    3755           0 :                 TALLOC_FREE(tmp_ctx);
    3756           0 :                 goto done;
    3757             :         }
    3758             : 
    3759        1490 :         exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
    3760        1490 :         torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
    3761             : 
    3762        1490 :         TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
    3763             : 
    3764        1490 :         stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
    3765             :                                     finfo.stream_info.out.num_streams *
    3766             :                                     sizeof(*stream_sort));
    3767        1490 :         torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
    3768             : 
    3769        1490 :         TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
    3770             : 
    3771        3480 :         for (i=0; i<num_exp; i++) {
    3772        3980 :                 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
    3773        3980 :                                 i, exp_sort[i], stream_sort[i].stream_name.s);
    3774        1990 :                 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s, exp_sort[i],
    3775             :                                               ret, done, "stream name");
    3776             :         }
    3777             : 
    3778        1490 : done:
    3779        1492 :         TALLOC_FREE(tmp_ctx);
    3780        1492 :         return ret;
    3781             : }
    3782             : 
    3783         288 : static bool check_stream_list_handle(struct smb2_tree *tree,
    3784             :                                      struct torture_context *tctx,
    3785             :                                      struct smb2_handle h,
    3786             :                                      int num_exp,
    3787             :                                      const char **exp,
    3788             :                                      bool is_dir)
    3789             : {
    3790         288 :         bool ret = true;
    3791             :         union smb_fileinfo finfo;
    3792             :         NTSTATUS status;
    3793             :         int i;
    3794         288 :         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
    3795             :         char **exp_sort;
    3796             :         struct stream_struct *stream_sort;
    3797             : 
    3798         288 :         torture_assert_goto(tctx, tmp_ctx != NULL, ret, done,
    3799             :                             "talloc_new failed\n");
    3800             : 
    3801         288 :         finfo = (union smb_fileinfo) {
    3802             :                 .stream_info.level = RAW_FILEINFO_STREAM_INFORMATION,
    3803             :                 .stream_info.in.file.handle = h,
    3804             :         };
    3805             : 
    3806         288 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    3807         288 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3808             :                                         "get stream info\n");
    3809             : 
    3810         288 :         torture_assert_int_equal_goto(tctx, finfo.stream_info.out.num_streams,
    3811             :                                       num_exp, ret, done, "stream count\n");
    3812             : 
    3813         288 :         if (num_exp == 0) {
    3814           0 :                 TALLOC_FREE(tmp_ctx);
    3815           0 :                 goto done;
    3816             :         }
    3817             : 
    3818         288 :         exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp));
    3819         288 :         torture_assert_goto(tctx, exp_sort != NULL, ret, done, __location__);
    3820             : 
    3821         288 :         TYPESAFE_QSORT(exp_sort, num_exp, qsort_string);
    3822             : 
    3823         288 :         stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams,
    3824             :                                     finfo.stream_info.out.num_streams *
    3825             :                                     sizeof(*stream_sort));
    3826         288 :         torture_assert_goto(tctx, stream_sort != NULL, ret, done, __location__);
    3827             : 
    3828         288 :         TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream);
    3829             : 
    3830         672 :         for (i=0; i<num_exp; i++) {
    3831         768 :                 torture_comment(tctx, "i[%d] exp[%s] got[%s]\n",
    3832         768 :                                 i, exp_sort[i], stream_sort[i].stream_name.s);
    3833         384 :                 torture_assert_str_equal_goto(tctx, stream_sort[i].stream_name.s,
    3834             :                                               exp_sort[i], ret, done,
    3835             :                                               "stream name\n");
    3836             :         }
    3837             : 
    3838         288 : done:
    3839         288 :         TALLOC_FREE(tmp_ctx);
    3840         288 :         return ret;
    3841             : }
    3842             : 
    3843             : /*
    3844             :   test stream names
    3845             : */
    3846           8 : static bool test_stream_names(struct torture_context *tctx,
    3847             :                               struct smb2_tree *tree)
    3848             : {
    3849           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    3850             :         NTSTATUS status;
    3851             :         struct smb2_create create;
    3852             :         struct smb2_handle h;
    3853           8 :         const char *fname = BASEDIR "\\stream_names.txt";
    3854             :         const char *sname1;
    3855             :         bool ret;
    3856             :         /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
    3857           8 :         const char *streams[] = {
    3858             :                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
    3859             :                 "::$DATA"
    3860             :         };
    3861             : 
    3862           8 :         sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
    3863             : 
    3864             :         /* clean slate ...*/
    3865           8 :         smb2_util_unlink(tree, fname);
    3866           8 :         smb2_deltree(tree, fname);
    3867           8 :         smb2_deltree(tree, BASEDIR);
    3868             : 
    3869           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h);
    3870           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    3871           8 :         smb2_util_close(tree, h);
    3872             : 
    3873           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    3874           8 :         torture_assert_goto(tctx, ret, ret, done, "torture_setup_file");
    3875             : 
    3876           8 :         torture_comment(tctx, "(%s) testing stream names\n", __location__);
    3877           8 :         ZERO_STRUCT(create);
    3878           8 :         create.in.desired_access = SEC_FILE_WRITE_DATA;
    3879           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    3880           8 :         create.in.share_access =
    3881             :                 NTCREATEX_SHARE_ACCESS_DELETE|
    3882             :                 NTCREATEX_SHARE_ACCESS_READ|
    3883             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    3884           8 :         create.in.create_disposition = NTCREATEX_DISP_CREATE;
    3885           8 :         create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    3886           8 :         create.in.fname = sname1;
    3887             : 
    3888           8 :         status = smb2_create(tree, mem_ctx, &create);
    3889           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    3890             : 
    3891           8 :         status = smb2_util_write(tree, create.out.file.handle, "foo", 0, 3);
    3892           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    3893             :                                         "smb2_util_write failed\n");
    3894             : 
    3895           8 :         smb2_util_close(tree, create.out.file.handle);
    3896             : 
    3897           8 :         ret = check_stream_list(tree, tctx, fname, 2, streams, false);
    3898           8 :         CHECK_VALUE(ret, true);
    3899             : 
    3900          16 : done:
    3901           8 :         status = smb2_util_unlink(tree, fname);
    3902           8 :         smb2_deltree(tree, BASEDIR);
    3903           8 :         talloc_free(mem_ctx);
    3904             : 
    3905           8 :         return ret;
    3906             : }
    3907             : 
    3908             : /* Renaming a directory with open file, should work for OS X AAPL clients */
    3909           8 : static bool test_rename_dir_openfile(struct torture_context *torture,
    3910             :                                      struct smb2_tree *tree)
    3911             : {
    3912           8 :         bool ret = true;
    3913             :         NTSTATUS status;
    3914             :         union smb_open io;
    3915             :         union smb_close cl;
    3916             :         union smb_setfileinfo sinfo;
    3917             :         struct smb2_handle d1, h1;
    3918           8 :         const char *renamedir = BASEDIR "-new";
    3919           8 :         bool server_is_osx = torture_setting_bool(torture, "osx", false);
    3920             : 
    3921           8 :         smb2_deltree(tree, BASEDIR);
    3922           8 :         smb2_util_rmdir(tree, BASEDIR);
    3923           8 :         smb2_deltree(tree, renamedir);
    3924             : 
    3925           8 :         ZERO_STRUCT(io.smb2);
    3926           8 :         io.generic.level = RAW_OPEN_SMB2;
    3927           8 :         io.smb2.in.create_flags = 0;
    3928           8 :         io.smb2.in.desired_access = 0x0017019f;
    3929           8 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    3930           8 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    3931           8 :         io.smb2.in.share_access = 0;
    3932           8 :         io.smb2.in.alloc_size = 0;
    3933           8 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    3934           8 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    3935           8 :         io.smb2.in.security_flags = 0;
    3936           8 :         io.smb2.in.fname = BASEDIR;
    3937             : 
    3938           8 :         status = smb2_create(tree, torture, &(io.smb2));
    3939           8 :         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
    3940           8 :         d1 = io.smb2.out.file.handle;
    3941             : 
    3942           8 :         ZERO_STRUCT(io.smb2);
    3943           8 :         io.generic.level = RAW_OPEN_SMB2;
    3944           8 :         io.smb2.in.create_flags = 0;
    3945           8 :         io.smb2.in.desired_access = 0x0017019f;
    3946           8 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
    3947           8 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    3948           8 :         io.smb2.in.share_access = 0;
    3949           8 :         io.smb2.in.alloc_size = 0;
    3950           8 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    3951           8 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    3952           8 :         io.smb2.in.security_flags = 0;
    3953           8 :         io.smb2.in.fname = BASEDIR "\\file.txt";
    3954             : 
    3955           8 :         status = smb2_create(tree, torture, &(io.smb2));
    3956           8 :         torture_assert_ntstatus_ok(torture, status, "smb2_create file");
    3957           8 :         h1 = io.smb2.out.file.handle;
    3958             : 
    3959           8 :         if (!server_is_osx) {
    3960           8 :                 torture_comment(torture, "Renaming directory without AAPL, must fail\n");
    3961             : 
    3962           8 :                 ZERO_STRUCT(sinfo);
    3963           8 :                 sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
    3964           8 :                 sinfo.rename_information.in.file.handle = d1;
    3965           8 :                 sinfo.rename_information.in.overwrite = 0;
    3966           8 :                 sinfo.rename_information.in.root_fid = 0;
    3967           8 :                 sinfo.rename_information.in.new_name = renamedir;
    3968           8 :                 status = smb2_setinfo_file(tree, &sinfo);
    3969             : 
    3970           8 :                 torture_assert_ntstatus_equal(torture, status,
    3971             :                                               NT_STATUS_ACCESS_DENIED,
    3972             :                                               "smb2_setinfo_file");
    3973             :         }
    3974             : 
    3975           8 :         status = smb2_util_close(tree, d1);
    3976           8 :         torture_assert_ntstatus_ok(torture, status, "smb2_util_close\n");
    3977           8 :         ZERO_STRUCT(d1);
    3978             : 
    3979           8 :         torture_comment(torture, "Enabling AAPL\n");
    3980             : 
    3981           8 :         ret = enable_aapl(torture, tree);
    3982           8 :         torture_assert(torture, ret == true, "enable_aapl failed");
    3983             : 
    3984           8 :         torture_comment(torture, "Renaming directory with AAPL\n");
    3985             : 
    3986           8 :         ZERO_STRUCT(io.smb2);
    3987           8 :         io.generic.level = RAW_OPEN_SMB2;
    3988           8 :         io.smb2.in.desired_access = 0x0017019f;
    3989           8 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    3990           8 :         io.smb2.in.share_access = 0;
    3991           8 :         io.smb2.in.alloc_size = 0;
    3992           8 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
    3993           8 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    3994           8 :         io.smb2.in.security_flags = 0;
    3995           8 :         io.smb2.in.fname = BASEDIR;
    3996             : 
    3997           8 :         status = smb2_create(tree, torture, &(io.smb2));
    3998           8 :         torture_assert_ntstatus_ok(torture, status, "smb2_create dir");
    3999           8 :         d1 = io.smb2.out.file.handle;
    4000             : 
    4001           8 :         ZERO_STRUCT(sinfo);
    4002           8 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
    4003           8 :         sinfo.rename_information.in.file.handle = d1;
    4004           8 :         sinfo.rename_information.in.overwrite = 0;
    4005           8 :         sinfo.rename_information.in.root_fid = 0;
    4006           8 :         sinfo.rename_information.in.new_name = renamedir;
    4007             : 
    4008           8 :         status = smb2_setinfo_file(tree, &sinfo);
    4009           8 :         torture_assert_ntstatus_ok(torture, status, "smb2_setinfo_file");
    4010             : 
    4011           8 :         ZERO_STRUCT(cl.smb2);
    4012           8 :         cl.smb2.level = RAW_CLOSE_SMB2;
    4013           8 :         cl.smb2.in.file.handle = d1;
    4014           8 :         status = smb2_close(tree, &(cl.smb2));
    4015           8 :         torture_assert_ntstatus_ok(torture, status, "smb2_close");
    4016           8 :         ZERO_STRUCT(d1);
    4017             : 
    4018           8 :         cl.smb2.in.file.handle = h1;
    4019           8 :         status = smb2_close(tree, &(cl.smb2));
    4020           8 :         torture_assert_ntstatus_ok(torture, status, "smb2_close");
    4021           8 :         ZERO_STRUCT(h1);
    4022             : 
    4023           8 :         torture_comment(torture, "Cleaning up\n");
    4024             : 
    4025           8 :         if (h1.data[0] || h1.data[1]) {
    4026           0 :                 ZERO_STRUCT(cl.smb2);
    4027           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
    4028           0 :                 cl.smb2.in.file.handle = h1;
    4029           0 :                 status = smb2_close(tree, &(cl.smb2));
    4030             :         }
    4031             : 
    4032           8 :         smb2_util_unlink(tree, BASEDIR "\\file.txt");
    4033           8 :         smb2_util_unlink(tree, BASEDIR "-new\\file.txt");
    4034           8 :         smb2_deltree(tree, renamedir);
    4035           8 :         smb2_deltree(tree, BASEDIR);
    4036           8 :         return ret;
    4037             : }
    4038             : 
    4039           8 : static bool test_afpinfo_enoent(struct torture_context *tctx,
    4040             :                                 struct smb2_tree *tree)
    4041             : {
    4042           8 :         bool ret = true;
    4043             :         NTSTATUS status;
    4044             :         struct smb2_create create;
    4045             :         struct smb2_handle h1;
    4046           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4047           8 :         const char *fname = BASEDIR "\\file";
    4048           8 :         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
    4049             : 
    4050           8 :         torture_comment(tctx, "Opening file without AFP_AfpInfo\n");
    4051             : 
    4052           8 :         smb2_deltree(tree, BASEDIR);
    4053           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h1);
    4054           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
    4055           8 :         smb2_util_close(tree, h1);
    4056           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    4057           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    4058             : 
    4059           8 :         torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
    4060             : 
    4061           8 :         ZERO_STRUCT(create);
    4062           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4063           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
    4064           8 :         create.in.fname = sname;
    4065             : 
    4066           8 :         status = smb2_create(tree, mem_ctx, &create);
    4067           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    4068             :                                            ret, done, "Got unexpected AFP_AfpInfo stream");
    4069             : 
    4070           8 : done:
    4071           8 :         smb2_util_unlink(tree, fname);
    4072           8 :         smb2_util_rmdir(tree, BASEDIR);
    4073           8 :         return ret;
    4074             : }
    4075             : 
    4076           8 : static bool test_create_delete_on_close(struct torture_context *tctx,
    4077             :                                         struct smb2_tree *tree)
    4078             : {
    4079           8 :         bool ret = true;
    4080             :         NTSTATUS status;
    4081             :         struct smb2_create create;
    4082             :         struct smb2_handle h1;
    4083           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4084           8 :         const char *fname = BASEDIR "\\file";
    4085           8 :         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
    4086           8 :         const char *type_creator = "SMB,OLE!";
    4087           8 :         AfpInfo *info = NULL;
    4088           8 :         const char *streams_basic[] = {
    4089             :                 "::$DATA"
    4090             :         };
    4091           8 :         const char *streams_afpinfo[] = {
    4092             :                 "::$DATA",
    4093             :                 AFPINFO_STREAM
    4094             :         };
    4095             : 
    4096           8 :         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
    4097             : 
    4098           8 :         torture_comment(tctx, "Checking whether create with delete-on-close work with AFP_AfpInfo\n");
    4099             : 
    4100           8 :         smb2_deltree(tree, BASEDIR);
    4101           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h1);
    4102           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
    4103           8 :         smb2_util_close(tree, h1);
    4104           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    4105           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    4106             : 
    4107           8 :         torture_comment(tctx, "Opening not existing AFP_AfpInfo\n");
    4108             : 
    4109           8 :         ZERO_STRUCT(create);
    4110           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4111           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
    4112           8 :         create.in.fname = sname;
    4113             : 
    4114           8 :         status = smb2_create(tree, mem_ctx, &create);
    4115           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    4116             :                                            ret, done, "Got unexpected AFP_AfpInfo stream");
    4117             : 
    4118           8 :         ZERO_STRUCT(create);
    4119           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4120           8 :         create.in.desired_access = SEC_FILE_ALL;
    4121           8 :         create.in.fname = sname;
    4122             : 
    4123           8 :         status = smb2_create(tree, mem_ctx, &create);
    4124           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    4125             :                                            ret, done, "Got unexpected AFP_AfpInfo stream");
    4126             : 
    4127           8 :         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
    4128           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4129             : 
    4130           8 :         torture_comment(tctx, "Deleting AFP_AfpInfo via create with delete-on-close\n");
    4131             : 
    4132           8 :         info = torture_afpinfo_new(mem_ctx);
    4133           8 :         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
    4134             : 
    4135           8 :         memcpy(info->afpi_FinderInfo, type_creator, 8);
    4136           8 :         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
    4137           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
    4138             : 
    4139           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    4140             :                            0, 60, 16, 8, type_creator);
    4141           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad type/creator in AFP_AfpInfo");
    4142             : 
    4143           8 :         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
    4144           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4145             : 
    4146           8 :         ZERO_STRUCT(create);
    4147           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4148           8 :         create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
    4149           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
    4150           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4151           8 :         create.in.fname = sname;
    4152           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4153             : 
    4154           8 :         status = smb2_create(tree, mem_ctx, &create);
    4155           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    4156             : 
    4157           8 :         h1 = create.out.file.handle;
    4158           8 :         smb2_util_close(tree, h1);
    4159             : 
    4160           8 :         ZERO_STRUCT(create);
    4161           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4162           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
    4163           8 :         create.in.fname = sname;
    4164           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4165           8 :         status = smb2_create(tree, mem_ctx, &create);
    4166           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    4167             :                                            ret, done, "Got unexpected AFP_AfpInfo stream");
    4168             : 
    4169           8 :         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
    4170           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4171             : 
    4172          16 : done:
    4173           8 :         smb2_util_unlink(tree, fname);
    4174           8 :         smb2_util_rmdir(tree, BASEDIR);
    4175           8 :         return ret;
    4176             : }
    4177             : 
    4178           8 : static bool test_setinfo_delete_on_close(struct torture_context *tctx,
    4179             :                                          struct smb2_tree *tree)
    4180             : {
    4181           8 :         bool ret = true;
    4182             :         NTSTATUS status;
    4183             :         struct smb2_create create;
    4184             :         union smb_setfileinfo sfinfo;
    4185             :         struct smb2_handle h1;
    4186           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4187           8 :         const char *fname = BASEDIR "\\file";
    4188           8 :         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
    4189           8 :         const char *type_creator = "SMB,OLE!";
    4190           8 :         AfpInfo *info = NULL;
    4191           8 :         const char *streams[] = {
    4192             :                 AFPINFO_STREAM,
    4193             :                 "::$DATA"
    4194             :         };
    4195           8 :         const char *streams_basic[] = {
    4196             :                 "::$DATA"
    4197             :         };
    4198             : 
    4199           8 :         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
    4200             : 
    4201           8 :         torture_comment(tctx, "Deleting AFP_AfpInfo via setinfo with delete-on-close\n");
    4202             : 
    4203           8 :         smb2_deltree(tree, BASEDIR);
    4204           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h1);
    4205           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
    4206           8 :         smb2_util_close(tree, h1);
    4207           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    4208           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    4209             : 
    4210           8 :         info = torture_afpinfo_new(mem_ctx);
    4211           8 :         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
    4212           8 :         memcpy(info->afpi_FinderInfo, type_creator, 8);
    4213           8 :         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
    4214           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
    4215             : 
    4216           8 :         ZERO_STRUCT(create);
    4217           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4218           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
    4219           8 :         create.in.fname = sname;
    4220           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4221           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4222             : 
    4223           8 :         status = smb2_create(tree, mem_ctx, &create);
    4224           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    4225             : 
    4226           8 :         h1 = create.out.file.handle;
    4227             : 
    4228             :         /* Delete stream via setinfo delete-on-close */
    4229           8 :         ZERO_STRUCT(sfinfo);
    4230           8 :         sfinfo.disposition_info.in.delete_on_close = 1;
    4231           8 :         sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
    4232           8 :         sfinfo.generic.in.file.handle = h1;
    4233           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    4234           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
    4235             : 
    4236           8 :         ret = check_stream_list(tree, tctx, fname, 2, streams, false);
    4237           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4238             : 
    4239           8 :         ZERO_STRUCT(create);
    4240           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4241           8 :         create.in.desired_access = SEC_FILE_ALL;
    4242           8 :         create.in.fname = sname;
    4243           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4244           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4245           8 :         status = smb2_create(tree, mem_ctx, &create);
    4246           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_DELETE_PENDING,
    4247             :                                            ret, done, "Got unexpected AFP_AfpInfo stream");
    4248             : 
    4249           8 :         smb2_util_close(tree, h1);
    4250             : 
    4251           8 :         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
    4252           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4253             : 
    4254           8 :         ZERO_STRUCT(create);
    4255           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4256           8 :         create.in.desired_access = SEC_FILE_ALL;
    4257           8 :         create.in.fname = sname;
    4258           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4259           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4260           8 :         status = smb2_create(tree, mem_ctx, &create);
    4261           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    4262             :                                            ret, done, "Got unexpected AFP_AfpInfo stream");
    4263             : 
    4264           8 : done:
    4265           8 :         smb2_util_unlink(tree, fname);
    4266           8 :         smb2_util_rmdir(tree, BASEDIR);
    4267           8 :         return ret;
    4268             : }
    4269             : 
    4270           8 : static bool test_setinfo_eof(struct torture_context *tctx,
    4271             :                              struct smb2_tree *tree)
    4272             : {
    4273           8 :         bool ret = true;
    4274             :         NTSTATUS status;
    4275             :         struct smb2_create create;
    4276             :         union smb_setfileinfo sfinfo;
    4277             :         struct smb2_handle h1;
    4278           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4279           8 :         const char *fname = BASEDIR "\\file";
    4280           8 :         const char *sname = BASEDIR "\\file" AFPINFO_STREAM_NAME;
    4281           8 :         const char *type_creator = "SMB,OLE!";
    4282           8 :         AfpInfo *info = NULL;
    4283           8 :         const char *streams_afpinfo[] = {
    4284             :                 "::$DATA",
    4285             :                 AFPINFO_STREAM
    4286             :         };
    4287             : 
    4288           8 :         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
    4289             : 
    4290           8 :         torture_comment(tctx, "Set AFP_AfpInfo EOF to 61, 1 and 0\n");
    4291             : 
    4292           8 :         smb2_deltree(tree, BASEDIR);
    4293           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h1);
    4294           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
    4295           8 :         smb2_util_close(tree, h1);
    4296           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    4297           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    4298             : 
    4299           8 :         info = torture_afpinfo_new(mem_ctx);
    4300           8 :         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
    4301           8 :         memcpy(info->afpi_FinderInfo, type_creator, 8);
    4302           8 :         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
    4303           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
    4304             : 
    4305           8 :         ZERO_STRUCT(create);
    4306           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4307           8 :         create.in.desired_access = SEC_FILE_ALL;
    4308           8 :         create.in.fname = sname;
    4309           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4310           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4311             : 
    4312           8 :         status = smb2_create(tree, mem_ctx, &create);
    4313           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    4314             : 
    4315           8 :         h1 = create.out.file.handle;
    4316             : 
    4317           8 :         torture_comment(tctx, "Set AFP_AfpInfo EOF to 61\n");
    4318             : 
    4319             :         /* Test setinfo end-of-file info */
    4320           8 :         ZERO_STRUCT(sfinfo);
    4321           8 :         sfinfo.generic.in.file.handle = h1;
    4322           8 :         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    4323           8 :         sfinfo.position_information.in.position = 61;
    4324           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    4325           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ALLOTTED_SPACE_EXCEEDED,
    4326             :                                            ret, done, "set eof 61 failed");
    4327             : 
    4328           8 :         torture_comment(tctx, "Set AFP_AfpInfo EOF to 1\n");
    4329             : 
    4330             :         /* Truncation returns success, but has no effect */
    4331           8 :         ZERO_STRUCT(sfinfo);
    4332           8 :         sfinfo.generic.in.file.handle = h1;
    4333           8 :         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    4334           8 :         sfinfo.position_information.in.position = 1;
    4335           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    4336           8 :         torture_assert_ntstatus_ok_goto(tctx, status,
    4337             :                                         ret, done, "set eof 1 failed");
    4338           8 :         smb2_util_close(tree, h1);
    4339             : 
    4340           8 :         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
    4341           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4342             : 
    4343           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    4344             :                            0, 60, 16, 8, type_creator);
    4345           8 :         torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
    4346             : 
    4347           8 :         ZERO_STRUCT(create);
    4348           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4349           8 :         create.in.desired_access = SEC_FILE_ALL;
    4350           8 :         create.in.fname = sname;
    4351           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4352           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4353             : 
    4354           8 :         status = smb2_create(tree, mem_ctx, &create);
    4355           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    4356             : 
    4357           8 :         h1 = create.out.file.handle;
    4358             : 
    4359             :         /*
    4360             :          * Delete stream via setinfo end-of-file info to 0, should
    4361             :          * return success but stream MUST NOT deleted
    4362             :          */
    4363           8 :         ZERO_STRUCT(sfinfo);
    4364           8 :         sfinfo.generic.in.file.handle = h1;
    4365           8 :         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    4366           8 :         sfinfo.position_information.in.position = 0;
    4367           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    4368           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
    4369             : 
    4370           8 :         smb2_util_close(tree, h1);
    4371             : 
    4372           8 :         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
    4373           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4374             : 
    4375           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    4376             :                            0, 60, 16, 8, type_creator);
    4377           8 :         torture_assert_goto(tctx, ret == true, ret, done, "FinderInfo changed");
    4378             : 
    4379          16 : done:
    4380           8 :         smb2_util_unlink(tree, fname);
    4381           8 :         smb2_util_rmdir(tree, BASEDIR);
    4382           8 :         return ret;
    4383             : }
    4384             : 
    4385           8 : static bool test_afpinfo_all0(struct torture_context *tctx,
    4386             :                               struct smb2_tree *tree)
    4387             : {
    4388           8 :         bool ret = true;
    4389             :         NTSTATUS status;
    4390             :         struct smb2_create create;
    4391           8 :         struct smb2_handle h1 = {{0}};
    4392           8 :         struct smb2_handle baseh = {{0}};
    4393             :         union smb_setfileinfo setfinfo;
    4394             :         union smb_fileinfo getfinfo;
    4395           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4396           8 :         const char *fname = BASEDIR "\\file";
    4397           8 :         const char *sname = BASEDIR "\\file" AFPINFO_STREAM;
    4398           8 :         const char *type_creator = "SMB,OLE!";
    4399           8 :         AfpInfo *info = NULL;
    4400           8 :         char *infobuf = NULL;
    4401           8 :         const char *streams_basic[] = {
    4402             :                 "::$DATA"
    4403             :         };
    4404           8 :         const char *streams_afpinfo[] = {
    4405             :                 "::$DATA",
    4406             :                 AFPINFO_STREAM
    4407             :         };
    4408             : 
    4409           8 :         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
    4410             : 
    4411           8 :         torture_comment(tctx, "Write all 0 to AFP_AfpInfo and see what happens\n");
    4412             : 
    4413           8 :         smb2_deltree(tree, BASEDIR);
    4414           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h1);
    4415           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
    4416           8 :         smb2_util_close(tree, h1);
    4417           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    4418           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    4419             : 
    4420           8 :         info = torture_afpinfo_new(mem_ctx);
    4421           8 :         torture_assert_goto(tctx, info != NULL, ret, done, "torture_afpinfo_new failed");
    4422           8 :         memcpy(info->afpi_FinderInfo, type_creator, 8);
    4423           8 :         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
    4424           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
    4425             : 
    4426           8 :         ret = check_stream_list(tree, tctx, fname, 2, streams_afpinfo, false);
    4427           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4428             : 
    4429             :         /* Write all 0 to AFP_AfpInfo */
    4430           8 :         memset(info->afpi_FinderInfo, 0, AFP_FinderSize);
    4431           8 :         infobuf = torture_afpinfo_pack(mem_ctx, info);
    4432           8 :         torture_assert_not_null_goto(tctx, infobuf, ret, done,
    4433             :                                      "torture_afpinfo_pack failed\n");
    4434             : 
    4435           8 :         ZERO_STRUCT(create);
    4436           8 :         create.in.desired_access = SEC_FILE_ALL;
    4437           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4438           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4439           8 :         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    4440           8 :         create.in.fname = fname;
    4441             : 
    4442           8 :         status = smb2_create(tree, mem_ctx, &create);
    4443           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    4444             :                                         "smb2_create failed\n");
    4445           8 :         baseh = create.out.file.handle;
    4446             : 
    4447           8 :         ZERO_STRUCT(create);
    4448           8 :         create.in.desired_access = SEC_FILE_ALL;
    4449           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4450           8 :         create.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    4451           8 :         create.in.fname = sname;
    4452             : 
    4453           8 :         status = smb2_create(tree, mem_ctx, &create);
    4454           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    4455             :                                         "smb2_create failed\n");
    4456           8 :         h1 = create.out.file.handle;
    4457             : 
    4458           8 :         status = smb2_util_write(tree, h1, infobuf, 0, AFP_INFO_SIZE);
    4459           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    4460             :                                         "smb2_util_write failed\n");
    4461             : 
    4462             :         /*
    4463             :          * Get stream information on open handle, must return only default
    4464             :          * stream, the AFP_AfpInfo stream must not be returned.
    4465             :          */
    4466             : 
    4467           8 :         ZERO_STRUCT(getfinfo);
    4468           8 :         getfinfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
    4469           8 :         getfinfo.generic.in.file.handle = baseh;
    4470             : 
    4471           8 :         status = smb2_getinfo_file(tree, tctx, &getfinfo);
    4472           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    4473             :                                         "get stream info\n");
    4474             : 
    4475           8 :         torture_assert_int_equal_goto(tctx, getfinfo.stream_info.out.num_streams,
    4476             :                                       1, ret, done, "stream count");
    4477             : 
    4478           8 :         smb2_util_close(tree, baseh);
    4479           8 :         ZERO_STRUCT(baseh);
    4480             : 
    4481             :         /*
    4482             :          * Try to set some file-basic-info (time) on the stream. This catches
    4483             :          * naive implementation mistakes that simply deleted the backing store
    4484             :          * from the filesystem in the zero-out step.
    4485             :          */
    4486             : 
    4487           8 :         ZERO_STRUCT(setfinfo);
    4488           8 :         unix_to_nt_time(&setfinfo.basic_info.in.write_time, time(NULL));
    4489           8 :         setfinfo.basic_info.in.attrib = 0x20;
    4490           8 :         setfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
    4491           8 :         setfinfo.generic.in.file.handle = h1;
    4492             : 
    4493           8 :         status = smb2_setinfo_file(tree, &setfinfo);
    4494           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    4495             :                                         "smb2_getinfo_file failed\n");
    4496             : 
    4497           8 :         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
    4498           8 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
    4499             : 
    4500           8 :         smb2_util_close(tree, h1);
    4501           8 :         ZERO_STRUCT(h1);
    4502             : 
    4503           8 :         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
    4504           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4505             : 
    4506          16 : done:
    4507           8 :         if (!smb2_util_handle_empty(h1)) {
    4508           0 :                 smb2_util_close(tree, h1);
    4509             :         }
    4510           8 :         if (!smb2_util_handle_empty(baseh)) {
    4511           0 :                 smb2_util_close(tree, baseh);
    4512             :         }
    4513           8 :         smb2_util_unlink(tree, fname);
    4514           8 :         smb2_util_rmdir(tree, BASEDIR);
    4515           8 :         return ret;
    4516             : }
    4517             : 
    4518           8 : static bool test_create_delete_on_close_resource(struct torture_context *tctx,
    4519             :                                                  struct smb2_tree *tree)
    4520             : {
    4521           8 :         bool ret = true;
    4522             :         NTSTATUS status;
    4523             :         struct smb2_create create;
    4524             :         struct smb2_handle h1;
    4525           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4526           8 :         const char *fname = BASEDIR "\\file";
    4527           8 :         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
    4528           8 :         const char *streams_basic[] = {
    4529             :                 "::$DATA"
    4530             :         };
    4531           8 :         const char *streams_afpresource[] = {
    4532             :                 "::$DATA",
    4533             :                 AFPRESOURCE_STREAM
    4534             :         };
    4535             : 
    4536           8 :         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
    4537             : 
    4538           8 :         torture_comment(tctx, "Checking whether create with delete-on-close is ignored for AFP_AfpResource\n");
    4539             : 
    4540           8 :         smb2_deltree(tree, BASEDIR);
    4541           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h1);
    4542           8 :         torture_assert_ntstatus_ok(tctx, status, "torture_smb2_testdir");
    4543           8 :         smb2_util_close(tree, h1);
    4544           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    4545           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    4546             : 
    4547           8 :         torture_comment(tctx, "Opening not existing AFP_AfpResource\n");
    4548             : 
    4549           8 :         ZERO_STRUCT(create);
    4550           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4551           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE; /* stat open */
    4552           8 :         create.in.fname = sname;
    4553             : 
    4554           8 :         status = smb2_create(tree, mem_ctx, &create);
    4555           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    4556             :                                            ret, done, "Got unexpected AFP_AfpResource stream");
    4557             : 
    4558           8 :         ZERO_STRUCT(create);
    4559           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4560           8 :         create.in.desired_access = SEC_FILE_ALL;
    4561           8 :         create.in.fname = sname;
    4562             : 
    4563           8 :         status = smb2_create(tree, mem_ctx, &create);
    4564           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    4565             :                                            ret, done, "Got unexpected AFP_AfpResource stream");
    4566             : 
    4567           8 :         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
    4568           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4569             : 
    4570           8 :         torture_comment(tctx, "Trying to delete AFP_AfpResource via create with delete-on-close\n");
    4571             : 
    4572           8 :         ret = write_stream(tree, __location__, tctx, mem_ctx,
    4573             :                            fname, AFPRESOURCE_STREAM_NAME,
    4574             :                            0, 10, "1234567890");
    4575           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
    4576             : 
    4577           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
    4578             :                            0, 10, 0, 10, "1234567890");
    4579           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
    4580             : 
    4581           8 :         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
    4582           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4583             : 
    4584           8 :         ZERO_STRUCT(create);
    4585           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4586           8 :         create.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
    4587           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
    4588           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4589           8 :         create.in.fname = sname;
    4590           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4591             : 
    4592           8 :         status = smb2_create(tree, mem_ctx, &create);
    4593           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    4594             : 
    4595           8 :         h1 = create.out.file.handle;
    4596           8 :         smb2_util_close(tree, h1);
    4597             : 
    4598           8 :         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
    4599           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4600             : 
    4601           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM_NAME,
    4602             :                            0, 10, 0, 10, "1234567890");
    4603           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad content from AFP_AfpResource");
    4604             : 
    4605          16 : done:
    4606           8 :         smb2_util_unlink(tree, fname);
    4607           8 :         smb2_util_rmdir(tree, BASEDIR);
    4608           8 :         return ret;
    4609             : }
    4610             : 
    4611           8 : static bool test_setinfo_delete_on_close_resource(struct torture_context *tctx,
    4612             :                                                   struct smb2_tree *tree)
    4613             : {
    4614           8 :         bool ret = true;
    4615             :         NTSTATUS status;
    4616             :         struct smb2_create create;
    4617             :         union smb_setfileinfo sfinfo;
    4618             :         struct smb2_handle h1;
    4619           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4620           8 :         const char *fname = BASEDIR "\\file";
    4621           8 :         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
    4622           8 :         const char *streams_afpresource[] = {
    4623             :                 "::$DATA",
    4624             :                 AFPRESOURCE_STREAM
    4625             :         };
    4626             : 
    4627           8 :         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
    4628             : 
    4629           8 :         torture_comment(tctx, "Trying to delete AFP_AfpResource via setinfo with delete-on-close\n");
    4630             : 
    4631           8 :         smb2_deltree(tree, BASEDIR);
    4632           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h1);
    4633           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
    4634           8 :         smb2_util_close(tree, h1);
    4635           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    4636           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    4637             : 
    4638           8 :         ret = write_stream(tree, __location__, tctx, mem_ctx,
    4639             :                            fname, AFPRESOURCE_STREAM_NAME,
    4640             :                            10, 10, "1234567890");
    4641           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
    4642             : 
    4643           8 :         ZERO_STRUCT(create);
    4644           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4645           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_STD_SYNCHRONIZE | SEC_STD_DELETE;
    4646           8 :         create.in.fname = sname;
    4647           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4648           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4649             : 
    4650           8 :         status = smb2_create(tree, mem_ctx, &create);
    4651           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    4652             : 
    4653           8 :         h1 = create.out.file.handle;
    4654             : 
    4655             :         /* Try to delete stream via setinfo delete-on-close */
    4656           8 :         ZERO_STRUCT(sfinfo);
    4657           8 :         sfinfo.disposition_info.in.delete_on_close = 1;
    4658           8 :         sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
    4659           8 :         sfinfo.generic.in.file.handle = h1;
    4660           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    4661           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set delete-on-close failed");
    4662             : 
    4663           8 :         smb2_util_close(tree, h1);
    4664             : 
    4665           8 :         ret = check_stream_list(tree, tctx, fname, 2, streams_afpresource, false);
    4666           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4667             : 
    4668           8 :         ZERO_STRUCT(create);
    4669           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4670           8 :         create.in.desired_access = SEC_FILE_ALL;
    4671           8 :         create.in.fname = sname;
    4672           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4673           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4674           8 :         status = smb2_create(tree, mem_ctx, &create);
    4675           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    4676             :                                         "Got unexpected AFP_AfpResource stream");
    4677             : 
    4678           8 : done:
    4679           8 :         smb2_util_unlink(tree, fname);
    4680           8 :         smb2_util_rmdir(tree, BASEDIR);
    4681           8 :         return ret;
    4682             : }
    4683             : 
    4684           8 : static bool test_setinfo_eof_resource(struct torture_context *tctx,
    4685             :                                       struct smb2_tree *tree)
    4686             : {
    4687           8 :         bool ret = true;
    4688             :         NTSTATUS status;
    4689             :         struct smb2_create create;
    4690             :         union smb_setfileinfo sfinfo;
    4691             :         union smb_fileinfo finfo;
    4692             :         struct smb2_handle h1;
    4693           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4694           8 :         const char *fname = BASEDIR "\\file";
    4695           8 :         const char *sname = BASEDIR "\\file" AFPRESOURCE_STREAM_NAME;
    4696           8 :         const char *streams_basic[] = {
    4697             :                 "::$DATA"
    4698             :         };
    4699             : 
    4700           8 :         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new");
    4701             : 
    4702           8 :         ret = enable_aapl(tctx, tree);
    4703           8 :         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
    4704             : 
    4705           8 :         torture_comment(tctx, "Set AFP_AfpResource EOF to 1 and 0\n");
    4706             : 
    4707           8 :         smb2_deltree(tree, BASEDIR);
    4708           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h1);
    4709           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir");
    4710           8 :         smb2_util_close(tree, h1);
    4711           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    4712           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    4713             : 
    4714           8 :         ret = write_stream(tree, __location__, tctx, mem_ctx,
    4715             :                            fname, AFPRESOURCE_STREAM_NAME,
    4716             :                            10, 10, "1234567890");
    4717           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Writing to AFP_AfpResource failed");
    4718             : 
    4719           8 :         ZERO_STRUCT(create);
    4720           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4721           8 :         create.in.desired_access = SEC_FILE_ALL;
    4722           8 :         create.in.fname = sname;
    4723           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4724           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4725             : 
    4726           8 :         status = smb2_create(tree, mem_ctx, &create);
    4727           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    4728             : 
    4729           8 :         h1 = create.out.file.handle;
    4730             : 
    4731           8 :         torture_comment(tctx, "Set AFP_AfpResource EOF to 1\n");
    4732             : 
    4733             :         /* Test setinfo end-of-file info */
    4734           8 :         ZERO_STRUCT(sfinfo);
    4735           8 :         sfinfo.generic.in.file.handle = h1;
    4736           8 :         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    4737           8 :         sfinfo.position_information.in.position = 1;
    4738           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    4739           8 :         torture_assert_ntstatus_ok_goto(tctx, status,
    4740             :                                         ret, done, "set eof 1 failed");
    4741             : 
    4742           8 :         smb2_util_close(tree, h1);
    4743             : 
    4744             :         /* Check size == 1 */
    4745           8 :         ZERO_STRUCT(create);
    4746           8 :         create.in.fname = sname;
    4747           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4748           8 :         create.in.desired_access = SEC_FILE_ALL;
    4749           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4750           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4751           8 :         status = smb2_create(tree, mem_ctx, &create);
    4752           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    4753             : 
    4754           8 :         h1 = create.out.file.handle;
    4755             : 
    4756           8 :         ZERO_STRUCT(finfo);
    4757           8 :         finfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
    4758           8 :         finfo.generic.in.file.handle = h1;
    4759           8 :         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
    4760           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed");
    4761             : 
    4762           8 :         smb2_util_close(tree, h1);
    4763             : 
    4764           8 :         torture_assert_goto(tctx, finfo.all_info.out.size == 1, ret, done, "size != 1");
    4765             : 
    4766           8 :         ZERO_STRUCT(create);
    4767           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4768           8 :         create.in.desired_access = SEC_FILE_ALL;
    4769           8 :         create.in.fname = sname;
    4770           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4771           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4772             : 
    4773           8 :         status = smb2_create(tree, mem_ctx, &create);
    4774           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    4775             : 
    4776           8 :         h1 = create.out.file.handle;
    4777             : 
    4778             :         /*
    4779             :          * Delete stream via setinfo end-of-file info to 0, this
    4780             :          * should delete the stream.
    4781             :          */
    4782           8 :         ZERO_STRUCT(sfinfo);
    4783           8 :         sfinfo.generic.in.file.handle = h1;
    4784           8 :         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    4785           8 :         sfinfo.position_information.in.position = 0;
    4786           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    4787           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "set eof 0 failed");
    4788             : 
    4789           8 :         smb2_util_close(tree, h1);
    4790             : 
    4791           8 :         ret = check_stream_list(tree, tctx, fname, 1, streams_basic, false);
    4792           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    4793             : 
    4794           8 :         ZERO_STRUCT(create);
    4795           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4796           8 :         create.in.desired_access = SEC_FILE_ALL;
    4797           8 :         create.in.fname = sname;
    4798           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4799           8 :         create.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
    4800             : 
    4801           8 :         status = smb2_create(tree, mem_ctx, &create);
    4802           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    4803             :                                            ret, done, "smb2_create failed");
    4804             : 
    4805           8 : done:
    4806           8 :         smb2_util_unlink(tree, fname);
    4807           8 :         smb2_util_rmdir(tree, BASEDIR);
    4808           8 :         return ret;
    4809             : }
    4810             : 
    4811             : /*
    4812             :  * This tests that right after creating the AFP_AfpInfo stream,
    4813             :  * reading from the stream returns an empty, default metadata blob of
    4814             :  * 60 bytes.
    4815             :  *
    4816             :  * NOTE: against OS X SMB server this only works if the read request
    4817             :  * is compounded with the create that created the stream, is fails
    4818             :  * otherwise. We don't care...
    4819             :  */
    4820           8 : static bool test_null_afpinfo(struct torture_context *tctx,
    4821             :                               struct smb2_tree *tree)
    4822             : {
    4823           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    4824           8 :         const char *fname = "test_null_afpinfo";
    4825           8 :         const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
    4826             :         NTSTATUS status;
    4827           8 :         bool ret = true;
    4828             :         struct smb2_request *req[3];
    4829             :         struct smb2_handle handle;
    4830             :         struct smb2_create create;
    4831             :         struct smb2_read read;
    4832           8 :         AfpInfo *afpinfo = NULL;
    4833           8 :         char *afpinfo_buf = NULL;
    4834           8 :         const char *type_creator = "SMB,OLE!";
    4835             :         struct smb2_handle handle2;
    4836             :         struct smb2_read r;
    4837             : 
    4838           8 :         torture_comment(tctx, "Checking create of AfpInfo stream\n");
    4839             : 
    4840           8 :         smb2_util_unlink(tree, fname);
    4841             : 
    4842           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    4843           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
    4844             : 
    4845           8 :         ZERO_STRUCT(create);
    4846           8 :         create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
    4847           8 :         create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
    4848           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4849           8 :         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
    4850           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    4851           8 :         create.in.fname = sname;
    4852             : 
    4853           8 :         smb2_transport_compound_start(tree->session->transport, 2);
    4854             : 
    4855           8 :         req[0] = smb2_create_send(tree, &create);
    4856             : 
    4857           8 :         handle.data[0] = UINT64_MAX;
    4858           8 :         handle.data[1] = UINT64_MAX;
    4859             : 
    4860           8 :         smb2_transport_compound_set_related(tree->session->transport, true);
    4861             : 
    4862           8 :         ZERO_STRUCT(read);
    4863           8 :         read.in.file.handle = handle;
    4864           8 :         read.in.length = AFP_INFO_SIZE;
    4865           8 :         req[1] = smb2_read_send(tree, &read);
    4866             : 
    4867           8 :         status = smb2_create_recv(req[0], tree, &create);
    4868           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
    4869             : 
    4870           8 :         handle = create.out.file.handle;
    4871             : 
    4872           8 :         status = smb2_read_recv(req[1], tree, &read);
    4873           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
    4874             : 
    4875           8 :         status = torture_smb2_testfile_access(tree, sname, &handle2,
    4876             :                                               SEC_FILE_READ_DATA);
    4877           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    4878             :                                         "torture_smb2_testfile failed\n");
    4879           8 :         r = (struct smb2_read) {
    4880             :                 .in.file.handle = handle2,
    4881             :                 .in.length      = AFP_INFO_SIZE,
    4882             :         };
    4883             : 
    4884           8 :         status = smb2_read(tree, tree, &r);
    4885           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    4886             :                                         "torture_smb2_testfile failed\n");
    4887           8 :         smb2_util_close(tree, handle2);
    4888             : 
    4889           8 :         afpinfo = torture_afpinfo_new(mem_ctx);
    4890           8 :         torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
    4891             : 
    4892           8 :         memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
    4893             : 
    4894           8 :         afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
    4895           8 :         torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
    4896             : 
    4897           8 :         status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
    4898           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
    4899             : 
    4900           8 :         smb2_util_close(tree, handle);
    4901             : 
    4902           8 :         ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
    4903             :                            0, 60, 16, 8, type_creator);
    4904           8 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
    4905             : 
    4906          16 : done:
    4907           8 :         smb2_util_unlink(tree, fname);
    4908           8 :         talloc_free(mem_ctx);
    4909           8 :         return ret;
    4910             : }
    4911             : 
    4912           8 : static bool test_delete_file_with_rfork(struct torture_context *tctx,
    4913             :                                         struct smb2_tree *tree)
    4914             : {
    4915           8 :         const char *fname = "torture_write_rfork_io";
    4916           8 :         const char *rfork_content = "1234567890";
    4917             :         NTSTATUS status;
    4918           8 :         bool ret = true;
    4919             : 
    4920           8 :         smb2_util_unlink(tree, fname);
    4921             : 
    4922           8 :         torture_comment(tctx, "Test deleting file with resource fork\n");
    4923             : 
    4924           8 :         ret = torture_setup_file(tctx, tree, fname, false);
    4925           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
    4926             : 
    4927           8 :         ret = write_stream(tree, __location__, tctx, tctx,
    4928             :                            fname, AFPRESOURCE_STREAM_NAME,
    4929             :                            10, 10, rfork_content);
    4930           8 :         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
    4931             : 
    4932           8 :         ret = check_stream(tree, __location__, tctx, tctx,
    4933             :                            fname, AFPRESOURCE_STREAM_NAME,
    4934             :                            0, 20, 10, 10, rfork_content);
    4935           8 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
    4936             : 
    4937           8 :         status = smb2_util_unlink(tree, fname);
    4938           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
    4939             : 
    4940           8 : done:
    4941           8 :         return ret;
    4942             : }
    4943             : 
    4944           8 : static bool test_rename_and_read_rsrc(struct torture_context *tctx,
    4945             :                                       struct smb2_tree *tree)
    4946             : {
    4947           8 :         bool ret = true;
    4948             :         NTSTATUS status;
    4949             :         struct smb2_create create, create2;
    4950             :         struct smb2_handle h1, h2;
    4951           8 :         const char *fname = "test_rename_openfile";
    4952           8 :         const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
    4953           8 :         const char *fname_renamed = "test_rename_openfile_renamed";
    4954           8 :         const char *data = "1234567890";
    4955             :         union smb_setfileinfo sinfo;
    4956           8 :         bool server_is_macos = torture_setting_bool(tctx, "osx", false);
    4957             :         NTSTATUS expected_status;
    4958             : 
    4959           8 :         ret = enable_aapl(tctx, tree);
    4960           8 :         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
    4961             : 
    4962           8 :         torture_comment(tctx, "Create file with resource fork\n");
    4963             : 
    4964           8 :         ret = torture_setup_file(tctx, tree, fname, false);
    4965           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    4966             : 
    4967           8 :         ret = write_stream(tree, __location__, tctx, tctx,
    4968             :                            fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
    4969           8 :         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
    4970             : 
    4971           8 :         torture_comment(tctx, "Open resource fork\n");
    4972             : 
    4973           8 :         ZERO_STRUCT(create);
    4974           8 :         create.in.desired_access = SEC_FILE_ALL;
    4975           8 :         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    4976           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4977           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    4978           8 :         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
    4979           8 :         create.in.fname = sname;
    4980             : 
    4981           8 :         status = smb2_create(tree, tctx, &create);
    4982           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    4983             : 
    4984           8 :         h1 = create.out.file.handle;
    4985             : 
    4986           8 :         torture_comment(tctx, "Rename base file\n");
    4987             : 
    4988           8 :         ZERO_STRUCT(create2);
    4989           8 :         create2.in.desired_access = SEC_FILE_ALL;
    4990           8 :         create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    4991           8 :         create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    4992           8 :         create2.in.create_disposition = NTCREATEX_DISP_OPEN;
    4993           8 :         create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
    4994           8 :         create2.in.fname = fname;
    4995             : 
    4996           8 :         status = smb2_create(tree, tctx, &create2);
    4997           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    4998             : 
    4999           8 :         h2 = create2.out.file.handle;
    5000             : 
    5001           8 :         ZERO_STRUCT(sinfo);
    5002           8 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
    5003           8 :         sinfo.rename_information.in.file.handle = h2;
    5004           8 :         sinfo.rename_information.in.overwrite = 0;
    5005           8 :         sinfo.rename_information.in.root_fid = 0;
    5006           8 :         sinfo.rename_information.in.new_name = fname_renamed;
    5007             : 
    5008           8 :         if (server_is_macos) {
    5009           0 :                 expected_status = NT_STATUS_SHARING_VIOLATION;
    5010             :         } else {
    5011           8 :                 expected_status = NT_STATUS_ACCESS_DENIED;
    5012             :         }
    5013             : 
    5014           8 :         status = smb2_setinfo_file(tree, &sinfo);
    5015           8 :         torture_assert_ntstatus_equal_goto(
    5016             :                 tctx, status, expected_status, ret, done,
    5017             :                 "smb2_setinfo_file failed");
    5018             : 
    5019           8 :         smb2_util_close(tree, h2);
    5020             : 
    5021           8 :         status = smb2_util_write(tree, h1, "foo", 0, 3);
    5022           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    5023             :                                         "write failed\n");
    5024             : 
    5025           8 :         smb2_util_close(tree, h1);
    5026             : 
    5027           8 : done:
    5028           8 :         smb2_util_unlink(tree, fname);
    5029           8 :         smb2_util_unlink(tree, fname_renamed);
    5030             : 
    5031           8 :         return ret;
    5032             : }
    5033             : 
    5034           8 : static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
    5035             :                                            struct smb2_tree *tree)
    5036             : {
    5037           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    5038           8 :         const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
    5039           8 :         const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
    5040             :         NTSTATUS status;
    5041             :         struct smb2_handle testdirh;
    5042           8 :         bool ret = true;
    5043             :         struct smb2_create io;
    5044             :         AfpInfo *info;
    5045           8 :         const char *type_creator = "SMB,OLE!";
    5046             :         struct smb2_find f;
    5047             :         unsigned int count;
    5048             :         union smb_search_data *d;
    5049             :         uint64_t rfork_len;
    5050             :         unsigned int i;
    5051             : 
    5052           8 :         smb2_deltree(tree, BASEDIR);
    5053             : 
    5054           8 :         status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
    5055           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
    5056           8 :         smb2_util_close(tree, testdirh);
    5057             : 
    5058           8 :         torture_comment(tctx, "Enabling AAPL\n");
    5059             : 
    5060           8 :         ret = enable_aapl(tctx, tree);
    5061           8 :         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
    5062             : 
    5063             :         /*
    5064             :          * Now that Requested AAPL extensions are enabled, setup some
    5065             :          * Mac files with metadata and resource fork
    5066             :          */
    5067             : 
    5068           8 :         torture_comment(tctx, "Preparing file\n");
    5069             : 
    5070           8 :         ret = torture_setup_file(mem_ctx, tree, fname, false);
    5071           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
    5072             : 
    5073           8 :         info = torture_afpinfo_new(mem_ctx);
    5074           8 :         torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
    5075             : 
    5076           8 :         memcpy(info->afpi_FinderInfo, type_creator, 8);
    5077           8 :         ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
    5078           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
    5079             : 
    5080           8 :         ret = write_stream(tree, __location__, tctx, mem_ctx,
    5081             :                            fname, AFPRESOURCE_STREAM_NAME,
    5082             :                            0, 3, "foo");
    5083           8 :         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
    5084             : 
    5085             :         /*
    5086             :          * Ok, file is prepared, now call smb2/find
    5087             :          */
    5088             : 
    5089           8 :         torture_comment(tctx, "Issue find\n");
    5090             : 
    5091           8 :         ZERO_STRUCT(io);
    5092           8 :         io.in.desired_access = SEC_RIGHTS_DIR_READ;
    5093           8 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    5094           8 :         io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    5095           8 :         io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
    5096             :                               NTCREATEX_SHARE_ACCESS_WRITE |
    5097             :                               NTCREATEX_SHARE_ACCESS_DELETE);
    5098           8 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    5099           8 :         io.in.fname = BASEDIR;
    5100           8 :         status = smb2_create(tree, tctx, &io);
    5101           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
    5102             : 
    5103           8 :         ZERO_STRUCT(f);
    5104           8 :         f.in.file.handle        = io.out.file.handle;
    5105           8 :         f.in.pattern            = "*";
    5106           8 :         f.in.max_response_size  = 0x1000;
    5107           8 :         f.in.level              = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
    5108             : 
    5109           8 :         status = smb2_find_level(tree, tree, &f, &count, &d);
    5110           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
    5111             : 
    5112           8 :         status = smb2_util_close(tree, io.out.file.handle);
    5113           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
    5114             : 
    5115           8 :         torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
    5116             : 
    5117          24 :         for (i = 0; i < count; i++) {
    5118          24 :                 const char *found = d[i].id_both_directory_info.name.s;
    5119             : 
    5120          24 :                 if (!strcmp(found, ".") || !strcmp(found, ".."))
    5121          16 :                         continue;
    5122           8 :                 if (strncmp(found, "._", 2) == 0) {
    5123           0 :                         continue;
    5124             :                 }
    5125           8 :                 break;
    5126             :         }
    5127             : 
    5128           8 :         torture_assert_str_equal_goto(tctx,
    5129             :                                       d[i].id_both_directory_info.name.s, name,
    5130             :                                       ret, done, "bad name");
    5131             : 
    5132           8 :         rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
    5133           8 :         torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
    5134             : 
    5135           8 :         torture_assert_mem_equal_goto(tctx, type_creator,
    5136             :                                       d[i].id_both_directory_info.short_name_buf + 8,
    5137             :                                       8, ret, done, "Bad FinderInfo");
    5138          16 : done:
    5139           8 :         smb2_util_unlink(tree, fname);
    5140           8 :         smb2_deltree(tree, BASEDIR);
    5141           8 :         talloc_free(mem_ctx);
    5142           8 :         return ret;
    5143             : }
    5144             : 
    5145           8 : static bool test_invalid_afpinfo(struct torture_context *tctx,
    5146             :                                  struct smb2_tree *tree1,
    5147             :                                  struct smb2_tree *tree2)
    5148             : {
    5149           8 :         const char *fname = "filtest_invalid_afpinfo";
    5150           8 :         const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
    5151             :         struct smb2_create create;
    5152           8 :         const char *streams_basic[] = {
    5153             :                 "::$DATA"
    5154             :         };
    5155           8 :         const char *streams_afpinfo[] = {
    5156             :                 "::$DATA",
    5157             :                 AFPINFO_STREAM
    5158             :         };
    5159             :         NTSTATUS status;
    5160           8 :         bool ret = true;
    5161             : 
    5162           8 :         if (tree2 == NULL) {
    5163           0 :                 torture_skip_goto(tctx, done, "need second share without fruit\n");
    5164             :         }
    5165             : 
    5166           8 :         torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
    5167             : 
    5168           8 :         ret = torture_setup_file(tctx, tree2, fname, false);
    5169           8 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    5170             : 
    5171           8 :         ret = write_stream(tree2, __location__, tctx, tctx,
    5172             :                            fname, AFPINFO_STREAM_NAME,
    5173             :                            0, 3, "foo");
    5174           8 :         torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
    5175             : 
    5176           8 :         ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
    5177           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    5178             : 
    5179           8 :         torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
    5180             : 
    5181           8 :         ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
    5182           8 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    5183             : 
    5184           8 :         torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
    5185             : 
    5186           8 :         ZERO_STRUCT(create);
    5187           8 :         create.in.desired_access = SEC_FILE_ALL;
    5188           8 :         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    5189           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    5190           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    5191           8 :         create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
    5192           8 :         create.in.fname = sname;
    5193             : 
    5194           8 :         status = smb2_create(tree1, tctx, &create);
    5195           8 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    5196             :                                            ret, done, "Stream still around?");
    5197             : 
    5198           8 : done:
    5199           8 :         smb2_util_unlink(tree1, fname);
    5200           8 :         return ret;
    5201             : }
    5202             : 
    5203           8 : static bool test_writing_afpinfo(struct torture_context *tctx,
    5204             :                                  struct smb2_tree *tree)
    5205             : {
    5206           8 :         const char *fname = "filtest_invalid_afpinfo";
    5207           8 :         const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM;
    5208           8 :         const char *streams_afpinfo[] = {
    5209             :                 "::$DATA",
    5210             :                 AFPINFO_STREAM
    5211             :         };
    5212           8 :         bool ret = true;
    5213             :         static AfpInfo *afpi = NULL;
    5214           8 :         char *buf = NULL;
    5215           8 :         char *afpi_buf = NULL;
    5216           8 :         char *zero_buf = NULL;
    5217           8 :         bool broken_osx = torture_setting_bool(tctx, "broken_osx_45759458", false);
    5218           8 :         off_t min_offset_for_2streams = 16;
    5219             :         int i;
    5220             :         NTSTATUS status;
    5221             :         struct test_sizes {
    5222             :                 off_t offset;
    5223             :                 size_t size;
    5224             :                 bool expected_result;
    5225           8 :         } test_sizes[] = {
    5226             :                 { 0, 1, false},
    5227             :                 { 0, 2, false},
    5228             :                 { 0, 3, true},
    5229             :                 { 0, 4, true},
    5230             :                 { 0, 14, true},
    5231             :                 { 0, 15, true},
    5232             :                 { 0, 16, true},
    5233             :                 { 0, 24, true},
    5234             :                 { 0, 34, true},
    5235             :                 { 0, 44, true},
    5236             :                 { 0, 54, true},
    5237             :                 { 0, 55, true},
    5238             :                 { 0, 56, true},
    5239             :                 { 0, 57, true},
    5240             :                 { 0, 58, true},
    5241             :                 { 0, 59, true},
    5242             :                 { 0, 60, true},
    5243             :                 { 0, 61, true},
    5244             :                 { 0, 64, true},
    5245             :                 { 0, 1024, true},
    5246             :                 { 0, 10064, true},
    5247             : 
    5248             :                 { 1, 1, false},
    5249             :                 { 1, 2, false},
    5250             :                 { 1, 3, false},
    5251             :                 { 1, 4, false},
    5252             :                 { 1, 14, false},
    5253             :                 { 1, 15, false},
    5254             :                 { 1, 16, false},
    5255             :                 { 1, 24, false},
    5256             :                 { 1, 34, false},
    5257             :                 { 1, 44, false},
    5258             :                 { 1, 54, false},
    5259             :                 { 1, 55, false},
    5260             :                 { 1, 56, false},
    5261             :                 { 1, 57, false},
    5262             :                 { 1, 58, false},
    5263             :                 { 1, 59, false},
    5264             :                 { 1, 60, true},
    5265             :                 { 1, 61, true},
    5266             :                 { 1, 1024, true},
    5267             :                 { 1, 10064, true},
    5268             : 
    5269             :                 { 30, 1, false},
    5270             :                 { 30, 2, false},
    5271             :                 { 30, 3, false},
    5272             :                 { 30, 4, false},
    5273             :                 { 30, 14, false},
    5274             :                 { 30, 15, false},
    5275             :                 { 30, 16, false},
    5276             :                 { 30, 24, false},
    5277             :                 { 30, 34, false},
    5278             :                 { 30, 44, false},
    5279             :                 { 30, 54, false},
    5280             :                 { 30, 55, false},
    5281             :                 { 30, 56, false},
    5282             :                 { 30, 57, false},
    5283             :                 { 30, 58, false},
    5284             :                 { 30, 59, false},
    5285             :                 { 30, 60, true},
    5286             :                 { 30, 61, true},
    5287             :                 { 30, 1024, true},
    5288             :                 { 30, 10064, true},
    5289             : 
    5290             :                 { 58, 1, false},
    5291             :                 { 58, 2, false},
    5292             :                 { 58, 3, false},
    5293             :                 { 58, 4, false},
    5294             :                 { 58, 14, false},
    5295             :                 { 58, 15, false},
    5296             :                 { 58, 16, false},
    5297             :                 { 58, 24, false},
    5298             :                 { 58, 34, false},
    5299             :                 { 58, 44, false},
    5300             :                 { 58, 54, false},
    5301             :                 { 58, 55, false},
    5302             :                 { 58, 56, false},
    5303             :                 { 58, 57, false},
    5304             :                 { 58, 58, false},
    5305             :                 { 58, 59, false},
    5306             :                 { 58, 60, true},
    5307             :                 { 58, 61, true},
    5308             :                 { 58, 1024, true},
    5309             :                 { 58, 10064, true},
    5310             : 
    5311             :                 { 59, 1, false},
    5312             :                 { 59, 2, false},
    5313             :                 { 59, 3, false},
    5314             :                 { 59, 4, false},
    5315             :                 { 59, 14, false},
    5316             :                 { 59, 15, false},
    5317             :                 { 59, 16, false},
    5318             :                 { 59, 24, false},
    5319             :                 { 59, 34, false},
    5320             :                 { 59, 44, false},
    5321             :                 { 59, 54, false},
    5322             :                 { 59, 55, false},
    5323             :                 { 59, 56, false},
    5324             :                 { 59, 57, false},
    5325             :                 { 59, 58, false},
    5326             :                 { 59, 59, false},
    5327             :                 { 59, 60, true},
    5328             :                 { 59, 61, true},
    5329             :                 { 59, 1024, true},
    5330             :                 { 59, 10064, true},
    5331             : 
    5332             :                 { 60, 1, false},
    5333             :                 { 60, 2, false},
    5334             :                 { 60, 3, false},
    5335             :                 { 60, 4, false},
    5336             :                 { 60, 14, false},
    5337             :                 { 60, 15, false},
    5338             :                 { 60, 16, false},
    5339             :                 { 60, 24, false},
    5340             :                 { 60, 34, false},
    5341             :                 { 60, 44, false},
    5342             :                 { 60, 54, false},
    5343             :                 { 60, 55, false},
    5344             :                 { 60, 56, false},
    5345             :                 { 60, 57, false},
    5346             :                 { 60, 58, false},
    5347             :                 { 60, 59, false},
    5348             :                 { 60, 60, true},
    5349             :                 { 60, 61, true},
    5350             :                 { 60, 1024, true},
    5351             :                 { 60, 10064, true},
    5352             : 
    5353             :                 { 61, 1, false},
    5354             :                 { 61, 2, false},
    5355             :                 { 61, 3, false},
    5356             :                 { 61, 4, false},
    5357             :                 { 61, 14, false},
    5358             :                 { 61, 15, false},
    5359             :                 { 61, 16, false},
    5360             :                 { 61, 24, false},
    5361             :                 { 61, 34, false},
    5362             :                 { 61, 44, false},
    5363             :                 { 61, 54, false},
    5364             :                 { 61, 55, false},
    5365             :                 { 61, 56, false},
    5366             :                 { 61, 57, false},
    5367             :                 { 61, 58, false},
    5368             :                 { 61, 59, false},
    5369             :                 { 61, 60, true},
    5370             :                 { 61, 61, true},
    5371             :                 { 61, 1024, true},
    5372             :                 { 61, 10064, true},
    5373             : 
    5374             :                 { 10000, 1, false},
    5375             :                 { 10000, 2, false},
    5376             :                 { 10000, 3, false},
    5377             :                 { 10000, 4, false},
    5378             :                 { 10000, 14, false},
    5379             :                 { 10000, 15, false},
    5380             :                 { 10000, 16, false},
    5381             :                 { 10000, 24, false},
    5382             :                 { 10000, 34, false},
    5383             :                 { 10000, 44, false},
    5384             :                 { 10000, 54, false},
    5385             :                 { 10000, 55, false},
    5386             :                 { 10000, 56, false},
    5387             :                 { 10000, 57, false},
    5388             :                 { 10000, 58, false},
    5389             :                 { 10000, 59, false},
    5390             :                 { 10000, 60, true},
    5391             :                 { 10000, 61, true},
    5392             :                 { 10000, 1024, true},
    5393             :                 { 10000, 10064, true},
    5394             : 
    5395             :                 { -1, 0, false},
    5396             :         };
    5397             : 
    5398           8 :         afpi = torture_afpinfo_new(tctx);
    5399           8 :         torture_assert_not_null_goto(tctx, afpi, ret, done,
    5400             :                                      "torture_afpinfo_new failed\n");
    5401             : 
    5402           8 :         memcpy(afpi->afpi_FinderInfo, "FOO BAR ", 8);
    5403             : 
    5404           8 :         buf = torture_afpinfo_pack(afpi, afpi);
    5405           8 :         torture_assert_not_null_goto(tctx, buf, ret, done,
    5406             :                                      "torture_afpinfo_pack failed\n");
    5407             : 
    5408           8 :         afpi_buf = talloc_zero_array(tctx, char, 10064);
    5409           8 :         torture_assert_not_null_goto(tctx, afpi_buf, ret, done,
    5410             :                                      "talloc_zero_array failed\n");
    5411           8 :         memcpy(afpi_buf, buf, 60);
    5412             : 
    5413           8 :         zero_buf = talloc_zero_array(tctx, char, 10064);
    5414           8 :         torture_assert_not_null_goto(tctx, zero_buf, ret, done,
    5415             :                                      "talloc_zero_array failed\n");
    5416             : 
    5417           8 :         ret = torture_setup_file(tctx, tree, fname, false);
    5418           8 :         torture_assert_goto(tctx, ret == true, ret, done,
    5419             :                             "torture_setup_file\n");
    5420             : 
    5421        1296 :         for (i = 0; test_sizes[i].offset != -1; i++) {
    5422             :                 struct smb2_handle h;
    5423             :                 struct smb2_create c;
    5424             :                 int expected_num_streams;
    5425             :                 size_t fi_check_size;
    5426             : 
    5427        2576 :                 torture_comment(tctx,
    5428             :                                 "Test %d: offset=%jd size=%zu result=%s\n",
    5429             :                                 i,
    5430        1288 :                                 (intmax_t)test_sizes[i].offset,
    5431             :                                 test_sizes[i].size,
    5432        1288 :                                 test_sizes[i].expected_result ? "true":"false");
    5433             : 
    5434             : 
    5435        1288 :                 c = (struct smb2_create) {
    5436             :                         .in.desired_access = SEC_FILE_WRITE_DATA,
    5437             :                         .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    5438             :                         .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    5439             :                         .in.fname = sname,
    5440             :                 };
    5441             : 
    5442        1288 :                 status = smb2_create(tree, tree, &c);
    5443        1288 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    5444             :                                                 "smb2_create\n");
    5445        1288 :                 h = c.out.file.handle;
    5446             : 
    5447        1288 :                 status = smb2_util_write(tree,
    5448             :                                          h,
    5449             :                                          zero_buf,
    5450             :                                          test_sizes[i].offset,
    5451             :                                          test_sizes[i].size);
    5452        1288 :                 torture_assert_ntstatus_equal_goto(
    5453             :                         tctx, status, NT_STATUS_INVALID_PARAMETER,
    5454             :                         ret, done, "smb2_util_write\n");
    5455             : 
    5456        1288 :                 status = smb2_util_write(tree,
    5457             :                                          h,
    5458             :                                          afpi_buf,
    5459             :                                          test_sizes[i].offset,
    5460             :                                          test_sizes[i].size);
    5461        1288 :                 smb2_util_close(tree, h);
    5462        1288 :                 if (test_sizes[i].expected_result == true) {
    5463         376 :                         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    5464             :                                                         "smb2_util_write\n");
    5465             :                 } else {
    5466         912 :                         torture_assert_ntstatus_equal_goto(
    5467             :                                 tctx, status, NT_STATUS_INVALID_PARAMETER,
    5468             :                                 ret, done, "smb2_util_write\n");
    5469             :                 }
    5470             : 
    5471        1288 :                 if (broken_osx) {
    5472             :                         /*
    5473             :                          * Currently macOS has a bug (Radar #45759458) where it
    5474             :                          * writes more bytes then requested from uninitialized
    5475             :                          * memory to the filesystem. That means it will likely
    5476             :                          * write data to FinderInfo so the stream is not empty
    5477             :                          * and thus listed when the number of streams is
    5478             :                          * queried.
    5479             :                          */
    5480           0 :                         min_offset_for_2streams = 2;
    5481             :                 }
    5482             : 
    5483        1664 :                 if ((test_sizes[i].expected_result == true) &&
    5484         376 :                     (test_sizes[i].size > min_offset_for_2streams))
    5485             :                 {
    5486         336 :                         expected_num_streams = 2;
    5487             :                 } else {
    5488         952 :                         expected_num_streams = 1;
    5489             :                 }
    5490             : 
    5491        1288 :                 ret = check_stream_list(tree, tctx, fname,
    5492             :                                         expected_num_streams,
    5493             :                                         streams_afpinfo, false);
    5494        1288 :                 torture_assert_goto(tctx, ret == true, ret, done,
    5495             :                                     "Bad streams\n");
    5496             : 
    5497        1288 :                 if (test_sizes[i].expected_result == false) {
    5498         912 :                         continue;
    5499             :                 }
    5500             : 
    5501         376 :                 if (test_sizes[i].size <= 16) {
    5502             :                         /*
    5503             :                          * FinderInfo with the "FOO BAR " string we wrote above
    5504             :                          * would start at offset 16. Check whether this test
    5505             :                          * wrote 1 byte or more.
    5506             :                          */
    5507          40 :                         goto next;
    5508             :                 }
    5509             : 
    5510         336 :                 fi_check_size = test_sizes[i].size - 16;
    5511         336 :                 fi_check_size = MIN(fi_check_size, 8);
    5512             : 
    5513         336 :                 ret = check_stream(tree, __location__,
    5514             :                                    tctx, tctx,
    5515             :                                    fname, AFPINFO_STREAM,
    5516             :                                    0, 60, 16, fi_check_size, "FOO BAR ");
    5517         336 :                 torture_assert_goto(tctx, ret == true, ret, done,
    5518             :                                     "Bad streams\n");
    5519             : 
    5520         336 : next:
    5521         376 :                 status = smb2_util_unlink(tree, sname);
    5522         376 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    5523             :                         bool missing_ok;
    5524             : 
    5525          40 :                         missing_ok = test_sizes[i].expected_result == false;
    5526          40 :                         missing_ok |= test_sizes[i].size <= 16;
    5527             : 
    5528          40 :                         torture_assert_goto(tctx, missing_ok,
    5529             :                                             ret, done, "smb2_util_unlink\n");
    5530             :                 }
    5531             :         }
    5532             : 
    5533           8 : done:
    5534           8 :         smb2_util_unlink(tree, fname);
    5535           8 :         return ret;
    5536             : }
    5537             : 
    5538           2 : static bool test_zero_file_id(struct torture_context *tctx,
    5539             :                               struct smb2_tree *tree)
    5540             : {
    5541           2 :         const char *fname = "filtest_file_id";
    5542           2 :         struct smb2_create create = {0};
    5543             :         NTSTATUS status;
    5544           2 :         bool ret = true;
    5545           2 :         uint8_t zero_file_id[8] = {0};
    5546             : 
    5547           2 :         torture_comment(tctx, "Testing zero file id\n");
    5548             : 
    5549           2 :         ret = torture_setup_file(tctx, tree, fname, false);
    5550           2 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    5551             : 
    5552           2 :         ZERO_STRUCT(create);
    5553           2 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
    5554           2 :         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    5555           2 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    5556           2 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    5557           2 :         create.in.fname = fname;
    5558           2 :         create.in.query_on_disk_id = true;
    5559             : 
    5560           2 :         status = smb2_create(tree, tctx, &create);
    5561           2 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
    5562             :                                            done,
    5563             :                                            "test file could not be opened");
    5564           2 :         torture_assert_mem_not_equal_goto(tctx, create.out.on_disk_id,
    5565             :                                           zero_file_id, 8, ret, done,
    5566             :                                           "unexpected zero file id");
    5567             : 
    5568           2 :         smb2_util_close(tree, create.out.file.handle);
    5569             : 
    5570           2 :         ret = enable_aapl(tctx, tree);
    5571           2 :         torture_assert(tctx, ret == true, "enable_aapl failed");
    5572             : 
    5573           2 :         ZERO_STRUCT(create);
    5574           2 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
    5575           2 :         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    5576           2 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    5577           2 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    5578           2 :         create.in.fname = fname;
    5579           2 :         create.in.query_on_disk_id = true;
    5580             : 
    5581           2 :         status = smb2_create(tree, tctx, &create);
    5582           2 :         torture_assert_ntstatus_equal_goto(
    5583             :             tctx, status, NT_STATUS_OK, ret, done,
    5584             :             "test file could not be opened with AAPL");
    5585           2 :         torture_assert_mem_equal_goto(tctx, create.out.on_disk_id, zero_file_id,
    5586             :                                       8, ret, done, "non-zero file id");
    5587             : 
    5588           2 :         smb2_util_close(tree, create.out.file.handle);
    5589             : 
    5590           2 : done:
    5591           2 :         smb2_util_unlink(tree, fname);
    5592           2 :         return ret;
    5593             : }
    5594             : 
    5595          16 : static bool copy_one_stream(struct torture_context *torture,
    5596             :                             struct smb2_tree *tree,
    5597             :                             TALLOC_CTX *tmp_ctx,
    5598             :                             const char *src_sname,
    5599             :                             const char *dst_sname)
    5600             : {
    5601          16 :         struct smb2_handle src_h = {{0}};
    5602          16 :         struct smb2_handle dest_h = {{0}};
    5603             :         NTSTATUS status;
    5604             :         union smb_ioctl io;
    5605             :         struct srv_copychunk_copy cc_copy;
    5606             :         struct srv_copychunk_rsp cc_rsp;
    5607             :         enum ndr_err_code ndr_ret;
    5608          16 :         bool ok = false;
    5609             : 
    5610          16 :         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
    5611             :                                    1, /* 1 chunk */
    5612             :                                    src_sname,
    5613             :                                    &src_h, 256, /* fill 256 byte src file */
    5614             :                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
    5615             :                                    dst_sname,
    5616             :                                    &dest_h, 0,      /* 0 byte dest file */
    5617             :                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
    5618             :                                    &cc_copy,
    5619             :                                    &io);
    5620          16 :         torture_assert_goto(torture, ok == true, ok, done,
    5621             :                             "setup copy chunk error\n");
    5622             : 
    5623             :         /* copy all src file data (via a single chunk desc) */
    5624          16 :         cc_copy.chunks[0].source_off = 0;
    5625          16 :         cc_copy.chunks[0].target_off = 0;
    5626          16 :         cc_copy.chunks[0].length = 256;
    5627             : 
    5628          16 :         ndr_ret = ndr_push_struct_blob(
    5629             :                 &io.smb2.in.out, tmp_ctx, &cc_copy,
    5630             :                 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
    5631             : 
    5632          16 :         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
    5633             :                                    "ndr_push_srv_copychunk_copy\n");
    5634             : 
    5635          16 :         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
    5636          16 :         torture_assert_ntstatus_ok_goto(torture, status, ok, done,
    5637             :                                         "FSCTL_SRV_COPYCHUNK\n");
    5638             : 
    5639          16 :         ndr_ret = ndr_pull_struct_blob(
    5640             :                 &io.smb2.out.out, tmp_ctx, &cc_rsp,
    5641             :                 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
    5642             : 
    5643          16 :         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
    5644             :                                    "ndr_pull_srv_copychunk_rsp\n");
    5645             : 
    5646          16 :         ok = check_copy_chunk_rsp(torture, &cc_rsp,
    5647             :                                   1,    /* chunks written */
    5648             :                                   0,    /* chunk bytes unsuccessfully written */
    5649             :                                   256); /* total bytes written */
    5650          16 :         torture_assert_goto(torture, ok == true, ok, done,
    5651             :                             "bad copy chunk response data\n");
    5652             : 
    5653          16 :         ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
    5654          16 :         if (!ok) {
    5655           0 :                 torture_fail(torture, "inconsistent file data\n");
    5656             :         }
    5657             : 
    5658          16 : done:
    5659          16 :         if (!smb2_util_handle_empty(src_h)) {
    5660          16 :                 smb2_util_close(tree, src_h);
    5661             :         }
    5662          16 :         if (!smb2_util_handle_empty(dest_h)) {
    5663          16 :                 smb2_util_close(tree, dest_h);
    5664             :         }
    5665             : 
    5666          16 :         return ok;
    5667             : }
    5668             : 
    5669           8 : static bool copy_finderinfo_stream(struct torture_context *torture,
    5670             :                                    struct smb2_tree *tree,
    5671             :                                    TALLOC_CTX *tmp_ctx,
    5672             :                                    const char *src_name,
    5673             :                                    const char *dst_name)
    5674             : {
    5675           8 :         struct smb2_handle src_h = {{0}};
    5676           8 :         struct smb2_handle dest_h = {{0}};
    5677             :         NTSTATUS status;
    5678             :         union smb_ioctl io;
    5679             :         struct srv_copychunk_copy cc_copy;
    5680             :         struct srv_copychunk_rsp cc_rsp;
    5681             :         enum ndr_err_code ndr_ret;
    5682           8 :         const char *type_creator = "SMB,OLE!";
    5683           8 :         AfpInfo *info = NULL;
    5684           8 :         const char *src_name_afpinfo = NULL;
    5685           8 :         const char *dst_name_afpinfo = NULL;
    5686           8 :         bool ok = false;
    5687             : 
    5688           8 :         src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
    5689             :                                            AFPINFO_STREAM);
    5690           8 :         torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
    5691             :                                      "talloc_asprintf failed\n");
    5692             : 
    5693           8 :         dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
    5694             :                                            AFPINFO_STREAM);
    5695           8 :         torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
    5696             :                                      "talloc_asprintf failed\n");
    5697             : 
    5698           8 :         info = torture_afpinfo_new(tmp_ctx);
    5699           8 :         torture_assert_not_null_goto(torture, info, ok, done,
    5700             :                                      "torture_afpinfo_new failed\n");
    5701             : 
    5702           8 :         memcpy(info->afpi_FinderInfo, type_creator, 8);
    5703           8 :         ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
    5704           8 :         torture_assert_goto(torture, ok == true, ok, done,
    5705             :                             "torture_write_afpinfo failed\n");
    5706             : 
    5707           8 :         ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
    5708             :                                    1, /* 1 chunk */
    5709             :                                    src_name_afpinfo,
    5710             :                                    &src_h, 0,
    5711             :                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
    5712             :                                    dst_name_afpinfo,
    5713             :                                    &dest_h, 0,
    5714             :                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
    5715             :                                    &cc_copy,
    5716             :                                    &io);
    5717           8 :         torture_assert_goto(torture, ok == true, ok, done,
    5718             :                             "setup copy chunk error\n");
    5719             : 
    5720             :         /* copy all src file data (via a single chunk desc) */
    5721           8 :         cc_copy.chunks[0].source_off = 0;
    5722           8 :         cc_copy.chunks[0].target_off = 0;
    5723           8 :         cc_copy.chunks[0].length = 60;
    5724             : 
    5725           8 :         ndr_ret = ndr_push_struct_blob(
    5726             :                 &io.smb2.in.out, tmp_ctx, &cc_copy,
    5727             :                 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
    5728             : 
    5729           8 :         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
    5730             :                                    "ndr_push_srv_copychunk_copy\n");
    5731             : 
    5732           8 :         status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
    5733           8 :         torture_assert_ntstatus_ok_goto(torture, status, ok, done,
    5734             :                                         "FSCTL_SRV_COPYCHUNK\n");
    5735             : 
    5736           8 :         ndr_ret = ndr_pull_struct_blob(
    5737             :                 &io.smb2.out.out, tmp_ctx, &cc_rsp,
    5738             :                 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
    5739             : 
    5740           8 :         torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
    5741             :                                    "ndr_pull_srv_copychunk_rsp\n");
    5742             : 
    5743           8 :         smb2_util_close(tree, src_h);
    5744           8 :         ZERO_STRUCT(src_h);
    5745           8 :         smb2_util_close(tree, dest_h);
    5746           8 :         ZERO_STRUCT(dest_h);
    5747             : 
    5748           8 :         ok = check_copy_chunk_rsp(torture, &cc_rsp,
    5749             :                                   1,    /* chunks written */
    5750             :                                   0,    /* chunk bytes unsuccessfully written */
    5751             :                                   60); /* total bytes written */
    5752           8 :         torture_assert_goto(torture, ok == true, ok, done,
    5753             :                             "bad copy chunk response data\n");
    5754             : 
    5755           8 :         ok = check_stream(tree, __location__, torture, tmp_ctx,
    5756             :                           dst_name, AFPINFO_STREAM,
    5757             :                           0, 60, 16, 8, type_creator);
    5758           8 :         torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
    5759             : 
    5760          16 : done:
    5761           8 :         if (!smb2_util_handle_empty(src_h)) {
    5762           0 :                 smb2_util_close(tree, src_h);
    5763             :         }
    5764           8 :         if (!smb2_util_handle_empty(dest_h)) {
    5765           0 :                 smb2_util_close(tree, dest_h);
    5766             :         }
    5767             : 
    5768           8 :         return ok;
    5769             : }
    5770             : 
    5771           8 : static bool test_copy_chunk_streams(struct torture_context *torture,
    5772             :                                     struct smb2_tree *tree)
    5773             : {
    5774           8 :         const char *src_name = "src";
    5775           8 :         const char *dst_name = "dst";
    5776             :         struct names {
    5777             :                 const char *src_sname;
    5778             :                 const char *dst_sname;
    5779           8 :         } names[] = {
    5780             :                 { "src:foo", "dst:foo" },
    5781             :                 { "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
    5782             :         };
    5783             :         size_t i;
    5784           8 :         TALLOC_CTX *tmp_ctx = NULL;
    5785           8 :         bool ok = false;
    5786             : 
    5787           8 :         tmp_ctx = talloc_new(tree);
    5788           8 :         torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
    5789             :                                      "torture_setup_file\n");
    5790             : 
    5791           8 :         smb2_util_unlink(tree, src_name);
    5792           8 :         smb2_util_unlink(tree, dst_name);
    5793             : 
    5794           8 :         ok = torture_setup_file(torture, tree, src_name, false);
    5795           8 :         torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
    5796           8 :         ok = torture_setup_file(torture, tree, dst_name, false);
    5797           8 :         torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
    5798             : 
    5799          24 :         for (i = 0; i < ARRAY_SIZE(names); i++) {
    5800          16 :                 ok = copy_one_stream(torture, tree, tmp_ctx,
    5801             :                                      names[i].src_sname,
    5802             :                                      names[i].dst_sname);
    5803          16 :                 torture_assert_goto(torture, ok == true, ok, done,
    5804             :                                     "copy_one_stream failed\n");
    5805             :         }
    5806             : 
    5807           8 :         ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
    5808             :                                     src_name, dst_name);
    5809           8 :         torture_assert_goto(torture, ok == true, ok, done,
    5810             :                             "copy_finderinfo_stream failed\n");
    5811             : 
    5812          16 : done:
    5813           8 :         smb2_util_unlink(tree, src_name);
    5814           8 :         smb2_util_unlink(tree, dst_name);
    5815           8 :         talloc_free(tmp_ctx);
    5816           8 :         return ok;
    5817             : }
    5818             : 
    5819             : /*
    5820             :  * Ensure this security descriptor has exactly one mode, uid
    5821             :  * and gid.
    5822             :  */
    5823             : 
    5824          16 : static NTSTATUS check_nfs_sd(const struct security_descriptor *psd)
    5825             : {
    5826             :         uint32_t i;
    5827          16 :         bool got_one_mode = false;
    5828          16 :         bool got_one_uid = false;
    5829          16 :         bool got_one_gid = false;
    5830             : 
    5831          16 :         if (psd->dacl == NULL) {
    5832           0 :                 return NT_STATUS_INVALID_SECURITY_DESCR;
    5833             :         }
    5834             : 
    5835         112 :         for (i = 0; i < psd->dacl->num_aces; i++) {
    5836          96 :                 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Mode,
    5837          96 :                                            &psd->dacl->aces[i].trustee) == 0) {
    5838          16 :                         if (got_one_mode == true) {
    5839             :                                 /* Can't have more than one. */
    5840           0 :                                 return NT_STATUS_INVALID_SECURITY_DESCR;
    5841             :                         }
    5842          16 :                         got_one_mode = true;
    5843             :                 }
    5844             :         }
    5845         112 :         for (i = 0; i < psd->dacl->num_aces; i++) {
    5846          96 :                 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Users,
    5847          96 :                                            &psd->dacl->aces[i].trustee) == 0) {
    5848          16 :                         if (got_one_uid == true) {
    5849             :                                 /* Can't have more than one. */
    5850           0 :                                 return NT_STATUS_INVALID_SECURITY_DESCR;
    5851             :                         }
    5852          16 :                         got_one_uid = true;
    5853             :                 }
    5854             :         }
    5855         112 :         for (i = 0; i < psd->dacl->num_aces; i++) {
    5856          96 :                 if (dom_sid_compare_domain(&global_sid_Unix_NFS_Groups,
    5857          96 :                                            &psd->dacl->aces[i].trustee) == 0) {
    5858          16 :                         if (got_one_gid == true) {
    5859             :                                 /* Can't have more than one. */
    5860           0 :                                 return NT_STATUS_INVALID_SECURITY_DESCR;
    5861             :                         }
    5862          16 :                         got_one_gid = true;
    5863             :                 }
    5864             :         }
    5865             :         /* Must have at least one of each. */
    5866          32 :         if (got_one_mode == false ||
    5867          32 :                         got_one_uid == false ||
    5868          16 :                         got_one_gid == false) {
    5869           0 :                 return NT_STATUS_INVALID_SECURITY_DESCR;
    5870             :         }
    5871          16 :         return NT_STATUS_OK;
    5872             : }
    5873             : 
    5874           8 : static bool test_nfs_aces(struct torture_context *tctx,
    5875             :                           struct smb2_tree *tree)
    5876             : {
    5877           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    5878             :         struct security_ace ace;
    5879             :         struct dom_sid sid;
    5880           8 :         const char *fname = BASEDIR "\\nfs_aces.txt";
    5881           8 :         struct smb2_handle h = {{0}};
    5882             :         union smb_fileinfo finfo2;
    5883             :         union smb_setfileinfo set;
    5884           8 :         struct security_descriptor *psd = NULL;
    5885             :         NTSTATUS status;
    5886           8 :         bool ret = true;
    5887           8 :         bool is_osx = torture_setting_bool(tctx, "osx", false);
    5888             : 
    5889           8 :         if (is_osx) {
    5890           0 :                 torture_skip(tctx, "Test only works with Samba\n");
    5891             :         }
    5892             : 
    5893           8 :         ret = enable_aapl(tctx, tree);
    5894           8 :         torture_assert(tctx, ret == true, "enable_aapl failed");
    5895             : 
    5896             :         /* clean slate ...*/
    5897           8 :         smb2_util_unlink(tree, fname);
    5898           8 :         smb2_deltree(tree, fname);
    5899           8 :         smb2_deltree(tree, BASEDIR);
    5900             : 
    5901           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h);
    5902           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    5903           8 :         smb2_util_close(tree, h);
    5904             : 
    5905             :         /* Create a test file. */
    5906           8 :         status = torture_smb2_testfile_access(tree,
    5907             :                                 fname,
    5908             :                                 &h,
    5909             :                                 SEC_STD_READ_CONTROL |
    5910             :                                 SEC_STD_WRITE_DAC |
    5911             :                                 SEC_RIGHTS_FILE_ALL);
    5912           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    5913             : 
    5914             :         /* Get the ACL. */
    5915           8 :         finfo2.query_secdesc.in.secinfo_flags =
    5916             :                 SECINFO_OWNER |
    5917             :                 SECINFO_GROUP |
    5918             :                 SECINFO_DACL;
    5919           8 :         finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
    5920           8 :         finfo2.generic.in.file.handle = h;
    5921           8 :         status = smb2_getinfo_file(tree, tctx, &finfo2);
    5922           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    5923             : 
    5924           8 :         psd = finfo2.query_secdesc.out.sd;
    5925             : 
    5926             :         /* Ensure we have only single mode/uid/gid NFS entries. */
    5927           8 :         status = check_nfs_sd(psd);
    5928           8 :         if (!NT_STATUS_IS_OK(status)) {
    5929           0 :                 NDR_PRINT_DEBUG(
    5930             :                         security_descriptor,
    5931             :                         discard_const_p(struct security_descriptor, psd));
    5932             :         }
    5933           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    5934             : 
    5935             :         /* Add a couple of extra NFS uids and gids. */
    5936           8 :         sid_compose(&sid, &global_sid_Unix_NFS_Users, 27);
    5937           8 :         init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
    5938           8 :         status = security_descriptor_dacl_add(psd, &ace);
    5939           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    5940           8 :         status = security_descriptor_dacl_add(psd, &ace);
    5941           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    5942             : 
    5943           8 :         sid_compose(&sid, &global_sid_Unix_NFS_Groups, 300);
    5944           8 :         init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0);
    5945           8 :         status = security_descriptor_dacl_add(psd, &ace);
    5946           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    5947           8 :         status = security_descriptor_dacl_add(psd, &ace);
    5948           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    5949             : 
    5950             :         /* Now set on the file handle. */
    5951           8 :         set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    5952           8 :         set.set_secdesc.in.file.handle = h;
    5953           8 :         set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    5954           8 :         set.set_secdesc.in.sd = psd;
    5955           8 :         status = smb2_setinfo_file(tree, &set);
    5956           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    5957             : 
    5958             :         /* Get the ACL again. */
    5959           8 :         finfo2.query_secdesc.in.secinfo_flags =
    5960             :                 SECINFO_OWNER |
    5961             :                 SECINFO_GROUP |
    5962             :                 SECINFO_DACL;
    5963           8 :         finfo2.generic.level = RAW_FILEINFO_SEC_DESC;
    5964           8 :         finfo2.generic.in.file.handle = h;
    5965           8 :         status = smb2_getinfo_file(tree, tctx, &finfo2);
    5966           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    5967             : 
    5968           8 :         psd = finfo2.query_secdesc.out.sd;
    5969             : 
    5970             :         /* Ensure we have only single mode/uid/gid NFS entries. */
    5971           8 :         status = check_nfs_sd(psd);
    5972           8 :         if (!NT_STATUS_IS_OK(status)) {
    5973           0 :                 NDR_PRINT_DEBUG(
    5974             :                         security_descriptor,
    5975             :                         discard_const_p(struct security_descriptor, psd));
    5976             :         }
    5977           8 :         CHECK_STATUS(status, NT_STATUS_OK);
    5978             : 
    5979          16 : done:
    5980           8 :         if (!smb2_util_handle_empty(h)) {
    5981           8 :                 smb2_util_close(tree, h);
    5982             :         }
    5983           8 :         smb2_util_unlink(tree, fname);
    5984           8 :         smb2_deltree(tree, fname);
    5985           8 :         smb2_deltree(tree, BASEDIR);
    5986           8 :         talloc_free(mem_ctx);
    5987           8 :         return ret;
    5988             : }
    5989             : 
    5990           8 : static bool test_setinfo_stream_eof(struct torture_context *tctx,
    5991             :                                     struct smb2_tree *tree)
    5992             : {
    5993           8 :         bool ret = true;
    5994             :         NTSTATUS status;
    5995             :         struct smb2_create create;
    5996             :         union smb_setfileinfo sfinfo;
    5997             :         union smb_fileinfo finfo;
    5998             :         struct smb2_handle h1;
    5999           8 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    6000           8 :         const char *fname = BASEDIR "\\file";
    6001           8 :         const char *sname = BASEDIR "\\file:foo";
    6002             : 
    6003           8 :         torture_assert_goto(tctx, mem_ctx != NULL, ret, done,
    6004             :                             "talloc_new failed\n");
    6005             : 
    6006           8 :         ret = enable_aapl(tctx, tree);
    6007           8 :         torture_assert(tctx, ret == true, "enable_aapl failed");
    6008             : 
    6009           8 :         torture_comment(tctx, "Test setting EOF on a stream\n");
    6010             : 
    6011           8 :         smb2_deltree(tree, BASEDIR);
    6012           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h1);
    6013           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6014             :                                         "torture_smb2_testdir\n");
    6015           8 :         smb2_util_close(tree, h1);
    6016             : 
    6017           8 :         status = torture_smb2_testfile(tree, fname, &h1);
    6018           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6019             :                                         "torture_smb2_testfile failed\n");
    6020           8 :         smb2_util_close(tree, h1);
    6021             : 
    6022           8 :         status = torture_smb2_testfile_access(tree, sname, &h1,
    6023             :                                               SEC_FILE_WRITE_DATA);
    6024           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6025             :                                         "torture_smb2_testfile failed\n");
    6026             : 
    6027           8 :         status = smb2_util_write(tree, h1, "1234567890", 0, 10);
    6028           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6029             :                                         "smb2_util_write failed\n");
    6030           8 :         smb2_util_close(tree, h1);
    6031             : 
    6032             :         /*
    6033             :          * Test setting EOF to 21
    6034             :          */
    6035             : 
    6036           8 :         torture_comment(tctx, "Setting stream EOF to 21\n");
    6037             : 
    6038           8 :         status = torture_smb2_testfile_access(tree, sname, &h1,
    6039             :                                               SEC_FILE_WRITE_DATA);
    6040           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6041             :                                         "torture_smb2_testfile failed\n");
    6042             : 
    6043           8 :         ZERO_STRUCT(sfinfo);
    6044           8 :         sfinfo.generic.in.file.handle = h1;
    6045           8 :         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    6046           8 :         sfinfo.position_information.in.position = 21;
    6047           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    6048           8 :         torture_assert_ntstatus_ok_goto(tctx, status,
    6049             :                                         ret, done, "set EOF 21 failed\n");
    6050             : 
    6051           8 :         smb2_util_close(tree, h1);
    6052             : 
    6053           8 :         status = torture_smb2_testfile_access(tree, sname, &h1,
    6054             :                                               SEC_FILE_WRITE_DATA);
    6055           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6056             :                                         "torture_smb2_testfile failed\n");
    6057             : 
    6058           8 :         ZERO_STRUCT(finfo);
    6059           8 :         finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
    6060           8 :         finfo.generic.in.file.handle = h1;
    6061           8 :         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
    6062           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6063             :                                         "smb2_getinfo_file failed");
    6064             : 
    6065           8 :         smb2_util_close(tree, h1);
    6066             : 
    6067           8 :         torture_assert_goto(tctx, finfo.standard_info.out.size == 21,
    6068             :                             ret, done, "size != 21\n");
    6069             : 
    6070             :         /*
    6071             :          * Test setting EOF to 0
    6072             :          */
    6073             : 
    6074           8 :         torture_comment(tctx, "Setting stream EOF to 0\n");
    6075             : 
    6076           8 :         status = torture_smb2_testfile_access(tree, sname, &h1,
    6077             :                                               SEC_FILE_WRITE_DATA);
    6078           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6079             :                                         "torture_smb2_testfile failed\n");
    6080             : 
    6081           8 :         ZERO_STRUCT(sfinfo);
    6082           8 :         sfinfo.generic.in.file.handle = h1;
    6083           8 :         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    6084           8 :         sfinfo.position_information.in.position = 0;
    6085           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    6086           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6087             :                                         "set eof 0 failed\n");
    6088             : 
    6089           8 :         ZERO_STRUCT(create);
    6090           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
    6091           8 :         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    6092           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    6093           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    6094           8 :         create.in.fname = sname;
    6095             : 
    6096           8 :         status = smb2_create(tree, tctx, &create);
    6097           8 :         torture_assert_ntstatus_equal_goto(
    6098             :                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
    6099             :                 "Unexpected status\n");
    6100             : 
    6101           8 :         smb2_util_close(tree, h1);
    6102             : 
    6103           8 :         ZERO_STRUCT(create);
    6104           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
    6105           8 :         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    6106           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    6107           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    6108           8 :         create.in.fname = sname;
    6109             : 
    6110           8 :         status = smb2_create(tree, tctx, &create);
    6111           8 :         torture_assert_ntstatus_equal_goto(
    6112             :                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
    6113             :                 "Unexpected status\n");
    6114             : 
    6115           8 :         status = torture_smb2_testfile_access(tree, sname, &h1,
    6116             :                                               SEC_FILE_WRITE_DATA);
    6117           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6118             :                                         "torture_smb2_testfile failed\n");
    6119             : 
    6120           8 :         ZERO_STRUCT(finfo);
    6121           8 :         finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
    6122           8 :         finfo.generic.in.file.handle = h1;
    6123           8 :         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
    6124           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6125             :                                         "smb2_getinfo_file failed\n");
    6126             : 
    6127           8 :         smb2_util_close(tree, h1);
    6128             : 
    6129           8 :         torture_assert_goto(tctx, finfo.standard_info.out.size == 0,
    6130             :                             ret, done, "size != 0\n");
    6131             : 
    6132             :         /*
    6133             :          * Test setinfo end-of-file info to 1
    6134             :          */
    6135             : 
    6136           8 :         torture_comment(tctx, "Setting stream EOF to 1\n");
    6137             : 
    6138           8 :         status = torture_smb2_testfile_access(tree, sname, &h1,
    6139             :                                               SEC_FILE_WRITE_DATA);
    6140           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6141             :                                         "torture_smb2_testfile failed\n");
    6142             : 
    6143           8 :         ZERO_STRUCT(sfinfo);
    6144           8 :         sfinfo.generic.in.file.handle = h1;
    6145           8 :         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    6146           8 :         sfinfo.position_information.in.position = 1;
    6147           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    6148           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6149             :                                         "set EOF 1 failed\n");
    6150             : 
    6151           8 :         smb2_util_close(tree, h1);
    6152             : 
    6153           8 :         status = torture_smb2_testfile_access(tree, sname, &h1,
    6154             :                                               SEC_FILE_WRITE_DATA);
    6155           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6156             :                                         "torture_smb2_testfile failed\n");
    6157             : 
    6158           8 :         ZERO_STRUCT(finfo);
    6159           8 :         finfo.generic.level = RAW_FILEINFO_STANDARD_INFORMATION;
    6160           8 :         finfo.generic.in.file.handle = h1;
    6161           8 :         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
    6162           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6163             :                                         "smb2_getinfo_file failed\n");
    6164             : 
    6165           8 :         smb2_util_close(tree, h1);
    6166             : 
    6167           8 :         torture_assert_goto(tctx, finfo.standard_info.out.size == 1,
    6168             :                             ret, done, "size != 1\n");
    6169             : 
    6170             :         /*
    6171             :          * Test setting EOF to 0 with AAPL enabled, should delete stream
    6172             :          */
    6173             : 
    6174           8 :         torture_comment(tctx, "Enabling AAPL extensions\n");
    6175             : 
    6176           8 :         ret = enable_aapl(tctx, tree);
    6177           8 :         torture_assert(tctx, ret == true, "enable_aapl failed\n");
    6178             : 
    6179           8 :         torture_comment(tctx, "Setting stream EOF to 0\n");
    6180           8 :         status = torture_smb2_testfile_access(tree, sname, &h1,
    6181             :                                               SEC_FILE_WRITE_DATA);
    6182           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6183             :                                         "torture_smb2_testfile failed\n");
    6184             : 
    6185           8 :         ZERO_STRUCT(sfinfo);
    6186           8 :         sfinfo.generic.in.file.handle = h1;
    6187           8 :         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    6188           8 :         sfinfo.position_information.in.position = 0;
    6189           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    6190           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6191             :                                         "set eof 0 failed\n");
    6192             : 
    6193           8 :         ZERO_STRUCT(create);
    6194           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
    6195           8 :         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    6196           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    6197           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    6198           8 :         create.in.fname = sname;
    6199             : 
    6200           8 :         status = smb2_create(tree, tctx, &create);
    6201           8 :         torture_assert_ntstatus_equal_goto(
    6202             :                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
    6203             :                 "Unexpected status\n");
    6204             : 
    6205           8 :         smb2_util_close(tree, h1);
    6206             : 
    6207           8 :         ZERO_STRUCT(create);
    6208           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
    6209           8 :         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    6210           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    6211           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    6212           8 :         create.in.fname = sname;
    6213             : 
    6214           8 :         status = smb2_create(tree, tctx, &create);
    6215           8 :         torture_assert_ntstatus_equal_goto(
    6216             :                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
    6217             :                 "Unexpected status\n");
    6218             : 
    6219           8 :         torture_comment(
    6220             :                 tctx, "Setting main file EOF to 1 to force 0-truncate\n");
    6221             : 
    6222           8 :         status = torture_smb2_testfile_access(
    6223             :                 tree,
    6224             :                 fname,
    6225             :                 &h1,
    6226             :                 SEC_FILE_WRITE_DATA);
    6227           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6228             :                                         "torture_smb2_testfile failed\n");
    6229             : 
    6230           8 :         ZERO_STRUCT(sfinfo);
    6231           8 :         sfinfo.generic.in.file.handle = h1;
    6232           8 :         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    6233           8 :         sfinfo.position_information.in.position = 1;
    6234           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    6235           8 :         torture_assert_ntstatus_ok_goto(
    6236             :                 tctx,
    6237             :                 status,
    6238             :                 ret,
    6239             :                 done,
    6240             :                 "set eof 1 failed\n");
    6241             : 
    6242           8 :         sfinfo.position_information.in.position = 0;
    6243           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    6244           8 :         torture_assert_ntstatus_ok_goto(
    6245             :                 tctx,
    6246             :                 status,
    6247             :                 ret,
    6248             :                 done,
    6249             :                 "set eof 0 failed\n");
    6250             : 
    6251           8 :         smb2_util_close(tree, h1);
    6252             : 
    6253           8 :         ZERO_STRUCT(create);
    6254           8 :         create.in.desired_access = SEC_FILE_READ_ATTRIBUTE;
    6255           8 :         create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
    6256           8 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    6257           8 :         create.in.create_disposition = NTCREATEX_DISP_OPEN;
    6258           8 :         create.in.fname = fname;
    6259             : 
    6260           8 :         status = smb2_create(tree, tctx, &create);
    6261           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6262             :                                         "torture_smb2_testfile failed\n");
    6263           8 :         smb2_util_close(tree, h1);
    6264             : 
    6265           8 :         torture_comment(tctx, "Writing to stream after setting EOF to 0\n");
    6266           8 :         status = torture_smb2_testfile_access(tree, sname, &h1,
    6267             :                                               SEC_FILE_WRITE_DATA);
    6268           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6269             :                                         "torture_smb2_testfile failed\n");
    6270             : 
    6271           8 :         status = smb2_util_write(tree, h1, "1234567890", 0, 10);
    6272           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6273             :                                         "smb2_util_write failed\n");
    6274             : 
    6275           8 :         ZERO_STRUCT(sfinfo);
    6276           8 :         sfinfo.generic.in.file.handle = h1;
    6277           8 :         sfinfo.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    6278           8 :         sfinfo.position_information.in.position = 0;
    6279           8 :         status = smb2_setinfo_file(tree, &sfinfo);
    6280           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6281             :                                         "set eof 0 failed\n");
    6282             : 
    6283           8 :         status = smb2_util_write(tree, h1, "1234567890", 0, 10);
    6284           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6285             :                                         "smb2_util_write failed\n");
    6286             : 
    6287           8 :         smb2_util_close(tree, h1);
    6288             : 
    6289           8 : done:
    6290           8 :         smb2_util_unlink(tree, fname);
    6291           8 :         smb2_util_rmdir(tree, BASEDIR);
    6292           8 :         return ret;
    6293             : }
    6294             : 
    6295             : #define MAX_STREAMS 16
    6296             : 
    6297             : struct tcase {
    6298             :         const char *name;
    6299             :         uint32_t access;
    6300             :         const char *write_data;
    6301             :         size_t write_size;
    6302             :         struct tcase_results {
    6303             :                 size_t size;
    6304             :                 NTSTATUS initial_status;
    6305             :                 NTSTATUS final_status;
    6306             :                 int num_streams_open_handle;
    6307             :                 const char *streams_open_handle[MAX_STREAMS];
    6308             :                 int num_streams_closed_handle;
    6309             :                 const char *streams_closed_handle[MAX_STREAMS];
    6310             :         } create, write, overwrite, eof, doc;
    6311             : };
    6312             : 
    6313             : typedef enum {T_CREATE, T_WRITE, T_OVERWRITE, T_EOF, T_DOC} subtcase_t;
    6314             : 
    6315         144 : static bool test_empty_stream_do_checks(
    6316             :         struct torture_context *tctx,
    6317             :         struct smb2_tree *tree,
    6318             :         struct smb2_tree *tree2,
    6319             :         struct tcase *tcase,
    6320             :         TALLOC_CTX *mem_ctx,
    6321             :         struct smb2_handle baseh,
    6322             :         struct smb2_handle streamh,
    6323             :         subtcase_t subcase)
    6324             : {
    6325         144 :         bool ret = false;
    6326             :         NTSTATUS status;
    6327             :         struct smb2_handle h1;
    6328             :         union smb_fileinfo finfo;
    6329         144 :         struct tcase_results *tcase_results = NULL;
    6330             : 
    6331         144 :         switch (subcase) {
    6332          48 :         case T_CREATE:
    6333          48 :                 tcase_results = &tcase->create;
    6334          48 :                 break;
    6335          24 :         case T_OVERWRITE:
    6336          24 :                 tcase_results = &tcase->overwrite;
    6337          24 :                 break;
    6338          24 :         case T_WRITE:
    6339          24 :                 tcase_results = &tcase->write;
    6340          24 :                 break;
    6341          24 :         case T_EOF:
    6342          24 :                 tcase_results = &tcase->eof;
    6343          24 :                 break;
    6344          24 :         case T_DOC:
    6345          24 :                 tcase_results = &tcase->doc;
    6346          24 :                 break;
    6347             :         }
    6348             : 
    6349         144 :         finfo = (union smb_fileinfo) {
    6350             :                 .generic.level = RAW_FILEINFO_STANDARD_INFORMATION,
    6351             :                 .generic.in.file.handle = streamh,
    6352             :         };
    6353             : 
    6354             :         /*
    6355             :          * Test: check size, same client
    6356             :          */
    6357             : 
    6358         144 :         status = smb2_getinfo_file(tree, mem_ctx, &finfo);
    6359         144 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6360             :                                         "torture_smb2_testfile failed\n");
    6361             : 
    6362         144 :         torture_assert_int_equal_goto(tctx, finfo.standard_info.out.size,
    6363             :                                       tcase_results->size,
    6364             :                                       ret, done, "Wrong size\n");
    6365             : 
    6366             :         /*
    6367             :          * Test: open, same client
    6368             :          */
    6369             : 
    6370         144 :         status = torture_smb2_open(tree, tcase->name,
    6371             :                                    SEC_FILE_READ_ATTRIBUTE, &h1);
    6372         144 :         torture_assert_ntstatus_equal_goto(tctx, status,
    6373             :                                            tcase_results->initial_status,
    6374             :                                            ret, done,
    6375             :                                            "smb2_create failed\n");
    6376         144 :         if (NT_STATUS_IS_OK(status)) {
    6377          32 :                 status = smb2_util_close(tree, h1);
    6378          32 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6379             :                                                 "smb2_util_close failed\n");
    6380             :         }
    6381             : 
    6382             :         /*
    6383             :          * Test: check streams, same client
    6384             :          */
    6385             : 
    6386         144 :         ret = check_stream_list_handle(tree, tctx, baseh,
    6387             :                                        tcase_results->num_streams_open_handle,
    6388         144 :                                        tcase_results->streams_open_handle,
    6389             :                                        false);
    6390         144 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    6391             : 
    6392             :         /*
    6393             :          * Test: open, different client
    6394             :          */
    6395             : 
    6396         144 :         status = torture_smb2_open(tree2, tcase->name,
    6397             :                                    SEC_FILE_READ_ATTRIBUTE, &h1);
    6398         144 :         torture_assert_ntstatus_equal_goto(tctx, status,
    6399             :                                            tcase_results->initial_status,
    6400             :                                            ret, done,
    6401             :                                            "smb2_create failed\n");
    6402         144 :         if (NT_STATUS_IS_OK(status)) {
    6403          32 :                 finfo = (union smb_fileinfo) {
    6404             :                         .generic.level = RAW_FILEINFO_STANDARD_INFORMATION,
    6405             :                         .generic.in.file.handle = h1,
    6406             :                 };
    6407             : 
    6408             :                 /*
    6409             :                  * Test: check size, different client
    6410             :                  */
    6411             : 
    6412          32 :                 status = smb2_getinfo_file(tree2, mem_ctx, &finfo);
    6413          32 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6414             :                                                 "smb2_getinfo_file failed\n");
    6415             : 
    6416          32 :                 torture_assert_int_equal_goto(tctx, finfo.standard_info.out.size,
    6417             :                                               tcase_results->size,
    6418             :                                               ret, done, "Wrong size\n");
    6419             : 
    6420             :                 /*
    6421             :                  * Test: check streams, different client
    6422             :                  */
    6423             : 
    6424          32 :                 ret = check_stream_list(tree2, tctx, BASEDIR "\\file",
    6425             :                                         tcase_results->num_streams_open_handle,
    6426          32 :                                         tcase_results->streams_open_handle,
    6427             :                                         false);
    6428          32 :                 torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    6429             : 
    6430          32 :                 status = smb2_util_close(tree2, h1);
    6431          32 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6432             :                                                 "smb2_util_close failed\n");
    6433             :         }
    6434             : 
    6435         144 :         status = smb2_util_close(tree, streamh);
    6436         144 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6437             :                                         "smb2_util_close failed\n");
    6438             : 
    6439             :         /*
    6440             :          * Test: open after close, same client
    6441             :          */
    6442             : 
    6443         144 :         status = torture_smb2_open(tree, tcase->name,
    6444             :                                    SEC_FILE_READ_DATA, &h1);
    6445         144 :         torture_assert_ntstatus_equal_goto(tctx, status,
    6446             :                                            tcase_results->final_status,
    6447             :                                            ret, done,
    6448             :                                            "smb2_create failed\n");
    6449         144 :         if (NT_STATUS_IS_OK(status)) {
    6450          40 :                 status = smb2_util_close(tree, h1);
    6451          40 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6452             :                                                 "smb2_util_close failed\n");
    6453             :         }
    6454             : 
    6455             :         /*
    6456             :          * Test: open after close, different client
    6457             :          */
    6458             : 
    6459         144 :         status = torture_smb2_open(tree2, tcase->name,
    6460             :                                    SEC_FILE_READ_DATA, &h1);
    6461         144 :         torture_assert_ntstatus_equal_goto(tctx, status,
    6462             :                                            tcase_results->final_status,
    6463             :                                            ret, done,
    6464             :                                            "smb2_create failed\n");
    6465         144 :         if (NT_STATUS_IS_OK(status)) {
    6466          40 :                 status = smb2_util_close(tree2, h1);
    6467          40 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6468             :                                                 "smb2_util_close failed\n");
    6469             :         }
    6470             : 
    6471             :         /*
    6472             :          * Test: check streams after close, same client
    6473             :          */
    6474             : 
    6475         144 :         ret = check_stream_list_handle(tree, tctx, baseh,
    6476             :                                        tcase_results->num_streams_closed_handle,
    6477         144 :                                        tcase_results->streams_closed_handle,
    6478             :                                        false);
    6479         144 :         torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
    6480             : 
    6481         144 :         ret = true;
    6482             : 
    6483         144 : done:
    6484         144 :         smb2_util_close(tree, streamh);
    6485         144 :         smb2_util_close(tree, baseh);
    6486         144 :         return ret;
    6487             : }
    6488             : 
    6489          48 : static bool test_empty_stream_do_one(
    6490             :         struct torture_context *tctx,
    6491             :         struct smb2_tree *tree,
    6492             :         struct smb2_tree *tree2,
    6493             :         struct tcase *tcase)
    6494             : {
    6495          48 :         bool ret = false;
    6496             :         NTSTATUS status;
    6497          48 :         struct smb2_handle baseh = {{0}};
    6498             :         struct smb2_handle streamh;
    6499             :         struct smb2_create create;
    6500             :         union smb_setfileinfo sfinfo;
    6501          48 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    6502             : 
    6503          48 :         torture_comment(tctx, "Testing stream [%s]\n", tcase->name);
    6504             : 
    6505          48 :         torture_assert_goto(tctx, mem_ctx != NULL, ret, done, "talloc_new\n");
    6506             : 
    6507             :         /*
    6508             :          * Subtest: create
    6509             :          */
    6510          48 :         torture_comment(tctx, "Subtest: T_CREATE\n");
    6511             : 
    6512          48 :         status = smb2_util_unlink(tree, BASEDIR "\\file");
    6513          48 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6514             :                                         "smb2_util_unlink failed\n");
    6515             : 
    6516          48 :         status = torture_smb2_testfile_access(tree, BASEDIR "\\file",
    6517             :                                               &baseh, SEC_FILE_ALL);
    6518          48 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6519             :                                         "torture_smb2_testfile_access failed\n");
    6520             : 
    6521          48 :         status = torture_smb2_testfile_access(tree, tcase->name, &streamh,
    6522             :                                               tcase->access);
    6523          48 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6524             :                                         "torture_smb2_testfile_access failed\n");
    6525             : 
    6526          48 :         ret = test_empty_stream_do_checks(tctx, tree, tree2, tcase,
    6527             :                                           mem_ctx, baseh, streamh, T_CREATE);
    6528          48 :         torture_assert_goto(tctx, ret, ret, done, "test failed\n");
    6529             : 
    6530          48 :         if (!(tcase->access & SEC_FILE_WRITE_DATA)) {
    6531             :                 /*
    6532             :                  * All subsequent tests require write access
    6533             :                  */
    6534          24 :                 ret = true;
    6535          24 :                 goto done;
    6536             :         }
    6537             : 
    6538             :         /*
    6539             :          * Subtest: create and write
    6540             :          */
    6541          24 :         torture_comment(tctx, "Subtest: T_WRITE\n");
    6542             : 
    6543          24 :         status = smb2_util_unlink(tree, BASEDIR "\\file");
    6544          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6545             :                                         "smb2_util_unlink failed\n");
    6546             : 
    6547          24 :         status = torture_smb2_testfile_access(tree, BASEDIR "\\file",
    6548             :                                               &baseh, SEC_FILE_ALL);
    6549          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6550             :                                         "torture_smb2_testfile_access failed\n");
    6551             : 
    6552          24 :         status = torture_smb2_testfile_access(tree, tcase->name, &streamh,
    6553             :                                               tcase->access);
    6554          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6555             :                                         "torture_smb2_testfile_access failed\n");
    6556             : 
    6557          24 :         status = smb2_util_write(tree, streamh, tcase->write_data, 0,
    6558             :                                  tcase->write_size);
    6559          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6560             :                                         "torture_smb2_open failed\n");
    6561             : 
    6562          24 :         ret = test_empty_stream_do_checks(tctx, tree, tree2, tcase,
    6563             :                                           mem_ctx, baseh, streamh, T_WRITE);
    6564          24 :         torture_assert_goto(tctx, ret, ret, done, "test failed\n");
    6565             : 
    6566             :         /*
    6567             :          * Subtest: overwrite
    6568             :          */
    6569          24 :         torture_comment(tctx, "Subtest: T_OVERWRITE\n");
    6570             : 
    6571          24 :         status = smb2_util_unlink(tree, BASEDIR "\\file");
    6572          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6573             :                                         "smb2_util_unlink failed\n");
    6574             : 
    6575          24 :         status = torture_smb2_testfile_access(tree, BASEDIR "\\file",
    6576             :                                               &baseh, SEC_FILE_ALL);
    6577          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6578             :                                         "torture_smb2_testfile_access failed\n");
    6579             : 
    6580          24 :         create = (struct smb2_create) {
    6581             :                 .in.desired_access = SEC_FILE_ALL,
    6582             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    6583             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    6584             :                 .in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF,
    6585          24 :                 .in.fname = tcase->name,
    6586             :         };
    6587             : 
    6588          24 :         status = smb2_create(tree, tctx, &create);
    6589          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6590             :                                         "torture_smb2_testfile failed\n");
    6591          24 :         streamh = create.out.file.handle;
    6592             : 
    6593          24 :         ret = test_empty_stream_do_checks(tctx, tree, tree2, tcase,
    6594             :                                           mem_ctx, baseh, streamh, T_OVERWRITE);
    6595          24 :         torture_assert_goto(tctx, ret, ret, done, "test failed\n");
    6596             : 
    6597             :         /*
    6598             :          * Subtest: setinfo EOF 0
    6599             :          */
    6600          24 :         torture_comment(tctx, "Subtest: T_EOF\n");
    6601             : 
    6602          24 :         status = smb2_util_unlink(tree, BASEDIR "\\file");
    6603          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6604             :                                         "smb2_util_unlink failed\n");
    6605             : 
    6606          24 :         status = torture_smb2_testfile_access(tree, BASEDIR "\\file",
    6607             :                                               &baseh, SEC_FILE_ALL);
    6608          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6609             :                                         "torture_smb2_testfile_access failed\n");
    6610             : 
    6611          24 :         status = torture_smb2_testfile_access(tree, tcase->name, &streamh,
    6612             :                                               tcase->access);
    6613          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6614             :                                         "torture_smb2_testfile_access failed\n");
    6615             : 
    6616          24 :         status = smb2_util_write(tree, streamh, tcase->write_data, 0,
    6617             :                                  tcase->write_size);
    6618          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6619             :                                         "torture_smb2_open failed\n");
    6620             : 
    6621          24 :         sfinfo = (union smb_setfileinfo) {
    6622             :                 .end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION,
    6623             :                 .end_of_file_info.in.file.handle = streamh,
    6624             :                 .end_of_file_info.in.size = 0,
    6625             :         };
    6626          24 :         status = smb2_setinfo_file(tree, &sfinfo);
    6627          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6628             :                                         "set eof 0 failed\n");
    6629             : 
    6630          24 :         ret = test_empty_stream_do_checks(tctx, tree, tree2, tcase,
    6631             :                                           mem_ctx, baseh, streamh, T_EOF);
    6632          24 :         torture_assert_goto(tctx, ret, ret, done, "test failed\n");
    6633             : 
    6634             :         /*
    6635             :          * Subtest: delete-on-close
    6636             :          */
    6637          24 :         torture_comment(tctx, "Subtest: T_DOC\n");
    6638             : 
    6639          24 :         status = smb2_util_unlink(tree, BASEDIR "\\file");
    6640          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6641             :                                         "smb2_util_unlink failed\n");
    6642             : 
    6643          24 :         status = torture_smb2_testfile_access(tree, BASEDIR "\\file",
    6644             :                                               &baseh, SEC_FILE_ALL);
    6645          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6646             :                                         "torture_smb2_testfile_access failed\n");
    6647             : 
    6648          24 :         status = torture_smb2_testfile_access(tree, tcase->name, &streamh,
    6649             :                                               tcase->access);
    6650          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6651             :                                         "torture_smb2_testfile_access failed\n");
    6652             : 
    6653          24 :         status = smb2_util_write(tree, streamh, tcase->write_data, 0,
    6654             :                                  tcase->write_size);
    6655          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6656             :                                         "torture_smb2_open failed\n");
    6657             : 
    6658          24 :         sfinfo = (union smb_setfileinfo) {
    6659             :                 .disposition_info.level = RAW_SFILEINFO_DISPOSITION_INFORMATION,
    6660             :                 .disposition_info.in.file.handle = streamh,
    6661             :                 .disposition_info.in.delete_on_close = true,
    6662             :         };
    6663          24 :         status = smb2_setinfo_file(tree, &sfinfo);
    6664          24 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6665             :                                         "set eof 0 failed\n");
    6666             : 
    6667          24 :         ret = test_empty_stream_do_checks(tctx, tree, tree2, tcase,
    6668             :                                           mem_ctx, baseh, streamh,
    6669             :                                           T_DOC);
    6670          24 :         torture_assert_goto(tctx, ret, ret, done, "test failed\n");
    6671             : 
    6672          24 :         ret = true;
    6673             : 
    6674          48 : done:
    6675          48 :         smb2_util_close(tree, baseh);
    6676          48 :         TALLOC_FREE(mem_ctx);
    6677          48 :         return ret;
    6678             : }
    6679             : 
    6680           8 : static bool test_empty_stream(struct torture_context *tctx,
    6681             :                               struct smb2_tree *tree)
    6682             : {
    6683           8 :         struct smb2_tree *tree2 = NULL;
    6684           8 :         struct tcase *tcase = NULL;
    6685           8 :         const char *fname = BASEDIR "\\file";
    6686             :         struct smb2_handle h1;
    6687           8 :         bool ret = true;
    6688             :         NTSTATUS status;
    6689           8 :         AfpInfo ai = (AfpInfo) {
    6690             :                 .afpi_Signature = AFP_Signature,
    6691             :                 .afpi_Version = AFP_Version,
    6692             :                 .afpi_BackupTime = AFP_BackupTime,
    6693             :                 .afpi_FinderInfo = "FOO BAR ",
    6694             :         };
    6695           8 :         char *ai_blob = torture_afpinfo_pack(tctx, &ai);
    6696           8 :         struct tcase tcase_afpinfo_ro = (struct tcase) {
    6697             :                 .name = BASEDIR "\\file" AFPINFO_STREAM,
    6698             :                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE,
    6699             :                 .create = {
    6700             :                         .size = 60,
    6701             :                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6702             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6703             :                         .num_streams_open_handle = 1,
    6704             :                         .num_streams_closed_handle = 1,
    6705             :                         .streams_open_handle = {"::$DATA"},
    6706             :                         .streams_closed_handle = {"::$DATA"},
    6707             :                 },
    6708             :         };
    6709           8 :         struct tcase tcase_afpinfo_rw = (struct tcase) {
    6710             :                 .name = BASEDIR "\\file" AFPINFO_STREAM,
    6711             :                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_DATA|SEC_STD_DELETE,
    6712             :                 .write_data = ai_blob,
    6713             :                 .write_size = AFP_INFO_SIZE,
    6714             :                 .create = {
    6715             :                         .size = 60,
    6716             :                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6717             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6718             :                         .num_streams_open_handle = 1,
    6719             :                         .num_streams_closed_handle = 1,
    6720             :                         .streams_open_handle = {"::$DATA"},
    6721             :                         .streams_closed_handle = {"::$DATA"},
    6722             :                 },
    6723             :                 .write = {
    6724             :                         .size = 60,
    6725             :                         .initial_status = NT_STATUS_OK,
    6726             :                         .final_status = NT_STATUS_OK,
    6727             :                         .num_streams_open_handle = 2,
    6728             :                         .num_streams_closed_handle = 2,
    6729             :                         .streams_open_handle = {"::$DATA", AFPINFO_STREAM},
    6730             :                         .streams_closed_handle = {"::$DATA", AFPINFO_STREAM},
    6731             :                 },
    6732             :                 .overwrite = {
    6733             :                         .size = 60,
    6734             :                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6735             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6736             :                         .num_streams_open_handle = 1,
    6737             :                         .num_streams_closed_handle = 1,
    6738             :                         .streams_open_handle = {"::$DATA"},
    6739             :                         .streams_closed_handle = {"::$DATA"},
    6740             :                 },
    6741             :                 .eof = {
    6742             :                         .size = 60,
    6743             :                         .initial_status = NT_STATUS_OK,
    6744             :                         .final_status = NT_STATUS_OK,
    6745             :                         .num_streams_open_handle = 2,
    6746             :                         .num_streams_closed_handle = 2,
    6747             :                         .streams_open_handle = {"::$DATA", AFPINFO_STREAM},
    6748             :                         .streams_closed_handle = {"::$DATA", AFPINFO_STREAM},
    6749             :                 },
    6750             :                 .doc = {
    6751             :                         .size = 60,
    6752             :                         .initial_status = NT_STATUS_DELETE_PENDING,
    6753             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6754             :                         .num_streams_open_handle = 2,
    6755             :                         .num_streams_closed_handle = 1,
    6756             :                         .streams_open_handle = {"::$DATA", AFPINFO_STREAM},
    6757             :                         .streams_closed_handle = {"::$DATA"},
    6758             :                 },
    6759             :         };
    6760             : 
    6761           8 :         struct tcase tcase_afpresource_ro = (struct tcase) {
    6762             :                 .name = BASEDIR "\\file" AFPRESOURCE_STREAM,
    6763             :                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE,
    6764             :                 .create = {
    6765             :                         .size = 0,
    6766             :                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6767             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6768             :                         .num_streams_open_handle = 1,
    6769             :                         .num_streams_closed_handle = 1,
    6770             :                         .streams_open_handle = {"::$DATA"},
    6771             :                         .streams_closed_handle = {"::$DATA"},
    6772             :                 },
    6773             :         };
    6774           8 :         struct tcase tcase_afpresource_rw = (struct tcase) {
    6775             :                 .name = BASEDIR "\\file" AFPRESOURCE_STREAM,
    6776             :                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_DATA|SEC_STD_DELETE,
    6777             :                 .write_data = "foo",
    6778             :                 .write_size = 3,
    6779             :                 .create = {
    6780             :                         .size = 0,
    6781             :                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6782             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6783             :                         .num_streams_open_handle = 1,
    6784             :                         .num_streams_closed_handle = 1,
    6785             :                         .streams_open_handle = {"::$DATA"},
    6786             :                         .streams_closed_handle = {"::$DATA"},
    6787             :                 },
    6788             :                 .write = {
    6789             :                         .size = 3,
    6790             :                         .initial_status = NT_STATUS_OK,
    6791             :                         .final_status = NT_STATUS_OK,
    6792             :                         .num_streams_open_handle = 2,
    6793             :                         .num_streams_closed_handle = 2,
    6794             :                         .streams_open_handle = {"::$DATA", AFPRESOURCE_STREAM},
    6795             :                         .streams_closed_handle = {"::$DATA", AFPRESOURCE_STREAM},
    6796             :                 },
    6797             :                 .overwrite = {
    6798             :                         .size = 0,
    6799             :                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6800             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6801             :                         .num_streams_open_handle = 1,
    6802             :                         .num_streams_closed_handle = 1,
    6803             :                         .streams_open_handle = {"::$DATA"},
    6804             :                         .streams_closed_handle = {"::$DATA"},
    6805             :                 },
    6806             :                 .eof = {
    6807             :                         .size = 0,
    6808             :                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6809             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6810             :                         .num_streams_open_handle = 1,
    6811             :                         .num_streams_closed_handle = 1,
    6812             :                         .streams_open_handle = {"::$DATA"},
    6813             :                         .streams_closed_handle = {"::$DATA"},
    6814             :                 },
    6815             :                 .doc = {
    6816             :                         .size = 3,
    6817             :                         .initial_status = NT_STATUS_DELETE_PENDING,
    6818             :                         .final_status = NT_STATUS_OK,
    6819             :                         .num_streams_open_handle = 2,
    6820             :                         .num_streams_closed_handle = 2,
    6821             :                         .streams_open_handle = {"::$DATA", AFPRESOURCE_STREAM},
    6822             :                         .streams_closed_handle = {"::$DATA", AFPRESOURCE_STREAM},
    6823             :                 },
    6824             :         };
    6825             : 
    6826           8 :         struct tcase tcase_foo_ro = (struct tcase) {
    6827             :                 .name = BASEDIR "\\file:foo",
    6828             :                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE,
    6829             :                 .write_data = "foo",
    6830             :                 .write_size = 3,
    6831             :                 .create = {
    6832             :                         .size = 0,
    6833             :                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6834             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6835             :                         .num_streams_open_handle = 1,
    6836             :                         .num_streams_closed_handle = 1,
    6837             :                         .streams_open_handle = {"::$DATA"},
    6838             :                         .streams_closed_handle = {"::$DATA"},
    6839             :                 },
    6840             :         };
    6841             : 
    6842           8 :         struct tcase tcase_foo_rw = (struct tcase) {
    6843             :                 .name = BASEDIR "\\file:foo",
    6844             :                 .access = SEC_FILE_READ_DATA|SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_DATA|SEC_STD_DELETE,
    6845             :                 .write_data = "foo",
    6846             :                 .write_size = 3,
    6847             :                 .create = {
    6848             :                         .size = 0,
    6849             :                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6850             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6851             :                         .num_streams_open_handle = 1,
    6852             :                         .num_streams_closed_handle = 1,
    6853             :                         .streams_open_handle = {"::$DATA"},
    6854             :                         .streams_closed_handle = {"::$DATA"},
    6855             :                 },
    6856             :                 .write = {
    6857             :                         .size = 3,
    6858             :                         .initial_status = NT_STATUS_OK,
    6859             :                         .final_status = NT_STATUS_OK,
    6860             :                         .num_streams_open_handle = 2,
    6861             :                         .num_streams_closed_handle = 2,
    6862             :                         .streams_open_handle = {"::$DATA", ":foo:$DATA"},
    6863             :                         .streams_closed_handle = {"::$DATA", ":foo:$DATA"},
    6864             :                 },
    6865             :                 .overwrite = {
    6866             :                         .size = 0,
    6867             :                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6868             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6869             :                         .num_streams_open_handle = 1,
    6870             :                         .num_streams_closed_handle = 1,
    6871             :                         .streams_open_handle = {"::$DATA"},
    6872             :                         .streams_closed_handle = {"::$DATA"},
    6873             :                 },
    6874             :                 .eof = {
    6875             :                         .size = 0,
    6876             :                         .initial_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6877             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6878             :                         .num_streams_open_handle = 1,
    6879             :                         .num_streams_closed_handle = 1,
    6880             :                         .streams_open_handle = {"::$DATA"},
    6881             :                         .streams_closed_handle = {"::$DATA"},
    6882             :                 },
    6883             :                 .doc = {
    6884             :                         .size = 3,
    6885             :                         .initial_status = NT_STATUS_DELETE_PENDING,
    6886             :                         .final_status = NT_STATUS_OBJECT_NAME_NOT_FOUND,
    6887             :                         .num_streams_open_handle = 2,
    6888             :                         .num_streams_closed_handle = 1,
    6889             :                         .streams_open_handle = {"::$DATA", ":foo:$DATA"},
    6890             :                         .streams_closed_handle = {"::$DATA"},
    6891             :                 },
    6892             :         };
    6893             : 
    6894           8 :         struct tcase tcases[] = {
    6895             :                 tcase_afpinfo_ro,
    6896             :                 tcase_afpinfo_rw,
    6897             :                 tcase_afpresource_ro,
    6898             :                 tcase_afpresource_rw,
    6899             :                 tcase_foo_ro,
    6900             :                 tcase_foo_rw,
    6901             :                 {0}
    6902             :         };
    6903             : 
    6904           8 :         ret = torture_smb2_connection(tctx, &tree2);
    6905           8 :         torture_assert_goto(tctx, ret == true, ret, done,
    6906             :                             "torture_smb2_connection failed\n");
    6907             : 
    6908           8 :         ret = enable_aapl(tctx, tree);
    6909           8 :         torture_assert(tctx, ret == true, "enable_aapl failed\n");
    6910             : 
    6911           8 :         ret = enable_aapl(tctx, tree2);
    6912           8 :         torture_assert(tctx, ret == true, "enable_aapl failed\n");
    6913             : 
    6914           8 :         smb2_deltree(tree, BASEDIR);
    6915             : 
    6916           8 :         status = torture_smb2_testdir(tree, BASEDIR, &h1);
    6917           8 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6918             :                                         "torture_smb2_testdir\n");
    6919           8 :         smb2_util_close(tree, h1);
    6920             : 
    6921          56 :         for (tcase = &tcases[0]; tcase->name != NULL; tcase++) {
    6922          48 :                 ret = torture_setup_file(tctx, tree, fname, false);
    6923          48 :                 torture_assert_goto(tctx, ret == true, ret, done,
    6924             :                                     "torture_setup_file failed\n");
    6925             : 
    6926          48 :                 ret = test_empty_stream_do_one(tctx, tree, tree2, tcase);
    6927          48 :                 torture_assert_goto(tctx, ret == true, ret, done,
    6928             :                                     "subtest failed\n");
    6929             : 
    6930          48 :                 status = smb2_util_unlink(tree, fname);
    6931          48 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    6932             :                                                 "smb2_util_unlink failed\n");
    6933             :         }
    6934             : 
    6935           8 : done:
    6936           8 :         smb2_deltree(tree, BASEDIR);
    6937           8 :         TALLOC_FREE(tree2);
    6938           8 :         return ret;
    6939             : }
    6940             : 
    6941             : /*
    6942             :  * Note: This test depends on "vfs objects = catia fruit streams_xattr".  For
    6943             :  * some tests torture must be run on the host it tests and takes an additional
    6944             :  * argument with the local path to the share:
    6945             :  * "--option=torture:localdir=<SHAREPATH>".
    6946             :  *
    6947             :  * When running against an OS X SMB server add "--option=torture:osx=true"
    6948             :  */
    6949        2355 : struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
    6950             : {
    6951        2355 :         struct torture_suite *suite = torture_suite_create(
    6952             :                 ctx, "fruit");
    6953             : 
    6954        2355 :         suite->description = talloc_strdup(suite, "vfs_fruit tests");
    6955             : 
    6956        2355 :         torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
    6957        2355 :         torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
    6958        2355 :         torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
    6959        2355 :         torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
    6960        2355 :         torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
    6961        2355 :         torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
    6962        2355 :         torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
    6963        2355 :         torture_suite_add_1smb2_test(suite, "opening and creating resource fork", test_rfork_create);
    6964        2355 :         torture_suite_add_1smb2_test(suite, "rename_dir_openfile", test_rename_dir_openfile);
    6965        2355 :         torture_suite_add_1smb2_test(suite, "File without AFP_AfpInfo", test_afpinfo_enoent);
    6966        2355 :         torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpInfo", test_create_delete_on_close);
    6967        2355 :         torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpInfo", test_setinfo_delete_on_close);
    6968        2355 :         torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpInfo", test_setinfo_eof);
    6969        2355 :         torture_suite_add_1smb2_test(suite, "delete AFP_AfpInfo by writing all 0", test_afpinfo_all0);
    6970        2355 :         torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
    6971        2355 :         torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
    6972        2355 :         torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
    6973        2355 :         torture_suite_add_1smb2_test(suite, "setinfo eof stream", test_setinfo_stream_eof);
    6974        2355 :         torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
    6975        2355 :         torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
    6976        2355 :         torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
    6977        2355 :         torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
    6978        2355 :         torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
    6979        2355 :         torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
    6980        2355 :         torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
    6981        2355 :         torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
    6982        2355 :         torture_suite_add_1smb2_test(suite, "NFS ACE entries", test_nfs_aces);
    6983        2355 :         torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion without embedded xattr", test_adouble_conversion_wo_xattr);
    6984        2355 :         torture_suite_add_1smb2_test(suite, "empty_stream", test_empty_stream);
    6985        2355 :         torture_suite_add_1smb2_test(suite, "writing_afpinfo", test_writing_afpinfo);
    6986             : 
    6987        2355 :         return suite;
    6988             : }
    6989             : 
    6990           2 : static bool test_stream_names_local(struct torture_context *tctx,
    6991             :                                     struct smb2_tree *tree)
    6992             : {
    6993           2 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    6994             :         NTSTATUS status;
    6995             :         struct smb2_create create;
    6996             :         struct smb2_handle h;
    6997           2 :         const char *fname = BASEDIR "\\stream_names.txt";
    6998             :         const char *sname1;
    6999             :         bool ret;
    7000             :         /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
    7001           2 :         const char *streams[] = {
    7002             :                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
    7003             :                 ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
    7004             :                 "::$DATA"
    7005             :         };
    7006           2 :         const char *localdir = NULL;
    7007             : 
    7008           2 :         localdir = torture_setting_string(tctx, "localdir", NULL);
    7009           2 :         if (localdir == NULL) {
    7010           0 :                 torture_skip(tctx, "Need localdir for test");
    7011             :         }
    7012             : 
    7013           2 :         sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
    7014             : 
    7015             :         /* clean slate ...*/
    7016           2 :         smb2_util_unlink(tree, fname);
    7017           2 :         smb2_deltree(tree, fname);
    7018           2 :         smb2_deltree(tree, BASEDIR);
    7019             : 
    7020           2 :         status = torture_smb2_testdir(tree, BASEDIR, &h);
    7021           2 :         CHECK_STATUS(status, NT_STATUS_OK);
    7022           2 :         smb2_util_close(tree, h);
    7023             : 
    7024           2 :         torture_comment(tctx, "(%s) testing stream names\n", __location__);
    7025           2 :         ZERO_STRUCT(create);
    7026           2 :         create.in.desired_access = SEC_FILE_WRITE_DATA;
    7027           2 :         create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    7028           2 :         create.in.share_access =
    7029             :                 NTCREATEX_SHARE_ACCESS_DELETE|
    7030             :                 NTCREATEX_SHARE_ACCESS_READ|
    7031             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    7032           2 :         create.in.create_disposition = NTCREATEX_DISP_CREATE;
    7033           2 :         create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    7034           2 :         create.in.fname = sname1;
    7035             : 
    7036           2 :         status = smb2_create(tree, mem_ctx, &create);
    7037           2 :         CHECK_STATUS(status, NT_STATUS_OK);
    7038             : 
    7039           2 :         status = smb2_util_write(tree, create.out.file.handle, "foo", 0, 3);
    7040           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    7041             :                                         "smb2_util_write failed\n");
    7042             : 
    7043           2 :         smb2_util_close(tree, create.out.file.handle);
    7044             : 
    7045           2 :         ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt",
    7046             :                                         "user.DosStream.bar:baz:$DATA",
    7047             :                                         "data", strlen("data"));
    7048           2 :         CHECK_VALUE(ret, true);
    7049             : 
    7050           2 :         ret = check_stream_list(tree, tctx, fname, 3, streams, false);
    7051           2 :         CHECK_VALUE(ret, true);
    7052             : 
    7053           4 : done:
    7054           2 :         status = smb2_util_unlink(tree, fname);
    7055           2 :         smb2_deltree(tree, BASEDIR);
    7056           2 :         talloc_free(mem_ctx);
    7057             : 
    7058           2 :         return ret;
    7059             : }
    7060             : 
    7061           2 : static bool test_fruit_locking_conflict(struct torture_context *tctx,
    7062             :                                         struct smb2_tree *tree,
    7063             :                                         struct smb2_tree *tree2)
    7064             : {
    7065             :         TALLOC_CTX *mem_ctx;
    7066             :         struct smb2_create create;
    7067             :         struct smb2_handle h;
    7068             :         struct smb2_lock lck;
    7069             :         struct smb2_lock_element el;
    7070           2 :         const char *fname = BASEDIR "\\locking_conflict.txt";
    7071             :         NTSTATUS status;
    7072           2 :         bool ret = false;
    7073             : 
    7074           2 :         mem_ctx = talloc_new(tctx);
    7075           2 :         torture_assert_not_null(tctx, mem_ctx, "talloc_new failed");
    7076             : 
    7077             :         /* clean slate ...*/
    7078           2 :         smb2_util_unlink(tree, fname);
    7079           2 :         smb2_deltree(tree, fname);
    7080           2 :         smb2_deltree(tree, BASEDIR);
    7081             : 
    7082           2 :         status = torture_smb2_testdir(tree, BASEDIR, &h);
    7083           2 :         CHECK_STATUS(status, NT_STATUS_OK);
    7084           2 :         smb2_util_close(tree, h);
    7085             : 
    7086           2 :         create = (struct smb2_create) {
    7087             :                 .in.desired_access = SEC_RIGHTS_FILE_READ,
    7088             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    7089             :                 .in.share_access =
    7090             :                 NTCREATEX_SHARE_ACCESS_READ|
    7091             :                 NTCREATEX_SHARE_ACCESS_WRITE,
    7092             :                 .in.create_disposition = NTCREATEX_DISP_CREATE,
    7093             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
    7094             :                 .in.fname = fname,
    7095             :         };
    7096             : 
    7097           2 :         status = smb2_create(tree, mem_ctx, &create);
    7098           2 :         CHECK_STATUS(status, NT_STATUS_OK);
    7099           2 :         h = create.out.file.handle;
    7100             : 
    7101             :         /* Add AD_FILELOCK_RSRC_DENY_WR lock. */
    7102           2 :         el = (struct smb2_lock_element) {
    7103             :                 .offset = 0xfffffffffffffffc,
    7104             :                 .length = 1,
    7105             :                 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
    7106             :         };
    7107           2 :         lck = (struct smb2_lock) {
    7108             :                 .in.lock_count = 1,
    7109             :                 .in.file.handle = h,
    7110             :                 .in.locks = &el,
    7111             :         };
    7112             : 
    7113             :         /*
    7114             :          * Lock up to and including:
    7115             :          * AD_FILELOCK_OPEN_WR
    7116             :          * AD_FILELOCK_OPEN_RD
    7117             :          * This is designed to cause a NetAtalk
    7118             :          * locking conflict on the next open,
    7119             :          * even though the share modes are
    7120             :          * compatible.
    7121             :          */
    7122           2 :         status = smb2_lock(tree, &lck);
    7123           2 :         CHECK_STATUS(status, NT_STATUS_OK);
    7124             : 
    7125           2 :         el = (struct smb2_lock_element) {
    7126             :                 .offset = 0,
    7127             :                 .length = 0x7ffffffffffffff7,
    7128             :                 .flags = SMB2_LOCK_FLAG_EXCLUSIVE,
    7129             :         };
    7130           2 :         status = smb2_lock(tree, &lck);
    7131           2 :         CHECK_STATUS(status, NT_STATUS_OK);
    7132             : 
    7133           2 :         create = (struct smb2_create) {
    7134             :                 .in.desired_access =
    7135             :                 SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
    7136             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    7137             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
    7138             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    7139             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
    7140             :                 .in.fname = fname,
    7141             :         };
    7142             : 
    7143             :         /*
    7144             :          * Open on the second tree - ensure we are
    7145             :          * emulating trying to access with a NetATalk
    7146             :          * process with an existing open/deny mode.
    7147             :          */
    7148           2 :         status = smb2_create(tree2, mem_ctx, &create);
    7149           2 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
    7150             : 
    7151             :         {
    7152           2 :                 struct smb2_close cl = {
    7153             :                         .level = RAW_CLOSE_SMB2,
    7154             :                         .in.file.handle = h,
    7155             :                 };
    7156           2 :                 smb2_close(tree, &cl);
    7157             :         }
    7158             : 
    7159           2 :         ret = true;
    7160           2 : done:
    7161           2 :         return ret;
    7162             : }
    7163             : 
    7164        2355 : struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
    7165             : {
    7166        2355 :         struct torture_suite *suite = torture_suite_create(
    7167             :                 ctx, "fruit_netatalk");
    7168             : 
    7169        2355 :         suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
    7170             : 
    7171        2355 :         torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
    7172        2355 :         torture_suite_add_1smb2_test(suite, "stream names with locally created xattr", test_stream_names_local);
    7173        2355 :         torture_suite_add_2smb2_test(
    7174             :                 suite, "locking conflict", test_fruit_locking_conflict);
    7175             : 
    7176        2355 :         return suite;
    7177             : }
    7178             : 
    7179        2355 : struct torture_suite *torture_vfs_fruit_file_id(TALLOC_CTX *ctx)
    7180             : {
    7181        1897 :         struct torture_suite *suite =
    7182         458 :             torture_suite_create(ctx, "fruit_file_id");
    7183             : 
    7184        2355 :         suite->description =
    7185        2355 :             talloc_strdup(suite, "vfs_fruit tests for on-disk file ID that "
    7186             :                                  "require fruit:zero_file_id=yes");
    7187             : 
    7188        2355 :         torture_suite_add_1smb2_test(suite, "zero file id if AAPL negotiated",
    7189             :                                      test_zero_file_id);
    7190             : 
    7191        2355 :         return suite;
    7192             : }
    7193             : 
    7194           2 : static bool test_timemachine_volsize(struct torture_context *tctx,
    7195             :                                      struct smb2_tree *tree)
    7196             : {
    7197           2 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    7198           2 :         struct smb2_handle h = {{0}};
    7199             :         union smb_fsinfo fsinfo;
    7200             :         NTSTATUS status;
    7201           2 :         bool ok = true;
    7202           2 :         const char *info_plist =
    7203             :                 "<dict>\n"
    7204             :                 "        <key>band-size</key>\n"
    7205             :                 "        <integer>8192</integer>\n"
    7206             :                 "</dict>\n";
    7207             : 
    7208           2 :         smb2_deltree(tree, "test.sparsebundle");
    7209             : 
    7210           2 :         ok = enable_aapl(tctx, tree);
    7211           2 :         torture_assert_goto(tctx, ok, ok, done, "enable_aapl failed");
    7212             : 
    7213           2 :         status = smb2_util_mkdir(tree, "test.sparsebundle");
    7214           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
    7215             :                                         "smb2_util_mkdir\n");
    7216             : 
    7217           2 :         ok = write_stream(tree, __location__, tctx, mem_ctx,
    7218             :                           "test.sparsebundle/Info.plist", NULL,
    7219             :                            0, strlen(info_plist), info_plist);
    7220           2 :         torture_assert_goto(tctx, ok, ok, done, "write_stream failed\n");
    7221             : 
    7222           2 :         status = smb2_util_mkdir(tree, "test.sparsebundle/bands");
    7223           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
    7224             :                                         "smb2_util_mkdir\n");
    7225             : 
    7226           2 :         ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/1", false);
    7227           2 :         torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
    7228             : 
    7229           2 :         ok = torture_setup_file(tctx, tree, "test.sparsebundle/bands/2", false);
    7230           2 :         torture_assert_goto(tctx, ok, ok, done, "torture_setup_file failed\n");
    7231             : 
    7232           2 :         status = smb2_util_roothandle(tree, &h);
    7233           2 :         torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
    7234             : 
    7235           2 :         ZERO_STRUCT(fsinfo);
    7236           2 :         fsinfo.generic.level = RAW_QFS_SIZE_INFORMATION;
    7237           2 :         fsinfo.generic.handle = h;
    7238             : 
    7239           2 :         status = smb2_getinfo_fs(tree, tree, &fsinfo);
    7240           2 :         torture_assert_ntstatus_ok(tctx, status, "smb2_getinfo_fs failed");
    7241             : 
    7242           2 :         torture_comment(tctx, "sectors_per_unit: %" PRIu32"\n"
    7243             :                         "bytes_per_sector: %" PRIu32"\n"
    7244             :                         "total_alloc_units: %" PRIu64"\n"
    7245             :                         "avail_alloc_units: %" PRIu64"\n",
    7246             :                         fsinfo.size_info.out.sectors_per_unit,
    7247             :                         fsinfo.size_info.out.bytes_per_sector,
    7248             :                         fsinfo.size_info.out.total_alloc_units,
    7249             :                         fsinfo.size_info.out.avail_alloc_units);
    7250             : 
    7251             :         /*
    7252             :          * Let me explain the numbers:
    7253             :          *
    7254             :          * - the share is set to "fruit:time machine max size = 32K"
    7255             :          * - we've faked a bandsize of 8 K in the Info.plist file
    7256             :          * - we've created two bands files
    7257             :          * - one allocation unit is made of two sectors with 512 B each
    7258             :          * => we've consumed 16 allocation units, there should be 16 free
    7259             :          */
    7260             : 
    7261           2 :         torture_assert_goto(tctx, fsinfo.size_info.out.sectors_per_unit == 2,
    7262             :                             ok, done, "Bad sectors_per_unit");
    7263             : 
    7264           2 :         torture_assert_goto(tctx, fsinfo.size_info.out.bytes_per_sector == 512,
    7265             :                             ok, done, "Bad bytes_per_sector");
    7266             : 
    7267           2 :         torture_assert_goto(tctx, fsinfo.size_info.out.total_alloc_units == 32,
    7268             :                             ok, done, "Bad total_alloc_units");
    7269             : 
    7270           2 :         torture_assert_goto(tctx, fsinfo.size_info.out.avail_alloc_units == 16,
    7271             :                             ok, done, "Bad avail_alloc_units");
    7272             : 
    7273           4 : done:
    7274           2 :         if (!smb2_util_handle_empty(h)) {
    7275           2 :                 smb2_util_close(tree, h);
    7276             :         }
    7277           2 :         smb2_deltree(tree, "test.sparsebundle");
    7278           2 :         talloc_free(mem_ctx);
    7279           2 :         return ok;
    7280             : }
    7281             : 
    7282        2355 : struct torture_suite *torture_vfs_fruit_timemachine(TALLOC_CTX *ctx)
    7283             : {
    7284        2355 :         struct torture_suite *suite = torture_suite_create(
    7285             :                 ctx, "fruit_timemachine");
    7286             : 
    7287        2355 :         suite->description = talloc_strdup(
    7288             :                 suite, "vfs_fruit tests for TimeMachine");
    7289             : 
    7290        2355 :         torture_suite_add_1smb2_test(suite, "Timemachine-volsize",
    7291             :                                      test_timemachine_volsize);
    7292             : 
    7293        2355 :         return suite;
    7294             : }
    7295             : 
    7296           4 : static bool test_convert_xattr_and_empty_rfork_then_delete(
    7297             :         struct torture_context *tctx,
    7298             :         struct smb2_tree *tree1,
    7299             :         struct smb2_tree *tree2)
    7300             : {
    7301           4 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    7302           4 :         const char *fname = BASEDIR "\\test_adouble_conversion";
    7303           4 :         const char *adname = BASEDIR "/._test_adouble_conversion";
    7304           4 :         const char *rfork = BASEDIR "\\test_adouble_conversion" AFPRESOURCE_STREAM_NAME;
    7305             :         NTSTATUS status;
    7306             :         struct smb2_handle testdirh;
    7307           4 :         bool ret = true;
    7308           4 :         const char *streams[] = {
    7309             :                 "::$DATA",
    7310             :                 AFPINFO_STREAM,
    7311             :                 ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
    7312             :                 ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
    7313             :         };
    7314             :         struct smb2_create create;
    7315             :         struct smb2_find find;
    7316             :         unsigned int count;
    7317             :         union smb_search_data *d;
    7318             :         bool delete_empty_adfiles;
    7319             :         int expected_num_files;
    7320             : 
    7321           4 :         delete_empty_adfiles = torture_setting_bool(tctx,
    7322             :                                                     "delete_empty_adfiles",
    7323             :                                                     false);
    7324             : 
    7325           4 :         smb2_deltree(tree1, BASEDIR);
    7326             : 
    7327           4 :         status = torture_smb2_testdir(tree1, BASEDIR, &testdirh);
    7328           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    7329             :                                         "torture_smb2_testdir failed\n");
    7330           4 :         smb2_util_close(tree1, testdirh);
    7331             : 
    7332           4 :         ret = torture_setup_file(tctx, tree1, fname, false);
    7333           4 :         torture_assert_goto(tctx, ret == true, ret, done,
    7334             :                             "torture_setup_file failed\n");
    7335             : 
    7336           4 :         ret = torture_setup_file(tctx, tree1, adname, false);
    7337           4 :         torture_assert_goto(tctx, ret == true, ret, done,
    7338             :                             "torture_setup_file failed\n");
    7339             : 
    7340           4 :         ret = write_stream(tree1, __location__, tctx, mem_ctx,
    7341             :                            adname, NULL,
    7342             :                            0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
    7343           4 :         torture_assert_goto(tctx, ret == true, ret, done,
    7344             :                             "write_stream failed\n");
    7345             : 
    7346           4 :         ret = enable_aapl(tctx, tree2);
    7347           4 :         torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
    7348             : 
    7349             :         /*
    7350             :          * Issue a smb2_find(), this triggers the server-side conversion
    7351             :          */
    7352             : 
    7353           4 :         create = (struct smb2_create) {
    7354             :                 .in.desired_access = SEC_RIGHTS_DIR_READ,
    7355             :                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
    7356             :                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
    7357             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
    7358             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    7359             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
    7360             :                 .in.fname = BASEDIR,
    7361             :         };
    7362             : 
    7363           4 :         status = smb2_create(tree2, tctx, &create);
    7364           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    7365             :                                         "smb2_create failed\n");
    7366             : 
    7367           4 :         find = (struct smb2_find) {
    7368             :                 .in.file.handle = create.out.file.handle,
    7369             :                 .in.pattern = "*",
    7370             :                 .in.max_response_size = 0x1000,
    7371             :                 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
    7372             :         };
    7373             : 
    7374           4 :         status = smb2_find_level(tree2, tree2, &find, &count, &d);
    7375           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    7376             :                                         "smb2_find_level failed\n");
    7377             : 
    7378           4 :         status = smb2_util_close(tree2, create.out.file.handle);
    7379           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    7380             :                                         "smb2_util_close failed");
    7381             : 
    7382             :         /*
    7383             :          * Check number of streams
    7384             :          */
    7385             : 
    7386           4 :         ret = check_stream_list(tree2, tctx, fname, 4, streams, false);
    7387           4 :         torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
    7388             : 
    7389             :         /*
    7390             :          * Check Resource Fork is gone
    7391             :          */
    7392             : 
    7393           4 :         create = (struct smb2_create) {
    7394             :                 .in.desired_access = SEC_RIGHTS_FILE_READ|SEC_RIGHTS_FILE_WRITE,
    7395             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    7396             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
    7397             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    7398             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
    7399             :                 .in.fname = rfork,
    7400             :         };
    7401             : 
    7402           4 :         status = smb2_create(tree2, mem_ctx, &create);
    7403           4 :         torture_assert_ntstatus_equal_goto(
    7404             :                 tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
    7405             :                 ret, done, "Bad smb2_create return\n");
    7406             : 
    7407             :         /*
    7408             :          * Check xattr data has been migrated from the AppleDouble file to
    7409             :          * streams.
    7410             :          */
    7411             : 
    7412           4 :         ret = check_stream(tree2, __location__, tctx, mem_ctx,
    7413             :                            fname, AFPINFO_STREAM,
    7414             :                            0, 60, 16, 8, "TESTSLOW");
    7415           4 :         torture_assert_goto(tctx, ret == true, ret, done,
    7416             :                             "check AFPINFO_STREAM failed\n");
    7417             : 
    7418           4 :         ret = check_stream(tree2, __location__, tctx, mem_ctx,
    7419             :                            fname, ":foo" "\xef\x80\xa2" "bar", /* foo:bar */
    7420             :                            0, 3, 0, 3, "baz");
    7421           4 :         torture_assert_goto(tctx, ret == true, ret, done,
    7422             :                             "check foo stream failed\n");
    7423             : 
    7424             :         /*
    7425             :          * Now check number of files. If delete_empty_adfiles is set, the
    7426             :          * AppleDouble files should have been deleted.
    7427             :          */
    7428             : 
    7429           4 :         create = (struct smb2_create) {
    7430             :                 .in.desired_access = SEC_RIGHTS_DIR_READ,
    7431             :                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
    7432             :                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
    7433             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_READ,
    7434             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    7435             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
    7436             :                 .in.fname = BASEDIR,
    7437             :         };
    7438             : 
    7439           4 :         status = smb2_create(tree2, tctx, &create);
    7440           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    7441             :                                         "smb2_create failed\n");
    7442             : 
    7443           4 :         find = (struct smb2_find) {
    7444             :                 .in.file.handle = create.out.file.handle,
    7445             :                 .in.pattern = "*",
    7446             :                 .in.max_response_size = 0x1000,
    7447             :                 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
    7448             :         };
    7449             : 
    7450           4 :         status = smb2_find_level(tree2, tree2, &find, &count, &d);
    7451           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    7452             :                                         "smb2_find_level failed\n");
    7453             : 
    7454           4 :         status = smb2_util_close(tree2, create.out.file.handle);
    7455           4 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    7456             :                                         "smb2_util_close failed");
    7457             : 
    7458           4 :         if (delete_empty_adfiles) {
    7459           2 :                 expected_num_files = 3;
    7460             :         } else {
    7461           2 :                 expected_num_files = 4;
    7462             :         }
    7463           4 :         torture_assert_int_equal_goto(tctx, count, expected_num_files, ret, done,
    7464             :                                       "Wrong number of files\n");
    7465             : 
    7466           8 : done:
    7467           4 :         smb2_deltree(tree1, BASEDIR);
    7468           4 :         talloc_free(mem_ctx);
    7469           4 :         return ret;
    7470             : }
    7471             : 
    7472        2355 : struct torture_suite *torture_vfs_fruit_conversion(TALLOC_CTX *ctx)
    7473             : {
    7474        2355 :         struct torture_suite *suite = torture_suite_create(
    7475             :                 ctx, "fruit_conversion");
    7476             : 
    7477        2355 :         suite->description = talloc_strdup(
    7478             :                 suite, "vfs_fruit conversion tests");
    7479             : 
    7480        2355 :         torture_suite_add_2ns_smb2_test(
    7481             :                 suite, "convert_xattr_and_empty_rfork_then_delete",
    7482             :                 test_convert_xattr_and_empty_rfork_then_delete);
    7483             : 
    7484        2355 :         return suite;
    7485             : }
    7486             : 
    7487             : /*
    7488             :  * The buf below contains the following AppleDouble encoded data:
    7489             :  *
    7490             :  * -----------------------------------------------------------------------------
    7491             :  * MagicNumber: 00051607                                        : AppleDouble
    7492             :  * Version    : 00020000                                        : Version 2
    7493             :  * Filler     : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
    7494             :  * Num. of ent: 0002                                            : 2
    7495             :  *
    7496             :  * -----------------------------------------------------------------------------
    7497             :  * Entry ID   : 00000002 : Resource Fork
    7498             :  * Offset     : 0000009A : 154
    7499             :  * Length     : 00000004 : 4
    7500             :  *
    7501             :  * -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
    7502             :  * 00000000   : 62 61 72 00                                     : bar.
    7503             :  *
    7504             :  * -----------------------------------------------------------------------------
    7505             :  * Entry ID   : 00000009 : Finder Info
    7506             :  * Offset     : 00000032 : 50
    7507             :  * Length     : 00000068 : 104
    7508             :  *
    7509             :  * -FInfo-----:
    7510             :  * Type       : 464F4F20 : FOO
    7511             :  * Creator    : 42415220 : BAR
    7512             :  * isAlias    : 0
    7513             :  * Invisible  : 0
    7514             :  * hasBundle  : 0
    7515             :  * nameLocked : 0
    7516             :  * Stationery : 0
    7517             :  * CustomIcon : 0
    7518             :  * Reserved   : 0
    7519             :  * Inited     : 0
    7520             :  * NoINITS    : 0
    7521             :  * Shared     : 0
    7522             :  * SwitchLaunc: 0
    7523             :  * Hidden Ext : 0
    7524             :  * color      : 000      : none
    7525             :  * isOnDesk   : 0
    7526             :  * Location v : 0000     : 0
    7527             :  * Location h : 0000     : 0
    7528             :  * Fldr       : 0000     : ..
    7529             :  *
    7530             :  * -FXInfo----:
    7531             :  * Rsvd|IconID: 0000     : 0
    7532             :  * Rsvd       : 0000     : ..
    7533             :  * Rsvd       : 0000     : ..
    7534             :  * Rsvd       : 0000     : ..
    7535             :  * AreInvalid : 0
    7536             :  * unknown bit: 0
    7537             :  * unknown bit: 0
    7538             :  * unknown bit: 0
    7539             :  * unknown bit: 0
    7540             :  * unknown bit: 0
    7541             :  * unknown bit: 0
    7542             :  * CustomBadge: 0
    7543             :  * ObjctIsBusy: 0
    7544             :  * unknown bit: 0
    7545             :  * unknown bit: 0
    7546             :  * unknown bit: 0
    7547             :  * unknown bit: 0
    7548             :  * RoutingInfo: 0
    7549             :  * unknown bit: 0
    7550             :  * unknown bit: 0
    7551             :  * Rsvd|commnt: 0000     : 0
    7552             :  * PutAway    : 00000000 : 0
    7553             :  *
    7554             :  * -EA--------:
    7555             :  * pad        : 0000     :
    7556             :  * magic      : 41545452 : ATTR
    7557             :  * debug_tag  : 00000000 : 0
    7558             :  * total_size : 0000009A : 154
    7559             :  * data_start : 00000096 : 150
    7560             :  * data_length: 00000004 : 4
    7561             :  * reserved[0]: 00000000 : ....
    7562             :  * reserved[1]: 00000000 : ....
    7563             :  * reserved[2]: 00000000 : ....
    7564             :  * flags      : 0000     : ..
    7565             :  * num_attrs  : 0001     : 1
    7566             :  * -EA ENTRY--:
    7567             :  * offset     : 00000096 : 150
    7568             :  * length     : 00000004 : 4
    7569             :  * flags      : 0000     : ..
    7570             :  * namelen    : 13       : 19
    7571             :  * -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
    7572             :  * 00000000   : 6F 72 67 2E 73 61 6D 62 61 EF 80 A2 77 6F 6F 68 : org.samba...wooh
    7573             :  * 00000010   : 6F 6F 00                                        : oo.
    7574             :  * -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
    7575             :  * 00000000   : 62 61 72 00                                     : bar.
    7576             :  *
    7577             :  * -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
    7578             :  * 00000000   : 46 4F 4F 20 42 41 52 20 00 00 00 00 00 00 00 00 : FOO BAR ........
    7579             :  * 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
    7580             :  * 00000020   : 00 00 41 54 54 52 00 00 00 00 00 00 00 9A 00 00 : baATTR..........
    7581             :  * 00000030   : 00 96 00 00 00 04 00 00 00 00 00 00 00 00 00 00 : ................
    7582             :  * 00000040   : 00 00 00 00 00 01 00 00 00 96 00 00 00 04 00 00 : ................
    7583             :  * 00000050   : 13 6F 72 67 2E 73 61 6D 62 61 EF 80 A2 77 6F 6F : .org.samba...woo
    7584             :  * 00000060   : 68 6F 6F 00 62 61 72 00                         : hoo.bar.
    7585             :  *
    7586             :  * It was created with:
    7587             :  *
    7588             :  * $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
    7589             :  */
    7590             : static char unconvert_adfile_data[] = {
    7591             :         0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
    7592             :         0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
    7593             :         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    7594             :         0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
    7595             :         0x00, 0x98, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
    7596             :         0x00, 0x09, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00,
    7597             :         0x00, 0x66, 0x46, 0x4f, 0x4f, 0x20, 0x42, 0x41,
    7598             :         0x52, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    7599             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    7600             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    7601             :         0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
    7602             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
    7603             :         0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x04,
    7604             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    7605             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    7606             :         0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x04,
    7607             :         0x00, 0x00, 0x11, 0x6f, 0x72, 0x67, 0x2e, 0x73,
    7608             :         0x61, 0x6d, 0x62, 0x61, 0x3a, 0x77, 0x6f, 0x6f,
    7609             :         0x68, 0x6f, 0x6f, 0x00, 0x62, 0x61, 0x72, 0x00,
    7610             :         0x62, 0x61, 0x72, 0x00
    7611             : };
    7612             : 
    7613           6 : static bool test_unconvert(struct torture_context *tctx,
    7614             :                            struct smb2_tree *tree1,
    7615             :                            struct smb2_tree *tree2)
    7616             : {
    7617           6 :         const char *fname = BASEDIR "\\unconvert";
    7618           6 :         const char *adname = BASEDIR "\\._unconvert";
    7619           6 :         const char *net = NULL;
    7620           6 :         const char *share = NULL;
    7621           6 :         AfpInfo *afpi = NULL;
    7622           6 :         char *cmd = NULL;
    7623             :         struct smb2_handle h1;
    7624             :         union smb_fileinfo finfo;
    7625             :         size_t adsize;
    7626             :         NTSTATUS status;
    7627             :         int result;
    7628           6 :         bool ret = true;
    7629             : 
    7630           6 :         torture_assert_not_null_goto(tctx, tree2, ret, done,
    7631             :                                      "Need a second share without fruit\n");
    7632             : 
    7633           6 :         net = torture_setting_string(tctx, "net", NULL);
    7634           6 :         torture_assert_not_null_goto(tctx, net, ret, done,
    7635             :                                      "Need path to 'net'");
    7636             : 
    7637           6 :         share = torture_setting_string(tctx, "sharename", NULL);
    7638           6 :         torture_assert_not_null_goto(tctx, share, ret, done,
    7639             :                                      "Need sharename");
    7640             : 
    7641           6 :         torture_comment(tctx, "Testing unconvert\n");
    7642             : 
    7643           6 :         smb2_deltree(tree1, BASEDIR);
    7644             : 
    7645           6 :         status = torture_smb2_testdir(tree1, BASEDIR, &h1);
    7646           6 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    7647             :                                         "torture_smb2_testdir\n");
    7648           6 :         smb2_util_close(tree1, h1);
    7649             : 
    7650           6 :         ret = torture_setup_file(tctx, tree1, fname, false);
    7651           6 :         torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
    7652             : 
    7653           6 :         afpi = torture_afpinfo_new(tctx);
    7654           6 :         torture_assert_not_null_goto(tctx, afpi, ret, done,
    7655             :                                      "torture_afpinfo_new failed\n");
    7656             : 
    7657           6 :         memcpy(afpi->afpi_FinderInfo, "FOO BAR ", 8);
    7658             : 
    7659           6 :         ret = torture_write_afpinfo(tree1, tctx, tctx, fname, afpi);
    7660           6 :         torture_assert_goto(tctx, ret == true, ret, done,
    7661             :                             "torture_write_afpinfo failed\n");
    7662             : 
    7663           6 :         ret = write_stream(tree1, __location__, tctx, tctx,
    7664             :                            fname,
    7665             :                            /*
    7666             :                             * \xef\x80\xa2 is ':' mapped to Unicoe private range
    7667             :                             */
    7668             :                            ":org.samba" "\xef\x80\xa2" "woohoo",
    7669             :                            0, 4, "bar");
    7670           6 :         torture_assert_goto(tctx, ret == true, ret, done,
    7671             :                             "write_stream failed\n");
    7672             : 
    7673           6 :         ret = write_stream(tree1, __location__, tctx, tctx,
    7674             :                            fname, AFPRESOURCE_STREAM_NAME,
    7675             :                            0, 4, "bar");
    7676           6 :         torture_assert_goto(tctx, ret == true, ret, done,
    7677             :                             "write_stream failed\n");
    7678             : 
    7679           6 :         cmd = talloc_asprintf(tctx,
    7680             :                               "%s --recursive vfs stream2adouble %s %s/",
    7681             :                               net,
    7682             :                               share,
    7683             :                               BASEDIR);
    7684           6 :         torture_assert_not_null_goto(tctx, cmd, ret, done,
    7685             :                                      "talloc_asprintf failed\n");
    7686             : 
    7687           6 :         torture_comment(tctx, "cmd: %s\n", cmd);
    7688             : 
    7689           6 :         result = system(cmd);
    7690           6 :         torture_assert_int_equal_goto(tctx, result, 0, ret, done,
    7691             :                             "command failed\n");
    7692             : 
    7693           6 :         status = torture_smb2_testfile(tree2, adname, &h1);
    7694           6 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    7695             :                                         "torture_smb2_testfile failed\n");
    7696             : 
    7697           6 :         finfo = (union smb_fileinfo) {
    7698             :                 .generic.level = RAW_FILEINFO_ALL_INFORMATION,
    7699             :                 .generic.in.file.handle = h1,
    7700             :         };
    7701             : 
    7702           6 :         status = smb2_getinfo_file(tree2, tctx, &finfo);
    7703           6 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    7704             :                                         "torture_smb2_testdir\n");
    7705           6 :         smb2_util_close(tree2, h1);
    7706             : 
    7707           6 :         adsize = finfo.all_info.out.size;
    7708           6 :         torture_assert_int_equal_goto(tctx, adsize,
    7709             :                                       sizeof(unconvert_adfile_data),
    7710             :                                       ret, done, "wrong size\n");
    7711             : 
    7712           6 :         ret = check_stream(tree2, __location__, tctx, tctx,
    7713             :                            adname, "", 0, adsize, 0, adsize,
    7714             :                            unconvert_adfile_data);
    7715           6 :         torture_assert_goto(tctx, ret == true, ret, done,
    7716             :                             "check_stream failed\n");
    7717             : 
    7718          12 : done:
    7719             : //      smb2_deltree(tree1, BASEDIR);
    7720           6 :         return ret;
    7721             : }
    7722             : 
    7723        2355 : struct torture_suite *torture_vfs_fruit_unfruit(TALLOC_CTX *ctx)
    7724             : {
    7725        2355 :         struct torture_suite *suite = torture_suite_create(
    7726             :                 ctx, "unfruit");
    7727             : 
    7728        2355 :         suite->description = talloc_strdup(
    7729             :                 suite, "test converting back to AppleDouble");
    7730             : 
    7731        2355 :         torture_suite_add_2ns_smb2_test(suite,
    7732             :                                         "unconvert",
    7733             :                                         test_unconvert);
    7734             : 
    7735        2355 :         return suite;
    7736             : }

Generated by: LCOV version 1.13