[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