[lxc-devel] [PATCH 1/1] create: pass --mapped-gid to templates next to --mapped-uid

Stéphane Graber stgraber at ubuntu.com
Tue Feb 4 21:30:37 UTC 2014


On Tue, Feb 04, 2014 at 01:33:10PM -0600, Serge Hallyn wrote:
> That way templates can fix group ownership alongside uid ownership.
> 
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>

As discussed on IRC, Ack but with a small inline change that I'll do to
fix invalid --mapped-uid value with the current patch.

Acked-by: Stéphane Graber <stgraber at ubuntu.com>

> ---
>  src/lxc/conf.c                | 14 +++++++-------
>  src/lxc/conf.h                |  4 ++--
>  src/lxc/lxccontainer.c        | 35 +++++++++++++++++++++++++++++++----
>  templates/lxc-download.in     | 13 +++++++++++--
>  templates/lxc-ubuntu-cloud.in | 10 ++++++++--
>  5 files changed, 59 insertions(+), 17 deletions(-)
> 
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index d4578f3..fed5327 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -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));
> diff --git a/src/lxc/conf.h b/src/lxc/conf.h
> index e5a23ec..16d7122 100644
> --- a/src/lxc/conf.h
> +++ b/src/lxc/conf.h
> @@ -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);
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 85c644a..e3c2e10 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -1004,13 +1004,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,21 +1028,48 @@ 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-4] = txtuid;
> +			n2[n2args-3] = "--mapped-gid";
> +			snprintf(txtuid, 20, "%d", hostgid_mapped);

^ This will override txtuid leading to both --mapped-uid and
--mapped-gid pointing to the gid value. I'll fix that by using a
separate txtgid variable.

>  			n2[n2args-2] = txtuid;
>  			n2[n2args-1] = NULL;
>  			free(newargv);
> diff --git a/templates/lxc-download.in b/templates/lxc-download.in
> index 3ef9fba..2a6e51d 100644
> --- a/templates/lxc-download.in
> +++ b/templates/lxc-download.in
> @@ -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 ""
> diff --git a/templates/lxc-ubuntu-cloud.in b/templates/lxc-ubuntu-cloud.in
> index c0566e8..07cb87d 100644
> --- a/templates/lxc-ubuntu-cloud.in
> +++ b/templates/lxc-ubuntu-cloud.in
> @@ -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
> -- 
> 1.9.rc1
> 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20140204/44ba0fe2/attachment-0001.pgp>


More information about the lxc-devel mailing list