X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fexecute.c;h=40af7d65f1864717f2ce34f72307c434256cbfd1;hp=b00ccde4d55a47bfb73a80d5681df8e4dd1add31;hb=ddd88763921a1534081ed28e36f6712a85449005;hpb=ae556c210942cb6986c6d77b58505b5daa66bbe2 diff --git a/src/execute.c b/src/execute.c index b00ccde4d..40af7d65f 100644 --- a/src/execute.c +++ b/src/execute.c @@ -551,7 +551,7 @@ static int restore_confirm_stdio(const ExecContext *context, static int get_group_creds(const char *groupname, gid_t *gid) { struct group *g; - unsigned long lu; + gid_t id; assert(groupname); assert(gid); @@ -564,9 +564,9 @@ static int get_group_creds(const char *groupname, gid_t *gid) { return 0; } - if (safe_atolu(groupname, &lu) >= 0) { + if (parse_gid(groupname, &id) >= 0) { errno = 0; - g = getgrgid((gid_t) lu); + g = getgrgid(id); } else { errno = 0; g = getgrnam(groupname); @@ -579,52 +579,6 @@ static int get_group_creds(const char *groupname, gid_t *gid) { return 0; } -static int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home) { - struct passwd *p; - unsigned long lu; - - assert(username); - assert(*username); - assert(uid); - assert(gid); - assert(home); - - /* We enforce some special rules for uid=0: in order to avoid - * NSS lookups for root we hardcode its data. */ - - if (streq(*username, "root") || streq(*username, "0")) { - *username = "root"; - *uid = 0; - *gid = 0; - *home = "/root"; - return 0; - } - - if (safe_atolu(*username, &lu) >= 0) { - errno = 0; - p = getpwuid((uid_t) lu); - - /* If there are multiple users with the same id, make - * sure to leave $USER to the configured value instead - * of the first occurrence in the database. However if - * the uid was configured by a numeric uid, then let's - * pick the real username from /etc/passwd. */ - if (*username && p) - *username = p->pw_name; - } else { - errno = 0; - p = getpwnam(*username); - } - - if (!p) - return errno != 0 ? -errno : -ESRCH; - - *uid = p->pw_uid; - *gid = p->pw_gid; - *home = p->pw_dir; - return 0; -} - static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) { bool keep_groups = false; int r; @@ -817,9 +771,6 @@ static int setup_pam( close_session = true; - if ((pam_code = pam_setcred(handle, PAM_ESTABLISH_CRED | PAM_SILENT)) != PAM_SUCCESS) - goto fail; - if ((!(e = pam_getenvlist(handle)))) { pam_code = PAM_BUF_ERR; goto fail; @@ -846,7 +797,7 @@ static int setup_pam( /* This string must fit in 10 chars (i.e. the length * of "/sbin/init") */ - rename_process("sd:pam"); + rename_process("sd(PAM)"); /* Make sure we don't keep open the passed fds in this child. We assume that otherwise only those fds are @@ -864,13 +815,20 @@ static int setup_pam( /* Check if our parent process might already have * died? */ if (getppid() == parent_pid) { - if (sigwait(&ss, &sig) < 0) - goto child_finish; + for (;;) { + if (sigwait(&ss, &sig) < 0) { + if (errno == EINTR) + continue; - assert(sig == SIGTERM); + goto child_finish; + } + + assert(sig == SIGTERM); + break; + } } - /* Only if our parent died we'll end the session */ + /* If our parent died we'll end the session */ if (getppid() != parent_pid) if ((pam_code = pam_close_session(handle, PAM_DATA_SILENT)) != PAM_SUCCESS) goto child_finish; @@ -886,7 +844,7 @@ static int setup_pam( * cleanups, so forget about the handle here. */ handle = NULL; - /* Unblock SIGSUR1 again in the parent */ + /* Unblock SIGTERM again in the parent */ if (sigprocmask(SIG_SETMASK, &old_ss, NULL) < 0) goto fail; @@ -894,6 +852,9 @@ static int setup_pam( * might have opened it, but we don't want this fd around. */ closelog(); + *pam_env = e; + e = NULL; + return 0; fail: @@ -1059,7 +1020,7 @@ int exec_spawn(ExecCommand *command, /* This string must fit in 10 chars (i.e. the length * of "/sbin/init") */ - rename_process("sd.exec"); + rename_process("sd(EXEC)"); /* We reset exactly these signals, since they are the * only ones we set to SIG_IGN in the main daemon. All @@ -1246,16 +1207,14 @@ int exec_spawn(ExecCommand *command, r = EXIT_STDIN; goto fail_child; } - } -#ifdef HAVE_PAM - if (context->pam_name && username) { - if (setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds) < 0) { - r = EXIT_PAM; - goto fail_child; - } + if (cgroup_bondings && context->control_group_modify) + if (cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid) < 0 || + cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid) < 0) { + r = EXIT_CGROUP; + goto fail_child; + } } -#endif if (apply_permissions) if (enforce_groups(context, username, uid) < 0) { @@ -1265,6 +1224,15 @@ int exec_spawn(ExecCommand *command, umask(context->umask); +#ifdef HAVE_PAM + if (context->pam_name && username) { + if (setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds) != 0) { + r = EXIT_PAM; + goto fail_child; + } + } +#endif + if (strv_length(context->read_write_dirs) > 0 || strv_length(context->read_only_dirs) > 0 || strv_length(context->inaccessible_dirs) > 0 || @@ -1649,12 +1617,14 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { "%sWorkingDirectory: %s\n" "%sRootDirectory: %s\n" "%sNonBlocking: %s\n" - "%sPrivateTmp: %s\n", + "%sPrivateTmp: %s\n" + "%sControlGroupModify: %s\n", prefix, c->umask, prefix, c->working_directory ? c->working_directory : "/", prefix, c->root_directory ? c->root_directory : "/", prefix, yes_no(c->non_blocking), - prefix, yes_no(c->private_tmp)); + prefix, yes_no(c->private_tmp), + prefix, yes_no(c->control_group_modify)); STRV_FOREACH(e, c->environment) fprintf(f, "%sEnvironment: %s\n", prefix, *e);