2 * Marc E. Fiuczynski <mef@cs.princeton.edu>
4 * Copyright (c) 2004 The Trustees of Princeton University (Trustees).
6 * vsh is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * vsh is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 * License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Poptop; see the file COPYING. If not, write to the Free
18 * Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 #include <sys/types.h>
30 #define DEFAULT_SHELL "/bin/sh"
32 /* Exit statuses for programs like 'env' that exec other programs.
33 EXIT_FAILURE might not be 1, so use EXIT_FAIL in such programs. */
36 EXIT_CANNOT_INVOKE = 126,
40 extern void slice_enter(char *);
41 extern void runas_slice_user(char *);
43 int main(int argc, char **argv)
45 char *context, *username, *shell;
55 if ((uid = getuid()) < 0) {
56 perror("vsh: getuid error ");
59 if ((pwd = getpwuid(uid)) == NULL) {
60 fprintf(stderr,"vsh: getpwnam error failed for %d\n",uid);
64 context = (char*)strdup(pwd->pw_name);
66 perror("vsh: strdup failed");
70 /* enter vserver "context" */
73 /* Now run as username in this context. Note that for PlanetLab's
74 vserver configuration the context name also happens to be the
75 "default" username within the vserver context.
78 runas_slice_user(username);
80 /* With the uid/gid appropriately set. Let's figure out what the
81 * shell in the vserver's /etc/passwd is for the given username.
83 if ((pwd = getpwnam(username)) == NULL) {
84 fprintf(stderr,"vsh: getpwnam error failed for %s\n",username);
88 /* Make sure pw->pw_shell is non-NULL.*/
89 if (pwd->pw_shell == NULL || pwd->pw_shell[0] == '\0') {
90 pwd->pw_shell = (char *) DEFAULT_SHELL;
93 shell = (char *)strdup(pwd->pw_shell);
95 perror("vsh: strdup failed");
99 /* Check whether 'su' or 'sshd' invoked us as a login shell or
100 not; did this above when testing argv[0]=='-'.
105 args = (char**)malloc(sizeof(char*)*(argc+2));
107 perror("vsh: malloc failed");
111 for(i=1;i<argc+1;i++) {
116 (void) execvp(shell,argv);
118 int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
122 return 0; /* shutup compiler */