1 /* Version 2 of vsh. Basically a wrapper around 'vserver <slice name> enter.' */
12 #define VSH_PATH "/usr/sbin/vsh"
17 #define VSERVER_PATH "/usr/sbin/vserver"
19 char* get_current_username (unsigned int uid)
21 struct passwd *passwd_entry;
22 if ((passwd_entry = getpwuid(uid)) == NULL) {
23 fprintf(stderr, "Could not look up user record for %d\n", uid);
27 return (strdup(passwd_entry->pw_name));
30 char **extend_argv(int argc, char **argv, int num_extra_args) {
34 argc2 = argc + num_extra_args;
35 argv2 = (char **) malloc((argc2 + 1) * sizeof(char *));
38 return (char **) NULL;
40 for (i=0; i<argc; i++) {
41 argv2[i+num_extra_args]=strdup(argv[i]);
48 void associate_vserver_cgroup(char *slice_name, int pid)
50 char cgroup_dir[4096], fn[4096];
55 sprintf(cgroup_dir, "/dev/cgroup/%s", slice_name);
57 result = stat(cgroup_dir, &st);
63 if (!S_ISDIR(st.st_mode)) {
68 /* Write the pid to the cgroup tasks file, so the SSH process is associated
69 * with the correct cgroup
72 sprintf(fn, "%s/tasks", cgroup_dir);
79 fprintf(f, "%d\n", pid);
83 #define NUM_VSERVER_EXEC_ARGS 5
85 int main(int argc, char **argv, char **envp)
90 char slice_id_str[256];
91 unsigned int slice_xid;
94 slice_name = get_current_username(slice_xid);
96 fprintf(stderr,"Could not look up slice name\n");
100 associate_vserver_cgroup(slice_name, getpid());
102 argv2 = extend_argv(argc, argv, NUM_VSERVER_EXEC_ARGS);
103 if (!argv2) goto out_exception;
106 // Populate arguments
107 snprintf(slice_id_str, 255, "%u", slice_xid);
108 argv2[0] = strdup(VSERVER_PATH);
109 argv2[1] = strdup(slice_name);
110 argv2[2] = strdup("exec");
111 argv2[3] = strdup("/bin/su");
112 argv2[4] = strdup("-");
113 argv2[5] = strdup(slice_name);
115 if (setuid(geteuid())) goto out_exception;
117 execve(VSERVER_PATH, argv2, envp);
120 printf("%s\n", strerror(errno));