From 18b0bce61728e5c0943caa5386425644f81d9aec Mon Sep 17 00:00:00 2001 From: Keith Bostic Date: Wed, 25 Jan 1989 05:53:52 -0800 Subject: [PATCH] fix chown; don't steal groups or give away files SCCS-vsn: sys/kern/vfs_syscalls.c 7.4 SCCS-vsn: sys/ufs/ffs/ffs_vnops.c 7.4 SCCS-vsn: sys/ufs/ffs/ufs_vnops.c 7.4 SCCS-vsn: sys/ufs/lfs/lfs_vnops.c 7.4 SCCS-vsn: sys/ufs/ufs/ufs_vnops.c 7.4 --- usr/src/sys/kern/vfs_syscalls.c | 19 ++++++++++++++----- usr/src/sys/ufs/ffs/ffs_vnops.c | 19 ++++++++++++++----- usr/src/sys/ufs/ffs/ufs_vnops.c | 19 ++++++++++++++----- usr/src/sys/ufs/lfs/lfs_vnops.c | 19 ++++++++++++++----- usr/src/sys/ufs/ufs/ufs_vnops.c | 19 ++++++++++++++----- 5 files changed, 70 insertions(+), 25 deletions(-) diff --git a/usr/src/sys/kern/vfs_syscalls.c b/usr/src/sys/kern/vfs_syscalls.c index a5e4d5dbef..7485eee2c9 100644 --- a/usr/src/sys/kern/vfs_syscalls.c +++ b/usr/src/sys/kern/vfs_syscalls.c @@ -3,7 +3,7 @@ * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * - * @(#)vfs_syscalls.c 7.3 (Berkeley) %G% + * @(#)vfs_syscalls.c 7.4 (Berkeley) %G% */ #include "param.h" @@ -600,8 +600,13 @@ chown() int uid; int gid; } *uap = (struct a *)u.u_ap; + register struct nameidata *ndp = &u.u_nd; - if ((ip = owner(uap->fname, NOFOLLOW)) == NULL) + ndp->ni_nameiop = LOOKUP | NOFOLLOW; + ndp->ni_segflg = UIO_USERSPACE; + ndp->ni_dirp = uap->fname; + ip = namei(ndp); + if (ip == NULL) return; u.u_error = chown1(ip, uap->uid, uap->gid); iput(ip); @@ -647,9 +652,13 @@ chown1(ip, uid, gid) uid = ip->i_uid; if (gid == -1) gid = ip->i_gid; - if (uid != ip->i_uid && !suser()) - return (u.u_error); - if (gid != ip->i_gid && !groupmember((gid_t)gid) && !suser()) + /* + * If we don't own the file, are trying to change the owner + * of the file, or are not a member of the target group, + * the caller must be superuser or the call fails. + */ + if ((u.u_uid != ip->i_uid || uid != ip->i_uid || + !groupmember((gid_t)gid)) && !suser()) return (u.u_error); #ifdef QUOTA if (ip->i_uid == uid) /* this just speeds things a little */ diff --git a/usr/src/sys/ufs/ffs/ffs_vnops.c b/usr/src/sys/ufs/ffs/ffs_vnops.c index ecfd247219..7566bc5a24 100644 --- a/usr/src/sys/ufs/ffs/ffs_vnops.c +++ b/usr/src/sys/ufs/ffs/ffs_vnops.c @@ -3,7 +3,7 @@ * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * - * @(#)ffs_vnops.c 7.3 (Berkeley) %G% + * @(#)ffs_vnops.c 7.4 (Berkeley) %G% */ #include "param.h" @@ -600,8 +600,13 @@ chown() int uid; int gid; } *uap = (struct a *)u.u_ap; + register struct nameidata *ndp = &u.u_nd; - if ((ip = owner(uap->fname, NOFOLLOW)) == NULL) + ndp->ni_nameiop = LOOKUP | NOFOLLOW; + ndp->ni_segflg = UIO_USERSPACE; + ndp->ni_dirp = uap->fname; + ip = namei(ndp); + if (ip == NULL) return; u.u_error = chown1(ip, uap->uid, uap->gid); iput(ip); @@ -647,9 +652,13 @@ chown1(ip, uid, gid) uid = ip->i_uid; if (gid == -1) gid = ip->i_gid; - if (uid != ip->i_uid && !suser()) - return (u.u_error); - if (gid != ip->i_gid && !groupmember((gid_t)gid) && !suser()) + /* + * If we don't own the file, are trying to change the owner + * of the file, or are not a member of the target group, + * the caller must be superuser or the call fails. + */ + if ((u.u_uid != ip->i_uid || uid != ip->i_uid || + !groupmember((gid_t)gid)) && !suser()) return (u.u_error); #ifdef QUOTA if (ip->i_uid == uid) /* this just speeds things a little */ diff --git a/usr/src/sys/ufs/ffs/ufs_vnops.c b/usr/src/sys/ufs/ffs/ufs_vnops.c index dcb13ebfed..016a175485 100644 --- a/usr/src/sys/ufs/ffs/ufs_vnops.c +++ b/usr/src/sys/ufs/ffs/ufs_vnops.c @@ -3,7 +3,7 @@ * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * - * @(#)ufs_vnops.c 7.3 (Berkeley) %G% + * @(#)ufs_vnops.c 7.4 (Berkeley) %G% */ #include "param.h" @@ -600,8 +600,13 @@ chown() int uid; int gid; } *uap = (struct a *)u.u_ap; + register struct nameidata *ndp = &u.u_nd; - if ((ip = owner(uap->fname, NOFOLLOW)) == NULL) + ndp->ni_nameiop = LOOKUP | NOFOLLOW; + ndp->ni_segflg = UIO_USERSPACE; + ndp->ni_dirp = uap->fname; + ip = namei(ndp); + if (ip == NULL) return; u.u_error = chown1(ip, uap->uid, uap->gid); iput(ip); @@ -647,9 +652,13 @@ chown1(ip, uid, gid) uid = ip->i_uid; if (gid == -1) gid = ip->i_gid; - if (uid != ip->i_uid && !suser()) - return (u.u_error); - if (gid != ip->i_gid && !groupmember((gid_t)gid) && !suser()) + /* + * If we don't own the file, are trying to change the owner + * of the file, or are not a member of the target group, + * the caller must be superuser or the call fails. + */ + if ((u.u_uid != ip->i_uid || uid != ip->i_uid || + !groupmember((gid_t)gid)) && !suser()) return (u.u_error); #ifdef QUOTA if (ip->i_uid == uid) /* this just speeds things a little */ diff --git a/usr/src/sys/ufs/lfs/lfs_vnops.c b/usr/src/sys/ufs/lfs/lfs_vnops.c index 60735780d8..bc4354f3ee 100644 --- a/usr/src/sys/ufs/lfs/lfs_vnops.c +++ b/usr/src/sys/ufs/lfs/lfs_vnops.c @@ -3,7 +3,7 @@ * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * - * @(#)lfs_vnops.c 7.3 (Berkeley) %G% + * @(#)lfs_vnops.c 7.4 (Berkeley) %G% */ #include "param.h" @@ -600,8 +600,13 @@ chown() int uid; int gid; } *uap = (struct a *)u.u_ap; + register struct nameidata *ndp = &u.u_nd; - if ((ip = owner(uap->fname, NOFOLLOW)) == NULL) + ndp->ni_nameiop = LOOKUP | NOFOLLOW; + ndp->ni_segflg = UIO_USERSPACE; + ndp->ni_dirp = uap->fname; + ip = namei(ndp); + if (ip == NULL) return; u.u_error = chown1(ip, uap->uid, uap->gid); iput(ip); @@ -647,9 +652,13 @@ chown1(ip, uid, gid) uid = ip->i_uid; if (gid == -1) gid = ip->i_gid; - if (uid != ip->i_uid && !suser()) - return (u.u_error); - if (gid != ip->i_gid && !groupmember((gid_t)gid) && !suser()) + /* + * If we don't own the file, are trying to change the owner + * of the file, or are not a member of the target group, + * the caller must be superuser or the call fails. + */ + if ((u.u_uid != ip->i_uid || uid != ip->i_uid || + !groupmember((gid_t)gid)) && !suser()) return (u.u_error); #ifdef QUOTA if (ip->i_uid == uid) /* this just speeds things a little */ diff --git a/usr/src/sys/ufs/ufs/ufs_vnops.c b/usr/src/sys/ufs/ufs/ufs_vnops.c index dcb13ebfed..016a175485 100644 --- a/usr/src/sys/ufs/ufs/ufs_vnops.c +++ b/usr/src/sys/ufs/ufs/ufs_vnops.c @@ -3,7 +3,7 @@ * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * - * @(#)ufs_vnops.c 7.3 (Berkeley) %G% + * @(#)ufs_vnops.c 7.4 (Berkeley) %G% */ #include "param.h" @@ -600,8 +600,13 @@ chown() int uid; int gid; } *uap = (struct a *)u.u_ap; + register struct nameidata *ndp = &u.u_nd; - if ((ip = owner(uap->fname, NOFOLLOW)) == NULL) + ndp->ni_nameiop = LOOKUP | NOFOLLOW; + ndp->ni_segflg = UIO_USERSPACE; + ndp->ni_dirp = uap->fname; + ip = namei(ndp); + if (ip == NULL) return; u.u_error = chown1(ip, uap->uid, uap->gid); iput(ip); @@ -647,9 +652,13 @@ chown1(ip, uid, gid) uid = ip->i_uid; if (gid == -1) gid = ip->i_gid; - if (uid != ip->i_uid && !suser()) - return (u.u_error); - if (gid != ip->i_gid && !groupmember((gid_t)gid) && !suser()) + /* + * If we don't own the file, are trying to change the owner + * of the file, or are not a member of the target group, + * the caller must be superuser or the call fails. + */ + if ((u.u_uid != ip->i_uid || uid != ip->i_uid || + !groupmember((gid_t)gid)) && !suser()) return (u.u_error); #ifdef QUOTA if (ip->i_uid == uid) /* this just speeds things a little */ -- 2.20.1