--- /dev/null
+/* Suid wrapper for the vserver shell script. This code checks and ensures
+ that it may only be called by /usr/sbin/vsh. All safety checks need to be implemented
+ in vsh */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <errno.h>
+
+typedef enum CREDS { CREDS_OK, CREDS_BAD, CREDS_ERR } creds_t;
+
+/* Ensure that the pid corresponds to the vsh executable, which
+ * transfers users from root to slice context. */
+
+#define VSH_PATH "/usr/sbin/vsh"
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
+creds_t get_pid_creds(int pid) {
+ char exe_link_path[PATH_MAX], exe_path[PATH_MAX];
+ snprintf(exe_link_path,PATH_MAX - 1, "/proc/%d/exe", pid);
+ if (readlink(exe_link_path, exe_path, PATH_MAX-1) == -1)
+ return CREDS_ERR;
+ else if (strncmp(exe_path, VSH_PATH, sizeof(VSH_PATH)) != 0)
+ return CREDS_BAD;
+ else
+ return CREDS_OK;
+}
+
+#define VSERVER_PATH "/usr/sbin/vserver"
+
+int main(int argc, char **argv, char **environment)
+{
+ environment = (char **) NULL;
+
+ int ppid = getppid();
+ creds_t caller_creds;
+
+ if (ppid == -1)
+ goto out_exception;
+
+ caller_creds = get_pid_creds(ppid);
+
+ if (caller_creds == CREDS_BAD) {
+ errno = EPERM;
+ goto out_exception;
+ }
+ else if (caller_creds == CREDS_ERR)
+ goto out_exception;
+
+ if (setuid(geteuid()))
+ goto out_exception;
+
+ system(VSERVER_PATH, argv, environment);
+ return 0;
+
+
+out_exception:
+ printf("%s\n", strerror(errno));
+ return errno;
+}