Commit f5a3679f authored by Simon Kelley's avatar Simon Kelley
parents facc18f2 5ac813cb
...@@ -89,6 +89,11 @@ version 2.77 ...@@ -89,6 +89,11 @@ version 2.77
Add mtu setting facility to --ra-param. Thanks to David Add mtu setting facility to --ra-param. Thanks to David
Flamand for the patch. Flamand for the patch.
Capture STDOUT and STDERR output from dhcp-script and log
it as part of the dnsmasq log stream. Makes life easier
for diagnosing unexpected problems in scripts.
Thanks to Petr Mensik for the patch.
version 2.76 version 2.76
Include 0.0.0.0/8 in DNS rebind checks. This range Include 0.0.0.0/8 in DNS rebind checks. This range
......
...@@ -57,8 +57,8 @@ idn_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) - ...@@ -57,8 +57,8 @@ idn_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) -
idn_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --libs libidn` idn_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --libs libidn`
ct_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --cflags libnetfilter_conntrack` ct_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --cflags libnetfilter_conntrack`
ct_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --libs libnetfilter_conntrack` ct_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --libs libnetfilter_conntrack`
lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.1` lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.2`
lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.1` lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.2`
nettle_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --cflags nettle hogweed` nettle_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --cflags nettle hogweed`
nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --libs nettle hogweed` nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --libs nettle hogweed`
gmp_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC NO_GMP --copy -lgmp` gmp_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC NO_GMP --copy -lgmp`
......
...@@ -1577,8 +1577,8 @@ database. ...@@ -1577,8 +1577,8 @@ database.
All file descriptors are All file descriptors are
closed except stdin, stdout and stderr which are open to /dev/null closed except stdin, which is open to /dev/null, and stdout and stderr which capture output for logging by dnsmasq.
(except in debug mode). (In debug mode, stdio, stdout and stderr file are left as those inherited from the invoker of dnsmasq).
The script is not invoked concurrently: at most one instance The script is not invoked concurrently: at most one instance
of the script is ever running (dnsmasq waits for an instance of script to exit of the script is ever running (dnsmasq waits for an instance of script to exit
......
...@@ -409,14 +409,14 @@ static char *compile_opts = ...@@ -409,14 +409,14 @@ static char *compile_opts =
"no-" "no-"
# endif # endif
"DHCPv6 " "DHCPv6 "
# if !defined(HAVE_SCRIPT) #endif
#if !defined(HAVE_SCRIPT)
"no-scripts " "no-scripts "
# else #else
# if !defined(HAVE_LUASCRIPT) # if !defined(HAVE_LUASCRIPT)
"no-" "no-"
# endif # endif
"Lua " "Lua "
# endif
#endif #endif
#ifndef HAVE_TFTP #ifndef HAVE_TFTP
"no-" "no-"
......
...@@ -1302,6 +1302,7 @@ static void async_event(int pipe, time_t now) ...@@ -1302,6 +1302,7 @@ static void async_event(int pipe, time_t now)
daemon->tcp_pids[i] = 0; daemon->tcp_pids[i] = 0;
break; break;
#if defined(HAVE_SCRIPT)
case EVENT_KILLED: case EVENT_KILLED:
my_syslog(LOG_WARNING, _("script process killed by signal %d"), ev.data); my_syslog(LOG_WARNING, _("script process killed by signal %d"), ev.data);
break; break;
...@@ -1315,12 +1316,19 @@ static void async_event(int pipe, time_t now) ...@@ -1315,12 +1316,19 @@ static void async_event(int pipe, time_t now)
daemon->lease_change_command, strerror(ev.data)); daemon->lease_change_command, strerror(ev.data));
break; break;
case EVENT_SCRIPT_LOG:
my_syslog(MS_SCRIPT | LOG_DEBUG, "%s", msg ? msg : "");
free(msg);
msg = NULL;
break;
/* necessary for fatal errors in helper */ /* necessary for fatal errors in helper */
case EVENT_USER_ERR: case EVENT_USER_ERR:
case EVENT_DIE: case EVENT_DIE:
case EVENT_LUA_ERR: case EVENT_LUA_ERR:
fatal_event(&ev, msg); fatal_event(&ev, msg);
break; break;
#endif
case EVENT_REOPEN: case EVENT_REOPEN:
/* Note: this may leave TCP-handling processes with the old file still open. /* Note: this may leave TCP-handling processes with the old file still open.
......
...@@ -169,6 +169,7 @@ struct event_desc { ...@@ -169,6 +169,7 @@ struct event_desc {
#define EVENT_NEWADDR 22 #define EVENT_NEWADDR 22
#define EVENT_NEWROUTE 23 #define EVENT_NEWROUTE 23
#define EVENT_TIME_ERR 24 #define EVENT_TIME_ERR 24
#define EVENT_SCRIPT_LOG 25
/* Exit codes. */ /* Exit codes. */
#define EC_GOOD 0 #define EC_GOOD 0
...@@ -245,6 +246,7 @@ struct event_desc { ...@@ -245,6 +246,7 @@ struct event_desc {
not to occupy the same bits as priorities, no matter how syslog.h is set up. */ not to occupy the same bits as priorities, no matter how syslog.h is set up. */
#define MS_TFTP LOG_USER #define MS_TFTP LOG_USER
#define MS_DHCP LOG_DAEMON #define MS_DHCP LOG_DAEMON
#define MS_SCRIPT LOG_MAIL
struct all_addr { struct all_addr {
union { union {
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdio.h>
#include "dnsmasq.h" #include "dnsmasq.h"
#ifdef HAVE_SCRIPT #ifdef HAVE_SCRIPT
...@@ -189,6 +190,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) ...@@ -189,6 +190,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
unsigned char *buf = (unsigned char *)daemon->namebuff; unsigned char *buf = (unsigned char *)daemon->namebuff;
unsigned char *end, *extradata, *alloc_buff = NULL; unsigned char *end, *extradata, *alloc_buff = NULL;
int is6, err = 0; int is6, err = 0;
int pipeout[2];
free(alloc_buff); free(alloc_buff);
...@@ -472,16 +474,54 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) ...@@ -472,16 +474,54 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
if (!daemon->lease_change_command) if (!daemon->lease_change_command)
continue; continue;
/* Pipe to capture stdout and stderr from script */
if (!option_bool(OPT_DEBUG) && pipe(pipeout) == -1)
continue;
/* possible fork errors are all temporary resource problems */ /* possible fork errors are all temporary resource problems */
while ((pid = fork()) == -1 && (errno == EAGAIN || errno == ENOMEM)) while ((pid = fork()) == -1 && (errno == EAGAIN || errno == ENOMEM))
sleep(2); sleep(2);
if (pid == -1) if (pid == -1)
{
if (!option_bool(OPT_DEBUG))
{
close(pipeout[0]);
close(pipeout[1]);
}
continue; continue;
}
/* wait for child to complete */ /* wait for child to complete */
if (pid != 0) if (pid != 0)
{ {
if (!option_bool(OPT_DEBUG))
{
FILE *fp;
close(pipeout[1]);
/* Read lines sent to stdout/err by the script and pass them back to be logged */
if (!(fp = fdopen(pipeout[0], "r")))
close(pipeout[0]);
else
{
while (fgets(daemon->packet, daemon->packet_buff_sz, fp))
{
/* do not include new lines, log will append them */
size_t len = strlen(daemon->packet);
if (len > 0)
{
--len;
if (daemon->packet[len] == '\n')
daemon->packet[len] = 0;
}
send_event(event_fd, EVENT_SCRIPT_LOG, 0, daemon->packet);
}
fclose(fp);
}
}
/* reap our children's children, if necessary */ /* reap our children's children, if necessary */
while (1) while (1)
{ {
...@@ -505,6 +545,15 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) ...@@ -505,6 +545,15 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
continue; continue;
} }
if (!option_bool(OPT_DEBUG))
{
/* map stdout/stderr of script to pipeout */
close(pipeout[0]);
dup2(pipeout[1], STDOUT_FILENO);
dup2(pipeout[1], STDERR_FILENO);
close(pipeout[1]);
}
if (data.action != ACTION_TFTP && data.action != ACTION_ARP) if (data.action != ACTION_TFTP && data.action != ACTION_ARP)
{ {
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
...@@ -581,6 +630,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) ...@@ -581,6 +630,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err); my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err);
} }
/* we need to have the event_fd around if exec fails */ /* we need to have the event_fd around if exec fails */
if ((i = fcntl(event_fd, F_GETFD)) != -1) if ((i = fcntl(event_fd, F_GETFD)) != -1)
fcntl(event_fd, F_SETFD, i | FD_CLOEXEC); fcntl(event_fd, F_SETFD, i | FD_CLOEXEC);
......
...@@ -288,6 +288,8 @@ void my_syslog(int priority, const char *format, ...) ...@@ -288,6 +288,8 @@ void my_syslog(int priority, const char *format, ...)
func = "-tftp"; func = "-tftp";
else if ((LOG_FACMASK & priority) == MS_DHCP) else if ((LOG_FACMASK & priority) == MS_DHCP)
func = "-dhcp"; func = "-dhcp";
else if ((LOG_FACMASK & priority) == MS_SCRIPT)
func = "-script";
#ifdef LOG_PRI #ifdef LOG_PRI
priority = LOG_PRI(priority); priority = LOG_PRI(priority);
......
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