[PATCH] fix sftp to preserve permissions and uid/gid

Gary Fernandez GaryF at livevault.com
Wed Nov 6 02:48:22 EST 2002


Sftp fails to correctly preserve permissions when fetching a file.  It adds
write permission for the owner (presumably so it can write the file).

Sftp also fails to preserve the uid/gid.  Added code so that if is running
as root, uid and gid are preserved.

patch is based on Openssh 3.4p1.

*** sftp-client.c@@\main\1 Tue Oct  1 17:26:20 2002
--- sftp-client.c Tue Nov  5 10:22:52 2002
***************
*** 666,672 ****
  
  	status = get_status(conn->fd_in, id);
  	if (status != SSH2_FX_OK)
! 		error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
  		    newpath, fx2txt(status));
  
  	return(status);
--- 666,672 ----
  
  	status = get_status(conn->fd_in, id);
  	if (status != SSH2_FX_OK)
! 		error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath,
  		    newpath, fx2txt(status));
  
  	return(status);
***************
*** 746,752 ****
  	int local_fd, status, num_req, max_req, write_error;
  	int read_error, write_errno;
  	u_int64_t offset, size;
! 	u_int handle_len, mode, type, id, buflen;
  	struct request {
  		u_int id;
  		u_int len;
--- 796,802 ----
  	int local_fd, status, num_req, max_req, write_error;
  	int read_error, write_errno;
  	u_int64_t offset, size;
! 	u_int handle_len, mode, type, id, buflen, savemode;
  	struct request {
  		u_int id;
  		u_int len;
***************
*** 763,773 ****
  		return(-1);
  
  	/* XXX: should we preserve set[ug]id? */
! 	if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
  		mode = S_IWRITE | (a->perm & 0777);
! 	else
  		mode = 0666;
! 
  	if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
  	    (a->perm & S_IFDIR)) {
  		error("Cannot download a directory: %s", remote_path);
--- 813,826 ----
  		return(-1);
  
  	/* XXX: should we preserve set[ug]id? */
! 	if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
  		mode = S_IWRITE | (a->perm & 0777);
! 		savemode = (a->perm & 0777);
! 	}
! 	else {
  		mode = 0666;
! 		savemode = 0666;
! 	}
  	if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
  	    (a->perm & S_IFDIR)) {
  		error("Cannot download a directory: %s", remote_path);
***************
*** 931,939 ****
  
  		/* Override umask and utimes if asked */
  #ifdef HAVE_FCHMOD
! 		if (pflag && fchmod(local_fd, mode) == -1)
  #else 
! 		if (pflag && chmod(local_path, mode) == -1)
  #endif /* HAVE_FCHMOD */
  			error("Couldn't set mode on \"%s\": %s", local_path,
  			      strerror(errno));
--- 984,992 ----
  
  		/* Override umask and utimes if asked */
  #ifdef HAVE_FCHMOD
! 		if (pflag && fchmod(local_fd, savemode) == -1)
  #else 
! 		if (pflag && chmod(local_path, savemode) == -1)
  #endif /* HAVE_FCHMOD */
  			error("Couldn't set mode on \"%s\": %s", local_path,
  			      strerror(errno));
***************
*** 945,950 ****
--- 998,1008 ----
  			if (utimes(local_path, tv) == -1)
  				error("Can't set times on \"%s\": %s",
  				      local_path, strerror(errno));
+ 		}
+ 		if (getuid() == 0 || geteuid() == 0) {
+ 			if (chown(local_path, a->uid, a->gid) < 0)
+ 				error("could not set owner & group on
\"%s\": %s", local_path,
+ 					strerror(errno));
  		}
  	}
  	close(local_fd);




More information about the openssh-unix-dev mailing list