r66: fixed a segv when printing an error from a session setup failure. This
[samba.git] / source / client / client.c
index 5c72da1731a8f465e65cb76ca93902945d08be4d..0430689865c323e4341b879a278d8ea24b88d640 100644 (file)
@@ -22,7 +22,6 @@
 */
 
 #include "includes.h"
-#include "../client/client_proto.h"
 #ifndef REGISTER
 #define REGISTER 0
 #endif
@@ -83,8 +82,6 @@ static BOOL abort_mget = True;
 
 static pstring fileselection = "";
 
-extern file_info def_finfo;
-
 /* timing globals */
 SMB_BIG_UINT get_total_size = 0;
 unsigned int get_total_time_ms = 0;
@@ -194,8 +191,8 @@ static void send_message(void)
        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));
+       if (!cli_message_start(cli->tree, desthost, username, &grp_id)) {
+               d_printf("message start: %s\n", cli_errstr(cli->tree));
                return;
        }
 
@@ -216,8 +213,8 @@ static void send_message(void)
                        msg[l] = c;   
                }
 
-               if (!cli_message_text(cli, msg, l, grp_id)) {
-                       d_printf("SMBsendtxt failed (%s)\n",cli_errstr(cli));
+               if (!cli_message_text(cli->tree, msg, l, grp_id)) {
+                       d_printf("SMBsendtxt failed (%s)\n",cli_errstr(cli->tree));
                        return;
                }      
                
@@ -229,8 +226,8 @@ static void send_message(void)
        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));
+       if (!cli_message_end(cli->tree, grp_id)) {
+               d_printf("SMBsendend failed (%s)\n",cli_errstr(cli->tree));
                return;
        }      
 }
@@ -244,8 +241,8 @@ static int do_dskattr(void)
 {
        int total, bsize, avail;
 
-       if (!cli_dskattr(cli, &bsize, &total, &avail)) {
-               d_printf("Error in dskattr: %s\n",cli_errstr(cli)); 
+       if (NT_STATUS_IS_ERR(cli_dskattr(cli->tree, &bsize, &total, &avail))) {
+               d_printf("Error in dskattr: %s\n",cli_errstr(cli->tree)); 
                return 1;
        }
 
@@ -293,8 +290,8 @@ static int do_cd(char *newdir)
        dos_clean_name(cur_dir);
        
        if (!strequal(cur_dir,"\\")) {
-               if (!cli_chkpath(cli, dname)) {
-                       d_printf("cd %s: %s\n", dname, cli_errstr(cli));
+               if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, dname))) {
+                       d_printf("cd %s: %s\n", dname, cli_errstr(cli->tree));
                        pstrcpy(cur_dir,saved_dir);
                }
        }
@@ -601,7 +598,7 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
                         */
                        pstring head;
                        pstrcpy(head, do_list_queue_head());
-                       cli_list(cli, head, attribute, do_list_helper, NULL);
+                       cli_list(cli->tree, head, attribute, do_list_helper, NULL);
                        remove_do_list_queue_head();
                        if ((! do_list_queue_empty()) && (fn == display_finfo))
                        {
@@ -625,9 +622,9 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
        }
        else
        {
-               if (cli_list(cli, mask, attribute, do_list_helper, NULL) == -1)
+               if (cli_list(cli->tree, mask, attribute, do_list_helper, NULL) == -1)
                {
-                       d_printf("%s listing %s\n", cli_errstr(cli), mask);
+                       d_printf("%s listing %s\n", cli_errstr(cli->tree), mask);
                }
        }
 
@@ -730,10 +727,10 @@ static int do_get(char *rname, const char *lname, BOOL reget)
                strlower(lname);
        }
 
-       fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
+       fnum = cli_open(cli->tree, rname, O_RDONLY, DENY_NONE);
 
        if (fnum == -1) {
-               d_printf("%s opening remote file %s\n",cli_errstr(cli),rname);
+               d_printf("%s opening remote file %s\n",cli_errstr(cli->tree),rname);
                return 1;
        }
 
@@ -760,11 +757,11 @@ static int do_get(char *rname, const char *lname, BOOL reget)
        }
 
 
-       if (!cli_qfileinfo(cli, fnum, 
-                          &attr, &size, NULL, NULL, NULL, NULL, NULL) &&
-           !cli_getattrE(cli, fnum, 
-                         &attr, &size, NULL, NULL, NULL)) {
-               d_printf("getattrib: %s\n",cli_errstr(cli));
+       if (NT_STATUS_IS_ERR(cli_qfileinfo(cli->tree, fnum, 
+                          &attr, &size, NULL, NULL, NULL, NULL, NULL)) &&
+           NT_STATUS_IS_ERR(cli_getattrE(cli->tree, fnum, 
+                         &attr, &size, NULL, NULL, NULL))) {
+               d_printf("getattrib: %s\n",cli_errstr(cli->tree));
                return 1;
        }
 
@@ -773,12 +770,12 @@ static int do_get(char *rname, const char *lname, BOOL reget)
 
        if(!(data = (char *)malloc(read_size))) { 
                d_printf("malloc fail for size %d\n", read_size);
-               cli_close(cli, fnum);
+               cli_close(cli->tree, fnum);
                return 1;
        }
 
        while (1) {
-               int n = cli_read(cli, fnum, data, nread + start, read_size);
+               int n = cli_read(cli->tree, fnum, data, nread + start, read_size);
 
                if (n <= 0) break;
  
@@ -800,8 +797,8 @@ static int do_get(char *rname, const char *lname, BOOL reget)
 
        SAFE_FREE(data);
        
-       if (!cli_close(cli, fnum)) {
-               d_printf("Error %s closing remote file\n",cli_errstr(cli));
+       if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) {
+               d_printf("Error %s closing remote file\n",cli_errstr(cli->tree));
                rc = 1;
        }
 
@@ -810,7 +807,7 @@ static int do_get(char *rname, const char *lname, BOOL reget)
        }
 
        if (archive_level >= 2 && (attr & FILE_ATTRIBUTE_ARCHIVE)) {
-               cli_setatr(cli, rname, attr & ~(uint16)FILE_ATTRIBUTE_ARCHIVE, 0);
+               cli_setatr(cli->tree, rname, attr & ~(uint16)FILE_ATTRIBUTE_ARCHIVE, 0);
        }
 
        {
@@ -1012,15 +1009,17 @@ static int cmd_mget(void)
 /****************************************************************************
 make a directory of name "name"
 ****************************************************************************/
-static BOOL do_mkdir(char *name)
+static NTSTATUS do_mkdir(char *name)
 {
-       if (!cli_mkdir(cli, name)) {
+       NTSTATUS status;
+
+       if (NT_STATUS_IS_ERR(status = cli_mkdir(cli->tree, name))) {
                d_printf("%s making remote directory %s\n",
-                        cli_errstr(cli),name);
-               return(False);
+                        cli_errstr(cli->tree),name);
+               return status;
        }
 
-       return(True);
+       return status;
 }
 
 /****************************************************************************
@@ -1029,9 +1028,9 @@ show 8.3 name of a file
 static BOOL do_altname(char *name)
 {
        const char *altname;
-       if (!NT_STATUS_IS_OK(cli_qpathinfo_alt_name(cli, name, &altname))) {
+       if (!NT_STATUS_IS_OK(cli_qpathinfo_alt_name(cli->tree, name, &altname))) {
                d_printf("%s getting alt name for %s\n",
-                        cli_errstr(cli),name);
+                        cli_errstr(cli->tree),name);
                return(False);
        }
        d_printf("%s\n", altname);
@@ -1080,7 +1079,7 @@ static int cmd_mkdir(void)
                p = strtok(ddir,"/\\");
                while (p) {
                        pstrcat(ddir2,p);
-                       if (!cli_chkpath(cli, ddir2)) { 
+                       if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, ddir2))) { 
                                do_mkdir(ddir2);
                        }
                        pstrcat(ddir2,"\\");
@@ -1134,20 +1133,21 @@ static int do_put(char *rname, char *lname, BOOL reput)
        GetTimeOfDay(&tp_start);
 
        if (reput) {
-               fnum = cli_open(cli, rname, O_RDWR|O_CREAT, DENY_NONE);
+               fnum = cli_open(cli->tree, rname, O_RDWR|O_CREAT, DENY_NONE);
                if (fnum >= 0) {
-                       if (!cli_qfileinfo(cli, fnum, NULL, &start, NULL, NULL, NULL, NULL, NULL) &&
-                           !cli_getattrE(cli, fnum, NULL, &start, NULL, NULL, NULL)) {
-                               d_printf("getattrib: %s\n",cli_errstr(cli));
+                       if (NT_STATUS_IS_ERR(cli_qfileinfo(cli->tree, fnum, NULL, &start, NULL, NULL, NULL, NULL, NULL)) &&
+                           NT_STATUS_IS_ERR(cli_getattrE(cli->tree, fnum, NULL, &start, NULL, NULL, NULL))) {
+                               d_printf("getattrib: %s\n",cli_errstr(cli->tree));
                                return 1;
                        }
                }
        } else {
-               fnum = cli_open(cli, rname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
+               fnum = cli_open(cli->tree, rname, O_RDWR|O_CREAT|O_TRUNC, 
+                               DENY_NONE);
        }
   
        if (fnum == -1) {
-               d_printf("%s opening remote file %s\n",cli_errstr(cli),rname);
+               d_printf("%s opening remote file %s\n",cli_errstr(cli->tree),rname);
                return 1;
        }
 
@@ -1196,10 +1196,10 @@ static int do_put(char *rname, char *lname, BOOL reput)
                        break;
                }
 
-               ret = cli_write(cli, fnum, 0, buf, nread + start, n);
+               ret = cli_write(cli->tree, fnum, 0, buf, nread + start, n);
 
                if (n != ret) {
-                       d_printf("Error writing file: %s\n", cli_errstr(cli));
+                       d_printf("Error writing file: %s\n", cli_errstr(cli->tree));
                        rc = 1;
                        break;
                } 
@@ -1207,8 +1207,8 @@ static int do_put(char *rname, char *lname, BOOL reput)
                nread += n;
        }
 
-       if (!cli_close(cli, fnum)) {
-               d_printf("%s closing remote file %s\n",cli_errstr(cli),rname);
+       if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) {
+               d_printf("%s closing remote file %s\n",cli_errstr(cli->tree),rname);
                x_fclose(f);
                SAFE_FREE(buf);
                return 1;
@@ -1453,8 +1453,8 @@ static int cmd_mput(void)
                                        SAFE_FREE(rname);
                                        if(asprintf(&rname, "%s%s", cur_dir, lname) < 0) break;
                                        dos_format(rname);
-                                       if (!cli_chkpath(cli, rname) && 
-                                           !do_mkdir(rname)) {
+                                       if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, rname)) && 
+                                           NT_STATUS_IS_ERR(do_mkdir(rname))) {
                                                DEBUG (0, ("Unable to make dir, skipping..."));
                                                /* Skip the directory */
                                                lname[strlen(lname)-1] = '/';
@@ -1570,8 +1570,8 @@ static void do_del(file_info *finfo)
        if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) 
                return;
 
-       if (!cli_unlink(cli, mask)) {
-               d_printf("%s deleting remote file %s\n",cli_errstr(cli),mask);
+       if (NT_STATUS_IS_ERR(cli_unlink(cli->tree, mask))) {
+               d_printf("%s deleting remote file %s\n",cli_errstr(cli->tree),mask);
        }
 }
 
@@ -1618,10 +1618,10 @@ static int cmd_deltree(void)
        }
        pstrcat(dname,buf);
 
-       ret = cli_deltree(cli, dname);
+       ret = cli_deltree(cli->tree, dname);
 
        if (ret == -1) {
-               printf("Failed to delete tree %s - %s\n", dname, cli_errstr(cli));
+               printf("Failed to delete tree %s - %s\n", dname, cli_errstr(cli->tree));
                return -1;
        }
 
@@ -1646,7 +1646,7 @@ static int cmd_allinfo(void)
        pstrcpy(fname,cur_dir);
        
        if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
-               d_printf("deltree <dirname>\n");
+               d_printf("allinfo <filename>\n");
                return 1;
        }
        pstrcat(fname,buf);
@@ -1683,12 +1683,12 @@ static int cmd_allinfo(void)
                d_printf("\talt_name:       %s\n", finfo.alt_name_info.out.fname.s);
        }
 
-       /* dev/inode if available */
+       /* file_id if available */
        finfo.generic.level = RAW_FILEINFO_INTERNAL_INFORMATION;
        status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
        if (NT_STATUS_IS_OK(status)) {
-               d_printf("\tdevice          0x%x\n", finfo.internal_information.out.device);
-               d_printf("\tinode           0x%x\n", finfo.internal_information.out.inode);
+               d_printf("\tfile_id         %.0f\n", 
+                        (double)finfo.internal_information.out.file_id);
        }
 
        /* the EAs, if any */
@@ -1739,6 +1739,52 @@ done:
 }
 
 
+/****************************************************************************
+show any ACL on a file
+****************************************************************************/
+static int cmd_acl(void)
+{
+       pstring fname;
+       fstring buf;
+       int ret = 0;
+       TALLOC_CTX *mem_ctx;
+       struct smb_query_secdesc query;
+       NTSTATUS status;
+       int fnum;
+
+       pstrcpy(fname,cur_dir);
+       
+       if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+               d_printf("acl <filename>\n");
+               return 1;
+       }
+       pstrcat(fname,buf);
+
+       fnum = cli_open(cli->tree, fname, O_RDONLY, DENY_NONE);
+       if (fnum == -1) {
+               d_printf("%s - %s\n", fname, cli_errstr(cli->tree));
+               return -1;
+       }
+
+       mem_ctx = talloc_init(fname);
+
+       query.in.fnum = fnum;
+       query.in.secinfo_flags = 0x7;
+
+       status = smb_raw_query_secdesc(cli->tree, mem_ctx, &query);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("%s - %s\n", fname, nt_errstr(status));
+               ret = 1;
+               goto done;
+       }
+
+       talloc_destroy(mem_ctx);
+
+done:
+       return ret;
+}
+
+
 /****************************************************************************
 ****************************************************************************/
 static int cmd_open(void)
@@ -1754,7 +1800,7 @@ static int cmd_open(void)
        }
        pstrcat(mask,buf);
 
-       cli_open(cli, mask, O_RDWR, DENY_ALL);
+       cli_open(cli->tree, mask, O_RDWR, DENY_ALL);
 
        return 0;
 }
@@ -1776,9 +1822,9 @@ static int cmd_rmdir(void)
        }
        pstrcat(mask,buf);
 
-       if (!cli_rmdir(cli, mask)) {
+       if (NT_STATUS_IS_ERR(cli_rmdir(cli->tree, mask))) {
                d_printf("%s removing remote directory file %s\n",
-                        cli_errstr(cli),mask);
+                        cli_errstr(cli->tree),mask);
        }
        
        return 0;
@@ -1809,8 +1855,8 @@ static int cmd_link(void)
        pstrcat(src,buf);
        pstrcat(dest,buf2);
 
-       if (!cli_unix_hardlink(cli, src, dest)) {
-               d_printf("%s linking files (%s -> %s)\n", cli_errstr(cli), src, dest);
+       if (NT_STATUS_IS_ERR(cli_unix_hardlink(cli->tree, src, dest))) {
+               d_printf("%s linking files (%s -> %s)\n", cli_errstr(cli->tree), src, dest);
                return 1;
        }  
 
@@ -1843,9 +1889,9 @@ static int cmd_symlink(void)
        pstrcat(src,buf);
        pstrcat(dest,buf2);
 
-       if (!cli_unix_symlink(cli, src, dest)) {
+       if (NT_STATUS_IS_ERR(cli_unix_symlink(cli->tree, src, dest))) {
                d_printf("%s symlinking files (%s -> %s)\n",
-                       cli_errstr(cli), src, dest);
+                       cli_errstr(cli->tree), src, dest);
                return 1;
        } 
 
@@ -1878,9 +1924,9 @@ static int cmd_chmod(void)
        mode = (mode_t)strtol(buf, NULL, 8);
        pstrcat(src,buf2);
 
-       if (!cli_unix_chmod(cli, src, mode)) {
+       if (NT_STATUS_IS_ERR(cli_unix_chmod(cli->tree, src, mode))) {
                d_printf("%s chmod file %s 0%o\n",
-                       cli_errstr(cli), src, (unsigned int)mode);
+                       cli_errstr(cli->tree), src, (unsigned int)mode);
                return 1;
        } 
 
@@ -1916,9 +1962,9 @@ static int cmd_chown(void)
        gid = (gid_t)atoi(buf2);
        pstrcat(src,buf3);
 
-       if (!cli_unix_chown(cli, src, uid, gid)) {
+       if (NT_STATUS_IS_ERR(cli_unix_chown(cli->tree, src, uid, gid))) {
                d_printf("%s chown file %s uid=%d, gid=%d\n",
-                       cli_errstr(cli), src, (int)uid, (int)gid);
+                       cli_errstr(cli->tree), src, (int)uid, (int)gid);
                return 1;
        } 
 
@@ -1945,8 +1991,8 @@ static int cmd_rename(void)
        pstrcat(src,buf);
        pstrcat(dest,buf2);
 
-       if (!cli_rename(cli, src, dest)) {
-               d_printf("%s renaming files\n",cli_errstr(cli));
+       if (NT_STATUS_IS_ERR(cli_rename(cli->tree, src, dest))) {
+               d_printf("%s renaming files\n",cli_errstr(cli->tree));
                return 1;
        }
        
@@ -2199,6 +2245,7 @@ static struct
 {
   {"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
   {"altname",cmd_altname,"<file> show alt name",{COMPL_NONE,COMPL_NONE}},
+  {"acl",cmd_acl,"<file> show file ACL",{COMPL_NONE,COMPL_NONE}},
   {"allinfo",cmd_allinfo,"<file> show all possible info about a file",{COMPL_NONE,COMPL_NONE}},
   {"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit",{COMPL_NONE,COMPL_NONE}},
   {"blocksize",cmd_block,"blocksize <number> (default 20)",{COMPL_NONE,COMPL_NONE}},
@@ -2402,8 +2449,12 @@ static char **remote_completion(const char *text, int len)
 {
        pstring dirmask;
        int i;
-       completion_remote_t info = { "", NULL, 1, len, text, len };
+       completion_remote_t info = { "", NULL, 1, 0, NULL, 0 };
 
+       info.samelen = len;
+       info.text = text;
+       info.len = len;
        if (len >= PATH_MAX)
                return(NULL);
 
@@ -2424,7 +2475,7 @@ static char **remote_completion(const char *text, int len)
        } else
                snprintf(dirmask, sizeof(dirmask), "%s*", cur_dir);
 
-       if (cli_list(cli, dirmask, 
+       if (cli_list(cli->tree, dirmask, 
                     FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, 
                     completion_remote_filter, &info) < 0)
                goto cleanup;
@@ -2573,7 +2624,7 @@ static void readline_callback(void)
        }
 
        if (cli->tree) {
-               cli_chkpath(cli, "\\");
+               cli_chkpath(cli->tree, "\\");
        }
 }
 
@@ -2632,6 +2683,7 @@ static struct cli_state *do_connect(const char *server, const char *share)
        struct in_addr ip;
        fstring servicename;
        char *sharename;
+       NTSTATUS status;
        
        /* make a copy so we don't modify the global string 'service' */
        fstrcpy(servicename, share);
@@ -2644,6 +2696,8 @@ static struct cli_state *do_connect(const char *server, const char *share)
                sharename++;
        }
 
+       asprintf(&sharename, "\\\\%s\\%s", server, sharename);
+
        server_n = server;
        
        zero_ip(&ip);
@@ -2664,7 +2718,7 @@ static struct cli_state *do_connect(const char *server, const char *share)
        if (!cli_transport_establish(c, &calling, &called)) {
                char *p;
                d_printf("session request to %s failed (%s)\n", 
-                        called.name, cli_errstr(c));
+                        called.name, cli_errstr(c->tree));
                cli_shutdown(c);
                if ((p=strchr_m(called.name, '.'))) {
                        *p = 0;
@@ -2679,7 +2733,7 @@ static struct cli_state *do_connect(const char *server, const char *share)
 
        DEBUG(4,(" session request ok\n"));
 
-       if (!cli_negprot(c)) {
+       if (NT_STATUS_IS_ERR(cli_negprot(c))) {
                d_printf("protocol negotiation failed\n");
                cli_shutdown(c);
                return NULL;
@@ -2692,12 +2746,14 @@ static struct cli_state *do_connect(const char *server, const char *share)
                }
        }
 
-       if (!cli_session_setup(c, username, password, 
-                              lp_workgroup())) {
+       status = cli_session_setup(c, username, password, lp_workgroup());
+       if (NT_STATUS_IS_ERR(status)) {
                /* if a password was not supplied then try again with a null username */
-               if (password[0] || !username[0] || use_kerberos ||
-                   !cli_session_setup(c, "", "", lp_workgroup())) { 
-                       d_printf("session setup failed: %s\n", cli_errstr(c));
+               if (password[0] || !username[0] || use_kerberos) {
+                       status = cli_session_setup(c, "", "", lp_workgroup());
+               }
+               if (NT_STATUS_IS_ERR(status)) {
+                       d_printf("session setup failed: %s\n", nt_errstr(status));
                        cli_shutdown(c);
                        return NULL;
                }
@@ -2706,8 +2762,8 @@ static struct cli_state *do_connect(const char *server, const char *share)
 
        DEBUG(4,(" session setup ok\n"));
 
-       if (!cli_send_tconX(c, sharename, "?????", password)) {
-               d_printf("tree connect failed: %s\n", cli_errstr(c));
+       if (NT_STATUS_IS_ERR(cli_send_tconX(c, sharename, "?????", password))) {
+               d_printf("tree connect failed: %s\n", cli_errstr(c->tree));
                cli_shutdown(c);
                return NULL;
        }
@@ -2890,7 +2946,7 @@ static void remember_query_host(const char *arg,
        *query_host = 0;
        *base_directory = 0;
 
-       setup_logging(argv[0],True);
+       setup_logging(argv[0],DEBUG_STDOUT);
        mem_ctx = talloc_init("client.c/main");
        if (!mem_ctx) {
                d_printf("\nclient.c: Not enough memory\n");
@@ -2980,7 +3036,7 @@ static void remember_query_host(const char *arg,
                pstrcpy(cmdline_auth_info.password,poptGetArg(pc));  
        }
 
-       //init_names();
+       /*init_names(); */
 
        if (!tar_type && !*query_host && !*service && !message) {
                poptPrintUsage(pc, stderr, 0);
@@ -2994,7 +3050,7 @@ static void remember_query_host(const char *arg,
        use_kerberos = cmdline_auth_info.use_kerberos;
        got_pass = cmdline_auth_info.got_pass;
 
-       DEBUG( 3, ( "Client started (version %s).\n", SAMBA_VERSION ) );
+       DEBUG( 3, ( "Client started (version %s).\n", SAMBA_VERSION_STRING ) );
 
        talloc_destroy(mem_ctx);
        if (tar_type) {