aboutsummaryrefslogtreecommitdiff
path: root/etc
diff options
context:
space:
mode:
authorMike Makonnen <mtm@FreeBSD.org>2003-08-20 06:15:18 +0000
committerMike Makonnen <mtm@FreeBSD.org>2003-08-20 06:15:18 +0000
commit130112f793bd03ae70f02652a3110abcb6ec6f01 (patch)
tree1401c7d38c4f23bad9b125bba53dcb61f9f0e691 /etc
parent74a9cb09699df2644229357c51f118371107d4e2 (diff)
downloadsrc-130112f793bd03ae70f02652a3110abcb6ec6f01.tar.gz
src-130112f793bd03ae70f02652a3110abcb6ec6f01.zip
Add a general mechanism for creating and applying
devfs(8) rules in rc(8). It is most useful for applying rules to devfs(5) mount points in /dev or inside jails. The following line of script is sufficient to mount a relatively useful+secure devfs(5) in a jail: devfs_mount_jail /some/jail/dev Some new shell routines available to scripts that source rc.subr(5): o devfs_link - Makes it a little easier to create symlinks o devfs_init_rulesets - Create devfs(8) rulesets from devfs.rules o devfs_set_ruleset - Set a ruleset to a devfs(5) mount o devfs_apply_ruleset - Apply a ruleset to a devfs(5) mount o devfs_domount - Mount devfs(5) and apply some ruleset o devfs_mount_jail - Mount devfs(5) and apply a ruleset appropriate to jails. Additional rulesets can be specified in /etc/devfs.rules. If the devfs_system_ruleset variable is defined in rc.conf and it contains the name of a ruleset defined in /etc/defaults/devfs.rules or user supplied rulesets in /etc/devfs.rules then that ruleset will be applied to /dev at startup by the /etc/rc.d/devfs script. It can also be applied post-startup: /etc/rc.d/devfs start This is a more flexible mechanism than the previous method of using /etc/devfs.conf. However, that method is still available. Note: since devfs(8) doesn't provide any way for creating symlinks as part of a ruleset, anyone wishing to create symlinks in a devfs(5) as part of the bootup sequence will still have to rely on /etc/devfs.conf.
Notes
Notes: svn path=/head/; revision=119166
Diffstat (limited to 'etc')
-rw-r--r--etc/defaults/Makefile2
-rw-r--r--etc/defaults/devfs.rules64
-rw-r--r--etc/defaults/rc.conf4
-rw-r--r--etc/rc.d/devfs12
-rw-r--r--etc/rc.subr218
5 files changed, 298 insertions, 2 deletions
diff --git a/etc/defaults/Makefile b/etc/defaults/Makefile
index 3e9a52d2c9be..56e74ffd4be7 100644
--- a/etc/defaults/Makefile
+++ b/etc/defaults/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-FILES= pccard.conf periodic.conf rc.conf
+FILES= devfs.rules pccard.conf periodic.conf rc.conf
NOOBJ= noobj
FILESDIR= /etc/defaults
FILESMODE= 644
diff --git a/etc/defaults/devfs.rules b/etc/defaults/devfs.rules
new file mode 100644
index 000000000000..aa618997ce01
--- /dev/null
+++ b/etc/defaults/devfs.rules
@@ -0,0 +1,64 @@
+#
+# The following are some default rules for devfs(5) mounts.
+# The format is very simple. Empty lines and lines begining
+# with a hash '#' are ignored. If the hash mark occurs anywhere
+# other than the beginning of a line, it and any subsequent
+# characters will be ignored. A line in between brackets '[]'
+# denotes the beginning of a ruleset. In the brackets should
+# be a name for the rule and its ruleset number. Any other lines
+# will be considered to be the 'action' part of a rule
+# passed to the devfs(8) command. These will be passed
+# "as-is" to the devfs(8) command with the exception that
+# any references to other rulesets will be expanded first. These
+# references must include a dollar sign '$' in-front of the
+# name to be expanded properly.
+#
+# $FreeBSD$
+#
+
+# Very basic and secure ruleset: Hide everything.
+# Used as a basis for other rules.
+#
+[devfsrules_hide_all=1]
+add hide
+
+# Basic devices typically necessary.
+# Requires: devfsrules_hide_all
+#
+[devfsrules_unhide_basic=2]
+add path null unhide
+add path zero unhide
+add path random unhide
+add path urandom unhide
+
+# Devices typically needed to support logged-in users.
+# Requires: devfsrules_hide_all
+#
+[devfsrules_unhide_login=3]
+add path 'ptyp*' unhide
+add path 'ptyq*' unhide
+add path 'ptyr*' unhide
+add path 'ptys*' unhide
+add path 'ptyP*' unhide
+add path 'ptyQ*' unhide
+add path 'ptyR*' unhide
+add path 'ptyS*' unhide
+add path 'ttyp*' unhide
+add path 'ttyq*' unhide
+add path 'ttyr*' unhide
+add path 'ttys*' unhide
+add path 'ttyP*' unhide
+add path 'ttyQ*' unhide
+add path 'ttyR*' unhide
+add path 'ttyS*' unhide
+add path 'fd/*' unhide
+add path stdin unhide
+add path stdout unhide
+add path stderr unhide
+
+# Devices usually found in a jail.
+#
+[devfsrules_jail=4]
+add include $devfsrules_hide_all
+add include $devfsrules_unhide_basic
+add include $devfsrules_unhide_login
diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index b247b3256c1b..be380f2973b7 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -434,6 +434,10 @@ jail_set_hostname_allow="YES" # Allow root user in a jail to change its hostname
jail_socket_unixiproute_only="YES" # Route only TCP/IP within a jail
jail_sysvipc_allow="NO" # Allow SystemV IPC use from within a jail
watchdogd_enable="NO" # Start the software watchdog daemon
+devfs_rulesets="/etc/defaults/devfs.rules /etc/devfs.rules" # Files containing
+ # devfs(8) rules.
+devfs_system_ruleset="" # The name of a ruleset to apply to /dev
+
##############################################################
### Define source_rc_confs, the mechanism used by /etc/rc.* ##
diff --git a/etc/rc.d/devfs b/etc/rc.d/devfs
index aaf828b51c12..07934fb4dc79 100644
--- a/etc/rc.d/devfs
+++ b/etc/rc.d/devfs
@@ -11,9 +11,19 @@
. /etc/rc.subr
name="devfs"
-start_cmd='read_devfs_conf'
+start_cmd='devfs_start'
stop_cmd=':'
+devfs_start()
+{
+ if [ -n "$devfs_system_ruleset" ]; then
+ devfs_init_rulesets
+ devfs_set_ruleset $devfs_system_ruleset /dev
+ devfs_apply_ruleset $devfs_system_ruleset /dev
+ fi
+ read_devfs_conf
+}
+
read_devfs_conf()
{
if [ -r /etc/devfs.conf ]; then
diff --git a/etc/rc.subr b/etc/rc.subr
index 87f9c4f8fcf5..c45938c71a92 100644
--- a/etc/rc.subr
+++ b/etc/rc.subr
@@ -1033,3 +1033,221 @@ backup_file()
esac
fi
}
+
+# devfs_link dir src link
+# Make a symbolic link 'link' to src in chroot/dev.
+# Returns 0 on sucess.
+#
+devfs_link()
+{
+ local dir src link _me
+ dir="$1"
+ src="$2"
+ link="$3"
+ _me="devfs_link"
+
+ if [ -z "$dir" -o -z "$src" -o -z "$link" ]; then
+ warn "devfs_link(): requires three arguments."
+ return 1
+ fi
+ if [ -z "$dir" ]; then
+ warn "$_me: the directory ($dir) does not exist"
+ return 1
+ fi
+ cd ${chroot}/dev
+ if ! ln -sf $src $link ; then
+ warn "$_me: unable to link $link --> $src in $dir"
+ return 1
+ fi
+ return 0
+}
+
+# devfs_rulesets_from_file file
+# Reads a set of devfs commands from file, and creates
+# the specified rulesets with their rules. Returns non-zero
+# if there was an error.
+#
+devfs_rulesets_from_file()
+{
+ local file _err _me
+ file="$1"
+ _me="devfs_rulesets_from_file"
+ _err=0
+
+ if [ -z "$file" ]; then
+ warn "$_me: you must specify a file"
+ return 1
+ fi
+ if [ ! -e "$file" ]; then
+ debug "$_me: no such file ($file)"
+ return 0
+ fi
+ debug "reading rulesets from file ($file)"
+ { while read line
+ do
+ case $line in
+ \#*)
+ continue
+ ;;
+ \[*\]*)
+ rulenum=`expr "$line" : "\[.*=\([0-9]*\)\]"`
+ if [ -z "$rulenum" ]; then
+ warn "$_me: cannot extract rule number ($line)"
+ _err=1
+ break
+ fi
+ rulename=`expr "$line" : "\[\(.*\)=[0-9]*\]"`
+ if [ -z "$rulename" ]; then
+ warn "$_me: cannot extract rule name ($line)"
+ _err=1
+ break;
+ fi
+ eval $rulename=\$rulenum
+ debug "found ruleset: $rulename=$rulenum"
+ if ! /sbin/devfs rule -s $rulenum delset ; then
+ _err=1
+ break
+ fi
+ ;;
+ *)
+ rulecmd="${line%%"\#*"}"
+ # evaluate the command incase it includes
+ # other rules
+ if [ -n "$rulecmd" ]; then
+ debug "adding rule ($rulecmd)"
+ if ! eval /sbin/devfs rule -s $rulenum $rulecmd
+ then
+ _err=1
+ break
+ fi
+ fi
+ ;;
+ esac
+ if [ $_err -ne 0 ]; then
+ debug "error in $_me"
+ break
+ fi
+ done } < $file
+ return $_err
+}
+
+# devfs_init_rulesets
+# Initializes rulesets from configuration files. Returns
+# non-zero if there was an error.
+#
+devfs_init_rulesets()
+{
+ local file _me
+ _me="devfs_init_rulesets"
+
+ # Go through this only once
+ if [ -n "$devfs_rulesets_init" ]; then
+ debug "$_me: devfs rulesets already initialized"
+ return
+ fi
+ for file in $devfs_rulesets ; do
+ devfs_rulesets_from_file $file || return 1
+ done
+ devfs_rulesets_init=1
+ debug "$_me: devfs rulesets initialized"
+ return 0
+}
+
+# devfs_set_ruleset ruleset [dir]
+# Sets the default ruleset of dir to ruleset. The ruleset arguement
+# must be a ruleset name as specified in devfs.rules(5) file.
+# Returns non-zero if it could not set it successfully.
+#
+devfs_set_ruleset()
+{
+ local devdir rs _me
+ [ -n "$1" ] && eval rs=\$$1 || rs=
+ [ -n "$2" ] && devdir="-m "$2"" || devdir=
+ _me="devfs_set_ruleset"
+
+ if [ -z "$rs" ]; then
+ warn "$_me: you must specify a ruleset number"
+ return 1
+ fi
+ debug "$_me: setting ruleset ($rs) on mount-point (${devdir#-m })"
+ if ! /sbin/devfs $devdir ruleset $rs ; then
+ warn "$_me: unable to set ruleset $rs to ${devdir#-m }"
+ return 1
+ fi
+ return 0
+}
+
+# devfs_apply_ruleset ruleset [dir]
+# Apply ruleset number $ruleset to the devfs mountpoint $dir.
+# The ruleset argument must be a ruleset name as specified
+# in a devfs.rules(5) file. Returns 0 on success or non-zero
+# if it could not apply the ruleset.
+#
+devfs_apply_ruleset()
+{
+ local devdir rs _me
+ [ -n "$1" ] && eval rs=\$$1 || rs=
+ [ -n "$2" ] && devdir="-m "$2"" || devdir=
+ _me="devfs_apply_ruleset"
+
+ if [ -z "$rs" ]; then
+ warn "$_me: you must specify a ruleset"
+ return 1
+ fi
+ debug "$_me: applying ruleset ($rs) to mount-point (${devdir#-m })"
+ if ! /sbin/devfs $devdir rule -s $rs applyset ; then
+ warn "$_me: unable to apply ruleset $rs to ${devdir#-m }"
+ return 1
+ fi
+ return 0
+}
+
+# devfs_domount dir [ruleset]
+# Mount devfs on dir. If ruleset is specified it is set
+# on the mount-point. It must also be a ruleset name as specified
+# in a devfs.rules(5) file. Returns 0 on success.
+#
+devfs_domount()
+{
+ local devdir rs _me
+ devdir="$1"
+ [ -n "$2" ] && rs=$2 || rs=
+ _me="devfs_domount()"
+
+ if [ -z "$devdir" ]; then
+ warn "$_me: you must specify a mount-point"
+ return 1
+ fi
+ debug "$_me: mount-point is ($devdir), ruleset is ($rs)"
+ if ! mount -t devfs dev "$devdir" ; then
+ warn "$_me: Unable to mount devfs on $devdir"
+ return 1
+ fi
+ if [ -n "$rs" ]; then
+ devfs_init_rulesets
+ devfs_set_ruleset $rs $devdir
+ fi
+ return 0
+}
+
+# devfs_mount_jail dir [ruleset]
+# Mounts a devfs file system appropriate for jails
+# on the directory dir. If ruleset is specified, the ruleset
+# it names will be used instead. If present, ruleset must
+# be the name of a ruleset as defined in a devfs.rules(5) file.
+# This function returns non-zero if an error occurs.
+#
+devfs_mount_jail()
+{
+ local jdev rs _me
+ jdev="$1"
+ [ -n "$2" ] && rs=$2 || rs="devfsrules_jail"
+ _me="devfs_mount_jail"
+
+ devfs_init_rulesets
+ if ! devfs_domount "$jdev" $rs ; then
+ warn "$_me: devfs was not mounted on $jdev"
+ return 1
+ fi
+ return 0
+}