--- /dev/null
+.deps
+.dirstamp
--- /dev/null
+.deps
+util-vserver-vars
--- /dev/null
+# $Id$ --*- sh -*--
+
+# Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+function findObject
+{
+ local mod=$1
+ local var=$2
+ local file=
+ local i=X
+ shift 2
+
+ for i; do
+ test "$i" || continue
+ test ! $mod "$i" || { file=$i; break; }
+ done
+
+ test -z "$i" -o "$file" || {
+ echo "Can not find file for '$var'; aborting"
+ exit 1
+ } >&2
+
+ eval "$var=\"$file\""
+}
+
+function findFile
+{
+ findObject -f "$@"
+}
+
+function findDir
+{
+ findObject -d "$@"
+}
+
+function getPhysicalDir
+{
+ ( set -P && cd "$1" && pwd )
+}
+
+function _pkgMountBindDir()
+{
+ test "$1" != "$2" || return 0
+
+ mount -n --bind "$1" "$2"
+}
+
+function _pkgSetVarsBase
+{
+ case "$vserver" in
+ /*)
+ echo "not supported yet"
+ exit 1
+ ;;
+ *)
+ BASEDIR=$CONFDIR/$vserver
+ test -d "$BASEDIR" || {
+ echo "Can not find configuration-directory"
+ exit 1
+ }
+
+ VDIR=$BASEDIR/vdir
+ test -d "$VDIR" || VDIR=/vservers/$vserver
+ VDIR=$(getPhysicalDir "$VDIR")
+
+ PKGDIR=$BASEDIR/apps/pkgmgmt
+ test -d "$PKGDIR" || {
+ echo "Can not find configuration-directory for package-managment tools"
+ exit 1
+ }
+
+ findDir EXECDIR $PKGDIR/execdir /
+
+ ;;
+ esac
+}
+
+function _pkgSetVarsRPM
+{
+ case "$vserver" in
+ /*)
+ echo "not supported yet"
+ exit 1
+ ;;
+
+ *)
+ findDir RPMETCDIR $PKGDIR/rpmetc $PKGDIR/base/rpm/etc /etc/rpm
+ findDir RPMSTATEDIR $PKGDIR/rpmstate $PKGDIR/base/rpm/state
+
+ findDir RPMLIBDIR $PKGDIR/rpmlib /
+
+ RPMSTATEDIR=$(getPhysicalDir "$RPMSTATEDIR")
+ RPMETCDIR=$(getPhysicalDir "$RPMETCDIR")
+ ;;
+ esac
+}
+
+function _pkgSetVarsApt
+{
+ case "$vserver" in
+ /*)
+ echo "not supported yet"
+ exit 1
+ ;;
+
+ *)
+ findDir APTETCDIR $PKGDIR/aptetc $PKGDIR/base/apt/etc /etc/apt
+ findDir APTSTATEDIR $PKGDIR/aptstate $PKGDIR/base/apt/state
+ findDir APTCACHEDIR $PKGDIR/aptcache $PKGDIR/base/apt/cache
+ findDir APTARCHIVDIR $PKGDIR/aptarchives $PKGDIR/base/apt/archives /var/cache/apt/archives
+ ;;
+ esac
+}
+
+function _pkgMountBase
+{
+ :
+}
+
+function _pkgMountApt
+{
+ :
+}
+
+function _pkgMountRPM
+{
+ _pkgMountBindDir "$RPMETCDIR" /etc/rpm
+ test "$RPMLIBDIR" = "/" || _pkgMountBindDir "$RPMLIBDIR" /usr/lib/rpm
+ "$_SECURE_MOUNT" "$VDIR" "$RPMSTATEDIR" /var/lib/rpm
+}
+
+function _pkgSetEnvBase
+{
+ test "$EXECDIR" = "/" || {
+ PATH=$EXECDIR:$PATH
+ LD_LIBRARY_PATH=$EXECDIR${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
+ }
+
+ export PATH LD_LIBRARY_PATH
+}
+
+function _pkgSetEnvApt
+{
+ :
+}
+
+function _pkgSetEnvRPM
+{
+ CUR_VSERVER=$vserver
+ RPM_FAKE_NAMESPACE_MOUNTS=/var/lib/rpm
+ RPM_BINARY=$_VRPM_PRELOAD
+
+ export CUR_VSERVER RPM_FAKE_NAMESPACE_MOUNTS RPM_BINARY
+}
+
+function pkgInit
+{
+ local i
+ local vserver=$1
+ shift
+
+ _pkgSetVarsBase
+ for i; do
+ case "$i" in
+ rpm) _pkgSetVarsRPM;;
+ apt) _pkgSetVarsApt;;
+ *) echo "Unknown packaging flavor"; exit 1;;
+ esac
+ done
+
+ _pkgMountBase
+ for i; do
+ case "$i" in
+ rpm) _pkgMountRPM;;
+ apt) _pkgMountApt;;
+ esac
+ done
+
+ _pkgSetEnvBase
+ for i; do
+ case "$i" in
+ rpm) _pkgSetEnvRPM;;
+ apt) _pkgSetEnvApt;;
+ esac
+ done
+
+ _PKG_FLAVORS="$@"
+ _PKG_VSERVER=$vserver
+}
+
+function getAllVservers
+{
+ local i
+ local var=$1
+
+ for i in $CONFDIR/*; do
+ test -d "$i" || continue
+ test ! -e "$i"/disabled || continue
+ test -d "$i"/vdir || continue
+
+ eval "$var=\"$var ${i##$CONFDIR/}\""
+ done
+}
--- /dev/null
+#! /bin/bash
+
+# Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+: ${UTIL_VSERVER_VARS:=$(dirname $0)/util-vserver-vars}
+test -e "$UTIL_VSERVER_VARS" || {
+ echo "Can not find util-vserver installation; aborting..."
+ exit 1
+}
+. "$UTIL_VSERVER_VARS"
+. "$_LIB_FUNCTIONS"
+
+function showHelp()
+{
+ echo "Usage: $0 <vserver-name>* [--all] -- <params>+"
+ exit $1
+}
+
+function showVersion()
+{
+ cat <<EOF
+vapt-get 0.23.5 -- apt-get for vservers
+Copyright (C) 2003 Enrico Scholz
+This program is free software; you may redistribute it under the terms of
+the GNU General Public License. This program has absolutely no warranty.
+EOF
+ exit $1
+}
+
+vservers=
+
+while test "$#" -ge 1; do
+ case "$1" in
+ --all)
+ getAllVservers tmp
+ vservers="$vservers $tmp";;
+ --)
+ shift; break;;
+ --help)
+ showHelp 0;;
+ --version)
+ showVersion 0;;
+ *) vservers="$vservers $1";;
+ esac
+ shift
+done
+
+test "$#" -ge 1 || showHelp 1 >&2
+
+cnt=0
+res=255
+for i in $vservers; do
+ cnt=$[ cnt + 1 ]
+ _APT_GET=apt-get \
+ "$_NEW_NAMESPACE" "$_VAPT_GET_WORKER" "$i" "$@"
+ res=$?
+done
+
+test "$cnt" -ge 0 || echo "No vservers specified" >&2
+exit $res
\ No newline at end of file
--- /dev/null
+#! /bin/bash -e
+# $Id$
+
+# Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+: ${UTIL_VSERVER_VARS:=$(dirname $0)/util-vserver-vars}
+test -e "$UTIL_VSERVER_VARS" || {
+ echo "Can not find util-vserver installation; aborting..."
+ exit 1
+}
+. "$UTIL_VSERVER_VARS"
+. "$_LIB_FUNCTIONS"
+
+
+function createAptFileSys()
+{
+ mkdir -p /var/state/apt/lists/partial
+ mkdir -p /var/cache/apt/archives/partial
+}
+
+vserver="$1"
+shift
+
+pkgInit "$vserver" rpm apt
+
+createAptFileSys
+
+$_APT_GET -o "RPM::RootDir=$VDIR" \
+ -o "Dir=$VDIR" \
+ -o "Dir::State=$APTSTATEDIR" \
+ -o "Dir::Cache=$APTCACHEDIR" \
+ -o "Dir::Cache::archives=$APTARCHIVDIR" \
+ -o "Dir::Bin::rpm=$RPM_BINARY" \
+ -o "Dir::Etc=$APTETCDIR" \
+ -o "RPM::Order=true" \
+ "$@"
+
+export PS1='@@ '
+exec bash
--- /dev/null
+#! /bin/bash -x
+
+: ${UTIL_VSERVER_VARS:=$(dirname $0)/util-vserver-vars}
+test -e "$UTIL_VSERVER_VARS" || {
+ echo "Can not find util-vserver installation; aborting..."
+ exit 1
+}
+. "$UTIL_VSERVER_VARS"
+
+lib=$_RPM_FAKE_SO
+
+function getSyscallParams
+{
+ set -- `grep '^__NR_new_s_context:' /proc/self/status`
+ scall_nr=$2
+ test "$3" && scall_rev=${3##rev}
+}
+
+need_cfg=
+case "$CUR_VSERVER" in
+ /*) vdir=$CUR_VSERVER;;
+ *) vdir=$CONFDIR/$CUR_VSERVER/vdir
+ need_cfg=1;;
+esac
+
+test "$CUR_VSERVER" -a -d "$vdir" || {
+ echo "No or invalid vserver-name given"
+ exit 1
+}
+
+ctxfile=/var/run/vservers/${CUR_VSERVER}.ctx
+if test -f "$ctxfile"; then
+ . "$ctxfile"
+else
+ S_CONTEXT=
+fi
+
+for bin in `which rpm` /bin/rpm /usr/lib/rpm/rpmi ""; do
+ ldd "$bin" &>/dev/null && break
+done
+
+test "$bin" || {
+ echo "No dynamically linked rpm binary found; exiting..."
+ exit 1
+}
+
+
+getSyscallParams
+
+RPM_FAKE_S_CONTEXT_REV=$scall_rev \
+RPM_FAKE_S_CONTEXT_NR=$scall_nr \
+RPM_FAKE_CTX=$S_CONTEXT \
+RPM_FAKE_CAP=$[ ~0x3404040f ] \
+LD_PRELOAD=$lib${LD_PRELOAD:+:$LD_PRELOAD} \
+exec $bin "$@"
--- /dev/null
+#! /bin/bash -e
+# $Id$
+
+# Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+set -x
+
+: ${UTIL_VSERVER_VARS:=$(dirname $0)/util-vserver-vars}
+test -e "$UTIL_VSERVER_VARS" || {
+ echo "Can not find util-vserver installation; aborting..."
+ exit 1
+}
+. "$UTIL_VSERVER_VARS"
+. "$_LIB_FUNCTIONS"
+
+vserver=$1
+shift
+
+pkgInit "$vserver" rpm
+
+exec $RPM_BINARY --root "$VDIR" "$@"
\ No newline at end of file
--- /dev/null
+#! /bin/bash -e
+
+# Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+: ${UTIL_VSERVER_VARS:=$(dirname $0)/util-vserver-vars}
+test -e "$UTIL_VSERVER_VARS" || {
+ echo "Can not find util-vserver installation; aborting..."
+ exit 1
+}
+. "$UTIL_VSERVER_VARS"
+. "$PKGLIBDIR/functions"
+
+tmp=$(getopt -o d:r: --long force,dir:,pkgcfg:,hostname:,iproot:,iprootmask:,iprootbcast:,iprootdev:,help,version \
+ -n "$0" -- "$@") || exit 1
+
+eval set -- "$tmp"
+
+distrib=
+root=/vservers
+dir=
+name=
+hostname=
+iproot=
+iprootmask=
+iprootbcast=
+iprootdev=
+force=
+pkgcfg=
+
+
+function makeInode
+{
+ mknod -m$6 $1/$2 $3 $4 $5
+}
+
+function installBasePackages
+{
+ local name="$1"
+ local dir="$2"
+
+ test "$dir" != / || return
+ for filelist in "$dir"/*; do
+ test -e "$filelist" || continue
+ local idx=0
+ local can_fail=false
+ local flags=
+
+ set -- $(<$filelist)
+ while test "$#" -gt 0; do
+ case "$1" in
+ --reinstall) flags='--reinstall';;
+ --can-fail) can_fail=true;;
+ *) break;;
+ esac
+ shift
+ done
+ "$_VAPT_GET" "$name" -- install $flags "$@" || $can_fail
+ done
+}
+
+while true; do
+ case "$1" in
+ -d) distrib="$2"; shift 2;;
+ -r) root="$2"; shift 2;;
+ --pkgcfg) pkgcfg="$2"; shift 2;;
+ --force) force=1; shift;;
+ --dir) dir="$2"; shift 2;;
+ --hostname) hostname="$2"; shift 2;;
+ --iproot) iproot="$2"; shift 2;;
+ --iprootmask) iprootmask="$2"; shift 2;;
+ --iprootbcast) iprootbcast="$2"; shift 2;;
+ --iprootdev) iprootdev="$2"; shift 2;;
+ --help) showHelp; exit 0;;
+ --version) showVersion; exit 0;;
+ --) shift; break;;
+ *) echo "Internal error!"; exit 1;;
+ esac
+done
+
+test "$#" != 0 || {
+ echo "No vserver name given" >&2
+ exit 1
+}
+
+test "$#" = 1 || {
+ echo "Too much parameters" >&2
+ exit 1
+}
+
+name=$1
+test "$dir" || dir=$name
+test "$pkgcfg" || pkgcfg=$root/.pkg/$name
+
+vdir=$root/$dir
+test ! -d "$vdir" || {
+ test "$force" && mv "$vdir" "$vdir".bak
+}
+
+confdir="$CONFDIR/$name"
+test ! -d "$confdir" || {
+ test "$force" && mv "$confdir" "$confdir".bak
+}
+
+test ! -d "$vdir" -a ! -d "$confdir" || {
+ echo "vserver-topdirectory and/or configuration exist already; "
+ echo "please try to use '--force', or remove them manually"
+ exit 1
+} >&2
+
+test "$distrib" || {
+ if test -e /etc/redhat-release; then
+ set -- $(cat /etc/redhat-release)
+ distrib=rh$5
+ else
+ echo "Can not determine distribution; please specify it manually"
+ echo "with the '-d' option"
+ exit 1
+ fi >&2
+}
+
+findFile INITPRE $CONFDIR/.distributions/$distrib/initpre $DISTRIBDIR/$distrib/initpre ""
+findFile INITPOST $CONFDIR/.distributions/$distrib/initpost $DISTRIBDIR/$distrib/initpost ""
+findFile DEVDESCR $CONFDIR/.distributions/$distrib/devs $DISTRIBDIR/$distrib/devs $DISTRIBDIR/defaults/devs
+findDir APTTMPL $CONFDIR/.distributions/$distrib/apt $DISTRIBDIR/$distrib/apt
+findDir RPMTMPL $CONFDIR/.distributions/$distrib/rpm $DISTRIBDIR/$distrib/rpm $DISTRIBDIR/defaults/rpm
+findDir EXECDIR $CONFDIR/.distributions/$distrib/execdir $DISTRIBDIR/$distrib/execdir /
+findDir RPMLIB $CONFDIR/.distributions/$distrib/rpmlib $DISTRIBDIR/$distrib/rpmlib /
+findDir PKGDIR $CONFDIR/.distributions/$distrib/pkgs $DISTRIBDIR/$distrib/pkgs /
+
+mkdir -p "$confdir"/apps/pkgmgmt "$vdir"/{dev,/var/lib/rpm,/etc} \
+ "$pkgcfg"/{rpm/{etc,state},apt/{etc,archives/partial,cache,state/lists/partial}}
+
+while read spec; do
+ makeInode "$vdir"/dev $spec
+done <$DEVDESCR
+
+ln -s "$vdir" "$confdir"/vdir
+for i in hostname iproot iprootmask iprootbcast iprootdev; do
+ i_=\$$i
+ eval "v=$i_"
+ test -z "$v" || echo $v >"$confdir/$i"
+done
+
+ln -s "$pkgcfg" "$confdir/apps/pkgmgmt/base"
+test "$EXECDIR" = / || ln -s "$EXECDIR" "$confdir/apps/pkgmgmt/execdir"
+test "$RPMLIB" = / || ln -s "$RPMLIB" "$confdir/apps/pkgmgmt/rpmlib"
+
+cp -a "$RPMTMPL/"* "$pkgcfg/rpm/etc/"
+cp -a "$APTTMPL/"* "$pkgcfg/apt/etc/"
+
+
+test -z "$INITPRE" || "$INITPRE" "$name"
+"$_VAPT_GET" "$name" -- update
+installBasePackages "$name" "$PKGDIR"
+"$_VAPT_GET" "$name" -- dist-upgrade
+test -z "$INITPOST" || "$INITPOST" "$name"
--- /dev/null
+.deps
+.dirstamp
+capchroot
+chbind
+chcontext
+fakerunlevel
+filetime
+ifspec
+listdevip
+new-namespace
+parserpmdump
+readlink
+rebootmgr
+reducecap
+secure-mount
+setctxlimit
+showattr
+showperm
+vbuild
+vcheck
+vdu
+vfiles
+vreboot
+vserver-stat
+vunify
--- /dev/null
+// $Id$ --*- c++ -*--
+
+// Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// Executes a program in a new namespace
+// Based on http://www.win.tue.nl/~aeb/linux/lk/lk-6.html
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "util.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sched.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sched.h>
+
+#ifndef CLONE_NEWNS
+# define CLONE_NEWNS 0x00020000
+#endif
+
+static int
+childFunc(void *argv_v)
+{
+ char ** argv = argv_v;
+
+ execvp(argv[0], argv);
+ perror("execvp()");
+ exit(255);
+}
+
+static void
+usage(int fd, char const *cmd, int exit_code)
+{
+ WRITE_MSG(fd, "Usage: ");
+ WRITE_STR(fd, cmd);
+ WRITE_MSG(fd,
+ " [--help] [--version] <cmd> <args*>\n"
+ "\n"
+ "Executes <cmd> in a new namespace.\n"
+ "\n"
+ "Report bugs to " PACKAGE_BUGREPORT "\n");
+
+ exit(exit_code);
+}
+
+static void
+showVersion()
+{
+ WRITE_MSG(1,
+ "new-namespace 0.1\n"
+ "Copyright (C) 2003 Enrico Scholz\n"
+ VERSION_COPYRIGHT_DISCLAIMER);
+ exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+ char buf[128];
+ int status;
+ pid_t pid, p;
+
+ if (argc==1) usage(2, argv[0], 255);
+ if (!strcmp(argv[1], "--help")) usage(1, argv[0], 0);
+ if (!strcmp(argv[1], "--version")) showVersion();
+ if (!strcmp(argv[1], "--")) ++argv;
+
+ pid = clone(childFunc, buf+sizeof(buf)/2, CLONE_NEWNS|CLONE_VFORK|SIGCHLD, argv+1);
+ if (pid==-1) {
+ perror("clone()");
+ exit(255);
+ }
+
+ p = wait4(pid, &status, 0,0);
+ if (p==-1) {
+ perror("waitpid()");
+ exit(255);
+ }
+
+ if (WIFEXITED(status)) return WEXITSTATUS(status);
+ else return 255;
+}
--- /dev/null
+// $Id$ --*- c++ -*--
+
+// Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <asm/unistd.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <sys/mount.h>
+#include <linux/fs.h>
+#include <sched.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#define LIBNAME "rpm-fake.so"
+#define PLATFORM_FILE "/etc/rpm/platform"
+
+#define INIT(FILE,FUNC) FUNC##_func = dlsym(FILE, #FUNC)
+#define DECLARE(FUNC) static __typeof__(FUNC) * FUNC##_func = 0
+
+static bool is_initialized = false;
+DECLARE(execv);
+ //DECLARE(open);
+
+static int def_NR_new_s_context = 259;
+#undef __NR_new_s_context
+static int __NR_new_s_context_rev0;
+static int __NR_new_s_context_rev1;
+
+static int new_s_context_rev0(int, int, int);
+static int new_s_context_rev1(int, int *, int, int);
+
+_syscall3(int, new_s_context_rev0, int, newctx, int, remove_cap, int, flags)
+_syscall4(int, new_s_context_rev1, int, nbctx, int *, ctxs, int, remove_cap, int, flags)
+
+static int
+new_s_context(int rev,
+ int nbctx, int *ctxs, int remove_cap, int flags)
+{
+ int ret;
+
+ switch (rev) {
+ case 0 :
+ {
+ int ctx;
+
+ switch (nbctx) {
+ case 0 : ctx = -1; break;
+ case 1 : ctx = ctxs[0]; break;
+ default : errno = EINVAL; return -1;
+ }
+
+ ret = new_s_context_rev0(ctx, remove_cap, flags);
+
+ break;
+ }
+
+ case 1 :
+ ret = new_s_context_rev1(nbctx, ctxs, remove_cap, flags);
+ break;
+
+ default :
+ errno = EINVAL; return -1;
+ }
+
+ return ret;
+}
+
+static void
+initVserverSyscalls(int s_context_NR)
+{
+ int nr = (s_context_NR!=-1) ? s_context_NR : def_NR_new_s_context;
+
+ __NR_new_s_context_rev0 = __NR_new_s_context_rev1 = nr;
+}
+
+static int
+getAndClearEnv(char const *key, int dflt)
+{
+ char *env = getenv(key);
+ int res;
+
+ if (env==0 || env[0]=='\0') res = dflt;
+ else {
+ res = atoi(env);
+ unsetenv(key);
+ }
+
+ return res;
+}
+
+static void
+initLib()
+{
+ if (is_initialized) return;
+
+ initVserverSyscalls(getAndClearEnv("RPM_FAKE_S_CONTEXT_NR", -1));
+ INIT(RTLD_NEXT, execv);
+ //INIT(RTLD_NEXT, open);
+
+ is_initialized = true;
+}
+
+static void
+fixPreloadEnv()
+{
+ char *env = getenv("LD_PRELOAD");
+ char *pos;
+
+ // the const <-> non-const assignment is not an issue since the following modifying operations
+ // will not be executed in the const-case
+ env = env ? env : "";
+ pos = strstr(env, LIBNAME);
+
+ if (pos!=0) {
+ char *end_pos = pos + sizeof(LIBNAME);
+ bool is_end = (end_pos[-1]=='\0');
+ char *start_pos;
+
+ end_pos[-1] = '\0';
+ start_pos = strrchr(env, ':');
+ if (start_pos==0) start_pos = env;
+ else if (!is_end) ++start_pos;
+
+ if (is_end) *start_pos = '\0';
+ else memmove(start_pos, end_pos, strlen(end_pos)+1);
+ }
+
+#ifdef DEBUG
+ printf("env='%s'\n", env);
+#endif
+
+ if (*env=='\0') unsetenv("LD_PRELOAD");
+}
+
+static int
+execvWorker(char const *path, char * const argv[])
+{
+ int res;
+ int ctx;
+
+ printf("+execvWorker\n");
+ ctx = getAndClearEnv("RPM_FAKE_CTX", -1);
+ if ( (res=new_s_context(getAndClearEnv("RPM_FAKE_S_CONTEXT_REV", 0),
+ ctx==-1 ? 0 : 1,
+ &ctx,
+ getAndClearEnv("RPM_FAKE_CAP", ~0x3404040f),
+ getAndClearEnv("RPM_FAKE_FLAGS", 0)))!=-1 &&
+ (res=execv_func(path, argv)!=-1) ) {}
+ printf("-execvWorker -> res=%u, err=%s\n",res,strerror(errno));
+
+ return res;
+}
+
+struct ExecvParams
+{
+ char const * path;
+ char * const * argv;
+ char const * mnts;
+};
+
+static int
+removeNamespaceMountsChild(void *params_v)
+{
+ struct ExecvParams * params = params_v;
+ char buf[strlen(params->mnts)+1], *ptr;
+
+ strcpy(buf, params->mnts);
+ ptr = strtok(buf, ":");
+ while (ptr) {
+ system("cat /proc/mounts");
+ system("pstree -h");
+ system("ls -l /proc/self/ /proc/self/fd/ /var/lib /var/lib/rpm/");
+ if (umount2(ptr, 0)==-1) { dprintf(2, "ptr='%s' -> ", ptr); perror("umount2()"); return -1; }
+ ptr = strtok(0, ":");
+ }
+
+ unsetenv("RPM_FAKE_NAMESPACE_MOUNTS");
+ return execvWorker(params->path, params->argv);
+}
+
+static int
+removeNamespaceMounts(char const *path, char * const argv[])
+{
+ char const * mnts = getenv("RPM_FAKE_NAMESPACE_MOUNTS");
+
+ printf("mnts='%s'\n", mnts);
+ if (mnts==0) return execvWorker(path, argv);
+
+ {
+ printf("l=%u\n", __LINE__);
+ char buf[512 + 2*strlen(mnts)];
+ int status;
+ pid_t p;
+ struct ExecvParams params = {
+ .path = path,
+ .argv = argv,
+ .mnts = mnts,
+ };
+
+ printf("l=%u\n", __LINE__);
+
+
+ system("mount -t proc none /proc");
+ system("cat /proc/mounts");
+ //system("pstree -h");
+ system("ls -l /proc/self/ /proc/self/fd/ /var/lib /var/lib/rpm/");
+ pid_t pid = clone(removeNamespaceMountsChild, buf+sizeof(buf)/2,
+ CLONE_NEWNS|SIGCHLD|CLONE_VFORK, ¶ms);
+
+ printf("l=%u\n", __LINE__);
+ if (pid==-1) return -1;
+ while ((p=waitpid(pid, &status, 0))==-1 &&
+ (errno==EINTR || errno==EAGAIN)) ;
+ if (p==-1) return -1;
+
+ printf("removeNamespaceMountsChild() -> status=%u\n", status);
+
+ if (WIFEXITED(status)) exit(WEXITSTATUS(status));
+ if (WIFSIGNALED(status)) kill(getpid(), WTERMSIG(status));
+
+ return -1;
+ }
+}
+
+int
+execv(char const *path, char * const argv[]) __THROW
+{
+ initLib();
+ fixPreloadEnv();
+ return removeNamespaceMounts(path, argv);
+}
--- /dev/null
+// $Id$ --*- c++ -*--
+
+// Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+ // secure-mount <chroot-base> <src> <dst>
+ //
+ // mounts <src> into the chroot <chroot-base> at destination <dst> in a way
+ // that prevents symlink attacks
+
+ // algorithm:
+ // enter chroot
+ // mount tmpfs-directory
+ // leave chroot
+ // mount --bind <src> tmpfs
+ // enter chroot
+ // mount --move tmpfs <dst>
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define VERSION_COPYRIGHT_YEAR "2003"
+#define VERSION_COPYRIGHT_AUTHOR "Enrico Scholz"
+#include "util.h"
+
+#include <unistd.h>
+#include <sys/mount.h>
+#include <linux/fs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#define MNTPOINT "/etc"
+
+static void
+showHelp(int fd, char const *cmd, int res)
+{
+ WRITE_MSG(fd, "Usage: ");
+ WRITE_STR(fd, cmd);
+ WRITE_MSG(fd,
+ " <chroot-base> <src> <dst>\n\n"
+ "Please report bugs to " PACKAGE_BUGREPORT "\n");
+
+ exit(res);
+}
+
+static void
+showVersion()
+{
+ WRITE_MSG(1,
+ "secure-mount 0.23.5\n"
+ "Copyright (C) 2003 Enrico Scholz\n"
+ VERSION_COPYRIGHT_DISCLAIMER);
+ exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+ int fd = open("/", O_RDONLY);
+ // HACK: sanity checks should be done before declaration, but this does
+ // not work with C89 compilers
+ char path[strlen(argc==1 ? "" : argv[1]) + sizeof(MNTPOINT) + 3];
+
+ if (argc>=2) {
+ if (!strcmp(argv[1], "--help")) showHelp(1, argv[0], 0);
+ if (!strcmp(argv[1], "--version")) showVersion();
+ }
+ if (argc!=4) {
+ WRITE_MSG(2, "Bad parameter count; use --help for further information.\n");
+ exit(255);
+ }
+
+ if (chroot(argv[1]) == -1 ||
+ chdir("/") == -1) {
+ perror("chroot()/chdir()");
+ exit(1);
+ }
+
+ if (mount("none", MNTPOINT, "tmpfs", 0, "size=4k")==-1) {
+ perror("mount()");
+ exit(1);
+ }
+
+ if (mkdir(MNTPOINT "/x",0600) == -1) {
+ perror("mkdir()/fchdir()");
+ goto err1;
+ }
+
+ if (fchdir(fd) == -1 ||
+ chroot(".") == -1) {
+ perror("chroot()");
+ goto err2;
+ }
+
+ strcpy(path, argv[1]);
+ strcat(path, MNTPOINT "/x");
+
+ if (mount(argv[2], path, "", MS_BIND, 0)==-1) {
+ perror("mount()");
+ goto err3;
+ }
+
+ if (chroot(argv[1]) == -1) {
+ perror("chroot()");
+ goto err4;
+ }
+
+ if (chdir("/") == -1 ||
+ mount(MNTPOINT "/x", argv[3], "", MS_MOVE, 0) == -1) {
+ perror("chdir()/mount()");
+ goto err5;
+ }
+
+ if (umount(MNTPOINT) == -1) {
+ perror("umount()");
+ }
+
+ return 0;
+
+ err5:
+ err4:
+ if (umount(path)==-1) perror("umount(path)");
+
+ err3:
+ if (chdir(argv[1])==-1) {
+ perror("chdir()");
+ return 1;
+ }
+
+ err2:
+ err1:
+ if (umount("mnt")==-1) perror("umount(\"mnt\")");
+
+ return 1;
+}
--- /dev/null
+// $Id$ --*- c++ -*--
+
+// Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifndef H_UTIL_VSERVER_SRC_UTIL_H
+#define H_UTIL_VSERVER_SRC_UTIL_H
+
+#include <unistd.h>
+#include <string.h>
+
+#ifndef PACKAGE_BUGREPORT
+# define PACKAGE_BUGREPORT "???"
+#endif
+
+#ifndef VERSION_COPYRIGHT_DISCLAIMER
+# define VERSION_COPYRIGHT_DISCLAIMER \
+ "This program is free software; you may redistribute it under the terms of\n" \
+ "the GNU General Public License. This program has absolutely no warranty.\n"
+#endif
+
+inline static void
+writeStr(int fd, char const *cmd)
+{
+ (void)write(fd, cmd, strlen(cmd));
+}
+
+#define WRITE_MSG(FD,X) (void)(write(FD,X,sizeof(X)))
+#define WRITE_STR(FD,X) writeStr(FD,X)
+
+#endif // H_UTIL_VSERVER_SRC_UTIL_H
--- /dev/null
+rebootmgr
+v_gated
+v_httpd
+v_named
+v_portmap
+v_sendmail
+v_smb
+v_sshd
+v_xinetd
+vservers
--- /dev/null
+.deps
+.dirstamp
+chrootsafe
+escaperoot
+forkbomb
+testipc
+testlimit
+testopenf