/* Unix SMB/CIFS implementation. vfs_fruit tests Copyright (C) Ralph Boehme 2014 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "includes.h" #include "system/filesys.h" #include "libcli/libcli.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" #include "libcli/smb/smb2_create_ctx.h" #include "lib/cmdline/popt_common.h" #include "param/param.h" #include "libcli/resolve/resolve.h" #include "MacExtensions.h" #include "torture/torture.h" #include "torture/util.h" #include "torture/smb2/proto.h" #include "torture/vfs/proto.h" #define BASEDIR "vfs_fruit_dir" #define CHECK_STATUS(status, correct) do { \ if (!NT_STATUS_EQUAL(status, correct)) { \ torture_result(tctx, TORTURE_FAIL, \ "(%s) Incorrect status %s - should be %s\n", \ __location__, nt_errstr(status), nt_errstr(correct)); \ ret = false; \ goto done; \ }} while (0) /* * REVIEW: * This is hokey, but what else can we do? */ #if defined(HAVE_ATTROPEN) || defined(FREEBSD) #define AFPINFO_EA_NETATALK "org.netatalk.Metadata" #define AFPRESOURCE_EA_NETATALK "org.netatalk.ResourceFork" #else #define AFPINFO_EA_NETATALK "user.org.netatalk.Metadata" #define AFPRESOURCE_EA_NETATALK "user.org.netatalk.ResourceFork" #endif /* The metadata xattr char buf below contains the following attributes: ------------------------------------------------------------------------------- Entry ID : 00000008 : File Dates Info Offset : 00000162 : 354 Length : 00000010 : 16 -DATE------: : (GMT) : (Local) create : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014 modify : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014 backup : 80000000 : Unknown or Initial access : 1B442169 : Mon Jun 30 13:23:53 2014 : Mon Jun 30 15:23:53 2014 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII) 00000000 : 1B 44 21 69 1B 44 21 69 80 00 00 00 1B 44 21 69 : .D!i.D!i.....D!i ------------------------------------------------------------------------------- Entry ID : 00000009 : Finder Info Offset : 0000007A : 122 Length : 00000020 : 32 -FInfo-----: Type : 42415252 : BARR Creator : 464F4F4F : FOOO isAlias : 0 Invisible : 1 hasBundle : 0 nameLocked : 0 Stationery : 0 CustomIcon : 0 Reserved : 0 Inited : 0 NoINITS : 0 Shared : 0 SwitchLaunc: 0 Hidden Ext : 0 color : 000 : none isOnDesk : 0 Location v : 0000 : 0 Location h : 0000 : 0 Fldr : 0000 : .. -FXInfo----: Rsvd|IconID: 0000 : 0 Rsvd : 0000 : .. Rsvd : 0000 : .. Rsvd : 0000 : .. AreInvalid : 0 unknown bit: 0 unknown bit: 0 unknown bit: 0 unknown bit: 0 unknown bit: 0 unknown bit: 0 CustomBadge: 0 ObjctIsBusy: 0 unknown bit: 0 unknown bit: 0 unknown bit: 0 unknown bit: 0 RoutingInfo: 0 unknown bit: 0 unknown bit: 0 Rsvd|commnt: 0000 : 0 PutAway : 00000000 : 0 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII) 00000000 : 42 41 52 52 46 4F 4F 4F 40 00 00 00 00 00 00 00 : BARRFOOO@....... 00000010 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................ ------------------------------------------------------------------------------- Entry ID : 0000000E : AFP File Info Offset : 00000172 : 370 Length : 00000004 : 4 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII) 00000000 : 00 00 01 A1 : .... */ char metadata_xattr[] = { 0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x72, 0x00, 0x00, 0x00, 0x04, 0x80, 0x44, 0x45, 0x56, 0x00, 0x00, 0x01, 0x76, 0x00, 0x00, 0x00, 0x08, 0x80, 0x49, 0x4e, 0x4f, 0x00, 0x00, 0x01, 0x7e, 0x00, 0x00, 0x00, 0x08, 0x80, 0x53, 0x59, 0x4e, 0x00, 0x00, 0x01, 0x86, 0x00, 0x00, 0x00, 0x08, 0x80, 0x53, 0x56, 0x7e, 0x00, 0x00, 0x01, 0x8e, 0x00, 0x00, 0x00, 0x04, 0x42, 0x41, 0x52, 0x52, 0x46, 0x4f, 0x4f, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x44, 0x21, 0x69, 0x1b, 0x44, 0x21, 0x69, 0x80, 0x00, 0x00, 0x00, 0x1b, 0x44, 0x21, 0x69, 0x00, 0x00, 0x01, 0xa1, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xe3, 0x86, 0x53, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x01, 0x00, 0x00 }; /* The buf below contains the following AppleDouble encoded data: ------------------------------------------------------------------------------- MagicNumber: 00051607 : AppleDouble Version : 00020000 : Version 2 Filler : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X Num. of ent: 0002 : 2 ------------------------------------------------------------------------------- Entry ID : 00000009 : Finder Info Offset : 00000032 : 50 Length : 00000EB0 : 3760 -FInfo-----: Type : 54455854 : TEXT Creator : 21526368 : !Rch ... -EA--------: pad : 0000 : .. magic : 41545452 : ATTR debug_tag : 0007F98E : 522638 total_size : 00000EE2 : 3810 data_start : 00000078 : 120 data_length: 00000000 : 0 reserved[0]: 00000000 : .... reserved[1]: 00000000 : .... reserved[2]: 00000000 : .... flags : 0000 : .. num_attrs : 0000 : 0 ------------------------------------------------------------------------------- Entry ID : 00000002 : Resource Fork Offset : 00000EE2 : 3810 Length : 0000011E : 286 -RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII) 00000000 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................ 00000010 : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo 00000020 : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally 00000030 : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 : left blank .. ... 00000110 : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF : .............. */ static char osx_adouble_w_xattr[] = { 0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00, 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0e, 0xb0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00, 0x01, 0x1e, 0x54, 0x45, 0x58, 0x54, 0x21, 0x52, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52, 0x00, 0x07, 0xf9, 0x8e, 0x00, 0x00, 0x0e, 0xe2, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x54, 0x68, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0xff, 0xff }; /** * talloc and intialize an AfpInfo **/ static AfpInfo *torture_afpinfo_new(TALLOC_CTX *mem_ctx) { AfpInfo *info; info = talloc_zero(mem_ctx, AfpInfo); if (info == NULL) { return NULL; } info->afpi_Signature = AFP_Signature; info->afpi_Version = AFP_Version; info->afpi_BackupTime = AFP_BackupTime; return info; } /** * Pack AfpInfo into a talloced buffer **/ static char *torture_afpinfo_pack(TALLOC_CTX *mem_ctx, AfpInfo *info) { char *buf; buf = talloc_array(mem_ctx, char, AFP_INFO_SIZE); if (buf == NULL) { return NULL; } RSIVAL(buf, 0, info->afpi_Signature); RSIVAL(buf, 4, info->afpi_Version); RSIVAL(buf, 12, info->afpi_BackupTime); memcpy(buf + 16, info->afpi_FinderInfo, sizeof(info->afpi_FinderInfo)); return buf; } /** * Unpack AfpInfo **/ #if 0 static void torture_afpinfo_unpack(AfpInfo *info, char *data) { info->afpi_Signature = RIVAL(data, 0); info->afpi_Version = RIVAL(data, 4); info->afpi_BackupTime = RIVAL(data, 12); memcpy(info->afpi_FinderInfo, (const char *)data + 16, sizeof(info->afpi_FinderInfo)); } #endif static bool torture_write_afpinfo(struct smb2_tree *tree, struct torture_context *tctx, TALLOC_CTX *mem_ctx, const char *fname, AfpInfo *info) { struct smb2_handle handle; struct smb2_create io; NTSTATUS status; const char *full_name; char *infobuf; bool ret = true; full_name = talloc_asprintf(mem_ctx, "%s%s", fname, AFPINFO_STREAM); if (full_name == NULL) { torture_comment(tctx, "talloc_asprintf error\n"); return false; } ZERO_STRUCT(io); io.in.desired_access = SEC_FILE_WRITE_DATA; io.in.file_attributes = FILE_ATTRIBUTE_NORMAL; io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF; io.in.create_options = 0; io.in.fname = full_name; status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); handle = io.out.file.handle; infobuf = torture_afpinfo_pack(mem_ctx, info); if (infobuf == NULL) { return false; } status = smb2_util_write(tree, handle, infobuf, 0, AFP_INFO_SIZE); CHECK_STATUS(status, NT_STATUS_OK); smb2_util_close(tree, handle); done: return ret; } /** * Read 'count' bytes at 'offset' from stream 'fname:sname' and * compare against buffer 'value' **/ static bool check_stream(struct smb2_tree *tree, const char *location, struct torture_context *tctx, TALLOC_CTX *mem_ctx, const char *fname, const char *sname, off_t read_offset, size_t read_count, off_t comp_offset, size_t comp_count, const char *value) { struct smb2_handle handle; struct smb2_create create; struct smb2_read r; NTSTATUS status; const char *full_name; full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname); if (full_name == NULL) { torture_comment(tctx, "talloc_asprintf error\n"); return false; } ZERO_STRUCT(create); create.in.desired_access = SEC_FILE_READ_DATA; create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; create.in.create_disposition = NTCREATEX_DISP_OPEN; create.in.fname = full_name; torture_comment(tctx, "Open stream %s\n", full_name); status = smb2_create(tree, mem_ctx, &create); if (!NT_STATUS_IS_OK(status)) { if (value == NULL) { return true; } else { torture_comment(tctx, "Unable to open stream %s\n", full_name); sleep(10000000); return false; } } handle = create.out.file.handle; if (value == NULL) { return true; } ZERO_STRUCT(r); r.in.file.handle = handle; r.in.length = read_count; r.in.offset = read_offset; status = smb2_read(tree, tree, &r); if (!NT_STATUS_IS_OK(status)) { torture_comment(tctx, "(%s) Failed to read %lu bytes from " "stream '%s'\n", location, (long)strlen(value), full_name); return false; } if (memcmp(r.out.data.data + comp_offset, value, comp_count) != 0) { torture_comment(tctx, "(%s) Bad data in stream\n", location); return false; } smb2_util_close(tree, handle); return true; } /** * Read 'count' bytes at 'offset' from stream 'fname:sname' and * compare against buffer 'value' **/ static bool write_stream(struct smb2_tree *tree, const char *location, struct torture_context *tctx, TALLOC_CTX *mem_ctx, const char *fname, const char *sname, off_t offset, size_t size, const char *value) { struct smb2_handle handle; struct smb2_create create; NTSTATUS status; const char *full_name; full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname); if (full_name == NULL) { torture_comment(tctx, "talloc_asprintf error\n"); return false; } ZERO_STRUCT(create); create.in.desired_access = SEC_FILE_WRITE_DATA; create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; create.in.create_disposition = NTCREATEX_DISP_OPEN_IF; create.in.fname = full_name; status = smb2_create(tree, mem_ctx, &create); if (!NT_STATUS_IS_OK(status)) { if (value == NULL) { return true; } else { torture_comment(tctx, "Unable to open stream %s\n", full_name); sleep(10000000); return false; } } handle = create.out.file.handle; if (value == NULL) { return true; } status = smb2_util_write(tree, handle, value, offset, size); if (!NT_STATUS_IS_OK(status)) { torture_comment(tctx, "(%s) Failed to write %lu bytes to " "stream '%s'\n", location, (long)size, full_name); return false; } smb2_util_close(tree, handle); return true; } static bool torture_setup_local_xattr(struct torture_context *tctx, const char *path_option, const char *name, const char *metadata, size_t size) { int ret = true; int result; const char *spath; char *path; spath = torture_setting_string(tctx, path_option, NULL); if (spath == NULL) { printf("No sharepath for option %s\n", path_option); return false; } path = talloc_asprintf(tctx, "%s/%s", spath, name); result = setxattr(path, AFPINFO_EA_NETATALK, metadata, size, 0); if (result != 0) { ret = false; } TALLOC_FREE(path); return ret; } static bool torture_setup_local_file(struct torture_context *tctx, const char *path_option, const char *name, const char *buf, size_t size) { int fd; const char *spath; char *path; ssize_t rsize; spath = torture_setting_string(tctx, path_option, NULL); if (spath == NULL) { printf("No sharepath for option %s\n", path_option); return false; } path = talloc_asprintf(tctx, "%s/%s", spath, name); if (path == NULL) { return false; } fd = creat(path, S_IRWXU); TALLOC_FREE(path); if (fd == -1) { return false; } if ((buf == NULL) || (size == 0)) { close(fd); return true; } rsize = write(fd, buf, size); if (rsize != size) { return false; } close(fd); return true; } /** * Create a file or directory **/ static bool torture_setup_file(TALLOC_CTX *mem_ctx, struct smb2_tree *tree, const char *name, bool dir) { struct smb2_create io; NTSTATUS status; smb2_util_unlink(tree, name); ZERO_STRUCT(io); io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; io.in.file_attributes = FILE_ATTRIBUTE_NORMAL; io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF; io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE| NTCREATEX_SHARE_ACCESS_READ| NTCREATEX_SHARE_ACCESS_WRITE; io.in.create_options = 0; io.in.fname = name; if (dir) { io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE; io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; io.in.create_disposition = NTCREATEX_DISP_CREATE; } status = smb2_create(tree, mem_ctx, &io); if (!NT_STATUS_IS_OK(status)) { return false; } status = smb2_util_close(tree, io.out.file.handle); if (!NT_STATUS_IS_OK(status)) { return false; } return true; } static bool test_read_atalk_metadata(struct torture_context *tctx, struct smb2_tree *tree1, struct smb2_tree *tree2) { TALLOC_CTX *mem_ctx = talloc_new(tctx); const char *fname = BASEDIR "\\torture_read_metadata"; NTSTATUS status; struct smb2_handle testdirh; bool ret = true; torture_comment(tctx, "Checking metadata access\n"); smb2_util_unlink(tree1, fname); status = torture_smb2_testdir(tree1, BASEDIR, &testdirh); CHECK_STATUS(status, NT_STATUS_OK); smb2_util_close(tree1, testdirh); ret = torture_setup_file(mem_ctx, tree1, fname, false); if (ret == false) { goto done; } ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/torture_read_metadata", metadata_xattr, sizeof(metadata_xattr)); if (ret == false) { goto done; } ret &= check_stream(tree1, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM, 0, 60, 0, 4, "AFP"); ret &= check_stream(tree1, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM, 0, 60, 16, 8, "BARRFOOO"); done: smb2_deltree(tree1, BASEDIR); talloc_free(mem_ctx); return ret; } static bool test_write_atalk_metadata(struct torture_context *tctx, struct smb2_tree *tree1, struct smb2_tree *tree2) { TALLOC_CTX *mem_ctx = talloc_new(tctx); const char *fname = BASEDIR "\\torture_write_metadata"; const char *type_creator = "SMB,OLE!"; NTSTATUS status; struct smb2_handle testdirh; bool ret = true; AfpInfo *info; smb2_util_unlink(tree1, fname); status = torture_smb2_testdir(tree1, BASEDIR, &testdirh); CHECK_STATUS(status, NT_STATUS_OK); smb2_util_close(tree1, testdirh); ret = torture_setup_file(mem_ctx, tree1, fname, false); if (ret == false) { goto done; } info = torture_afpinfo_new(mem_ctx); if (info == NULL) { goto done; } memcpy(info->afpi_FinderInfo, type_creator, 8); ret = torture_write_afpinfo(tree1, tctx, mem_ctx, fname, info); ret &= check_stream(tree1, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM, 0, 60, 16, 8, type_creator); done: smb2_deltree(tree1, BASEDIR); talloc_free(mem_ctx); return ret; } static bool test_write_atalk_rfork_io(struct torture_context *tctx, struct smb2_tree *tree1, struct smb2_tree *tree2) { TALLOC_CTX *mem_ctx = talloc_new(tctx); const char *fname = BASEDIR "\\torture_write_rfork_io"; const char *rfork = BASEDIR "\\torture_write_rfork_io" AFPRESOURCE_STREAM; const char *rfork_content = "1234567890"; NTSTATUS status; struct smb2_handle testdirh; bool ret = true; union smb_open io; struct smb2_handle filehandle; union smb_fileinfo finfo; union smb_setfileinfo sinfo; smb2_util_unlink(tree1, fname); status = torture_smb2_testdir(tree1, BASEDIR, &testdirh); CHECK_STATUS(status, NT_STATUS_OK); smb2_util_close(tree1, testdirh); ret = torture_setup_file(mem_ctx, tree1, fname, false); if (ret == false) { goto done; } torture_comment(tctx, "(%s) writing to resource fork\n", __location__); ret &= write_stream(tree1, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM, 10, 10, rfork_content); ret &= check_stream(tree1, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM, 0, 20, 10, 10, rfork_content); /* Check size after write */ ZERO_STRUCT(io); io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN; io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE; io.smb2.in.fname = rfork; status = smb2_create(tree1, mem_ctx, &(io.smb2)); CHECK_STATUS(status, NT_STATUS_OK); filehandle = io.smb2.out.file.handle; torture_comment(tctx, "(%s) check resource fork size after write\n", __location__); ZERO_STRUCT(finfo); finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION; finfo.generic.in.file.handle = filehandle; status = smb2_getinfo_file(tree1, mem_ctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); if (finfo.all_info.out.size != 20) { torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect resource fork size\n", __location__); ret = false; smb2_util_close(tree1, filehandle); goto done; } smb2_util_close(tree1, filehandle); /* Write at large offset */ torture_comment(tctx, "(%s) writing to resource fork at large offset\n", __location__); ret &= write_stream(tree1, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM, (off_t)1<<32, 10, rfork_content); ret &= check_stream(tree1, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM, (off_t)1<<32, 10, 0, 10, rfork_content); /* Truncate back to size of 1 byte */ torture_comment(tctx, "(%s) truncate resource fork and check size\n", __location__); ZERO_STRUCT(io); io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN; io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE; io.smb2.in.fname = rfork; status = smb2_create(tree1, mem_ctx, &(io.smb2)); CHECK_STATUS(status, NT_STATUS_OK); filehandle = io.smb2.out.file.handle; ZERO_STRUCT(sinfo); sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; sinfo.end_of_file_info.in.file.handle = filehandle; sinfo.end_of_file_info.in.size = 1; status = smb2_setinfo_file(tree1, &sinfo); CHECK_STATUS(status, NT_STATUS_OK); smb2_util_close(tree1, filehandle); /* Now check size */ ZERO_STRUCT(io); io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN; io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE; io.smb2.in.fname = rfork; status = smb2_create(tree1, mem_ctx, &(io.smb2)); CHECK_STATUS(status, NT_STATUS_OK); filehandle = io.smb2.out.file.handle; ZERO_STRUCT(finfo); finfo.generic.level = RAW_FILEINFO_ALL_INFORMATION; finfo.generic.in.file.handle = filehandle; status = smb2_getinfo_file(tree1, mem_ctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); if (finfo.all_info.out.size != 1) { torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect resource fork size\n", __location__); ret = false; smb2_util_close(tree1, filehandle); goto done; } smb2_util_close(tree1, filehandle); done: smb2_deltree(tree1, BASEDIR); talloc_free(mem_ctx); return ret; } static bool test_adouble_conversion(struct torture_context *tctx, struct smb2_tree *tree1, struct smb2_tree *tree2) { TALLOC_CTX *mem_ctx = talloc_new(tctx); const char *fname = BASEDIR "\\test_adouble_conversion"; const char *fname_local = BASEDIR "/test_adouble_conversion"; const char *adname_local = BASEDIR "/._test_adouble_conversion"; NTSTATUS status; struct smb2_handle testdirh; bool ret = true; const char *data = "This resource fork intentionally left blank"; size_t datalen = strlen(data); smb2_util_unlink(tree1, fname); status = torture_smb2_testdir(tree1, BASEDIR, &testdirh); CHECK_STATUS(status, NT_STATUS_OK); smb2_util_close(tree1, testdirh); ret = torture_setup_local_file(tctx, "localdir", fname_local, NULL, 0); if (ret == false) { goto done; } ret = torture_setup_local_file(tctx, "localdir", adname_local, osx_adouble_w_xattr, sizeof(osx_adouble_w_xattr)); if (ret == false) { goto done; } torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n", __location__); ret &= check_stream(tree1, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM, 16, datalen, 0, datalen, data); done: smb2_deltree(tree1, BASEDIR); talloc_free(mem_ctx); return ret; } static bool test_aapl(struct torture_context *tctx, struct smb2_tree *tree1, struct smb2_tree *tree2) { TALLOC_CTX *mem_ctx = talloc_new(tctx); const char *fname = BASEDIR "\\test_aapl"; NTSTATUS status; struct smb2_handle testdirh; bool ret = true; struct smb2_create io; DATA_BLOB data; struct smb2_create_blob *aapl = NULL; AfpInfo *info; const char *type_creator = "SMB,OLE!"; char type_creator_buf[9]; uint32_t aapl_cmd; uint32_t aapl_reply_bitmap; uint32_t aapl_server_caps; uint32_t aapl_vol_caps; char *model; struct smb2_find f; unsigned int count; union smb_search_data *d; uint64_t rfork_len; smb2_deltree(tree1, BASEDIR); status = torture_smb2_testdir(tree1, BASEDIR, &testdirh); CHECK_STATUS(status, NT_STATUS_OK); smb2_util_close(tree1, testdirh); ZERO_STRUCT(io); io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; io.in.file_attributes = FILE_ATTRIBUTE_NORMAL; io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF; io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE | NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE); io.in.fname = fname; /* * Issuing an SMB2/CREATE with a suitably formed AAPL context, * controls behaviour of Apple's SMB2 extensions for the whole * session! */ data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t)); SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY); SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS | SMB2_CRTCTX_AAPL_VOLUME_CAPS | SMB2_CRTCTX_AAPL_MODEL_INFO)); SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR | SMB2_CRTCTX_AAPL_UNIX_BASED | SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE)); torture_comment(tctx, "Testing SMB2 create context AAPL\n"); status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data); CHECK_STATUS(status, NT_STATUS_OK); status = smb2_create(tree1, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); status = smb2_util_close(tree1, io.out.file.handle); CHECK_STATUS(status, NT_STATUS_OK); /* * Now check returned AAPL context */ torture_comment(tctx, "Comparing returned AAPL capabilites\n"); aapl = smb2_create_blob_find(&io.out.blobs, SMB2_CREATE_TAG_AAPL); if (aapl->data.length != 50) { /* * uint32_t CommandCode = kAAPL_SERVER_QUERY * uint32_t Reserved = 0; * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS | * kAAPL_VOLUME_CAPS | * kAAPL_MODEL_INFO; * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR | * kAAPL_SUPPORTS_OSX_COPYFILE; * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID | * kAAPL_CASE_SENSITIVE; * uint32_t Pad2 = 0; * uint32_t ModelStringLen = 10; * ucs2_t ModelString[5] = "Samba"; */ ret = false; goto done; } aapl_cmd = IVAL(aapl->data.data, 0); if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) { torture_result(tctx, TORTURE_FAIL, "(%s) unexpected cmd: %d", __location__, (int)aapl_cmd); ret = false; goto done; } aapl_reply_bitmap = BVAL(aapl->data.data, 8); if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS | SMB2_CRTCTX_AAPL_VOLUME_CAPS | SMB2_CRTCTX_AAPL_MODEL_INFO)) { torture_result(tctx, TORTURE_FAIL, "(%s) unexpected reply_bitmap: %d", __location__, (int)aapl_reply_bitmap); ret = false; goto done; } aapl_server_caps = BVAL(aapl->data.data, 16); if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED | SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR | SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE)) { torture_result(tctx, TORTURE_FAIL, "(%s) unexpected server_caps: %d", __location__, (int)aapl_server_caps); ret = false; goto done; } aapl_vol_caps = BVAL(aapl->data.data, 24); if (aapl_vol_caps != SMB2_CRTCTX_AAPL_CASE_SENSITIVE) { /* this will fail on a case insensitive fs ... */ torture_result(tctx, TORTURE_FAIL, "(%s) unexpected vol_caps: %d", __location__, (int)aapl_vol_caps); ret = false; goto done; } ret = convert_string_talloc(mem_ctx, CH_UTF16LE, CH_UNIX, aapl->data.data + 40, 10, &model, NULL); if (ret == false) { torture_result(tctx, TORTURE_FAIL, "(%s) convert_string_talloc() failed", __location__); goto done; } if (strncmp(model, "Samba", 5) != 0) { torture_result(tctx, TORTURE_FAIL, "(%s) expected model \"Samba\", got: \"%s\"", __location__, model); ret = false; goto done; } /* * Now that Requested AAPL extensions are enabled, setup some * Mac files with metadata and resource fork */ ret = torture_setup_file(mem_ctx, tree1, fname, false); if (ret == false) { torture_result(tctx, TORTURE_FAIL, "(%s) torture_setup_file() failed", __location__); goto done; } info = torture_afpinfo_new(mem_ctx); if (info == NULL) { torture_result(tctx, TORTURE_FAIL, "(%s) torture_afpinfo_new() failed", __location__); ret = false; goto done; } memcpy(info->afpi_FinderInfo, type_creator, 8); ret = torture_write_afpinfo(tree1, tctx, mem_ctx, fname, info); if (ret == false) { torture_result(tctx, TORTURE_FAIL, "(%s) torture_write_afpinfo() failed", __location__); goto done; } ret = write_stream(tree1, __location__, tctx, mem_ctx, fname, AFPRESOURCE_STREAM, 0, 3, "foo"); if (ret == false) { torture_result(tctx, TORTURE_FAIL, "(%s) write_stream() failed", __location__); goto done; } /* * Ok, file is prepared, now call smb2/find */ ZERO_STRUCT(io); io.in.desired_access = SEC_RIGHTS_DIR_ALL; io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE); io.in.create_disposition = NTCREATEX_DISP_OPEN; io.in.fname = BASEDIR; status = smb2_create(tree1, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); ZERO_STRUCT(f); f.in.file.handle = io.out.file.handle; f.in.pattern = "test_aapl"; f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE; f.in.max_response_size = 0x1000; f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO; status = smb2_find_level(tree1, tree1, &f, &count, &d); CHECK_STATUS(status, NT_STATUS_OK); status = smb2_util_close(tree1, io.out.file.handle); CHECK_STATUS(status, NT_STATUS_OK); if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) { torture_result(tctx, TORTURE_FAIL, "(%s) write_stream() failed", __location__); ret = false; goto done; } if (d[0].id_both_directory_info.short_name.private_length != 24) { torture_result(tctx, TORTURE_FAIL, "(%s) bad short_name length %" PRIu32 ", expected 24", __location__, d[0].id_both_directory_info.short_name.private_length); ret = false; goto done; } torture_comment(tctx, "short_name buffer:\n"); dump_data(0, d[0].id_both_directory_info.short_name_buf, 24); /* * Extract data as specified by the AAPL extension: * - ea_size contains max_access * - short_name contains resource fork length + FinderInfo * - reserved2 contains the unix mode */ torture_comment(tctx, "mac_access: %" PRIx32 "\n", d[0].id_both_directory_info.ea_size); rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0); if (rfork_len != 3) { torture_result(tctx, TORTURE_FAIL, "(%s) expected resource fork length 3, got: %" PRIu64, __location__, rfork_len); ret = false; goto done; } memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8); type_creator_buf[8] = 0; if (strcmp(type_creator, type_creator_buf) != 0) { torture_result(tctx, TORTURE_FAIL, "(%s) expected type/creator \"%s\" , got: %s", __location__, type_creator, type_creator_buf); ret = false; goto done; } done: talloc_free(mem_ctx); return ret; } /* * Note: This test depends on "vfs objects = catia fruit * streams_xattr". Note: To run this test, use * "--option=torture:share1= * --option=torture:share2= * --option=torture:localdir=" */ struct torture_suite *torture_vfs_fruit(void) { struct torture_suite *suite = torture_suite_create( talloc_autofree_context(), "fruit"); suite->description = talloc_strdup(suite, "vfs_fruit tests"); torture_suite_add_2ns_smb2_test(suite, "read metadata", test_read_atalk_metadata); torture_suite_add_2ns_smb2_test(suite, "write metadata", test_write_atalk_metadata); torture_suite_add_2ns_smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io); torture_suite_add_2ns_smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion); torture_suite_add_2ns_smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl); return suite; }