X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fvserver_suid_wrapper.c;fp=src%2Fvserver_suid_wrapper.c;h=f6c63b7c2750a34e8d2ccaac1a2a3976e95783b8;hb=d70f3b771147484708ecf150aebaba61ee65bc9d;hp=0000000000000000000000000000000000000000;hpb=61f3ec29fd733b9add1a2cb562db75058cfe9e27;p=util-vserver-pl.git diff --git a/src/vserver_suid_wrapper.c b/src/vserver_suid_wrapper.c new file mode 100644 index 0000000..f6c63b7 --- /dev/null +++ b/src/vserver_suid_wrapper.c @@ -0,0 +1,63 @@ +/* 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 +#include +#include +#include +#include + +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; +}