Reviewed by: hackers@freebsd.org in general
Obtained from: Whistle Communications tree Add an option to the way UFS works dependent on the SUID bit of directories This changes makes things a whole lot simpler on systems running as fileservers for PCs and MACS. to enable the new code you must 1/ enable option SUIDDIR on the kernel. 2/ mount the filesystem with option suiddir. hopefully this makes it difficult enough for people to do this accidentally. see the new chmod(2) man page for detailed info.
This commit is contained in:
parent
a272e47d50
commit
52bf64c787
@ -33,7 +33,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)chmod.1 8.4 (Berkeley) 3/31/94
|
||||
.\" $Id$
|
||||
.\" $Id: chmod.1,v 1.7 1997/02/22 14:01:29 peter Exp $
|
||||
.\"
|
||||
.Dd March 31, 1994
|
||||
.Dt CHMOD 1
|
||||
@ -110,10 +110,14 @@ the following values:
|
||||
.Bl -tag -width 6n -compact -offset indent
|
||||
.It Li 4000
|
||||
set-user-ID-on-execution
|
||||
( see
|
||||
.Xr chmod 2
|
||||
for directories )
|
||||
.It Li 2000
|
||||
set-group-ID-on-execution
|
||||
.It Li 1000
|
||||
sticky bit, see chmod(2)
|
||||
sticky bit, see
|
||||
.Xr chmod 2
|
||||
.It Li 0400
|
||||
read by owner
|
||||
.It Li 0200
|
||||
|
@ -30,7 +30,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)chmod.2 8.1 (Berkeley) 6/4/93
|
||||
.\" $Id: chmod.2,v 1.9 1997/03/21 20:57:18 mpp Exp $
|
||||
.\" $Id: chmod.2,v 1.10 1997/08/17 00:19:28 steve Exp $
|
||||
.\"
|
||||
.Dd June 4, 1993
|
||||
.Dt CHMOD 2
|
||||
@ -112,6 +112,25 @@ permissions.
|
||||
For more details of the properties of the sticky bit, see
|
||||
.Xr sticky 8 .
|
||||
.Pp
|
||||
If mode ISUID (set UID) is set on a directory,
|
||||
and the MNT_SUIDDIR option was used in the mount of the filesystem,
|
||||
then the owner of any new files and sub-directories
|
||||
created within this directory are set
|
||||
to be the same as the owner of that directory.
|
||||
If this function is enabled, new directories will inherit
|
||||
the bit from their parents. Execute bits are removed from
|
||||
the file, and it will not be given to root. This behaviour does not change the
|
||||
requirements for the user to be allowed to write the file, but only the eventual
|
||||
owner after it has been created. Group inheritance is not effected.
|
||||
.Pp
|
||||
This feature is designed for use on fileservers serving PC users via
|
||||
ftp, SAMBA, or netatalk. It provides security holes for shell users and as
|
||||
such should not be used on shell machines, especially on home directories.
|
||||
This option requires the SUIDDIR
|
||||
option in the kernel to work. Only UFS filesystems support this option.
|
||||
For more details of the suiddir mount option, see
|
||||
.Xr mount 8 .
|
||||
.Pp
|
||||
Writing or changing the owner of a file
|
||||
turns off the set-user-id and set-group-id bits
|
||||
unless the user is the super-user.
|
||||
|
@ -89,6 +89,8 @@ Do not honor setuid or setgid bits on files when executing them.
|
||||
Disable update of file access times.
|
||||
.It Dv MNT_NODEV
|
||||
Do not interpret special files on the filesystem.
|
||||
.It Dv MNT_SUIDDIR
|
||||
Directories with the SUID bit set chown new files to their own owner.
|
||||
.It Dv MNT_SYNCHRONOUS
|
||||
All I/O to the filesystem should be done synchronously.
|
||||
.It Dv MNT_ASYNC
|
||||
@ -153,6 +155,16 @@ even if files are still active.
|
||||
Active special devices continue to work,
|
||||
but any further accesses to any other active files result in errors
|
||||
even if the filesystem is later remounted.
|
||||
.Pp
|
||||
The
|
||||
.Dv MNT_SUIDDIR
|
||||
option requires the SUIDDIR option to have been compiled into the kernel
|
||||
to have any effect.
|
||||
See the
|
||||
.Xr mount 8
|
||||
and
|
||||
.Xr chmod 2
|
||||
pages for more information.
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn mount
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)mntopts.h 8.7 (Berkeley) 3/29/95
|
||||
* $Id: mntopts.h,v 1.10 1997/08/25 21:02:21 bde Exp $
|
||||
* $Id: mntopts.h,v 1.11 1997/09/27 13:44:08 kato Exp $
|
||||
*/
|
||||
|
||||
struct mntopt {
|
||||
@ -54,6 +54,7 @@ struct mntopt {
|
||||
#define MOPT_GROUPQUOTA { "groupquota", 0, 0, 0 }
|
||||
#define MOPT_NOCLUSTERR { "clusterr", 1, MNT_NOCLUSTERR, 0 }
|
||||
#define MOPT_NOCLUSTERW { "clusterw", 1, MNT_NOCLUSTERW, 0 }
|
||||
#define MOPT_SUIDDIR { "suiddir", 0, MNT_SUIDDIR, 0 }
|
||||
|
||||
/* Control flags. */
|
||||
#define MOPT_FORCE { "force", 0, MNT_FORCE, 0 }
|
||||
@ -77,6 +78,7 @@ struct mntopt {
|
||||
MOPT_NOATIME, \
|
||||
MOPT_NODEV, \
|
||||
MOPT_NOEXEC, \
|
||||
MOPT_SUIDDIR, /* must be before MOPT_NOSUID */ \
|
||||
MOPT_NOSUID, \
|
||||
MOPT_RDONLY, \
|
||||
MOPT_UNION, \
|
||||
|
@ -30,7 +30,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)mount.8 8.8 (Berkeley) 6/16/94
|
||||
.\" $Id: mount.8,v 1.18 1997/08/24 21:02:48 steve Exp $
|
||||
.\" $Id: mount.8,v 1.19 1997/09/27 13:44:12 kato Exp $
|
||||
.\"
|
||||
.Dd June 16, 1994
|
||||
.Dt MOUNT 8
|
||||
@ -154,6 +154,22 @@ mount the file system read-only (even the super-user may not write it).
|
||||
All
|
||||
.Tn I/O
|
||||
to the file system should be done synchronously.
|
||||
.It suiddir
|
||||
A directory on the mounted filesystem will respond to the SUID bit
|
||||
being set, by setting the owner of any new files to be the same
|
||||
as the owner of the directory.
|
||||
New directories will inherit the bit from their parents.
|
||||
Execute bits are removed from
|
||||
the file, and it will not be given to root.
|
||||
.Pp
|
||||
This feature is designed for use on fileservers serving PC users via
|
||||
ftp, SAMBA, or netatalk. It provides security holes for shell users and as
|
||||
such should not be used on shell machines, especially on home directories.
|
||||
This option requires the SUIDDIR
|
||||
option in the kernel to work. Only UFS filesystems support this option.
|
||||
See
|
||||
.Xr chmod 2
|
||||
for more information.
|
||||
.It update
|
||||
The same as
|
||||
.Fl u ;
|
||||
|
@ -42,7 +42,7 @@ static const char copyright[] =
|
||||
static char sccsid[] = "@(#)mount.c 8.25 (Berkeley) 5/8/95";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$Id: mount.c,v 1.19 1997/08/24 21:02:49 steve Exp $";
|
||||
"$Id: mount.c,v 1.20 1997/09/27 13:44:17 kato Exp $";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -97,6 +97,7 @@ static struct opt {
|
||||
{ MNT_UNION, "union" },
|
||||
{ MNT_NOCLUSTERR, "noclusterr" },
|
||||
{ MNT_NOCLUSTERW, "noclusterw" },
|
||||
{ MNT_SUIDDIR, "suiddir" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)mntopts.h 8.7 (Berkeley) 3/29/95
|
||||
* $Id: mntopts.h,v 1.10 1997/08/25 21:02:21 bde Exp $
|
||||
* $Id: mntopts.h,v 1.11 1997/09/27 13:44:08 kato Exp $
|
||||
*/
|
||||
|
||||
struct mntopt {
|
||||
@ -54,6 +54,7 @@ struct mntopt {
|
||||
#define MOPT_GROUPQUOTA { "groupquota", 0, 0, 0 }
|
||||
#define MOPT_NOCLUSTERR { "clusterr", 1, MNT_NOCLUSTERR, 0 }
|
||||
#define MOPT_NOCLUSTERW { "clusterw", 1, MNT_NOCLUSTERW, 0 }
|
||||
#define MOPT_SUIDDIR { "suiddir", 0, MNT_SUIDDIR, 0 }
|
||||
|
||||
/* Control flags. */
|
||||
#define MOPT_FORCE { "force", 0, MNT_FORCE, 0 }
|
||||
@ -77,6 +78,7 @@ struct mntopt {
|
||||
MOPT_NOATIME, \
|
||||
MOPT_NODEV, \
|
||||
MOPT_NOEXEC, \
|
||||
MOPT_SUIDDIR, /* must be before MOPT_NOSUID */ \
|
||||
MOPT_NOSUID, \
|
||||
MOPT_RDONLY, \
|
||||
MOPT_UNION, \
|
||||
|
@ -30,7 +30,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)mount.8 8.8 (Berkeley) 6/16/94
|
||||
.\" $Id: mount.8,v 1.18 1997/08/24 21:02:48 steve Exp $
|
||||
.\" $Id: mount.8,v 1.19 1997/09/27 13:44:12 kato Exp $
|
||||
.\"
|
||||
.Dd June 16, 1994
|
||||
.Dt MOUNT 8
|
||||
@ -154,6 +154,22 @@ mount the file system read-only (even the super-user may not write it).
|
||||
All
|
||||
.Tn I/O
|
||||
to the file system should be done synchronously.
|
||||
.It suiddir
|
||||
A directory on the mounted filesystem will respond to the SUID bit
|
||||
being set, by setting the owner of any new files to be the same
|
||||
as the owner of the directory.
|
||||
New directories will inherit the bit from their parents.
|
||||
Execute bits are removed from
|
||||
the file, and it will not be given to root.
|
||||
.Pp
|
||||
This feature is designed for use on fileservers serving PC users via
|
||||
ftp, SAMBA, or netatalk. It provides security holes for shell users and as
|
||||
such should not be used on shell machines, especially on home directories.
|
||||
This option requires the SUIDDIR
|
||||
option in the kernel to work. Only UFS filesystems support this option.
|
||||
See
|
||||
.Xr chmod 2
|
||||
for more information.
|
||||
.It update
|
||||
The same as
|
||||
.Fl u ;
|
||||
|
@ -42,7 +42,7 @@ static const char copyright[] =
|
||||
static char sccsid[] = "@(#)mount.c 8.25 (Berkeley) 5/8/95";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$Id: mount.c,v 1.19 1997/08/24 21:02:49 steve Exp $";
|
||||
"$Id: mount.c,v 1.20 1997/09/27 13:44:17 kato Exp $";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -97,6 +97,7 @@ static struct opt {
|
||||
{ MNT_UNION, "union" },
|
||||
{ MNT_NOCLUSTERR, "noclusterr" },
|
||||
{ MNT_NOCLUSTERW, "noclusterw" },
|
||||
{ MNT_SUIDDIR, "suiddir" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: options,v 1.36 1997/10/18 01:15:32 peter Exp $
|
||||
# $Id: options,v 1.37 1997/11/05 20:17:06 joerg Exp $
|
||||
|
||||
# Format:
|
||||
# Option name filename
|
||||
@ -9,6 +9,7 @@ DDB
|
||||
DDB_UNATTENDED opt_ddb.h
|
||||
GDB_REMOTE_CHAT opt_ddb.h
|
||||
DEVFS_ROOT opt_devfs.h
|
||||
SUIDDIR
|
||||
KTRACE
|
||||
QUOTA
|
||||
SYSVMSG opt_sysvipc.h
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
|
||||
* $Id: vfs_syscalls.c,v 1.80 1997/11/06 19:29:30 phk Exp $
|
||||
* $Id: vfs_syscalls.c,v 1.81 1997/11/12 05:42:17 julian Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -261,10 +261,10 @@ mount(p, uap)
|
||||
mp->mnt_kern_flag |= MNTK_WANTRDWR;
|
||||
mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
|
||||
MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME |
|
||||
MNT_NOCLUSTERR | MNT_NOCLUSTERW);
|
||||
MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
|
||||
mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC |
|
||||
MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE |
|
||||
MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW);
|
||||
MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
|
||||
/*
|
||||
* Mount the filesystem.
|
||||
*/
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
|
||||
* $Id: vfs_syscalls.c,v 1.80 1997/11/06 19:29:30 phk Exp $
|
||||
* $Id: vfs_syscalls.c,v 1.81 1997/11/12 05:42:17 julian Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -261,10 +261,10 @@ mount(p, uap)
|
||||
mp->mnt_kern_flag |= MNTK_WANTRDWR;
|
||||
mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
|
||||
MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME |
|
||||
MNT_NOCLUSTERR | MNT_NOCLUSTERW);
|
||||
MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
|
||||
mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC |
|
||||
MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE |
|
||||
MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW);
|
||||
MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
|
||||
/*
|
||||
* Mount the filesystem.
|
||||
*/
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)mount.h 8.21 (Berkeley) 5/20/95
|
||||
* $Id: mount.h,v 1.48 1997/10/12 20:26:02 phk Exp $
|
||||
* $Id: mount.h,v 1.49 1997/11/12 05:42:23 julian Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_MOUNT_H_
|
||||
@ -146,7 +146,7 @@ struct mount {
|
||||
struct vnode *mnt_vnodecovered; /* vnode we mounted on */
|
||||
struct vnodelst mnt_vnodelist; /* list of vnodes this mount */
|
||||
struct lock mnt_lock; /* mount structure lock */
|
||||
int mnt_flag; /* exported flags */
|
||||
int mnt_flag; /* flags shared with user */
|
||||
int mnt_kern_flag; /* kernel only flags */
|
||||
int mnt_maxsymlinklen; /* max size of short symlink */
|
||||
struct statfs mnt_stat; /* cache of filesystem stats */
|
||||
@ -155,9 +155,7 @@ struct mount {
|
||||
};
|
||||
|
||||
/*
|
||||
* Mount flags.
|
||||
*
|
||||
* Unmount uses MNT_FORCE flag.
|
||||
* User specifiable flags.
|
||||
*/
|
||||
#define MNT_RDONLY 0x00000001 /* read only filesystem */
|
||||
#define MNT_SYNCHRONOUS 0x00000002 /* file system written synchronously */
|
||||
@ -166,12 +164,13 @@ struct mount {
|
||||
#define MNT_NODEV 0x00000010 /* don't interpret special files */
|
||||
#define MNT_UNION 0x00000020 /* union with underlying filesystem */
|
||||
#define MNT_ASYNC 0x00000040 /* file system written asynchronously */
|
||||
#define MNT_SUIDDIR 0x00100000 /* Disable cluster read */
|
||||
#define MNT_NOATIME 0x10000000 /* Disable update of file access time */
|
||||
#define MNT_NOCLUSTERR 0x40000000 /* Disable cluster read */
|
||||
#define MNT_NOCLUSTERW 0x80000000 /* Disable cluster read */
|
||||
|
||||
/*
|
||||
* exported mount flags.
|
||||
* NFS export related mount flags.
|
||||
*/
|
||||
#define MNT_EXRDONLY 0x00000080 /* exported read only */
|
||||
#define MNT_EXPORTED 0x00000100 /* file system is exported */
|
||||
@ -181,7 +180,9 @@ struct mount {
|
||||
#define MNT_EXPUBLIC 0x20000000 /* public export (WebNFS) */
|
||||
|
||||
/*
|
||||
* Flags set by internal operations.
|
||||
* Flags set by internal operations,
|
||||
* but visible to the user.
|
||||
* XXX some of these are not quite right.. (I've never seen the root flag set)
|
||||
*/
|
||||
#define MNT_LOCAL 0x00001000 /* filesystem is stored locally */
|
||||
#define MNT_QUOTA 0x00002000 /* quotas are enabled on filesystem */
|
||||
@ -190,25 +191,31 @@ struct mount {
|
||||
|
||||
/*
|
||||
* Mask of flags that are visible to statfs()
|
||||
* XXX I think that this could now become (~(MNT_CMDFLAGS))
|
||||
* but the 'mount' program may need changing to handle this.
|
||||
* XXX MNT_EXPUBLIC is presently left out. I don't know why.
|
||||
*/
|
||||
#define MNT_VISFLAGMASK (MNT_RDONLY|MNT_SYNCHRONOUS|MNT_NOEXEC|MNT_NOSUID| \
|
||||
MNT_NODEV|MNT_UNION|MNT_ASYNC|MNT_EXRDONLY| \
|
||||
MNT_EXPORTED|MNT_DEFEXPORTED|MNT_EXPORTANON| \
|
||||
MNT_EXKERB|MNT_LOCAL|MNT_USER|MNT_QUOTA|MNT_ROOTFS| \
|
||||
MNT_NOATIME|MNT_NOCLUSTERR|MNT_NOCLUSTERW \
|
||||
/* | MNT_EXPUBLIC */)
|
||||
|
||||
#define MNT_VISFLAGMASK (MNT_RDONLY | MNT_SYNCHRONOUS | MNT_NOEXEC | \
|
||||
MNT_NOSUID | MNT_NODEV | MNT_UNION | \
|
||||
MNT_ASYNC | MNT_EXRDONLY | MNT_EXPORTED | \
|
||||
MNT_DEFEXPORTED | MNT_EXPORTANON| MNT_EXKERB | \
|
||||
MNT_LOCAL | MNT_USER | MNT_QUOTA | \
|
||||
MNT_ROOTFS | MNT_NOATIME | MNT_NOCLUSTERR| \
|
||||
MNT_NOCLUSTERW | MNT_SUIDDIR/* | MNT_EXPUBLIC */)
|
||||
/*
|
||||
* External filesystem control flags.
|
||||
* External filesystem command modifier flags.
|
||||
* Unmount can use the MNT_FORCE flag.
|
||||
* XXX These are not STATES and really should be somewhere else.
|
||||
*/
|
||||
#define MNT_UPDATE 0x00010000 /* not a real mount, just an update */
|
||||
#define MNT_DELEXPORT 0x00020000 /* delete export host lists */
|
||||
#define MNT_RELOAD 0x00040000 /* reload filesystem data */
|
||||
#define MNT_FORCE 0x00080000 /* force unmount or readonly change */
|
||||
#define MNT_CMDFLAGS (MNT_UPDATE|MNT_DELEXPORT|MNT_RELOAD|MNT_FORCE)
|
||||
/*
|
||||
* Internal filesystem control flags.
|
||||
* Internal filesystem control flags stored in mnt_kern_flag.
|
||||
*
|
||||
* MNT_UNMOUNT locks the mount entry so that name lookup cannot proceed
|
||||
* MNTK_UNMOUNT locks the mount entry so that name lookup cannot proceed
|
||||
* past the mount point. This keeps the subtree stable during mounts
|
||||
* and unmounts.
|
||||
*/
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
|
||||
* $Id: ufs_vnops.c,v 1.64 1997/10/26 20:55:39 phk Exp $
|
||||
* $Id: ufs_vnops.c,v 1.65 1997/10/27 13:33:47 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_quota.h"
|
||||
@ -1329,8 +1329,57 @@ ufs_mkdir(ap)
|
||||
if (error)
|
||||
goto out;
|
||||
ip = VTOI(tvp);
|
||||
ip->i_uid = cnp->cn_cred->cr_uid;
|
||||
ip->i_gid = dp->i_gid;
|
||||
#ifdef SUIDDIR
|
||||
{
|
||||
#ifdef QUOTA
|
||||
struct ucred ucred, *ucp;
|
||||
ucp = cnp->cn_cred
|
||||
#endif I
|
||||
/*
|
||||
* if we are hacking owners here, (only do this where told to)
|
||||
* and we are not giving it TOO root, (would subvert quotas)
|
||||
* then go ahead and give it to the other user.
|
||||
* The new directory also inherits the SUID bit.
|
||||
* If user's UID an ddir UID are the same,
|
||||
* 'give it away' so that the SUID is still forced on.
|
||||
*/
|
||||
if ( (dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
|
||||
(dp->i_mode & ISUID) && dp->i_uid) {
|
||||
dmode |= ISUID;
|
||||
ip->i_uid = dp->i_uid;
|
||||
#ifdef QUOTA
|
||||
if (pdir->i_uid != cnp->cn_cred->cr_uid) {
|
||||
/*
|
||||
* make sure the correct user gets charged
|
||||
* for the space.
|
||||
* Make a dummy credential for the victim.
|
||||
* XXX This seems to never be accessed out of
|
||||
* our context so a stack variable is ok.
|
||||
*/
|
||||
ucred.cr_ref = 1
|
||||
ucred.cr_uid = ip->i_uid;
|
||||
ucred.cr_ngroups = 1
|
||||
ucred.cr_groups[0] = dp->i_gid;
|
||||
ucp = *ucred;
|
||||
}
|
||||
#endif I
|
||||
} else {
|
||||
ip->i_uid = cnp->cn_cred->cr_uid;
|
||||
}
|
||||
#ifdef QUOTA
|
||||
if ((error = getinoquota(ip)) ||
|
||||
(error = chkiq(ip, 1, ucp, 0))) {
|
||||
free(cnp->cn_pnbuf, M_NAMEI);
|
||||
VOP_VFREE(tvp, ip->i_number, dmode);
|
||||
vput(tvp);
|
||||
vput(dvp);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
ip->i_uid = cnp->cn_cred->cr_uid;
|
||||
#ifdef QUOTA
|
||||
if ((error = getinoquota(ip)) ||
|
||||
(error = chkiq(ip, 1, cnp->cn_cred, 0))) {
|
||||
@ -1340,6 +1389,7 @@ ufs_mkdir(ap)
|
||||
vput(dvp);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
|
||||
ip->i_mode = dmode;
|
||||
@ -2007,6 +2057,55 @@ ufs_makeinode(mode, dvp, vpp, cnp)
|
||||
}
|
||||
ip = VTOI(tvp);
|
||||
ip->i_gid = pdir->i_gid;
|
||||
#ifdef SUIDDIR
|
||||
{
|
||||
#ifdef QUOTA
|
||||
struct ucred ucred, *ucp;
|
||||
ucp = cnp->cn_cred
|
||||
#endif I
|
||||
/*
|
||||
* if we are
|
||||
* not the owner of the directory,
|
||||
* and we are hacking owners here, (only do this where told to)
|
||||
* and we are not giving it TOO root, (would subvert quotas)
|
||||
* then go ahead and give it to the other user.
|
||||
* Note that this drops off the execute bits for security.
|
||||
*/
|
||||
if ( (dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
|
||||
(pdir->i_mode & ISUID) &&
|
||||
(pdir->i_uid != cnp->cn_cred->cr_uid) && pdir->i_uid) {
|
||||
ip->i_uid = pdir->i_uid;
|
||||
mode &= ~07111;
|
||||
#ifdef QUOTA
|
||||
/*
|
||||
* make sure the correct user gets charged
|
||||
* for the space.
|
||||
* Quickly knock up a dummy credential for the victim.
|
||||
* XXX This seems to never be accessed out of our
|
||||
* context so a stack variable is ok.
|
||||
*/
|
||||
ucred.cr_ref = 1
|
||||
ucred.cr_uid = ip->i_uid;
|
||||
ucred.cr_ngroups = 1
|
||||
ucred.cr_groups[0] = pdir->i_gid;
|
||||
ucp = *ucred;
|
||||
#endif I
|
||||
} else {
|
||||
ip->i_uid = cnp->cn_cred->cr_uid;
|
||||
}
|
||||
|
||||
#ifdef QUOTA
|
||||
if ((error = getinoquota(ip)) ||
|
||||
(error = chkiq(ip, 1, ucp, 0))) {
|
||||
free(cnp->cn_pnbuf, M_NAMEI);
|
||||
VOP_VFREE(tvp, ip->i_number, mode);
|
||||
vput(tvp);
|
||||
vput(dvp);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
ip->i_uid = cnp->cn_cred->cr_uid;
|
||||
#ifdef QUOTA
|
||||
if ((error = getinoquota(ip)) ||
|
||||
@ -2017,6 +2116,7 @@ ufs_makeinode(mode, dvp, vpp, cnp)
|
||||
vput(dvp);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
|
||||
ip->i_mode = mode;
|
||||
|
Loading…
Reference in New Issue
Block a user