[lxc-devel] [PATCH 1/1] print a helpful message if creating unpriv container with no idmap

Serge Hallyn serge.hallyn at ubuntu.com
Tue Jul 29 18:26:29 UTC 2014


This gives me:

ubuntu at c-t1:~$ lxc-create -t download -n u1
lxc_container: No mapping for container root
lxc_container: Error chowning /home/ubuntu/.local/share/lxc/u1/rootfs to container root
lxc_container: You must either run as root, or define uid mappings
lxc_container: To pass uid mappings to lxc-create, you could create
lxc_container: ~/.config/lxc/default.conf:
lxc_container: lxc.include = /etc/lxc/default.conf
lxc_container: lxc.id_map = u 0 100000 65536
lxc_container: lxc.id_map = g 0 100000 65536
lxc_container: Error creating backing store type (none) for u1
lxc_container: Error creating container u1

when I create a container without having an id mapping defined.

Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
 src/lxc/conf.c           | 147 +++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/conf.h           |   5 ++
 src/lxc/lxc_usernsexec.c |   2 -
 src/lxc/lxccontainer.c   |   1 +
 4 files changed, 153 insertions(+), 2 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 052db98..9bd5437 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -32,6 +32,9 @@
 #include <inttypes.h>
 #include <sys/wait.h>
 #include <sys/syscall.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
 #include <time.h>
 
 #if HAVE_PTY_H
@@ -4655,3 +4658,147 @@ err:
 	close(p[1]);
 	return -1;
 }
+
+static char* getuname(void)
+{
+	struct passwd pwd, *result;
+	char *buf, *ret = NULL;
+	size_t bufsize;
+	int s;
+
+	bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+	if (bufsize == -1)
+		bufsize = 16384;
+
+	buf = malloc(bufsize);
+	if (!buf)
+		return NULL;
+	
+	s = getpwuid_r(geteuid(), &pwd, buf, bufsize, &result);
+	if (s || result == NULL)
+		goto out;
+
+	ret = strdup(pwd.pw_name);
+out:
+	free(buf);
+	return ret;
+}
+
+static char *getgname(void)
+{
+	struct group grp, *result;
+	char *buf, *ret = NULL;
+	size_t bufsize;
+	int s;
+
+	bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
+	if (bufsize == -1)
+		bufsize = 16384;
+
+	buf = malloc(bufsize);
+	if (!buf)
+		return NULL;
+	
+	s = getgrgid_r(geteuid(), &grp, buf, bufsize, &result);
+	if (s || result == NULL)
+		goto out;
+
+	ret = strdup(grp.gr_name);
+out:
+	free(buf);
+	return ret;
+}
+
+void suggest_default_idmap(void)
+{
+	FILE *f;
+	unsigned int uid = 0, urange = 0, gid = 0, grange = 0;
+	char *line = NULL;
+	char *uname, *gname;
+	size_t len = 0;
+
+	if (!(uname = getuname()))
+		return;
+
+	if (!(gname = getgname())) {
+		free(uname);
+		return;
+	}
+
+	f = fopen(subuidfile, "r");
+	if (!f) {
+		ERROR("Your system is not configured with subuids");
+		free(gname);
+		free(uname);
+		return;
+	}
+	while (getline(&line, &len, f) != -1) {
+		char *p = strchr(line, ':'), *p2;
+		if (*line == '#')
+			continue;
+		if (!p)
+			continue;
+		*p = '\0';
+		p++;
+		if (strcmp(line, uname))
+			continue;
+		p2 = strchr(p, ':');
+		if (!p2)
+			continue;
+		*p2 = '\0';
+		p2++;
+		if (!*p2)
+			continue;
+		uid = atoi(p);
+		urange = atoi(p2);
+	}
+	fclose(f);
+
+	f = fopen(subuidfile, "r");
+	if (!f) {
+		ERROR("Your system is not configured with subgids");
+		free(gname);
+		free(uname);
+		return;
+	}
+	while (getline(&line, &len, f) != -1) {
+		char *p = strchr(line, ':'), *p2;
+		if (*line == '#')
+			continue;
+		if (!p)
+			continue;
+		*p = '\0';
+		p++;
+		if (strcmp(line, uname))
+			continue;
+		p2 = strchr(p, ':');
+		if (!p2)
+			continue;
+		*p2 = '\0';
+		p2++;
+		if (!*p2)
+			continue;
+		gid = atoi(p);
+		grange = atoi(p2);
+	}
+	fclose(f);
+
+	if (line)
+		free(line);
+
+	if (!urange || !grange) {
+		ERROR("You do not have subuids or subgids allocated");
+		ERROR("Unprivileged containers require subuids and subgids");
+		return;
+	}
+
+	ERROR("You must either run as root, or define uid mappings");
+	ERROR("To pass uid mappings to lxc-create, you could create");
+	ERROR("~/.config/lxc/default.conf:");
+	ERROR("lxc.include = %s", LXC_DEFAULT_CONFIG);
+	ERROR("lxc.id_map = u 0 %u %u", uid, urange);
+	ERROR("lxc.id_map = g 0 %u %u", gid, grange);
+
+	free(gname);
+	free(uname);
+}
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 3527c44..b540cce 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -38,6 +38,10 @@
 typedef void * scmp_filter_ctx;
 #endif
 
+/* worth moving to configure.ac? */
+#define subuidfile "/etc/subuid"
+#define subgidfile "/etc/subgid"
+
 enum {
 	LXC_NET_EMPTY,
 	LXC_NET_VETH,
@@ -400,4 +404,5 @@ extern int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data);
 extern int parse_mntopts(const char *mntopts, unsigned long *mntflags,
 			 char **mntdata);
 extern void tmp_proc_unmount(struct lxc_conf *lxc_conf);
+extern void suggest_default_idmap(void);
 #endif
diff --git a/src/lxc/lxc_usernsexec.c b/src/lxc/lxc_usernsexec.c
index 732a74a..3c1fec5 100644
--- a/src/lxc/lxc_usernsexec.c
+++ b/src/lxc/lxc_usernsexec.c
@@ -250,8 +250,6 @@ static int read_default_map(char *fnam, int which, char *username)
 	return 0;
 }
 
-#define subuidfile "/etc/subuid"
-#define subgidfile "/etc/subgid"
 static int find_default_map(void)
 {
 	struct passwd *p = getpwuid(getuid());
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 103309c..ca5da87 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -813,6 +813,7 @@ static struct bdev *do_bdev_create(struct lxc_container *c, const char *type,
 	if (geteuid() != 0 || (c->lxc_conf && !lxc_list_empty(&c->lxc_conf->id_map))) {
 		if (chown_mapped_root(bdev->dest, c->lxc_conf) < 0) {
 			ERROR("Error chowning %s to container root", bdev->dest);
+			suggest_default_idmap();
 			bdev_put(bdev);
 			return NULL;
 		}
-- 
1.9.1



More information about the lxc-devel mailing list