The common UID/GID space implementation. It has been discussed on -arch

in 1999, and there are changes to the sysctl names compared to PR,
according to that discussion. The description is in sys/conf/NOTES.
Lines in the GENERIC files are added in commented-out form.
I'll attach the test script I've used to PR.

PR:		kern/14584
Submitted by:	babkin
This commit is contained in:
Sergey Babkin 2006-06-25 18:37:44 +00:00
parent 92d4d9230c
commit 7a799f1ef0
9 changed files with 143 additions and 0 deletions

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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.