/* * vexec - Wrapper for command execution in a vserver * * Copyright 2005 Björn Steinbrink * * 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 of the License, 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. */ #include #include #include #include #include #include #define VDIRBASE "/etc/vservers/.defaults/vdirbase/" #define PASSWD "/etc/passwd" #define BASH "/bin/bash" #define VSERVER "/usr/sbin/vserver" #define CMD "exec" #define SU "su" void usage(char *name) { printf("Usage:\n"); printf("%s \n", name); } int main(int argc, char **argv) { struct passwd *host_user, *vserver_user; FILE *vserver_passwd; char *vserver_passwd_path; int len; char **cmd; int i; if (argc < 3) { usage(argv[0]); exit(EXIT_FAILURE); } if ((host_user = getpwuid(getuid())) == NULL) { perror("getpwuid"); exit(EXIT_FAILURE); } len = strlen(VDIRBASE) + strlen(argv[1]) + strlen(PASSWD) + 1; vserver_passwd_path = (char*)malloc(len); strcpy(vserver_passwd_path, VDIRBASE); strcat(vserver_passwd_path, argv[1]); strcat(vserver_passwd_path, PASSWD); if ((vserver_passwd = fopen(vserver_passwd_path, "r")) == NULL) { perror("fopen"); exit(EXIT_FAILURE); } while ((vserver_user = fgetpwent(vserver_passwd)) != NULL) { if (!strcmp(host_user->pw_name, vserver_user->pw_name)) break; } fclose(vserver_passwd); if (!vserver_user) { fprintf(stderr, "No user %s found in vserver %s\n", host_user->pw_name, argv[1]); exit(EXIT_FAILURE); } setuid(0); cmd = (char**)malloc(sizeof(char*) * (argc+4)); cmd[0] = BASH; cmd[1] = VSERVER; cmd[2] = argv[1]; cmd[3] = CMD; cmd[4] = SU; cmd[5] = "-"; cmd[6] = vserver_user->pw_name; for (i = 2; i < argc; i++) { cmd[i+5] = argv[i]; } cmd[i+5] = NULL; execv(cmd[0], cmd); perror("execv"); fprintf(stderr, "Failed...!\n"); exit(EXIT_FAILURE); }