r11758: unified the parse code for the SMB and SMB2 qfsinfo and qfileinfo calls
authorAndrew Tridgell <tridge@samba.org>
Thu, 17 Nov 2005 11:06:13 +0000 (11:06 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:46:23 +0000 (13:46 -0500)
(This used to be commit ba897e537b9a1544dc214e9d5504c87fee6fced2)

source4/include/smb_interfaces.h
source4/include/trans2.h
source4/libcli/raw/rawfileinfo.c
source4/libcli/smb2/getinfo.c
source4/libcli/smb2/smb2_calls.h
source4/torture/smb2/getinfo.c
source4/torture/smb2/util.c

index f0781341949d838cf9d8c2a93c0ccc8dd96e66f2..c6635251a249a146a122d0f816fb157fecc7aa59 100644 (file)
@@ -315,7 +315,6 @@ enum smb_fileinfo_level {
                     RAW_FILEINFO_ACCESS_INFORMATION         = SMB_QFILEINFO_ACCESS_INFORMATION,
                     RAW_FILEINFO_NAME_INFORMATION           = SMB_QFILEINFO_NAME_INFORMATION,
                     RAW_FILEINFO_POSITION_INFORMATION       = SMB_QFILEINFO_POSITION_INFORMATION,
-                    RAW_FILEINFO_FULL_EA_INFORMATION        = SMB_QFILEINFO_FULL_EA_INFORMATION,
                     RAW_FILEINFO_MODE_INFORMATION           = SMB_QFILEINFO_MODE_INFORMATION,
                     RAW_FILEINFO_ALIGNMENT_INFORMATION      = SMB_QFILEINFO_ALIGNMENT_INFORMATION,
                     RAW_FILEINFO_ALL_INFORMATION            = SMB_QFILEINFO_ALL_INFORMATION,
@@ -323,7 +322,17 @@ enum smb_fileinfo_level {
                     RAW_FILEINFO_STREAM_INFORMATION         = SMB_QFILEINFO_STREAM_INFORMATION,
                     RAW_FILEINFO_COMPRESSION_INFORMATION    = SMB_QFILEINFO_COMPRESSION_INFORMATION,
                     RAW_FILEINFO_NETWORK_OPEN_INFORMATION   = SMB_QFILEINFO_NETWORK_OPEN_INFORMATION,
-                    RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION  = SMB_QFILEINFO_ATTRIBUTE_TAG_INFORMATION
+                    RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION  = SMB_QFILEINFO_ATTRIBUTE_TAG_INFORMATION,
+                    /* SMB2 specific levels */
+                    RAW_FILEINFO_SMB2_ALL_EAS               = 0x0f01,
+                    RAW_FILEINFO_SMB2_ALL_INFORMATION       = 0x1201
+};
+
+/*
+  file handles in SMB2 are 16 bytes
+*/
+struct smb2_handle {
+       uint64_t data[2];
 };
 
 
@@ -335,11 +344,14 @@ union smb_fileinfo {
                enum smb_fileinfo_level level;
 
                /* each level can be called on either a pathname or a
-                * filename, in either case the return format is
-                * identical */
+                  filename, in either case the return format is
+                  identical 
+                  On SMB2 a 16 byte handle is used 
+               */
                union smb_fileinfo_in {
                        const char *fname;
                        uint16_t fnum;
+                       struct smb2_handle handle;
                } in;
                
                struct {
@@ -445,7 +457,7 @@ union smb_fileinfo {
                } out;
        } ea_list;
 
-       /* trans2 RAW_FILEINFO_ALL_EAS interface */
+       /* trans2 RAW_FILEINFO_ALL_EAS and RAW_FILEINFO_FULL_EA_INFORMATION interfaces */
        struct {
                enum smb_fileinfo_level level;
                union smb_fileinfo_in in;
@@ -530,6 +542,33 @@ union smb_fileinfo {
                } out;
        } all_info;     
 
+       /* RAW_FILEINFO_SMB2_ALL_INFORMATION interface */
+       struct {
+               enum smb_fileinfo_level level;
+               union smb_fileinfo_in in;
+
+               struct {
+                       NTTIME   create_time;
+                       NTTIME   access_time;
+                       NTTIME   write_time;
+                       NTTIME   change_time;
+                       uint32_t attrib;
+                       uint32_t unknown1;
+                       uint64_t alloc_size;
+                       uint64_t size;
+                       uint32_t nlink;
+                       uint8_t  delete_pending;
+                       uint8_t  directory;
+                       /* uint16_t _pad; */
+                       uint64_t file_id;
+                       uint32_t ea_size;
+                       uint32_t access_mask;
+                       uint64_t unknown2;
+                       uint64_t unknown3;
+                       WIRE_STRING fname;
+               } out;
+       } all_info2;    
+
        /* RAW_FILEINFO_ALT_NAME_INFO and RAW_FILEINFO_ALT_NAME_INFORMATION interfaces */
        struct {
                enum smb_fileinfo_level level;
@@ -917,6 +956,7 @@ union smb_fsinfo {
        /* generic interface */
        struct {
                enum smb_fsinfo_level level;
+               struct smb2_handle handle; /* only for smb2 */
 
                struct {
                        uint32_t block_size;
@@ -976,6 +1016,7 @@ union smb_fsinfo {
        /* TRANS2 RAW_QFS_VOLUME_INFO and RAW_QFS_VOLUME_INFORMATION interfaces */
        struct {
                enum smb_fsinfo_level level;
+               struct smb2_handle handle; /* only for smb2 */
 
                struct {
                        NTTIME create_time;
@@ -987,6 +1028,7 @@ union smb_fsinfo {
        /* trans2 RAW_QFS_SIZE_INFO and RAW_QFS_SIZE_INFORMATION interfaces */
        struct {
                enum smb_fsinfo_level level;
+               struct smb2_handle handle; /* only for smb2 */
 
                struct {
                        uint64_t total_alloc_units;
@@ -999,6 +1041,7 @@ union smb_fsinfo {
        /* TRANS2 RAW_QFS_DEVICE_INFO and RAW_QFS_DEVICE_INFORMATION interfaces */
        struct {
                enum smb_fsinfo_level level;
+               struct smb2_handle handle; /* only for smb2 */
 
                struct {
                        uint32_t device_type;
@@ -1010,6 +1053,7 @@ union smb_fsinfo {
        /* TRANS2 RAW_QFS_ATTRIBUTE_INFO and RAW_QFS_ATTRIBUTE_INFORMATION interfaces */
        struct {
                enum smb_fsinfo_level level;
+               struct smb2_handle handle; /* only for smb2 */
 
                struct {
                        uint32_t fs_attr;
@@ -1033,6 +1077,7 @@ union smb_fsinfo {
        /* trans2 RAW_QFS_QUOTA_INFORMATION interface */
        struct {
                enum smb_fsinfo_level level;
+               struct smb2_handle handle; /* only for smb2 */
 
                struct {
                        uint64_t unknown[3];
@@ -1045,6 +1090,7 @@ union smb_fsinfo {
        /* trans2 RAW_QFS_FULL_SIZE_INFORMATION interface */
        struct {
                enum smb_fsinfo_level level;
+               struct smb2_handle handle; /* only for smb2 */
 
                struct {
                        uint64_t total_alloc_units;
@@ -1058,6 +1104,7 @@ union smb_fsinfo {
        /* trans2 RAW_QFS_OBJECTID_INFORMATION interface */
        struct {
                enum smb_fsinfo_level level;
+               struct smb2_handle handle; /* only for smb2 */
 
                struct {
                        struct GUID  guid;
index 6768476e1d04c18f031da51d91fef79dab1b33d4..a3f6e28a2afafd7561191bb6512b5e3ffd0592bf 100644 (file)
@@ -147,7 +147,6 @@ Found 8 aliased levels
 #define SMB_QFILEINFO_ACCESS_INFORMATION               1008
 #define SMB_QFILEINFO_NAME_INFORMATION                 1009
 #define SMB_QFILEINFO_POSITION_INFORMATION             1014
-#define SMB_QFILEINFO_FULL_EA_INFORMATION              1015 /* only on SMB2 */
 #define SMB_QFILEINFO_MODE_INFORMATION                 1016
 #define SMB_QFILEINFO_ALIGNMENT_INFORMATION            1017
 #define SMB_QFILEINFO_ALL_INFORMATION                  1018
index 2edb6d5b4293e3877b42a7a2ae93082c768a5a30..7119eed5e7147d9da258008899f946210180eb81 100644 (file)
@@ -176,12 +176,6 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_
                parms->position_information.out.position = BVAL(blob->data, 0);
                return NT_STATUS_OK;
 
-       case RAW_FILEINFO_FULL_EA_INFORMATION:
-               FINFO_CHECK_MIN_SIZE(4);
-               return ea_pull_list_chained(blob, mem_ctx, 
-                                           &parms->all_eas.out.num_eas,
-                                           &parms->all_eas.out.eas);
-
        case RAW_FILEINFO_MODE_INFORMATION:
                FINFO_CHECK_SIZE(4);
                parms->mode_information.out.mode = IVAL(blob->data, 0);
@@ -220,6 +214,51 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_
                parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4);
                return NT_STATUS_OK;
 
+       case RAW_FILEINFO_SMB2_ALL_EAS:
+               FINFO_CHECK_MIN_SIZE(4);
+               return ea_pull_list_chained(blob, mem_ctx, 
+                                           &parms->all_eas.out.num_eas,
+                                           &parms->all_eas.out.eas);
+
+       case RAW_FILEINFO_SMB2_ALL_INFORMATION:
+               FINFO_CHECK_MIN_SIZE(0x64);
+               parms->all_info2.out.create_time    = smbcli_pull_nttime(blob->data, 0x00);
+               parms->all_info2.out.access_time    = smbcli_pull_nttime(blob->data, 0x08);
+               parms->all_info2.out.write_time     = smbcli_pull_nttime(blob->data, 0x10);
+               parms->all_info2.out.change_time    = smbcli_pull_nttime(blob->data, 0x18);
+               parms->all_info2.out.attrib         = IVAL(blob->data, 0x20);
+               parms->all_info2.out.unknown1       = IVAL(blob->data, 0x24);
+               parms->all_info2.out.alloc_size     = BVAL(blob->data, 0x28);
+               parms->all_info2.out.size           = BVAL(blob->data, 0x30);
+               parms->all_info2.out.nlink          = IVAL(blob->data, 0x38);
+               parms->all_info2.out.delete_pending = CVAL(blob->data, 0x3C);
+               parms->all_info2.out.directory      = CVAL(blob->data, 0x3D);
+               parms->all_info2.out.file_id        = BVAL(blob->data, 0x40);
+               parms->all_info2.out.ea_size        = IVAL(blob->data, 0x48);
+               parms->all_info2.out.access_mask    = IVAL(blob->data, 0x4C);
+               parms->all_info2.out.unknown2       = BVAL(blob->data, 0x50);
+               parms->all_info2.out.unknown3       = BVAL(blob->data, 0x58);
+               smbcli_blob_pull_string(NULL, mem_ctx, blob,
+                                       &parms->all_info2.out.fname, 0x60, 0x64, STR_UNICODE);
+               return NT_STATUS_OK;
+
+       case RAW_FILEINFO_SEC_DESC: {
+               struct ndr_pull *ndr;
+               NTSTATUS status;
+               ndr = ndr_pull_init_blob(blob, mem_ctx);
+               if (!ndr) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               parms->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor);
+               if (parms->query_secdesc.out.sd == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, 
+                                                     parms->query_secdesc.out.sd);
+               talloc_free(ndr);
+               return status;
+       }
+
        default:
                break;
        }
@@ -335,10 +374,6 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session,
                return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
                                                       RAW_FILEINFO_POSITION_INFORMATION, parms);
 
-       case RAW_FILEINFO_FULL_EA_INFORMATION:
-               return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
-                                                      RAW_FILEINFO_FULL_EA_INFORMATION, parms);
-
        case RAW_FILEINFO_MODE_INFORMATION:
                return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
                                                       RAW_FILEINFO_MODE_INFORMATION, parms);
@@ -381,6 +416,15 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session,
        case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
                return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
                                                       RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, parms);
+
+       case RAW_FILEINFO_SMB2_ALL_INFORMATION:
+               return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
+                                                      RAW_FILEINFO_SMB2_ALL_INFORMATION, parms);
+
+       case RAW_FILEINFO_SMB2_ALL_EAS:
+               return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, 
+                                                      RAW_FILEINFO_SMB2_ALL_EAS, parms);
+
        }
 
        return NT_STATUS_INVALID_LEVEL;
index fe27cc711b3083917f1f14b529e39c4b7a4f6117..cb8ce76a074de3cb385591407f2354a234497508 100644 (file)
@@ -41,8 +41,8 @@ struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getin
        SSVAL(req->out.body, 0x02, io->in.level);
        SIVAL(req->out.body, 0x04, io->in.max_response_size);
        SIVAL(req->out.body, 0x08, io->in.unknown1);
-       SIVAL(req->out.body, 0x0C, io->in.flags);
-       SIVAL(req->out.body, 0x10, io->in.unknown3);
+       SIVAL(req->out.body, 0x0C, io->in.unknown2);
+       SIVAL(req->out.body, 0x10, io->in.flags);
        SIVAL(req->out.body, 0x14, io->in.unknown4);
        smb2_push_handle(req->out.body+0x18, &io->in.handle);
 
@@ -87,203 +87,64 @@ NTSTATUS smb2_getinfo(struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
 
 
 /*
-  parse a returned getinfo data blob
+  recv a getinfo reply and parse the level info
 */
-NTSTATUS smb2_getinfo_parse(TALLOC_CTX *mem_ctx, 
-                           uint16_t level,
-                           DATA_BLOB blob,
-                           union smb2_fileinfo *io)
+NTSTATUS smb2_getinfo_file_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
+                               union smb_fileinfo *io)
 {
-       switch (level) {
-       case SMB2_GETINFO_FILE_BASIC_INFO:
-               if (blob.length != 0x28) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->basic_info.create_time = smbcli_pull_nttime(blob.data, 0x00);
-               io->basic_info.access_time = smbcli_pull_nttime(blob.data, 0x08);
-               io->basic_info.write_time  = smbcli_pull_nttime(blob.data, 0x10);
-               io->basic_info.change_time = smbcli_pull_nttime(blob.data, 0x18);
-               io->basic_info.file_attr   = IVAL(blob.data, 0x20);
-               io->basic_info.unknown     = IVAL(blob.data, 0x24);
-               break;
-
-       case SMB2_GETINFO_FILE_SIZE_INFO:
-               if (blob.length != 0x18) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->size_info.alloc_size     = BVAL(blob.data, 0x00);
-               io->size_info.size           = BVAL(blob.data, 0x08);
-               io->size_info.nlink          = IVAL(blob.data, 0x10);
-               io->size_info.delete_pending = CVAL(blob.data, 0x14);
-               io->size_info.directory      = CVAL(blob.data, 0x15);
-               break;
-
-       case SMB2_GETINFO_FILE_ID:
-               if (blob.length != 0x8) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->file_id.file_id = BVAL(blob.data, 0x00);
-               break;
-
-       case SMB2_GETINFO_FILE_EA_SIZE:
-               if (blob.length != 0x4) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->ea_size.ea_size = IVAL(blob.data, 0x00);
-               break;
-
-       case SMB2_GETINFO_FILE_ACCESS_INFO:
-               if (blob.length != 0x4) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->access_info.access_mask = IVAL(blob.data, 0x00);
-               break;
-
-       case SMB2_GETINFO_FILE_0E:
-               if (blob.length != 0x8) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->unknown0e.unknown1     = IVAL(blob.data, 0x00);
-               io->unknown0e.unknown2     = IVAL(blob.data, 0x04);
-               break;
-
-       case SMB2_GETINFO_FILE_ALL_EAS:
-               return ea_pull_list_chained(&blob, mem_ctx, 
-                                           &io->all_eas.num_eas,
-                                           &io->all_eas.eas);
-
-       case SMB2_GETINFO_FILE_10:
-               if (blob.length != 0x4) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->unknown10.unknown     = IVAL(blob.data, 0x00);
-               break;
-
-       case SMB2_GETINFO_FILE_11:
-               if (blob.length != 0x4) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->unknown11.unknown     = IVAL(blob.data, 0x00);
-               break;
-
-       case SMB2_GETINFO_FILE_ALL_INFO: {
-               uint32_t nlen;
-               ssize_t size;
-               void *vstr;
-               if (blob.length < 0x64) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->all_info.create_time    = smbcli_pull_nttime(blob.data, 0x00);
-               io->all_info.access_time    = smbcli_pull_nttime(blob.data, 0x08);
-               io->all_info.write_time     = smbcli_pull_nttime(blob.data, 0x10);
-               io->all_info.change_time    = smbcli_pull_nttime(blob.data, 0x18);
-               io->all_info.file_attr      = IVAL(blob.data, 0x20);
-               io->all_info.unknown1       = IVAL(blob.data, 0x24);
-               io->all_info.alloc_size     = BVAL(blob.data, 0x28);
-               io->all_info.size           = BVAL(blob.data, 0x30);
-               io->all_info.nlink          = IVAL(blob.data, 0x38);
-               io->all_info.delete_pending = CVAL(blob.data, 0x3C);
-               io->all_info.directory      = CVAL(blob.data, 0x3D);
-               io->all_info.file_id        = BVAL(blob.data, 0x40);
-               io->all_info.ea_size        = IVAL(blob.data, 0x48);
-               io->all_info.access_mask    = IVAL(blob.data, 0x4C);
-               io->all_info.unknown5       = BVAL(blob.data, 0x50);
-               io->all_info.unknown6       = BVAL(blob.data, 0x58);
-               nlen                        = IVAL(blob.data, 0x60);
-               if (nlen > blob.length - 0x64) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, 
-                                            blob.data+0x64, nlen, &vstr);
-               if (size == -1) {
-                       return NT_STATUS_ILLEGAL_CHARACTER;
-               }
-               io->all_info.fname = vstr;
-               break;
-       }
+       struct smb2_getinfo b;
+       NTSTATUS status;
 
-       case SMB2_GETINFO_FILE_SHORT_INFO: {
-               uint32_t nlen;
-               ssize_t size;
-               void *vstr;
-               if (blob.length < 0x04) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               nlen                     = IVAL(blob.data, 0x00);
-               if (nlen > blob.length - 0x04) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, 
-                                            blob.data+0x04, nlen, &vstr);
-               if (size == -1) {
-                       return NT_STATUS_ILLEGAL_CHARACTER;
-               }
-               io->short_info.short_name = vstr;
-               break;
-       }
+       status = smb2_getinfo_recv(req, mem_ctx, &b);
+       NT_STATUS_NOT_OK_RETURN(status);
 
-       case SMB2_GETINFO_FILE_STREAM_INFO:
-               return smbcli_parse_stream_info(blob, mem_ctx, &io->stream_info);
-
-       case SMB2_GETINFO_FILE_EOF_INFO:
-               if (blob.length != 0x10) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->eof_info.size     = BVAL(blob.data, 0x00);
-               io->eof_info.unknown  = BVAL(blob.data, 0x08);
-               break;
-
-       case SMB2_GETINFO_FILE_STANDARD_INFO:
-               if (blob.length != 0x38) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->standard_info.create_time = smbcli_pull_nttime(blob.data, 0x00);
-               io->standard_info.access_time = smbcli_pull_nttime(blob.data, 0x08);
-               io->standard_info.write_time  = smbcli_pull_nttime(blob.data, 0x10);
-               io->standard_info.change_time = smbcli_pull_nttime(blob.data, 0x18);
-               io->standard_info.alloc_size  = BVAL(blob.data, 0x20);
-               io->standard_info.size        = BVAL(blob.data, 0x28);
-               io->standard_info.file_attr   = IVAL(blob.data, 0x30);
-               io->standard_info.unknown     = IVAL(blob.data, 0x34);
-               break;
-
-       case SMB2_GETINFO_FILE_ATTRIB_INFO:
-               if (blob.length != 0x08) {
-                       return NT_STATUS_INFO_LENGTH_MISMATCH;
-               }
-               io->attrib_info.file_attr   = IVAL(blob.data, 0x00);
-               io->attrib_info.unknown     = IVAL(blob.data, 0x04);
-               break;
-
-       case SMB2_GETINFO_SECURITY: {
-               struct ndr_pull *ndr;
-               NTSTATUS status;
-               ndr = ndr_pull_init_blob(&blob, mem_ctx);
-               if (!ndr) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               io->security.sd = talloc(mem_ctx, struct security_descriptor);
-               if (io->security.sd == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               status = ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, io->security.sd);
-               talloc_free(ndr);
-               return status;
+       status = smb_raw_fileinfo_passthru_parse(&b.out.blob, mem_ctx, io->generic.level, io);
+       data_blob_free(&b.out.blob);
+
+       return status;
+}
+
+/*
+  level specific getinfo call
+*/
+NTSTATUS smb2_getinfo_file(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, 
+                          union smb_fileinfo *io)
+{
+       struct smb2_getinfo b;
+       struct smb2_request *req;
+       uint16_t smb2_level;
+
+       if (io->generic.level == RAW_FILEINFO_SEC_DESC) {
+               smb2_level = SMB2_GETINFO_SECURITY;
+       } else if ((io->generic.level & 0xFF) == SMB2_GETINFO_FILE) {
+               smb2_level = io->generic.level;
+       } else if (io->generic.level > 1000) {
+               smb2_level = ((io->generic.level-1000)<<8) | SMB2_GETINFO_FILE;
+       } else {
+               /* SMB2 only does the passthru levels */
+               return NT_STATUS_INVALID_LEVEL;
        }
-               
-       default:
-               return NT_STATUS_INVALID_INFO_CLASS;
+
+       ZERO_STRUCT(b);
+       b.in.max_response_size = 0x10000;
+       b.in.handle            = io->generic.in.handle;
+       b.in.level             = smb2_level;
+
+       if (io->generic.level == RAW_FILEINFO_SEC_DESC) {
+               b.in.flags = io->query_secdesc.secinfo_flags;
        }
 
-       return NT_STATUS_OK;
+       req = smb2_getinfo_send(tree, &b);
+       
+       return smb2_getinfo_file_recv(req, mem_ctx, io);
 }
 
 
 /*
   recv a getinfo reply and parse the level info
 */
-NTSTATUS smb2_getinfo_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
-                                uint16_t level, union smb2_fileinfo *io)
+NTSTATUS smb2_getinfo_fs_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
+                               union smb_fsinfo *io)
 {
        struct smb2_getinfo b;
        NTSTATUS status;
@@ -291,7 +152,7 @@ NTSTATUS smb2_getinfo_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
        status = smb2_getinfo_recv(req, mem_ctx, &b);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       status = smb2_getinfo_parse(mem_ctx, level, b.out.blob, io);
+       status = smb_raw_fsinfo_passthru_parse(b.out.blob, mem_ctx, io->generic.level, io);
        data_blob_free(&b.out.blob);
 
        return status;
@@ -300,19 +161,29 @@ NTSTATUS smb2_getinfo_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
 /*
   level specific getinfo call
 */
-NTSTATUS smb2_getinfo_level(struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
-                           struct smb2_handle handle,
-                           uint16_t level, union smb2_fileinfo *io)
+NTSTATUS smb2_getinfo_fs(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, 
+                          union smb_fsinfo *io)
 {
        struct smb2_getinfo b;
        struct smb2_request *req;
+       uint16_t smb2_level;
+       
+       if ((io->generic.level & 0xFF) == SMB2_GETINFO_FS) {
+               smb2_level = io->generic.level;
+       } else if (io->generic.level > 1000) {
+               smb2_level = ((io->generic.level-1000)<<8) | SMB2_GETINFO_FS;
+       } else {
+               /* SMB2 only does the passthru levels */
+               return NT_STATUS_INVALID_LEVEL;
+       }
 
        ZERO_STRUCT(b);
        b.in.max_response_size = 0x10000;
-       b.in.handle            = handle;
-       b.in.level             = level;
+       b.in.handle            = io->generic.handle;
+       b.in.level             = smb2_level;
 
        req = smb2_getinfo_send(tree, &b);
        
-       return smb2_getinfo_level_recv(req, mem_ctx, level, io);
+       return smb2_getinfo_fs_recv(req, mem_ctx, io);
 }
+
index 872e20f156c439af8e7d94f49faa266d212be0af..3ccb5309e5b2131f997cfe53c01b7e7fe61b3757 100644 (file)
@@ -103,14 +103,6 @@ struct smb2_tree_connect {
        } out;
 };
 
-/*
-  file handles in SMB2 are 16 bytes
-*/
-struct smb2_handle {
-       uint64_t data[2];
-};
-
-
 #define SMB2_CREATE_FLAG_REQUEST_OPLOCK           0x0100
 #define SMB2_CREATE_FLAG_REQUEST_EXCLUSIVE_OPLOCK 0x0800
 #define SMB2_CREATE_FLAG_GRANT_OPLOCK             0x0001
@@ -190,35 +182,14 @@ struct smb2_close {
        } out;
 };
 
-/* fs information levels */
-#define SMB2_GETINFO_FS_VOLUME_INFO     0x0102
-#define SMB2_GETINFO_FS_SIZE_INFO       0x0302
-#define SMB2_GETINFO_FS_DEVICE_INFO     0x0402
-#define SMB2_GETINFO_FS_ATTRIBUTE_INFO  0x0502
-#define SMB2_GETINFO_FS_QUOTA_INFO      0x0602
-#define SMB2_GETINFO_FS_FULL_SIZE_INFO  0x0702
-#define SMB2_GETINFO_FS_OBJECTID_INFO   0x0802
-
-/* class 3 levels */
-#define SMB2_GETINFO_SECURITY           0x0003
-
-/* file information levels */
-#define SMB2_GETINFO_FILE_BASIC_INFO    0x0401
-#define SMB2_GETINFO_FILE_SIZE_INFO     0x0501
-#define SMB2_GETINFO_FILE_ID            0x0601
-#define SMB2_GETINFO_FILE_EA_SIZE       0x0701
-#define SMB2_GETINFO_FILE_ACCESS_INFO   0x0801
-#define SMB2_GETINFO_FILE_0E            0x0e01
-#define SMB2_GETINFO_FILE_ALL_EAS       0x0f01
-#define SMB2_GETINFO_FILE_10            0x1001
-#define SMB2_GETINFO_FILE_11            0x1101
-#define SMB2_GETINFO_FILE_ALL_INFO      0x1201
-#define SMB2_GETINFO_FILE_SHORT_INFO    0x1501
-#define SMB2_GETINFO_FILE_STREAM_INFO   0x1601
-#define SMB2_GETINFO_FILE_EOF_INFO      0x1c01
-#define SMB2_GETINFO_FILE_STANDARD_INFO 0x2201
-#define SMB2_GETINFO_FILE_ATTRIB_INFO   0x2301
+/* getinfo classes */
+#define SMB2_GETINFO_FILE               0x01
+#define SMB2_GETINFO_FS                 0x02
+#define SMB2_GETINFO_SECURITY           0x03
 
+/* NOTE! the getinfo fs and file levels exactly match up with the
+   'passthru' SMB levels, which are levels >= 1000. The SMB2 client
+   lib uses the names from the libcli/raw/ library */
 
 struct smb2_getinfo {
        struct {
@@ -227,8 +198,8 @@ struct smb2_getinfo {
                uint16_t level;
                uint32_t max_response_size;
                uint32_t unknown1;
+               uint32_t unknown2;
                uint32_t flags; /* level specific */
-               uint32_t unknown3;
                uint32_t unknown4;
                struct smb2_handle handle;
        } in;
@@ -244,105 +215,6 @@ struct smb2_getinfo {
        } out;
 };
 
-union smb2_fileinfo {
-       struct {
-               NTTIME   create_time;
-               NTTIME   access_time;
-               NTTIME   write_time;
-               NTTIME   change_time;
-               uint32_t file_attr;
-               uint32_t unknown;
-       } basic_info;
-
-       struct {
-               uint64_t alloc_size;
-               uint64_t size;
-               uint32_t nlink;
-               uint8_t  delete_pending;
-               uint8_t  directory;
-       } size_info;
-
-       struct {
-               uint64_t file_id;
-       } file_id;
-
-       struct {
-               uint32_t ea_size;
-       } ea_size;
-
-       struct {
-               uint32_t access_mask;
-       } access_info;
-
-       struct {
-               uint32_t unknown1;
-               uint32_t unknown2;
-       } unknown0e;
-
-       struct smb_ea_list all_eas;
-
-       struct {
-               uint32_t unknown;
-       } unknown10;
-
-       struct {
-               uint32_t unknown;
-       } unknown11;
-
-       struct {
-               NTTIME   create_time;
-               NTTIME   access_time;
-               NTTIME   write_time;
-               NTTIME   change_time;
-               uint32_t file_attr;
-               uint32_t unknown1;
-               uint64_t alloc_size;
-               uint64_t size;
-               uint32_t nlink;
-               uint8_t  delete_pending;
-               uint8_t  directory;
-               /* uint16_t _pad; */
-               uint64_t file_id;
-               uint32_t ea_size;
-               uint32_t access_mask;
-               uint64_t unknown5;
-               uint64_t unknown6;
-               const char *fname;
-       } all_info;
-
-       struct {
-               const char *short_name;
-       } short_info;
-
-       struct stream_information stream_info;
-
-       struct {
-               uint64_t size;
-               uint64_t unknown;
-       } eof_info;
-
-       struct {
-               NTTIME   create_time;
-               NTTIME   access_time;
-               NTTIME   write_time;
-               NTTIME   change_time;
-               uint64_t alloc_size;
-               uint64_t size;
-               uint32_t file_attr;
-               uint32_t unknown;
-       } standard_info;
-
-       struct {
-               uint32_t file_attr;
-               uint32_t unknown;
-       } attrib_info;
-
-       struct {
-               struct security_descriptor *sd;
-       } security;
-};
-
-
 struct smb2_write {
        struct {
                /* static body buffer 48 (0x30) bytes */
index f175b19f893811f011e9b1fd5b3a41be975ca620..327ca8a12b5755841d5d9c2541e53882b1995ccf 100644 (file)
 #include "includes.h"
 #include "libcli/smb2/smb2.h"
 #include "libcli/smb2/smb2_calls.h"
+#include "librpc/gen_ndr/security.h"
 
 static struct {
        const char *name;
        uint16_t level;
        NTSTATUS fstatus;
        NTSTATUS dstatus;
-       union smb2_fileinfo finfo;
-       union smb2_fileinfo dinfo;
-} levels[] = {
+       union smb_fileinfo finfo;
+       union smb_fileinfo dinfo;
+} file_levels[] = {
 #define LEVEL(x) #x, x
-       { LEVEL(SMB2_GETINFO_FS_VOLUME_INFO) },
-       { LEVEL(SMB2_GETINFO_FS_SIZE_INFO) },
-       { LEVEL(SMB2_GETINFO_FS_DEVICE_INFO) },
-       { LEVEL(SMB2_GETINFO_FS_ATTRIBUTE_INFO) },
-       { LEVEL(SMB2_GETINFO_FS_QUOTA_INFO) },
-       { LEVEL(SMB2_GETINFO_FS_FULL_SIZE_INFO) },
-       { LEVEL(SMB2_GETINFO_FS_OBJECTID_INFO) },
-       { LEVEL(SMB2_GETINFO_SECURITY) },
-       { LEVEL(SMB2_GETINFO_FILE_BASIC_INFO) },
-       { LEVEL(SMB2_GETINFO_FILE_SIZE_INFO) },
-       { LEVEL(SMB2_GETINFO_FILE_ID) },
-       { LEVEL(SMB2_GETINFO_FILE_EA_SIZE) },
-       { LEVEL(SMB2_GETINFO_FILE_ACCESS_INFO) },
-       { LEVEL(SMB2_GETINFO_FILE_0E) },
-       { LEVEL(SMB2_GETINFO_FILE_ALL_EAS) },
-       { LEVEL(SMB2_GETINFO_FILE_10) },
-       { LEVEL(SMB2_GETINFO_FILE_11) },
-       { LEVEL(SMB2_GETINFO_FILE_ALL_INFO) },
-       { LEVEL(SMB2_GETINFO_FILE_SHORT_INFO) },
-       { LEVEL(SMB2_GETINFO_FILE_STREAM_INFO) },
-       { LEVEL(SMB2_GETINFO_FILE_EOF_INFO) },
-       { LEVEL(SMB2_GETINFO_FILE_STANDARD_INFO) },
-       { LEVEL(SMB2_GETINFO_FILE_ATTRIB_INFO) }
+ { LEVEL(RAW_FILEINFO_BASIC_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_STANDARD_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_INTERNAL_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_EA_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_ACCESS_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_POSITION_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_MODE_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_ALIGNMENT_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_ALL_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_ALT_NAME_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_STREAM_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_COMPRESSION_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_NETWORK_OPEN_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS) },
+ { LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION) },
+ { LEVEL(RAW_FILEINFO_SEC_DESC) }
+};
+
+static struct {
+       const char *name;
+       uint16_t level;
+       NTSTATUS status;
+       union smb_fsinfo info;
+} fs_levels[] = {
+ { LEVEL(RAW_QFS_VOLUME_INFORMATION) },
+ { LEVEL(RAW_QFS_SIZE_INFORMATION) },
+ { LEVEL(RAW_QFS_DEVICE_INFORMATION) },
+ { LEVEL(RAW_QFS_ATTRIBUTE_INFORMATION) },
+ { LEVEL(RAW_QFS_QUOTA_INFORMATION) },
+ { LEVEL(RAW_QFS_FULL_SIZE_INFORMATION) },
+ { LEVEL(RAW_QFS_OBJECTID_INFORMATION) }
 };
 
 #define FNAME "testsmb2_file.dat"
 #define DNAME "testsmb2_dir"
 
-/* basic testing of all SMB2 getinfo levels
+/*
+  test fileinfo levels
 */
-BOOL torture_smb2_getinfo(void)
+static BOOL torture_smb2_fileinfo(struct smb2_tree *tree)
 {
-       TALLOC_CTX *mem_ctx = talloc_new(NULL);
        struct smb2_handle hfile, hdir;
-       struct smb2_tree *tree;
        NTSTATUS status;
        int i;
 
-       if (!torture_smb2_connection(mem_ctx, &tree)) {
-               goto failed;
-       }
-
-       torture_setup_complex_file(FNAME);
-       torture_setup_complex_file(FNAME ":streamtwo");
-       torture_setup_complex_dir(DNAME);
-       torture_setup_complex_file(DNAME ":streamtwo");
-
        status = torture_smb2_testfile(tree, FNAME, &hfile);
        if (!NT_STATUS_IS_OK(status)) {
                printf("Unable to create test file '%s' - %s\n", FNAME, nt_errstr(status));
@@ -95,22 +95,81 @@ BOOL torture_smb2_getinfo(void)
        torture_smb2_all_info(tree, hfile);
        torture_smb2_all_info(tree, hdir);
 
-       for (i=0;i<ARRAY_SIZE(levels);i++) {
-               levels[i].fstatus = smb2_getinfo_level(tree, mem_ctx, hfile, 
-                                                      levels[i].level, &levels[i].finfo);
-               if (!NT_STATUS_IS_OK(levels[i].fstatus)) {
-                       printf("%s failed on file - %s\n", levels[i].name, nt_errstr(levels[i].fstatus));
+       for (i=0;i<ARRAY_SIZE(file_levels);i++) {
+               if (file_levels[i].level == RAW_FILEINFO_SEC_DESC) {
+                       file_levels[i].finfo.query_secdesc.secinfo_flags = 0x7;
+                       file_levels[i].dinfo.query_secdesc.secinfo_flags = 0x7;
                }
-               levels[i].dstatus = smb2_getinfo_level(tree, mem_ctx, hdir, 
-                                                      levels[i].level, &levels[i].dinfo);
-               if (!NT_STATUS_IS_OK(levels[i].dstatus)) {
-                       printf("%s failed on dir - %s\n", levels[i].name, nt_errstr(levels[i].dstatus));
+               file_levels[i].finfo.generic.level = file_levels[i].level;
+               file_levels[i].finfo.generic.in.handle = hfile;
+               file_levels[i].fstatus = smb2_getinfo_file(tree, tree, &file_levels[i].finfo);
+               if (!NT_STATUS_IS_OK(file_levels[i].fstatus)) {
+                       printf("%s failed on file - %s\n", file_levels[i].name, nt_errstr(file_levels[i].fstatus));
+               }
+               file_levels[i].dinfo.generic.level = file_levels[i].level;
+               file_levels[i].dinfo.generic.in.handle = hdir;
+               file_levels[i].dstatus = smb2_getinfo_file(tree, tree, &file_levels[i].dinfo);
+               if (!NT_STATUS_IS_OK(file_levels[i].dstatus)) {
+                       printf("%s failed on dir - %s\n", file_levels[i].name, nt_errstr(file_levels[i].dstatus));
                }
        }
 
        return True;
 
 failed:
-       talloc_free(mem_ctx);
        return False;
 }
+
+
+/*
+  test fsinfo levels
+*/
+static BOOL torture_smb2_fsinfo(struct smb2_tree *tree)
+{
+       int i;
+       NTSTATUS status;
+       struct smb2_handle handle;
+
+       status = torture_smb2_testdir(tree, DNAME, &handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Unable to create test directory '%s' - %s\n", DNAME, nt_errstr(status));
+               return False;
+       }
+
+       for (i=0;i<ARRAY_SIZE(fs_levels);i++) {
+               fs_levels[i].info.generic.level = fs_levels[i].level;
+               fs_levels[i].info.generic.handle = handle;
+               fs_levels[i].status = smb2_getinfo_fs(tree, tree, &fs_levels[i].info);
+               if (!NT_STATUS_IS_OK(fs_levels[i].status)) {
+                       printf("%s failed - %s\n", fs_levels[i].name, nt_errstr(fs_levels[i].status));
+               }
+       }
+
+       return True;
+}
+
+
+/* basic testing of all SMB2 getinfo levels
+*/
+BOOL torture_smb2_getinfo(void)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(NULL);
+       struct smb2_tree *tree;
+       BOOL ret = True;
+
+       if (!torture_smb2_connection(mem_ctx, &tree)) {
+               return False;
+       }
+
+       torture_setup_complex_file(FNAME);
+       torture_setup_complex_file(FNAME ":streamtwo");
+       torture_setup_complex_dir(DNAME);
+       torture_setup_complex_file(DNAME ":streamtwo");
+
+       ret &= torture_smb2_fileinfo(tree);
+       ret &= torture_smb2_fsinfo(tree);
+
+       talloc_free(mem_ctx);
+
+       return ret;
+}
index 6cbc2306303c95435bc11734a894c74ddab57296..95624220f7ec5a7e985b019523f1304bf7886b87 100644 (file)
@@ -34,65 +34,68 @@ void torture_smb2_all_info(struct smb2_tree *tree, struct smb2_handle handle)
 {
        NTSTATUS status;
        TALLOC_CTX *tmp_ctx = talloc_new(tree);
-       union smb2_fileinfo io;
+       union smb_fileinfo io;
 
-       status = smb2_getinfo_level(tree, tmp_ctx, handle, SMB2_GETINFO_FILE_ALL_INFO, &io);
+       io.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
+       io.generic.in.handle = handle;
+
+       status = smb2_getinfo_file(tree, tmp_ctx, &io);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("getinfo failed - %s\n", nt_errstr(status)));
                talloc_free(tmp_ctx);
                return;
        }
 
-       d_printf("\tcreate_time:    %s\n", nt_time_string(tmp_ctx, io.all_info.create_time));
-       d_printf("\taccess_time:    %s\n", nt_time_string(tmp_ctx, io.all_info.access_time));
-       d_printf("\twrite_time:     %s\n", nt_time_string(tmp_ctx, io.all_info.write_time));
-       d_printf("\tchange_time:    %s\n", nt_time_string(tmp_ctx, io.all_info.change_time));
-       d_printf("\tattrib:         0x%x\n", io.all_info.file_attr);
-       d_printf("\tunknown1:       0x%x\n", io.all_info.unknown1);
-       d_printf("\talloc_size:     %llu\n", (uint64_t)io.all_info.alloc_size);
-       d_printf("\tsize:           %llu\n", (uint64_t)io.all_info.size);
-       d_printf("\tnlink:          %u\n", io.all_info.nlink);
-       d_printf("\tdelete_pending: %u\n", io.all_info.delete_pending);
-       d_printf("\tdirectory:      %u\n", io.all_info.directory);
-       d_printf("\tfile_id:        %llu\n", io.all_info.file_id);
-       d_printf("\tea_size:        %u\n", io.all_info.ea_size);
-       d_printf("\taccess_mask:    0x%08x\n", io.all_info.access_mask);
-       d_printf("\tunknown5:       0x%llx\n", io.all_info.unknown5);
-       d_printf("\tunknown6:       0x%llx\n", io.all_info.unknown6);
-       d_printf("\tfname:          '%s'\n", io.all_info.fname);
+       d_printf("\tcreate_time:    %s\n", nt_time_string(tmp_ctx, io.all_info2.out.create_time));
+       d_printf("\taccess_time:    %s\n", nt_time_string(tmp_ctx, io.all_info2.out.access_time));
+       d_printf("\twrite_time:     %s\n", nt_time_string(tmp_ctx, io.all_info2.out.write_time));
+       d_printf("\tchange_time:    %s\n", nt_time_string(tmp_ctx, io.all_info2.out.change_time));
+       d_printf("\tattrib:         0x%x\n", io.all_info2.out.attrib);
+       d_printf("\tunknown1:       0x%x\n", io.all_info2.out.unknown1);
+       d_printf("\talloc_size:     %llu\n", (uint64_t)io.all_info2.out.alloc_size);
+       d_printf("\tsize:           %llu\n", (uint64_t)io.all_info2.out.size);
+       d_printf("\tnlink:          %u\n", io.all_info2.out.nlink);
+       d_printf("\tdelete_pending: %u\n", io.all_info2.out.delete_pending);
+       d_printf("\tdirectory:      %u\n", io.all_info2.out.directory);
+       d_printf("\tfile_id:        %llu\n", io.all_info2.out.file_id);
+       d_printf("\tea_size:        %u\n", io.all_info2.out.ea_size);
+       d_printf("\taccess_mask:    0x%08x\n", io.all_info2.out.access_mask);
+       d_printf("\tunknown2:       0x%llx\n", io.all_info2.out.unknown2);
+       d_printf("\tunknown3:       0x%llx\n", io.all_info2.out.unknown3);
+       d_printf("\tfname:          '%s'\n", io.all_info2.out.fname.s);
 
        /* short name, if any */
-       status = smb2_getinfo_level(tree, tmp_ctx, handle, 
-                                   SMB2_GETINFO_FILE_SHORT_INFO, &io);
+       io.generic.level = RAW_FILEINFO_ALT_NAME_INFORMATION;
+       status = smb2_getinfo_file(tree, tmp_ctx, &io);
        if (NT_STATUS_IS_OK(status)) {
-               d_printf("\tshort name:     '%s'\n", io.short_info.short_name);
+               d_printf("\tshort name:     '%s'\n", io.alt_name_info.out.fname.s);
        }
 
        /* the EAs, if any */
-       status = smb2_getinfo_level(tree, tmp_ctx, handle, 
-                                   SMB2_GETINFO_FILE_ALL_EAS, &io);
+       io.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
+       status = smb2_getinfo_file(tree, tmp_ctx, &io);
        if (NT_STATUS_IS_OK(status)) {
                int i;
-               for (i=0;i<io.all_eas.num_eas;i++) {
+               for (i=0;i<io.all_eas.out.num_eas;i++) {
                        d_printf("\tEA[%d] flags=%d len=%d '%s'\n", i,
-                                io.all_eas.eas[i].flags,
-                                (int)io.all_eas.eas[i].value.length,
-                                io.all_eas.eas[i].name.s);
+                                io.all_eas.out.eas[i].flags,
+                                (int)io.all_eas.out.eas[i].value.length,
+                                io.all_eas.out.eas[i].name.s);
                }
        }
 
        /* streams, if available */
-       status = smb2_getinfo_level(tree, tmp_ctx, handle, 
-                                   SMB2_GETINFO_FILE_STREAM_INFO, &io);
+       io.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
+       status = smb2_getinfo_file(tree, tmp_ctx, &io);
        if (NT_STATUS_IS_OK(status)) {
                int i;
-               for (i=0;i<io.stream_info.num_streams;i++) {
+               for (i=0;i<io.stream_info.out.num_streams;i++) {
                        d_printf("\tstream %d:\n", i);
                        d_printf("\t\tsize       %ld\n", 
-                                (long)io.stream_info.streams[i].size);
+                                (long)io.stream_info.out.streams[i].size);
                        d_printf("\t\talloc size %ld\n", 
-                                (long)io.stream_info.streams[i].alloc_size);
-                       d_printf("\t\tname       %s\n", io.stream_info.streams[i].stream_name.s);
+                                (long)io.stream_info.out.streams[i].alloc_size);
+                       d_printf("\t\tname       %s\n", io.stream_info.out.streams[i].stream_name.s);
                }
        }       
 
@@ -173,7 +176,7 @@ NTSTATUS torture_smb2_testdir(struct smb2_tree *tree, const char *fname,
        io.in.access_mask = SEC_RIGHTS_DIR_ALL;
        io.in.file_attr   = FILE_ATTRIBUTE_DIRECTORY;
        io.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
-       io.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE;
+       io.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE;
        io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
        io.in.fname = fname;
        io.in.blob  = data_blob(NULL, 0);