Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Apr 1999 13:27:32 -0500 (EST)
From:      ajk@purdue.edu
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/11031: [PATCH] mount and umount support for mortal users
Message-ID:  <199904081827.NAA26269@poynting.physics.purdue.edu>

next in thread | raw e-mail | index | archive | help

>Number:         11031
>Category:       bin
>Synopsis:       [PATCH] mount and umount support for mortal users
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr  8 11:30:01 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     Andrew J. Korty
>Release:        FreeBSD 3.0-RELEASE i386
>Organization:
Physics Computer Network, Purdue University
>Environment:

FreeBSD galileo.physics.purdue.edu 3.1-PCN FreeBSD 3.1-PCN #7:
Mon Apr 5 14:45:22 EST 1999
csg@tesla.physics.purdue.edu:/usr/src/sys/compile/PCN-GALILEO  i386

>Description:

These new versions of mount(8) and umount(8) are designed to be
installed set-uid root.  They behave as normal if invoked by root,
but act according to a configuration file otherwise.  Mortal users
(console users only if desired) are given permission to mount
certain devices on a fixed mount point.  This mount point must be
at least two levels deep, so that the owner and modes on the parent
directory can be changed so as to only allow access by the calling
user.  One or more filesystems may be specified for a given device.

>How-To-Repeat:

Apply this patch, set MORTAL_MOUNT in /etc/make.conf, and "make
all install" in src/sbin/mount and src/sbin/umount.  You'll also
need to create an /etc/mountcap file to use these features (this
patch includes a man page for mountcap(5)).

>Fix:

Index: src/sbin/mount/Makefile
===================================================================
RCS file: /project/cvs/PCN/freebsd/src/sbin/mount/Makefile,v
retrieving revision 1.1.1.2
retrieving revision 1.3
diff -u -r1.1.1.2 -r1.3
--- Makefile	1999/02/03 03:04:26	1.1.1.2
+++ Makefile	1999/04/08 17:55:31	1.3
@@ -6,4 +6,12 @@
 MAN8=	mount.8
 # We do NOT install the getmntopts.3 man page.
+
+.ifdef MORTAL_MOUNT
+BINOWN=		root
+BINMODE=	4555
+CFLAGS+=	-DMORTAL
+SRCS+=		cf.c mortal.c
+MAN5=		mountcap.5
+.endif
 
 .include <bsd.prog.mk>
Index: src/sbin/mount/cf.c
===================================================================
RCS file: cf.c
diff -N cf.c
--- /dev/null	Thu Apr  8 03:05:02 1999
+++ /tmp/cvsk57416	Thu Apr  8 13:17:36 1999
@@ -0,0 +1,121 @@
+/*-
+ * Copyright (c) 1980, 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+	"$Id: cf.c,v 1.2 1999/04/08 18:02:13 ajk Exp $";
+#endif /* not lint */
+
+#include <err.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+
+#include "cf.h"
+#include "mortal.h"
+
+static int
+Cap_Errors(int error, const char *cap, const char *name)
+{
+	switch (error) {
+	case 1:
+		warnx("%s: %s: %s: unresolved \"tc\" reference,"
+		    "continuing ...", PATH_CF, name, cap);
+		break;
+	case -1:
+		return 0;
+	case -2:
+		err(EX_OSERR, "%s: %s: %s", PATH_CF, name, cap);
+	case -3:
+		errx(EX_DATAERR, "%s: %s: possible \"tc\" loop",
+		    PATH_CF, name, cap);
+	}
+	return 1;
+}
+
+char *
+Get_Dev_Cap(const char *dev)
+{
+	char *base;
+	char *buf;
+	char *new;
+	int r;
+	char *db_array[] = { PATH_CF, (char *)0 };
+
+	if (!dev)
+		return NULL;
+	new = strdup(dev);
+	if (!new)
+		err(EX_OSERR, NULL);
+	base = strrchr(new, '/');
+	if (base)
+		++base;
+	else
+		base = new;
+	if ('r' == *base)
+		++base;
+	r = cgetent(&buf, db_array, base);
+	free(new);
+	return (r == 0) ? buf : NULL;
+}
+
+int
+Get_Str(char *buf, char *cap, char **str)
+{
+        return Cap_Errors(cgetstr(buf, cap, str), cap, *str);
+}
+
+char *
+Parent(char *str)
+{
+	static char *r;
+	char *p;
+
+	if (!str)
+		return NULL;
+	if (r != str) {
+		if (r)
+			free(r);
+		r = strdup(str);
+		if (!r)
+			err(EX_OSERR, NULL);
+	}
+	p = strrchr(r, '/');
+	if (!p || p == str)
+		errx(EX_DATAERR, "%s: mount point must have at"
+		    " least two levels", str);
+	*p++ = '\0';
+	if (!*p)
+		(void) Parent(r);
+	return r;
+}
Index: src/sbin/mount/cf.h
===================================================================
RCS file: cf.h
diff -N cf.h
--- /dev/null	Thu Apr  8 03:05:02 1999
+++ /tmp/cvsC57416	Thu Apr  8 13:17:36 1999
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 1980, 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define PATH_CF		"/etc/mountcap"
+#define CF_COMMON	"opts"
+#define CF_CONSOLE	"co"
+#define CF_FSTYPE	"fs"
+#define CF_NODE	"on"
+
+char *Get_Dev_Cap(const char *);
+char *Parent(char *);
+int Get_Str(char *, char *, char **);
Index: src/sbin/mount/mortal.c
===================================================================
RCS file: mortal.c
diff -N mortal.c
--- /dev/null	Thu Apr  8 03:05:02 1999
+++ /tmp/cvsx57416	Thu Apr  8 13:17:36 1999
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 1980, 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+	"$Id: mortal.c,v 1.3 1999/04/08 18:02:13 ajk Exp $";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include "cf.h"
+#include "mortal.h"
+
+extern char *catopt(char *, const char *);
+extern int debug;
+
+mortal_mountfs(spec, name, flags, options, uid)
+	const char *spec, *name, *options;
+	int flags, uid;
+{
+	char *cap;		/* cap key for a filesystem's options */
+	char *cf;		/* mount.cf entry */
+	char *common_opts;	/* common filesystem options */
+	char *console;		/* file whose owner is on console */
+	char *dir;		/* parent directory of mount point */
+	char *fs_opts;		/* this filesystem's options */
+	char *fs_opts_x;	/* expanded filesystem options */
+	char *node;		/* mount point */
+	char *tmp_p;		/* temp file for error log */
+	char *type;		/* current fstype we're trying */
+	char *type_list;	/* list of fstypes to try */
+	int err_fd;		/* redirected STDERR_FILENO */
+	int nbytes;		/* number of bytes read from logfile */
+	int r;			/* return value from mountfs */
+	char err_buf[BUFSIZ];	/* for dumping error file */
+	char tmp[] = ERR_TEMPL;	/* error logfile template */
+
+	cf = Get_Dev_Cap(spec);
+	if (!cf)	/* not in mountcap, therefore not permitted */
+		errc(EX_NOPERM, EPERM, "%s", spec);
+	/*
+	 * Is user on console?  If not, allow anybody!
+	 */
+	if (Get_Str(cf, CF_CONSOLE, &console)) {
+		struct stat sbuf;
+
+		if (-1 == stat(console, &sbuf))
+			err(EX_OSFILE, "%s", console);
+		if (debug)
+			warnx("ruid %d, %s owned by %d", uid, console,
+			    sbuf.st_uid);
+		if (uid != sbuf.st_uid)
+			errx(EX_NOPERM,
+			    "you must be on console to mount this device");
+	}
+	if (!Get_Str(cf, CF_NODE, &node))
+		node = NULL;
+	if (!Get_Str(cf, CF_COMMON, &common_opts))
+		common_opts = DEFAULT_OPTS;
+	if (!Get_Str(cf, CF_FSTYPE, &type_list))
+		type_list = DEFAULT_FSTYPE;
+	err_fd = dup(STDERR_FILENO);
+	(void) close(STDERR_FILENO);
+	tmp_p = mktemp(tmp);
+	if (tmp_p)
+		(void) open(tmp_p, O_RDWR|O_CREAT, 0600);
+	if (debug)
+		warnx("error log: %s", tmp_p);
+	while (type = strsep(&type_list, ",")) {
+		if (-1 == asprintf(&cap, "%s_opts", type))
+			err(EX_OSERR, NULL);
+		if (debug)
+			warnx("looking up %s", cap);
+		fs_opts_x = NULL;
+		if (Get_Str(cf, cap, &fs_opts)) {
+			/*
+			 * This hack lets the uid be substitued
+			 * for %d in the config file.  We'll
+			 * generalize this code when we have a
+			 * need.
+			 */
+			if (debug)
+				warnx("parsing %s", fs_opts);
+			if (-1 == asprintf(&fs_opts_x, fs_opts, uid))
+				err(EX_OSERR, NULL);
+			free(fs_opts);
+		}
+		free(cap);
+		options = catopt(fs_opts_x, common_opts);
+		if (debug)
+			warnx("%s -t %s -o %s %s %s",
+			    PATH_MOUNT, type, options,
+			    spec, node ? node : name);
+		if (0 == strcmp(type, DEFAULT_FSTYPE))
+			type = "ufs";
+		r = mountfs(type, spec, name, flags, options, NULL);
+		if (r)
+			continue;
+		dir = strdup(node);
+		if (!dir)
+			err(EX_OSERR, NULL);
+		dir = Parent(node);
+		if (-1 == chown(dir, uid, -1) || -1 == chmod(dir, 0700))
+			err(EX_OSERR, "%s", dir);
+		free(dir);
+		return r;
+	}
+	if (tmp_p) {
+		(void) lseek(STDERR_FILENO, 0L, SEEK_SET);
+		while (nbytes = read(STDERR_FILENO, err_buf, sizeof err_buf))
+			(void) write(err_fd, err_buf, nbytes);
+		(void) close(STDERR_FILENO);
+		(void) unlink(tmp_p);
+	}
+	return r;
+}
Index: src/sbin/mount/mortal.h
===================================================================
RCS file: mortal.h
diff -N mortal.h
--- /dev/null	Thu Apr  8 03:05:02 1999
+++ /tmp/cvsh57416	Thu Apr  8 13:17:36 1999
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 1980, 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define PATH_MOUNT	"/sbin/mount"
+#define PATH_UMOUNT	"/sbin/umount"
+
+#define ERR_TEMPL	"/tmp/mortalXXXXXX"
+
+#define DEFAULT_OPTS	"nodev,noexec,nosuid,nosymfollow"
+#define DEFAULT_FSTYPE	"default"
+
+void Usage(void);
Index: src/sbin/mount/mount.8
===================================================================
RCS file: /project/cvs/PCN/freebsd/src/sbin/mount/mount.8,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- mount.8	1998/12/03 15:38:52	1.1.1.1
+++ mount.8	1999/04/08 17:55:31	1.2
@@ -307,6 +307,36 @@
 The options specific to NFS filesystems are described in the
 .Xr mount_nfs 8
 manual page.
+.Sh USING MOUNT AS A NON-ROOT USER
+If the sources have been compiled with the \s-1MORTAL\s0 option,
+the system administrator can arrange for non-root users to mount
+filesystems based on a set of guidelines in the /etc/mountcap file.
+These guidelines include a mount point that will be used regardless
+of the user's specification (or the
+.Xr fstab 5
+specification), a file whose ownership will determine whether the
+user is on console, and a list of filesystems to attempt to mount
+from the device.
+.Pp
+The mount point must be at least a two level diretory to work,
+since the owner of the parent directory of the mount point is
+changed to the calling user, and its permissions are changed to
+0700.  When the device is unmounted, the ownership is changed back
+to root and the permissions are kept at 0700.
+.Pp
+This feature is mainly designed to give console users exclusive
+access to removable media devices such as floppy disks and CD-ROMs,
+but it can be used for other purposes as well.  Granting access
+this way is more flexible than changing permissions and ownerships
+on the special device and more secure than making the filesystem-specific
+mount command (\fIe.g.,\fP
+.Xr mount_msdos 8 )
+set-uid root.  Support for this feature can be added by setting
+the \s-1MORTAL_MOUNT\s0 variable in \fI/etc/make.conf\fP before
+building
+.Xr mount 8
+and
+.Xr umount 8 .
 .Sh DIAGNOSTICS
 Various, most of them are self-explanatory.
 .Pp
@@ -332,6 +362,7 @@
 .Xr mount 2 ,
 .Xr vfsload 3 ,
 .Xr fstab 5 ,
+.Xr mountcap 5 ,
 .Xr mount_cd9660 8 ,
 .Xr mount_devfs 8 ,
 .Xr mount_fdesc 8 ,
Index: src/sbin/mount/mount.c
===================================================================
RCS file: /project/cvs/PCN/freebsd/src/sbin/mount/mount.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- mount.c	1998/12/03 15:38:52	1.1.1.1
+++ mount.c	1999/03/30 15:12:09	1.2
@@ -125,6 +125,9 @@
 	pid_t pid;
 	int all, ch, i, init_flags, mntsize, rval;
 	char *options;
+#ifdef MORTAL
+	int uid;
+#endif /* defined(MORTAL) */
 
 	all = init_flags = 0;
 	options = NULL;
@@ -175,6 +178,10 @@
 	argc -= optind;
 	argv += optind;
 
+#ifdef MORTAL
+	uid = getuid();
+#endif /* defined(MORTAL) */
+
 #define	BADTYPE(type)							\
 	(strcmp(type, FSTAB_RO) &&					\
 	    strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ))
@@ -182,6 +189,9 @@
 	rval = 0;
 	switch (argc) {
 	case 0:
+#ifdef MORTAL
+		seteuid(uid);
+#endif /* defined(MORTAL) */
 		if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0)
 			err(1, "getmntinfo");
 		if (all) {
@@ -227,6 +237,13 @@
 				mntfromname = fs->fs_spec;
 			else
 				mntfromname = mntbuf->f_mntfromname;
+#ifdef MORTAL
+			if (uid)
+				rval = mortal_mountfs(mntfromname,
+				    mntbuf->f_mntonname, init_flags,
+				    options, uid);
+			else
+#endif /* defined(MORTAL) */
 			rval = mountfs(mntbuf->f_fstypename, mntfromname,
 			    mntbuf->f_mntonname, init_flags, options, 0);
 			break;
@@ -238,6 +255,12 @@
 		if (BADTYPE(fs->fs_type))
 			errx(1, "%s has unknown file system type",
 			    *argv);
+#ifdef MORTAL
+		if (uid)
+			rval = mortal_mountfs(fs->fs_spec, fs->fs_file,
+			    init_flags, options, uid);
+		else
+#endif /* defined(MORTAL) */
 		rval = mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file,
 		    init_flags, options, fs->fs_mntops);
 		break;
@@ -249,6 +272,12 @@
 		 */
 		if (vfslist == NULL && strpbrk(argv[0], ":@") != NULL)
 			vfstype = "nfs";
+#ifdef MORTAL
+		if (uid)
+			rval = mortal_mountfs(argv[0], argv[1], init_flags,
+			    options, uid);
+		else
+#endif /* defined(MORTAL) */
 		rval = mountfs(vfstype,
 		    argv[0], argv[1], init_flags, options, NULL);
 		break;
Index: src/sbin/mount/mountcap.5
===================================================================
RCS file: mountcap.5
diff -N mountcap.5
--- /dev/null	Thu Apr  8 03:05:02 1999
+++ /tmp/cvsl57416	Thu Apr  8 13:17:36 1999
@@ -0,0 +1,116 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	$Id: mountcap.5,v 1.1 1999/04/08 17:55:32 ajk Exp $
+.\" "
+.Dd April 8, 1999
+.Dt MOUNTCAP 5
+.Os FreeBSD 3.2
+.\" turn off hyphenation
+.hym 999
+.Sh NAME
+.Nm mountcap
+.Nd mount/umount configuration database for non-root users
+.Sh SYNOPSIS
+.Nm mountcap
+.Sh DESCRIPTION
+The
+.Nm
+file is a simplified version of the
+.Xr termcap 5
+data base used to describe how
+.Xr mount 8
+and
+.Xr umount 8
+behave when called by non-root users, providing these programs have been
+compiled with the \s-1MORTAL\s0 flag set.  This feature is primarily
+designed to allow console users to mount removable devices.  The
+.Nm
+file allows the super-user to set for a given device a fixed
+mount point, a list of filesystems to try and their options, and
+a file whose ownership will determine whether the user is on console.
+The \fBtc=\fP option is also provided for substitution.
+.Sh CAPABILITIES
+Refer to
+.Xr termcap 5
+for a description of the file layout.
+.Bl -column Namexx Default
+.It Sy Name	Type	Description
+.It "fs	str	comma-separated list of filesystems to try"
+.It "on	str	mount point (overrides any other specification)"
+.It "tc	str	table continuation"
+.El
+.Pp
+Any valid filesystem name (\fIe.g.,\fP msdos, cd9660, \fIetc.\fP)
+may be listed in an \fBfs=\fP entry.  If the word \fIdefault\fP is
+used,
+.Xr mount 8 's
+default filesystem (currently \fIufs\fP) is used.
+.Pp
+For each filesystem
+specified, there may be an entry of \f(BIfs\fP\fB_opts\fP, where
+\fIfs\fP is the name of the filesystem as it appears in the list.
+Wherever the string \fI%d\fP appears in this string, it will be
+replaced by the calling user's uid.
+.Pp
+A specified mount point must be at least two levels deep so that
+.Xr mount 8
+can set the ownership and permissions of the mount point's parent
+directory such that only the calling user can access the mounted
+filesystem.
+.Sh EXAMPLE
+The following example will allow a user to access \fI/dev/floppy\fP,
+always mounting it on \fI/console/floppy\fP.  The \fI-u\fP and
+\fI-m\fP options will be passed to
+.Xr mount_msdos ,
+setting the ownership on each file to the calling user and the
+permissions to 0700.  The filesystem on the floppy could be any of
+\fImsdos, ext2fs,\fP or \fIufs\fP, and the mount would succeed.
+The mount will only be permitted if \fI/dev/console\fP is owned by
+the calling user.  After the mount takes place, \fI/console\fP will
+be owned by the calling user and mode 0700.
+.Bd -literal -offset indent
+common:\\
+        :co=/dev/console:\\
+        :cd9660_opts=rdonly:\\
+        :msdos_opts=-u=%d,-m=700:
+floppy:\\
+        :fs=msdos,ext2fs,default:\\
+        :on=/console/floppy:\\
+        :tc=common:
+.Ed
+.Sh SEE ALSO
+.Xr mount 8 ,
+.Xr umount 8 .
+.Sh HISTORY
+The
+.Nm
+file format appeared in FreeBSD 3.2.
Index: src/sbin/umount/Makefile
===================================================================
RCS file: /project/cvs/PCN/freebsd/src/sbin/umount/Makefile,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- Makefile	1998/12/03 15:38:58	1.1.1.1
+++ Makefile	1999/03/30 15:12:35	1.2
@@ -8,4 +8,11 @@
 CFLAGS+= -I${MOUNT}
 .PATH:	${MOUNT}
 
+.ifdef MORTAL_MOUNT
+BINOWN=		root
+BINMODE=	4555
+CFLAGS+=	-DMORTAL
+SRCS+=		cf.c
+.endif
+
 .include <bsd.prog.mk>
Index: src/sbin/umount/umount.8
===================================================================
RCS file: /project/cvs/PCN/freebsd/src/sbin/umount/umount.8,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- umount.8	1998/12/03 15:38:59	1.1.1.1
+++ umount.8	1999/04/08 17:55:41	1.2
@@ -118,9 +118,19 @@
 .It Pa /etc/fstab
 filesystem table
 .El
+.Pp
+If the calling user is not the super-user and
+.Xr umount 8
+was compiled with \s-1MORTAL\s0 set, the device will be unmounted
+if found in \fI/etc/mountcap\fP.  See
+.Xr mount 8
+and
+.Xr mountcap 5
+for more information.
 .Sh SEE ALSO
 .Xr unmount 2 ,
 .Xr fstab 5 ,
+.Xr mountcap 5 ,
 .Xr mount 8
 .Sh BUGS
 When using union filesystems,
Index: src/sbin/umount/umount.c
===================================================================
RCS file: /project/cvs/PCN/freebsd/src/sbin/umount/umount.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- umount.c	1998/12/03 15:38:59	1.1.1.1
+++ umount.c	1999/03/30 20:11:43	1.3
@@ -60,6 +60,12 @@
 #include <string.h>
 #include <unistd.h>
 
+#ifdef MORTAL
+#include <errno.h>
+#include <sysexits.h>
+#include "cf.h"
+#endif /* defined(MORTAL) */
+
 typedef enum { MNTON, MNTFROM } mntwhat;
 
 int	fake, fflag, vflag;
@@ -83,6 +89,9 @@
 	int all, ch, errs, mnts;
 	char **typelist = NULL;
 	struct statfs *mntbuf;
+#ifdef MORTAL
+	int uid;
+#endif /* defined(MORTAL) */
 
 	/* Start disks transferring immediately. */
 	sync();
@@ -128,8 +137,15 @@
 	if ((nfshost != NULL) && (typelist == NULL))
 		typelist = makevfslist("nfs");
 
+#ifdef MORTAL
+	uid = getuid();
+#endif /* defined(MORTAL) */
+
 	switch (all) {
 	case 2:
+#ifdef MORTAL
+		seteuid(uid);
+#endif /* defined(MORTAL) */
 		if ((mnts = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
 			warn("getmntinfo");
 			errs = 1;
@@ -143,6 +159,9 @@
 		}
 		break;
 	case 1:
+#ifdef MORTAL
+		seteuid(uid);
+#endif /* defined(MORTAL) */
 		if (setfsent() == 0)
 			err(1, "%s", _PATH_FSTAB);
 		errs = umountall(typelist);
@@ -212,6 +231,11 @@
 	CLIENT *clp;
 	int so;
 	char *type, *delimp, *hostp, *mntpt, *origname, rname[MAXPATHLEN];
+#ifdef MORTAL
+	char *dev;
+	char *dir;
+	int uid;
+#endif /* defined(MORTAL) */
 
 	if (realpath(name, rname) == NULL) {
 		/* Continue and let the system call check it... */
@@ -221,6 +245,9 @@
 	origname = name;
 	if (stat(name, &sb) < 0) {
 		mntpt = rname;
+#ifdef MORTAL
+		dev = name;
+#endif /* defined(MORTAL) */
 		if ((getmntname(rname, MNTFROM, &type) == NULL) &&
 		    ((mntpt = getmntname(name, MNTON, &type)) == NULL)) {
 			warnx("%s: not currently mounted", name);
@@ -231,8 +258,14 @@
 			warnx("%s: not currently mounted", name);
 			return (1);
 		}
+#ifdef MORTAL
+		dev = name;
+#endif /* defined(MORTAL) */
 	} else if (S_ISDIR(sb.st_mode)) {
 		mntpt = rname;
+#ifdef MORTAL
+		dev = name;
+#endif /* defined(MORTAL) */
 		if (getmntname(mntpt, MNTFROM, &type) == NULL) {
 			warnx("%s: not currently mounted", name);
 			return (1);
@@ -246,6 +279,29 @@
 	if (checkvfsname(type, typelist))
 		return (1);
 
+#ifdef MORTAL
+	uid = getuid();
+	if (uid) {
+		char *cap;
+		struct stat stat_buf;
+
+		cap = Get_Dev_Cap(dev);
+		if (!cap)	/* not in mount.cf, therefore not permitted */
+			errc(EX_NOPERM, EPERM, "%s", dev);
+		if (!Get_Str(cap, CF_NODE, &dir))
+			errc(EX_NOPERM, EPERM, "%s", dev);
+		dir = strdup(dir);
+		if (!dir)
+			err(EX_OSERR, NULL);
+		dir = Parent(dir);
+		if (-1 == stat(dir, &stat_buf))
+			err(EX_OSFILE, "%s", dir);
+		if (uid != stat_buf.st_uid)
+			errc(EX_NOPERM, EPERM, "%s", dir);
+
+	}
+#endif /* defined(MORTAL) */
+
 	hp = NULL;
 	if (!strcmp(type, "nfs")) {
 		if ((delimp = strchr(name, '@')) != NULL) {
@@ -274,6 +330,11 @@
 		warn("%s", mntpt);
 		return (1);
 	}
+
+#ifdef MORTAL
+	if (uid && (-1 == chown(dir, 0, -1) || -1 == chmod(dir, 0700)))
+		err(EX_OSERR, "%s", dir);
+#endif /* defined(MORTAL) */
 
 	if ((hp != NULL) && !(fflag & MNT_FORCE)) {
 		*delimp = '\0';

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199904081827.NAA26269>