r11801: - added basic SMB2 find support
authorAndrew Tridgell <tridge@samba.org>
Sat, 19 Nov 2005 06:39:12 +0000 (06:39 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:46:29 +0000 (13:46 -0500)
- added SMB2-SCANFIND test

- cleaned up continue flags in EAs and find requests
(This used to be commit 8792bc07d927e6470874230153177748afae3ee8)

source4/include/smb_interfaces.h
source4/include/structs.h
source4/libcli/smb2/config.mk
source4/libcli/smb2/find.c [new file with mode: 0644]
source4/libcli/smb2/getinfo.c
source4/libcli/smb2/smb2_calls.h
source4/torture/smb2/getinfo.c
source4/torture/smb2/scan.c
source4/torture/torture.c

index 9d42494fc5de2f5df6079e788648affcd6dbaa46..49fe085f2cfde6dff1dcfffc67ce15f8586bd6bd 100644 (file)
@@ -461,7 +461,7 @@ union smb_fileinfo {
        struct {
                enum smb_fileinfo_level level;
                union smb_fileinfo_in in;
-               uint8_t ea_flags; /* SMB2 only - SMB2_GETINFO_EA_FLAG_* */
+               uint8_t continue_flags; /* SMB2 only - SMB2_CONTINUE_FLAG_* */
 
                struct smb_ea_list out;
        } all_eas;
index 68f7f9af1444ece693874400d5bd256c7dc50f70..a846b39bcff702be38f5d2045db1fcddd213c8b1 100644 (file)
@@ -354,6 +354,5 @@ struct smb2_getinfo;
 struct smb2_setinfo;
 struct smb2_read;
 struct smb2_write;
+struct smb2_find;
 struct smb2_handle;
-
-union smb2_fileinfo;
index fcea996f01dfb41e803b04b00f83e1410b23bb37..c0974dbfa5e605edc8393e8d2a213e81eb45a83c 100644 (file)
@@ -11,5 +11,6 @@ OBJ_FILES = \
        getinfo.o \
        write.o \
        read.o \
-       setinfo.o
+       setinfo.o \
+       find.o
 REQUIRED_SUBSYSTEMS = LIBCLI_RAW LIBPACKET
diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c
new file mode 100644 (file)
index 0000000..91be5e4
--- /dev/null
@@ -0,0 +1,90 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   SMB2 client find calls
+
+   Copyright (C) Andrew Tridgell 2005
+   
+   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 2 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, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
+
+/*
+  send a find request
+*/
+struct smb2_request *smb2_find_send(struct smb2_tree *tree, struct smb2_find *io)
+{
+       struct smb2_request *req;
+       NTSTATUS status;
+
+       req = smb2_request_init_tree(tree, SMB2_OP_FIND, 0x20, 1);
+       if (req == NULL) return NULL;
+
+       SCVAL(req->out.body, 0x02, io->in.level);
+       SCVAL(req->out.body, 0x03, io->in.continue_flags);
+       SIVAL(req->out.body, 0x04, io->in.unknown);
+       smb2_push_handle(req->out.body+0x08, &io->in.handle);
+       SIVAL(req->out.body, 0x1C, io->in.max_response_size);
+
+       status = smb2_push_o16s16_string(&req->out, 0x18, io->in.pattern);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(req);
+               return NULL;
+       }
+
+       smb2_transport_send(req);
+
+       return req;
+}
+
+
+/*
+  recv a find reply
+*/
+NTSTATUS smb2_find_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
+                          struct smb2_find *io)
+{
+       NTSTATUS status;
+
+       if (!smb2_request_receive(req) || 
+           smb2_request_is_error(req)) {
+               return smb2_request_destroy(req);
+       }
+
+       SMB2_CHECK_PACKET_RECV(req, 0x08, True);
+
+       status = smb2_pull_o16s32_blob(&req->in, mem_ctx, 
+                                      req->in.body+0x02, &io->out.blob);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       return smb2_request_destroy(req);
+}
+
+/*
+  sync find request
+*/
+NTSTATUS smb2_find(struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
+                     struct smb2_find *io)
+{
+       struct smb2_request *req = smb2_find_send(tree, io);
+       return smb2_find_recv(req, mem_ctx, io);
+}
+
index 62418a05b7fd26e9b5b606791ccd981c725d5145..e406fdf45c11188f22fd5f28dc98b9fafbd66b2f 100644 (file)
@@ -125,7 +125,7 @@ struct smb2_request *smb2_getinfo_file_send(struct smb2_tree *tree, union smb_fi
                b.in.flags = io->query_secdesc.secinfo_flags;
        }
        if (io->generic.level == RAW_FILEINFO_SMB2_ALL_EAS) {
-               b.in.flags2 = io->all_eas.ea_flags;
+               b.in.flags2 = io->all_eas.continue_flags;
        }
 
        return smb2_getinfo_send(tree, &b);
index e6e1872d5e5349b8f240b61b5418fd31eada722b..10d6cda7a3ac8ae6da83225d313ec2231b0c7411 100644 (file)
@@ -189,8 +189,8 @@ struct smb2_close {
 #define SMB2_GETINFO_SECURITY           0x03
 
 /* flags for RAW_FILEINFO_SMB2_ALL_EAS */
-#define SMB2_GETINFO_EA_FLAG_RESTART    0x01
-#define SMB2_GETINFO_EA_FLAG_SINGLE     0x02
+#define SMB2_CONTINUE_FLAG_RESTART    0x01
+#define SMB2_CONTINUE_FLAG_SINGLE     0x02
 
 /* NOTE! the getinfo fs and file levels exactly match up with the
    'passthru' SMB levels, which are levels >= 1000. The SMB2 client
@@ -278,3 +278,18 @@ struct smb2_read {
                DATA_BLOB data;
        } out;
 };
+
+struct smb2_find {
+       struct {
+               uint8_t level;
+               uint8_t continue_flags; /* SMB2_CONTINUE_FLAG_* */
+               uint32_t unknown; /* perhaps a continue token? */
+               struct smb2_handle handle;
+               uint32_t max_response_size;
+               const char *pattern;
+       } in;
+
+       struct {
+               DATA_BLOB blob;
+       } out;
+};
index 7c0fe7fbd7d0c9a36349e6b909ebf6afc2598e8d..209c220e60094eebbba61a1359791d88bfe7a59f 100644 (file)
@@ -102,10 +102,10 @@ static BOOL torture_smb2_fileinfo(struct smb2_tree *tree)
                        file_levels[i].dinfo.query_secdesc.secinfo_flags = 0x7;
                }
                if (file_levels[i].level == RAW_FILEINFO_SMB2_ALL_EAS) {
-                       file_levels[i].finfo.all_eas.ea_flags = 
-                               SMB2_GETINFO_EA_FLAG_RESTART;
-                       file_levels[i].dinfo.all_eas.ea_flags = 
-                               SMB2_GETINFO_EA_FLAG_RESTART;
+                       file_levels[i].finfo.all_eas.continue_flags = 
+                               SMB2_CONTINUE_FLAG_RESTART;
+                       file_levels[i].dinfo.all_eas.continue_flags = 
+                               SMB2_CONTINUE_FLAG_RESTART;
                }
                file_levels[i].finfo.generic.level = file_levels[i].level;
                file_levels[i].finfo.generic.in.handle = hfile;
index 81e0bea69a10ec51c0e0cc869383a8b39c8d1029..b0c4ba4c8d6872442022616dfc49459fe680c0af 100644 (file)
@@ -146,6 +146,54 @@ BOOL torture_smb2_setinfo_scan(void)
        return True;
 }
 
+
+/* 
+   scan for valid SMB2 scan levels
+*/
+BOOL torture_smb2_find_scan(void)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(NULL);
+       struct smb2_tree *tree;
+       NTSTATUS status;
+       struct smb2_find io;
+       struct smb2_handle handle;
+       int i;
+
+       if (!torture_smb2_connection(mem_ctx, &tree)) {
+               return False;
+       }
+
+       status = smb2_util_roothandle(tree, &handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Failed to open roothandle - %s\n", nt_errstr(status));
+               return False;
+       }
+
+       ZERO_STRUCT(io);
+       io.in.pattern = "*";
+       io.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
+       io.in.max_response_size = 0x10000;
+       io.in.handle = handle;
+
+       for (i=1;i<0x100;i++) {
+               io.in.level = i;
+
+               io.in.handle = handle;
+               status = smb2_find(tree, mem_ctx, &io);
+               if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) &&
+                   !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
+                   !NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+                       printf("find level 0x%04x is %d bytes - %s\n", 
+                              io.in.level, io.out.blob.length, nt_errstr(status));
+                       dump_data(1, io.out.blob.data, io.out.blob.length);
+               }
+       }
+
+       talloc_free(mem_ctx);
+
+       return True;
+}
+
 /* 
    scan for valid SMB2 opcodes
 */
index 434bca250030c536fab5a833bb4fb7ffcaac3932..e4ceffc02a17f8d39956debc24529fb23a6ec565 100644 (file)
@@ -2256,6 +2256,7 @@ static struct {
        {"SMB2-SCAN", torture_smb2_scan, 0},
        {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
        {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
+       {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
        {"SMB2-GETINFO", torture_smb2_getinfo, 0},
        {"SMB2-SETINFO", torture_smb2_setinfo, 0},