-#include <sys/resource.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <stdarg.h>
-
-//--------------------------------------------------------------------
-#include <vserver.h>
-#include "planetlab.h"
-
-/* Change to root:root (before entering new context) */
-static int setuidgid_root()
-{
- if (setgid(0) < 0) {
- PERROR("setgid(0)");
- return -1;
- }
- if (setuid(0) < 0) {
- PERROR("setuid(0)");
- return -1;
- }
- return 0;
-}
-
-static void compute_new_root(char *base, char **root, const struct passwd *pwd)
-{
- int root_len;
-
- root_len =
- strlen(base) + strlen("/") +
- strlen(pwd->pw_name) + NULLBYTE_SIZE;
- (*root) = (char *)malloc(root_len);
- if ((*root) == NULL) {
- PERROR("malloc(%d)", root_len);
- exit(1);
- }
-
- sprintf((*root), "%s/%s", base, pwd->pw_name);
- (*root)[root_len - 1] = '\0';
-}
-
-static int sandbox_chroot(const struct passwd *pwd)
-{
- char *sandbox_root = NULL;
-
- compute_new_root(DEFAULT_VSERVERDIR,&sandbox_root, pwd);
- if (chroot(sandbox_root) < 0) {
- PERROR("chroot(%s)", sandbox_root);
- exit(1);
- }
- if (chdir("/") < 0) {
- PERROR("chdir(/)");
- exit(1);
- }
- return 0;
-}
-
-static int sandbox_processes(xid_t ctx, const char *context, const struct passwd *pwd)
-{
-#ifdef CONFIG_VSERVER_LEGACY
- int flags;
-
- flags = 0;
- flags |= 1; /* VX_INFO_LOCK -- cannot request a new vx_id */
- /* flags |= 4; VX_INFO_NPROC -- limit number of procs in a context */
-
- (void) vc_new_s_context(ctx, 0, flags);
-
- /* use legacy dirty hack for capremove */
- if (vc_new_s_context(VC_SAMECTX, vc_get_insecurebcaps(), flags) == VC_NOCTX) {
- PERROR("vc_new_s_context(%u, 0x%16llx, 0x%08x)",
- VC_SAMECTX, vc_get_insecurebcaps(), flags);
- exit(1);
- }
-#else
- int ctx_is_new;
- struct sliver_resources slr;
- char hostname[HOST_NAME_MAX+1];
- pl_get_limits(context,&slr);
-
- if (gethostname(hostname, sizeof hostname) == -1)
- {
- PERROR("gethostname(...)");
- exit(1);
- }
-
- /* check whether the slice has been suspended */
- if (slr.vs_cpu==0)
- {
- fprintf(stderr, "*** %s: %s has zero cpu resources and presumably it has been disabled/suspended ***\n", hostname, context);
- exit(0);
- }
-
- (void) (sandbox_chroot(pwd));
-
- if ((ctx_is_new = pl_chcontext(ctx, ~vc_get_insecurebcaps(),&slr)) < 0)
- {
- PERROR("pl_chcontext(%u)", ctx);
- exit(1);
- }
- if (ctx_is_new)
- {
- fprintf(stderr, " *** %s: %s has not been started yet, please check back later ***\n", hostname, context);
- exit(1);
- }
-#endif
- return 0;
-}
-
-
-void runas_slice_user(struct passwd *pwd)
-{
- char *username = pwd->pw_name;
- char *home_env, *logname_env, *mail_env, *shell_env, *user_env;
- int home_len, logname_len, mail_len, shell_len, user_len;
- static char *envp[10];
-
- if (setgid(pwd->pw_gid) < 0) {
- PERROR("setgid(%d)", pwd->pw_gid);
- exit(1);
- }
-
- if (setuid(pwd->pw_uid) < 0) {
- PERROR("setuid(%d)", pwd->pw_uid);
- exit(1);
- }
-
- if (chdir(pwd->pw_dir) < 0) {
- PERROR("chdir(%s)", pwd->pw_dir);
- exit(1);
- }
-
- home_len = strlen("HOME=") + strlen(pwd->pw_dir) + NULLBYTE_SIZE;
- logname_len = strlen("LOGNAME=") + strlen(username) + NULLBYTE_SIZE;
- mail_len = strlen("MAIL=/var/spool/mail/") + strlen(username)
- + NULLBYTE_SIZE;
- shell_len = strlen("SHELL=") + strlen(pwd->pw_shell) + NULLBYTE_SIZE;
- user_len = strlen("USER=") + strlen(username) + NULLBYTE_SIZE;
-
- home_env = (char *)malloc(home_len);
- logname_env = (char *)malloc(logname_len);
- mail_env = (char *)malloc(mail_len);
- shell_env = (char *)malloc(shell_len);
- user_env = (char *)malloc(user_len);
-
- if ((home_env == NULL) ||
- (logname_env == NULL) ||
- (mail_env == NULL) ||
- (shell_env == NULL) ||
- (user_env == NULL)) {
- PERROR("malloc");
- exit(1);
- }
-
- sprintf(home_env, "HOME=%s", pwd->pw_dir);
- sprintf(logname_env, "LOGNAME=%s", username);
- sprintf(mail_env, "MAIL=/var/spool/mail/%s", username);
- sprintf(shell_env, "SHELL=%s", pwd->pw_shell);
- sprintf(user_env, "USER=%s", username);
-
- home_env[home_len - 1] = '\0';
- logname_env[logname_len - 1] = '\0';
- mail_env[mail_len - 1] = '\0';
- shell_env[shell_len - 1] = '\0';
- user_env[user_len - 1] = '\0';
-
- envp[0] = home_env;
- envp[1] = logname_env;
- envp[2] = mail_env;
- envp[3] = shell_env;
- envp[4] = user_env;
- envp[5] = 0;
-
- if ((putenv(home_env) < 0) ||
- (putenv(logname_env) < 0) ||
- (putenv(mail_env) < 0) ||
- (putenv(shell_env) < 0) ||
- (putenv(user_env) < 0)) {
- PERROR("vserver: putenv error ");
- exit(1);
- }
-}
-
-void slice_enter(struct passwd *pwd)
-{
- if (setuidgid_root() < 0) { /* For chroot, new_s_context */
- fprintf(stderr, "vsh: Could not become root, check that SUID flag is set on binary\n");
- exit(2);
- }