summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/options3
-rw-r--r--sys/kern/vfs_extattr.c6
-rw-r--r--sys/kern/vfs_syscalls.c6
-rw-r--r--sys/sys/mount.h41
-rw-r--r--sys/ufs/ufs/ufs_vnops.c104
5 files changed, 134 insertions, 26 deletions
diff --git a/sys/conf/options b/sys/conf/options
index e89580c..89f1552 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -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
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 5e1fa19..eb8cb4e 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.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 @@ update:
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.
*/
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 5e1fa19..eb8cb4e 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.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 @@ update:
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.
*/
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index d787a01..25895ae 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -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.
*/
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index bc13a05..613fe5d 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -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))) {
@@ -1341,6 +1390,7 @@ ufs_mkdir(ap)
return (error);
}
#endif
+#endif
ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
ip->i_mode = dmode;
tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */
@@ -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)) ||
@@ -2018,6 +2117,7 @@ ufs_makeinode(mode, dvp, vpp, cnp)
return (error);
}
#endif
+#endif
ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
ip->i_mode = mode;
tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */
OpenPOWER on IntegriCloud