]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
create: pass --mapped-gid to templates next to --mapped-uid
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Tue, 4 Feb 2014 19:33:10 +0000 (13:33 -0600)
committerStéphane Graber <stgraber@ubuntu.com>
Tue, 4 Feb 2014 21:31:37 +0000 (16:31 -0500)
That way templates can fix group ownership alongside uid ownership.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
src/lxc/conf.c
src/lxc/conf.h
src/lxc/lxccontainer.c
templates/lxc-download.in
templates/lxc-ubuntu-cloud.in

index d4578f349e4a49dd71f30010457bdf2eb5ae077a..fed532737a13e780c33198d00b2fe4bed8f7946c 100644 (file)
@@ -3177,13 +3177,13 @@ bool get_mapped_rootid(struct lxc_conf *conf, enum idtype idtype,
        return false;
 }
 
-int mapped_hostid(int id, struct lxc_conf *conf)
+int mapped_hostid(unsigned id, struct lxc_conf *conf, enum idtype idtype)
 {
        struct lxc_list *it;
        struct id_map *map;
        lxc_list_for_each(it, &conf->id_map) {
                map = it->elem;
-               if (map->idtype != ID_TYPE_UID)
+               if (map->idtype != idtype)
                        continue;
                if (id >= map->hostid && id < map->hostid + map->range)
                        return (id - map->hostid) + map->nsid;
@@ -3191,15 +3191,15 @@ int mapped_hostid(int id, struct lxc_conf *conf)
        return -1;
 }
 
-int find_unmapped_nsuid(struct lxc_conf *conf)
+int find_unmapped_nsuid(struct lxc_conf *conf, enum idtype idtype)
 {
        struct lxc_list *it;
        struct id_map *map;
-       uid_t freeid = 0;
+       unsigned int freeid = 0;
 again:
        lxc_list_for_each(it, &conf->id_map) {
                map = it->elem;
-               if (map->idtype != ID_TYPE_UID)
+               if (map->idtype != idtype)
                        continue;
                if (freeid >= map->nsid && freeid < map->nsid + map->range) {
                        freeid = map->nsid + map->range;
@@ -3992,7 +3992,7 @@ static int run_userns_fn(void *data)
  */
 static struct lxc_list *idmap_add_id(struct lxc_conf *conf, uid_t uid)
 {
-       int hostid_mapped = mapped_hostid(uid, conf);
+       int hostid_mapped = mapped_hostid(uid, conf, ID_TYPE_UID);
        struct lxc_list *new = NULL, *tmp, *it, *next;
        struct id_map *entry;
 
@@ -4004,7 +4004,7 @@ static struct lxc_list *idmap_add_id(struct lxc_conf *conf, uid_t uid)
        lxc_list_init(new);
 
        if (hostid_mapped < 0) {
-               hostid_mapped = find_unmapped_nsuid(conf);
+               hostid_mapped = find_unmapped_nsuid(conf, ID_TYPE_UID);
                if (hostid_mapped < 0)
                        goto err;
                tmp = malloc(sizeof(*tmp));
index e5a23ec44d3d23b7267fde5df824b7562363f814..16d71224215d49522eff338b3aec3f72c98e4846 100644 (file)
@@ -371,8 +371,8 @@ extern int lxc_setup(struct lxc_handler *handler);
 
 extern void lxc_rename_phys_nics_on_shutdown(struct lxc_conf *conf);
 
-extern int find_unmapped_nsuid(struct lxc_conf *conf);
-extern int mapped_hostid(int id, struct lxc_conf *conf);
+extern int find_unmapped_nsuid(struct lxc_conf *conf, enum idtype idtype);
+extern int mapped_hostid(unsigned id, struct lxc_conf *conf, enum idtype idtype);
 extern int chown_mapped_root(char *path, struct lxc_conf *conf);
 extern int ttys_shift_ids(struct lxc_conf *c);
 extern int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data);
index 85c644afb1f14aa35723690b171bf1faddc11fcb..7d3ebdb28db313992cd40cdd27ad45c815c70ab8 100644 (file)
@@ -977,6 +977,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet
                if (geteuid() != 0 && !lxc_list_empty(&conf->id_map)) {
                        int n2args = 1;
                        char txtuid[20];
+                       char txtgid[20];
                        char **n2 = malloc(n2args * sizeof(*n2));
                        struct lxc_list *it;
                        struct id_map *map;
@@ -1004,13 +1005,13 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet
                                if (ret < 0 || ret >= 200)
                                        exit(1);
                        }
-                       int hostid_mapped = mapped_hostid(geteuid(), conf);
+                       int hostid_mapped = mapped_hostid(geteuid(), conf, ID_TYPE_UID);
                        int extraargs = hostid_mapped >= 0 ? 1 : 3;
                        n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
                        if (!n2)
                                exit(1);
                        if (hostid_mapped < 0) {
-                               hostid_mapped = find_unmapped_nsuid(conf);
+                               hostid_mapped = find_unmapped_nsuid(conf, ID_TYPE_UID);
                                n2[n2args++] = "-m";
                                if (hostid_mapped < 0) {
                                        ERROR("Could not find free uid to map");
@@ -1028,22 +1029,49 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet
                                        exit(1);
                                }
                        }
+                       int hostgid_mapped = mapped_hostid(getegid(), conf, ID_TYPE_GID);
+                       extraargs = hostgid_mapped >= 0 ? 1 : 3;
+                       n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
+                       if (!n2)
+                               exit(1);
+                       if (hostgid_mapped < 0) {
+                               hostgid_mapped = find_unmapped_nsuid(conf, ID_TYPE_GID);
+                               n2[n2args++] = "-m";
+                               if (hostgid_mapped < 0) {
+                                       ERROR("Could not find free uid to map");
+                                       exit(1);
+                               }
+                               n2[n2args++] = malloc(200);
+                               if (!n2[n2args-1]) {
+                                       SYSERROR("out of memory");
+                                       exit(1);
+                               }
+                               ret = snprintf(n2[n2args-1], 200, "g:%d:%d:1",
+                                       hostgid_mapped, getegid());
+                               if (ret < 0 || ret >= 200) {
+                                       ERROR("string too long");
+                                       exit(1);
+                               }
+                       }
                        n2[n2args++] = "--";
                        for (i = 0; i < nargs; i++)
                                n2[i + n2args] = newargv[i];
                        n2args += nargs;
                        // Finally add "--mapped-uid $uid" to tell template what to chown
                        // cached images to
-                       n2args += 2;
+                       n2args += 4;
                        n2 = realloc(n2, n2args * sizeof(char *));
                        if (!n2) {
                                SYSERROR("out of memory");
                                exit(1);
                        }
                        // note n2[n2args-1] is NULL
-                       n2[n2args-3] = "--mapped-uid";
+                       n2[n2args-5] = "--mapped-uid";
                        snprintf(txtuid, 20, "%d", hostid_mapped);
-                       n2[n2args-2] = txtuid;
+                       n2[n2args-4] = txtuid;
+                       n2[n2args-3] = "--mapped-gid";
+                       snprintf(txtgid, 20, "%d", hostgid_mapped);
+                       n2[n2args-2] = txtgid;
                        n2[n2args-1] = NULL;
                        free(newargv);
                        newargv = n2;
index 3ef9fba8202f14cb2ac5f35d8b8bacdc2d66d141..2a6e51d26d62b7d82ef08e5d57dbad1055c0726b 100644 (file)
@@ -51,6 +51,7 @@ LXC_NAME=
 LXC_PATH=
 LXC_ROOTFS=
 LXC_MAPPED_UID=
+LXC_MAPPED_GID=
 
 # Some useful functions
 cleanup() {
@@ -175,14 +176,15 @@ LXC internal arguments (do not pass manually!):
 [ --name <name> ]: The container name
 [ --path <path> ]: The path to the container
 [ --rootfs <rootfs> ]: The path to the container's rootfs
-[ --mapped-uid <map> ]: A uid/gid map (user namespaces)
+[ --mapped-uid <map> ]: A uid map (user namespaces)
+[ --mapped-gid <map> ]: A gid map (user namespaces)
 EOF
     return 0
 }
 
 options=$(getopt -o d:r:a:hl -l dist:,release:,arch:,help,list,variant:,\
 server:,keyid:,no-validate,flush-cache,force-cache,name:,path:,\
-rootfs:,mapped-uid: -- "$@")
+rootfs:,mapped-uid:,mapped-gid: -- "$@")
 
 if [ $? -ne 0 ]; then
     usage
@@ -207,6 +209,7 @@ while :; do
         --path)             LXC_PATH=$2; shift 2;;
         --rootfs)           LXC_ROOTFS=$2; shift 2;;
         --mapped-uid)       LXC_MAPPED_UID=$2; shift 2;;
+        --mapped-gid)       LXC_MAPPED_GID=$2; shift 2;;
         *)                  break;;
     esac
 done
@@ -434,6 +437,9 @@ if [ "$DOWNLOAD_USE_CACHE" = "false" ]; then
         if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then
             chown -R $LXC_MAPPED_UID $LXC_CACHE_BASE >/dev/null 2>&1 || true
         fi
+        if [ -n "$LXC_MAPPED_GID" ] && [ "$LXC_MAPPED_GID" != "-1" ]; then
+            chgrp -R $LXC_MAPPED_GID $LXC_CACHE_BASE >/dev/null 2>&1 || true
+        fi
         echo "The image cache is now ready"
     fi
 else
@@ -527,6 +533,9 @@ done
 if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then
     chown $LXC_MAPPED_UID $LXC_PATH/config $LXC_PATH/fstab >/dev/null 2>&1 || true
 fi
+if [ -n "$LXC_MAPPED_GID" ] && [ "$LXC_MAPPED_GID" != "-1" ]; then
+    chgrp $LXC_MAPPED_GID $LXC_PATH/config $LXC_PATH/fstab >/dev/null 2>&1 || true
+fi
 
 if [ -e "$(relevant_file create-message)" ]; then
     echo ""
index c0566e84d39311d86283eb7c87afcf61d6265b48..07cb87d9b6824a7efcb600d74b988b92d228ea4c 100644 (file)
@@ -147,7 +147,7 @@ EOF
     return 0
 }
 
-options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds:u: -l arch:,help,rootfs:,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream:,userdata:,mapped-uid: -- "$@")
+options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds:u: -l arch:,help,rootfs:,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream:,userdata:,mapped-uid:,mapped-gid: -- "$@")
 if [ $? -ne 0 ]; then
     usage $(basename $0)
     exit 1
@@ -155,6 +155,7 @@ fi
 eval set -- "$options"
 
 mapped_uid=-1
+mapped_gid=-1
 # default release is precise, or the systems release if recognized
 release=precise
 if [ -f /etc/lsb-release ]; then
@@ -216,12 +217,12 @@ do
     -C|--cloud)        cloneargs[${#cloneargs[@]}]="--cloud"; shift 1;;
     -S|--auth-key)     cloneargs[${#cloneargs[@]}]="--auth-key=$2"; shift 2;;
     --mapped-uid)      mapped_uid=$2; shift 2;;
+    --mapped-gid)      mapped_gid=$2; shift 2;;
     --)                shift 1; break ;;
         *)              break ;;
     esac
 done
 
-echo "mapped_uid is .$mapped_uid."
 cloneargs=( "--name=$name" "${cloneargs[@]}" )
 
 if [ $debug -eq 1 ]; then
@@ -390,6 +391,11 @@ if [ $mapped_uid -ne -1 ]; then
     chown -R $mapped_uid $STATE_DIR
     chown -R $mapped_uid $cache
 fi
+if [ $mapped_gid -ne -1 ]; then
+    chgrp $mapped_gid $path/config
+    chgrp -R $mapped_gid $STATE_DIR
+    chgrp -R $mapped_gid $cache
+fi
 
 echo "Container $name created."
 exit 0