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);
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 >
dknodel at csc.com.au
2002-Nov-05 23:07 UTC
[PATCH] fix sftp to preserve permissions and uid/gid
> Don't know...I don't like that idea. Mainly because the remote sidemany> 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. > > - BenI can see that it may not be appropriate for sftp to always do this, but a command-line option and built-in sftp toggleable setting for this would be fantastic.> On Tue, 5 Nov 2002, Gary Fernandez wrote:> > Sftp fails to correctly preserve permissions when fetching a file. Itadds> > 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 isrunning> > as root, uid and gid are preserved. > > > patch is based on Openssh 3.4p1. > _______________________________________________ > openssh-unix-dev at mindrot.org mailing list > http://www.mindrot.org/mailman/listinfo/openssh-unix-dev- David Knodel