Beispiel #1
0
/* This is a variation of get_list below it. This version allows two additional
 * features. If a list is passed to it, it adds to it. It allows for empty
 * entries (i.e. "group1,,group2") generating and empty list entry.
 */
static struct lxc_list *accumulate_list(char *input, char *delimiter,
					struct lxc_list *str_list)
{
	char *workstr = NULL;
	char *workptr = NULL;
	char *next_ptr = NULL;
	struct lxc_list *worklist;
	struct lxc_list *workstr_list;

	workstr = strdup(input);
	if (!workstr)
		return NULL;

	workstr_list = str_list;
	if (!workstr_list) {
		workstr_list = malloc(sizeof(*workstr_list));
		lxc_list_init(workstr_list);
	}

	for (workptr = workstr; workptr; workptr = next_ptr) {
		/* We can't use strtok_r here because it collapses multiple
		 * delimiters into 1 making empty fields impossible...
		 */
		next_ptr = strchr(workptr, *delimiter);
		if (next_ptr)
			*next_ptr++ = '\0';

		/* At this point, we'd like to check to see if this group is
		 * already contained in the list and ignore it if it is...  This
		 * also helps us with any corner cases where a string begins or
		 * ends with a delimiter.
		 */
		if (list_contains_entry(workptr, workstr_list)) {
			if (*workptr)
				fprintf(stderr, "Duplicate group \"%s\" in list - ignoring\n", workptr);
			else
				fprintf(stderr, "Duplicate NULL group in list - ignoring\n");
		} else {
			worklist = malloc(sizeof(*worklist));
			if (!worklist)
				break;

			worklist->elem = strdup(workptr);
			if (!worklist->elem) {
				free(worklist);
				break;
			}

			lxc_list_add_tail(workstr_list, worklist);
		}
	}

	free(workstr);

	return workstr_list;
}
Beispiel #2
0
/*
 * This is called if the user did not pass any uid ranges in
 * through -m flags.  It's called once to get the default uid
 * map, and once for the default gid map.
 * Go through /etc/subuids and /etc/subgids to find this user's
 * allowed map.  We only use the first one for each of uid and
 * gid, because otherwise we're not sure which entries the user
 * wanted.
 */
static int read_default_map(char *fnam, int which, char *username)
{
	FILE *fin;
	char *line = NULL;
	size_t sz = 0;
	struct id_map *newmap;
	struct lxc_list *tmp = NULL;
	char *p1, *p2;

	fin = fopen(fnam, "r");
	if (!fin)
		return -1;
	while (getline(&line, &sz, fin) != -1) {
		if (sz <= strlen(username) ||
		    strncmp(line, username, strlen(username)) != 0 ||
		    line[strlen(username)] != ':')
			continue;
		p1 = strchr(line, ':');
		if (!p1)
			continue;
		p2 = strchr(p1+1, ':');
		if (!p2)
			continue;
		newmap = malloc(sizeof(*newmap));
		if (!newmap)  {
			fclose(fin);
			free(line);
			return -1;
		}
		newmap->hostid = atol(p1+1);
		newmap->range = atol(p2+1);
		newmap->nsid = 0;
		newmap->idtype = which;

		tmp = malloc(sizeof(*tmp));
		if (!tmp) {
			fclose(fin);
			free(line);
			free(newmap);
			return -1;
		}

		tmp->elem = newmap;
		lxc_list_add_tail(&active_map, tmp);
		break;
	}

	free(line);
	fclose(fin);
	return 0;
}
Beispiel #3
0
/*
 * given a string like "b:0:100000:10", map both uids and gids
 * 0-10 to 100000 to 100010
 */
static int parse_map(char *map)
{
	struct id_map *newmap;
	struct lxc_list *tmp = NULL;
	int ret;
	int i;
	char types[2] = {'u', 'g'};
	char which;
	long host_id, ns_id, range;

	if (!map)
		return -1;

	ret = sscanf(map, "%c:%ld:%ld:%ld", &which, &ns_id, &host_id, &range);
	if (ret != 4)
		return -1;

	if (which != 'b' && which != 'u' && which != 'g')
		return -1;

	for (i = 0; i < 2; i++) {
		if (which != types[i] && which != 'b')
			continue;

		newmap = malloc(sizeof(*newmap));
		if (!newmap)
			return -1;

		newmap->hostid = host_id;
		newmap->nsid = ns_id;
		newmap->range = range;

		if (types[i] == 'u')
			newmap->idtype = ID_TYPE_UID;
		else
			newmap->idtype = ID_TYPE_GID;

		tmp = malloc(sizeof(*tmp));
		if (!tmp) {
			free(newmap);
			return -1;
		}

		tmp->elem = newmap;
		lxc_list_add_tail(&active_map, tmp);
	}

	return 0;
}
Beispiel #4
0
static int config_network_type(const char *key, char *value,
			       struct lxc_conf *lxc_conf)
{
	struct lxc_list *network = &lxc_conf->network;
	struct lxc_netdev *netdev;
	struct lxc_list *list;

	netdev = malloc(sizeof(*netdev));
	if (!netdev) {
		SYSERROR("failed to allocate memory");
		return -1;
	}

	memset(netdev, 0, sizeof(*netdev));
	lxc_list_init(&netdev->ipv4);
	lxc_list_init(&netdev->ipv6);

	list = malloc(sizeof(*list));
	if (!list) {
		SYSERROR("failed to allocate memory");
		return -1;
	}

	lxc_list_init(list);
	list->elem = netdev;

	lxc_list_add_tail(network, list);

	if (!strcmp(value, "veth"))
		netdev->type = LXC_NET_VETH;
	else if (!strcmp(value, "macvlan"))
		netdev->type = LXC_NET_MACVLAN;
	else if (!strcmp(value, "vlan"))
		netdev->type = LXC_NET_VLAN;
	else if (!strcmp(value, "phys"))
		netdev->type = LXC_NET_PHYS;
	else if (!strcmp(value, "empty"))
		netdev->type = LXC_NET_EMPTY;
	else {
		ERROR("invalid network type %s", value);
		return -1;
	}
	return 0;
}
Beispiel #5
0
static struct lxc_list *get_list(char *input, char *delimiter) {
	char *workstr = NULL;
	char *workptr = NULL;
	char *sptr = NULL;
	char *token = NULL;
	struct lxc_list *worklist;
	struct lxc_list *workstr_list;

	workstr_list = malloc(sizeof(*workstr_list));
	lxc_list_init(workstr_list);

	workstr = strdup(input);
	if (!workstr) {
		free(workstr_list);
		return NULL;
	}

	for (workptr = workstr;;workptr = NULL) {
		token = strtok_r(workptr, delimiter, &sptr);
		if (!token) {
			break;
		}

		worklist = malloc(sizeof(*worklist));
		if (!worklist)
			break;

		worklist->elem = strdup(token);
		if (!worklist->elem) {
			free(worklist);
			break;
		}

		lxc_list_add_tail(workstr_list, worklist);
	}

	free(workstr);

	return workstr_list;
}
Beispiel #6
0
/*
 * This is called if the user did not pass any uid ranges in through -m flags.
 * It's called once to get the default uid map, and once for the default gid
 * map.
 * Go through /etc/subuids and /etc/subgids to find this user's allowed map. We
 * only use the first one for each of uid and gid, because otherwise we're not
 * sure which entries the user wanted.
 */
static int read_default_map(char *fnam, int which, char *user)
{
	size_t len;
	char *p1, *p2;
	unsigned long ul1, ul2;
	FILE *fin;
	int ret = -1;
	size_t sz = 0;
	char *line = NULL;
	struct lxc_list *tmp = NULL;
	struct id_map *newmap = NULL;

	fin = fopen(fnam, "r");
	if (!fin)
		return -1;

	len = strlen(user);
	while (getline(&line, &sz, fin) != -1) {
		if (sz <= len || strncmp(line, user, len) != 0 || line[len] != ':')
			continue;

		p1 = strchr(line, ':');
		if (!p1)
			continue;

		p2 = strchr(p1 + 1, ':');
		if (!p2)
			continue;

		line[strlen(line) - 1] = '\0';
		*p2 = '\0';

		ret = lxc_safe_ulong(p1 + 1, &ul1);
		if (ret < 0)
			break;

		ret = lxc_safe_ulong(p2 + 1, &ul2);
		if (ret < 0)
			break;

		ret = -1;
		newmap = malloc(sizeof(*newmap));
		if (!newmap)
			break;

		newmap->nsid = 0;
		newmap->idtype = which;
		newmap->hostid = ul1;
		newmap->range = ul2;

		tmp = malloc(sizeof(*tmp));
		if (!tmp) {
			free(newmap);
			break;
		}

		tmp->elem = newmap;
		lxc_list_add_tail(&active_map, tmp);

		ret = 0;
		break;
	}

	fclose(fin);
	free(line);

	return ret;
}