fix chown; don't steal groups or give away files
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Wed, 25 Jan 1989 13:53:52 +0000 (05:53 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Wed, 25 Jan 1989 13:53:52 +0000 (05:53 -0800)
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
usr/src/sys/ufs/ffs/ffs_vnops.c
usr/src/sys/ufs/ffs/ufs_vnops.c
usr/src/sys/ufs/lfs/lfs_vnops.c
usr/src/sys/ufs/ufs/ufs_vnops.c

index a5e4d5d..7485eee 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * 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"
  */
 
 #include "param.h"
@@ -600,8 +600,13 @@ chown()
                int     uid;
                int     gid;
        } *uap = (struct a *)u.u_ap;
                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);
                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;
                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 */
                return (u.u_error);
 #ifdef QUOTA
        if (ip->i_uid == uid)           /* this just speeds things a little */
index ecfd247..7566bc5 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * 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"
  */
 
 #include "param.h"
@@ -600,8 +600,13 @@ chown()
                int     uid;
                int     gid;
        } *uap = (struct a *)u.u_ap;
                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);
                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;
                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 */
                return (u.u_error);
 #ifdef QUOTA
        if (ip->i_uid == uid)           /* this just speeds things a little */
index dcb13eb..016a175 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * 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"
  */
 
 #include "param.h"
@@ -600,8 +600,13 @@ chown()
                int     uid;
                int     gid;
        } *uap = (struct a *)u.u_ap;
                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);
                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;
                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 */
                return (u.u_error);
 #ifdef QUOTA
        if (ip->i_uid == uid)           /* this just speeds things a little */
index 6073578..bc4354f 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * 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"
  */
 
 #include "param.h"
@@ -600,8 +600,13 @@ chown()
                int     uid;
                int     gid;
        } *uap = (struct a *)u.u_ap;
                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);
                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;
                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 */
                return (u.u_error);
 #ifdef QUOTA
        if (ip->i_uid == uid)           /* this just speeds things a little */
index dcb13eb..016a175 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * 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"
  */
 
 #include "param.h"
@@ -600,8 +600,13 @@ chown()
                int     uid;
                int     gid;
        } *uap = (struct a *)u.u_ap;
                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);
                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;
                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 */
                return (u.u_error);
 #ifdef QUOTA
        if (ip->i_uid == uid)           /* this just speeds things a little */