Replace the double fork with a fork + daemonize.
This commit is contained in:
@@ -341,6 +341,9 @@
|
|||||||
/* Define to 1 if you have the `setrlimit' function. */
|
/* Define to 1 if you have the `setrlimit' function. */
|
||||||
#undef HAVE_SETRLIMIT
|
#undef HAVE_SETRLIMIT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setsid' function. */
|
||||||
|
#undef HAVE_SETSID
|
||||||
|
|
||||||
/* Define to 1 if you have the `set_auth_parameters' function. */
|
/* Define to 1 if you have the `set_auth_parameters' function. */
|
||||||
#undef HAVE_SET_AUTH_PARAMETERS
|
#undef HAVE_SET_AUTH_PARAMETERS
|
||||||
|
|
||||||
|
3
configure
vendored
3
configure
vendored
@@ -15506,9 +15506,10 @@ LIBS=$ac_save_LIBS
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for ac_func in strchr strrchr memchr memcpy memset sysconf tzset \
|
for ac_func in strchr strrchr memchr memcpy memset sysconf tzset \
|
||||||
strftime setrlimit initgroups getgroups fstat gettimeofday \
|
strftime setrlimit initgroups getgroups fstat gettimeofday \
|
||||||
setlocale getaddrinfo
|
setlocale getaddrinfo setsid
|
||||||
do
|
do
|
||||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||||
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
|
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||||
|
@@ -1757,7 +1757,7 @@ dnl
|
|||||||
AC_FUNC_GETGROUPS
|
AC_FUNC_GETGROUPS
|
||||||
AC_CHECK_FUNCS(strchr strrchr memchr memcpy memset sysconf tzset \
|
AC_CHECK_FUNCS(strchr strrchr memchr memcpy memset sysconf tzset \
|
||||||
strftime setrlimit initgroups getgroups fstat gettimeofday \
|
strftime setrlimit initgroups getgroups fstat gettimeofday \
|
||||||
setlocale getaddrinfo)
|
setlocale getaddrinfo setsid)
|
||||||
if test -z "$SKIP_SETRESUID"; then
|
if test -z "$SKIP_SETRESUID"; then
|
||||||
AC_CHECK_FUNCS(setresuid, [SKIP_SETREUID=yes])
|
AC_CHECK_FUNCS(setresuid, [SKIP_SETREUID=yes])
|
||||||
fi
|
fi
|
||||||
|
84
logging.c
84
logging.c
@@ -27,6 +27,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef STDC_HEADERS
|
#ifdef STDC_HEADERS
|
||||||
@@ -52,6 +53,7 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "sudo.h"
|
#include "sudo.h"
|
||||||
|
|
||||||
@@ -425,9 +427,9 @@ send_mail(line)
|
|||||||
{
|
{
|
||||||
FILE *mail;
|
FILE *mail;
|
||||||
char *p;
|
char *p;
|
||||||
int pfd[2], status;
|
int fd, pfd[2], status;
|
||||||
pid_t pid, rv;
|
pid_t pid, rv;
|
||||||
sigaction_t sa, saved_sa_pipe;
|
sigaction_t sa;
|
||||||
#ifndef NO_ROOT_MAILER
|
#ifndef NO_ROOT_MAILER
|
||||||
static char *root_envp[] = {
|
static char *root_envp[] = {
|
||||||
"HOME=/",
|
"HOME=/",
|
||||||
@@ -443,20 +445,32 @@ send_mail(line)
|
|||||||
if (!def_mailerpath || !def_mailto)
|
if (!def_mailerpath || !def_mailto)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Fork a child so we can be asyncronous. */
|
/* Fork and return, child will daemonize. */
|
||||||
switch (pid = fork()) {
|
switch (pid = fork()) {
|
||||||
case -1:
|
case -1:
|
||||||
/* Error. */
|
/* Error. */
|
||||||
error(1, "cannot fork");
|
error(1, "cannot fork");
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
/* Child continues below. */
|
/* Child. */
|
||||||
|
switch (pid = fork()) {
|
||||||
|
case -1:
|
||||||
|
/* Error. */
|
||||||
|
mysyslog(LOG_ERR, "cannot fork: %m");
|
||||||
|
_exit(1);
|
||||||
|
case 0:
|
||||||
|
/* Grandchild continues below. */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Parent waits and returns. */
|
/* Parent will wait for us. */
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Parent. */
|
||||||
do {
|
do {
|
||||||
#ifdef sudo_waitpid
|
#ifdef HAVE_WAITPID
|
||||||
rv = sudo_waitpid(pid, &status, 0);
|
rv = waitpid(pid, &status, 0);
|
||||||
#else
|
#else
|
||||||
rv = wait(&status);
|
rv = wait(&status);
|
||||||
#endif
|
#endif
|
||||||
@@ -464,36 +478,46 @@ send_mail(line)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fork again and orphan the grandchild so parent can continue. */
|
/* Daemonize - disassociate from session/tty. */
|
||||||
switch (pid = fork()) {
|
#ifdef HAVE_SETSID
|
||||||
case -1:
|
if (setsid() == -1)
|
||||||
/* Error. */
|
warning("setsid");
|
||||||
warning("cannot fork");
|
#else
|
||||||
_exit(1);
|
setpgrp(0, 0);
|
||||||
break;
|
# ifdef TIOCNOTTY
|
||||||
case 0:
|
if ((fd = open(_PATH_TTY, O_RDWR, 0644)) != -1) {
|
||||||
/* Grandchild continues below. */
|
ioctl(fd, TIOCNOTTY, NULL);
|
||||||
break;
|
close(fd);
|
||||||
default:
|
|
||||||
/* Orphan grandchild. */
|
|
||||||
_exit(0);
|
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
chdir("/");
|
||||||
|
if ((fd = open(_PATH_DEVNULL, O_RDWR, 0644)) != -1) {
|
||||||
|
(void) dup2(fd, STDIN_FILENO);
|
||||||
|
(void) dup2(fd, STDOUT_FILENO);
|
||||||
|
(void) dup2(fd, STDERR_FILENO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close password, group and other fds so we don't leak. */
|
||||||
|
sudo_endpwent();
|
||||||
|
sudo_endgrent();
|
||||||
|
closefrom(STDERR_FILENO + 1);
|
||||||
|
|
||||||
/* Ignore SIGPIPE in case mailer exits prematurely (or is missing). */
|
/* Ignore SIGPIPE in case mailer exits prematurely (or is missing). */
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = 0;
|
sa.sa_flags = 0;
|
||||||
sa.sa_handler = SIG_IGN;
|
sa.sa_handler = SIG_IGN;
|
||||||
(void) sigaction(SIGPIPE, &sa, &saved_sa_pipe);
|
(void) sigaction(SIGPIPE, &sa, NULL);
|
||||||
|
|
||||||
if (pipe(pfd) == -1) {
|
if (pipe(pfd) == -1) {
|
||||||
warning("cannot open pipe");
|
mysyslog(LOG_ERR, "cannot open pipe: %m");
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (pid = fork()) {
|
switch (pid = fork()) {
|
||||||
case -1:
|
case -1:
|
||||||
/* Error. */
|
/* Error. */
|
||||||
warning("cannot fork");
|
mysyslog(LOG_ERR, "cannot fork: %m");
|
||||||
_exit(1);
|
_exit(1);
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
@@ -502,7 +526,7 @@ send_mail(line)
|
|||||||
char *mpath, *mflags;
|
char *mpath, *mflags;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Great-grandchild, set stdin to output side of the pipe */
|
/* Child, set stdin to output side of the pipe */
|
||||||
if (pfd[0] != STDIN_FILENO) {
|
if (pfd[0] != STDIN_FILENO) {
|
||||||
(void) dup2(pfd[0], STDIN_FILENO);
|
(void) dup2(pfd[0], STDIN_FILENO);
|
||||||
(void) close(pfd[0]);
|
(void) close(pfd[0]);
|
||||||
@@ -525,11 +549,6 @@ send_mail(line)
|
|||||||
}
|
}
|
||||||
argv[i] = NULL;
|
argv[i] = NULL;
|
||||||
|
|
||||||
/* Close password, group and other fds so we don't leak. */
|
|
||||||
sudo_endpwent();
|
|
||||||
sudo_endgrent();
|
|
||||||
closefrom(STDERR_FILENO + 1);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Depending on the config, either run the mailer as root
|
* Depending on the config, either run the mailer as root
|
||||||
* (so user cannot kill it) or as the user (for the paranoid).
|
* (so user cannot kill it) or as the user (for the paranoid).
|
||||||
@@ -541,6 +560,7 @@ send_mail(line)
|
|||||||
set_perms(PERM_FULL_USER);
|
set_perms(PERM_FULL_USER);
|
||||||
execv(mpath, argv);
|
execv(mpath, argv);
|
||||||
#endif /* NO_ROOT_MAILER */
|
#endif /* NO_ROOT_MAILER */
|
||||||
|
mysyslog(LOG_ERR, "cannot execute %s: %m", mpath);
|
||||||
_exit(127);
|
_exit(127);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -573,13 +593,13 @@ send_mail(line)
|
|||||||
get_timestr(), user_name, line);
|
get_timestr(), user_name, line);
|
||||||
fclose(mail);
|
fclose(mail);
|
||||||
do {
|
do {
|
||||||
#ifdef sudo_waitpid
|
#ifdef HAVE_WAITPID
|
||||||
rv = sudo_waitpid(pid, &status, 0);
|
rv = waitpid(pid, &status, 0);
|
||||||
#else
|
#else
|
||||||
rv = wait(&status);
|
rv = wait(&status);
|
||||||
#endif
|
#endif
|
||||||
} while (rv == -1 && errno == EINTR);
|
} while (rv == -1 && errno == EINTR);
|
||||||
(void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user