summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/conf/GENERIC1
-rw-r--r--sys/conf/NOTES64
-rw-r--r--sys/conf/options1
-rw-r--r--sys/i386/conf/GENERIC1
-rw-r--r--sys/ia64/conf/GENERIC1
-rw-r--r--sys/kern/vfs_subr.c72
-rw-r--r--sys/pc98/conf/GENERIC1
-rw-r--r--sys/powerpc/conf/GENERIC1
-rw-r--r--sys/sparc64/conf/GENERIC1
9 files changed, 143 insertions, 0 deletions
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index b27c52d..222c8d4 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -59,6 +59,7 @@ options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options ADAPTIVE_GIANT # Giant mutex is adaptive.
options STOP_NMI # Stop CPUS using NMI instead of IPI
+#options COMMONID # Enable support for common UID/GID space
# Debugging for use in -current
options KDB # Enable kernel debugger support.
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 7d610bc..79ecc5d 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -905,6 +905,70 @@ options QUOTA #enable disk quotas
#
options SUIDDIR
+# The common user and group ID space for the local filesystems
+# (see PR kern/14584), AKA "poor man's ACLs".
+#
+# From the systems administration standpoint ACLs are a pain to use:
+# * they are not supported by the classic file formats like tar and cpio
+# * they need lots of ugly flags to commands like chown or ls
+# * they are just by themselves difficult to show in ls
+# * they promote ad-hoc and messy assignment of permissions
+#
+# But in fact the classic Unix permissions seem to have only one real problem:
+# sometimes it's neccessary to give read permissions to one group of
+# users and read-write permissions to another group of users. But only
+# one group is supported and that makes a problem. The common ID
+# support solves this problem without breaking any compatibility.
+#
+# Controlled by the sysctl:
+# vfs.commonid.local.enabled: Enable common UID/GID space for local filesystems
+# vfs.commonid.local.low: Lowest common UID/GID value for local filesystems
+# vfs.commonid.local.high: Highest common UID/GID value for local filesystems
+#
+# When enabled, the user and group ID space in the range [low, high]
+# becomes common. That is, if there is an user with some ID in this range,
+# there must not be a group with the same ID (except for a special case
+# described later). Traditionally this kind of overlapping exists in the
+# low values of system IDs, so the implementation won't allow to set the
+# low border below 100. If it's set manually below 100, the first time
+# an access check is done, the system will reset it to 100.
+#
+# The special case is that for the symbolic group and user names to work
+# correctly, every time a user is created, a pseudo-group with the same
+# ID and name must be created. And the other way around - every time
+# a group is created, a pseudo-user with the same name and ID must be created.
+# Otherwise command like "ls" won't show the user/group names correctly
+# and command like "chown" won't understand the symbolic names correctly.
+#
+# The IDs in the common range can be used interchangeably in both the
+# user and group fields of file permissions. For example, if you have
+# groups group1 and group2 with IDs in the common range, you can do:
+# chmod 240 file
+# chown group1:group2 file
+# This would allow the group1 to write to the file and group2 to read
+# the file.
+#
+# This semantics works only for the access but not for modification of
+# the permissions. In the example above the members of group1 aren't allowed
+# to call chmod on the file. Such changes must be done either by root
+# or through the pseudo-user group1.
+#
+# If it's desiable to give the "owner group" of some files (like group1
+# in this example) the rights to change the permissions of all the files
+# it owns, it can be achieved through cloning the chmod binary and
+# adding the pseudo-user setuid rights to it:
+# cp /bin/chmod /usr/local/bin/group1chmod
+# chown group1 /usr/local/bin/group1chmod
+# chmod u=xs,g=,o= /usr/local/bin/group1chmod
+# A similar thing can be done for chown.
+# In result all the members of group1 would be able to execute group1chmod,
+# which would assume the ID of pseudo-user "group1" and will be able
+# to change the file permissions.
+#
+# This logic does not work on the remote filesystems (such as NFS).
+
+options COMMONID # Enable support for common UID/GID space
+
# NFS options:
options NFS_MINATTRTIMO=3 # VREG attrib cache timeout in sec
options NFS_MAXATTRTIMO=60
diff --git a/sys/conf/options b/sys/conf/options
index 19cca6f..2aee2d4 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -163,6 +163,7 @@ VFS_AIO
VERBOSE_SYSINIT opt_global.h
WLCACHE opt_wavelan.h
WLDEBUG opt_wavelan.h
+COMMONID opt_commonid.h
# POSIX kernel options
P1003_1B_MQUEUE opt_posix.h
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index b802541..3c305ce 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -59,6 +59,7 @@ options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options ADAPTIVE_GIANT # Giant mutex is adaptive.
options STOP_NMI # Stop CPUS using NMI instead of IPI
+#options COMMONID # Enable support for common UID/GID space
# Debugging for use in -current
options KDB # Enable kernel debugger support.
diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC
index b2f7183..f28fcdf 100644
--- a/sys/ia64/conf/GENERIC
+++ b/sys/ia64/conf/GENERIC
@@ -53,6 +53,7 @@ options SYSVSHM # SYSV-style shared memory
options UFS_ACL # Support for access control lists
options UFS_DIRHASH # Hash-based directory lookup scheme
options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B RT extensions
+#options COMMONID # Enable support for common UID/GID space
# Various "busses"
device firewire # FireWire bus code
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 45577ab..83cd325 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include "opt_ddb.h"
#include "opt_mac.h"
+#include "opt_commonid.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -278,6 +279,36 @@ SYSCTL_INT(_debug, OID_AUTO, vnlru_nowhere, CTLFLAG_RW,
#define VSHOULDFREE(vp) (!((vp)->v_iflag & VI_FREE) && !(vp)->v_holdcnt)
#define VSHOULDBUSY(vp) (((vp)->v_iflag & VI_FREE) && (vp)->v_holdcnt)
+#ifdef COMMONID
+/*
+ * Sysctl variables to control the unified user and group ID space.
+ */
+
+/* ID below that are the traditional system IDs that
+ * can't be in the common space
+ */
+#define MINCOMMONID 100
+
+typedef struct {
+ int enabled; /* flag: commonid is enabled */
+ int low; /* the lowest common ID */
+ int high; /* the highest common ID */
+} commonid_ctl_t;
+
+static commonid_ctl_t commonid = { 0, 1000, 60000 }; /* safe values */
+
+SYSCTL_NODE(_vfs, OID_AUTO, commonid, CTLFLAG_RW, 0, "Common UID/GID space");
+SYSCTL_NODE(_vfs_commonid, OID_AUTO, local, CTLFLAG_RW, 0,
+ "Common UID/GID space for local filesystems");
+SYSCTL_INT(_vfs_commonid_local, OID_AUTO, enabled, CTLFLAG_RW,
+ &commonid.enabled, 0,
+ "Enable common UID/GID space for local filesystems");
+SYSCTL_INT(_vfs_commonid_local, OID_AUTO, low, CTLFLAG_RW, &commonid.low,
+ 0, "Lowest common UID/GID value for local filesystems");
+SYSCTL_INT(_vfs_commonid_local, OID_AUTO, high, CTLFLAG_RW, &commonid.high,
+ 0, "Highest common UID/GID value for local filesystems");
+
+#endif /* COMMONID */
/*
* Initialize the vnode management data structures.
@@ -3171,6 +3202,47 @@ vaccess(enum vtype type, mode_t file_mode, uid_t file_uid, gid_t file_gid,
goto privcheck;
}
+#ifdef COMMONID
+ /* If the common UID/GID is enabled, check the user agains the
+ * file GID and groups against file UID
+ */
+ if (commonid.enabled) {
+ if (commonid.low < MINCOMMONID)
+ commonid.low = MINCOMMONID;
+
+ if (cred->cr_uid == file_gid
+ && file_gid >= commonid.low && file_gid <= commonid.high) {
+ /* no VADMIN in this case */
+ if (file_mode & S_IXGRP)
+ dac_granted |= VEXEC;
+ if (file_mode & S_IRGRP)
+ dac_granted |= VREAD;
+ if (file_mode & S_IWGRP)
+ dac_granted |= (VWRITE | VAPPEND);
+
+ if ((acc_mode & dac_granted) == acc_mode)
+ return (0);
+
+ goto privcheck;
+ }
+ if (file_uid >= commonid.low && file_uid <= commonid.high
+ && groupmember(file_uid, cred)) {
+ /* no VADMIN in this case */
+ if (file_mode & S_IXUSR)
+ dac_granted |= VEXEC;
+ if (file_mode & S_IRUSR)
+ dac_granted |= VREAD;
+ if (file_mode & S_IWUSR)
+ dac_granted |= (VWRITE | VAPPEND);
+
+ if ((acc_mode & dac_granted) == acc_mode)
+ return (0);
+
+ goto privcheck;
+ }
+ }
+#endif /* COMMONID */
+
/* Otherwise, check the groups (first match) */
if (groupmember(file_gid, cred)) {
if (file_mode & S_IXGRP)
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index 1903d71..fc79b86 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -59,6 +59,7 @@ options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+#options COMMONID # Enable support for common UID/GID space
# Debugging for use in -current
options KDB # Enable kernel debugger support.
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index 8767262..d30b795 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -57,6 +57,7 @@ options SYSVSHM #SYSV-style shared memory
options SYSVMSG #SYSV-style message queues
options SYSVSEM #SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+#options COMMONID # Enable support for common UID/GID space
# Debugging for use in -current
options KDB #Enable the kernel debugger
diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
index 77ac662..53ba359 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -58,6 +58,7 @@ options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options ADAPTIVE_GIANT # Giant mutex is adaptive.
+#options COMMONID # Enable support for common UID/GID space
# Debugging for use in -current
options KDB # Enable kernel debugger support.
OpenPOWER on IntegriCloud