Unverified Commit bf31b337 by Ruben Jenster Committed by Christian Brauner

confile: add lxc.init.groups to keep additional groups

parent 5a7f1dc6
......@@ -3919,6 +3919,7 @@ void lxc_conf_free(struct lxc_conf *conf)
free(conf->rcfile);
free(conf->execute_cmd);
free(conf->init_cmd);
free(conf->init_groups.list);
free(conf->init_cwd);
free(conf->unexpanded_config);
free(conf->syslog);
......
......@@ -417,6 +417,10 @@ struct lxc_conf {
* should run under when using lxc-execute */
uid_t init_uid;
gid_t init_gid;
struct {
int size;
gid_t *list;
} init_groups;
/* indicator if the container will be destroyed on shutdown */
unsigned int ephemeral;
......
......@@ -94,6 +94,7 @@ lxc_config_define(init_cmd);
lxc_config_define(init_cwd);
lxc_config_define(init_gid);
lxc_config_define(init_uid);
lxc_config_define(init_groups);
lxc_config_define(keyring_session);
lxc_config_define(log_file);
lxc_config_define(log_level);
......@@ -211,6 +212,7 @@ static struct lxc_config_t config_jump_table[] = {
{ "lxc.include", set_config_includefiles, get_config_includefiles, clr_config_includefiles, },
{ "lxc.init.cmd", set_config_init_cmd, get_config_init_cmd, clr_config_init_cmd, },
{ "lxc.init.gid", set_config_init_gid, get_config_init_gid, clr_config_init_gid, },
{ "lxc.init.groups", set_config_init_groups, get_config_init_groups, clr_config_init_groups, },
{ "lxc.init.uid", set_config_init_uid, get_config_init_uid, clr_config_init_uid, },
{ "lxc.init.cwd", set_config_init_cwd, get_config_init_cwd, clr_config_init_cwd, },
{ "lxc.keyring.session", set_config_keyring_session, get_config_keyring_session, clr_config_keyring_session },
......@@ -1178,6 +1180,53 @@ static int set_config_init_gid(const char *key, const char *value,
return 0;
}
static int set_config_init_groups(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
__do_free char *value_dup = NULL;
__do_free gid_t *init_groups = NULL;
int num_groups = 0;
int iter = 0;
char *token;
if (lxc_config_value_empty(value))
return clr_config_init_groups(key, lxc_conf, NULL);
value_dup = strdup(value);
if (!value_dup)
return -ENOMEM;
lxc_iterate_parts(token, value_dup, ",")
num_groups++;
if (num_groups == 0)
return clr_config_init_groups(key, lxc_conf, NULL);
init_groups = zalloc(sizeof(gid_t) * num_groups);
if (!init_groups)
return ret_errno(ENOMEM);
/* Restore duplicated value so we can call lxc_iterate_parts() again. */
strcpy(value_dup, value);
lxc_iterate_parts(token, value_dup, ",") {
int ret;
gid_t group;
ret = lxc_safe_uint(token, &group);
if (ret)
return ret;
init_groups[iter++] = group;
}
lxc_conf->init_groups.size = num_groups;
lxc_conf->init_groups.list = move_ptr(init_groups);
return 0;
}
static int set_config_hooks(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
......@@ -4278,6 +4327,26 @@ static int get_config_init_gid(const char *key, char *retv, int inlen,
return lxc_get_conf_int(c, retv, inlen, c->init_gid);
}
static int get_config_init_groups(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
int fulllen = 0, len;
if (!retv)
inlen = 0;
else
memset(retv, 0, inlen);
if (c->init_groups.size == 0)
return 0;
for (int i = 0; i < c->init_groups.size; i++)
strprint(retv, inlen, "%s%d", (i > 0) ? "," : "",
c->init_groups.list[i]);
return fulllen;
}
static int get_config_ephemeral(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
......@@ -4964,6 +5033,14 @@ static inline int clr_config_init_gid(const char *key, struct lxc_conf *c,
return 0;
}
static inline int clr_config_init_groups(const char *key, struct lxc_conf *c,
void *data)
{
free_disarm(c->init_groups.list);
c->init_groups.size = 0;
return 0;
}
static inline int clr_config_ephemeral(const char *key, struct lxc_conf *c,
void *data)
{
......
......@@ -1406,12 +1406,21 @@ static int do_start(void *data)
* we switched to root in the new user namespace further above. Only
* drop groups if we can, so ensure that we have necessary privilege.
*/
if (lxc_list_empty(&handler->conf->id_map))
if (lxc_list_empty(&handler->conf->id_map)) {
#if HAVE_LIBCAP
if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE))
#endif
if (!lxc_drop_groups())
goto out_warn_father;
{
if (handler->conf->init_groups.size > 0) {
if (!lxc_setgroups(handler->conf->init_groups.list,
handler->conf->init_groups.size))
goto out_warn_father;
} else {
if (!lxc_drop_groups())
goto out_warn_father;
}
}
}
if (!lxc_switch_uid_gid(new_uid, new_gid))
goto out_warn_father;
......
......@@ -136,6 +136,34 @@ int main(int argc, char *argv[])
}
printf("lxc.init_gid returned %d %s\n", ret, v2);
if (!c->set_config_item(c, "lxc.init.groups", "")) {
fprintf(stderr, "%d: failed to set init_groups\n", __LINE__);
goto out;
}
if (!c->set_config_item(c, "lxc.init.groups", "10,20,foo,40")) {
printf("failed to set init_groups to '10,20,foo,40' as expected\n");
} else {
goto out;
}
if (!c->set_config_item(c, "lxc.init.groups", "10,20,30,40")) {
fprintf(stderr, "%d: failed to set init_groups\n", __LINE__);
goto out;
}
ret = c->get_config_item(c, "lxc.init.groups", v2, 255);
if (ret < 0) {
fprintf(stderr, "%d: get_config_item(lxc.init_gid) returned %d\n",
__LINE__, ret);
goto out;
}
ret = strcmp("10,20,30,40", v2);
printf("lxc.init_groups returned %d %s\n", ret, v2);
if (ret != 0) {
goto out;
}
#define HNAME "hostname1"
// demonstrate proper usage:
char *alloced;
......
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