diff options
author | peter <peter@FreeBSD.org> | 1997-03-31 12:02:53 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1997-03-31 12:02:53 +0000 |
commit | 760db2332ecbe275e9d104f54ef480fa8adcc1c9 (patch) | |
tree | 75518bc437ecbc8627b474513a579baea6269e49 /sys/kern | |
parent | 1543ecae887bd6435390612196e8618908146b13 (diff) | |
download | FreeBSD-src-760db2332ecbe275e9d104f54ef480fa8adcc1c9.zip FreeBSD-src-760db2332ecbe275e9d104f54ef480fa8adcc1c9.tar.gz |
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.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_extattr.c | 89 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 89 |
2 files changed, 38 insertions, 140 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 2997fe5..ffc796f 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -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); } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 2997fe5..ffc796f 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -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); } |