]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
print a helpful message if creating unpriv container with no idmap
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Tue, 29 Jul 2014 18:26:29 +0000 (18:26 +0000)
committerStéphane Graber <stgraber@ubuntu.com>
Thu, 31 Jul 2014 18:17:04 +0000 (14:17 -0400)
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 <serge.hallyn@ubuntu.com>
src/lxc/conf.c
src/lxc/conf.h
src/lxc/lxc_usernsexec.c
src/lxc/lxccontainer.c

index d6f3c22185fb5b4316ddd55d4abdd384a1185810..690013938a8acd2ab345b4048a1db933e2b528aa 100644 (file)
@@ -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
@@ -4670,3 +4673,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);
+}
index 5ada506bbc545e1fe52201453cbaf7b67441985d..615f276d8b731ac2413dc68cc866e91fe5609d34 100644 (file)
 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,
@@ -405,4 +409,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
index 732a74a825af77e78c7dce20ddf9c73eb7899801..3c1fec5728e1ace0662123253a3d9e38ba9d6751 100644 (file)
@@ -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());
index 103309caa4260e04a4c918d5cce2a96cc3212a9f..ca5da87a1b4ac126f6aea9870295220eccb109c2 100644 (file)
@@ -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;
                }