#! /bin/sh /usr/share/dpatch/dpatch-run
## 07_vcontext-uid.dpatch by Micah Anderson <Micah Anderson <micah@debian.org>>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: No description.

@DPATCH@
diff -urNad trunk~/ensc_wrappers/wrappers-unistd.hc trunk/ensc_wrappers/wrappers-unistd.hc
--- trunk~/ensc_wrappers/wrappers-unistd.hc	2006-03-20 08:16:47.000000000 -0500
+++ trunk/ensc_wrappers/wrappers-unistd.hc	2006-04-12 15:31:56.000000000 -0400
@@ -156,6 +156,12 @@
 {
   FatalErrnoError(setgroups(size, list)==-1, "setgroups()");
 }
+
+inline static void
+Einitgroups(const char *user, gid_t group)
+{
+  FatalErrnoError(initgroups(user, group)==-1, "initgroups()");
+}
 #endif
 
 inline static WRAPPER_DECL int
diff -urNad trunk~/scripts/vserver trunk/scripts/vserver
--- trunk~/scripts/vserver	2006-03-20 08:16:45.000000000 -0500
+++ trunk/scripts/vserver	2006-04-12 15:31:56.000000000 -0400
@@ -212,15 +212,15 @@
 	;;
     (exec)
 	shift 2
-	suexec root "$@"
+	suexec 0 "$@"
 	;;
     (chkconfig)
 	shift 2
-	suexec root chkconfig "$@"
+	suexec 0 chkconfig "$@"
 	;;
     (enter)
 	getEnterShell "$VSERVER_DIR"
-	suexec root "${ENTER_SHELL[@]}"
+	suexec 0 "${ENTER_SHELL[@]}"
 	;;
     (running)
 	isVserverRunning "$VSERVER_DIR"
diff -urNad trunk~/src/vcontext.c trunk/src/vcontext.c
--- trunk~/src/vcontext.c	2006-03-20 08:16:45.000000000 -0500
+++ trunk/src/vcontext.c	2006-04-12 15:31:56.000000000 -0400
@@ -1,6 +1,6 @@
 // $Id: vcontext.c,v 1.18 2005/04/28 18:08:12 ensc Exp $    --*- c -*--
 
-// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+// Copyright (C) 2004-2006 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
@@ -33,6 +33,9 @@
 #include <sys/un.h>
 #include <assert.h>
 #include <signal.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
 
 #include <linux/personality.h>
 
@@ -104,7 +107,7 @@
     uint_least32_t	personality_type;
     int			verbosity;
     bool		do_chroot;
-    uid_t		uid;
+    char const *	uid;
     xid_t		xid;
     char const *	sync_sock;
     char const *	sync_msg;
@@ -159,7 +162,7 @@
   WRITE_MSG(1,
 	    "vcontext " VERSION " -- manages the creation of security contexts\n"
 	    "This program is part of " PACKAGE_STRING "\n\n"
-	    "Copyright (C) 2004 Enrico Scholz\n"
+	    "Copyright (C) 2004-2006 Enrico Scholz\n"
 	    VERSION_COPYRIGHT_DISCLAIMER);
   exit(0);
 }
@@ -275,9 +278,35 @@
     if (args->do_migrate && !args->do_migrateself)
       Evc_ctx_migrate(xid);
 
-    if (args->uid!=(uid_t)(-1) && getuid()!=args->uid) {
-      Esetuid(args->uid);
-      if (getuid()!=args->uid) {
+    if (args->uid != NULL) {
+      uid_t uid = 0;
+      unsigned long tmp;
+
+      if (!isNumberUnsigned(args->uid, &tmp, false)) {
+#ifdef __dietlibc__
+	struct passwd *pw;
+	pw = getpwnam(args->uid);
+	if (pw == NULL) {
+	  WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "Username '");
+	  WRITE_STR(2, args->uid);
+	  WRITE_MSG(2, "' does not exist\n");
+	  return wrapper_exit_code;
+	}
+	uid = pw->pw_uid;
+	Einitgroups(args->uid, pw->pw_gid);
+	Esetgid(pw->pw_gid);
+#else
+	WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "Uid '");
+	WRITE_STR(2, args->uid);
+	WRITE_MSG(2, "' is not a number\n");
+	return wrapper_exit_code;
+#endif
+      }
+      else
+	uid = (uid_t) tmp;
+
+      Esetuid((uid_t) uid);
+      if (getuid()!=uid) {
 	WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "Something went wrong while changing the UID\n");
 	exit(wrapper_exit_code);
       }
@@ -345,7 +374,7 @@
     .is_silentexist    = false,
     .set_namespace     = false,
     .verbosity         = 1,
-    .uid               = -1,
+    .uid               = NULL,
     .xid               = VC_DYNAMIC_XID,
     .personality_type  = VC_BAD_PERSONALITY,
     .personality_flags = 0,
@@ -369,7 +398,7 @@
       case CMD_SILENTEXIST	:  args.is_silentexist = true;   break;
       case CMD_SYNCSOCK		:  args.sync_sock      = optarg; break;
       case CMD_SYNCMSG		:  args.sync_msg       = optarg; break;
-      case CMD_UID		:  args.uid = atol(optarg);      break;
+      case CMD_UID		:  args.uid            = optarg; break;
       case CMD_XID		:  args.xid = Evc_xidopt2xid(optarg,true); break;
       case CMD_SILENT		:  --args.verbosity; break;
       case CMD_PERSTYPE		:
