r16980: - make struct smb_notify a union and add levels RAW_NOTIFY_NTTRANS,RAW_NOTIFY...
[jra/samba/.git] / source4 / torture / gentest.c
index 03a66487fa7413e64473130208929277ae5d2380..7ce27c7679d17662feb2619665d1ab9b84b366f8 100644 (file)
 */
 
 #include "includes.h"
+#include "system/time.h"
+#include "system/filesys.h"
+#include "libcli/raw/request.h"
+#include "libcli/libcli.h"
+#include "libcli/raw/libcliraw.h"
+#include "librpc/gen_ndr/security.h"
+#include "auth/gensec/gensec.h"
 
 #define NSERVERS 2
 #define NINSTANCES 2
@@ -51,11 +58,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 +74,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];
 
@@ -78,7 +84,7 @@ static struct {
 static struct {
        int notify_count;
        NTSTATUS status;
-       struct smb_notify notify;
+       union smb_notify notify;
 } notifies[NSERVERS][NINSTANCES];
 
 /* info relevant to the current operation */
@@ -94,8 +100,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,7 +133,7 @@ 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 (NT_STATUS_IS_ERR((cli_close(servers[i].cli[open_handles[h].instance]->tree,
+                       if (NT_STATUS_IS_ERR((smbcli_close(servers[i].cli[open_handles[h].instance]->tree,
                                       open_handles[h].server_fnum[i])))) {
                                return False;
                        }
@@ -158,8 +164,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]);
+                               talloc_free(servers[i].cli[j]);
                                servers[i].cli[j] = NULL;
                        }
                }
@@ -170,13 +176,15 @@ 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);
+
+                       cli_credentials_set_workstation(servers[i].credentials, 
+                                                       "gentest", CRED_SPECIFIED);
+
+                       status = smbcli_full_connection(NULL, &servers[i].cli[j],
+                                                       servers[i].server_name, 
+                                                       servers[i].share_name, NULL, 
+                                                       servers[i].credentials, NULL);
                        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 +192,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);
                }
        }
 
@@ -198,7 +206,7 @@ static BOOL connect_servers(void)
 static uint_t time_skew(void)
 {
        uint_t ret;
-       ret = ABS(servers[0].cli[0]->transport->negotiate.server_time -
+       ret = labs(servers[0].cli[0]->transport->negotiate.server_time -
                  servers[1].cli[0]->transport->negotiate.server_time);
        return ret + 300;
 }
@@ -206,7 +214,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 +232,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 +242,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 (NT_STATUS_IS_ERR((cli_close(servers[i].cli[open_handles[h].instance]->tree, 
+                       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]->tree));
+                                      smbcli_errstr(servers[i].cli[open_handles[h].instance]->tree));
                        }
                }
                printf("Recovered handle %d\n", h);
@@ -260,7 +268,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 +298,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 +307,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 +328,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 +350,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 +420,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 +453,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 +463,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 +480,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 +492,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 +502,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 +511,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 +519,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 +528,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 +548,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 +557,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 +567,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 +576,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 +585,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 +613,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;
@@ -648,6 +656,8 @@ static struct ea_struct gen_ea_struct(void)
                               "ASOMEWHATLONGERATTRIBUTEVALUE"};
        int i;
 
+       ZERO_STRUCT(ea);
+
        do {
                i = gen_int_range(0, ARRAY_SIZE(names)-1);
        } while (ignore_pattern(names[i]));
@@ -670,23 +680,24 @@ static 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;
+       union 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);
 
+       notify.nttrans.level = RAW_NOTIFY_NTTRANS;
        status = smb_raw_changenotify_recv(req, current_op.mem_ctx, &notify);
        if (NT_STATUS_IS_OK(status)) {
                printf("notify tid=%d num_changes=%d action=%d name=%s\n", 
                       tid, 
-                      notify.out.num_changes,
-                      notify.out.changes[0].action,
-                      notify.out.changes[0].name.s);
+                      notify.nttrans.out.num_changes,
+                      notify.nttrans.out.changes[0].action,
+                      notify.nttrans.out.changes[0].name.s);
        }
 
        for (i=0;i<NSERVERS;i++) {
@@ -701,16 +712,26 @@ static void async_notify(struct cli_request *req)
        }
 }
 
+static void oplock_handler_close_recv(struct smbcli_request *req)
+{
+       NTSTATUS status;
+       status = smbcli_request_simple_recv(req);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("close failed in oplock_handler\n");
+               smb_panic("close failed in oplock_handler");
+       }
+}
+
 /*
   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;
+       struct smbcli_request *req;
 
        srandom(current_op.seed);
        do_close = gen_chance(50);
@@ -736,19 +757,24 @@ 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);
 
        io.close.level = RAW_CLOSE_CLOSE;
-       io.close.in.fnum = fnum;
+       io.close.in.file.fnum = fnum;
        io.close.in.write_time = 0;
-       status = smb_raw_close(tree, &io);
+       req = smb_raw_close_send(tree, &io);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("WARNING: close failed in oplock_handler_close - %s\n", nt_errstr(status));
+       if (req == NULL) {
+               printf("WARNING: close failed in oplock_handler_close\n");
+               return False;
        }
+
+       req->async.fn = oplock_handler_close_recv;
+       req->async.private = NULL;
+
        return True;
 }
 
@@ -758,19 +784,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 +829,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 +867,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;
                        }
@@ -878,7 +893,7 @@ again:
        for (j=0;j<NINSTANCES;j++) {
                for (i=1;i<NSERVERS;i++) {
                        int n;
-                       struct smb_notify not1, not2;
+                       union smb_notify not1, not2;
 
                        if (notifies[0][j].notify_count != notifies[i][j].notify_count) {
                                if (tries++ < 10) goto again;
@@ -905,26 +920,26 @@ again:
                        not1 = notifies[0][j].notify;
                        not2 = notifies[i][j].notify;
 
-                       for (n=0;n<not1.out.num_changes;n++) {
-                               if (not1.out.changes[n].action != 
-                                   not2.out.changes[n].action) {
+                       for (n=0;n<not1.nttrans.out.num_changes;n++) {
+                               if (not1.nttrans.out.changes[n].action != 
+                                   not2.nttrans.out.changes[n].action) {
                                        printf("Notify action %d inconsistent %d %d\n", n,
-                                              not1.out.changes[n].action,
-                                              not2.out.changes[n].action);
+                                              not1.nttrans.out.changes[n].action,
+                                              not2.nttrans.out.changes[n].action);
                                        return False;
                                }
-                               if (strcmp(not1.out.changes[n].name.s,
-                                          not2.out.changes[n].name.s)) {
+                               if (strcmp(not1.nttrans.out.changes[n].name.s,
+                                          not2.nttrans.out.changes[n].name.s)) {
                                        printf("Notify name %d inconsistent %s %s\n", n,
-                                              not1.out.changes[n].name.s,
-                                              not2.out.changes[n].name.s);
+                                              not1.nttrans.out.changes[n].name.s,
+                                              not2.nttrans.out.changes[n].name.s);
                                        return False;
                                }
-                               if (not1.out.changes[n].name.private_length !=
-                                   not2.out.changes[n].name.private_length) {
+                               if (not1.nttrans.out.changes[n].name.private_length !=
+                                   not2.nttrans.out.changes[n].name.private_length) {
                                        printf("Notify name length %d inconsistent %d %d\n", n,
-                                              not1.out.changes[n].name.private_length,
-                                              not2.out.changes[n].name.private_length);
+                                              not1.nttrans.out.changes[n].name.private_length,
+                                              not2.nttrans.out.changes[n].name.private_length);
                                        return False;
                                }
                        }
@@ -949,7 +964,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 +983,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 +992,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; \
@@ -1022,7 +1037,7 @@ again:
 } while(0)
 
 #define CHECK_TIMES_EQUAL(field) do { \
-       if (ABS(parm[0].field - parm[1].field) > time_skew() && \
+       if (labs(parm[0].field - parm[1].field) > time_skew() && \
            !ignore_pattern(#field)) { \
                printf("Mismatch in %s - 0x%x 0x%x\n", #field, \
                       (int)parm[0].field, (int)parm[1].field); \
@@ -1031,12 +1046,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 (labs(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)
@@ -1080,7 +1095,7 @@ static BOOL handler_openx(int instance)
        CHECK_TIMES_EQUAL(openx.out.write_time);
 
        /* open creates a new file handle */
-       ADD_HANDLE(parm[0].openx.in.fname, openx.out.fnum);
+       ADD_HANDLE(parm[0].openx.in.fname, openx.out.file.fnum);
 
        return True;
 }
@@ -1094,27 +1109,27 @@ static BOOL handler_open(int instance)
        union smb_open parm[NSERVERS];
        NTSTATUS status[NSERVERS];
 
-       parm[0].open.level = RAW_OPEN_OPEN;
-       parm[0].open.in.flags = gen_bits_mask2(0xF, 0xFFFF);
-       parm[0].open.in.search_attrs = gen_attrib();
-       parm[0].open.in.fname = gen_fname_open(instance);
+       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].open.in.flags &= ~(OPENX_FLAGS_REQUEST_OPLOCK|
-                                          OPENX_FLAGS_REQUEST_BATCH_OPLOCK);
+               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(open.out.attrib);
-       CHECK_TIMES_EQUAL(open.out.write_time);
-       CHECK_EQUAL(open.out.size);
-       CHECK_EQUAL(open.out.rmode);
+       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].open.in.fname, open.out.fnum);
+       ADD_HANDLE(parm[0].openold.in.fname, openold.out.file.fnum);
 
        return True;
 }
@@ -1167,7 +1182,7 @@ static BOOL handler_ntcreatex(int instance)
        CHECK_EQUAL(ntcreatex.out.is_directory);
 
        /* ntcreatex creates a new file handle */
-       ADD_HANDLE(parm[0].ntcreatex.in.fname, ntcreatex.out.fnum);
+       ADD_HANDLE(parm[0].ntcreatex.in.fname, ntcreatex.out.file.fnum);
 
        return True;
 }
@@ -1181,14 +1196,14 @@ static BOOL handler_close(int instance)
        NTSTATUS status[NSERVERS];
 
        parm[0].close.level = RAW_CLOSE_CLOSE;
-       parm[0].close.in.fnum = gen_fnum_close(instance);
+       parm[0].close.in.file.fnum = gen_fnum_close(instance);
        parm[0].close.in.write_time = gen_timet();
 
        GEN_COPY_PARM;
-       GEN_SET_FNUM(close.in.fnum);
+       GEN_SET_FNUM(close.in.file.fnum);
        GEN_CALL(smb_raw_close(tree, &parm[i]));
 
-       REMOVE_HANDLE(close.in.fnum);
+       REMOVE_HANDLE(close.in.file.fnum);
 
        return True;
 }
@@ -1198,11 +1213,11 @@ static BOOL handler_close(int instance)
 */
 static BOOL handler_unlink(int instance)
 {
-       struct smb_unlink parm[NSERVERS];
+       union smb_unlink parm[NSERVERS];
        NTSTATUS status[NSERVERS];
 
-       parm[0].in.pattern = gen_pattern();
-       parm[0].in.attrib = gen_attrib();
+       parm[0].unlink.in.pattern = gen_pattern();
+       parm[0].unlink.in.attrib = gen_attrib();
 
        GEN_COPY_PARM;
        GEN_CALL(smb_raw_unlink(tree, &parm[i]));
@@ -1215,10 +1230,10 @@ static BOOL handler_unlink(int instance)
 */
 static BOOL handler_chkpath(int instance)
 {
-       struct smb_chkpath parm[NSERVERS];
+       union smb_chkpath parm[NSERVERS];
        NTSTATUS status[NSERVERS];
 
-       parm[0].in.path = gen_fname_open(instance);
+       parm[0].chkpath.in.path = gen_fname_open(instance);
 
        GEN_COPY_PARM;
        GEN_CALL(smb_raw_chkpath(tree, &parm[i]));
@@ -1305,18 +1320,18 @@ static BOOL handler_ntrename(int instance)
 */
 static BOOL handler_seek(int instance)
 {
-       struct smb_seek parm[NSERVERS];
+       union 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();
+       parm[0].lseek.in.file.fnum = gen_fnum(instance);
+       parm[0].lseek.in.mode = gen_bits_mask2(0x3, 0xFFFF);
+       parm[0].lseek.in.offset = gen_offset();
 
        GEN_COPY_PARM;
-       GEN_SET_FNUM(in.fnum);
+       GEN_SET_FNUM(lseek.in.file.fnum);
        GEN_CALL(smb_raw_seek(tree, &parm[i]));
 
-       CHECK_EQUAL(out.offset);
+       CHECK_EQUAL(lseek.out.offset);
 
        return True;
 }
@@ -1331,16 +1346,17 @@ static BOOL handler_readx(int instance)
        NTSTATUS status[NSERVERS];
 
        parm[0].readx.level = RAW_READ_READX;
-       parm[0].readx.in.fnum = gen_fnum(instance);
+       parm[0].readx.in.file.fnum = gen_fnum(instance);
        parm[0].readx.in.offset = gen_offset();
        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.in.read_for_execute = gen_bool();
+       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);
+       GEN_SET_FNUM(readx.in.file.fnum);
        GEN_CALL(smb_raw_read(tree, &parm[i]));
 
        CHECK_EQUAL(readx.out.remaining);
@@ -1359,15 +1375,15 @@ static BOOL handler_writex(int instance)
        NTSTATUS status[NSERVERS];
 
        parm[0].writex.level = RAW_WRITE_WRITEX;
-       parm[0].writex.in.fnum = gen_fnum(instance);
+       parm[0].writex.in.file.fnum = gen_fnum(instance);
        parm[0].writex.in.offset = gen_offset();
        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);
+       GEN_SET_FNUM(writex.in.file.fnum);
        GEN_CALL(smb_raw_write(tree, &parm[i]));
 
        CHECK_EQUAL(writex.out.nwritten);
@@ -1386,7 +1402,7 @@ static BOOL handler_lockingx(int instance)
        int n, nlocks;
 
        parm[0].lockx.level = RAW_LOCK_LOCKX;
-       parm[0].lockx.in.fnum = gen_fnum(instance);
+       parm[0].lockx.in.file.fnum = gen_fnum(instance);
        parm[0].lockx.in.mode = gen_lock_mode();
        parm[0].lockx.in.timeout = gen_timeout();
        do {
@@ -1398,8 +1414,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();
@@ -1408,7 +1425,7 @@ static BOOL handler_lockingx(int instance)
        }
 
        GEN_COPY_PARM;
-       GEN_SET_FNUM(lockx.in.fnum);
+       GEN_SET_FNUM(lockx.in.file.fnum);
        GEN_CALL(smb_raw_lock(tree, &parm[i]));
 
        return True;
@@ -1422,7 +1439,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),
@@ -1604,6 +1621,14 @@ static BOOL cmp_fileinfo(int instance,
                CHECK_EQUAL(attribute_tag_information.out.attrib);
                CHECK_EQUAL(attribute_tag_information.out.reparse_tag);
                break;
+
+               /* Unhandled levels */
+
+       case RAW_FILEINFO_SEC_DESC:
+       case RAW_FILEINFO_EA_LIST:
+       case RAW_FILEINFO_UNIX_BASIC:
+       case RAW_FILEINFO_UNIX_LINK:
+               break;
        }
 
        return True;
@@ -1617,7 +1642,7 @@ static BOOL handler_qpathinfo(int instance)
        union smb_fileinfo parm[NSERVERS];
        NTSTATUS status[NSERVERS];
 
-       parm[0].generic.in.fname = gen_fname_open(instance);
+       parm[0].generic.in.file.path = gen_fname_open(instance);
 
        gen_fileinfo(instance, &parm[0]);
 
@@ -1635,12 +1660,12 @@ static BOOL handler_qfileinfo(int instance)
        union smb_fileinfo parm[NSERVERS];
        NTSTATUS status[NSERVERS];
 
-       parm[0].generic.in.fnum = gen_fnum(instance);
+       parm[0].generic.in.file.fnum = gen_fnum(instance);
 
        gen_fileinfo(instance, &parm[0]);
 
        GEN_COPY_PARM;
-       GEN_SET_FNUM(generic.in.fnum);
+       GEN_SET_FNUM(generic.in.file.fnum);
        GEN_CALL(smb_raw_fileinfo(tree, current_op.mem_ctx, &parm[i]));
 
        return cmp_fileinfo(instance, parm, status);
@@ -1656,7 +1681,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
@@ -1691,8 +1716,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:
@@ -1725,6 +1754,19 @@ static void gen_setfileinfo(int instance, union smb_setfileinfo *info)
        case RAW_SFILEINFO_MODE_INFORMATION:
                info->mode_information.in.mode = gen_bits_mask(0xFFFFFFFF);
                break;
+       case RAW_SFILEINFO_GENERIC:
+       case RAW_SFILEINFO_SEC_DESC:
+       case RAW_SFILEINFO_UNIX_BASIC:
+       case RAW_SFILEINFO_UNIX_LINK:
+       case RAW_SFILEINFO_UNIX_HLINK:
+       case RAW_SFILEINFO_1023:
+       case RAW_SFILEINFO_1025:
+       case RAW_SFILEINFO_1029:
+       case RAW_SFILEINFO_1032:
+       case RAW_SFILEINFO_1039:
+       case RAW_SFILEINFO_1040:
+               /* Untested */
+               break;
        }
 }
 
@@ -1736,7 +1778,7 @@ static BOOL handler_spathinfo(int instance)
        union smb_setfileinfo parm[NSERVERS];
        NTSTATUS status[NSERVERS];
 
-       parm[0].generic.file.fname = gen_fname_open(instance);
+       parm[0].generic.in.file.path = gen_fname_open(instance);
 
        gen_setfileinfo(instance, &parm[0]);
 
@@ -1762,12 +1804,12 @@ static BOOL handler_sfileinfo(int instance)
        union smb_setfileinfo parm[NSERVERS];
        NTSTATUS status[NSERVERS];
 
-       parm[0].generic.file.fnum = gen_fnum(instance);
+       parm[0].generic.in.file.fnum = gen_fnum(instance);
 
        gen_setfileinfo(instance, &parm[0]);
 
        GEN_COPY_PARM;
-       GEN_SET_FNUM(generic.file.fnum);
+       GEN_SET_FNUM(generic.in.file.fnum);
        GEN_CALL(smb_raw_setfileinfo(tree, &parm[i]));
 
        return True;
@@ -1779,19 +1821,21 @@ static BOOL handler_sfileinfo(int instance)
 */
 static BOOL handler_notify(int instance)
 {
-       struct smb_notify parm[NSERVERS];
+       union smb_notify parm[NSERVERS];
        int n;
 
-       parm[0].in.buffer_size = gen_io_count();
-       parm[0].in.completion_filter = gen_bits_mask(0xFF);
-       parm[0].in.fnum = gen_fnum(instance);
-       parm[0].in.recursive = gen_bool();
+       ZERO_STRUCT(parm[0]);
+       parm[0].nttrans.level                   = RAW_NOTIFY_NTTRANS;
+       parm[0].nttrans.in.buffer_size          = gen_io_count();
+       parm[0].nttrans.in.completion_filter    = gen_bits_mask(0xFF);
+       parm[0].nttrans.in.file.fnum            = gen_fnum(instance);
+       parm[0].nttrans.in.recursive            = gen_bool();
 
        GEN_COPY_PARM;
-       GEN_SET_FNUM(in.fnum);
+       GEN_SET_FNUM(nttrans.in.file.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;
        }
@@ -1806,14 +1850,14 @@ static void wipe_files(void)
 {
        int i;
        for (i=0;i<NSERVERS;i++) {
-               int n = cli_deltree(servers[i].cli[0]->tree, "\\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 (NT_STATUS_IS_ERR(cli_mkdir(servers[i].cli[0]->tree, "\\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]->tree));
+                              smbcli_errstr(servers[i].cli[0]->tree));
                        exit(1);
                }
                if (n > 0) {
@@ -1924,11 +1968,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)) {
@@ -2036,7 +2080,7 @@ static BOOL start_gentest(void)
        /* generate the seeds - after this everything is deterministic */
        if (options.use_preset_seeds) {
                int numops;
-               char **preset = file_lines_load(options.seeds_file, &numops);
+               char **preset = file_lines_load(options.seeds_file, &numops, NULL);
                if (!preset) {
                        printf("Failed to load %s - %s\n", options.seeds_file, strerror(errno));
                        exit(1);
@@ -2079,7 +2123,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\
@@ -2094,13 +2138,35 @@ static void usage(void)
 ");
 }
 
+/**
+  split a UNC name into server and share names
+*/
+static BOOL split_unc_name(const char *unc, char **server, char **share)
+{
+       char *p = strdup(unc);
+       if (!p) return False;
+       all_string_sub(p, "\\", "/", 0);
+       if (strncmp(p, "//", 2) != 0) return False;
+
+       (*server) = p+2;
+       p = strchr(*server, '/');
+       if (!p) return False;
+
+       *p = 0;
+       (*share) = p+1;
+       
+       return True;
+}
+
+
+
 /****************************************************************************
   main program
 ****************************************************************************/
  int main(int argc, char *argv[])
 {
        int opt;
-       int i;
+       int i, username_count=0;
        BOOL ret;
 
        setlinebuf(stdout);
@@ -2116,6 +2182,7 @@ static void usage(void)
 
        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;
@@ -2125,8 +2192,12 @@ static void usage(void)
        argc -= NSERVERS;
        argv += NSERVERS;
 
-       lp_load(dyn_CONFIGFILE,True,False,False);
-       load_interfaces();
+       lp_load();
+
+       servers[0].credentials = cli_credentials_init(talloc_autofree_context());
+       servers[1].credentials = cli_credentials_init(talloc_autofree_context());
+       cli_credentials_guess(servers[0].credentials);
+       cli_credentials_guess(servers[1].credentials);
 
        options.seed = time(NULL);
        options.numops = 1000;
@@ -2136,13 +2207,13 @@ 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;
+                       if (username_count == 2) {
+                               usage();
+                               exit(1);
                        }
+                       cli_credentials_parse_string(servers[username_count].credentials, 
+                                                    optarg, CRED_SPECIFIED);
+                       username_count++;
                        break;
                case 'd':
                        DEBUGLEVEL = atoi(optarg);
@@ -2179,7 +2250,7 @@ static void usage(void)
                        options.analyze_continuous = True;
                        break;
                case 'i':
-                       options.ignore_patterns = file_lines_load(optarg, NULL);
+                       options.ignore_patterns = file_lines_load(optarg, NULL, NULL);
                        break;
                case 'h':
                        usage();
@@ -2190,10 +2261,15 @@ static void usage(void)
                }
        }
 
-       if (!servers[0].username || !servers[1].username) {
+       gensec_init();
+
+       if (username_count == 0) {
                usage();
                return -1;
        }
+       if (username_count == 1) {
+               servers[1].credentials = servers[0].credentials;
+       }
 
        printf("seed=%u\n", options.seed);