From 61bfa0ce515288897b93640507e48f09f0d78010 Mon Sep 17 00:00:00 2001 From: wujing Date: Tue, 14 Apr 2020 23:17:04 -0400 Subject: [PATCH 26/49] Supporting UID GID configuration Signed-off-by: wujing --- src/lxc/attach.c | 16 ++++++++ src/lxc/conf.c | 19 ++++++++- src/lxc/conf.h | 4 ++ src/lxc/start.c | 8 ++++ src/lxc/tools/lxc_attach.c | 99 +++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 139 insertions(+), 7 deletions(-) diff --git a/src/lxc/attach.c b/src/lxc/attach.c index 33946bb..c77b929 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -749,8 +749,10 @@ static int attach_child_main(struct attach_clone_payload *payload) goto on_error; } +#ifndef HAVE_ISULAD if (!lxc_setgroups(0, NULL) && errno != EPERM) goto on_error; +#endif if (options->namespaces & CLONE_NEWUSER) { /* Check whether nsuid 0 has a mapping. */ @@ -892,6 +894,12 @@ static int attach_child_main(struct attach_clone_payload *payload) if (new_gid == ns_root_gid) new_gid = LXC_INVALID_GID; +#ifdef HAVE_ISULAD + if (!lxc_setgroups(init_ctx->container->lxc_conf->init_groups_len, + init_ctx->container->lxc_conf->init_groups)) + goto on_error; +#endif + /* Make sure that the processes STDIO is correctly owned by the user that we are switching to */ ret = fix_stdio_permissions(new_uid); if (ret) @@ -1058,6 +1066,14 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, } conf = init_ctx->container->lxc_conf; +#ifdef HAVE_ISULAD + // always switch uid and gid for attach + if (options->uid == -1) + options->uid = init_ctx->container->lxc_conf->init_uid; + if (options->gid == -1) + options->gid = init_ctx->container->lxc_conf->init_gid; +#endif + if (!fetch_seccomp(init_ctx->container, options)) WARN("Failed to get seccomp policy"); diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 71fd6f9..43ef067 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -5100,6 +5100,7 @@ void lxc_conf_free(struct lxc_conf *conf) close(conf->exit_fd); } lxc_clear_init_args(conf); + lxc_clear_init_groups(conf); lxc_clear_populate_devices(conf); lxc_clear_rootfs_masked_paths(conf); lxc_clear_rootfs_ro_paths(conf); @@ -5919,11 +5920,25 @@ struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings) /*isulad clear init args*/ int lxc_clear_init_args(struct lxc_conf *lxc_conf) { - size_t i; + int i; - for (i = 0; i < lxc_conf->init_argc; i++) + for (i = 0; i < lxc_conf->init_argc; i++) { free(lxc_conf->init_argv[i]); + lxc_conf->init_argv[i] = NULL; + } free(lxc_conf->init_argv); + lxc_conf->init_argv = NULL; + lxc_conf->init_argc = 0; + + return 0; +} + +/*isulad clear init groups*/ +int lxc_clear_init_groups(struct lxc_conf *lxc_conf) +{ + free(lxc_conf->init_groups); + lxc_conf->init_groups = NULL; + lxc_conf->init_groups_len = 0; return 0; } diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 61c3383..879e427 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -451,6 +451,9 @@ struct lxc_conf { char **init_argv; size_t init_argc; + gid_t *init_groups; + size_t init_groups_len; + /* populate devices*/ struct lxc_list populate_devs; mode_t umask; //umask value @@ -548,6 +551,7 @@ extern int parse_mntopts(const char *mntopts, unsigned long *mntflags, #ifdef HAVE_ISULAD // isulad add int lxc_clear_init_args(struct lxc_conf *lxc_conf); +int lxc_clear_init_groups(struct lxc_conf *lxc_conf); int lxc_clear_populate_devices(struct lxc_conf *c); int lxc_clear_rootfs_masked_paths(struct lxc_conf *c); int lxc_clear_rootfs_ro_paths(struct lxc_conf *c); diff --git a/src/lxc/start.c b/src/lxc/start.c index 4f45776..e2311ec 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -1685,8 +1685,16 @@ static int do_start(void *data) #if HAVE_LIBCAP if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE)) #endif + #ifdef HAVE_ISULAD + /* isulad: set groups for init process, and before we set uid and gid */ + if (!lxc_setgroups(handler->conf->init_groups_len, handler->conf->init_groups)) { + ERROR("Can not set groups"); + goto out_warn_father; + } + #else if (!lxc_setgroups(0, NULL)) goto out_warn_father; + #endif if (!lxc_switch_uid_gid(new_uid, new_gid)) goto out_warn_father; diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c index 47ac2f2..b068c9a 100644 --- a/src/lxc/tools/lxc_attach.c +++ b/src/lxc/tools/lxc_attach.c @@ -72,9 +72,11 @@ static const struct option my_longopts[] = { {"set-var", required_argument, 0, 'v'}, {"pty-log", required_argument, 0, 'L'}, {"rcfile", required_argument, 0, 'f'}, +#ifndef HAVE_ISULAD {"uid", required_argument, 0, 'u'}, {"gid", required_argument, 0, 'g'}, -#ifdef HAVE_ISULAD +#else + {"user", required_argument, 0, 'u'}, {"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, /* isulad add terminal fifos*/ {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, @@ -130,9 +132,18 @@ Options :\n\ multiple times.\n\ -f, --rcfile=FILE\n\ Load configuration file FILE\n\ +" +#ifndef HAVE_ISULAD +"\ -u, --uid=UID Execute COMMAND with UID inside the container\n\ -g, --gid=GID Execute COMMAND with GID inside the container\n\ -", +" +#else +"\ + --user User ID (format: UID[:GID])\n\ +" +#endif +, .options = my_longopts, .parser = my_parser, .checker = NULL, @@ -142,6 +153,71 @@ Options :\n\ .gid = LXC_INVALID_GID, }; +#ifdef HAVE_ISULAD +static int parse_user_id(const char *username, char **uid, char **gid, char **tmp_dup) +{ + char *tmp = NULL; + char *pdot = NULL; + + if (uid == NULL || gid == NULL || tmp_dup == NULL) { + return -1; + } + + if (username != NULL) { + tmp = strdup(username); + if (tmp == NULL) { + ERROR("Failed to duplicate user name"); + return -1; + } + + // for free tmp in caller + *tmp_dup = tmp; + pdot = strstr(tmp, ":"); + if (pdot != NULL) { + *pdot = '\0'; + if (pdot != tmp) { + // uid found + *uid = tmp; + } + + if (*(pdot + 1) != '\0') { + // gid found + *gid = pdot + 1; + } + } else { + // No : found + if (*tmp != '\0') { + *uid = tmp; + } + } + } + + return 0; +} + +static int get_attach_uid_gid(const char *username, uid_t *user_id, gid_t *group_id) +{ + char *tmp = NULL; + char *uid = NULL; + char *gid = NULL; + + // parse uid and gid by username + if (parse_user_id(username, &uid, &gid, &tmp) != 0) { + return -1; + } + + if (uid != NULL) { + *user_id = (unsigned int)atoll(uid); + } + if (gid != NULL) { + *group_id = (unsigned int)atoll(gid); + } + + free(tmp); + return 0; +} +#endif + static int my_parser(struct lxc_arguments *args, int c, char *arg) { int ret; @@ -199,6 +275,7 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) case 'f': args->rcfile = arg; break; +#ifndef HAVE_ISULAD case 'u': if (lxc_safe_uint(arg, &args->uid) < 0) return -1; @@ -207,7 +284,13 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) if (lxc_safe_uint(arg, &args->gid) < 0) return -1; break; -#ifdef HAVE_ISULAD +#else + case 'u': + if (get_attach_uid_gid(arg, &args->uid, &args->gid) != 0) { + ERROR("Failed to get attach user U/GID"); + return -1; + } + break; case OPT_INPUT_FIFO: args->terminal_fifos[0] = arg; break; @@ -286,7 +369,7 @@ static int lxc_attach_create_log_file(const char *log_file) #ifdef HAVE_ISULAD // isulad: send '128 + signal' if container is killed by signal. -#define ExitSignalOffset 128 +#define EXIT_SIGNAL_OFFSET 128 /*isulad: attach with terminal*/ static int do_attach_foreground(struct lxc_container *c, lxc_attach_command_t *command, @@ -316,7 +399,7 @@ static int do_attach_foreground(struct lxc_container *c, lxc_attach_command_t *c if (WIFSIGNALED(ret)) { signal = WTERMSIG(ret); - wexit = ExitSignalOffset + signal; + wexit = EXIT_SIGNAL_OFFSET + signal; } out: if (c->lxc_conf->errmsg) @@ -515,6 +598,12 @@ int main(int argc, char *argv[]) } } + if (my_args.uid != LXC_INVALID_UID) + attach_options.uid = my_args.uid; + + if (my_args.gid != LXC_INVALID_GID) + attach_options.gid = my_args.gid; + attach_options.suffix = my_args.suffix; /* isulad: add do attach background */ -- 1.8.3.1