subunit: Support formatting compatible with upstream subunit, for consistency.
[sfrench/samba-autobuild/.git] / source4 / torture / locktest.c
index fcb229df083db9992c260ec5ca46357926796e27..b3ee8fc28f9d47b8105d4f35fd7bf1074a29f9d0 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 "lib/cmdline/popt_common.h"
+#include "lib/events/events.h"
+#include "system/filesys.h"
+#include "system/time.h"
+#include "auth/credentials/credentials.h"
+#include "auth/gensec/gensec.h"
+#include "libcli/libcli.h"
+#include "param/param.h"
+#include "libcli/resolve/resolve.h"
 
-static fstring password[2];
-static fstring username[2];
-static int got_user;
-static int got_pass;
-static BOOL use_kerberos;
 static int numops = 1000;
-static BOOL showall;
-static BOOL analyze;
-static BOOL hide_unlock_fails;
-static BOOL use_oplocks;
-static unsigned lock_range = 100;
-static unsigned lock_base = 0;
-static unsigned min_length = 0;
-static BOOL exact_error_codes;
-static BOOL zero_zero;
+static int showall;
+static int analyze;
+static int hide_unlock_fails;
+static int use_oplocks;
+static unsigned int lock_range = 100;
+static unsigned int lock_base = 0;
+static unsigned int min_length = 0;
+static int exact_error_codes;
+static int zero_zero;
 
 #define FILENAME "\\locktest.dat"
 
@@ -47,7 +50,7 @@ static BOOL zero_zero;
 #define NFILES 2
 #define LOCK_TIMEOUT 0
 
-#define NASTY_POSIX_LOCK_HACK 0
+static struct cli_credentials *servers[NSERVERS];
 
 enum lock_op {OP_LOCK, OP_UNLOCK, OP_REOPEN};
 
@@ -55,8 +58,9 @@ struct record {
        enum lock_op lock_op;
        enum brl_type lock_type;
        char conn, f;
-       SMB_BIG_UINT start, len;
+       uint64_t start, len;
        char needed;
+       uint16_t pid;
 };
 
 #define PRESETS 0
@@ -102,29 +106,73 @@ static struct record *recorded;
 /***************************************************** 
 return a connection to a server
 *******************************************************/
-static struct cli_state *connect_one(char *share, int snum)
+static struct smbcli_state *connect_one(struct tevent_context *ev,
+                                       struct loadparm_context *lp_ctx,
+                                       TALLOC_CTX *mem_ctx,
+                                       char *share, int snum, int conn)
 {
-       struct cli_state *c;
-       fstring server, myname;
-       uint_t flags = 0;
+       struct smbcli_state *c;
+       char *server, *myname;
        NTSTATUS status;
+       int retries = 10;
+       struct smbcli_options options;
+       struct smbcli_session_options session_options;
 
-       fstrcpy(server,share+2);
+       lp_smbcli_options(lp_ctx, &options);
+       lp_smbcli_session_options(lp_ctx, &session_options);
+
+       printf("connect_one(%s, %d, %d)\n", share, snum, conn);
+
+       server = talloc_strdup(mem_ctx, share+2);
        share = strchr_m(server,'\\');
        if (!share) return NULL;
        *share = 0;
        share++;
 
-       slprintf(myname,sizeof(myname), "lock-%u-%u", getpid(), snum);
+       if (snum == 0) {
+               char **unc_list = NULL;
+               int num_unc_names;
+               const char *p;
+               p = lp_parm_string(lp_ctx, NULL, "torture", "unclist");
+               if (p) {
+                       char *h, *s;
+                       unc_list = file_lines_load(p, &num_unc_names, 0, 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);
+                       }
+                       server = talloc_strdup(mem_ctx, h);
+                       share = talloc_strdup(mem_ctx, s);
+               }
+       }
 
-       if (use_kerberos)
-               flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
-       
-       status = cli_full_connection(&c, myname,
-                                    server, NULL,  
-                                    share, "?????", 
-                                    username[snum], lp_workgroup(), 
-                                    password[snum], flags, NULL);
+
+       myname = talloc_asprintf(mem_ctx, "lock-%u-%u", getpid(), snum);
+       cli_credentials_set_workstation(servers[snum], myname, CRED_SPECIFIED);
+
+       do {
+               printf("\\\\%s\\%s\n", server, share);
+               status = smbcli_full_connection(NULL, &c, 
+                                               server, 
+                                               lp_smb_ports(lp_ctx),
+                                               share, NULL,
+                                               lp_socket_options(lp_ctx),
+                                               servers[snum], 
+                                               lp_resolve_context(lp_ctx),
+                                               ev, &options, &session_options,
+                                               lp_iconv_convenience(lp_ctx),
+                                               lp_gensec_settings(mem_ctx, lp_ctx));
+               if (!NT_STATUS_IS_OK(status)) {
+                       sleep(2);
+               }
+       } while (!NT_STATUS_IS_OK(status) && retries--);
 
        if (!NT_STATUS_IS_OK(status)) {
                return NULL;
@@ -134,7 +182,10 @@ static struct cli_state *connect_one(char *share, int snum)
 }
 
 
-static void reconnect(struct cli_state *cli[NSERVERS][NCONNECTIONS], int fnum[NSERVERS][NCONNECTIONS][NFILES],
+static void reconnect(struct tevent_context *ev,
+                     struct loadparm_context *lp_ctx,
+                         TALLOC_CTX *mem_ctx,
+                     struct smbcli_state *cli[NSERVERS][NCONNECTIONS], int fnum[NSERVERS][NCONNECTIONS][NFILES],
                      char *share[NSERVERS])
 {
        int server, conn, f;
@@ -144,13 +195,14 @@ static void reconnect(struct cli_state *cli[NSERVERS][NCONNECTIONS], int fnum[NS
                if (cli[server][conn]) {
                        for (f=0;f<NFILES;f++) {
                                if (fnum[server][conn][f] != -1) {
-                                       cli_close(cli[server][conn]->tree, fnum[server][conn][f]);
+                                       smbcli_close(cli[server][conn]->tree, fnum[server][conn][f]);
                                        fnum[server][conn][f] = -1;
                                }
                        }
-                       cli_shutdown(cli[server][conn]);
+                       talloc_free(cli[server][conn]);
                }
-               cli[server][conn] = connect_one(share[server], server);
+               cli[server][conn] = connect_one(ev, lp_ctx, mem_ctx, share[server], 
+                                               server, conn);
                if (!cli[server][conn]) {
                        DEBUG(0,("Failed to connect to %s\n", share[server]));
                        exit(1);
@@ -160,27 +212,53 @@ static void reconnect(struct cli_state *cli[NSERVERS][NCONNECTIONS], int fnum[NS
 
 
 
-static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS], 
+static bool test_one(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], 
                     int fnum[NSERVERS][NCONNECTIONS][NFILES],
                     struct record *rec)
 {
-       unsigned conn = rec->conn;
-       unsigned f = rec->f;
-       SMB_BIG_UINT start = rec->start;
-       SMB_BIG_UINT len = rec->len;
+       unsigned int conn = rec->conn;
+       unsigned int f = rec->f;
+       uint64_t start = rec->start;
+       uint64_t len = rec->len;
        enum brl_type op = rec->lock_type;
        int server;
-       BOOL ret[NSERVERS];
+       bool ret[NSERVERS];
        NTSTATUS status[NSERVERS];
 
        switch (rec->lock_op) {
        case OP_LOCK:
                /* set a lock */
                for (server=0;server<NSERVERS;server++) {
-                       ret[server] = cli_lock64(cli[server][conn]->tree, 
-                                                fnum[server][conn][f],
-                                                start, len, LOCK_TIMEOUT, op);
-                       status[server] = cli_nt_error(cli[server][conn]->tree);
+                       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], 
                                            NT_STATUS_FILE_LOCK_CONFLICT)) {
@@ -194,16 +272,39 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS],
                               op==READ_LOCK?"READ_LOCK":"WRITE_LOCK",
                               nt_errstr(status[0]), nt_errstr(status[1]));
                }
-               if (!NT_STATUS_EQUAL(status[0],status[1])) return False;
+               if (!NT_STATUS_EQUAL(status[0],status[1])) return false;
                break;
                
        case OP_UNLOCK:
                /* unset a lock */
                for (server=0;server<NSERVERS;server++) {
-                       ret[server] = cli_unlock64(cli[server][conn]->tree, 
-                                                  fnum[server][conn][f],
-                                                  start, len);
-                       status[server] = cli_nt_error(cli[server][conn]->tree);
+                       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 || 
                    (!hide_unlock_fails && !NT_STATUS_EQUAL(status[0],status[1]))) {
@@ -213,22 +314,22 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS],
                               nt_errstr(status[0]), nt_errstr(status[1]));
                }
                if (!hide_unlock_fails && !NT_STATUS_EQUAL(status[0],status[1])) 
-                       return False;
+                       return false;
                break;
 
        case OP_REOPEN:
                /* reopen the file */
                for (server=0;server<NSERVERS;server++) {
-                       cli_close(cli[server][conn]->tree, fnum[server][conn][f]);
+                       smbcli_close(cli[server][conn]->tree, fnum[server][conn][f]);
                        fnum[server][conn][f] = -1;
                }
                for (server=0;server<NSERVERS;server++) {
-                       fnum[server][conn][f] = cli_open(cli[server][conn]->tree, FILENAME,
+                       fnum[server][conn][f] = smbcli_open(cli[server][conn]->tree, FILENAME,
                                                         O_RDWR|O_CREAT,
                                                         DENY_NONE);
                        if (fnum[server][conn][f] == -1) {
                                printf("failed to reopen on share%d\n", server);
-                               return False;
+                               return false;
                        }
                }
                if (showall) {
@@ -238,10 +339,10 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS],
                break;
        }
 
-       return True;
+       return true;
 }
 
-static void close_files(struct cli_state *cli[NSERVERS][NCONNECTIONS], 
+static void close_files(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], 
                        int fnum[NSERVERS][NCONNECTIONS][NFILES])
 {
        int server, conn, f; 
@@ -250,16 +351,16 @@ static void close_files(struct cli_state *cli[NSERVERS][NCONNECTIONS],
        for (conn=0;conn<NCONNECTIONS;conn++)
        for (f=0;f<NFILES;f++) {
                if (fnum[server][conn][f] != -1) {
-                       cli_close(cli[server][conn]->tree, fnum[server][conn][f]);
+                       smbcli_close(cli[server][conn]->tree, fnum[server][conn][f]);
                        fnum[server][conn][f] = -1;
                }
        }
        for (server=0;server<NSERVERS;server++) {
-               cli_unlink(cli[server][0]->tree, FILENAME);
+               smbcli_unlink(cli[server][0]->tree, FILENAME);
        }
 }
 
-static void open_files(struct cli_state *cli[NSERVERS][NCONNECTIONS], 
+static void open_files(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], 
                       int fnum[NSERVERS][NCONNECTIONS][NFILES])
 {
        int server, conn, f; 
@@ -267,7 +368,7 @@ static void open_files(struct cli_state *cli[NSERVERS][NCONNECTIONS],
        for (server=0;server<NSERVERS;server++)
        for (conn=0;conn<NCONNECTIONS;conn++)
        for (f=0;f<NFILES;f++) {
-               fnum[server][conn][f] = cli_open(cli[server][conn]->tree, FILENAME,
+               fnum[server][conn][f] = smbcli_open(cli[server][conn]->tree, FILENAME,
                                                 O_RDWR|O_CREAT,
                                                 DENY_NONE);
                if (fnum[server][conn][f] == -1) {
@@ -279,12 +380,12 @@ static void open_files(struct cli_state *cli[NSERVERS][NCONNECTIONS],
 }
 
 
-static int retest(struct cli_state *cli[NSERVERS][NCONNECTIONS], 
+static int retest(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], 
                   int fnum[NSERVERS][NCONNECTIONS][NFILES],
                   int n)
 {
        int i;
-       printf("testing %u ...\n", n);
+       printf("Testing %u ...\n", n);
        for (i=0; i<n; i++) {
                if (i && i % 100 == 0) {
                        printf("%u\n", i);
@@ -303,16 +404,19 @@ static int retest(struct cli_state *cli[NSERVERS][NCONNECTIONS],
    we then do random locking ops in tamdem on the 4 fnums from each
    server and ensure that the results match
  */
-static void test_locks(char *share[NSERVERS])
+static int test_locks(struct tevent_context *ev,
+                     struct loadparm_context *lp_ctx,
+                         TALLOC_CTX *mem_ctx,
+                     char *share[NSERVERS])
 {
-       struct cli_state *cli[NSERVERS][NCONNECTIONS];
+       struct smbcli_state *cli[NSERVERS][NCONNECTIONS];
        int fnum[NSERVERS][NCONNECTIONS][NFILES];
        int n, i, n1, skip, r1, r2; 
 
        ZERO_STRUCT(fnum);
        ZERO_STRUCT(cli);
 
-       recorded = (struct record *)malloc(sizeof(*recorded) * numops);
+       recorded = malloc_array_p(struct record, numops);
 
        for (n=0; n<numops; n++) {
 #if PRESETS
@@ -322,11 +426,15 @@ static void test_locks(char *share[NSERVERS])
 #endif
                        recorded[n].conn = random() % NCONNECTIONS;
                        recorded[n].f = random() % NFILES;
-                       recorded[n].start = lock_base + ((unsigned)random() % (lock_range-1));
+                       recorded[n].start = lock_base + ((unsigned int)random() % (lock_range-1));
                        recorded[n].len =  min_length +
                                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) {
@@ -341,7 +449,7 @@ static void test_locks(char *share[NSERVERS])
                        } else {
                                recorded[n].lock_op = OP_REOPEN;
                        }
-                       recorded[n].needed = True;
+                       recorded[n].needed = true;
                        if (!zero_zero && recorded[n].start==0 && recorded[n].len==0) {
                                recorded[n].len = 1;
                        }
@@ -350,11 +458,16 @@ static void test_locks(char *share[NSERVERS])
 #endif
        }
 
-       reconnect(cli, fnum, share);
+       reconnect(ev, lp_ctx, mem_ctx, cli, fnum, share);
        open_files(cli, fnum);
        n = retest(cli, fnum, numops);
 
-       if (n == numops || !analyze) return;
+       if (n == numops || !analyze) {
+               if (n != numops) {
+                       return 1;
+               }
+               return 0;
+       }
        n++;
 
        skip = n/2;
@@ -363,14 +476,14 @@ static void test_locks(char *share[NSERVERS])
                n1 = n;
 
                close_files(cli, fnum);
-               reconnect(cli, fnum, share);
+               reconnect(ev, lp_ctx, mem_ctx, cli, fnum, share);
                open_files(cli, fnum);
 
                for (i=0;i<n-skip;i+=skip) {
                        int m, j;
                        printf("excluding %d-%d\n", i, i+skip-1);
                        for (j=i;j<i+skip;j++) {
-                               recorded[j].needed = False;
+                               recorded[j].needed = false;
                        }
 
                        close_files(cli, fnum);
@@ -379,7 +492,7 @@ static void test_locks(char *share[NSERVERS])
                        m = retest(cli, fnum, n);
                        if (m == n) {
                                for (j=i;j<i+skip;j++) {
-                                       recorded[j].needed = True;
+                                       recorded[j].needed = true;
                                }
                        } else {
                                if (i+(skip-1) < m) {
@@ -401,9 +514,9 @@ static void test_locks(char *share[NSERVERS])
        }
 
        close_files(cli, fnum);
-       reconnect(cli, fnum, share);
+       reconnect(ev, lp_ctx, mem_ctx, cli, fnum, share);
        open_files(cli, fnum);
-       showall = True;
+       showall = true;
        n1 = retest(cli, fnum, n);
        if (n1 != n-1) {
                printf("ERROR - inconsistent result (%u %u)\n", n1, n);
@@ -420,30 +533,16 @@ static void test_locks(char *share[NSERVERS])
                       (double)recorded[i].len,
                       recorded[i].needed);
        }       
+
+       return 1;
 }
 
 
 
-static void usage(void)
+static void usage(poptContext pc)
 {
-       printf(
-"Usage:\n\
-  locktest //server1/share1 //server2/share2 [options..]\n\
-  options:\n\
-        -U user%%pass        (may be specified twice)\n\
-        -k               use kerberos\n\
-        -s seed\n\
-        -o numops\n\
-        -u          hide unlock fails\n\
-        -a          (show all ops)\n\
-        -A          analyse for minimal ops\n\
-        -O          use oplocks\n\
-        -E          enable exact error code checking\n\
-        -Z          enable the zero/zero lock\n\
-        -R range    set lock range\n\
-        -B base     set lock base\n\
-        -M min      set min lock length\n\
-");
+       printf("Usage:\n\tlocktest //server1/share1 //server2/share2 [options..]\n");
+       poptPrintUsage(pc, stdout, 0);
 }
 
 /****************************************************************************
@@ -453,114 +552,105 @@ static void usage(void)
 {
        char *share[NSERVERS];
        int opt;
-       char *p;
        int seed, server;
+       int username_count=0;
+       struct tevent_context *ev;
+       struct loadparm_context *lp_ctx;
+       poptContext pc;
+       int argc_new, i;
+       char **argv_new;
+       enum {OPT_UNCLIST=1000};
+       struct poptOption long_options[] = {
+               POPT_AUTOHELP
+               {"seed",          0, POPT_ARG_INT,  &seed,      0,      "Seed to use for randomizer",   NULL},
+               {"num-ops",       0, POPT_ARG_INT,  &numops,    0,      "num ops",      NULL},
+               {"lockrange",     0, POPT_ARG_INT,  &lock_range,0,      "locking range", NULL},
+               {"lockbase",      0, POPT_ARG_INT,  &lock_base, 0,      "locking base", NULL},
+               {"minlength",     0, POPT_ARG_INT,  &min_length,0,      "min lock length", NULL},
+               {"hidefails",     0, POPT_ARG_NONE, &hide_unlock_fails,0,"hide unlock fails", NULL},
+               {"oplocks",       0, POPT_ARG_NONE, &use_oplocks,0,      "use oplocks", NULL},
+               {"showall",       0, POPT_ARG_NONE, &showall,    0,      "display all operations", NULL},
+               {"analyse",       0, POPT_ARG_NONE, &analyze,    0,      "do backtrack analysis", NULL},
+               {"zerozero",      0, POPT_ARG_NONE, &zero_zero,    0,      "do zero/zero lock", NULL},
+               {"exacterrors",   0, POPT_ARG_NONE, &exact_error_codes,0,"use exact error codes", NULL},
+               {"unclist",       0, POPT_ARG_STRING,   NULL,   OPT_UNCLIST,    "unclist",      NULL},
+               { "user", 'U',       POPT_ARG_STRING, NULL, 'U', "Set the network username", "[DOMAIN/]USERNAME[%PASSWORD]" },
+               POPT_COMMON_SAMBA
+               POPT_COMMON_CONNECTION
+               POPT_COMMON_CREDENTIALS
+               POPT_COMMON_VERSION
+               { NULL }
+       };
 
        setlinebuf(stdout);
+       seed = time(NULL);
 
-       setup_logging("locktest", DEBUG_STDOUT);
-
-       if (argc < 3 || argv[1][0] == '-') {
-               usage();
-               exit(1);
-       }
-
-       setup_logging(argv[0], DEBUG_STDOUT);
-
-       for (server=0;server<NSERVERS;server++) {
-               share[server] = argv[1+server];
-               all_string_sub(share[server],"/","\\",0);
-       }
-
-       argc -= NSERVERS;
-       argv += NSERVERS;
+       pc = poptGetContext("locktest", argc, (const char **) argv, long_options, 
+                           POPT_CONTEXT_KEEP_FIRST);
 
-       lp_load(dyn_CONFIGFILE,True,False,False);
-       load_interfaces();
+       poptSetOtherOptionHelp(pc, "<unc1> <unc2>");
 
-       if (getenv("USER")) {
-               fstrcpy(username[0],getenv("USER"));
-               fstrcpy(username[1],getenv("USER"));
-       }
+       lp_ctx = cmdline_lp_ctx;
+       servers[0] = cli_credentials_init(talloc_autofree_context());
+       servers[1] = cli_credentials_init(talloc_autofree_context());
+       cli_credentials_guess(servers[0], lp_ctx);
+       cli_credentials_guess(servers[1], lp_ctx);
 
-       seed = time(NULL);
-
-       while ((opt = getopt(argc, argv, "U:s:ho:aAW:OkR:B:M:EZ")) != EOF) {
+       while((opt = poptGetNextOpt(pc)) != -1) {
                switch (opt) {
-               case 'k':
-#ifdef HAVE_KRB5
-                       use_kerberos = True;
-#else
-                       d_printf("No kerberos support compiled in\n");
-                       exit(1);
-#endif
+               case OPT_UNCLIST:
+                       lp_set_cmdline(cmdline_lp_ctx, "torture:unclist", poptGetOptArg(pc));
                        break;
                case 'U':
-                       got_user = 1;
-                       if (got_pass == 2) {
-                               d_printf("Max of 2 usernames\n");
+                       if (username_count == 2) {
+                               usage(pc);
                                exit(1);
                        }
-                       fstrcpy(username[got_pass],optarg);
-                       p = strchr_m(username[got_pass],'%');
-                       if (p) {
-                               *p = 0;
-                               fstrcpy(password[got_pass], p+1);
-                               got_pass++;
-                       }
-                       break;
-               case 'R':
-                       lock_range = strtol(optarg, NULL, 0);
-                       break;
-               case 'B':
-                       lock_base = strtol(optarg, NULL, 0);
-                       break;
-               case 'M':
-                       min_length = strtol(optarg, NULL, 0);
+                       cli_credentials_parse_string(servers[username_count], poptGetOptArg(pc), CRED_SPECIFIED);
+                       username_count++;
                        break;
-               case 's':
-                       seed = atoi(optarg);
-                       break;
-               case 'u':
-                       hide_unlock_fails = True;
-                       break;
-               case 'o':
-                       numops = atoi(optarg);
-                       break;
-               case 'O':
-                       use_oplocks = True;
-                       break;
-               case 'a':
-                       showall = True;
-                       break;
-               case 'A':
-                       analyze = True;
-                       break;
-               case 'Z':
-                       zero_zero = True;
-                       break;
-               case 'E':
-                       exact_error_codes = True;
+               }
+       }
+
+       argv_new = discard_const_p(char *, poptGetArgs(pc));
+       argc_new = argc;
+       for (i=0; i<argc; i++) {
+               if (argv_new[i] == NULL) {
+                       argc_new = i;
                        break;
-               case 'h':
-                       usage();
-                       exit(1);
-               default:
-                       printf("Unknown option %c (%d)\n", (char)opt, opt);
-                       exit(1);
                }
        }
 
-       if(use_kerberos && !got_user) got_pass = True;
+       if (!(argc_new >= 3)) {
+               usage(pc);
+               exit(1);
+       }
+
+       setup_logging("locktest", DEBUG_STDOUT);
+
+       for (server=0;server<NSERVERS;server++) {
+               share[server] = argv_new[1+server];
+               all_string_sub(share[server],"/","\\",0);
+       }
+
+       lp_ctx = cmdline_lp_ctx;
 
-       argc -= optind;
-       argv += optind;
+       if (username_count == 0) {
+               usage(pc);
+               return -1;
+       }
+       if (username_count == 1) {
+               servers[1] = servers[0];
+       }
+
+       ev = s4_event_context_init(talloc_autofree_context());
+
+       gensec_init(lp_ctx);
 
        DEBUG(0,("seed=%u base=%d range=%d min_length=%d\n", 
                 seed, lock_base, lock_range, min_length));
        srandom(seed);
 
-       test_locks(share);
-
-       return(0);
+       return test_locks(ev, lp_ctx, NULL, share);
 }
+