r25430: Add the loadparm context to all parametric options.
[kai/samba.git] / source4 / torture / locktest.c
index 005f9af71b11837360c34f3dfea853a7b280cfde..562defe09e3460d9506faaa6a8a702bf678ffbaa 100644 (file)
@@ -5,7 +5,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 "system/filesys.h"
-#include "dynconfig.h"
 #include "system/time.h"
+#include "pstring.h"
+#include "auth/credentials/credentials.h"
+#include "auth/gensec/gensec.h"
+#include "libcli/libcli.h"
+#include "param/param.h"
+#include "dynconfig.h"
 
 static int numops = 1000;
 static BOOL showall;
@@ -45,9 +49,7 @@ static BOOL zero_zero;
 #define NFILES 2
 #define LOCK_TIMEOUT 0
 
-#define NASTY_POSIX_LOCK_HACK 0
-
-static struct cli_credentials servers[NSERVERS];
+static struct cli_credentials *servers[NSERVERS];
 
 enum lock_op {OP_LOCK, OP_UNLOCK, OP_REOPEN};
 
@@ -57,6 +59,7 @@ struct record {
        char conn, f;
        uint64_t start, len;
        char needed;
+       uint16_t pid;
 };
 
 #define PRESETS 0
@@ -102,26 +105,55 @@ static struct record *recorded;
 /***************************************************** 
 return a connection to a server
 *******************************************************/
-static struct smbcli_state *connect_one(char *share, int snum)
+static struct smbcli_state *connect_one(char *share, int snum, int conn)
 {
        struct smbcli_state *c;
        fstring server, myname;
        NTSTATUS status;
        int retries = 10;
 
+       printf("connect_one(%s, %d, %d)\n", share, snum, conn);
+
        fstrcpy(server,share+2);
        share = strchr_m(server,'\\');
        if (!share) return NULL;
        *share = 0;
        share++;
 
+       if (snum == 0) {
+               char **unc_list = NULL;
+               int num_unc_names;
+               const char *p;
+               p = lp_parm_string(global_loadparm, NULL, "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);
+                       }
+
+                       if (!smbcli_parse_unc(unc_list[conn % num_unc_names],
+                                             NULL, &h, &s)) {
+                               printf("Failed to parse UNC name %s\n",
+                                      unc_list[conn % num_unc_names]);
+                               exit(1);
+                       }
+                       fstrcpy(server, h);
+                       fstrcpy(share, s);
+               }
+       }
+
+
        slprintf(myname,sizeof(myname), "lock-%u-%u", getpid(), snum);
+       cli_credentials_set_workstation(servers[snum], myname, CRED_SPECIFIED);
 
        do {
-               status = smbcli_full_connection(NULL, &c, myname,
+               printf("\\\\%s\\%s\n", server, share);
+               status = smbcli_full_connection(NULL, &c, 
                                                server, 
                                                share, NULL,
-                                               &servers[snum]);
+                                               servers[snum], NULL);
                if (!NT_STATUS_IS_OK(status)) {
                        sleep(2);
                }
@@ -149,9 +181,9 @@ static void reconnect(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], int fnum
                                        fnum[server][conn][f] = -1;
                                }
                        }
-                       smbcli_shutdown(cli[server][conn]);
+                       talloc_free(cli[server][conn]);
                }
-               cli[server][conn] = connect_one(share[server], server);
+               cli[server][conn] = connect_one(share[server], server, conn);
                if (!cli[server][conn]) {
                        DEBUG(0,("Failed to connect to %s\n", share[server]));
                        exit(1);
@@ -161,7 +193,7 @@ static void reconnect(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], int fnum
 
 
 
-static BOOL test_one(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], 
+static bool test_one(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], 
                     int fnum[NSERVERS][NCONNECTIONS][NFILES],
                     struct record *rec)
 {
@@ -178,9 +210,35 @@ static BOOL test_one(struct smbcli_state *cli[NSERVERS][NCONNECTIONS],
        case OP_LOCK:
                /* set a lock */
                for (server=0;server<NSERVERS;server++) {
-                       ret[server] = NT_STATUS_IS_OK(smbcli_lock64(cli[server][conn]->tree, 
-                                                fnum[server][conn][f],
-                                                start, len, LOCK_TIMEOUT, op));
+                       NTSTATUS res;
+                       struct smbcli_tree *tree=cli[server][conn]->tree;
+                       int fn=fnum[server][conn][f];
+
+                       if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
+                               res=smbcli_lock(tree, fn, start, len, LOCK_TIMEOUT, rec->lock_op);
+                       } else {
+                               union smb_lock parms;
+                               int ltype;
+                               struct smb_lock_entry lock[1];
+
+                               parms.lockx.level = RAW_LOCK_LOCKX;
+                               parms.lockx.in.file.fnum = fn;
+       
+                               ltype = (rec->lock_op == READ_LOCK? 1 : 0);
+                               ltype |= LOCKING_ANDX_LARGE_FILES;
+                               parms.lockx.in.mode = ltype;
+                               parms.lockx.in.timeout = LOCK_TIMEOUT;
+                               parms.lockx.in.ulock_cnt = 0;
+                               parms.lockx.in.lock_cnt = 1;
+                               lock[0].pid = rec->pid;
+                               lock[0].offset = start;
+                               lock[0].count = len;
+                               parms.lockx.in.locks = &lock[0];
+
+                               res = smb_raw_lock(tree, &parms);
+                       }
+
+                       ret[server] = NT_STATUS_IS_OK(res); 
                        status[server] = smbcli_nt_error(cli[server][conn]->tree);
                        if (!exact_error_codes && 
                            NT_STATUS_EQUAL(status[server], 
@@ -201,9 +259,32 @@ static BOOL test_one(struct smbcli_state *cli[NSERVERS][NCONNECTIONS],
        case OP_UNLOCK:
                /* unset a lock */
                for (server=0;server<NSERVERS;server++) {
-                       ret[server] = NT_STATUS_IS_OK(smbcli_unlock64(cli[server][conn]->tree, 
-                                                  fnum[server][conn][f],
-                                                  start, len));
+                       NTSTATUS res;
+                       struct smbcli_tree *tree=cli[server][conn]->tree;
+                       int fn=fnum[server][conn][f];
+
+
+                       if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
+                               res=smbcli_unlock(tree, fn, start, len);
+                       } else {
+                               union smb_lock parms;
+                               struct smb_lock_entry lock[1];
+
+                               parms.lockx.level = RAW_LOCK_LOCKX;
+                               parms.lockx.in.file.fnum = fn;
+                               parms.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
+                               parms.lockx.in.timeout = 0;
+                               parms.lockx.in.ulock_cnt = 1;
+                               parms.lockx.in.lock_cnt = 0;
+                               lock[0].pid = rec->pid;
+                               lock[0].count = len;
+                               lock[0].offset = start;
+                               parms.lockx.in.locks = &lock[0];
+
+                               res = smb_raw_lock(tree, &parms);
+                       }
+
+                       ret[server] = NT_STATUS_IS_OK(res);
                        status[server] = smbcli_nt_error(cli[server][conn]->tree);
                }
                if (showall || 
@@ -328,6 +409,10 @@ static void test_locks(char *share[NSERVERS])
                                random() % (lock_range-(recorded[n].start-lock_base));
                        recorded[n].start *= RANGE_MULTIPLE;
                        recorded[n].len *= RANGE_MULTIPLE;
+                       recorded[n].pid = random()%3;
+                       if (recorded[n].pid == 2) {
+                               recorded[n].pid = 0xFFFF; /* see if its magic */
+                       }
                        r1 = random() % 100;
                        r2 = random() % 100;
                        if (r1 < READ_PCT) {
@@ -443,6 +528,7 @@ static void usage(void)
         -R range    set lock range\n\
         -B base     set lock base\n\
         -M min      set min lock length\n\
+        -l filename unclist file\n\
 ");
 }
 
@@ -453,7 +539,8 @@ static void usage(void)
 {
        char *share[NSERVERS];
        int opt;
-       int seed, server, i;
+       int seed, server;
+       int username_count=0;
 
        setlinebuf(stdout);
 
@@ -474,17 +561,25 @@ static void usage(void)
        argc -= NSERVERS;
        argv += NSERVERS;
 
-       lp_load(dyn_CONFIGFILE,True,False,False);
-       load_interfaces();
+       lp_load(dyn_CONFIGFILE);
+
+       servers[0] = cli_credentials_init(talloc_autofree_context());
+       servers[1] = cli_credentials_init(talloc_autofree_context());
+       cli_credentials_guess(servers[0]);
+       cli_credentials_guess(servers[1]);
 
        seed = time(NULL);
 
-       while ((opt = getopt(argc, argv, "U:s:ho:aAW:OR:B:M:EZW:")) != EOF) {
+       while ((opt = getopt(argc, argv, "U:s:ho:aAW:OR:B:M:EZW:l:")) != EOF) {
                switch (opt) {
                case 'U':
-                       i = servers[0].username?1:0;
-                       cli_credentials_parse_string(&servers[0], optarg, CRED_SPECIFIED);
-
+                       if (username_count == 2) {
+                               usage();
+                               exit(1);
+                       }
+                       cli_credentials_parse_string(servers[username_count], 
+                                                    optarg, CRED_SPECIFIED);
+                       username_count++;
                        break;
                case 'R':
                        lock_range = strtol(optarg, NULL, 0);
@@ -519,8 +614,11 @@ static void usage(void)
                case 'E':
                        exact_error_codes = True;
                        break;
+               case 'l':
+                       lp_set_cmdline(global_loadparm, "torture:unclist", optarg);
+                       break;
                case 'W':
-                       lp_set_cmdline("workgroup", optarg);
+                       lp_set_cmdline(global_loadparm, "workgroup", optarg);
                        break;
                case 'h':
                        usage();
@@ -531,16 +629,15 @@ static void usage(void)
                }
        }
 
-       if (!servers[0].username) {
+       if (username_count == 0) {
                usage();
                return -1;
        }
-       if (!servers[1].username) {
-               servers[1].username = servers[0].username;
-               servers[1].password = servers[0].password;
+       if (username_count == 1) {
+               servers[1] = servers[0];
        }
 
-       locktest_init_subsystems;
+       gensec_init();
 
        argc -= optind;
        argv += optind;
@@ -553,3 +650,4 @@ static void usage(void)
 
        return(0);
 }
+