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:
peter 1997-03-31 12:02:53 +00:00
parent 1543ecae88
commit 760db2332e
4 changed files with 41 additions and 147 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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))) {