util_smb: For some (unknown) reason the previous patch changed the permissions -...
[ira/wip.git] / source4 / torture / util_smb.c
index 12d6f826432765635d4189daf1d74b9b4f678bcd..99b00d232939febb7f42dcb967a3e5c16b0727a9 100644 (file)
 #include "includes.h"
 #include "lib/cmdline/popt_common.h"
 #include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
 #include "libcli/raw/ioctl.h"
 #include "libcli/libcli.h"
 #include "system/filesys.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 "../lib/util/dlinklist.h"
 #include "auth/credentials/credentials.h"
+#include "libcli/resolve/resolve.h"
 #include "param/param.h"
 
 
@@ -43,9 +44,9 @@ _PUBLIC_ bool torture_setup_dir(struct smbcli_state *cli, const char *dname)
        if (smbcli_deltree(cli->tree, dname) == -1 ||
            NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
                printf("Unable to setup %s - %s\n", dname, smbcli_errstr(cli->tree));
-               return False;
+               return false;
        }
-       return True;
+       return true;
 }
 
 /*
@@ -256,6 +257,23 @@ void *shm_setup(int size)
        int shmid;
        void *ret;
 
+#ifdef __QNXNTO__
+       shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+       if (shmid == -1) {
+               printf("can't get shared memory\n");
+               exit(1);
+       }
+       shm_unlink("private");
+       if (ftruncate(shmid, size) == -1) {
+               printf("can't set shared memory size\n");
+               exit(1);
+       }
+       ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
+       if (ret == MAP_FAILED) {
+               printf("can't map shared memory\n");
+               exit(1);
+       }
+#else
        shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
        if (shmid == -1) {
                printf("can't get shared memory\n");
@@ -274,26 +292,28 @@ void *shm_setup(int size)
           See Stevens "advanced programming in unix env" for details
           */
        shmctl(shmid, IPC_RMID, 0);
+#endif
        
        return ret;
 }
 
 
-/*
+/**
   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_transport *transport)
+bool wire_bad_flags(struct smb_wire_string *str, int flags, 
+                   struct smbcli_transport *transport)
 {
        bool server_unicode;
        int len;
-       if (!str || !str->s) return True;
+       if (!str || !str->s) return true;
        len = strlen(str->s);
        if (flags & STR_TERMINATE) len++;
 
-       server_unicode = (transport->negotiate.capabilities&CAP_UNICODE)?True:False;
-       if (getenv("CLI_FORCE_ASCII") || !lp_unicode(global_loadparm)) {
-               server_unicode = False;
+       server_unicode = (transport->negotiate.capabilities&CAP_UNICODE)?true:false;
+       if (getenv("CLI_FORCE_ASCII") || !transport->options.unicode) {
+               server_unicode = false;
        }
 
        if ((flags & STR_UNICODE) || server_unicode) {
@@ -304,9 +324,9 @@ bool wire_bad_flags(struct smb_wire_string *str, int flags, struct smbcli_transp
        if (str->private_length != len) {
                printf("Expected wire_length %d but got %d for '%s'\n", 
                       len, str->private_length, str->s);
-               return True;
+               return true;
        }
-       return False;
+       return false;
 }
 
 /*
@@ -385,7 +405,7 @@ NTSTATUS torture_set_sparse(struct smbcli_tree *tree, int fnum)
        nt.ntioctl.level = RAW_IOCTL_NTIOCTL;
        nt.ntioctl.in.function = FSCTL_SET_SPARSE;
        nt.ntioctl.in.file.fnum = fnum;
-       nt.ntioctl.in.fsctl = True;
+       nt.ntioctl.in.fsctl = true;
        nt.ntioctl.in.filter = 0;
        nt.ntioctl.in.max_data = 0;
        nt.ntioctl.in.blob = data_blob(NULL, 0);
@@ -465,96 +485,108 @@ NTSTATUS torture_check_ea(struct smbcli_state *cli,
 
 _PUBLIC_ bool torture_open_connection_share(TALLOC_CTX *mem_ctx,
                                   struct smbcli_state **c, 
+                                  struct torture_context *tctx,
                                   const char *hostname, 
                                   const char *sharename,
-                                  struct event_context *ev)
+                                  struct tevent_context *ev)
 {
        NTSTATUS status;
 
+       struct smbcli_options options;
+       struct smbcli_session_options session_options;
+
+       lp_smbcli_options(tctx->lp_ctx, &options);
+       lp_smbcli_session_options(tctx->lp_ctx, &session_options);
+
+       options.use_oplocks = torture_setting_bool(tctx, "use_oplocks", true);
+       options.use_level2_oplocks = torture_setting_bool(tctx, "use_level2_oplocks", true);
+
        status = smbcli_full_connection(mem_ctx, c, hostname, 
+                                       lp_smb_ports(tctx->lp_ctx),
                                        sharename, NULL,
-                                       cmdline_credentials, ev);
+                                       lp_socket_options(tctx->lp_ctx),
+                                       cmdline_credentials, 
+                                       lp_resolve_context(tctx->lp_ctx),
+                                       ev, &options, &session_options,
+                                       lp_iconv_convenience(tctx->lp_ctx),
+                                       lp_gensec_settings(tctx, tctx->lp_ctx));
        if (!NT_STATUS_IS_OK(status)) {
                printf("Failed to open connection - %s\n", nt_errstr(status));
-               return False;
+               return false;
        }
 
-       (*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;
+       return true;
 }
 
 _PUBLIC_ bool torture_get_conn_index(int conn_index,
                                     TALLOC_CTX *mem_ctx,
+                                    struct torture_context *tctx,
                                     char **host, char **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"));
+       (*host) = talloc_strdup(mem_ctx, torture_setting_string(tctx, "host", NULL));
+       (*share) = talloc_strdup(mem_ctx, torture_setting_string(tctx, "share", NULL));
        
-       p = lp_parm_string(NULL, "torture", "unclist");
+       p = torture_setting_string(tctx, "unclist", NULL);
        if (!p) {
-               return True;
+               return true;
        }
 
-       unc_list = file_lines_load(p, &num_unc_names, NULL);
+       unc_list = file_lines_load(p, &num_unc_names, 0, NULL);
        if (!unc_list || num_unc_names <= 0) {
                DEBUG(0,("Failed to load unc names list from '%s'\n", p));
-               return False;
+               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 false;
        }
 
        talloc_free(unc_list);
-       return True;
+       return true;
 }
 
 
 
 _PUBLIC_ bool torture_open_connection_ev(struct smbcli_state **c,
                                         int conn_index,
-                                        struct event_context *ev)
+                                        struct torture_context *tctx,
+                                        struct tevent_context *ev)
 {
        char *host, *share;
        bool ret;
 
-       if (!torture_get_conn_index(conn_index, ev, &host, &share)) {
-               return False;
+       if (!torture_get_conn_index(conn_index, ev, tctx, &host, &share)) {
+               return false;
        }
 
-       ret = torture_open_connection_share(NULL, c, host, share, ev);
+       ret = torture_open_connection_share(NULL, c, tctx, host, share, ev);
        talloc_free(host);
        talloc_free(share);
 
        return ret;
 }
 
-_PUBLIC_ bool torture_open_connection(struct smbcli_state **c, int conn_index)
+_PUBLIC_ bool torture_open_connection(struct smbcli_state **c, struct torture_context *tctx, int conn_index)
 {
-       return torture_open_connection_ev(c, conn_index, 
-                                         cli_credentials_get_event_context(cmdline_credentials));
+       return torture_open_connection_ev(c, conn_index, tctx, tctx->ev);
 }
 
 
 
 _PUBLIC_ bool torture_close_connection(struct smbcli_state *c)
 {
-       bool ret = True;
-       if (!c) return 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));
-               ret = False;
+               ret = false;
        }
        talloc_free(c);
        return ret;
@@ -569,25 +601,25 @@ _PUBLIC_ bool check_error(const char *location, struct smbcli_state *c,
        
        status = smbcli_nt_error(c->tree);
        if (NT_STATUS_IS_DOS(status)) {
-               int class, num;
-               class = NT_STATUS_DOS_CLASS(status);
+               int classnum, num;
+               classnum = NT_STATUS_DOS_CLASS(status);
                num = NT_STATUS_DOS_CODE(status);
-                if (eclass != class || ecode != num) {
+                if (eclass != classnum || ecode != num) {
                         printf("unexpected error code %s\n", nt_errstr(status));
                         printf(" expected %s or %s (at %s)\n", 
                               nt_errstr(NT_STATUS_DOS(eclass, ecode)), 
                                nt_errstr(nterr), location);
-                        return False;
+                        return false;
                 }
         } else {
                 if (!NT_STATUS_EQUAL(nterr, status)) {
                         printf("unexpected error code %s\n", nt_errstr(status));
                         printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
-                        return False;
+                        return false;
                 }
         }
 
-       return True;
+       return true;
 }
 
 static struct smbcli_state *current_cli;
@@ -609,7 +641,7 @@ double torture_create_procs(struct torture_context *tctx,
        double start_time_limit = 10 + (torture_nprocs * 1.5);
        struct timeval tv;
 
-       *result = True;
+       *result = true;
 
        synccount = 0;
 
@@ -629,7 +661,7 @@ double torture_create_procs(struct torture_context *tctx,
 
        for (i = 0; i < torture_nprocs; i++) {
                child_status[i] = 0;
-               child_status_out[i] = True;
+               child_status_out[i] = true;
        }
 
        tv = timeval_current();
@@ -642,13 +674,16 @@ double torture_create_procs(struct torture_context *tctx,
                        pid_t mypid = getpid();
                        srandom(((int)mypid) ^ ((int)time(NULL)));
 
-                       asprintf(&myname, "CLIENT%d", i);
-                       lp_set_cmdline(global_loadparm, "netbios name", myname);
+                       if (asprintf(&myname, "CLIENT%d", i) == -1) {
+                               printf("asprintf failed\n");
+                               return -1;
+                       }
+                       lp_set_cmdline(tctx->lp_ctx, "netbios name", myname);
                        free(myname);
 
 
                        while (1) {
-                               if (torture_open_connection(&current_cli, i)) {
+                               if (torture_open_connection(&current_cli, tctx, i)) {
                                        break;
                                }
                                if (tries-- == 0) {
@@ -684,7 +719,7 @@ double torture_create_procs(struct torture_context *tctx,
 
        if (synccount != torture_nprocs) {
                printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
-               *result = False;
+               *result = false;
                return timeval_elapsed(&tv);
        }
 
@@ -704,7 +739,7 @@ double torture_create_procs(struct torture_context *tctx,
                int ret;
                while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
                if (ret == -1 || WEXITSTATUS(status) != 0) {
-                       *result = False;
+                       *result = false;
                }
        }
 
@@ -712,7 +747,7 @@ double torture_create_procs(struct torture_context *tctx,
        
        for (i=0;i<torture_nprocs;i++) {
                if (!child_status_out[i]) {
-                       *result = False;
+                       *result = false;
                }
        }
        return timeval_elapsed(&tv);
@@ -766,8 +801,8 @@ static bool wrap_simple_2smb_test(struct torture_context *torture_ctx,
 
        struct smbcli_state *cli1, *cli2;
 
-       if (!torture_open_connection(&cli1, 0) || 
-               !torture_open_connection(&cli2, 1))
+       if (!torture_open_connection(&cli1, torture_ctx, 0) || 
+               !torture_open_connection(&cli2, torture_ctx, 1))
                return false;
 
        fn = test->fn;
@@ -817,7 +852,7 @@ static bool wrap_simple_1smb_test(struct torture_context *torture_ctx,
 
        struct smbcli_state *cli1;
 
-       if (!torture_open_connection(&cli1, 0))
+       if (!torture_open_connection(&cli1, torture_ctx, 0))
                return false;
 
        fn = test->fn;
@@ -853,3 +888,42 @@ _PUBLIC_ struct torture_test *torture_suite_add_1smb_test(
 }
 
 
+NTSTATUS torture_second_tcon(TALLOC_CTX *mem_ctx,
+                            struct smbcli_session *session,
+                            const char *sharename,
+                            struct smbcli_tree **res)
+{
+       union smb_tcon tcon;
+       struct smbcli_tree *result;
+       TALLOC_CTX *tmp_ctx;
+       NTSTATUS status;
+
+       if ((tmp_ctx = talloc_new(mem_ctx)) == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       result = smbcli_tree_init(session, tmp_ctx, false);
+       if (result == NULL) {
+               talloc_free(tmp_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       tcon.generic.level = RAW_TCON_TCONX;
+       tcon.tconx.in.flags = 0;
+
+       /* Ignore share mode security here */
+       tcon.tconx.in.password = data_blob(NULL, 0);
+       tcon.tconx.in.path = sharename;
+       tcon.tconx.in.device = "?????";
+
+       status = smb_raw_tcon(result, tmp_ctx, &tcon);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(tmp_ctx);
+               return status;
+       }
+
+       result->tid = tcon.tconx.out.tid;
+       *res = talloc_steal(mem_ctx, result);
+       talloc_free(tmp_ctx);
+       return NT_STATUS_OK;
+}