From: Tomas Mraz Date: Mon, 7 Mar 2011 13:27:46 +0000 (+0100) Subject: Set only groups in the process handling PAM calls. Keep uids at 0 X-Git-Tag: cronie1.4.7~16 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4d8294bcf025b0467c6fdc1943a9008e280d38c5;p=cronie Set only groups in the process handling PAM calls. Keep uids at 0 so the process is not killable by the user. --- diff --git a/src/do_command.c b/src/do_command.c index 1a80f48..e664d4c 100644 --- a/src/do_command.c +++ b/src/do_command.c @@ -166,9 +166,6 @@ static int child_process(entry * e, user * u, char **jobenv) { case 0: Debug(DPROC, ("[%ld] grandchild process fork()'ed\n", (long) getpid())) - if (cron_change_user_permanently(e->pwd, env_get("HOME", jobenv)) < 0) - _exit(ERROR_EXIT); - /* write a log message. we've waited this long to do it * because it was not until now that we knew the PID that * the actual user command shell was going to get and the @@ -181,9 +178,8 @@ static int child_process(entry * e, user * u, char **jobenv) { free(x); } - /* that's the last thing we'll log. close the log files. - */ - log_close(); + if (cron_change_user_permanently(e->pwd, env_get("HOME", jobenv)) < 0) + _exit(ERROR_EXIT); /* get new pgrp, void tty, etc. */ @@ -414,12 +410,11 @@ static int child_process(entry * e, user * u, char **jobenv) { gethostname(hostname, MAXHOSTNAMELEN); if (MailCmd[0] == '\0') { - if (strlens(MAILFMT, MAILARG, mailfrom, NULL) + 1 + if (snprintf(mailcmd, sizeof mailcmd, MAILFMT, MAILARG, mailfrom) >= sizeof mailcmd) { fprintf(stderr, "mailcmd too long\n"); (void) _exit(ERROR_EXIT); } - (void) sprintf(mailcmd, MAILFMT, MAILARG, mailfrom); } else { strncpy(mailcmd, MailCmd, MAX_COMMAND); diff --git a/src/funcs.h b/src/funcs.h index fabd0b2..f0e576e 100644 --- a/src/funcs.h +++ b/src/funcs.h @@ -93,7 +93,7 @@ int cron_open_security_session( struct passwd *pw ); void cron_close_security_session( void ); -int cron_change_user( struct passwd *pw ); +int cron_change_groups( struct passwd *pw ); int cron_change_user_permanently( struct passwd *pw, char *homedir ); diff --git a/src/popen.c b/src/popen.c index 48afbb2..baf0724 100644 --- a/src/popen.c +++ b/src/popen.c @@ -108,6 +108,9 @@ FILE *cron_popen(char *program, const char *type, struct passwd *pw) { sa.sa_handler = SIG_DFL; sigaction(SIGPIPE, &sa, NULL); + if (cron_change_user_permanently(pw, pw->pw_dir) != 0) + _exit(2); + if (execvp(argv[0], argv) < 0) { int save_errno = errno; diff --git a/src/security.c b/src/security.c index 6f6ff39..5816205 100644 --- a/src/security.c +++ b/src/security.c @@ -142,13 +142,10 @@ int cron_set_job_security_context(entry * e, user * u, char ***jobenv) { } #endif - if (cron_change_user(e->pwd) != 0) { - log_it(e->pwd->pw_name, getpid(), "ERROR", "failed to change user", 0); + if (cron_change_groups(e->pwd) != 0) { return -1; } - log_close(); - time_t job_run_time = time(0L); if ((minutely_time > 0) && ((job_run_time / 60) != (minutely_time / 60))) { @@ -211,11 +208,9 @@ void cron_close_pam(void) { #endif } -int cron_change_user(struct passwd *pw) { +int cron_change_groups(struct passwd *pw) { pid_t pid = getpid(); - /* set our directory, uid and gid. Set gid first, since once - * we set uid, we've lost root privledges. - */ + if (setgid(pw->pw_gid) != 0) { log_it("CRON", pid, "ERROR", "setgid failed", errno); return -1; @@ -226,10 +221,11 @@ int cron_change_user(struct passwd *pw) { return -1; } - if (setreuid(pw->pw_uid, -1) != 0) { - log_it("CRON", pid, "ERROR", "setreuid failed", errno); - return -1; - } +#if defined(WITH_PAM) + /* credentials may take form of supplementary groups so reinitialize + * them here */ + pam_setcred(pamh, PAM_REINITIALIZE_CRED | PAM_SILENT); +#endif return 0; } @@ -239,11 +235,14 @@ int cron_change_user_permanently(struct passwd *pw, char *homedir) { log_it("CRON", getpid(), "ERROR", "setreuid failed", errno); return -1; } + if (chdir(homedir) == -1) { log_it("CRON", getpid(), "ERROR chdir failed", homedir, errno); return -1; } + log_close(); + return 0; }