r25035: Fix some more warnings, use service pointer rather than service number in...
[bbaumbach/samba-autobuild/.git] / source4 / torture / util_smb.c
index c1e4edc5e6f10a29de50b44c0de225f124b08fba..8b944e33a09f8eed640194c35673e9ba35bdfd78 100644 (file)
@@ -2,10 +2,11 @@
    Unix SMB/CIFS implementation.
    SMB torture tester utility functions
    Copyright (C) Andrew Tridgell 2003
+   Copyright (C) Jelmer Vernooij 2006
    
    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,
@@ -14,8 +15,7 @@
    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 "system/shmem.h"
 #include "system/wait.h"
 #include "system/time.h"
+#include "torture/ui.h"
 #include "torture/torture.h"
+#include "util/dlinklist.h"
+#include "auth/credentials/credentials.h"
+#include "param/param.h"
 
 
 /**
   setup a directory ready for a test
 */
-_PUBLIC_ BOOL torture_setup_dir(struct smbcli_state *cli, const char *dname)
+_PUBLIC_ bool torture_setup_dir(struct smbcli_state *cli, const char *dname)
 {
        smb_raw_exit(cli->session);
        if (smbcli_deltree(cli->tree, dname) == -1 ||
@@ -53,7 +57,7 @@ NTSTATUS create_directory_handle(struct smbcli_tree *tree, const char *dname, in
        union smb_open io;
        TALLOC_CTX *mem_ctx;
 
-       mem_ctx = talloc_init("create_directory_handle");
+       mem_ctx = talloc_named_const(tree, 0, "create_directory_handle");
 
        io.generic.level = RAW_OPEN_NTCREATEX;
        io.ntcreatex.in.root_fid = 0;
@@ -279,15 +283,15 @@ void *shm_setup(int size)
   check that a wire string matches the flags specified 
   not 100% accurate, but close enough for testing
 */
-BOOL wire_bad_flags(struct smb_wire_string *str, int flags, struct smbcli_state *cli)
+bool wire_bad_flags(struct smb_wire_string *str, int flags, struct smbcli_transport *transport)
 {
-       BOOL server_unicode;
+       bool server_unicode;
        int len;
        if (!str || !str->s) return True;
        len = strlen(str->s);
        if (flags & STR_TERMINATE) len++;
 
-       server_unicode = (cli->transport->negotiate.capabilities&CAP_UNICODE)?True:False;
+       server_unicode = (transport->negotiate.capabilities&CAP_UNICODE)?True:False;
        if (getenv("CLI_FORCE_ASCII") || !lp_unicode()) {
                server_unicode = False;
        }
@@ -329,7 +333,7 @@ void dump_all_info(TALLOC_CTX *mem_ctx, union smb_fileinfo *finfo)
 */
 void torture_all_info(struct smbcli_tree *tree, const char *fname)
 {
-       TALLOC_CTX *mem_ctx = talloc_init("%s", fname);
+       TALLOC_CTX *mem_ctx = talloc_named(tree, 0, "%s", fname);
        union smb_fileinfo finfo;
        NTSTATUS status;
 
@@ -350,7 +354,7 @@ void torture_all_info(struct smbcli_tree *tree, const char *fname)
 /*
   set a attribute on a file
 */
-BOOL torture_set_file_attribute(struct smbcli_tree *tree, const char *fname, uint16_t attrib)
+bool torture_set_file_attribute(struct smbcli_tree *tree, const char *fname, uint16_t attrib)
 {
        union smb_setfileinfo sfinfo;
        NTSTATUS status;
@@ -373,7 +377,7 @@ NTSTATUS torture_set_sparse(struct smbcli_tree *tree, int fnum)
        NTSTATUS status;
        TALLOC_CTX *mem_ctx;
 
-       mem_ctx = talloc_init("torture_set_sparse");
+       mem_ctx = talloc_named_const(tree, 0, "torture_set_sparse");
        if (!mem_ctx) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -459,7 +463,7 @@ NTSTATUS torture_check_ea(struct smbcli_state *cli,
        return NT_STATUS_EA_CORRUPT_ERROR;
 }
 
-BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
+_PUBLIC_ bool torture_open_connection_share(TALLOC_CTX *mem_ctx,
                                   struct smbcli_state **c, 
                                   const char *hostname, 
                                   const char *sharename,
@@ -475,80 +479,78 @@ BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
                return False;
        }
 
-       (*c)->transport->options.use_oplocks = use_oplocks;
-       (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
+       (*c)->transport->options.use_oplocks = lp_parm_bool(NULL, "torture", 
+                                                                                                               "use_oplocks", false);
+       (*c)->transport->options.use_level2_oplocks = lp_parm_bool(NULL, "torture", 
+                                                                                               "use_level2_oplocks", false);
 
        return True;
 }
 
-_PUBLIC_ BOOL torture_open_connection(struct smbcli_state **c, int conn_index)
+_PUBLIC_ bool torture_get_conn_index(int conn_index,
+                                    TALLOC_CTX *mem_ctx,
+                                    char **host, char **share)
 {
-       const char *host = lp_parm_string(-1, "torture", "host");
-       const char *share = lp_parm_string(-1, "torture", "share");
        char **unc_list = NULL;
        int num_unc_names = 0;
        const char *p;
+
+       (*host) = talloc_strdup(mem_ctx, lp_parm_string(NULL, "torture", "host"));
+       (*share) = talloc_strdup(mem_ctx, lp_parm_string(NULL, "torture", "share"));
        
-       p = lp_parm_string(-1, "torture", "unclist");
-       if (p) {
-               char *h, *s;
-               unc_list = file_lines_load(p, &num_unc_names, NULL);
-               if (!unc_list || num_unc_names <= 0) {
-                       printf("Failed to load unc names list from '%s'\n", p);
-                       exit(1);
-               }
+       p = lp_parm_string(NULL, "torture", "unclist");
+       if (!p) {
+               return True;
+       }
 
-               if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
-                                     NULL, &h, &s)) {
-                       printf("Failed to parse UNC name %s\n",
-                              unc_list[conn_index % num_unc_names]);
-                       exit(1);
-               }
-               host = h;
-               share = s;
+       unc_list = file_lines_load(p, &num_unc_names, NULL);
+       if (!unc_list || num_unc_names <= 0) {
+               DEBUG(0,("Failed to load unc names list from '%s'\n", p));
+               return False;
+       }
+
+       if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
+                             mem_ctx, host, share)) {
+               DEBUG(0, ("Failed to parse UNC name %s\n",
+                         unc_list[conn_index % num_unc_names]));
+               return False;
        }
 
-       return torture_open_connection_share(NULL, c, host, share, NULL);
+       talloc_free(unc_list);
+       return True;
 }
 
-_PUBLIC_ BOOL torture_open_connection_ev(struct smbcli_state **c,
+
+
+_PUBLIC_ bool torture_open_connection_ev(struct smbcli_state **c,
                                         int conn_index,
                                         struct event_context *ev)
 {
-       const char *host = lp_parm_string(-1, "torture", "host");
-       const char *share = lp_parm_string(-1, "torture", "share");
-       char **unc_list = NULL;
-       int num_unc_names = 0;
-       const char *p;
-       
-       p = lp_parm_string(-1, "torture", "unclist");
-       if (p) {
-               char *h, *s;
-               unc_list = file_lines_load(p, &num_unc_names, NULL);
-               if (!unc_list || num_unc_names <= 0) {
-                       printf("Failed to load unc names list from '%s'\n", p);
-                       exit(1);
-               }
+       char *host, *share;
+       bool ret;
 
-               if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
-                                     NULL, &h, &s)) {
-                       printf("Failed to parse UNC name %s\n",
-                              unc_list[conn_index % num_unc_names]);
-                       exit(1);
-               }
-               host = h;
-               share = s;
+       if (!torture_get_conn_index(conn_index, ev, &host, &share)) {
+               return False;
        }
 
+       ret = torture_open_connection_share(NULL, c, host, share, ev);
+       talloc_free(host);
+       talloc_free(share);
+
+       return ret;
+}
 
-       return torture_open_connection_share(NULL, c, host, share, ev);
+_PUBLIC_ bool torture_open_connection(struct smbcli_state **c, int conn_index)
+{
+       return torture_open_connection_ev(c, conn_index, 
+                                         cli_credentials_get_event_context(cmdline_credentials));
 }
 
 
 
-_PUBLIC_ BOOL torture_close_connection(struct smbcli_state *c)
+_PUBLIC_ bool torture_close_connection(struct smbcli_state *c)
 {
-       BOOL ret = True;
+       bool ret = True;
        if (!c) return True;
        if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
                printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
@@ -560,7 +562,7 @@ _PUBLIC_ BOOL torture_close_connection(struct smbcli_state *c)
 
 
 /* check if the server produced the expected error code */
-_PUBLIC_ BOOL check_error(const char *location, struct smbcli_state *c, 
+_PUBLIC_ bool check_error(const char *location, struct smbcli_state *c, 
                 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
 {
        NTSTATUS status;
@@ -595,13 +597,15 @@ static void sigcont(int sig)
 {
 }
 
-double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
+double torture_create_procs(struct torture_context *tctx, 
+                                                       bool (*fn)(struct torture_context *, struct smbcli_state *, int), bool *result)
 {
        int i, status;
        volatile pid_t *child_status;
-       volatile BOOL *child_status_out;
+       volatile bool *child_status_out;
        int synccount;
        int tries = 8;
+       int torture_nprocs = torture_setting_int(tctx, "nprocs", 4);
        double start_time_limit = 10 + (torture_nprocs * 1.5);
        struct timeval tv;
 
@@ -617,7 +621,7 @@ double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result
                return -1;
        }
 
-       child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
+       child_status_out = (volatile bool *)shm_setup(sizeof(bool)*torture_nprocs);
        if (!child_status_out) {
                printf("Failed to setup result status shared memory\n");
                return -1;
@@ -664,7 +668,7 @@ double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result
                                _exit(1);
                        }
 
-                       child_status_out[i] = fn(current_cli, i);
+                       child_status_out[i] = fn(tctx, current_cli, i);
                        _exit(0);
                }
        }
@@ -714,30 +718,138 @@ double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result
        return timeval_elapsed(&tv);
 }
 
-static BOOL wrap_old_torture_multifn(struct torture_context *torture,
-                                                               const void *_fn)
+static bool wrap_smb_multi_test(struct torture_context *torture,
+                                                               struct torture_tcase *tcase,
+                                                               struct torture_test *test)
 {
-       BOOL (*fn)(struct smbcli_state *, int ) = _fn;
-       BOOL result;
+       bool (*fn)(struct torture_context *, struct smbcli_state *, int ) = test->fn;
+       bool result;
 
-       torture_create_procs(fn, &result);
+       torture_create_procs(torture, fn, &result);
 
        return result;
 }
 
-_PUBLIC_ NTSTATUS register_torture_multi_op(const char *name, 
-                                                                                       BOOL (*multi_fn)(struct smbcli_state *, int ))
+_PUBLIC_ struct torture_test *torture_suite_add_smb_multi_test(
+                                                                       struct torture_suite *suite,
+                                                                       const char *name,
+                                                                       bool (*run) (struct torture_context *,
+                                                                                                struct smbcli_state *,
+                                                                                               int i))
+{
+       struct torture_test *test; 
+       struct torture_tcase *tcase;
+       
+       tcase = torture_suite_add_tcase(suite, name);
+
+       test = talloc(tcase, struct torture_test);
+
+       test->name = talloc_strdup(test, name);
+       test->description = NULL;
+       test->run = wrap_smb_multi_test;
+       test->fn = run;
+       test->dangerous = false;
+
+       DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+
+       return test;
+
+}
+
+static bool wrap_simple_2smb_test(struct torture_context *torture_ctx,
+                                                                       struct torture_tcase *tcase,
+                                                                       struct torture_test *test)
 {
-       struct torture_suite *suite;
+       bool (*fn) (struct torture_context *, struct smbcli_state *,
+                               struct smbcli_state *);
+       bool ret;
+
+       struct smbcli_state *cli1, *cli2;
+
+       if (!torture_open_connection(&cli1, 0) || 
+               !torture_open_connection(&cli2, 1))
+               return false;
+
+       fn = test->fn;
+
+       ret = fn(torture_ctx, cli1, cli2);
+
+       talloc_free(cli1);
+       talloc_free(cli2);
+
+       return ret;
+}
+
+
+
+_PUBLIC_ struct torture_test *torture_suite_add_2smb_test(
+                                                                       struct torture_suite *suite,
+                                                                       const char *name,
+                                                                       bool (*run) (struct torture_context *,
+                                                                                               struct smbcli_state *,
+                                                                                               struct smbcli_state *))
+{
+       struct torture_test *test; 
+       struct torture_tcase *tcase;
+       
+       tcase = torture_suite_add_tcase(suite, name);
+
+       test = talloc(tcase, struct torture_test);
+
+       test->name = talloc_strdup(test, name);
+       test->description = NULL;
+       test->run = wrap_simple_2smb_test;
+       test->fn = run;
+       test->dangerous = false;
+
+       DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+
+       return test;
+
+}
+
+static bool wrap_simple_1smb_test(struct torture_context *torture_ctx,
+                                                                       struct torture_tcase *tcase,
+                                                                       struct torture_test *test)
+{
+       bool (*fn) (struct torture_context *, struct smbcli_state *);
+       bool ret;
+
+       struct smbcli_state *cli1;
+
+       if (!torture_open_connection(&cli1, 0))
+               return false;
+
+       fn = test->fn;
+
+       ret = fn(torture_ctx, cli1);
+
+       talloc_free(cli1);
+
+       return ret;
+}
+
+_PUBLIC_ struct torture_test *torture_suite_add_1smb_test(
+                               struct torture_suite *suite,
+                               const char *name,
+                               bool (*run) (struct torture_context *, struct smbcli_state *))
+{
+       struct torture_test *test; 
+       struct torture_tcase *tcase;
+       
+       tcase = torture_suite_add_tcase(suite, name);
+
+       test = talloc(tcase, struct torture_test);
 
-       suite = torture_suite_create(talloc_autofree_context(), name);
+       test->name = talloc_strdup(test, name);
+       test->description = NULL;
+       test->run = wrap_simple_1smb_test;
+       test->fn = run;
+       test->dangerous = false;
 
-       torture_suite_add_simple_tcase(suite, name, 
-                                                                  wrap_old_torture_multifn,
-                                                                  multi_fn);
-       torture_register_suite(suite);
+       DLIST_ADD_END(tcase->tests, test, struct torture_test *);
 
-       return NT_STATUS_OK;
+       return test;
 }