r5963: Fix parameter passing for gentest and locktest
[samba.git] / source4 / torture / gentest.c
index 72b8e8d4049b6c699a9354bc7083a8a11a08c4d8..5f036910b60b477e7abbbd39746393be15b5c102 100644 (file)
 */
 
 #include "includes.h"
+#include "dynconfig.h"
+#include "system/time.h"
+#include "system/filesys.h"
+#include "request.h"
+#include "libcli/raw/libcliraw.h"
+#include "librpc/gen_ndr/ndr_security.h"
 
 #define NSERVERS 2
 #define NINSTANCES 2
@@ -51,11 +57,10 @@ static uint_t num_open_handles;
 /* state information for the servers. We open NINSTANCES connections to
    each server */
 static struct {
-       struct cli_state *cli[NINSTANCES];
+       struct smbcli_state *cli[NINSTANCES];
        char *server_name;
        char *share_name;
-       char *username;
-       char *password;
+       struct cli_credentials *credentials;
 } servers[NSERVERS];
 
 /* the seeds and flags for each operation */
@@ -68,9 +73,9 @@ static struct {
 /* oplock break info */
 static struct {
        BOOL got_break;
-       uint16 fnum;
-       uint16 handle;
-       uint8 level;
+       uint16_t fnum;
+       uint16_t handle;
+       uint8_t level;
        BOOL do_close;
 } oplocks[NSERVERS][NINSTANCES];
 
@@ -94,8 +99,8 @@ static struct {
 
 #define BAD_HANDLE 0xFFFE
 
-static BOOL oplock_handler(struct cli_transport *transport, uint16 tid, uint16 fnum, uint8 level, void *private);
-static void idle_func(struct cli_transport *transport, void *private);
+static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *private);
+static void idle_func(struct smbcli_transport *transport, void *private);
 
 /*
   check if a string should be ignored. This is used as the basis
@@ -127,8 +132,8 @@ static BOOL connect_servers_fast(void)
        for (h=0;h<options.max_open_handles;h++) {
                if (!open_handles[h].active) continue;
                for (i=0;i<NSERVERS;i++) {
-                       if (!cli_close(servers[i].cli[open_handles[h].instance],
-                                      open_handles[h].server_fnum[i])) {
+                       if (NT_STATUS_IS_ERR((smbcli_close(servers[i].cli[open_handles[h].instance]->tree,
+                                      open_handles[h].server_fnum[i])))) {
                                return False;
                        }
                        open_handles[h].active = False;
@@ -158,8 +163,8 @@ static BOOL connect_servers(void)
        for (i=0;i<NSERVERS;i++) {
                for (j=0;j<NINSTANCES;j++) {
                        if (servers[i].cli[j]) {
-                               cli_tdis(servers[i].cli[j]);
-                               cli_shutdown(servers[i].cli[j]);
+                               smbcli_tdis(servers[i].cli[j]);
+                               smbcli_shutdown(servers[i].cli[j]);
                                servers[i].cli[j] = NULL;
                        }
                }
@@ -170,13 +175,13 @@ static BOOL connect_servers(void)
                        NTSTATUS status;
                        printf("Connecting to \\\\%s\\%s as %s - instance %d\n",
                               servers[i].server_name, servers[i].share_name, 
-                              servers[i].username, j);
-                       status = cli_full_connection(&servers[i].cli[j],
-                                                    "gentest",
-                                                    servers[i].server_name, NULL, 
-                                                    servers[i].share_name, "?????"
-                                                    servers[i].username, lp_workgroup(),
-                                                    servers[i].password, 0, NULL);
+                              servers[i].credentials->username, j);
+
+                       status = smbcli_full_connection(NULL, &servers[i].cli[j],
+                                                       "gentest",
+                                                       servers[i].server_name
+                                                       servers[i].share_name, NULL, 
+                                                       servers[i].credentials);
                        if (!NT_STATUS_IS_OK(status)) {
                                printf("Failed to connect to \\\\%s\\%s - %s\n",
                                       servers[i].server_name, servers[i].share_name,
@@ -184,8 +189,8 @@ static BOOL connect_servers(void)
                                return False;
                        }
 
-                       cli_oplock_handler(servers[i].cli[j]->transport, oplock_handler, NULL);
-                       cli_transport_idle_handler(servers[i].cli[j]->transport, idle_func, 10, NULL);
+                       smbcli_oplock_handler(servers[i].cli[j]->transport, oplock_handler, NULL);
+                       smbcli_transport_idle_handler(servers[i].cli[j]->transport, idle_func, 50000, NULL);
                }
        }
 
@@ -206,7 +211,7 @@ static uint_t time_skew(void)
 /*
   turn an fnum for an instance into a handle
 */
-static uint_t fnum_to_handle(int server, int instance, uint16 fnum)
+static uint_t fnum_to_handle(int server, int instance, uint16_t fnum)
 {
        uint_t i;
        for (i=0;i<options.max_open_handles;i++) {
@@ -224,7 +229,7 @@ static uint_t fnum_to_handle(int server, int instance, uint16 fnum)
 /*
   add some newly opened handles
 */
-static void gen_add_handle(int instance, const char *name, uint16 fnums[NSERVERS])
+static void gen_add_handle(int instance, const char *name, uint16_t fnums[NSERVERS])
 {
        int i, h;
        for (h=0;h<options.max_open_handles;h++) {
@@ -234,10 +239,10 @@ static void gen_add_handle(int instance, const char *name, uint16 fnums[NSERVERS
                /* we have to force close a random handle */
                h = random() % options.max_open_handles;
                for (i=0;i<NSERVERS;i++) {
-                       if (!cli_close(servers[i].cli[open_handles[h].instance]
-                                      open_handles[h].server_fnum[i])) {
+                       if (NT_STATUS_IS_ERR((smbcli_close(servers[i].cli[open_handles[h].instance]->tree
+                                      open_handles[h].server_fnum[i])))) {
                                printf("INTERNAL ERROR: Close failed when recovering handle! - %s\n",
-                                      cli_errstr(servers[i].cli[open_handles[h].instance]));
+                                      smbcli_errstr(servers[i].cli[open_handles[h].instance]->tree));
                        }
                }
                printf("Recovered handle %d\n", h);
@@ -260,7 +265,7 @@ static void gen_add_handle(int instance, const char *name, uint16 fnums[NSERVERS
 /*
   remove a closed handle
 */
-static void gen_remove_handle(int instance, uint16 fnums[NSERVERS])
+static void gen_remove_handle(int instance, uint16_t fnums[NSERVERS])
 {
        int h;
        for (h=0;h<options.max_open_handles;h++) {
@@ -290,7 +295,7 @@ static BOOL gen_chance(uint_t chance)
 /*
   map an internal handle number to a server fnum
 */
-static uint16 gen_lookup_fnum(int server, uint16 handle)
+static uint16_t gen_lookup_fnum(int server, uint16_t handle)
 {
        if (handle == BAD_HANDLE) return handle;
        return open_handles[handle].server_fnum[server];
@@ -299,9 +304,9 @@ static uint16 gen_lookup_fnum(int server, uint16 handle)
 /*
   return a file handle
 */
-static uint16 gen_fnum(int instance)
+static uint16_t gen_fnum(int instance)
 {
-       uint16 h;
+       uint16_t h;
        int count = 0;
 
        if (gen_chance(20)) return BAD_HANDLE;
@@ -320,7 +325,7 @@ static uint16 gen_fnum(int instance)
   return a file handle, but skewed so we don't close the last
   couple of handles too readily
 */
-static uint16 gen_fnum_close(int instance)
+static uint16_t gen_fnum_close(int instance)
 {
        if (num_open_handles < 3) {
                if (gen_chance(80)) return BAD_HANDLE;
@@ -342,7 +347,7 @@ static int gen_int_range(uint_t min, uint_t max)
   return a fnum for use as a root fid
   be careful to call GEN_SET_FNUM() when you use this!
 */
-static uint16 gen_root_fid(int instance)
+static uint16_t gen_root_fid(int instance)
 {
        if (gen_chance(5)) return gen_fnum(instance);
        return 0;
@@ -412,7 +417,7 @@ static const char *gen_fname(void)
 */
 static const char *gen_fname_open(int instance)
 {
-       uint16 h;
+       uint16_t h;
        h = gen_fnum(instance);
        if (h == BAD_HANDLE) {
                return gen_fname();
@@ -445,7 +450,7 @@ static const char *gen_pattern(void)
 /*
   generate a bitmask
 */
-static uint32 gen_bits_mask(uint_t mask)
+static uint32_t gen_bits_mask(uint_t mask)
 {
        uint_t ret = random();
        return ret & mask;
@@ -455,7 +460,7 @@ static uint32 gen_bits_mask(uint_t mask)
   generate a bitmask with high probability of the first mask
   and low of the second
 */
-static uint32 gen_bits_mask2(uint32 mask1, uint32 mask2)
+static uint32_t gen_bits_mask2(uint32_t mask1, uint32_t mask2)
 {
        if (gen_chance(10)) return gen_bits_mask(mask2);
        return gen_bits_mask(mask1);
@@ -472,7 +477,7 @@ static BOOL gen_bool(void)
 /*
   generate ntrename flags
 */
-static uint16 gen_rename_flags(void)
+static uint16_t gen_rename_flags(void)
 {
        if (gen_chance(30)) return RENAME_FLAG_RENAME;
        if (gen_chance(30)) return RENAME_FLAG_HARD_LINK;
@@ -484,7 +489,7 @@ static uint16 gen_rename_flags(void)
 /*
   return a lockingx lock mode
 */
-static uint16 gen_lock_mode(void)
+static uint16_t gen_lock_mode(void)
 {
        if (gen_chance(5))  return gen_bits_mask(0xFFFF);
        if (gen_chance(20)) return gen_bits_mask(0x1F);
@@ -494,7 +499,7 @@ static uint16 gen_lock_mode(void)
 /*
   generate a pid 
 */
-static uint16 gen_pid(void)
+static uint16_t gen_pid(void)
 {
        if (gen_chance(10)) return gen_bits_mask(0xFFFF);
        return getpid();
@@ -503,7 +508,7 @@ static uint16 gen_pid(void)
 /*
   generate a lock count
 */
-static SMB_OFF_T gen_lock_count(void)
+static off_t gen_lock_count(void)
 {
        return gen_int_range(0, 3);
 }
@@ -511,7 +516,7 @@ static SMB_OFF_T gen_lock_count(void)
 /*
   generate a ntcreatex flags field
 */
-static uint32 gen_ntcreatex_flags(void)
+static uint32_t gen_ntcreatex_flags(void)
 {
        if (gen_chance(70)) return NTCREATEX_FLAGS_EXTENDED;
        return gen_bits_mask2(0x1F, 0xFFFFFFFF);
@@ -520,17 +525,17 @@ static uint32 gen_ntcreatex_flags(void)
 /*
   generate a NT access mask
 */
-static uint32 gen_access_mask(void)
+static uint32_t gen_access_mask(void)
 {
-       if (gen_chance(50)) return SEC_RIGHT_MAXIMUM_ALLOWED;
-       if (gen_chance(20)) return GENERIC_RIGHTS_FILE_ALL_ACCESS;
+       if (gen_chance(50)) return SEC_FLAG_MAXIMUM_ALLOWED;
+       if (gen_chance(20)) return SEC_FILE_ALL;
        return gen_bits_mask(0xFFFFFFFF);
 }
 
 /*
   generate a ntcreatex create options bitfield
 */
-static uint32 gen_create_options(void)
+static uint32_t gen_create_options(void)
 {
        if (gen_chance(20)) return gen_bits_mask(0xFFFFFFFF);
        if (gen_chance(50)) return 0;
@@ -540,7 +545,7 @@ static uint32 gen_create_options(void)
 /*
   generate a ntcreatex open disposition
 */
-static uint32 gen_open_disp(void)
+static uint32_t gen_open_disp(void)
 {
        if (gen_chance(10)) return gen_bits_mask(0xFFFFFFFF);
        return gen_int_range(0, 5);
@@ -549,7 +554,7 @@ static uint32 gen_open_disp(void)
 /*
   generate an openx open mode
 */
-static uint16 gen_openx_mode(void)
+static uint16_t gen_openx_mode(void)
 {
        if (gen_chance(20)) return gen_bits_mask(0xFFFF);
        if (gen_chance(20)) return gen_bits_mask(0xFF);
@@ -559,7 +564,7 @@ static uint16 gen_openx_mode(void)
 /*
   generate an openx flags field
 */
-static uint16 gen_openx_flags(void)
+static uint16_t gen_openx_flags(void)
 {
        if (gen_chance(20)) return gen_bits_mask(0xFFFF);
        return gen_bits_mask(0x7);
@@ -568,7 +573,7 @@ static uint16 gen_openx_flags(void)
 /*
   generate an openx open function
 */
-static uint16 gen_openx_func(void)
+static uint16_t gen_openx_func(void)
 {
        if (gen_chance(20)) return gen_bits_mask(0xFFFF);
        return gen_bits_mask(0x13);
@@ -577,7 +582,7 @@ static uint16 gen_openx_func(void)
 /*
   generate a file attrib combination
 */
-static uint32 gen_attrib(void)
+static uint32_t gen_attrib(void)
 {
        if (gen_chance(20)) return gen_bits_mask(0xFFFFFFFF);
        return gen_bits_mask(FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY);
@@ -605,7 +610,7 @@ static NTTIME gen_nttime(void)
 /*
   generate a milliseconds protocol timeout
 */
-static uint32 gen_timeout(void)
+static uint32_t gen_timeout(void)
 {
        if (gen_chance(98)) return 0;
        return random() % 50;
@@ -631,7 +636,7 @@ static uint_t gen_alloc_size(void)
 /*
   generate an ea_struct
 */
-struct ea_struct gen_ea_struct(void)
+static struct ea_struct gen_ea_struct(void)
 {
        struct ea_struct ea;
        const char *names[] = {"EAONE", 
@@ -670,13 +675,13 @@ struct ea_struct gen_ea_struct(void)
 /*
   this is called when a change notify reply comes in
 */
-static void async_notify(struct cli_request *req)
+static void async_notify(struct smbcli_request *req)
 {
        struct smb_notify notify;
        NTSTATUS status;
        int i, j;
-       uint16 tid;
-       struct cli_transport *transport = req->transport;
+       uint16_t tid;
+       struct smbcli_transport *transport = req->transport;
 
        tid = SVAL(req->in.hdr, HDR_TID);
 
@@ -704,13 +709,13 @@ static void async_notify(struct cli_request *req)
 /*
   the oplock handler will either ack the break or close the file
 */
-static BOOL oplock_handler(struct cli_transport *transport, uint16 tid, uint16 fnum, uint8 level, void *private)
+static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *private)
 {
        union smb_close io;
        NTSTATUS status;
        int i, j;
        BOOL do_close;
-       struct cli_tree *tree = NULL;
+       struct smbcli_tree *tree = NULL;
 
        srandom(current_op.seed);
        do_close = gen_chance(50);
@@ -736,7 +741,7 @@ static BOOL oplock_handler(struct cli_transport *transport, uint16 tid, uint16 f
 
        if (!do_close) {
                printf("oplock ack fnum=%d\n", fnum);
-               return cli_oplock_ack(tree, fnum, level == 1? 0x102 : 2);
+               return smbcli_oplock_ack(tree, fnum, level);
        }
 
        printf("oplock close fnum=%d\n", fnum);
@@ -758,19 +763,14 @@ static BOOL oplock_handler(struct cli_transport *transport, uint16 tid, uint16 f
   an operation on another connection blocking until that break is acked
   we check for operations on all transports in the idle function
 */
-static void idle_func(struct cli_transport *transport, void *private)
+static void idle_func(struct smbcli_transport *transport, void *private)
 {
        int i, j;
        for (i=0;i<NSERVERS;i++) {
                for (j=0;j<NINSTANCES;j++) {
                        if (servers[i].cli[j] &&
-                           transport != servers[i].cli[j]->transport &&
-                           cli_transport_pending(servers[i].cli[j]->transport)) {
-                               if (!cli_request_receive_next(servers[i].cli[j]->transport)) {
-                                       printf("Connection to server %d instance %d died!\n",
-                                              i, j);
-                                       exit(1);
-                               }
+                           transport != servers[i].cli[j]->transport) {
+                               smbcli_transport_process(servers[i].cli[j]->transport);
                        }
                }
        }
@@ -808,13 +808,7 @@ static void check_pending(void)
 
        for (j=0;j<NINSTANCES;j++) {
                for (i=0;i<NSERVERS;i++) {
-                       if (cli_transport_pending(servers[i].cli[j]->transport)) {
-                               if (!cli_request_receive_next(servers[i].cli[j]->transport)) {
-                                       printf("Connection to server %d instance %d died!\n",
-                                              i, j);
-                                       exit(1);                                        
-                               }
-                       }
+                       smbcli_transport_process(servers[i].cli[j]->transport);
                }
        }       
 }
@@ -852,7 +846,7 @@ again:
        for (j=0;j<NINSTANCES;j++) {
                if (oplocks[0][j].got_break &&
                    oplocks[0][j].do_close) {
-                       uint16 fnums[NSERVERS];
+                       uint16_t fnums[NSERVERS];
                        for (i=0;i<NSERVERS;i++) {
                                fnums[i] = oplocks[i][j].fnum;
                        }
@@ -949,7 +943,7 @@ again:
        ZERO_STRUCT(oplocks); \
        ZERO_STRUCT(notifies); \
        for (i=0;i<NSERVERS;i++) { \
-               struct cli_tree *tree = servers[i].cli[instance]->tree; \
+               struct smbcli_tree *tree = servers[i].cli[instance]->tree; \
                status[i] = call; \
        } \
        current_op.status = status[0]; \
@@ -968,7 +962,7 @@ again:
 } while(0)
 
 #define ADD_HANDLE(name, field) do { \
-       uint16 fnums[NSERVERS]; \
+       uint16_t fnums[NSERVERS]; \
        int i; \
        for (i=0;i<NSERVERS;i++) { \
                fnums[i] = parm[i].field; \
@@ -977,7 +971,7 @@ again:
 } while(0)
 
 #define REMOVE_HANDLE(field) do { \
-       uint16 fnums[NSERVERS]; \
+       uint16_t fnums[NSERVERS]; \
        int i; \
        for (i=0;i<NSERVERS;i++) { \
                fnums[i] = parm[i].field; \
@@ -1031,12 +1025,12 @@ again:
 } while(0)
 
 #define CHECK_NTTIMES_EQUAL(field) do { \
-       if (ABS(nt_time_to_unix(&parm[0].field) - \
-               nt_time_to_unix(&parm[1].field)) > time_skew() && \
+       if (ABS(nt_time_to_unix(parm[0].field) - \
+               nt_time_to_unix(parm[1].field)) > time_skew() && \
            !ignore_pattern(#field)) { \
                printf("Mismatch in %s - 0x%x 0x%x\n", #field, \
-                      (int)nt_time_to_unix(&parm[0].field), \
-                      (int)nt_time_to_unix(&parm[1].field)); \
+                      (int)nt_time_to_unix(parm[0].field), \
+                      (int)nt_time_to_unix(parm[1].field)); \
                return False; \
        } \
 } while(0)
@@ -1086,6 +1080,40 @@ static BOOL handler_openx(int instance)
 }
 
 
+/*
+  generate open operations
+*/
+static BOOL handler_open(int instance)
+{
+       union smb_open parm[NSERVERS];
+       NTSTATUS status[NSERVERS];
+
+       parm[0].openold.level = RAW_OPEN_OPEN;
+       parm[0].openold.in.open_mode = gen_bits_mask2(0xF, 0xFFFF);
+       parm[0].openold.in.search_attrs = gen_attrib();
+       parm[0].openold.in.fname = gen_fname_open(instance);
+
+       if (!options.use_oplocks) {
+               /* mask out oplocks */
+               parm[0].openold.in.open_mode &= ~(OPENX_FLAGS_REQUEST_OPLOCK|
+                                                 OPENX_FLAGS_REQUEST_BATCH_OPLOCK);
+       }
+       
+       GEN_COPY_PARM;
+       GEN_CALL(smb_raw_open(tree, current_op.mem_ctx, &parm[i]));
+
+       CHECK_EQUAL(openold.out.attrib);
+       CHECK_TIMES_EQUAL(openold.out.write_time);
+       CHECK_EQUAL(openold.out.size);
+       CHECK_EQUAL(openold.out.rmode);
+
+       /* open creates a new file handle */
+       ADD_HANDLE(parm[0].openold.in.fname, openold.out.fnum);
+
+       return True;
+}
+
+
 /*
   generate ntcreatex operations
 */
@@ -1256,7 +1284,7 @@ static BOOL handler_ntrename(int instance)
        parm[0].ntrename.in.old_name = gen_fname();
        parm[0].ntrename.in.new_name = gen_fname();
        parm[0].ntrename.in.attrib = gen_attrib();
-       parm[0].ntrename.in.root_fid = gen_root_fid(instance);
+       parm[0].ntrename.in.cluster_size = gen_bits_mask2(0, 0xFFFFFFF);
        parm[0].ntrename.in.flags = gen_rename_flags();
 
        GEN_COPY_PARM;
@@ -1266,6 +1294,28 @@ static BOOL handler_ntrename(int instance)
 }
 
 
+/*
+  generate seek operations
+*/
+static BOOL handler_seek(int instance)
+{
+       struct smb_seek parm[NSERVERS];
+       NTSTATUS status[NSERVERS];
+
+       parm[0].in.fnum = gen_fnum(instance);
+       parm[0].in.mode = gen_bits_mask2(0x3, 0xFFFF);
+       parm[0].in.offset = gen_offset();
+
+       GEN_COPY_PARM;
+       GEN_SET_FNUM(in.fnum);
+       GEN_CALL(smb_raw_seek(tree, &parm[i]));
+
+       CHECK_EQUAL(out.offset);
+
+       return True;
+}
+
+
 /*
   generate readx operations
 */
@@ -1280,8 +1330,8 @@ static BOOL handler_readx(int instance)
        parm[0].readx.in.mincnt = gen_io_count();
        parm[0].readx.in.maxcnt = gen_io_count();
        parm[0].readx.in.remaining = gen_io_count();
-       parm[0].readx.out.data = talloc(current_op.mem_ctx,
-                                       MAX(parm[0].readx.in.mincnt, parm[0].readx.in.maxcnt));
+       parm[0].readx.out.data = talloc_size(current_op.mem_ctx,
+                                            MAX(parm[0].readx.in.mincnt, parm[0].readx.in.maxcnt));
 
        GEN_COPY_PARM;
        GEN_SET_FNUM(readx.in.fnum);
@@ -1308,7 +1358,7 @@ static BOOL handler_writex(int instance)
        parm[0].writex.in.wmode = gen_bits_mask(0xFFFF);
        parm[0].writex.in.remaining = gen_io_count();
        parm[0].writex.in.count = gen_io_count();
-       parm[0].writex.in.data = talloc_zero(current_op.mem_ctx, parm[0].writex.in.count);
+       parm[0].writex.in.data = talloc_zero_size(current_op.mem_ctx, parm[0].writex.in.count);
 
        GEN_COPY_PARM;
        GEN_SET_FNUM(writex.in.fnum);
@@ -1342,8 +1392,9 @@ static BOOL handler_lockingx(int instance)
        } while (nlocks == 0);
 
        if (nlocks > 0) {
-               parm[0].lockx.in.locks = talloc(current_op.mem_ctx,
-                                               sizeof(parm[0].lockx.in.locks[0]) * nlocks);
+               parm[0].lockx.in.locks = talloc_array(current_op.mem_ctx,
+                                                       struct smb_lock_entry,
+                                                       nlocks);
                for (n=0;n<nlocks;n++) {
                        parm[0].lockx.in.locks[n].pid = gen_pid();
                        parm[0].lockx.in.locks[n].offset = gen_offset();
@@ -1366,7 +1417,7 @@ static void gen_fileinfo(int instance, union smb_fileinfo *info)
        int i;
        #define LVL(v) {RAW_FILEINFO_ ## v, "RAW_FILEINFO_" #v}
        struct {
-               enum fileinfo_level level;
+               enum smb_fileinfo_level level;
                const char *name;
        }  levels[] = {
                LVL(GETATTR), LVL(GETATTRE), LVL(STANDARD),
@@ -1515,8 +1566,7 @@ static BOOL cmp_fileinfo(int instance,
                break;
 
        case RAW_FILEINFO_INTERNAL_INFORMATION:
-               CHECK_EQUAL(internal_information.out.device);
-               CHECK_EQUAL(internal_information.out.inode);
+               CHECK_EQUAL(internal_information.out.file_id);
                break;
 
        case RAW_FILEINFO_ACCESS_INFORMATION:
@@ -1601,7 +1651,7 @@ static void gen_setfileinfo(int instance, union smb_setfileinfo *info)
        #undef LVL
        #define LVL(v) {RAW_SFILEINFO_ ## v, "RAW_SFILEINFO_" #v}
        struct {
-               enum setfileinfo_level level;
+               enum smb_setfileinfo_level level;
                const char *name;
        }  levels[] = {
 #if 0
@@ -1636,8 +1686,12 @@ static void gen_setfileinfo(int instance, union smb_setfileinfo *info)
                info->standard.in.access_time = gen_timet();
                info->standard.in.write_time = gen_timet();
                break;
-       case RAW_SFILEINFO_EA_SET:
-               info->ea_set.in.ea = gen_ea_struct();
+       case RAW_SFILEINFO_EA_SET: {
+               static struct ea_struct ea;
+               info->ea_set.in.num_eas = 1;
+               info->ea_set.in.eas = &ea;
+               info->ea_set.in.eas[0] = gen_ea_struct();
+       }
                break;
        case RAW_SFILEINFO_BASIC_INFO:
        case RAW_SFILEINFO_BASIC_INFORMATION:
@@ -1736,7 +1790,7 @@ static BOOL handler_notify(int instance)
        GEN_SET_FNUM(in.fnum);
 
        for (n=0;n<NSERVERS;n++) {
-               struct cli_request *req;
+               struct smbcli_request *req;
                req = smb_raw_changenotify_send(servers[n].cli[instance]->tree, &parm[n]);
                req->async.fn = async_notify;
        }
@@ -1751,14 +1805,14 @@ static void wipe_files(void)
 {
        int i;
        for (i=0;i<NSERVERS;i++) {
-               int n = cli_deltree(servers[i].cli[0], "\\gentest");
+               int n = smbcli_deltree(servers[i].cli[0]->tree, "\\gentest");
                if (n == -1) {
                        printf("Failed to wipe tree on server %d\n", i);
                        exit(1);
                }
-               if (!cli_mkdir(servers[i].cli[0], "\\gentest")) {
+               if (NT_STATUS_IS_ERR(smbcli_mkdir(servers[i].cli[0]->tree, "\\gentest"))) {
                        printf("Failed to create \\gentest - %s\n",
-                              cli_errstr(servers[i].cli[0]));
+                              smbcli_errstr(servers[i].cli[0]->tree));
                        exit(1);
                }
                if (n > 0) {
@@ -1798,6 +1852,7 @@ static struct {
        BOOL (*handler)(int instance);
        int count, success_count;
 } gen_ops[] = {
+       {"OPEN",       handler_open},
        {"OPENX",      handler_openx},
        {"NTCREATEX",  handler_ntcreatex},
        {"CLOSE",      handler_close},
@@ -1815,6 +1870,7 @@ static struct {
        {"SPATHINFO",  handler_spathinfo},
        {"SFILEINFO",  handler_sfileinfo},
        {"NOTIFY",     handler_notify},
+       {"SEEK",       handler_seek},
 };
 
 
@@ -1867,11 +1923,11 @@ static int run_test(void)
                current_op.opnum = op;
                current_op.name = gen_ops[which_op].name;
                current_op.status = NT_STATUS_OK;
-               current_op.mem_ctx = talloc_init(current_op.name);
+               current_op.mem_ctx = talloc_init("%s", current_op.name);
 
                ret = gen_ops[which_op].handler(instance);
 
-               talloc_destroy(current_op.mem_ctx);
+               talloc_free(current_op.mem_ctx);
 
                gen_ops[which_op].count++;
                if (NT_STATUS_IS_OK(current_op.status)) {
@@ -2022,7 +2078,7 @@ static void usage(void)
 "Usage:\n\
   gentest2 //server1/share1 //server2/share2 [options..]\n\
   options:\n\
-        -U user%%pass        (must be specified twice)\n\
+        -U user%%pass        (can be specified twice)\n\
         -s seed\n\
         -o numops\n\
         -a            (show all ops)\n\
@@ -2055,10 +2111,11 @@ static void usage(void)
                exit(1);
        }
 
-       setup_logging(argv[0],True);
+       setup_logging(argv[0], DEBUG_STDOUT);
 
        for (i=0;i<NSERVERS;i++) {
                const char *share = argv[1+i];
+               servers[i].credentials = cli_credentials_init(NULL);
                if (!split_unc_name(share, &servers[i].server_name, &servers[i].share_name)) {
                        printf("Invalid share name '%s'\n", share);
                        return -1;
@@ -2079,17 +2136,12 @@ static void usage(void)
        while ((opt = getopt(argc, argv, "U:s:o:ad:i:AOhS:LFXC")) != EOF) {
                switch (opt) {
                case 'U':
-                       i = servers[0].username?1:0;
-                       if (!split_username(optarg, 
-                                           &servers[i].username, 
-                                           &servers[i].password)) {
-                               printf("Must supply USER%%PASS\n");
-                               return -1;
-                       }
+                       i = servers[0].credentials->username?1:0;
+                       cli_credentials_parse_string(servers[i].credentials, optarg, CRED_SPECIFIED);
                        break;
                case 'd':
                        DEBUGLEVEL = atoi(optarg);
-                       setup_logging(NULL,True);
+                       setup_logging(NULL, DEBUG_STDOUT);
                        break;
                case 's':
                        options.seed = atoi(optarg);
@@ -2133,10 +2185,16 @@ static void usage(void)
                }
        }
 
-       if (!servers[0].username || !servers[1].username) {
+       gentest_init_subsystems;
+
+       if (!servers[0].credentials->username) {
                usage();
                return -1;
        }
+       if (!servers[1].credentials->username) {
+               servers[1].credentials->username = servers[0].credentials->username;
+               servers[1].credentials->password = servers[0].credentials->password;
+       }
 
        printf("seed=%u\n", options.seed);