示例#1
0
static void
set_param(const char *name, char *value)
{
	struct jailparam *param;
	int i;

	static int paramlistsize;

	/* Separate the name from the value, if not done already. */
	if (name == NULL) {
		name = value;
		if ((value = strchr(value, '=')))
			*value++ = '\0';
	}

	/* jail_set won't chdir along with its chroot, so do it here. */
	if (!strcmp(name, "path") && chdir(value) < 0)
		err(1, "chdir: %s", value);

	/* Check for repeat parameters */
	for (i = 0; i < nparams; i++)
		if (!strcmp(name, params[i].jp_name)) {
			jailparam_free(params + i, 1);
			memcpy(params + i, params + i + 1,
			    (--nparams - i) * sizeof(struct jailparam));
			break;
		}

	/* Make sure there is room for the new param record. */
	if (!nparams) {
		paramlistsize = 32;
		params = malloc(paramlistsize * sizeof(*params));
		param_values = malloc(paramlistsize * sizeof(*param_values));
		if (params == NULL || param_values == NULL)
			err(1, "malloc");
	} else if (nparams >= paramlistsize) {
		paramlistsize *= 2;
		params = realloc(params, paramlistsize * sizeof(*params));
		param_values = realloc(param_values,
		    paramlistsize * sizeof(*param_values));
		if (params == NULL)
			err(1, "realloc");
	}

	/* Look up the paramter. */
	param_values[nparams] = value;
	param = params + nparams++;
	if (jailparam_init(param, name) < 0 ||
	    jailparam_import(param, value) < 0)
		errx(1, "%s", jail_errmsg);
}
示例#2
0
static int
add_param(const char *name, void *value, size_t valuelen,
    struct jailparam *source, unsigned flags)
{
	struct jailparam *param, *tparams;
	int i, tnparams;

	static int paramlistsize;

	/* The pseudo-parameter "all" scans the list of available parameters. */
	if (!strcmp(name, "all")) {
		tnparams = jailparam_all(&tparams);
		if (tnparams < 0)
			xo_errx(1, "%s", jail_errmsg);
		qsort(tparams, (size_t)tnparams, sizeof(struct jailparam),
		    sort_param);
		for (i = 0; i < tnparams; i++)
			add_param(tparams[i].jp_name, NULL, (size_t)0,
			    tparams + i, flags);
		free(tparams);
		return -1;
	}

	/* Check for repeat parameters. */
	for (i = 0; i < nparams; i++)
		if (!strcmp(name, params[i].jp_name)) {
			if (value != NULL && jailparam_import_raw(params + i,
			    value, valuelen) < 0)
				xo_errx(1, "%s", jail_errmsg);
			params[i].jp_flags |= flags;
			if (source != NULL)
				jailparam_free(source, 1);
			return i;
		}

	/* Make sure there is room for the new param record. */
	if (!nparams) {
		paramlistsize = 32;
		params = malloc(paramlistsize * sizeof(*params));
		param_parent = malloc(paramlistsize * sizeof(*param_parent));
		if (params == NULL || param_parent == NULL)
			xo_err(1, "malloc");
	} else if (nparams >= paramlistsize) {
		paramlistsize *= 2;
		params = realloc(params, paramlistsize * sizeof(*params));
		param_parent = realloc(param_parent,
		    paramlistsize * sizeof(*param_parent));
		if (params == NULL || param_parent == NULL)
			xo_err(1, "realloc");
	}

	/* Look up the parameter. */
	param_parent[nparams] = -1;
	param = params + nparams++;
	if (source != NULL) {
		*param = *source;
		param->jp_flags |= flags;
		return param - params;
	}
	if (jailparam_init(param, name) < 0 ||
	    (value != NULL ? jailparam_import_raw(param, value, valuelen)
	     : jailparam_import(param, value)) < 0) {
		if (flags & JP_OPT) {
			nparams--;
			return (-1);
		}
		xo_errx(1, "%s", jail_errmsg);
	}
	param->jp_flags = flags;
	return param - params;
}
示例#3
0
int
main(int argc, char **argv)
{
	struct jailparam params[MAXPARAMS];
	char ifname[IFNAMSIZ];
	struct ifreq ifreq;
	vi_cmd_t newcmd, cmd;
	int recurse = 0;
	int verbose = 0;
	int jid, i, s, namelen;
	int vst_size, vst_last;
	vstat_t *vst;
	char *str;
	char ch;

	invocname = argv[0];

	newcmd = cmd = VI_SWITCHTO; /* Default if no modifiers specified. */
	while ((ch = getopt(argc, argv, "cdijlmrv")) != -1) {
		switch (ch) {
		case 'c':
			newcmd = VI_CREATE;
			break;
		case 'm':
			newcmd = VI_MODIFY;
			break;
		case 'd':
			newcmd = VI_DESTROY;
			break;
		case 'l':
			newcmd = VI_GET;
			break;
		case 'i':
			newcmd = VI_IFMOVE;
			break;
		case 'r':
			recurse = 1;
			break;
		case 'v':
			verbose++;
			break;
		case 'j':
			verbose = 2;
			break;
		default:
			usage();
		}
		if (cmd == VI_SWITCHTO || cmd == newcmd)
			cmd = newcmd;
		else
			usage();
	}
	argc -= optind;
	argv += optind;

	if ((cmd != VI_GET && (argc == 0 || recurse != 0 || verbose != 0)) ||
	    (cmd == VI_IFMOVE && (argc < 2 || argc > 3)) ||
	    (cmd == VI_MODIFY && argc < 2) || argc >= MAXPARAMS)
		usage();

	switch (cmd) {
	case VI_GET:
		vst_last = 0;
		vst_size = VST_SIZE_STEP;
		if ((vst = malloc(vst_size * sizeof(*vst))) == NULL)
			break;
		if (argc == 1)
			namelen = strlen(argv[0]);
		else
			namelen = 0;
		jid = 0;
		while ((jid = getjail(&vst[vst_last], jid, verbose)) > 0) {
			/* Skip jails which do not own vnets. */
			if (vst[vst_last].vnet != 1)
				continue;
			/* Skip non-matching vnames / hierarchies. */
			if (namelen &&
			    ((strlen(vst[vst_last].name) < namelen ||
			    strncmp(vst[vst_last].name, argv[0], namelen) != 0)
			    || (strlen(vst[vst_last].name) > namelen &&
			    vst[vst_last].name[namelen] != '.')))
				continue;
			/* Skip any sub-trees if -r not requested. */
			if (!recurse &&
			    (strlen(vst[vst_last].name) < namelen ||
			    strchr(&vst[vst_last].name[namelen], '.') != NULL))
				continue;
			/* Grow vst table if necessary. */
			if (++vst_last == vst_size) {
				vst_size += VST_SIZE_STEP;
				vst = realloc(vst, vst_size * sizeof(*vst));
				if (vst == NULL)
					break;
			}
		}
		if (vst == NULL)
			break;
		/* Sort: the key is the 1st field in *vst, i.e. vimage name. */
		qsort(vst, vst_last, sizeof(*vst), (void *) strcmp);
		for (i = 0; i < vst_last; i++) {
			if (!verbose) {
				printf("%s\n", vst[i].name);
				continue;
			}

			printf("%s:\n", vst[i].name);
			printf("    Path: %s\n", vst[i].path);
			printf("    Hostname: %s\n", vst[i].hostname);
			printf("    Domainname: %s\n", vst[i].domainname);
			printf("    Children: %d\n", vst[i].childcnt);

			if (verbose < 2)
				continue;

			printf("    Children limit: %d\n", vst[i].childmax);
			printf("    CPUsetID: %d\n", vst[i].cpuset);
			printf("    JID: %d\n", vst[i].jid);
			printf("    PJID: %d\n", vst[i].parentjid);
			printf("    Raw sockets allowed: %d\n", vst[i].rawsock);
			printf("    All AF allowed: %d\n", vst[i].socket_af);
			printf("    Mount allowed: %d\n", vst[i].mount);
		}
		free(vst);
		exit(0);

	case VI_IFMOVE:
		if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
			break;
		if ((jid = jail_getid(argv[0])) < 0)
			break;
		ifreq.ifr_jid = jid;
		strncpy(ifreq.ifr_name, argv[1], sizeof(ifreq.ifr_name));
		if (ioctl(s, SIOCSIFVNET, (caddr_t)&ifreq) < 0)
			break;
		close(s);
		if (argc == 3)
			snprintf(ifname, sizeof(ifname), "%s", argv[2]);
		else
			snprintf(ifname, sizeof(ifname), "eth0");
		ifreq.ifr_data = ifname;
		/* Do we need to rename the ifnet? */
		if (strcmp(ifreq.ifr_name, ifname) != 0) {
			/* Switch to the context of the target vimage. */
			if (jail_attach(jid) < 0)
				break;
			if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
				break;
			for (namelen = 0; isalpha(ifname[namelen]); namelen++);
			i = 0;
			/* Search for a free ifunit in target vnet.  Unsafe. */
			while (ioctl(s, SIOCSIFNAME, (caddr_t)&ifreq) < 0) {
				snprintf(&ifname[namelen],
				    sizeof(ifname) - namelen, "%d", i);
				/* Emergency brake. */
				if (i++ == IF_MAXUNIT)
					break;
			}
		}
		if (i < IF_MAXUNIT)
			printf("%s@%s\n", ifname, argv[0]);
		else
			printf("%s@%s\n", ifreq.ifr_name, argv[0]);
		exit(0);

	case VI_CREATE:
		if (jail_setv(JAIL_CREATE,
		    "name", argv[0],
		    "vnet", NULL,
		    "host", NULL,
		    "persist", NULL,
		    "allow.raw_sockets", "true",
		    "allow.socket_af", "true",
		    "allow.mount", "true",
		    NULL) < 0)
			break;
		if (argc == 1)
			exit(0);
		/* Not done yet, proceed to apply non-default parameters. */

	case VI_MODIFY:
		jailparam_init(&params[0], "name");
		jailparam_import(&params[0], argv[0]);
		for (i = 1; i < argc; i++) {
			for (str = argv[i]; *str != '=' && *str != 0; str++) {
				/* Do nothing - search for '=' delimeter. */
			}
			if (*str == 0)
				break;
			*str++ = 0;
			if (*str == 0)
				break;
			jailparam_init(&params[i], argv[i]);
			jailparam_import(&params[i], str);
		}
		if (i != argc)
			break;
		if (jailparam_set(params, i, JAIL_UPDATE) < 0)
			break;
		exit(0);

	case VI_DESTROY:
		if ((jid = jail_getid(argv[0])) < 0)
			break;
		if (jail_remove(jid) < 0)
			break;
		exit(0);

	case VI_SWITCHTO:
		if ((jid = jail_getid(argv[0])) < 0)
			break;
		if (jail_attach(jid) < 0)
			break;
		if (argc == 1) {
			printf("Switched to vimage %s\n", argv[0]);
			if ((str = getenv("SHELL")) == NULL)
				execlp("/bin/sh", invocname, NULL);
			else
				execlp(str, invocname, NULL);
		} else 
			execvp(argv[1], &argv[1]);
		break;

	default:
		/* Should be unreachable. */
		break;
	}

	if (jail_errmsg[0])
		fprintf(stderr, "Error: %s\n", jail_errmsg);
	else
		perror("Error");
	exit(1);
}