more useful output in scan
[kai/samba.git] / source4 / torture / smb2 / scan.c
index 0fcd3250fbaf2f48d8d6eb67300278e2e9576225..ae51af18820ed0ad97281be2a97814f3321423ef 100644 (file)
@@ -7,7 +7,7 @@
    
    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
+   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,
    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.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
-#include "libcli/raw/libcliraw.h"
 #include "libcli/smb2/smb2.h"
 #include "libcli/smb2/smb2_calls.h"
 #include "lib/cmdline/popt_common.h"
 #include "lib/events/events.h"
+#include "torture/torture.h"
+#include "param/param.h"
+#include "libcli/resolve/resolve.h"
 
+#include "torture/smb2/proto.h"
+
+#define FNAME "scan-getinfo.dat"
+#define DNAME "scan-getinfo.dir"
+
+
+/* 
+   scan for valid SMB2 getinfo levels
+*/
+bool torture_smb2_getinfo_scan(struct torture_context *torture)
+{
+       struct smb2_tree *tree;
+       NTSTATUS status;
+       struct smb2_getinfo io;
+       struct smb2_handle fhandle, dhandle;
+       int c, i;
+
+       if (!torture_smb2_connection(torture, &tree)) {
+               return false;
+       }
+
+       status = torture_setup_complex_file(tree, FNAME);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Failed to setup complex file '%s'\n", FNAME);
+               return false;
+       }
+       torture_setup_complex_file(tree, FNAME ":2ndstream");
+
+       status = torture_setup_complex_dir(tree, DNAME);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Failed to setup complex dir  '%s'\n", DNAME);
+               return false;
+       }
+       torture_setup_complex_file(tree, DNAME ":2ndstream");
+
+       torture_smb2_testfile(tree, FNAME, &fhandle);
+       torture_smb2_testdir(tree, DNAME, &dhandle);
+
+
+       ZERO_STRUCT(io);
+       io.in.output_buffer_length = 0xFFFF;
+
+       for (c=1;c<5;c++) {
+               for (i=0;i<0x100;i++) {
+                       io.in.info_type = c;
+                       io.in.info_class = i;
+
+                       io.in.file.handle = fhandle;
+                       status = smb2_getinfo(tree, torture, &io);
+                       if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
+                               printf("file level 0x%02x:%02x %u is %ld bytes - %s\n", 
+                                      io.in.info_type, io.in.info_class, 
+                                      (unsigned)io.in.info_class, 
+                                      (long)io.out.blob.length, nt_errstr(status));
+                               dump_data(1, io.out.blob.data, io.out.blob.length);
+                       }
+
+                       io.in.file.handle = dhandle;
+                       status = smb2_getinfo(tree, torture, &io);
+                       if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
+                               printf("dir  level 0x%02x:%02x %u is %ld bytes - %s\n", 
+                                      io.in.info_type, io.in.info_class,
+                                      (unsigned)io.in.info_class, 
+                                      (long)io.out.blob.length, nt_errstr(status));
+                               dump_data(1, io.out.blob.data, io.out.blob.length);
+                       }
+               }
+       }
+
+       return true;
+}
+
+/* 
+   scan for valid SMB2 setinfo levels
+*/
+bool torture_smb2_setinfo_scan(struct torture_context *torture)
+{
+       struct smb2_tree *tree;
+       NTSTATUS status;
+       struct smb2_setinfo io;
+       struct smb2_handle handle;
+       int c, i;
+
+       if (!torture_smb2_connection(torture, &tree)) {
+               return false;
+       }
+
+       status = torture_setup_complex_file(tree, FNAME);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Failed to setup complex file '%s'\n", FNAME);
+               return false;
+       }
+       torture_setup_complex_file(tree, FNAME ":2ndstream");
+
+       torture_smb2_testfile(tree, FNAME, &handle);
+
+       ZERO_STRUCT(io);
+       io.in.blob = data_blob_talloc_zero(torture, 1024);
+
+       for (c=1;c<5;c++) {
+               for (i=0;i<0x100;i++) {
+                       io.in.level = (i<<8) | c;
+                       io.in.file.handle = handle;
+                       status = smb2_setinfo(tree, &io);
+                       if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
+                               printf("file level 0x%04x - %s\n", 
+                                      io.in.level, nt_errstr(status));
+                       }
+               }
+       }
+
+       return true;
+}
+
+
+/* 
+   scan for valid SMB2 scan levels
+*/
+bool torture_smb2_find_scan(struct torture_context *torture)
+{
+       struct smb2_tree *tree;
+       NTSTATUS status;
+       struct smb2_find io;
+       struct smb2_handle handle;
+       int i;
+
+       if (!torture_smb2_connection(torture, &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.file.handle       = handle;
+       io.in.pattern           = "*";
+       io.in.continue_flags    = SMB2_CONTINUE_FLAG_RESTART;
+       io.in.max_response_size = 0x10000;
+
+       for (i=1;i<0x100;i++) {
+               io.in.level = i;
+
+               io.in.file.handle = handle;
+               status = smb2_find(tree, torture, &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 %ld bytes - %s\n", 
+                              io.in.level, (long)io.out.blob.length, nt_errstr(status));
+                       dump_data(1, io.out.blob.data, io.out.blob.length);
+               }
+       }
+
+       return true;
+}
 
 /* 
    scan for valid SMB2 opcodes
 */
-BOOL torture_smb2_scan(void)
+bool torture_smb2_scan(struct torture_context *torture)
 {
        TALLOC_CTX *mem_ctx = talloc_new(NULL);
        struct smb2_tree *tree;
-       const char *host = lp_parm_string(-1, "torture", "host");
-       const char *share = lp_parm_string(-1, "torture", "share");
+       const char *host = torture_setting_string(torture, "host", NULL);
+       const char *share = torture_setting_string(torture, "share", NULL);
        struct cli_credentials *credentials = cmdline_credentials;
        NTSTATUS status;
        int opcode;
        struct smb2_request *req;
+       struct smbcli_options options;
+
+       lp_smbcli_options(torture->lp_ctx, &options);
 
-       status = smb2_connect(mem_ctx, host, share, credentials, &tree, 
-                             event_context_find(mem_ctx));
+       status = smb2_connect(mem_ctx, host, share, 
+                             lp_resolve_context(torture->lp_ctx), 
+                             credentials, &tree, 
+                             torture->ev, &options);
        if (!NT_STATUS_IS_OK(status)) {
                printf("Connection failed - %s\n", nt_errstr(status));
-               return False;
+               return false;
        }
 
-       tree->session->transport->options.timeout = 3;
+       tree->session->transport->options.request_timeout = 3;
 
        for (opcode=0;opcode<1000;opcode++) {
-               req = smb2_request_init_tree(tree, opcode, 2);
+               req = smb2_request_init_tree(tree, opcode, 2, false, 0);
                SSVAL(req->out.body, 0, 0);
                smb2_transport_send(req);
                if (!smb2_request_receive(req)) {
                        talloc_free(tree);
-                       status = smb2_connect(mem_ctx, host, share, credentials, &tree, 
-                                             event_context_find(mem_ctx));
+                       status = smb2_connect(mem_ctx, host, share, 
+                                             lp_resolve_context(torture->lp_ctx), 
+                                             credentials, &tree, 
+                                             torture->ev, &options);
                        if (!NT_STATUS_IS_OK(status)) {
                                printf("Connection failed - %s\n", nt_errstr(status));
-                               return False;
+                               return false;
                        }
-                       tree->session->transport->options.timeout = 3;
+                       tree->session->transport->options.request_timeout = 3;
                } else {
                        status = smb2_request_destroy(req);
                        printf("active opcode %4d gave status %s\n", opcode, nt_errstr(status));
@@ -72,5 +238,5 @@ BOOL torture_smb2_scan(void)
 
        talloc_free(mem_ctx);
 
-       return True;
+       return true;
 }