Treat symlinks as first class citizens with their own uid/gid rather than
as shadows of their containing directory. This should solve the problem of users not being able to delete their symlinks from /tmp once and for all. Symlinks do not have modes though, they are accessable to everything that can read the directory (as before). They are made to show this fact at lstat time (they appear as mode 0777 always, since that's how the the lookup routines in the kernel treat them). More commits will follow, eg: add a real lchown() syscall and man pages.
This commit is contained in:
parent
1543ecae88
commit
760db2332e
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
|
||||
* $Id: vfs_syscalls.c,v 1.60 1997/03/23 03:36:35 bde Exp $
|
||||
* $Id: vfs_syscalls.c,v 1.61 1997/03/23 20:08:11 guido Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1473,48 +1473,23 @@ olstat(p, uap, retval)
|
||||
} */ *uap;
|
||||
register_t *retval;
|
||||
{
|
||||
struct vnode *vp, *dvp;
|
||||
struct stat sb, sb1;
|
||||
struct vnode *vp;
|
||||
struct stat sb;
|
||||
struct ostat osb;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE,
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
|
||||
SCARG(uap, path), p);
|
||||
if (error = namei(&nd))
|
||||
return (error);
|
||||
/*
|
||||
* For symbolic links, always return the attributes of its
|
||||
* containing directory, except for mode, size, and links.
|
||||
*/
|
||||
vp = nd.ni_vp;
|
||||
dvp = nd.ni_dvp;
|
||||
if (vp->v_type != VLNK) {
|
||||
if (dvp == vp)
|
||||
vrele(dvp);
|
||||
else
|
||||
vput(dvp);
|
||||
error = vn_stat(vp, &sb, p);
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
} else {
|
||||
error = vn_stat(dvp, &sb, p);
|
||||
vput(dvp);
|
||||
if (error) {
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
error = vn_stat(vp, &sb1, p);
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
sb.st_mode &= ~S_IFDIR;
|
||||
sb.st_mode |= S_IFLNK;
|
||||
sb.st_nlink = sb1.st_nlink;
|
||||
sb.st_size = sb1.st_size;
|
||||
sb.st_blocks = sb1.st_blocks;
|
||||
}
|
||||
error = vn_stat(vp, &sb, p);
|
||||
if (vp->v_type == VLNK)
|
||||
sb.st_mode |= S_IFLNK | ACCESSPERMS; /* 0777 */
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
cvtstat(&sb, &osb);
|
||||
error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
|
||||
return (error);
|
||||
@ -1605,47 +1580,21 @@ lstat(p, uap, retval)
|
||||
register_t *retval;
|
||||
{
|
||||
int error;
|
||||
struct vnode *vp, *dvp;
|
||||
struct stat sb, sb1;
|
||||
struct vnode *vp;
|
||||
struct stat sb;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE,
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
|
||||
SCARG(uap, path), p);
|
||||
if (error = namei(&nd))
|
||||
return (error);
|
||||
/*
|
||||
* For symbolic links, always return the attributes of its containing
|
||||
* directory, except for mode, size, inode number, and links.
|
||||
*/
|
||||
vp = nd.ni_vp;
|
||||
dvp = nd.ni_dvp;
|
||||
if (vp->v_type != VLNK) {
|
||||
if (dvp == vp)
|
||||
vrele(dvp);
|
||||
else
|
||||
vput(dvp);
|
||||
error = vn_stat(vp, &sb, p);
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
} else {
|
||||
error = vn_stat(dvp, &sb, p);
|
||||
vput(dvp);
|
||||
if (error) {
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
error = vn_stat(vp, &sb1, p);
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
sb.st_mode &= ~S_IFDIR;
|
||||
sb.st_mode |= S_IFLNK;
|
||||
sb.st_nlink = sb1.st_nlink;
|
||||
sb.st_size = sb1.st_size;
|
||||
sb.st_blocks = sb1.st_blocks;
|
||||
sb.st_ino = sb1.st_ino;
|
||||
}
|
||||
error = vn_stat(vp, &sb, p);
|
||||
if (vp->v_type == VLNK)
|
||||
sb.st_mode |= S_IFLNK | ACCESSPERMS; /* 0777 */
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
|
||||
return (error);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
|
||||
* $Id: vfs_syscalls.c,v 1.60 1997/03/23 03:36:35 bde Exp $
|
||||
* $Id: vfs_syscalls.c,v 1.61 1997/03/23 20:08:11 guido Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1473,48 +1473,23 @@ olstat(p, uap, retval)
|
||||
} */ *uap;
|
||||
register_t *retval;
|
||||
{
|
||||
struct vnode *vp, *dvp;
|
||||
struct stat sb, sb1;
|
||||
struct vnode *vp;
|
||||
struct stat sb;
|
||||
struct ostat osb;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE,
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
|
||||
SCARG(uap, path), p);
|
||||
if (error = namei(&nd))
|
||||
return (error);
|
||||
/*
|
||||
* For symbolic links, always return the attributes of its
|
||||
* containing directory, except for mode, size, and links.
|
||||
*/
|
||||
vp = nd.ni_vp;
|
||||
dvp = nd.ni_dvp;
|
||||
if (vp->v_type != VLNK) {
|
||||
if (dvp == vp)
|
||||
vrele(dvp);
|
||||
else
|
||||
vput(dvp);
|
||||
error = vn_stat(vp, &sb, p);
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
} else {
|
||||
error = vn_stat(dvp, &sb, p);
|
||||
vput(dvp);
|
||||
if (error) {
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
error = vn_stat(vp, &sb1, p);
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
sb.st_mode &= ~S_IFDIR;
|
||||
sb.st_mode |= S_IFLNK;
|
||||
sb.st_nlink = sb1.st_nlink;
|
||||
sb.st_size = sb1.st_size;
|
||||
sb.st_blocks = sb1.st_blocks;
|
||||
}
|
||||
error = vn_stat(vp, &sb, p);
|
||||
if (vp->v_type == VLNK)
|
||||
sb.st_mode |= S_IFLNK | ACCESSPERMS; /* 0777 */
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
cvtstat(&sb, &osb);
|
||||
error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
|
||||
return (error);
|
||||
@ -1605,47 +1580,21 @@ lstat(p, uap, retval)
|
||||
register_t *retval;
|
||||
{
|
||||
int error;
|
||||
struct vnode *vp, *dvp;
|
||||
struct stat sb, sb1;
|
||||
struct vnode *vp;
|
||||
struct stat sb;
|
||||
struct nameidata nd;
|
||||
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE,
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
|
||||
SCARG(uap, path), p);
|
||||
if (error = namei(&nd))
|
||||
return (error);
|
||||
/*
|
||||
* For symbolic links, always return the attributes of its containing
|
||||
* directory, except for mode, size, inode number, and links.
|
||||
*/
|
||||
vp = nd.ni_vp;
|
||||
dvp = nd.ni_dvp;
|
||||
if (vp->v_type != VLNK) {
|
||||
if (dvp == vp)
|
||||
vrele(dvp);
|
||||
else
|
||||
vput(dvp);
|
||||
error = vn_stat(vp, &sb, p);
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
} else {
|
||||
error = vn_stat(dvp, &sb, p);
|
||||
vput(dvp);
|
||||
if (error) {
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
error = vn_stat(vp, &sb1, p);
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
sb.st_mode &= ~S_IFDIR;
|
||||
sb.st_mode |= S_IFLNK;
|
||||
sb.st_nlink = sb1.st_nlink;
|
||||
sb.st_size = sb1.st_size;
|
||||
sb.st_blocks = sb1.st_blocks;
|
||||
sb.st_ino = sb1.st_ino;
|
||||
}
|
||||
error = vn_stat(vp, &sb, p);
|
||||
if (vp->v_type == VLNK)
|
||||
sb.st_mode |= S_IFLNK | ACCESSPERMS; /* 0777 */
|
||||
vput(vp);
|
||||
if (error)
|
||||
return (error);
|
||||
error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
|
||||
return (error);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ufs_lookup.c 8.15 (Berkeley) 6/16/95
|
||||
* $Id: ufs_lookup.c,v 1.12 1997/02/22 09:47:49 peter Exp $
|
||||
* $Id: ufs_lookup.c,v 1.13 1997/03/09 06:10:33 mpp Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -504,7 +504,6 @@ ufs_lookup(ap)
|
||||
if ((dp->i_mode & ISVTX) &&
|
||||
cred->cr_uid != 0 &&
|
||||
cred->cr_uid != dp->i_uid &&
|
||||
tdp->v_type != VLNK &&
|
||||
VTOI(tdp)->i_uid != cred->cr_uid) {
|
||||
vput(tdp);
|
||||
return (EPERM);
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
|
||||
* $Id: ufs_vnops.c,v 1.47 1997/03/09 06:10:36 mpp Exp $
|
||||
* $Id: ufs_vnops.c,v 1.48 1997/03/22 06:53:45 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_quota.h"
|
||||
@ -2128,10 +2128,7 @@ ufs_makeinode(mode, dvp, vpp, cnp)
|
||||
}
|
||||
ip = VTOI(tvp);
|
||||
ip->i_gid = pdir->i_gid;
|
||||
if ((mode & IFMT) == IFLNK)
|
||||
ip->i_uid = pdir->i_uid;
|
||||
else
|
||||
ip->i_uid = cnp->cn_cred->cr_uid;
|
||||
ip->i_uid = cnp->cn_cred->cr_uid;
|
||||
#ifdef QUOTA
|
||||
if ((error = getinoquota(ip)) ||
|
||||
(error = chkiq(ip, 1, cnp->cn_cred, 0))) {
|
||||
|
Loading…
Reference in New Issue
Block a user