Commit 2133f58c by Serge Hallyn Committed by Stéphane Graber

create: pass --mapped-gid to templates next to --mapped-uid

That way templates can fix group ownership alongside uid ownership. Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 8ec981fc
...@@ -3177,13 +3177,13 @@ bool get_mapped_rootid(struct lxc_conf *conf, enum idtype idtype, ...@@ -3177,13 +3177,13 @@ bool get_mapped_rootid(struct lxc_conf *conf, enum idtype idtype,
return false; 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 lxc_list *it;
struct id_map *map; struct id_map *map;
lxc_list_for_each(it, &conf->id_map) { lxc_list_for_each(it, &conf->id_map) {
map = it->elem; map = it->elem;
if (map->idtype != ID_TYPE_UID) if (map->idtype != idtype)
continue; continue;
if (id >= map->hostid && id < map->hostid + map->range) if (id >= map->hostid && id < map->hostid + map->range)
return (id - map->hostid) + map->nsid; return (id - map->hostid) + map->nsid;
...@@ -3191,15 +3191,15 @@ int mapped_hostid(int id, struct lxc_conf *conf) ...@@ -3191,15 +3191,15 @@ int mapped_hostid(int id, struct lxc_conf *conf)
return -1; 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 lxc_list *it;
struct id_map *map; struct id_map *map;
uid_t freeid = 0; unsigned int freeid = 0;
again: again:
lxc_list_for_each(it, &conf->id_map) { lxc_list_for_each(it, &conf->id_map) {
map = it->elem; map = it->elem;
if (map->idtype != ID_TYPE_UID) if (map->idtype != idtype)
continue; continue;
if (freeid >= map->nsid && freeid < map->nsid + map->range) { if (freeid >= map->nsid && freeid < map->nsid + map->range) {
freeid = map->nsid + map->range; freeid = map->nsid + map->range;
...@@ -3992,7 +3992,7 @@ static int run_userns_fn(void *data) ...@@ -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) 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 lxc_list *new = NULL, *tmp, *it, *next;
struct id_map *entry; struct id_map *entry;
...@@ -4004,7 +4004,7 @@ static struct lxc_list *idmap_add_id(struct lxc_conf *conf, uid_t uid) ...@@ -4004,7 +4004,7 @@ static struct lxc_list *idmap_add_id(struct lxc_conf *conf, uid_t uid)
lxc_list_init(new); lxc_list_init(new);
if (hostid_mapped < 0) { if (hostid_mapped < 0) {
hostid_mapped = find_unmapped_nsuid(conf); hostid_mapped = find_unmapped_nsuid(conf, ID_TYPE_UID);
if (hostid_mapped < 0) if (hostid_mapped < 0)
goto err; goto err;
tmp = malloc(sizeof(*tmp)); tmp = malloc(sizeof(*tmp));
......
...@@ -371,8 +371,8 @@ extern int lxc_setup(struct lxc_handler *handler); ...@@ -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 void lxc_rename_phys_nics_on_shutdown(struct lxc_conf *conf);
extern int find_unmapped_nsuid(struct lxc_conf *conf); extern int find_unmapped_nsuid(struct lxc_conf *conf, enum idtype idtype);
extern int mapped_hostid(int id, struct lxc_conf *conf); 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 chown_mapped_root(char *path, struct lxc_conf *conf);
extern int ttys_shift_ids(struct lxc_conf *c); extern int ttys_shift_ids(struct lxc_conf *c);
extern int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data); extern int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data);
......
...@@ -977,6 +977,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet ...@@ -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)) { if (geteuid() != 0 && !lxc_list_empty(&conf->id_map)) {
int n2args = 1; int n2args = 1;
char txtuid[20]; char txtuid[20];
char txtgid[20];
char **n2 = malloc(n2args * sizeof(*n2)); char **n2 = malloc(n2args * sizeof(*n2));
struct lxc_list *it; struct lxc_list *it;
struct id_map *map; struct id_map *map;
...@@ -1004,13 +1005,13 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet ...@@ -1004,13 +1005,13 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet
if (ret < 0 || ret >= 200) if (ret < 0 || ret >= 200)
exit(1); 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; int extraargs = hostid_mapped >= 0 ? 1 : 3;
n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *)); n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
if (!n2) if (!n2)
exit(1); exit(1);
if (hostid_mapped < 0) { if (hostid_mapped < 0) {
hostid_mapped = find_unmapped_nsuid(conf); hostid_mapped = find_unmapped_nsuid(conf, ID_TYPE_UID);
n2[n2args++] = "-m"; n2[n2args++] = "-m";
if (hostid_mapped < 0) { if (hostid_mapped < 0) {
ERROR("Could not find free uid to map"); 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 ...@@ -1028,22 +1029,49 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet
exit(1); 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++] = "--"; n2[n2args++] = "--";
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
n2[i + n2args] = newargv[i]; n2[i + n2args] = newargv[i];
n2args += nargs; n2args += nargs;
// Finally add "--mapped-uid $uid" to tell template what to chown // Finally add "--mapped-uid $uid" to tell template what to chown
// cached images to // cached images to
n2args += 2; n2args += 4;
n2 = realloc(n2, n2args * sizeof(char *)); n2 = realloc(n2, n2args * sizeof(char *));
if (!n2) { if (!n2) {
SYSERROR("out of memory"); SYSERROR("out of memory");
exit(1); exit(1);
} }
// note n2[n2args-1] is NULL // note n2[n2args-1] is NULL
n2[n2args-3] = "--mapped-uid"; n2[n2args-5] = "--mapped-uid";
snprintf(txtuid, 20, "%d", hostid_mapped); 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; n2[n2args-1] = NULL;
free(newargv); free(newargv);
newargv = n2; newargv = n2;
......
...@@ -51,6 +51,7 @@ LXC_NAME= ...@@ -51,6 +51,7 @@ LXC_NAME=
LXC_PATH= LXC_PATH=
LXC_ROOTFS= LXC_ROOTFS=
LXC_MAPPED_UID= LXC_MAPPED_UID=
LXC_MAPPED_GID=
# Some useful functions # Some useful functions
cleanup() { cleanup() {
...@@ -175,14 +176,15 @@ LXC internal arguments (do not pass manually!): ...@@ -175,14 +176,15 @@ LXC internal arguments (do not pass manually!):
[ --name <name> ]: The container name [ --name <name> ]: The container name
[ --path <path> ]: The path to the container [ --path <path> ]: The path to the container
[ --rootfs <rootfs> ]: The path to the container's rootfs [ --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 EOF
return 0 return 0
} }
options=$(getopt -o d:r:a:hl -l dist:,release:,arch:,help,list,variant:,\ options=$(getopt -o d:r:a:hl -l dist:,release:,arch:,help,list,variant:,\
server:,keyid:,no-validate,flush-cache,force-cache,name:,path:,\ server:,keyid:,no-validate,flush-cache,force-cache,name:,path:,\
rootfs:,mapped-uid: -- "$@") rootfs:,mapped-uid:,mapped-gid: -- "$@")
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
usage usage
...@@ -207,6 +209,7 @@ while :; do ...@@ -207,6 +209,7 @@ while :; do
--path) LXC_PATH=$2; shift 2;; --path) LXC_PATH=$2; shift 2;;
--rootfs) LXC_ROOTFS=$2; shift 2;; --rootfs) LXC_ROOTFS=$2; shift 2;;
--mapped-uid) LXC_MAPPED_UID=$2; shift 2;; --mapped-uid) LXC_MAPPED_UID=$2; shift 2;;
--mapped-gid) LXC_MAPPED_GID=$2; shift 2;;
*) break;; *) break;;
esac esac
done done
...@@ -434,6 +437,9 @@ if [ "$DOWNLOAD_USE_CACHE" = "false" ]; then ...@@ -434,6 +437,9 @@ if [ "$DOWNLOAD_USE_CACHE" = "false" ]; then
if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then
chown -R $LXC_MAPPED_UID $LXC_CACHE_BASE >/dev/null 2>&1 || true chown -R $LXC_MAPPED_UID $LXC_CACHE_BASE >/dev/null 2>&1 || true
fi 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" echo "The image cache is now ready"
fi fi
else else
...@@ -527,6 +533,9 @@ done ...@@ -527,6 +533,9 @@ done
if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then 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 chown $LXC_MAPPED_UID $LXC_PATH/config $LXC_PATH/fstab >/dev/null 2>&1 || true
fi 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 if [ -e "$(relevant_file create-message)" ]; then
echo "" echo ""
......
...@@ -147,7 +147,7 @@ EOF ...@@ -147,7 +147,7 @@ EOF
return 0 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 if [ $? -ne 0 ]; then
usage $(basename $0) usage $(basename $0)
exit 1 exit 1
...@@ -155,6 +155,7 @@ fi ...@@ -155,6 +155,7 @@ fi
eval set -- "$options" eval set -- "$options"
mapped_uid=-1 mapped_uid=-1
mapped_gid=-1
# default release is precise, or the systems release if recognized # default release is precise, or the systems release if recognized
release=precise release=precise
if [ -f /etc/lsb-release ]; then if [ -f /etc/lsb-release ]; then
...@@ -216,12 +217,12 @@ do ...@@ -216,12 +217,12 @@ do
-C|--cloud) cloneargs[${#cloneargs[@]}]="--cloud"; shift 1;; -C|--cloud) cloneargs[${#cloneargs[@]}]="--cloud"; shift 1;;
-S|--auth-key) cloneargs[${#cloneargs[@]}]="--auth-key=$2"; shift 2;; -S|--auth-key) cloneargs[${#cloneargs[@]}]="--auth-key=$2"; shift 2;;
--mapped-uid) mapped_uid=$2; shift 2;; --mapped-uid) mapped_uid=$2; shift 2;;
--mapped-gid) mapped_gid=$2; shift 2;;
--) shift 1; break ;; --) shift 1; break ;;
*) break ;; *) break ;;
esac esac
done done
echo "mapped_uid is .$mapped_uid."
cloneargs=( "--name=$name" "${cloneargs[@]}" ) cloneargs=( "--name=$name" "${cloneargs[@]}" )
if [ $debug -eq 1 ]; then if [ $debug -eq 1 ]; then
...@@ -390,6 +391,11 @@ if [ $mapped_uid -ne -1 ]; then ...@@ -390,6 +391,11 @@ if [ $mapped_uid -ne -1 ]; then
chown -R $mapped_uid $STATE_DIR chown -R $mapped_uid $STATE_DIR
chown -R $mapped_uid $cache chown -R $mapped_uid $cache
fi 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." echo "Container $name created."
exit 0 exit 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment