From: Serge Hallyn Date: Tue, 29 Jul 2014 18:26:29 +0000 (+0000) Subject: print a helpful message if creating unpriv container with no idmap X-Git-Tag: lxc-1.0.6~66 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6affb6ef1e5088cdad5e04b090c2ca136b960561;p=thirdparty%2Flxc.git print a helpful message if creating unpriv container with no idmap This gives me: ubuntu@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 --- diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 6882076c5..47c73f27f 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include #include #if HAVE_PTY_H @@ -4575,3 +4578,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 8823dc1c4..606421cf3 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, @@ -394,4 +398,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 732a74a82..3c1fec572 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 31f5bb030..9be1ce1f3 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -809,6 +809,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; }