| 1 |
#! /bin/bash |
|---|
| 2 |
# $Id$ |
|---|
| 3 |
|
|---|
| 4 |
# Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de> |
|---|
| 5 |
# |
|---|
| 6 |
# This program is free software; you can redistribute it and/or modify |
|---|
| 7 |
# it under the terms of the GNU General Public License as published by |
|---|
| 8 |
# the Free Software Foundation; version 2 of the License. |
|---|
| 9 |
# |
|---|
| 10 |
# This program is distributed in the hope that it will be useful, |
|---|
| 11 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 |
# GNU General Public License for more details. |
|---|
| 14 |
# |
|---|
| 15 |
# You should have received a copy of the GNU General Public License |
|---|
| 16 |
# along with this program; if not, write to the Free Software |
|---|
| 17 |
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|---|
| 18 |
|
|---|
| 19 |
: ${UTIL_VSERVER_VARS:=/usr/lib/util-vserver/util-vserver-vars} |
|---|
| 20 |
test -e "$UTIL_VSERVER_VARS" || { |
|---|
| 21 |
echo $"Can not find util-vserver installation (the file '$UTIL_VSERVER_VARS' would be expected); aborting..." >&2 |
|---|
| 22 |
exit 1 |
|---|
| 23 |
} |
|---|
| 24 |
. "$UTIL_VSERVER_VARS" |
|---|
| 25 |
. "$_LIB_FUNCTIONS" |
|---|
| 26 |
|
|---|
| 27 |
function showHelp() |
|---|
| 28 |
{ |
|---|
| 29 |
echo \ |
|---|
| 30 |
$"Usage: $1 [--cap [!]<cap_name>] [--secure] [--xid <num>] [--disconnect] |
|---|
| 31 |
[--domainname <name>] [--hostname <name>] [--flag <flags>+] |
|---|
| 32 |
[--silent] [--] command arguments ... |
|---|
| 33 |
|
|---|
| 34 |
chcontext allocate a new security context and executes |
|---|
| 35 |
a command in that context. |
|---|
| 36 |
By default, a new/unused context is allocated |
|---|
| 37 |
|
|---|
| 38 |
--cap CAP_NAME |
|---|
| 39 |
Add a capability from the command. This option may be |
|---|
| 40 |
repeated several time. |
|---|
| 41 |
See /usr/include/linux/capability.h |
|---|
| 42 |
In general, this option is used with the --secure option |
|---|
| 43 |
--secure removes most critical capabilities and --cap |
|---|
| 44 |
adds specific ones. |
|---|
| 45 |
|
|---|
| 46 |
--cap !CAP_NAME |
|---|
| 47 |
Remove a capability from the command. This option may be |
|---|
| 48 |
repeated several time. |
|---|
| 49 |
See /usr/include/linux/capability.h |
|---|
| 50 |
|
|---|
| 51 |
--xid num |
|---|
| 52 |
Select the context. On root in context 0 is allowed to |
|---|
| 53 |
select a specific context. |
|---|
| 54 |
Context number 1 is special. It can see all processes |
|---|
| 55 |
in any contexts, but can't kill them though. |
|---|
| 56 |
Option --xid may be repeated several times to specify up to 16 contexts. |
|---|
| 57 |
--disconnect |
|---|
| 58 |
Start the command in background and make the process |
|---|
| 59 |
a child of process 1. |
|---|
| 60 |
--domainname new_domainname |
|---|
| 61 |
Set the domainname (NIS) in the new security context. |
|---|
| 62 |
Use "none" to unset the domain name. |
|---|
| 63 |
--flag |
|---|
| 64 |
Set one flag in the new or current security context. The following |
|---|
| 65 |
flags are supported. The option may be used several time. |
|---|
| 66 |
|
|---|
| 67 |
fakeinit: The new process will believe it is process number 1. |
|---|
| 68 |
Useful to run a real /sbin/init in a vserver. |
|---|
| 69 |
lock: The new process is trapped and can't use chcontext anymore. |
|---|
| 70 |
sched: The new process and its children will share a common |
|---|
| 71 |
execution priority. |
|---|
| 72 |
nproc: Limit the number of process in the vserver according to |
|---|
| 73 |
ulimit setting. Normally, ulimit is a per user thing. |
|---|
| 74 |
With this flag, it becomes a per vserver thing. |
|---|
| 75 |
private: No one can join this security context once created. |
|---|
| 76 |
ulimit: Apply the current ulimit to the whole context |
|---|
| 77 |
--hostname new_hostname |
|---|
| 78 |
Set the hostname in the new security context |
|---|
| 79 |
This is need because if you create a less privileged |
|---|
| 80 |
security context, it may be unable to change its hostname |
|---|
| 81 |
--secure |
|---|
| 82 |
Remove all the capabilities to make a virtual server trustable |
|---|
| 83 |
--silent |
|---|
| 84 |
Do not print the allocated context number. |
|---|
| 85 |
|
|---|
| 86 |
Report bugs to <$PACKAGE_BUGREPORT>." |
|---|
| 87 |
exit $2 |
|---|
| 88 |
} |
|---|
| 89 |
|
|---|
| 90 |
function showVersion() |
|---|
| 91 |
{ |
|---|
| 92 |
echo \ |
|---|
| 93 |
$"chcontext $PACKAGE_VERSION -- allocates/enters a security context |
|---|
| 94 |
This program is part of $PACKAGE_STRING |
|---|
| 95 |
|
|---|
| 96 |
Copyright (C) 2004 Enrico Scholz |
|---|
| 97 |
This program is free software; you may redistribute it under the terms of |
|---|
| 98 |
the GNU General Public License. This program has absolutely no warranty." |
|---|
| 99 |
exit $1 |
|---|
| 100 |
} |
|---|
| 101 |
|
|---|
| 102 |
$_VSERVER_INFO - FEATURE migrate || exec $_CHCONTEXT_COMPAT "$@" |
|---|
| 103 |
|
|---|
| 104 |
tmp=$(getopt -o + --long cap:,ctx:,xid:,disconnect,domainname:,flag:,hostname:,secure,silent,help,version,spaces: -n "$0" -- "$@") || exit 1 |
|---|
| 105 |
eval set -- "$tmp" |
|---|
| 106 |
|
|---|
| 107 |
OPT_CAPS=() |
|---|
| 108 |
OPT_CTX= |
|---|
| 109 |
OPT_DISCONNECT= |
|---|
| 110 |
OPT_FLAGS=() |
|---|
| 111 |
OPT_SECURE= |
|---|
| 112 |
OPT_SILENT= |
|---|
| 113 |
OPT_INITPID= |
|---|
| 114 |
OPT_SPACES=--default |
|---|
| 115 |
|
|---|
| 116 |
while true; do |
|---|
| 117 |
case "$1" in |
|---|
| 118 |
--help) showHelp $0 0;; |
|---|
| 119 |
--version) showVersion 0;; |
|---|
| 120 |
--cap) OPT_CAPS=( "${OPT_CAPS[@]}" "$2" ); shift;; |
|---|
| 121 |
--ctx|--xid) OPT_CTX=$2; shift;; |
|---|
| 122 |
--disconnect) OPT_DISCONNECT=1;; |
|---|
| 123 |
--domainname) OPT_DOMAINNAME=$2; shift;; |
|---|
| 124 |
--hostname) OPT_HOSTNAME=$2; shift;; |
|---|
| 125 |
--flag) |
|---|
| 126 |
test "$2" != "fakeinit" || OPT_INITPID=--initpid |
|---|
| 127 |
OPT_FLAGS=( "${OPT_FLAGS[@]}" "$2" ) |
|---|
| 128 |
shift |
|---|
| 129 |
;; |
|---|
| 130 |
--secure) OPT_SECURE=1;; |
|---|
| 131 |
--silent) OPT_SILENT=1;; |
|---|
| 132 |
--spaces) OPT_SPACES=$2; shift;; |
|---|
| 133 |
--) shift; break;; |
|---|
| 134 |
*) echo $"chcontext: internal error; arg=='$1'" >&2; exit 1;; |
|---|
| 135 |
esac |
|---|
| 136 |
shift |
|---|
| 137 |
done |
|---|
| 138 |
|
|---|
| 139 |
create_cmd=( ${OPT_CTX:+$_VTAG --create --tag "$OPT_CTX" --silentexist --silent --} |
|---|
| 140 |
$_VSPACE --new $OPT_SPACES -- |
|---|
| 141 |
$_VCONTEXT --create --silentexist |
|---|
| 142 |
${OPT_SILENT:+--silent} |
|---|
| 143 |
${OPT_CTX:+--xid "$OPT_CTX"} ) |
|---|
| 144 |
|
|---|
| 145 |
chain_cmd=() |
|---|
| 146 |
|
|---|
| 147 |
old_IFS=$IFS |
|---|
| 148 |
IFS=,$IFS |
|---|
| 149 |
|
|---|
| 150 |
chain_cmd=( "${chain_cmd[@]}" |
|---|
| 151 |
-- |
|---|
| 152 |
$_VSPACE --set $OPT_SPACES ) |
|---|
| 153 |
|
|---|
| 154 |
test -z "$OPT_DOMAINNAME$OPT_HOSTNAME" || \ |
|---|
| 155 |
chain_cmd=( "${chain_cmd[@]}" |
|---|
| 156 |
-- |
|---|
| 157 |
$_VUNAME --set --xid self |
|---|
| 158 |
${OPT_DOMAINNAME:+-t domainname="$OPT_DOMAINNAME"} |
|---|
| 159 |
${OPT_HOSTNAME:+ -t nodename="$OPT_HOSTNAME"} ) |
|---|
| 160 |
|
|---|
| 161 |
chain_cmd=( "${chain_cmd[@]}" |
|---|
| 162 |
-- |
|---|
| 163 |
$_VATTRIBUTE --set |
|---|
| 164 |
${OPT_SECURE:+--secure} |
|---|
| 165 |
${OPT_CAPS:+--bcap "${OPT_CAPS[*]}"} |
|---|
| 166 |
${OPT_FLAGS:+--flag "${OPT_FLAGS[*]}"} ) |
|---|
| 167 |
|
|---|
| 168 |
migrate_cmd=( $_VCONTEXT |
|---|
| 169 |
${OPT_SILENT:+--silent} |
|---|
| 170 |
${OPT_DISCONNECT:+--disconnect} |
|---|
| 171 |
$OPT_INITPID ) |
|---|
| 172 |
|
|---|
| 173 |
IFS=$old_IFS |
|---|
| 174 |
|
|---|
| 175 |
$_VSERVER_INFO -q "$OPT_CTX" XIDTYPE static |
|---|
| 176 |
is_static=$? |
|---|
| 177 |
test -z "$OPT_CTX" |
|---|
| 178 |
is_dynamic=$? |
|---|
| 179 |
|
|---|
| 180 |
if test "$is_dynamic" -eq 0 || test "$is_static" -eq 0; then |
|---|
| 181 |
"${create_cmd[@]}" "${chain_cmd[@]}" -- \ |
|---|
| 182 |
"${migrate_cmd[@]}" --endsetup --migrate-self -- "$@" |
|---|
| 183 |
rc=$? |
|---|
| 184 |
else |
|---|
| 185 |
rc=254 |
|---|
| 186 |
fi |
|---|
| 187 |
|
|---|
| 188 |
if test "$is_static" -eq 0; then |
|---|
| 189 |
migrate_cmd=( $_VTAG --migrate --tag "$OPT_CTX" --silent -- \ |
|---|
| 190 |
$_VSPACE --enter "$OPT_CTX" $OPT_SPACES -- \ |
|---|
| 191 |
"${migrate_cmd[@]}" ) |
|---|
| 192 |
fi |
|---|
| 193 |
|
|---|
| 194 |
|
|---|
| 195 |
test "$rc" -ne 254 || exec "${migrate_cmd[@]}" --xid "$OPT_CTX" --migrate -- \ |
|---|
| 196 |
"$@" |
|---|
| 197 |
exit $rc |
|---|