Matthew Sienkiewicz
2020-Aug-21 21:21 UTC
Why does sftp-client create new local files with the remote file permissions when preserve_flag it NOT specified?
Fantastic Friday All,
I was tracking down a problem with SFTP retrieved files having unexpected file
permissions.
The remote file permissions were 0070.
The local file did not exist before the transfer request.
The local account had a umask of 0022.
The local file permissions after the transfer were 0250.
The code below is from the sftp-client.c file : in the do_download function
[that starts around Line 1197 in a recent snapshot].
----------------------------------------------------------------------------------------------------------------------------------------------------
(My comment: This gets the permissions of the remote file and stores them in the
variable "mode")
/* Do not preserve set[ug]id here, as we do not preserve ownership */
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
mode = a->perm & 0777;
else
mode = 0666;
----------------------------------------------------------------------------------------------------------------------------------------------------
(My comment: This opens and creates the local file with the permissions of the
remote file with a user write bit added and masked by the local umask)
local_fd = open(local_path,
O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR)
----------------------------------------------------------------------------------------------------------------------------------------------------
(My comment: After all is transferred, change the local file permissions if
they should be preserved (e.g. get -p) by applying what is stored in the
"mode" variable)
/* Override umask and utimes if asked */
#ifdef HAVE_FCHMOD
if (preserve_flag && fchmod(local_fd, mode) == -1)
#else
if (preserve_flag && chmod(local_path, mode) == -1)
#endif /* HAVE_FCHMOD */
error("Couldn't set mode on \"%s\":
%s", local_path,
strerror(errno));
----------------------------------------------------------------------------------------------------------------------------------------------------
MY QUESTION: Why is the local file create the following code:
local_fd = open(local_path, O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC),
mode | S_IWUSR)
Why is it created with the remote file permissions but the local umask?
Why is it not something like the following (apply the local account umask to
0666)?
local_fd = open(local_path, O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC),
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
What am I missing? Is there a controlling standard?
Thanks,
Matt S
Damien Miller
2020-Aug-23 08:18 UTC
Why does sftp-client create new local files with the remote file permissions when preserve_flag it NOT specified?
On Fri, 21 Aug 2020, Matthew Sienkiewicz wrote:> Fantastic Friday All, > > I was tracking down a problem with SFTP retrieved files having > unexpected file permissions. > > The remote file permissions were 0070. > > The local file did not exist before the transfer request. > The local account had a umask of 0022. > The local file permissions after the transfer were 0250.This is because the sftp protocol has no notion of a user's umask - all permissions are passed explicitly in the protocol, so it has to pick a default. The default we chose was the permissions of the origin file. An alternative might be to implement the notion of a umask in the client, but I think the current behaviour should stay as default for safety and backwards conmpatibility. -d