s3: Remove a "typedef struct"
[sfrench/samba-autobuild/.git] / source3 / client / client.c
index adcbffe6fac30f9fbff4aaaac5778b704da4a8e1..9245428c5e2684b74dc386c25543921f14cad044 100644 (file)
@@ -23,7 +23,8 @@
 
 #include "includes.h"
 #include "client/client_proto.h"
-#include "include/rpc_client.h"
+#include "../librpc/gen_ndr/cli_srvsvc.h"
+
 #ifndef REGISTER
 #define REGISTER 0
 #endif
@@ -45,7 +46,7 @@ const char *cmd_ptr = NULL;
 static int io_bufsize = 524288;
 
 static int name_type = 0x20;
-extern int max_protocol;
+static int max_protocol = PROTOCOL_NT1;
 
 static int process_tok(char *tok);
 static int cmd_help(void);
@@ -103,6 +104,9 @@ struct cli_state *cli;
 static char CLI_DIRSEP_CHAR = '\\';
 static char CLI_DIRSEP_STR[] = { '\\', '\0' };
 
+/* Authentication for client connections. */
+struct user_auth_info *auth_info;
+
 /* Accessor functions for directory paths. */
 static char *fileselection;
 static const char *client_get_fileselection(void)
@@ -158,6 +162,24 @@ const char *client_set_cur_dir(const char *newdir)
        return client_get_cur_dir();
 }
 
+/****************************************************************************
+ Put up a yes/no prompt.
+****************************************************************************/
+
+static bool yesno(const char *p)
+{
+       char ans[20];
+       printf("%s",p);
+
+       if (!fgets(ans,sizeof(ans)-1,stdin))
+               return(False);
+
+       if (*ans == 'y' || *ans == 'Y')
+               return(True);
+
+       return(False);
+}
+
 /****************************************************************************
  Write to a local file with CR/LF->LF translation if appropriate. Return the
  number taken from the buffer. This may not equal the number written.
@@ -240,51 +262,29 @@ static size_t push_source(uint8_t *buf, size_t n, void *priv)
 
 static void send_message(const char *username)
 {
-       int total_len = 0;
-       int grp_id;
-
-       if (!cli_message_start(cli, desthost, username, &grp_id)) {
-               d_printf("message start: %s\n", cli_errstr(cli));
-               return;
-       }
-
-
-       d_printf("Connected. Type your message, ending it with a Control-D\n");
-
-       while (!feof(stdin) && total_len < 1600) {
-               int maxlen = MIN(1600 - total_len,127);
-               char msg[1024];
-               int l=0;
-               int c;
+       char buf[1600];
+       NTSTATUS status;
+       int i;
 
-               ZERO_ARRAY(msg);
+       d_printf("Type your message, ending it with a Control-D\n");
 
-               for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++) {
-                       if (c == '\n')
-                               msg[l++] = '\r';
-                       msg[l] = c;
-               }
-
-               if ((total_len > 0) && (strlen(msg) == 0)) {
+       i = 0;
+       while (i<sizeof(buf)-2) {
+               int c = fgetc(stdin);
+               if (c == EOF) {
                        break;
                }
-
-               if (!cli_message_text(cli, msg, l, grp_id)) {
-                       d_printf("SMBsendtxt failed (%s)\n",cli_errstr(cli));
-                       return;
+               if (c == '\n') {
+                       buf[i++] = '\r';
                }
-
-               total_len += l;
+               buf[i++] = c;
        }
+       buf[i] = '\0';
 
-       if (total_len >= 1600)
-               d_printf("the message was truncated to 1600 bytes\n");
-       else
-               d_printf("sent %d bytes\n",total_len);
-
-       if (!cli_message_end(cli, grp_id)) {
-               d_printf("SMBsendend failed (%s)\n",cli_errstr(cli));
-               return;
+       status = cli_message(cli, desthost, username, buf);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "cli_message returned %s\n",
+                         nt_errstr(status));
        }
 }
 
@@ -299,12 +299,12 @@ static int do_dskattr(void)
        char *targetpath = NULL;
        TALLOC_CTX *ctx = talloc_tos();
 
-       if ( !cli_resolve_path(ctx, "", cli, client_get_cur_dir(), &targetcli, &targetpath)) {
+       if ( !cli_resolve_path(ctx, "", auth_info, cli, client_get_cur_dir(), &targetcli, &targetpath)) {
                d_printf("Error in dskattr: %s\n", cli_errstr(cli));
                return 1;
        }
 
-       if (!cli_dskattr(targetcli, &bsize, &total, &avail)) {
+       if (!NT_STATUS_IS_OK(cli_dskattr(targetcli, &bsize, &total, &avail))) {
                d_printf("Error in dskattr: %s\n",cli_errstr(targetcli));
                return 1;
        }
@@ -393,7 +393,7 @@ static int do_cd(const char *new_dir)
        new_cd = clean_name(ctx, new_cd);
        client_set_cur_dir(new_cd);
 
-       if ( !cli_resolve_path(ctx, "", cli, new_cd, &targetcli, &targetpath)) {
+       if ( !cli_resolve_path(ctx, "", auth_info, cli, new_cd, &targetcli, &targetpath)) {
                d_printf("cd %s: %s\n", new_cd, cli_errstr(cli));
                client_set_cur_dir(saved_dir);
                goto out;
@@ -408,8 +408,12 @@ static int do_cd(const char *new_dir)
           Except Win9x doesn't support the qpathinfo_basic() call..... */
 
        if (targetcli->protocol > PROTOCOL_LANMAN2 && !targetcli->win95) {
-               if (!cli_qpathinfo_basic( targetcli, targetpath, &sbuf, &attributes ) ) {
-                       d_printf("cd %s: %s\n", new_cd, cli_errstr(targetcli));
+               NTSTATUS status;
+
+               status = cli_qpathinfo_basic(targetcli, targetpath, &sbuf,
+                                            &attributes);
+               if (!NT_STATUS_IS_OK(status)) {
+                       d_printf("cd %s: %s\n", new_cd, nt_errstr(status));
                        client_set_cur_dir(saved_dir);
                        goto out;
                }
@@ -434,7 +438,7 @@ static int do_cd(const char *new_dir)
                        goto out;
                }
 
-               if (!cli_chkpath(targetcli, targetpath)) {
+               if (!NT_STATUS_IS_OK(cli_chkpath(targetcli, targetpath))) {
                        d_printf("cd %s: %s\n", new_cd, cli_errstr(targetcli));
                        client_set_cur_dir(saved_dir);
                        goto out;
@@ -532,12 +536,12 @@ static void display_finfo(file_info *finfo, const char *dir)
                dir_total += finfo->size;
        } else {
                char *afname = NULL;
-               int fnum;
+               uint16_t fnum;
 
                /* skip if this is . or .. */
                if ( strequal(finfo->name,"..") || strequal(finfo->name,".") )
                        return;
-               /* create absolute filename for cli_nt_create() FIXME */
+               /* create absolute filename for cli_ntcreate() FIXME */
                afname = talloc_asprintf(ctx,
                                        "%s%s%s",
                                        dir,
@@ -551,8 +555,9 @@ static void display_finfo(file_info *finfo, const char *dir)
                d_printf( "MODE:%s\n", attrib_string(finfo->mode));
                d_printf( "SIZE:%.0f\n", (double)finfo->size);
                d_printf( "MTIME:%s", time_to_asc(t));
-               fnum = cli_nt_create(finfo->cli, afname, CREATE_ACCESS_READ);
-               if (fnum == -1) {
+               if (!NT_STATUS_IS_OK(cli_ntcreate(finfo->cli, afname, 0,
+                               CREATE_ACCESS_READ, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
+                               FILE_OPEN, 0x0, 0x0, &fnum))) {
                        DEBUG( 0, ("display_finfo() Failed to open %s: %s\n",
                                afname,
                                cli_errstr( finfo->cli)));
@@ -819,7 +824,7 @@ void do_list(const char *mask,
 
                        /* check for dfs */
 
-                       if ( !cli_resolve_path(ctx, "", cli, head, &targetcli, &targetpath ) ) {
+                       if ( !cli_resolve_path(ctx, "", auth_info, cli, head, &targetcli, &targetpath ) ) {
                                d_printf("do_list: [%s] %s\n", head, cli_errstr(cli));
                                remove_do_list_queue_head();
                                continue;
@@ -852,7 +857,7 @@ void do_list(const char *mask,
                }
        } else {
                /* check for dfs */
-               if (cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetpath)) {
+               if (cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetpath)) {
                        if (cli_list(targetcli, targetpath, attribute, do_list_helper, NULL) == -1) {
                                d_printf("%s listing %s\n",
                                        cli_errstr(targetcli), targetpath);
@@ -996,7 +1001,8 @@ static NTSTATUS writefile_sink(char *buf, size_t n, void *priv)
 static int do_get(const char *rname, const char *lname_in, bool reget)
 {
        TALLOC_CTX *ctx = talloc_tos();
-       int handle = 0, fnum;
+       int handle = 0;
+       uint16_t fnum;
        bool newhandle = false;
        struct timeval tp_start;
        uint16 attr;
@@ -1018,16 +1024,14 @@ static int do_get(const char *rname, const char *lname_in, bool reget)
                strlower_m(lname);
        }
 
-       if (!cli_resolve_path(ctx, "", cli, rname, &targetcli, &targetname ) ) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, rname, &targetcli, &targetname ) ) {
                d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli));
                return 1;
        }
 
        GetTimeOfDay(&tp_start);
 
-       fnum = cli_open(targetcli, targetname, O_RDONLY, DENY_NONE);
-
-       if (fnum == -1) {
+       if (!NT_STATUS_IS_OK(cli_open(targetcli, targetname, O_RDONLY, DENY_NONE, &fnum))) {
                d_printf("%s opening remote file %s\n",cli_errstr(cli),rname);
                return 1;
        }
@@ -1057,8 +1061,8 @@ static int do_get(const char *rname, const char *lname_in, bool reget)
 
        if (!cli_qfileinfo(targetcli, fnum,
                           &attr, &size, NULL, NULL, NULL, NULL, NULL) &&
-           !cli_getattrE(targetcli, fnum,
-                         &attr, &size, NULL, NULL, NULL)) {
+           !NT_STATUS_IS_OK(cli_getattrE(targetcli, fnum,
+                         &attr, &size, NULL, NULL, NULL))) {
                d_printf("getattrib: %s\n",cli_errstr(targetcli));
                return 1;
        }
@@ -1075,7 +1079,7 @@ static int do_get(const char *rname, const char *lname_in, bool reget)
                return 1;
        }
 
-       if (!cli_close(targetcli, fnum)) {
+       if (!NT_STATUS_IS_OK(cli_close(targetcli, fnum))) {
                d_printf("Error %s closing remote file\n",cli_errstr(cli));
                rc = 1;
        }
@@ -1278,7 +1282,7 @@ static int cmd_more(void)
        if (!lname) {
                return 1;
        }
-       fd = smb_mkstemp(lname);
+       fd = mkstemp(lname);
        if (fd == -1) {
                d_printf("failed to create temporary file for more\n");
                return 1;
@@ -1381,12 +1385,12 @@ static bool do_mkdir(const char *name)
        struct cli_state *targetcli;
        char *targetname = NULL;
 
-       if (!cli_resolve_path(ctx, "", cli, name, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, name, &targetcli, &targetname)) {
                d_printf("mkdir %s: %s\n", name, cli_errstr(cli));
                return false;
        }
 
-       if (!cli_mkdir(targetcli, targetname)) {
+       if (!NT_STATUS_IS_OK(cli_mkdir(targetcli, targetname))) {
                d_printf("%s making remote directory %s\n",
                         cli_errstr(targetcli),name);
                return false;
@@ -1419,7 +1423,7 @@ static bool do_altname(const char *name)
 
 static int cmd_quit(void)
 {
-       cli_cm_shutdown();
+       cli_shutdown(cli);
        exit(0);
        /* NOTREACHED */
        return 0;
@@ -1464,7 +1468,7 @@ static int cmd_mkdir(void)
                        return 1;
                }
 
-               if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+               if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                        return 1;
                }
 
@@ -1479,7 +1483,7 @@ static int cmd_mkdir(void)
                        if (!ddir2) {
                                return 1;
                        }
-                       if (!cli_chkpath(targetcli, ddir2)) {
+                       if (!NT_STATUS_IS_OK(cli_chkpath(targetcli, ddir2))) {
                                do_mkdir(ddir2);
                        }
                        ddir2 = talloc_asprintf_append(ddir2, "%s", CLI_DIRSEP_STR);
@@ -1615,7 +1619,7 @@ static int cmd_allinfo(void)
 static int do_put(const char *rname, const char *lname, bool reput)
 {
        TALLOC_CTX *ctx = talloc_tos();
-       int fnum;
+       uint16_t fnum;
        XFILE *f;
        SMB_OFF_T start = 0;
        int rc = 0;
@@ -1625,7 +1629,7 @@ static int do_put(const char *rname, const char *lname, bool reput)
        struct push_state state;
        NTSTATUS status;
 
-       if (!cli_resolve_path(ctx, "", cli, rname, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, rname, &targetcli, &targetname)) {
                d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli));
                return 1;
        }
@@ -1633,19 +1637,19 @@ static int do_put(const char *rname, const char *lname, bool reput)
        GetTimeOfDay(&tp_start);
 
        if (reput) {
-               fnum = cli_open(targetcli, targetname, O_RDWR|O_CREAT, DENY_NONE);
-               if (fnum >= 0) {
+               status = cli_open(targetcli, targetname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
+               if (NT_STATUS_IS_OK(status)) {
                        if (!cli_qfileinfo(targetcli, fnum, NULL, &start, NULL, NULL, NULL, NULL, NULL) &&
-                           !cli_getattrE(targetcli, fnum, NULL, &start, NULL, NULL, NULL)) {
+                           !NT_STATUS_IS_OK(cli_getattrE(targetcli, fnum, NULL, &start, NULL, NULL, NULL))) {
                                d_printf("getattrib: %s\n",cli_errstr(cli));
                                return 1;
                        }
                }
        } else {
-               fnum = cli_open(targetcli, targetname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
+               status = cli_open(targetcli, targetname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnum);
        }
 
-       if (fnum == -1) {
+       if (!NT_STATUS_IS_OK(status)) {
                d_printf("%s opening remote file %s\n",cli_errstr(targetcli),rname);
                return 1;
        }
@@ -1663,6 +1667,7 @@ static int do_put(const char *rname, const char *lname, bool reput)
                if (f && reput) {
                        if (x_tseek(f, start, SEEK_SET) == -1) {
                                d_printf("Error seeking local file\n");
+                               x_fclose(f);
                                return 1;
                        }
                }
@@ -1687,9 +1692,11 @@ static int do_put(const char *rname, const char *lname, bool reput)
                d_fprintf(stderr, "cli_push returned %s\n", nt_errstr(status));
        }
 
-       if (!cli_close(targetcli, fnum)) {
+       if (!NT_STATUS_IS_OK(cli_close(targetcli, fnum))) {
                d_printf("%s closing remote file %s\n",cli_errstr(cli),rname);
-               x_fclose(f);
+               if (f != x_stdin) {
+                       x_fclose(f);
+               }
                return 1;
        }
 
@@ -1714,7 +1721,7 @@ static int do_put(const char *rname, const char *lname, bool reput)
        }
 
        if (f == x_stdin) {
-               cli_cm_shutdown();
+               cli_shutdown(cli);
                exit(0);
        }
 
@@ -1760,7 +1767,7 @@ static int cmd_put(void)
                SMB_STRUCT_STAT st;
                /* allow '-' to represent stdin
                   jdblair, 24.jun.98 */
-               if (!file_exist_stat(lname,&st) &&
+               if (!file_exist_stat(lname, &st, false) &&
                    (strcmp(lname,"-"))) {
                        d_printf("%s does not exist\n",lname);
                        return 1;
@@ -1784,13 +1791,13 @@ static struct file_list {
  Free a file_list structure.
 ****************************************************************************/
 
-static void free_file_list (struct file_list *list_head)
+static void free_file_list (struct file_list *l_head)
 {
        struct file_list *list, *next;
 
-       for (list = list_head; list; list = next) {
+       for (list = l_head; list; list = next) {
                next = list->next;
-               DLIST_REMOVE(list_head, list);
+               DLIST_REMOVE(l_head, list);
                SAFE_FREE(list->file_path);
                SAFE_FREE(list);
        }
@@ -1953,7 +1960,7 @@ static int cmd_mput(void)
                                                break;
                                        }
                                        normalize_name(rname);
-                                       if (!cli_chkpath(cli, rname) &&
+                                       if (!NT_STATUS_IS_OK(cli_chkpath(cli, rname)) &&
                                            !do_mkdir(rname)) {
                                                DEBUG (0, ("Unable to make dir, skipping..."));
                                                /* Skip the directory */
@@ -2112,7 +2119,7 @@ static void do_del(file_info *finfo, const char *dir)
                return;
        }
 
-       if (!cli_unlink(finfo->cli, mask)) {
+       if (!NT_STATUS_IS_OK(cli_unlink(finfo->cli, mask, aSYSTEM | aHIDDEN))) {
                d_printf("%s deleting remote file %s\n",
                                cli_errstr(finfo->cli),mask);
        }
@@ -2183,12 +2190,12 @@ static int cmd_wdel(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("cmd_wdel %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
 
-       if (!cli_unlink_full(targetcli, targetname, attribute)) {
+       if (!NT_STATUS_IS_OK(cli_unlink(targetcli, targetname, attribute))) {
                d_printf("%s deleting remote files %s\n",cli_errstr(targetcli),targetname);
        }
        return 0;
@@ -2204,7 +2211,7 @@ static int cmd_open(void)
        char *buf = NULL;
        char *targetname = NULL;
        struct cli_state *targetcli;
-       int fnum;
+       uint16_t fnum = (uint16_t)-1;
 
        if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                d_printf("open <filename>\n");
@@ -2218,15 +2225,17 @@ static int cmd_open(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("open %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
 
-       fnum = cli_nt_create(targetcli, targetname, FILE_READ_DATA|FILE_WRITE_DATA);
-       if (fnum == -1) {
-               fnum = cli_nt_create(targetcli, targetname, FILE_READ_DATA);
-               if (fnum != -1) {
+       if (!NT_STATUS_IS_OK(cli_ntcreate(targetcli, targetname, 0,
+                       FILE_READ_DATA|FILE_WRITE_DATA, 0,
+                       FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
+               if (NT_STATUS_IS_OK(cli_ntcreate(targetcli, targetname, 0,
+                               FILE_READ_DATA, 0,
+                               FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
                        d_printf("open file %s: for read/write fnum %d\n", targetname, fnum);
                } else {
                        d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli));
@@ -2291,7 +2300,7 @@ static int cmd_posix_open(void)
        char *targetname = NULL;
        struct cli_state *targetcli;
        mode_t mode;
-       int fnum;
+       uint16_t fnum;
 
        if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                d_printf("posix_open <filename> 0<mode>\n");
@@ -2311,15 +2320,13 @@ static int cmd_posix_open(void)
        }
        mode = (mode_t)strtol(buf, (char **)NULL, 8);
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("posix_open %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
 
-       fnum = cli_posix_open(targetcli, targetname, O_CREAT|O_RDWR, mode);
-       if (fnum == -1) {
-               fnum = cli_posix_open(targetcli, targetname, O_CREAT|O_RDONLY, mode);
-               if (fnum != -1) {
+       if (!NT_STATUS_IS_OK(cli_posix_open(targetcli, targetname, O_CREAT|O_RDWR, mode, &fnum))) {
+               if (!NT_STATUS_IS_OK(cli_posix_open(targetcli, targetname, O_CREAT|O_RDONLY, mode, &fnum))) {
                        d_printf("posix_open file %s: for read/write fnum %d\n", targetname, fnum);
                } else {
                        d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli));
@@ -2339,7 +2346,6 @@ static int cmd_posix_mkdir(void)
        char *targetname = NULL;
        struct cli_state *targetcli;
        mode_t mode;
-       int fnum;
 
        if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                d_printf("posix_mkdir <filename> 0<mode>\n");
@@ -2359,13 +2365,12 @@ static int cmd_posix_mkdir(void)
        }
        mode = (mode_t)strtol(buf, (char **)NULL, 8);
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("posix_mkdir %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
 
-       fnum = cli_posix_mkdir(targetcli, targetname, mode);
-       if (fnum == -1) {
+       if (!NT_STATUS_IS_OK(cli_posix_mkdir(targetcli, targetname, mode))) {
                d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli));
        } else {
                d_printf("posix_mkdir created directory %s\n", targetname);
@@ -2393,12 +2398,12 @@ static int cmd_posix_unlink(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("posix_unlink %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
 
-       if (!cli_posix_unlink(targetcli, targetname)) {
+       if (!NT_STATUS_IS_OK(cli_posix_unlink(targetcli, targetname))) {
                d_printf("Failed to unlink file %s. %s\n", targetname, cli_errstr(cli));
        } else {
                d_printf("posix_unlink deleted file %s\n", targetname);
@@ -2427,12 +2432,12 @@ static int cmd_posix_rmdir(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("posix_rmdir %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
 
-       if (!cli_posix_rmdir(targetcli, targetname)) {
+       if (!NT_STATUS_IS_OK(cli_posix_rmdir(targetcli, targetname))) {
                d_printf("Failed to unlink directory %s. %s\n", targetname, cli_errstr(cli));
        } else {
                d_printf("posix_rmdir deleted directory %s\n", targetname);
@@ -2454,7 +2459,7 @@ static int cmd_close(void)
 
        fnum = atoi(buf);
        /* We really should use the targetcli here.... */
-       if (!cli_close(cli, fnum)) {
+       if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
                d_printf("close %d: %s\n", fnum, cli_errstr(cli));
                return 1;
        }
@@ -2467,14 +2472,18 @@ static int cmd_posix(void)
        uint16 major, minor;
        uint32 caplow, caphigh;
        char *caps;
+       NTSTATUS status;
 
        if (!SERVER_HAS_UNIX_CIFS(cli)) {
                d_printf("Server doesn't support UNIX CIFS extensions.\n");
                return 1;
        }
 
-       if (!cli_unix_extensions_version(cli, &major, &minor, &caplow, &caphigh)) {
-               d_printf("Can't get UNIX CIFS extensions version from server.\n");
+       status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
+                                            &caphigh);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("Can't get UNIX CIFS extensions version from "
+                        "server: %s\n", nt_errstr(status));
                return 1;
        }
 
@@ -2545,8 +2554,11 @@ static int cmd_posix(void)
 
        d_printf("Server supports CIFS capabilities %s\n", caps);
 
-       if (!cli_set_unix_extensions_capabilities(cli, major, minor, caplow, caphigh)) {
-               d_printf("Can't set UNIX CIFS extensions capabilities. %s.\n", cli_errstr(cli));
+       status = cli_set_unix_extensions_capabilities(cli, major, minor,
+                                                     caplow, caphigh);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("Can't set UNIX CIFS extensions capabilities. %s.\n",
+                        nt_errstr(status));
                return 1;
        }
 
@@ -2601,7 +2613,7 @@ static int cmd_lock(void)
 
        len = (uint64_t)strtol(buf, (char **)NULL, 16);
 
-       if (!cli_posix_lock(cli, fnum, start, len, true, lock_type)) {
+       if (!NT_STATUS_IS_OK(cli_posix_lock(cli, fnum, start, len, true, lock_type))) {
                d_printf("lock failed %d: %s\n", fnum, cli_errstr(cli));
        }
 
@@ -2635,7 +2647,7 @@ static int cmd_unlock(void)
 
        len = (uint64_t)strtol(buf, (char **)NULL, 16);
 
-       if (!cli_posix_unlock(cli, fnum, start, len)) {
+       if (!NT_STATUS_IS_OK(cli_posix_unlock(cli, fnum, start, len))) {
                d_printf("unlock failed %d: %s\n", fnum, cli_errstr(cli));
        }
 
@@ -2667,12 +2679,12 @@ static int cmd_rmdir(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, mask, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) {
                d_printf("rmdir %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
 
-       if (!cli_rmdir(targetcli, targetname)) {
+       if (!NT_STATUS_IS_OK(cli_rmdir(targetcli, targetname))) {
                d_printf("%s removing remote directory file %s\n",
                         cli_errstr(targetcli),mask);
        }
@@ -2714,7 +2726,7 @@ static int cmd_link(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, oldname, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, oldname, &targetcli, &targetname)) {
                d_printf("link %s: %s\n", oldname, cli_errstr(cli));
                return 1;
        }
@@ -2724,13 +2736,61 @@ static int cmd_link(void)
                return 1;
        }
 
-       if (!cli_unix_hardlink(targetcli, targetname, newname)) {
+       if (!NT_STATUS_IS_OK(cli_posix_hardlink(targetcli, targetname, newname))) {
                d_printf("%s linking files (%s -> %s)\n", cli_errstr(targetcli), newname, oldname);
                return 1;
        }
        return 0;
 }
 
+/****************************************************************************
+ UNIX readlink.
+****************************************************************************/
+
+static int cmd_readlink(void)
+{
+       TALLOC_CTX *ctx = talloc_tos();
+       char *name= NULL;
+       char *buf = NULL;
+       char *targetname = NULL;
+       char linkname[PATH_MAX+1];
+       struct cli_state *targetcli;
+
+       if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
+               d_printf("readlink <name>\n");
+               return 1;
+       }
+       name = talloc_asprintf(ctx,
+                       "%s%s",
+                       client_get_cur_dir(),
+                       buf);
+       if (!name) {
+               return 1;
+       }
+
+       if (!cli_resolve_path(ctx, "", auth_info, cli, name, &targetcli, &targetname)) {
+               d_printf("readlink %s: %s\n", name, cli_errstr(cli));
+               return 1;
+       }
+
+       if (!SERVER_HAS_UNIX_CIFS(targetcli)) {
+               d_printf("Server doesn't support UNIX CIFS calls.\n");
+               return 1;
+       }
+
+       if (!NT_STATUS_IS_OK(cli_posix_readlink(targetcli, name,
+                       linkname, PATH_MAX+1))) {
+               d_printf("%s readlink on file %s\n",
+                       cli_errstr(targetcli), name);
+               return 1;
+       }
+
+       d_printf("%s -> %s\n", name, linkname);
+
+       return 0;
+}
+
+
 /****************************************************************************
  UNIX symlink.
 ****************************************************************************/
@@ -2765,7 +2825,7 @@ static int cmd_symlink(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, oldname, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, oldname, &targetcli, &targetname)) {
                d_printf("link %s: %s\n", oldname, cli_errstr(cli));
                return 1;
        }
@@ -2775,7 +2835,7 @@ static int cmd_symlink(void)
                return 1;
        }
 
-       if (!cli_unix_symlink(targetcli, targetname, newname)) {
+       if (!NT_STATUS_IS_OK(cli_posix_symlink(targetcli, targetname, newname))) {
                d_printf("%s symlinking files (%s -> %s)\n",
                        cli_errstr(targetcli), newname, targetname);
                return 1;
@@ -2813,7 +2873,7 @@ static int cmd_chmod(void)
 
        mode = (mode_t)strtol(buf, NULL, 8);
 
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) {
                d_printf("chmod %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -2823,7 +2883,7 @@ static int cmd_chmod(void)
                return 1;
        }
 
-       if (!cli_unix_chmod(targetcli, targetname, mode)) {
+       if (!NT_STATUS_IS_OK(cli_posix_chmod(targetcli, targetname, mode))) {
                d_printf("%s chmod file %s 0%o\n",
                        cli_errstr(targetcli), src, (unsigned int)mode);
                return 1;
@@ -2953,6 +3013,7 @@ static int cmd_getfacl(void)
        uint16 num_file_acls = 0;
        uint16 num_dir_acls = 0;
        uint16 i;
+       NTSTATUS status;
 
        if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) {
                d_printf("getfacl filename\n");
@@ -2966,7 +3027,7 @@ static int cmd_getfacl(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) {
                d_printf("stat %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -2976,9 +3037,11 @@ static int cmd_getfacl(void)
                return 1;
        }
 
-       if (!cli_unix_extensions_version(targetcli, &major, &minor,
-                               &caplow, &caphigh)) {
-               d_printf("Can't get UNIX CIFS version from server.\n");
+       status = cli_unix_extensions_version(targetcli, &major, &minor,
+                                            &caplow, &caphigh);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("Can't get UNIX CIFS version from server: %s.\n",
+                        nt_errstr(status));
                return 1;
        }
 
@@ -2988,23 +3051,22 @@ static int cmd_getfacl(void)
                return 1;
        }
 
-       if (!cli_unix_stat(targetcli, targetname, &sbuf)) {
+       if (!NT_STATUS_IS_OK(cli_posix_stat(targetcli, targetname, &sbuf))) {
                d_printf("%s getfacl doing a stat on file %s\n",
                        cli_errstr(targetcli), src);
                return 1;
        }
 
-       if (!cli_unix_getfacl(targetcli, targetname, &rb_size, &retbuf)) {
+       if (!NT_STATUS_IS_OK(cli_posix_getfacl(targetcli, targetname, ctx, &rb_size, &retbuf))) {
                d_printf("%s getfacl file %s\n",
                        cli_errstr(targetcli), src);
                return 1;
        }
 
        /* ToDo : Print out the ACL values. */
-       if (SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION || rb_size < 6) {
+       if (rb_size < 6 || SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION) {
                d_printf("getfacl file %s, unknown POSIX acl version %u.\n",
                        src, (unsigned int)CVAL(retbuf,0) );
-               SAFE_FREE(retbuf);
                return 1;
        }
 
@@ -3015,13 +3077,11 @@ static int cmd_getfacl(void)
                        src,
                        (unsigned int)(SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)),
                        (unsigned int)rb_size);
-
-               SAFE_FREE(retbuf);
                return 1;
        }
 
        d_printf("# file: %s\n", src);
-       d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_uid, (unsigned int)sbuf.st_gid);
+       d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_ex_uid, (unsigned int)sbuf.st_ex_gid);
 
        if (num_file_acls == 0 && num_dir_acls == 0) {
                d_printf("No acls found.\n");
@@ -3101,7 +3161,6 @@ static int cmd_getfacl(void)
                d_printf("%s\n", perms_to_string(permstring, perms));
        }
 
-       SAFE_FREE(retbuf);
        return 0;
 }
 
@@ -3119,6 +3178,7 @@ static int cmd_stat(void)
        fstring mode_str;
        SMB_STRUCT_STAT sbuf;
        struct tm *lt;
+       time_t tmp_time;
 
        if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) {
                d_printf("stat file\n");
@@ -3132,7 +3192,7 @@ static int cmd_stat(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) {
                d_printf("stat %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -3142,7 +3202,7 @@ static int cmd_stat(void)
                return 1;
        }
 
-       if (!cli_unix_stat(targetcli, targetname, &sbuf)) {
+       if (!NT_STATUS_IS_OK(cli_posix_stat(targetcli, targetname, &sbuf))) {
                d_printf("%s stat file %s\n",
                        cli_errstr(targetcli), src);
                return 1;
@@ -3151,30 +3211,31 @@ static int cmd_stat(void)
        /* Print out the stat values. */
        d_printf("File: %s\n", src);
        d_printf("Size: %-12.0f\tBlocks: %u\t%s\n",
-               (double)sbuf.st_size,
-               (unsigned int)sbuf.st_blocks,
-               filetype_to_str(sbuf.st_mode));
+               (double)sbuf.st_ex_size,
+               (unsigned int)sbuf.st_ex_blocks,
+               filetype_to_str(sbuf.st_ex_mode));
 
 #if defined(S_ISCHR) && defined(S_ISBLK)
-       if (S_ISCHR(sbuf.st_mode) || S_ISBLK(sbuf.st_mode)) {
+       if (S_ISCHR(sbuf.st_ex_mode) || S_ISBLK(sbuf.st_ex_mode)) {
                d_printf("Inode: %.0f\tLinks: %u\tDevice type: %u,%u\n",
-                       (double)sbuf.st_ino,
-                       (unsigned int)sbuf.st_nlink,
-                       unix_dev_major(sbuf.st_rdev),
-                       unix_dev_minor(sbuf.st_rdev));
+                       (double)sbuf.st_ex_ino,
+                       (unsigned int)sbuf.st_ex_nlink,
+                       unix_dev_major(sbuf.st_ex_rdev),
+                       unix_dev_minor(sbuf.st_ex_rdev));
        } else
 #endif
                d_printf("Inode: %.0f\tLinks: %u\n",
-                       (double)sbuf.st_ino,
-                       (unsigned int)sbuf.st_nlink);
+                       (double)sbuf.st_ex_ino,
+                       (unsigned int)sbuf.st_ex_nlink);
 
        d_printf("Access: (0%03o/%s)\tUid: %u\tGid: %u\n",
-               ((int)sbuf.st_mode & 0777),
-               unix_mode_to_str(mode_str, sbuf.st_mode),
-               (unsigned int)sbuf.st_uid,
-               (unsigned int)sbuf.st_gid);
+               ((int)sbuf.st_ex_mode & 0777),
+               unix_mode_to_str(mode_str, sbuf.st_ex_mode),
+               (unsigned int)sbuf.st_ex_uid,
+               (unsigned int)sbuf.st_ex_gid);
 
-       lt = localtime(&sbuf.st_atime);
+       tmp_time = convert_timespec_to_time_t(sbuf.st_ex_atime);
+       lt = localtime(&tmp_time);
        if (lt) {
                strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
        } else {
@@ -3182,7 +3243,8 @@ static int cmd_stat(void)
        }
        d_printf("Access: %s\n", mode_str);
 
-       lt = localtime(&sbuf.st_mtime);
+       tmp_time = convert_timespec_to_time_t(sbuf.st_ex_mtime);
+       lt = localtime(&tmp_time);
        if (lt) {
                strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
        } else {
@@ -3190,7 +3252,8 @@ static int cmd_stat(void)
        }
        d_printf("Modify: %s\n", mode_str);
 
-       lt = localtime(&sbuf.st_ctime);
+       tmp_time = convert_timespec_to_time_t(sbuf.st_ex_ctime);
+       lt = localtime(&tmp_time);
        if (lt) {
                strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
        } else {
@@ -3233,7 +3296,7 @@ static int cmd_chown(void)
        if (!src) {
                return 1;
        }
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname) ) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname) ) {
                d_printf("chown %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -3243,7 +3306,7 @@ static int cmd_chown(void)
                return 1;
        }
 
-       if (!cli_unix_chown(targetcli, targetname, uid, gid)) {
+       if (!NT_STATUS_IS_OK(cli_posix_chown(targetcli, targetname, uid, gid))) {
                d_printf("%s chown file %s uid=%d, gid=%d\n",
                        cli_errstr(targetcli), src, (int)uid, (int)gid);
                return 1;
@@ -3287,17 +3350,17 @@ static int cmd_rename(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetsrc)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetsrc)) {
                d_printf("rename %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, dest, &targetcli, &targetdest)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, dest, &targetcli, &targetdest)) {
                d_printf("rename %s: %s\n", dest, cli_errstr(cli));
                return 1;
        }
 
-       if (!cli_rename(targetcli, targetsrc, targetdest)) {
+       if (!NT_STATUS_IS_OK(cli_rename(targetcli, targetsrc, targetdest))) {
                d_printf("%s renaming files %s -> %s \n",
                        cli_errstr(targetcli),
                        targetsrc,
@@ -3317,9 +3380,12 @@ static int cmd_volume(void)
        fstring volname;
        uint32 serial_num;
        time_t create_date;
+       NTSTATUS status;
 
-       if (!cli_get_fs_volume_info(cli, volname, &serial_num, &create_date)) {
-               d_printf("Errr %s getting volume info\n",cli_errstr(cli));
+       status = cli_get_fs_volume_info(cli, volname, &serial_num,
+                                       &create_date);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("Error %s getting volume info\n", nt_errstr(status));
                return 1;
        }
 
@@ -3362,12 +3428,12 @@ static int cmd_hardlink(void)
                return 1;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, src, &targetcli, &targetname)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) {
                d_printf("hardlink %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
 
-       if (!cli_nt_hardlink(targetcli, targetname, dest)) {
+       if (!NT_STATUS_IS_OK(cli_nt_hardlink(targetcli, targetname, dest))) {
                d_printf("%s doing an NT hard link of files\n",cli_errstr(targetcli));
                return 1;
        }
@@ -3398,8 +3464,8 @@ static int cmd_newer(void)
        SMB_STRUCT_STAT sbuf;
 
        ok = next_token_talloc(ctx, &cmd_ptr,&buf,NULL);
-       if (ok && (sys_stat(buf,&sbuf) == 0)) {
-               newer_than = sbuf.st_mtime;
+       if (ok && (sys_stat(buf, &sbuf, false) == 0)) {
+               newer_than = convert_timespec_to_time_t(sbuf.st_ex_mtime);
                DEBUG(1,("Getting files newer than %s",
                         time_to_asc(newer_than)));
        } else {
@@ -3577,7 +3643,7 @@ static int cmd_reput(void)
                return 1;
        }
 
-       if (!file_exist_stat(local_name, &st)) {
+       if (!file_exist_stat(local_name, &st, false)) {
                d_printf("%s does not exist\n", local_name);
                return 1;
        }
@@ -3638,7 +3704,7 @@ static void browse_fn(const char *name, uint32 m,
 static bool browse_host_rpc(bool sort)
 {
        NTSTATUS status;
-       struct rpc_pipe_client *pipe_hnd;
+       struct rpc_pipe_client *pipe_hnd = NULL;
        TALLOC_CTX *frame = talloc_stackframe();
        WERROR werr;
        struct srvsvc_NetShareInfoCtr info_ctr;
@@ -3815,7 +3881,7 @@ static int cmd_logon(void)
 
 static int cmd_list_connect(void)
 {
-       cli_cm_display();
+       cli_cm_display(cli);
        return 0;
 }
 
@@ -3829,7 +3895,7 @@ static int cmd_show_connect( void )
        struct cli_state *targetcli;
        char *targetpath;
 
-       if (!cli_resolve_path(ctx, "", cli, client_get_cur_dir(),
+       if (!cli_resolve_path(ctx, "", auth_info, cli, client_get_cur_dir(),
                                &targetcli, &targetpath ) ) {
                d_printf("showconnect %s: %s\n", cur_dir, cli_errstr(cli));
                return 1;
@@ -3948,6 +4014,7 @@ static struct {
   {"q",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
   {"queue",cmd_queue,"show the print queue",{COMPL_NONE,COMPL_NONE}},
   {"quit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
+  {"readlink",cmd_readlink,"filename Do a UNIX extensions readlink call on a symlink",{COMPL_REMOTE,COMPL_REMOTE}},
   {"rd",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
   {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}},  
   {"reget",cmd_reget,"<remote name> [local name] get a file restarting at end of local file",{COMPL_REMOTE,COMPL_LOCAL}},
@@ -4051,7 +4118,9 @@ static int process_command_string(const char *cmd_in)
        if (!cli) {
                cli = cli_cm_open(talloc_tos(), NULL,
                                have_ip ? dest_ss_str : desthost,
-                               service, true, smb_encrypt);
+                               service, auth_info,
+                               true, smb_encrypt,
+                               max_protocol, port, name_type);
                if (!cli) {
                        return 1;
                }
@@ -4092,20 +4161,20 @@ static int process_command_string(const char *cmd_in)
 
 #define MAX_COMPLETIONS 100
 
-typedef struct {
+struct completion_remote {
        char *dirmask;
        char **matches;
        int count, samelen;
        const char *text;
        int len;
-} completion_remote_t;
+};
 
 static void completion_remote_filter(const char *mnt,
                                file_info *f,
                                const char *mask,
                                void *state)
 {
-       completion_remote_t *info = (completion_remote_t *)state;
+       struct completion_remote *info = (struct completion_remote *)state;
 
        if ((info->count < MAX_COMPLETIONS - 1) &&
                        (strncmp(info->text, f->name, info->len) == 0) &&
@@ -4163,9 +4232,9 @@ static char **remote_completion(const char *text, int len)
        char *targetpath = NULL;
        struct cli_state *targetcli = NULL;
        int i;
-       completion_remote_t info = { NULL, NULL, 1, 0, NULL, 0 };
+       struct completion_remote info = { NULL, NULL, 1, 0, NULL, 0 };
 
-       /* can't have non-static intialisation on Sun CC, so do it
+       /* can't have non-static initialisation on Sun CC, so do it
           at run time here */
        info.samelen = len;
        info.text = text;
@@ -4219,7 +4288,7 @@ static char **remote_completion(const char *text, int len)
                goto cleanup;
        }
 
-       if (!cli_resolve_path(ctx, "", cli, dirmask, &targetcli, &targetpath)) {
+       if (!cli_resolve_path(ctx, "", auth_info, cli, dirmask, &targetcli, &targetpath)) {
                goto cleanup;
        }
        if (cli_list(targetcli, targetpath, aDIR | aSYSTEM | aHIDDEN,
@@ -4516,7 +4585,8 @@ static int process(const char *base_directory)
 
        cli = cli_cm_open(talloc_tos(), NULL,
                        have_ip ? dest_ss_str : desthost,
-                       service, true, smb_encrypt);
+                       service, auth_info, true, smb_encrypt,
+                       max_protocol, port, name_type);
        if (!cli) {
                return 1;
        }
@@ -4524,7 +4594,7 @@ static int process(const char *base_directory)
        if (base_directory && *base_directory) {
                rc = do_cd(base_directory);
                if (rc) {
-                       cli_cm_shutdown();
+                       cli_shutdown(cli);
                        return rc;
                }
        }
@@ -4535,7 +4605,7 @@ static int process(const char *base_directory)
                process_stdin();
        }
 
-       cli_cm_shutdown();
+       cli_shutdown(cli);
        return rc;
 }
 
@@ -4545,19 +4615,24 @@ static int process(const char *base_directory)
 
 static int do_host_query(const char *query_host)
 {
-       struct sockaddr_storage ss;
-
        cli = cli_cm_open(talloc_tos(), NULL,
-                       query_host, "IPC$", true, smb_encrypt);
+                       query_host, "IPC$", auth_info, true, smb_encrypt,
+                       max_protocol, port, name_type);
        if (!cli)
                return 1;
 
        browse_host(true);
 
-       if (interpret_string_addr(&ss, query_host, 0) && (ss.ss_family != AF_INET)) {
-               d_printf("%s is an IPv6 address -- no workgroup available\n",
-                       query_host);
-               return 1;
+       /* Ensure that the host can do IPv4 */
+
+       if (!interpret_addr(query_host)) {
+               struct sockaddr_storage ss;
+               if (interpret_string_addr(&ss, query_host, 0) &&
+                               (ss.ss_family != AF_INET)) {
+                       d_printf("%s is an IPv6 address -- no workgroup available\n",
+                               query_host);
+                       return 1;
+               }
        }
 
        if (port != 139) {
@@ -4565,10 +4640,10 @@ static int do_host_query(const char *query_host)
                /* Workgroups simply don't make sense over anything
                   else but port 139... */
 
-               cli_cm_shutdown();
-               cli_cm_set_port( 139 );
+               cli_shutdown(cli);
                cli = cli_cm_open(talloc_tos(), NULL,
-                               query_host, "IPC$", true, smb_encrypt);
+                               query_host, "IPC$", auth_info, true, smb_encrypt,
+                               max_protocol, 139, name_type);
        }
 
        if (cli == NULL) {
@@ -4578,7 +4653,7 @@ static int do_host_query(const char *query_host)
 
        list_servers(lp_workgroup());
 
-       cli_cm_shutdown();
+       cli_shutdown(cli);
 
        return(0);
 }
@@ -4595,7 +4670,8 @@ static int do_tar_op(const char *base_directory)
        if (!cli) {
                cli = cli_cm_open(talloc_tos(), NULL,
                        have_ip ? dest_ss_str : desthost,
-                       service, true, smb_encrypt);
+                       service, auth_info, true, smb_encrypt,
+                       max_protocol, port, name_type);
                if (!cli)
                        return 1;
        }
@@ -4605,14 +4681,14 @@ static int do_tar_op(const char *base_directory)
        if (base_directory && *base_directory)  {
                ret = do_cd(base_directory);
                if (ret) {
-                       cli_cm_shutdown();
+                       cli_shutdown(cli);
                        return ret;
                }
        }
 
        ret=process_tar();
 
-       cli_cm_shutdown();
+       cli_shutdown(cli);
 
        return(ret);
 }
@@ -4621,7 +4697,7 @@ static int do_tar_op(const char *base_directory)
  Handle a message operation.
 ****************************************************************************/
 
-static int do_message_op(struct user_auth_info *auth_info)
+static int do_message_op(struct user_auth_info *a_info)
 {
        struct sockaddr_storage ss;
        struct nmb_name called, calling;
@@ -4645,10 +4721,11 @@ static int do_message_op(struct user_auth_info *auth_info)
 
        msg_port = port ? port : 139;
 
-       if (!(cli=cli_initialise()) || (cli_set_port(cli, msg_port) != msg_port)) {
+       if (!(cli=cli_initialise())) {
                d_printf("Connection to %s failed\n", desthost);
                return 1;
        }
+       cli_set_port(cli, msg_port);
 
        status = cli_connect(cli, server_name, &ss);
        if (!NT_STATUS_IS_OK(status)) {
@@ -4658,12 +4735,12 @@ static int do_message_op(struct user_auth_info *auth_info)
 
        if (!cli_session_request(cli, &calling, &called)) {
                d_printf("session request failed\n");
-               cli_cm_shutdown();
+               cli_shutdown(cli);
                return 1;
        }
 
-       send_message(get_cmdline_auth_info_username(auth_info));
-       cli_cm_shutdown();
+       send_message(get_cmdline_auth_info_username(a_info));
+       cli_shutdown(cli);
 
        return 0;
 }
@@ -4678,7 +4755,6 @@ static int do_message_op(struct user_auth_info *auth_info)
        int opt;
        char *query_host = NULL;
        bool message = false;
-       char *term_code = NULL;
        static const char *new_name_resolve_order = NULL;
        poptContext pc;
        char *p;
@@ -4694,7 +4770,6 @@ static int do_message_op(struct user_auth_info *auth_info)
                { "ip-address", 'I', POPT_ARG_STRING, NULL, 'I', "Use this IP to connect to", "IP" },
                { "stderr", 'E', POPT_ARG_NONE, NULL, 'E', "Write messages to stderr instead of stdout" },
                { "list", 'L', POPT_ARG_STRING, NULL, 'L', "Get a list of shares available on a host", "HOST" },
-               { "terminal", 't', POPT_ARG_STRING, NULL, 't', "Terminal I/O code {sjis|euc|jis7|jis8|junet|hex}", "CODE" },
                { "max-protocol", 'm', POPT_ARG_STRING, NULL, 'm', "Set the max protocol level", "LEVEL" },
                { "tar", 'T', POPT_ARG_STRING, NULL, 'T', "Command line tar", "<c|x>IXFqgbNan" },
                { "directory", 'D', POPT_ARG_STRING, NULL, 'D', "Start from directory", "DIR" },
@@ -4709,21 +4784,11 @@ static int do_message_op(struct user_auth_info *auth_info)
                POPT_TABLEEND
        };
        TALLOC_CTX *frame = talloc_stackframe();
-       struct user_auth_info *auth_info;
 
        if (!client_set_cur_dir("\\")) {
                exit(ENOMEM);
        }
 
-#ifdef KANJI
-       term_code = talloc_strdup(frame,KANJI);
-#else /* KANJI */
-       term_code = talloc_strdup(frame,"");
-#endif /* KANJI */
-       if (!term_code) {
-               exit(ENOMEM);
-       }
-
        /* initialize the workgroup name so we can determine whether or
           not it was set by a command line option */
 
@@ -4786,13 +4851,12 @@ static int do_message_op(struct user_auth_info *auth_info)
                         * to port 139 instead of port 445. srl,crh
                         */
                        name_type = 0x03;
-                       cli_cm_set_dest_name_type( name_type );
                        desthost = talloc_strdup(frame,poptGetOptArg(pc));
                        if (!desthost) {
                                exit(ENOMEM);
                        }
                        if( !port )
-                               cli_cm_set_port( 139 );
+                               port = 139;
                        message = true;
                        break;
                case 'I':
@@ -4818,12 +4882,6 @@ static int do_message_op(struct user_auth_info *auth_info)
                                exit(ENOMEM);
                        }
                        break;
-               case 't':
-                       term_code = talloc_strdup(frame,poptGetOptArg(pc));
-                       if (!term_code) {
-                               exit(ENOMEM);
-                       }
-                       break;
                case 'm':
                        max_protocol = interpret_protocol(poptGetOptArg(pc), max_protocol);
                        break;
@@ -4888,11 +4946,6 @@ static int do_message_op(struct user_auth_info *auth_info)
                                               poptGetArg(pc));
        }
 
-       /* check for the -P option */
-
-       if ( port != 0 )
-               cli_cm_set_port( port );
-
        /*
         * Don't load debug level from smb.conf. It should be
         * set by cmdline arg or remain default (0)
@@ -4971,11 +5024,10 @@ static int do_message_op(struct user_auth_info *auth_info)
 
        poptFreeContext(pc);
 
-       /* Store the username and password for dfs support */
-
-       cli_cm_set_credentials(auth_info);
+       DEBUG(3,("Client started (version %s).\n", samba_version_string()));
 
-       DEBUG(3,("Client started (version %s).\n", SAMBA_VERSION_STRING));
+       /* Ensure we have a password (or equivalent). */
+       set_cmdline_auth_info_getpass(auth_info);
 
        if (tar_type) {
                if (cmdstr)
@@ -4999,7 +5051,6 @@ static int do_message_op(struct user_auth_info *auth_info)
                        *p = 0;
                        p++;
                        sscanf(p, "%x", &name_type);
-                       cli_cm_set_dest_name_type( name_type );
                }
 
                return do_host_query(qhost);