Merge branch 'master' of ssh://git.samba.org/data/git/samba
[ira/wip.git] / source3 / client / client.c
index 276ffb93d8c9ce34c610f852efb009d1c3ff733a..c88b918dc8c0eba265cb384d57668b621fe434ba 100644 (file)
@@ -40,7 +40,7 @@ static char *desthost;
 static char *calling_name;
 static bool grepable = false;
 static char *cmdstr = NULL;
-static const char *cmd_ptr = NULL;
+const char *cmd_ptr = NULL;
 
 static int io_bufsize = 524288;
 
@@ -84,9 +84,9 @@ static struct sockaddr_storage dest_ss;
 static bool abort_mget = true;
 
 /* timing globals */
-SMB_BIG_UINT get_total_size = 0;
+uint64_t get_total_size = 0;
 unsigned int get_total_time_ms = 0;
-static SMB_BIG_UINT put_total_size = 0;
+static uint64_t put_total_size = 0;
 static unsigned int put_total_time_ms = 0;
 
 /* totals globals */
@@ -218,13 +218,12 @@ static int readfile(char *b, int n, XFILE *f)
  Send a message.
 ****************************************************************************/
 
-static void send_message(void)
+static void send_message(const char *username)
 {
        int total_len = 0;
        int grp_id;
 
-       if (!cli_message_start(cli, desthost,
-                               get_cmdline_auth_info_username(), &grp_id)) {
+       if (!cli_message_start(cli, desthost, username, &grp_id)) {
                d_printf("message start: %s\n", cli_errstr(cli));
                return;
        }
@@ -521,14 +520,14 @@ static void display_finfo(file_info *finfo, const char *dir)
                /* create absolute filename for cli_nt_create() FIXME */
                afname = talloc_asprintf(ctx,
                                        "%s%s%s",
-                                       client_get_cwd(),
+                                       dir,
                                        CLI_DIRSEP_STR,
                                        finfo->name);
                if (!afname) {
                        return;
                }
                /* print file meta date header */
-               d_printf( "FILENAME:%s\n", afname);
+               d_printf( "FILENAME:%s\n", finfo->name);
                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));
@@ -943,6 +942,7 @@ static int cmd_echo(void)
        TALLOC_CTX *ctx = talloc_tos();
        char *num;
        char *data;
+       NTSTATUS status;
 
        if (!next_token_talloc(ctx, &cmd_ptr, &num, NULL)
            || !next_token_talloc(ctx, &cmd_ptr, &data, NULL)) {
@@ -950,9 +950,10 @@ static int cmd_echo(void)
                return 1;
        }
 
-       if (!cli_echo(cli, atoi(num), (uint8 *)data, strlen(data))) {
-               d_printf("echo failed: %s\n",
-                        nt_errstr(cli_get_nt_error(cli)));
+       status = cli_echo(cli, atoi(num), data_blob_const(data, strlen(data)));
+
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("echo failed: %s\n", nt_errstr(status));
                return 1;
        }
 
@@ -1078,7 +1079,7 @@ static int do_get(const char *rname, const char *lname_in, bool reget)
                get_total_time_ms += this_time;
                get_total_size += nread;
 
-               DEBUG(1,("(%3.1f kb/s) (average %3.1f kb/s)\n",
+               DEBUG(1,("(%3.1f KiloBytes/sec) (average %3.1f KiloBytes/sec)\n",
                         nread / (1.024*this_time + 1.0e-4),
                         get_total_size / (1.024*get_total_time_ms)));
        }
@@ -1201,7 +1202,7 @@ static void do_mget(file_info *finfo, const char *dir)
                strlower_m(finfo->name);
        }
 
-       if (!directory_exist(finfo->name,NULL) &&
+       if (!directory_exist(finfo->name) &&
            mkdir(finfo->name,0777) != 0) {
                d_printf("failed to create directory %s\n",finfo->name);
                client_set_cur_dir(saved_curdir);
@@ -1650,6 +1651,9 @@ static int do_put(const char *rname, const char *lname, bool reput)
                d_printf("ERROR: Not enough memory!\n");
                return 1;
        }
+
+       x_setvbuf(f, NULL, X_IOFBF, maxwrite);
+
        while (!x_feof(f)) {
                int n = maxwrite;
                int ret;
@@ -1750,7 +1754,7 @@ static int cmd_put(void)
                SMB_STRUCT_STAT st;
                /* allow '-' to represent stdin
                   jdblair, 24.jun.98 */
-               if (!file_exist(lname,&st) &&
+               if (!file_exist_stat(lname,&st) &&
                    (strcmp(lname,"-"))) {
                        d_printf("%s does not exist\n",lname);
                        return 1;
@@ -2553,7 +2557,7 @@ static int cmd_lock(void)
 {
        TALLOC_CTX *ctx = talloc_tos();
        char *buf = NULL;
-       SMB_BIG_UINT start, len;
+       uint64_t start, len;
        enum brl_type lock_type;
        int fnum;
 
@@ -2582,14 +2586,14 @@ static int cmd_lock(void)
                return 1;
        }
 
-       start = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
+       start = (uint64_t)strtol(buf, (char **)NULL, 16);
 
        if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n");
                return 1;
        }
 
-       len = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
+       len = (uint64_t)strtol(buf, (char **)NULL, 16);
 
        if (!cli_posix_lock(cli, fnum, start, len, true, lock_type)) {
                d_printf("lock failed %d: %s\n", fnum, cli_errstr(cli));
@@ -2602,7 +2606,7 @@ static int cmd_unlock(void)
 {
        TALLOC_CTX *ctx = talloc_tos();
        char *buf = NULL;
-       SMB_BIG_UINT start, len;
+       uint64_t start, len;
        int fnum;
 
        if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
@@ -2616,14 +2620,14 @@ static int cmd_unlock(void)
                return 1;
        }
 
-       start = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
+       start = (uint64_t)strtol(buf, (char **)NULL, 16);
 
        if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                d_printf("unlock <fnum> <hex-start> <hex-len>\n");
                return 1;
        }
 
-       len = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
+       len = (uint64_t)strtol(buf, (char **)NULL, 16);
 
        if (!cli_posix_unlock(cli, fnum, start, len)) {
                d_printf("unlock failed %d: %s\n", fnum, cli_errstr(cli));
@@ -3036,7 +3040,7 @@ static int cmd_getfacl(void)
                                break;
                        case SMB_POSIX_ACL_GROUP:
                                uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
-                               d_printf("group:%u", uorg);
+                               d_printf("group:%u:", uorg);
                                break;
                        case SMB_POSIX_ACL_MASK:
                                d_printf("mask::");
@@ -3073,7 +3077,7 @@ static int cmd_getfacl(void)
                                break;
                        case SMB_POSIX_ACL_GROUP:
                                uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+2);
-                               d_printf("default:group:%u", uorg);
+                               d_printf("default:group:%u:", uorg);
                                break;
                        case SMB_POSIX_ACL_MASK:
                                d_printf("default:mask::");
@@ -3564,7 +3568,7 @@ static int cmd_reput(void)
                return 1;
        }
 
-       if (!file_exist(local_name, &st)) {
+       if (!file_exist_stat(local_name, &st)) {
                d_printf("%s does not exist\n", local_name);
                return 1;
        }
@@ -3634,9 +3638,10 @@ static bool browse_host_rpc(bool sort)
        uint32_t total_entries = 0;
        int i;
 
-       pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &status);
+       status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc.syntax_id,
+                                         &pipe_hnd);
 
-       if (pipe_hnd == NULL) {
+       if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10, ("Could not connect to srvsvc pipe: %s\n",
                           nt_errstr(status)));
                TALLOC_FREE(frame);
@@ -3650,7 +3655,7 @@ static bool browse_host_rpc(bool sort)
        info_ctr.ctr.ctr1 = &ctr1;
 
        status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, frame,
-                                             pipe_hnd->cli->desthost,
+                                             pipe_hnd->desthost,
                                              &info_ctr,
                                              0xffffffff,
                                              &total_entries,
@@ -3658,7 +3663,7 @@ static bool browse_host_rpc(bool sort)
                                              &werr);
 
        if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
-               cli_rpc_pipe_close(pipe_hnd);
+               TALLOC_FREE(pipe_hnd);
                TALLOC_FREE(frame);
                return false;
        }
@@ -3668,7 +3673,7 @@ static bool browse_host_rpc(bool sort)
                browse_fn(info.name, info.type, info.comment, NULL);
        }
 
-       cli_rpc_pipe_close(pipe_hnd);
+       TALLOC_FREE(pipe_hnd);
        TALLOC_FREE(frame);
        return true;
 }
@@ -4342,6 +4347,8 @@ cleanup:
        }
 }
 
+static bool finished;
+
 /****************************************************************************
  Make sure we swallow keepalives during idle time.
 ****************************************************************************/
@@ -4382,12 +4389,14 @@ static void readline_callback(void)
 
                set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK);
 
-               status = receive_smb_raw(cli->fd, cli->inbuf, 0, 0, &len);
+               status = receive_smb_raw(cli->fd, cli->inbuf, cli->bufsize, 0, 0, &len);
 
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0, ("Read from server failed, maybe it closed "
                                  "the connection\n"));
 
+                       finished = true;
+                       smb_readline_done();
                        if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) {
                                set_smb_read_error(&cli->smb_rw_error,
                                                   SMB_READ_EOF);
@@ -4414,9 +4423,17 @@ static void readline_callback(void)
 
        /* Ping the server to keep the connection alive using SMBecho. */
        {
+               NTSTATUS status;
                unsigned char garbage[16];
                memset(garbage, 0xf0, sizeof(garbage));
-               cli_echo(cli, 1, garbage, sizeof(garbage));
+               status = cli_echo(cli, 1, data_blob_const(garbage, sizeof(garbage)));
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(0, ("SMBecho failed. Maybe server has closed "
+                               "the connection\n"));
+                       finished = true;
+                       smb_readline_done();
+               }
        }
 }
 
@@ -4428,7 +4445,7 @@ static int process_stdin(void)
 {
        int rc = 0;
 
-       while (1) {
+       while (!finished) {
                TALLOC_CTX *frame = talloc_stackframe();
                char *tok = NULL;
                char *the_prompt = NULL;
@@ -4589,7 +4606,7 @@ static int do_tar_op(const char *base_directory)
  Handle a message operation.
 ****************************************************************************/
 
-static int do_message_op(void)
+static int do_message_op(struct user_auth_info *auth_info)
 {
        struct sockaddr_storage ss;
        struct nmb_name called, calling;
@@ -4605,7 +4622,7 @@ static int do_message_op(void)
        snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type);
        fstrcat(server_name, name_type_hex);
 
-        zero_addr(&ss);
+        zero_sockaddr(&ss);
        if (have_ip)
                ss = dest_ss;
 
@@ -4630,7 +4647,7 @@ static int do_message_op(void)
                return 1;
        }
 
-       send_message();
+       send_message(get_cmdline_auth_info_username(auth_info));
        cli_cm_shutdown();
 
        return 0;
@@ -4677,6 +4694,7 @@ static int do_message_op(void)
                POPT_TABLEEND
        };
        TALLOC_CTX *frame = talloc_stackframe();
+       struct user_auth_info *auth_info;
 
        if (!client_set_cur_dir("\\")) {
                exit(ENOMEM);
@@ -4706,6 +4724,12 @@ static int do_message_op(void)
 
        load_case_tables();
 
+       auth_info = user_auth_info_init(frame);
+       if (auth_info == NULL) {
+               exit(1);
+       }
+       popt_common_set_auth_info(auth_info);
+
        /* skip argv(0) */
        pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, 0);
        poptSetOtherOptionHelp(pc, "service <password>");
@@ -4733,8 +4757,11 @@ static int do_message_op(void)
                }
 
                /* if the service has already been retrieved then check if we have also a password */
-               if (service_opt && (!get_cmdline_auth_info_got_pass()) && poptPeekArg(pc)) {
-                       set_cmdline_auth_info_password(poptGetArg(pc));
+               if (service_opt
+                   && (!get_cmdline_auth_info_got_pass(auth_info))
+                   && poptPeekArg(pc)) {
+                       set_cmdline_auth_info_password(auth_info,
+                                                      poptGetArg(pc));
                }
 
                switch (opt) {
@@ -4840,8 +4867,11 @@ static int do_message_op(void)
        }
 
        /* if the service has already been retrieved then check if we have also a password */
-       if (service_opt && !get_cmdline_auth_info_got_pass() && poptPeekArg(pc)) {
-               set_cmdline_auth_info_password(poptGetArg(pc));
+       if (service_opt
+           && !get_cmdline_auth_info_got_pass(auth_info)
+           && poptPeekArg(pc)) {
+               set_cmdline_auth_info_password(auth_info,
+                                              poptGetArg(pc));
        }
 
        /* check for the -P option */
@@ -4875,6 +4905,11 @@ static int do_message_op(void)
                        argv[0], get_dyn_CONFIGFILE());
        }
 
+       if (get_cmdline_auth_info_use_machine_account(auth_info) &&
+           !set_cmdline_auth_info_machine_account_creds(auth_info)) {
+               exit(-1);
+       }
+
        load_interfaces();
 
        if (service_opt && service) {
@@ -4906,7 +4941,7 @@ static int do_message_op(void)
                calling_name = talloc_strdup(frame, global_myname() );
        }
 
-       smb_encrypt = get_cmdline_auth_info_smb_encrypt();
+       smb_encrypt = get_cmdline_auth_info_smb_encrypt(auth_info);
        if (!init_names()) {
                fprintf(stderr, "init_names() failed\n");
                exit(1);
@@ -4924,7 +4959,7 @@ static int do_message_op(void)
 
        /* Store the username and password for dfs support */
 
-       cli_cm_set_credentials();
+       cli_cm_set_credentials(auth_info);
 
        DEBUG(3,("Client started (version %s).\n", SAMBA_VERSION_STRING));
 
@@ -4957,7 +4992,7 @@ static int do_message_op(void)
        }
 
        if (message) {
-               return do_message_op();
+               return do_message_op(auth_info);
        }
 
        if (process(base_directory)) {