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

Ben Lindstrom mouring at etoh.eviladmin.org
Wed Nov 6 03:48:04 EST 2002


Don't know...I don't like that idea.   Mainly because the remote side many
not be UNIX and it may not be a sane thing to do.

Plus I'm not sure this is really something that sftp should be doing to
start with.

- Ben

On Tue, 5 Nov 2002, Gary Fernandez wrote:

> 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);
>
> _______________________________________________
> openssh-unix-dev at mindrot.org mailing list
> http://www.mindrot.org/mailman/listinfo/openssh-unix-dev
>




More information about the openssh-unix-dev mailing list