Why does sftp-client create new local files with the remote file permissions when preserve_flag it NOT specified?

Matthew Sienkiewicz matts at stsci.edu
Sat Aug 22 07:21:47 AEST 2020


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 


More information about the openssh-unix-dev mailing list