upstream: fix incorrect directory permissions on scp -3
transfers; ok markus@ OpenBSD-Commit-ID: 64b2abaa5635a2be65ee2e77688ad9bcebf576c2
This commit is contained in:
parent
98b59244ca
commit
133b44e500
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: sftp-client.c,v 1.148 2021/08/07 00:09:57 djm Exp $ */
|
/* $OpenBSD: sftp-client.c,v 1.149 2021/08/07 00:10:49 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||||
*
|
*
|
||||||
|
@ -307,6 +307,7 @@ get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX returing &static is error-prone. Refactor to fill *Attrib argument */
|
||||||
static Attrib *
|
static Attrib *
|
||||||
get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
|
get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
|
||||||
{
|
{
|
||||||
|
@ -2377,6 +2378,7 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
|
||||||
SFTP_DIRENT **dir_entries;
|
SFTP_DIRENT **dir_entries;
|
||||||
char *filename, *new_from_path = NULL, *new_to_path = NULL;
|
char *filename, *new_from_path = NULL, *new_to_path = NULL;
|
||||||
mode_t mode = 0777;
|
mode_t mode = 0777;
|
||||||
|
Attrib curdir;
|
||||||
|
|
||||||
if (depth >= MAX_DIR_DEPTH) {
|
if (depth >= MAX_DIR_DEPTH) {
|
||||||
error("Maximum directory depth exceeded: %d levels", depth);
|
error("Maximum directory depth exceeded: %d levels", depth);
|
||||||
|
@ -2395,17 +2397,34 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
|
||||||
if (print_flag)
|
if (print_flag)
|
||||||
mprintf("Retrieving %s\n", from_path);
|
mprintf("Retrieving %s\n", from_path);
|
||||||
|
|
||||||
dirattrib->flags &= ~SSH2_FILEXFER_ATTR_SIZE;
|
curdir = *dirattrib; /* dirattrib will be clobbered */
|
||||||
dirattrib->flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
|
curdir.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
|
||||||
if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
|
curdir.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
|
||||||
mode = dirattrib->perm & 01777;
|
if ((curdir.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) == 0) {
|
||||||
dirattrib->perm = mode | (S_IWUSR|S_IXUSR); /* temp */
|
debug("Origin did not send permissions for "
|
||||||
} else {
|
|
||||||
debug("Server did not send permissions for "
|
|
||||||
"directory \"%s\"", to_path);
|
"directory \"%s\"", to_path);
|
||||||
|
curdir.perm = S_IWUSR|S_IXUSR;
|
||||||
|
curdir.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
|
||||||
}
|
}
|
||||||
if (do_mkdir(to, to_path, dirattrib, print_flag) != 0)
|
/* We need to be able to write to the directory while we transfer it */
|
||||||
return -1;
|
mode = curdir.perm & 01777;
|
||||||
|
curdir.perm = mode | (S_IWUSR|S_IXUSR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sftp lacks a portable status value to match errno EEXIST,
|
||||||
|
* so if we get a failure back then we must check whether
|
||||||
|
* the path already existed and is a directory. Ensure we can
|
||||||
|
* write to the directory we create for the duration of the transfer.
|
||||||
|
*/
|
||||||
|
if (do_mkdir(to, to_path, &curdir, 0) != 0) {
|
||||||
|
if ((dirattrib = do_stat(to, to_path, 0)) == NULL)
|
||||||
|
return -1;
|
||||||
|
if (!S_ISDIR(dirattrib->perm)) {
|
||||||
|
error("\"%s\" exists but is not a directory", to_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curdir.perm = mode;
|
||||||
|
|
||||||
if (do_readdir(from, from_path, &dir_entries) == -1) {
|
if (do_readdir(from, from_path, &dir_entries) == -1) {
|
||||||
error("%s: Failed to get directory contents", from_path);
|
error("%s: Failed to get directory contents", from_path);
|
||||||
|
@ -2443,8 +2462,7 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
|
||||||
free(new_to_path);
|
free(new_to_path);
|
||||||
free(new_from_path);
|
free(new_from_path);
|
||||||
|
|
||||||
dirattrib->perm = mode; /* original mode */
|
do_setstat(to, to_path, &curdir);
|
||||||
do_setstat(to, to_path, dirattrib);
|
|
||||||
|
|
||||||
free_sftp_dirents(dir_entries);
|
free_sftp_dirents(dir_entries);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue