/* vi: set sw=4 ts=4: */
/*
 * Mini nsenter implementation for busybox.
 *
 * Copyright (C) 2016 by Bartosz Golaszewski <bartekgola@gmail.com>
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */
//config:config NSENTER
//config:	bool "nsenter (6.5 kb)"
//config:	default y
//config:	help
//config:	Run program with namespaces of other processes.

//applet:IF_NSENTER(APPLET(nsenter, BB_DIR_USR_BIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_NSENTER) += nsenter.o

//usage:#define nsenter_trivial_usage
//usage:       "[OPTIONS] [PROG ARGS]"
//usage:#define nsenter_full_usage "\n"
//usage:     "\n	-t PID		Target process to get namespaces from"
//usage:     "\n	-m[FILE]	Enter mount namespace"
//usage:     "\n	-u[FILE]	Enter UTS namespace (hostname etc)"
//usage:     "\n	-i[FILE]	Enter System V IPC namespace"
//usage:     "\n	-n[FILE]	Enter network namespace"
//usage:     "\n	-p[FILE]	Enter pid namespace"
//usage:     "\n	-U[FILE]	Enter user namespace"
//usage:     "\n	-S UID		Set uid in entered namespace"
//usage:     "\n	-G GID		Set gid in entered namespace"
//usage:	IF_LONG_OPTS(
//usage:     "\n	--preserve-credentials	Don't touch uids or gids"
//usage:	)
//usage:     "\n	-r[DIR]		Set root directory"
//usage:     "\n	-w[DIR]		Set working directory"
//usage:     "\n	-F		Don't fork before exec'ing PROG"

#include <sched.h>
#ifndef CLONE_NEWUTS
# define CLONE_NEWUTS  0x04000000
#endif
#ifndef CLONE_NEWIPC
# define CLONE_NEWIPC  0x08000000
#endif
#ifndef CLONE_NEWUSER
# define CLONE_NEWUSER 0x10000000
#endif
#ifndef CLONE_NEWPID
# define CLONE_NEWPID  0x20000000
#endif
#ifndef CLONE_NEWNET
# define CLONE_NEWNET  0x40000000
#endif

#include "libbb.h"

struct namespace_descr {
	int flag;		/* value passed to setns() */
	char ns_nsfile8[8];	/* "ns/" + namespace file in process' procfs entry */
};

struct namespace_ctx {
	char *path;		/* optional path to a custom ns file */
	int fd;			/* opened namespace file descriptor */
};

enum {
	OPT_user	= 1 << 0,
	OPT_ipc		= 1 << 1,
	OPT_uts		= 1 << 2,
	OPT_network	= 1 << 3,
	OPT_pid		= 1 << 4,
	OPT_mount	= 1 << 5,
	OPT_target	= 1 << 6,
	OPT_setuid	= 1 << 7,
	OPT_setgid	= 1 << 8,
	OPT_root	= 1 << 9,
	OPT_wd		= 1 << 10,
	OPT_nofork	= 1 << 11,
	OPT_prescred	= (1 << 12) * ENABLE_LONG_OPTS,
};
enum {
	NS_USR_POS = 0,
	NS_IPC_POS,
	NS_UTS_POS,
	NS_NET_POS,
	NS_PID_POS,
	NS_MNT_POS,
	NS_COUNT,
};
/*
 * The order is significant in nsenter.
 * The user namespace comes first, so that it is entered first.
 * This gives an unprivileged user the potential to enter other namespaces.
 */
static const struct namespace_descr ns_list[] = {
	{ CLONE_NEWUSER, "ns/user", },
	{ CLONE_NEWIPC,  "ns/ipc",  },
	{ CLONE_NEWUTS,  "ns/uts",  },
	{ CLONE_NEWNET,  "ns/net",  },
	{ CLONE_NEWPID,  "ns/pid",  },
	{ CLONE_NEWNS,   "ns/mnt",  },
};
/*
 * Upstream nsenter doesn't support the short option for --preserve-credentials
 * "+": stop on first non-option
 */
static const char opt_str[] ALIGN1 = "+""U::i::u::n::p::m::""t:+S:+G:+r::w::F";

#if ENABLE_LONG_OPTS
static const char nsenter_longopts[] ALIGN1 =
	"user\0"			Optional_argument	"U"
	"ipc\0"				Optional_argument	"i"
	"uts\0"				Optional_argument	"u"
	"net\0"				Optional_argument	"n"
	"pid\0"				Optional_argument	"p"
	"mount\0"			Optional_argument	"m"
	"target\0"			Required_argument	"t"
	"setuid\0"			Required_argument	"S"
	"setgid\0"			Required_argument	"G"
	"root\0"			Optional_argument	"r"
	"wd\0"				Optional_argument	"w"
	"no-fork\0"			No_argument		"F"
	"preserve-credentials\0"	No_argument		"\xff"
	;
#endif

/*
 * Open a file and return the new descriptor. If a full path is provided in
 * fs_path, then the file to which it points is opened. Otherwise (fd_path is
 * NULL) the routine builds a path to a procfs file using the following
 * template: '/proc/<target_pid>/<target_file>'.
 */
static int open_by_path_or_target(const char *path,
				  pid_t target_pid, const char *target_file)
{
	char proc_path_buf[sizeof("/proc/%u/1234567890") + sizeof(int)*3];

	if (!path) {
		if (target_pid == 0) {
			/* Example:
			 * "nsenter -p PROG" - neither -pFILE nor -tPID given.
			 */
			bb_show_usage();
		}
		snprintf(proc_path_buf, sizeof(proc_path_buf),
			 "/proc/%u/%s", (unsigned)target_pid, target_file);
		path = proc_path_buf;
	}

	return xopen(path, O_RDONLY);
}

int nsenter_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int nsenter_main(int argc UNUSED_PARAM, char **argv)
{
	int i;
	unsigned int opts;
	const char *root_dir_str = NULL;
	const char *wd_str = NULL;
	struct namespace_ctx ns_ctx_list[NS_COUNT];
	int setgroups_failed;
	int root_fd, wd_fd;
	int target_pid = 0;
	int uid = 0;
	int gid = 0;

	memset(ns_ctx_list, 0, sizeof(ns_ctx_list));

	opts = getopt32long(argv, opt_str, nsenter_longopts,
			&ns_ctx_list[NS_USR_POS].path,
			&ns_ctx_list[NS_IPC_POS].path,
			&ns_ctx_list[NS_UTS_POS].path,
			&ns_ctx_list[NS_NET_POS].path,
			&ns_ctx_list[NS_PID_POS].path,
			&ns_ctx_list[NS_MNT_POS].path,
			&target_pid, &uid, &gid,
			&root_dir_str, &wd_str
	);
	argv += optind;

	root_fd = wd_fd = -1;
	if (opts & OPT_root)
		root_fd = open_by_path_or_target(root_dir_str,
						 target_pid, "root");
	if (opts & OPT_wd)
		wd_fd = open_by_path_or_target(wd_str, target_pid, "cwd");

	for (i = 0; i < NS_COUNT; i++) {
		const struct namespace_descr *ns = &ns_list[i];
		struct namespace_ctx *ns_ctx = &ns_ctx_list[i];

		ns_ctx->fd = -1;
		if (opts & (1 << i))
			ns_ctx->fd = open_by_path_or_target(ns_ctx->path,
					target_pid, ns->ns_nsfile8);
	}

	/*
	 * Entering the user namespace without --preserve-credentials implies
	 * --setuid & --setgid and clearing root's groups.
	 */
	setgroups_failed = 0;
	if ((opts & OPT_user) && !(opts & OPT_prescred)) {
		opts |= (OPT_setuid | OPT_setgid);
		/*
		 * We call setgroups() before and after setns() and only
		 * bail-out if it fails twice.
		 */
		setgroups_failed = (setgroups(0, NULL) < 0);
	}

	for (i = 0; i < NS_COUNT; i++) {
		const struct namespace_descr *ns = &ns_list[i];
		struct namespace_ctx *ns_ctx = &ns_ctx_list[i];

		if (ns_ctx->fd < 0)
			continue;
		if (setns(ns_ctx->fd, ns->flag)) {
			bb_perror_msg_and_die(
				"setns(): can't reassociate to namespace '%s'",
				ns->ns_nsfile8 + 3 /* skip over "ns/" */
			);
		}
		close(ns_ctx->fd); /* should close fds, to not confuse exec'ed PROG */
		/*ns_ctx->fd = -1;*/
	}

	if (root_fd >= 0) {
		if (wd_fd < 0) {
			/*
			 * Save the current working directory if we're not
			 * changing it.
			 */
			wd_fd = xopen(".", O_RDONLY);
		}
		xfchdir(root_fd);
		xchroot(".");
		close(root_fd);
		/*root_fd = -1;*/
	}

	if (wd_fd >= 0) {
		xfchdir(wd_fd);
		close(wd_fd);
		/*wd_fd = -1;*/
	}

	/*
	 * Entering the pid namespace implies forking unless it's been
	 * explicitly requested by the user not to.
	 */
	if (!(opts & OPT_nofork) && (opts & OPT_pid)) {
		xvfork_parent_waits_and_exits();
		/* Child continues */
	}

	if (opts & OPT_setgid) {
		if (setgroups(0, NULL) < 0 && setgroups_failed)
			bb_simple_perror_msg_and_die("setgroups");
		xsetgid(gid);
	}
	if (opts & OPT_setuid)
		xsetuid(uid);

	exec_prog_or_SHELL(argv);
}
