s3: smbclient: Ensure we call client_clean_name() before all operations on remote...
authorJeremy Allison <jra@samba.org>
Fri, 20 Oct 2017 22:09:38 +0000 (15:09 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 24 Oct 2017 17:35:08 +0000 (19:35 +0200)
This allows names containing .. components to be resolved on the client side
before being sent to the server. Relative names work in SMB1 but not in SMB2.
Fix both client.c and clitar.c

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13093

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/client/client.c
source3/client/clitar.c

index 8cc511983cb385e000ae364d0e7b20a4e4714159..8f449e813118bc23cc7f7fc371e7a815d299c31a 100644 (file)
@@ -430,7 +430,7 @@ static int do_cd(const char *new_dir)
        }
        client_set_cur_dir(new_cd);
 
-       new_cd = clean_name(ctx, new_cd);
+       new_cd = client_clean_name(ctx, new_cd);
        client_set_cur_dir(new_cd);
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
@@ -474,7 +474,7 @@ static int do_cd(const char *new_dir)
                        client_set_cur_dir(saved_dir);
                        goto out;
                }
-               targetpath = clean_name(ctx, targetpath);
+               targetpath = client_clean_name(ctx, targetpath);
                if (!targetpath) {
                        client_set_cur_dir(saved_dir);
                        goto out;
@@ -984,6 +984,11 @@ static int cmd_dir(void)
                return 1;
        }
 
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
+
        if (showacls) {
                /* cwd is only used if showacls is on */
                client_set_cwd(client_get_cur_dir());
@@ -1036,6 +1041,14 @@ static int cmd_du(void)
        } else {
                mask = talloc_strdup(ctx, "*");
        }
+       if (!mask) {
+               return 1;
+       }
+
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
 
        status = do_list(mask, attribute, do_du, recurse, true);
        if (!NT_STATUS_IS_OK(status)) {
@@ -1232,7 +1245,7 @@ static int cmd_get(void)
        if (!rname) {
                return 1;
        }
-       rname = clean_name(ctx, rname);
+       rname = client_clean_name(ctx, rname);
        if (!rname) {
                return 1;
        }
@@ -1298,6 +1311,10 @@ static NTSTATUS do_mget(struct cli_state *cli_state, struct file_info *finfo,
                if (!rname) {
                        return NT_STATUS_NO_MEMORY;
                }
+               rname = client_clean_name(ctx, rname);
+               if (rname == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
                do_get(rname, finfo->name, false);
                TALLOC_FREE(rname);
                return NT_STATUS_OK;
@@ -1317,6 +1334,10 @@ static NTSTATUS do_mget(struct cli_state *cli_state, struct file_info *finfo,
        if (!new_cd) {
                return NT_STATUS_NO_MEMORY;
        }
+       new_cd = client_clean_name(ctx, new_cd);
+       if (new_cd == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
        client_set_cur_dir(new_cd);
 
        string_replace(finfo->name,'\\','/');
@@ -1347,6 +1368,10 @@ static NTSTATUS do_mget(struct cli_state *cli_state, struct file_info *finfo,
                return NT_STATUS_NO_MEMORY;
        }
 
+       mget_mask = client_clean_name(ctx, mget_mask);
+       if (mget_mask == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
        status = do_list(mget_mask,
                         (FILE_ATTRIBUTE_SYSTEM
                          | FILE_ATTRIBUTE_HIDDEN
@@ -1416,7 +1441,7 @@ static int cmd_more(void)
        if (!rname) {
                return 1;
        }
-       rname = clean_name(ctx,rname);
+       rname = client_clean_name(ctx,rname);
        if (!rname) {
                return 1;
        }
@@ -1474,6 +1499,10 @@ static int cmd_mget(void)
                if (!mget_mask) {
                        return 1;
                }
+               mget_mask = client_clean_name(ctx, mget_mask);
+               if (mget_mask == NULL) {
+                       return 1;
+               }
                status = do_list(mget_mask, attribute, do_mget, false, true);
                if (!NT_STATUS_IS_OK(status)) {
                        return 1;
@@ -1492,6 +1521,10 @@ static int cmd_mget(void)
                if (!mget_mask) {
                        return 1;
                }
+               mget_mask = client_clean_name(ctx, mget_mask);
+               if (mget_mask == NULL) {
+                       return 1;
+               }
                status = do_list(mget_mask, attribute, do_mget, false, true);
                if (!NT_STATUS_IS_OK(status)) {
                        return 1;
@@ -1588,6 +1621,10 @@ static int cmd_mkdir(void)
        if (!mask) {
                return 1;
        }
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
 
        if (recurse) {
                char *ddir = NULL;
@@ -1659,6 +1696,10 @@ static int cmd_altname(void)
        if (!name) {
                return 1;
        }
+       name = client_clean_name(ctx, name);
+       if (name == NULL) {
+               return 1;
+       }
        do_altname(name);
        return 0;
 }
@@ -1889,7 +1930,10 @@ static int cmd_allinfo(void)
        if (!name) {
                return 1;
        }
-
+       name = client_clean_name(ctx, name);
+       if (name == NULL) {
+               return 1;
+       }
        do_allinfo(name);
 
        return 0;
@@ -2052,7 +2096,7 @@ static int cmd_put(void)
                return 1;
        }
 
-       rname = clean_name(ctx, rname);
+       rname = client_clean_name(ctx, rname);
        if (!rname) {
                return 1;
        }
@@ -2261,6 +2305,19 @@ static int cmd_mput(void)
                                                break;
                                        }
                                        normalize_name(rname);
+                                       {
+                                               char *tmp_rname =
+                                                       client_clean_name(ctx, rname);
+                                               if (tmp_rname == NULL) {
+                                                       break;
+                                               }
+                                               SAFE_FREE(rname);
+                                               rname = smb_xstrdup(tmp_rname);
+                                               TALLOC_FREE(tmp_rname);
+                                               if (rname == NULL) {
+                                                       break;
+                                               }
+                                       }
                                        if (!NT_STATUS_IS_OK(cli_chkpath(cli, rname)) &&
                                            !do_mkdir(rname)) {
                                                DEBUG (0, ("Unable to make dir, skipping..."));
@@ -2291,6 +2348,18 @@ static int cmd_mput(void)
 
                        normalize_name(rname);
 
+                       {
+                               char *tmp_rname = client_clean_name(ctx, rname);
+                               if (tmp_rname == NULL) {
+                                       break;
+                               }
+                               SAFE_FREE(rname);
+                               rname = smb_xstrdup(tmp_rname);
+                               TALLOC_FREE(tmp_rname);
+                               if (rname == NULL) {
+                                       break;
+                               }
+                       }
                        do_put(rname, lname, false);
                }
                free_file_list(file_list);
@@ -2461,6 +2530,10 @@ static int cmd_del(void)
        if (!mask) {
                return 1;
        }
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
 
        status = do_list(mask,attribute,do_del,false,false);
        if (!NT_STATUS_IS_OK(status)) {
@@ -2577,6 +2650,10 @@ static int cmd_deltree(void)
        if (mask == NULL) {
                return 1;
        }
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
 
        deltree_list_head = NULL;
 
@@ -2678,6 +2755,10 @@ static int cmd_wdel(void)
        if (!mask) {
                return 1;
        }
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                                cli, mask, &targetcli, &targetname);
@@ -2719,6 +2800,11 @@ static int cmd_open(void)
                return 1;
        }
 
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
+
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                        cli, mask, &targetcli, &targetname);
        if (!NT_STATUS_IS_OK(status)) {
@@ -2834,6 +2920,10 @@ static int cmd_posix_open(void)
        if (!mask) {
                return 1;
        }
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
 
        if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                d_printf("posix_open <filename> 0<mode>\n");
@@ -2889,6 +2979,10 @@ static int cmd_posix_mkdir(void)
        if (!mask) {
                return 1;
        }
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
 
        if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                d_printf("posix_mkdir <filename> 0<mode>\n");
@@ -2933,6 +3027,10 @@ static int cmd_posix_unlink(void)
        if (!mask) {
                return 1;
        }
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                                cli, mask, &targetcli, &targetname);
@@ -2972,6 +3070,10 @@ static int cmd_posix_rmdir(void)
        if (!mask) {
                return 1;
        }
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                        cli, mask, &targetcli, &targetname);
@@ -3274,6 +3376,10 @@ static int cmd_rmdir(void)
        if (!mask) {
                return 1;
        }
+       mask = client_clean_name(ctx, mask);
+       if (mask == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                        cli, mask, &targetcli, &targetname);
@@ -3318,6 +3424,10 @@ static int cmd_link(void)
        if (!oldname) {
                return 1;
        }
+       oldname = client_clean_name(ctx, oldname);
+       if (oldname == NULL) {
+               return 1;
+       }
        newname = talloc_asprintf(ctx,
                        "%s%s",
                        client_get_cur_dir(),
@@ -3325,6 +3435,10 @@ static int cmd_link(void)
        if (!newname) {
                return 1;
        }
+       newname = client_clean_name(ctx, newname);
+       if (newname == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                        cli, oldname, &targetcli, &targetname);
@@ -3372,6 +3486,10 @@ static int cmd_readlink(void)
        if (!name) {
                return 1;
        }
+       name = client_clean_name(ctx, name);
+       if (name == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                        cli, name, &targetcli, &targetname);
@@ -3426,6 +3544,10 @@ static int cmd_symlink(void)
                if (!newname) {
                        return 1;
                }
+               newname = client_clean_name(ctx, newname);
+               if (newname == NULL) {
+                       return 1;
+               }
                /* New name must be present in share namespace. */
                status = cli_resolve_path(ctx, "",
                                popt_get_cmdline_auth_info(), cli, newname,
@@ -3477,6 +3599,10 @@ static int cmd_chmod(void)
        if (!src) {
                return 1;
        }
+       src = client_clean_name(ctx, src);
+       if (src == NULL) {
+               return 1;
+       }
 
        mode = (mode_t)strtol(buf, NULL, 8);
 
@@ -3636,6 +3762,10 @@ static int cmd_getfacl(void)
        if (!src) {
                return 1;
        }
+       src = client_clean_name(ctx, src);
+       if (src == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                        cli, src, &targetcli, &targetname);
@@ -3804,6 +3934,10 @@ static int cmd_geteas(void)
        if (!src) {
                return 1;
        }
+       src = client_clean_name(ctx, src);
+       if (src == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                        cli, src, &targetcli, &targetname);
@@ -3861,6 +3995,10 @@ static int cmd_setea(void)
        if (!src) {
                return 1;
        }
+       src = client_clean_name(ctx, src);
+       if (src == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                        cli, src, &targetcli, &targetname);
@@ -3907,6 +4045,10 @@ static int cmd_stat(void)
        if (!src) {
                return 1;
        }
+       src = client_clean_name(ctx, src);
+       if (src == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                        cli, src, &targetcli, &targetname);
@@ -4016,6 +4158,10 @@ static int cmd_chown(void)
        if (!src) {
                return 1;
        }
+       src = client_clean_name(ctx, src);
+       if (src == NULL) {
+               return 1;
+       }
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                        cli, src, &targetcli, &targetname);
        if (!NT_STATUS_IS_OK(status)) {
@@ -4066,6 +4212,10 @@ static int cmd_rename(void)
        if (!src) {
                return 1;
        }
+       src = client_clean_name(ctx, src);
+       if (src == NULL) {
+               return 1;
+       }
 
        dest = talloc_asprintf(ctx,
                        "%s%s",
@@ -4074,6 +4224,10 @@ static int cmd_rename(void)
        if (!dest) {
                return 1;
        }
+       dest = client_clean_name(ctx, dest);
+       if (dest == NULL) {
+               return 1;
+       }
 
        if (next_token_talloc(ctx, &cmd_ptr, &buf, NULL) &&
            strcsequal(buf, "-f")) {
@@ -4159,6 +4313,10 @@ static int cmd_scopy(void)
        if (!src) {
                return 1;
        }
+       src = client_clean_name(ctx, src);
+       if (src == NULL) {
+               return 1;
+       }
 
        dest = talloc_asprintf(ctx,
                        "%s%s",
@@ -4167,6 +4325,10 @@ static int cmd_scopy(void)
        if (!dest) {
                return 1;
        }
+       dest = client_clean_name(ctx, dest);
+       if (dest == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                        cli, src, &targetcli, &targetsrc);
@@ -4289,6 +4451,10 @@ static int cmd_hardlink(void)
        if (!src) {
                return 1;
        }
+       src = client_clean_name(ctx, src);
+       if (src == NULL) {
+               return 1;
+       }
 
        dest = talloc_asprintf(ctx,
                        "%s%s",
@@ -4297,6 +4463,10 @@ static int cmd_hardlink(void)
        if (!dest) {
                return 1;
        }
+       dest = client_clean_name(ctx, dest);
+       if (dest == NULL) {
+               return 1;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                                cli, src, &targetcli, &targetname);
@@ -4376,6 +4546,10 @@ static int cmd_notify(void)
        if (name == NULL) {
                goto fail;
        }
+       name = client_clean_name(talloc_tos(), name);
+       if (name == NULL) {
+               return 1;
+       }
        status = cli_ntcreate(
                cli, name, 0, FILE_READ_DATA, 0,
                FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
@@ -4550,7 +4724,7 @@ static int cmd_reget(void)
        if (!remote_name) {
                return 1;
        }
-       remote_name = clean_name(ctx,remote_name);
+       remote_name = client_clean_name(ctx,remote_name);
        if (!remote_name) {
                return 1;
        }
@@ -4602,7 +4776,7 @@ static int cmd_reput(void)
                return 1;
        }
 
-       remote_name = clean_name(ctx, remote_name);
+       remote_name = client_clean_name(ctx, remote_name);
        if (!remote_name) {
                return 1;
        }
@@ -5038,6 +5212,11 @@ static int cmd_utimes(void)
                err = 1;
                goto out;
        }
+       fname = client_clean_name(ctx, fname);
+       if (fname == NULL) {
+               err = 1;
+               goto out;
+       }
 
        while (next_token_talloc(ctx, &cmd_ptr, &buf, NULL) &&
                time_count < 4) {
@@ -5161,6 +5340,11 @@ int cmd_setmode(void)
                err = 1;
                goto out;
        }
+       fname = client_clean_name(ctx, fname);
+       if (fname == NULL) {
+               err = 1;
+               goto out;
+       }
 
        while (next_token_talloc(ctx, &cmd_ptr, &buf, NULL)) {
                const char *s = buf;
@@ -5671,6 +5855,10 @@ static char **remote_completion(const char *text, int len)
        if (!dirmask) {
                goto cleanup;
        }
+       dirmask = client_clean_name(ctx, dirmask);
+       if (dirmask == NULL) {
+               goto cleanup;
+       }
 
        status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
                                cli, dirmask, &targetcli, &targetpath);
index eff796983150cbc1ac01478081e7e60cc86d3ed4..b8009c92cb682c547cb9531935a4a96d2b104f38 100644 (file)
@@ -699,6 +699,11 @@ static int tar_create(struct tar* t)
                        err = 1;
                        goto out_close;
                }
+               mask = client_clean_name(ctx, mask);
+               if (mask == NULL) {
+                       err = 1;
+                       goto out_close;
+               }
                DBG(5, ("tar_process do_list with mask: %s\n", mask));
                status = do_list(mask, TAR_DO_LIST_ATTR, get_file_callback, false, true);
                if (!NT_STATUS_IS_OK(status)) {
@@ -764,6 +769,11 @@ static int tar_create_from_list(struct tar *t)
                        err = 1;
                        goto out;
                }
+               mask = client_clean_name(ctx, mask);
+               if (mask == NULL) {
+                       err = 1;
+                       goto out;
+               }
 
                DBG(5, ("incl. path='%s', base='%s', mask='%s'\n",
                                        path, base ? base : "NULL", mask));
@@ -775,6 +785,12 @@ static int tar_create_from_list(struct tar *t)
                                err = 1;
                                goto out;
                        }
+                       base = client_clean_name(ctx, base);
+                       if (base == NULL) {
+                               err = 1;
+                               goto out;
+                       }
+
                        DBG(5, ("cd '%s' before do_list\n", base));
                        client_set_cur_dir(base);
                }
@@ -820,6 +836,11 @@ static NTSTATUS get_file_callback(struct cli_state *cli,
                status = NT_STATUS_NO_MEMORY;
                goto out;
        }
+       remote_name = client_clean_name(ctx, remote_name);
+       if (remote_name == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto out;
+       }
 
        if (strequal(finfo->name, "..") || strequal(finfo->name, ".")) {
                goto out;
@@ -853,6 +874,11 @@ static NTSTATUS get_file_callback(struct cli_state *cli,
                        status = NT_STATUS_NO_MEMORY;
                        goto out;
                }
+               mask = client_clean_name(ctx, mask);
+               if (mask == NULL) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto out;
+               }
 
                rc = tar_get_file(&tar_ctx, remote_name, finfo);
                if (rc != 0) {
@@ -1112,6 +1138,11 @@ static int tar_send_file(struct tar *t, struct archive_entry *entry)
                err = 1;
                goto out;
        }
+       full_path = client_clean_name(ctx, full_path);
+       if (full_path == NULL) {
+               err = 1;
+               goto out;
+       }
 
        if (mode != AE_IFREG && mode != AE_IFDIR) {
                DBG(0, ("Skipping non-dir & non-regular file %s\n", full_path));