Skip to content

Commit

Permalink
fix incorrect directory permissions on scp -3 transfers;
Browse files Browse the repository at this point in the history
ok markus@
  • Loading branch information
djmdjm committed Aug 7, 2021
1 parent d785416 commit 8aaf94a
Showing 1 changed file with 30 additions and 12 deletions.
42 changes: 30 additions & 12 deletions usr.bin/ssh/sftp-client.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
*
Expand Down Expand Up @@ -293,6 +293,7 @@ get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
return handle;
}

/* XXX returing &static is error-prone. Refactor to fill *Attrib argument */
static Attrib *
get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
{
Expand Down Expand Up @@ -2358,6 +2359,7 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
SFTP_DIRENT **dir_entries;
char *filename, *new_from_path = NULL, *new_to_path = NULL;
mode_t mode = 0777;
Attrib curdir;

if (depth >= MAX_DIR_DEPTH) {
error("Maximum directory depth exceeded: %d levels", depth);
Expand All @@ -2376,17 +2378,34 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
if (print_flag)
mprintf("Retrieving %s\n", from_path);

dirattrib->flags &= ~SSH2_FILEXFER_ATTR_SIZE;
dirattrib->flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
mode = dirattrib->perm & 01777;
dirattrib->perm = mode | (S_IWUSR|S_IXUSR); /* temp */
} else {
debug("Server did not send permissions for "
curdir = *dirattrib; /* dirattrib will be clobbered */
curdir.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
curdir.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
if ((curdir.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) == 0) {
debug("Origin did not send permissions for "
"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)
return -1;
/* We need to be able to write to the directory while we transfer it */
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) {
error("%s: Failed to get directory contents", from_path);
Expand Down Expand Up @@ -2424,8 +2443,7 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
free(new_to_path);
free(new_from_path);

dirattrib->perm = mode; /* original mode */
do_setstat(to, to_path, dirattrib);
do_setstat(to, to_path, &curdir);

free_sftp_dirents(dir_entries);

Expand Down

0 comments on commit 8aaf94a

Please sign in to comment.