|
|
e20e41 |
From 87444dc6977b61096127dcdfe87dc6cf2c0167d6 Mon Sep 17 00:00:00 2001
|
|
|
e20e41 |
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
|
|
e20e41 |
Date: Sun, 16 Apr 2017 20:20:08 +0100
|
|
|
e20e41 |
Subject: [PATCH] Capture and log STDOUT and STDERR output from dhcp-script.
|
|
|
e20e41 |
|
|
|
e20e41 |
(cherry picked from commit c77fb9d8f09d136fa71bde2469c4fd11cefa6f4a)
|
|
|
e20e41 |
|
|
|
e20e41 |
Compile-time check on buffer sizes for leasefile parsing code.
|
|
|
e20e41 |
|
|
|
e20e41 |
(cherry picked from commit bf4e62c19e619f7edf8d03d58d33a5752f190bfd)
|
|
|
e20e41 |
|
|
|
e20e41 |
Improve error handling with shcp-script "init" mode.
|
|
|
e20e41 |
|
|
|
e20e41 |
(cherry picked from commit 3a8b0f6fccf464b1ec6d24c0e00e540ab2b17705)
|
|
|
e20e41 |
|
|
|
e20e41 |
Tweak logging introduced in 3a8b0f6fccf464b1ec6d24c0e00e540ab2b17705
|
|
|
e20e41 |
|
|
|
e20e41 |
(cherry picked from commit efff74c1aea14757ce074db28e02671c7f7bb5f5)
|
|
|
e20e41 |
|
|
|
e20e41 |
Don't die() on failing to parse lease-script output.
|
|
|
e20e41 |
|
|
|
e20e41 |
(cherry picked from commit 05f76dab89d5b879519a4f45b0cccaa1fc3d162d)
|
|
|
e20e41 |
---
|
|
|
e20e41 |
man/dnsmasq.8 | 4 +-
|
|
|
e20e41 |
src/dhcp-common.c | 16 +++---
|
|
|
e20e41 |
src/dhcp-protocol.h | 4 ++
|
|
|
e20e41 |
src/dnsmasq.c | 8 +++
|
|
|
e20e41 |
src/dnsmasq.h | 54 +++++++++---------
|
|
|
e20e41 |
src/helper.c | 56 +++++++++++++++++-
|
|
|
e20e41 |
src/lease.c | 159 +++++++++++++++++++++++++++++++---------------------
|
|
|
e20e41 |
src/log.c | 4 +-
|
|
|
e20e41 |
src/rfc3315.c | 2 +-
|
|
|
e20e41 |
9 files changed, 202 insertions(+), 105 deletions(-)
|
|
|
e20e41 |
|
|
|
e20e41 |
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
|
|
|
e20e41 |
index 0521534..97d0a4f 100644
|
|
|
e20e41 |
--- a/man/dnsmasq.8
|
|
|
e20e41 |
+++ b/man/dnsmasq.8
|
|
|
e20e41 |
@@ -1551,8 +1551,8 @@ database.
|
|
|
e20e41 |
|
|
|
e20e41 |
|
|
|
e20e41 |
All file descriptors are
|
|
|
e20e41 |
-closed except stdin, stdout and stderr which are open to /dev/null
|
|
|
e20e41 |
-(except in debug mode).
|
|
|
e20e41 |
+closed except stdin, which is open to /dev/null, and stdout and stderr which capture output for logging by dnsmasq.
|
|
|
e20e41 |
+(In debug mode, stdio, stdout and stderr file are left as those inherited from the invoker of dnsmasq).
|
|
|
e20e41 |
|
|
|
e20e41 |
The script is not invoked concurrently: at most one instance
|
|
|
e20e41 |
of the script is ever running (dnsmasq waits for an instance of script to exit
|
|
|
e20e41 |
diff --git a/src/dhcp-common.c b/src/dhcp-common.c
|
|
|
e20e41 |
index 08528e8..ecc752b 100644
|
|
|
e20e41 |
--- a/src/dhcp-common.c
|
|
|
e20e41 |
+++ b/src/dhcp-common.c
|
|
|
e20e41 |
@@ -20,11 +20,11 @@
|
|
|
e20e41 |
|
|
|
e20e41 |
void dhcp_common_init(void)
|
|
|
e20e41 |
{
|
|
|
e20e41 |
- /* These each hold a DHCP option max size 255
|
|
|
e20e41 |
- and get a terminating zero added */
|
|
|
e20e41 |
- daemon->dhcp_buff = safe_malloc(256);
|
|
|
e20e41 |
- daemon->dhcp_buff2 = safe_malloc(256);
|
|
|
e20e41 |
- daemon->dhcp_buff3 = safe_malloc(256);
|
|
|
e20e41 |
+ /* These each hold a DHCP option max size 255
|
|
|
e20e41 |
+ and get a terminating zero added */
|
|
|
e20e41 |
+ daemon->dhcp_buff = safe_malloc(DHCP_BUFF_SZ);
|
|
|
e20e41 |
+ daemon->dhcp_buff2 = safe_malloc(DHCP_BUFF_SZ);
|
|
|
e20e41 |
+ daemon->dhcp_buff3 = safe_malloc(DHCP_BUFF_SZ);
|
|
|
e20e41 |
|
|
|
e20e41 |
/* dhcp_packet is used by v4 and v6, outpacket only by v6
|
|
|
e20e41 |
sizeof(struct dhcp_packet) is as good an initial size as any,
|
|
|
e20e41 |
@@ -855,14 +855,14 @@ void log_context(int family, struct dhcp_context *context)
|
|
|
e20e41 |
if (context->flags & CONTEXT_RA_STATELESS)
|
|
|
e20e41 |
{
|
|
|
e20e41 |
if (context->flags & CONTEXT_TEMPLATE)
|
|
|
e20e41 |
- strncpy(daemon->dhcp_buff, context->template_interface, 256);
|
|
|
e20e41 |
+ strncpy(daemon->dhcp_buff, context->template_interface, DHCP_BUFF_SZ);
|
|
|
e20e41 |
else
|
|
|
e20e41 |
strcpy(daemon->dhcp_buff, daemon->addrbuff);
|
|
|
e20e41 |
}
|
|
|
e20e41 |
else
|
|
|
e20e41 |
#endif
|
|
|
e20e41 |
- inet_ntop(family, start, daemon->dhcp_buff, 256);
|
|
|
e20e41 |
- inet_ntop(family, end, daemon->dhcp_buff3, 256);
|
|
|
e20e41 |
+ inet_ntop(family, start, daemon->dhcp_buff, DHCP_BUFF_SZ);
|
|
|
e20e41 |
+ inet_ntop(family, end, daemon->dhcp_buff3, DHCP_BUFF_SZ);
|
|
|
e20e41 |
my_syslog(MS_DHCP | LOG_INFO,
|
|
|
e20e41 |
(context->flags & CONTEXT_RA_STATELESS) ?
|
|
|
e20e41 |
_("%s stateless on %s%.0s%.0s%s") :
|
|
|
e20e41 |
diff --git a/src/dhcp-protocol.h b/src/dhcp-protocol.h
|
|
|
e20e41 |
index a31d829..0ea449b 100644
|
|
|
e20e41 |
--- a/src/dhcp-protocol.h
|
|
|
e20e41 |
+++ b/src/dhcp-protocol.h
|
|
|
e20e41 |
@@ -19,6 +19,10 @@
|
|
|
e20e41 |
#define DHCP_CLIENT_ALTPORT 1068
|
|
|
e20e41 |
#define PXE_PORT 4011
|
|
|
e20e41 |
|
|
|
e20e41 |
+/* These each hold a DHCP option max size 255
|
|
|
e20e41 |
+ and get a terminating zero added */
|
|
|
e20e41 |
+#define DHCP_BUFF_SZ 256
|
|
|
e20e41 |
+
|
|
|
e20e41 |
#define BOOTREQUEST 1
|
|
|
e20e41 |
#define BOOTREPLY 2
|
|
|
e20e41 |
#define DHCP_COOKIE 0x63825363
|
|
|
e20e41 |
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
|
|
|
e20e41 |
index 045ec53..9cd4052 100644
|
|
|
e20e41 |
--- a/src/dnsmasq.c
|
|
|
e20e41 |
+++ b/src/dnsmasq.c
|
|
|
e20e41 |
@@ -1294,6 +1294,7 @@ static void async_event(int pipe, time_t now)
|
|
|
e20e41 |
daemon->tcp_pids[i] = 0;
|
|
|
e20e41 |
break;
|
|
|
e20e41 |
|
|
|
e20e41 |
+#if defined(HAVE_SCRIPT)
|
|
|
e20e41 |
case EVENT_KILLED:
|
|
|
e20e41 |
my_syslog(LOG_WARNING, _("script process killed by signal %d"), ev.data);
|
|
|
e20e41 |
break;
|
|
|
e20e41 |
@@ -1307,12 +1308,19 @@ static void async_event(int pipe, time_t now)
|
|
|
e20e41 |
daemon->lease_change_command, strerror(ev.data));
|
|
|
e20e41 |
break;
|
|
|
e20e41 |
|
|
|
e20e41 |
+ case EVENT_SCRIPT_LOG:
|
|
|
e20e41 |
+ my_syslog(MS_SCRIPT | LOG_DEBUG, "%s", msg ? msg : "");
|
|
|
e20e41 |
+ free(msg);
|
|
|
e20e41 |
+ msg = NULL;
|
|
|
e20e41 |
+ break;
|
|
|
e20e41 |
+
|
|
|
e20e41 |
/* necessary for fatal errors in helper */
|
|
|
e20e41 |
case EVENT_USER_ERR:
|
|
|
e20e41 |
case EVENT_DIE:
|
|
|
e20e41 |
case EVENT_LUA_ERR:
|
|
|
e20e41 |
fatal_event(&ev, msg);
|
|
|
e20e41 |
break;
|
|
|
e20e41 |
+#endif
|
|
|
e20e41 |
|
|
|
e20e41 |
case EVENT_REOPEN:
|
|
|
e20e41 |
/* Note: this may leave TCP-handling processes with the old file still open.
|
|
|
e20e41 |
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
|
|
|
e20e41 |
index 1896a64..0cfd3c6 100644
|
|
|
e20e41 |
--- a/src/dnsmasq.h
|
|
|
e20e41 |
+++ b/src/dnsmasq.h
|
|
|
e20e41 |
@@ -145,30 +145,31 @@ struct event_desc {
|
|
|
e20e41 |
int event, data, msg_sz;
|
|
|
e20e41 |
};
|
|
|
e20e41 |
|
|
|
e20e41 |
-#define EVENT_RELOAD 1
|
|
|
e20e41 |
-#define EVENT_DUMP 2
|
|
|
e20e41 |
-#define EVENT_ALARM 3
|
|
|
e20e41 |
-#define EVENT_TERM 4
|
|
|
e20e41 |
-#define EVENT_CHILD 5
|
|
|
e20e41 |
-#define EVENT_REOPEN 6
|
|
|
e20e41 |
-#define EVENT_EXITED 7
|
|
|
e20e41 |
-#define EVENT_KILLED 8
|
|
|
e20e41 |
-#define EVENT_EXEC_ERR 9
|
|
|
e20e41 |
-#define EVENT_PIPE_ERR 10
|
|
|
e20e41 |
-#define EVENT_USER_ERR 11
|
|
|
e20e41 |
-#define EVENT_CAP_ERR 12
|
|
|
e20e41 |
-#define EVENT_PIDFILE 13
|
|
|
e20e41 |
-#define EVENT_HUSER_ERR 14
|
|
|
e20e41 |
-#define EVENT_GROUP_ERR 15
|
|
|
e20e41 |
-#define EVENT_DIE 16
|
|
|
e20e41 |
-#define EVENT_LOG_ERR 17
|
|
|
e20e41 |
-#define EVENT_FORK_ERR 18
|
|
|
e20e41 |
-#define EVENT_LUA_ERR 19
|
|
|
e20e41 |
-#define EVENT_TFTP_ERR 20
|
|
|
e20e41 |
-#define EVENT_INIT 21
|
|
|
e20e41 |
-#define EVENT_NEWADDR 22
|
|
|
e20e41 |
-#define EVENT_NEWROUTE 23
|
|
|
e20e41 |
-#define EVENT_TIME_ERR 24
|
|
|
e20e41 |
+#define EVENT_RELOAD 1
|
|
|
e20e41 |
+#define EVENT_DUMP 2
|
|
|
e20e41 |
+#define EVENT_ALARM 3
|
|
|
e20e41 |
+#define EVENT_TERM 4
|
|
|
e20e41 |
+#define EVENT_CHILD 5
|
|
|
e20e41 |
+#define EVENT_REOPEN 6
|
|
|
e20e41 |
+#define EVENT_EXITED 7
|
|
|
e20e41 |
+#define EVENT_KILLED 8
|
|
|
e20e41 |
+#define EVENT_EXEC_ERR 9
|
|
|
e20e41 |
+#define EVENT_PIPE_ERR 10
|
|
|
e20e41 |
+#define EVENT_USER_ERR 11
|
|
|
e20e41 |
+#define EVENT_CAP_ERR 12
|
|
|
e20e41 |
+#define EVENT_PIDFILE 13
|
|
|
e20e41 |
+#define EVENT_HUSER_ERR 14
|
|
|
e20e41 |
+#define EVENT_GROUP_ERR 15
|
|
|
e20e41 |
+#define EVENT_DIE 16
|
|
|
e20e41 |
+#define EVENT_LOG_ERR 17
|
|
|
e20e41 |
+#define EVENT_FORK_ERR 18
|
|
|
e20e41 |
+#define EVENT_LUA_ERR 19
|
|
|
e20e41 |
+#define EVENT_TFTP_ERR 20
|
|
|
e20e41 |
+#define EVENT_INIT 21
|
|
|
e20e41 |
+#define EVENT_NEWADDR 22
|
|
|
e20e41 |
+#define EVENT_NEWROUTE 23
|
|
|
e20e41 |
+#define EVENT_TIME_ERR 24
|
|
|
e20e41 |
+#define EVENT_SCRIPT_LOG 25
|
|
|
e20e41 |
|
|
|
e20e41 |
/* Exit codes. */
|
|
|
e20e41 |
#define EC_GOOD 0
|
|
|
e20e41 |
@@ -242,8 +243,9 @@ struct event_desc {
|
|
|
e20e41 |
|
|
|
e20e41 |
/* extra flags for my_syslog, we use a couple of facilities since they are known
|
|
|
e20e41 |
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
|
|
|
e20e41 |
-#define MS_TFTP LOG_USER
|
|
|
e20e41 |
-#define MS_DHCP LOG_DAEMON
|
|
|
e20e41 |
+#define MS_TFTP LOG_USER
|
|
|
e20e41 |
+#define MS_DHCP LOG_DAEMON
|
|
|
e20e41 |
+#define MS_SCRIPT LOG_MAIL
|
|
|
e20e41 |
|
|
|
e20e41 |
struct all_addr {
|
|
|
e20e41 |
union {
|
|
|
e20e41 |
diff --git a/src/helper.c b/src/helper.c
|
|
|
e20e41 |
index 9c37e37..de31383 100644
|
|
|
e20e41 |
--- a/src/helper.c
|
|
|
e20e41 |
+++ b/src/helper.c
|
|
|
e20e41 |
@@ -14,6 +14,7 @@
|
|
|
e20e41 |
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
e20e41 |
*/
|
|
|
e20e41 |
|
|
|
e20e41 |
+#include <stdio.h>
|
|
|
e20e41 |
#include "dnsmasq.h"
|
|
|
e20e41 |
|
|
|
e20e41 |
#ifdef HAVE_SCRIPT
|
|
|
e20e41 |
@@ -135,7 +136,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|
|
e20e41 |
max_fd != STDIN_FILENO && max_fd != pipefd[0] &&
|
|
|
e20e41 |
max_fd != event_fd && max_fd != err_fd)
|
|
|
e20e41 |
close(max_fd);
|
|
|
e20e41 |
-
|
|
|
e20e41 |
+
|
|
|
e20e41 |
#ifdef HAVE_LUASCRIPT
|
|
|
e20e41 |
if (daemon->luascript)
|
|
|
e20e41 |
{
|
|
|
e20e41 |
@@ -189,6 +190,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|
|
e20e41 |
unsigned char *buf = (unsigned char *)daemon->namebuff;
|
|
|
e20e41 |
unsigned char *end, *extradata, *alloc_buff = NULL;
|
|
|
e20e41 |
int is6, err = 0;
|
|
|
e20e41 |
+ int pipeout[2];
|
|
|
e20e41 |
|
|
|
e20e41 |
free(alloc_buff);
|
|
|
e20e41 |
|
|
|
e20e41 |
@@ -472,16 +474,54 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|
|
e20e41 |
if (!daemon->lease_change_command)
|
|
|
e20e41 |
continue;
|
|
|
e20e41 |
|
|
|
e20e41 |
+ /* Pipe to capture stdout and stderr from script */
|
|
|
e20e41 |
+ if (!option_bool(OPT_DEBUG) && pipe(pipeout) == -1)
|
|
|
e20e41 |
+ continue;
|
|
|
e20e41 |
+
|
|
|
e20e41 |
/* possible fork errors are all temporary resource problems */
|
|
|
e20e41 |
while ((pid = fork()) == -1 && (errno == EAGAIN || errno == ENOMEM))
|
|
|
e20e41 |
sleep(2);
|
|
|
e20e41 |
|
|
|
e20e41 |
if (pid == -1)
|
|
|
e20e41 |
- continue;
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ if (!option_bool(OPT_DEBUG))
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ close(pipeout[0]);
|
|
|
e20e41 |
+ close(pipeout[1]);
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
+ continue;
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
|
|
|
e20e41 |
/* wait for child to complete */
|
|
|
e20e41 |
if (pid != 0)
|
|
|
e20e41 |
{
|
|
|
e20e41 |
+ if (!option_bool(OPT_DEBUG))
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ FILE *fp;
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ close(pipeout[1]);
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ /* Read lines sent to stdout/err by the script and pass them back to be logged */
|
|
|
e20e41 |
+ if (!(fp = fdopen(pipeout[0], "r")))
|
|
|
e20e41 |
+ close(pipeout[0]);
|
|
|
e20e41 |
+ else
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ while (fgets(daemon->packet, daemon->packet_buff_sz, fp))
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ /* do not include new lines, log will append them */
|
|
|
e20e41 |
+ size_t len = strlen(daemon->packet);
|
|
|
e20e41 |
+ if (len > 0)
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ --len;
|
|
|
e20e41 |
+ if (daemon->packet[len] == '\n')
|
|
|
e20e41 |
+ daemon->packet[len] = 0;
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
+ send_event(event_fd, EVENT_SCRIPT_LOG, 0, daemon->packet);
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
+ fclose(fp);
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
+
|
|
|
e20e41 |
/* reap our children's children, if necessary */
|
|
|
e20e41 |
while (1)
|
|
|
e20e41 |
{
|
|
|
e20e41 |
@@ -504,6 +544,15 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|
|
e20e41 |
|
|
|
e20e41 |
continue;
|
|
|
e20e41 |
}
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ if (!option_bool(OPT_DEBUG))
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ /* map stdout/stderr of script to pipeout */
|
|
|
e20e41 |
+ close(pipeout[0]);
|
|
|
e20e41 |
+ dup2(pipeout[1], STDOUT_FILENO);
|
|
|
e20e41 |
+ dup2(pipeout[1], STDERR_FILENO);
|
|
|
e20e41 |
+ close(pipeout[1]);
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
|
|
|
e20e41 |
if (data.action != ACTION_TFTP && data.action != ACTION_ARP)
|
|
|
e20e41 |
{
|
|
|
e20e41 |
@@ -579,7 +628,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|
|
e20e41 |
hostname = NULL;
|
|
|
e20e41 |
|
|
|
e20e41 |
my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err;;
|
|
|
e20e41 |
- }
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
+
|
|
|
e20e41 |
/* we need to have the event_fd around if exec fails */
|
|
|
e20e41 |
if ((i = fcntl(event_fd, F_GETFD)) != -1)
|
|
|
e20e41 |
fcntl(event_fd, F_SETFD, i | FD_CLOEXEC);
|
|
|
e20e41 |
diff --git a/src/lease.c b/src/lease.c
|
|
|
e20e41 |
index 20cac90..64047f9 100644
|
|
|
e20e41 |
--- a/src/lease.c
|
|
|
e20e41 |
+++ b/src/lease.c
|
|
|
e20e41 |
@@ -21,94 +21,62 @@
|
|
|
e20e41 |
static struct dhcp_lease *leases = NULL, *old_leases = NULL;
|
|
|
e20e41 |
static int dns_dirty, file_dirty, leases_left;
|
|
|
e20e41 |
|
|
|
e20e41 |
-void lease_init(time_t now)
|
|
|
e20e41 |
+static int read_leases(time_t now, FILE *leasestream)
|
|
|
e20e41 |
{
|
|
|
e20e41 |
unsigned long ei;
|
|
|
e20e41 |
struct all_addr addr;
|
|
|
e20e41 |
struct dhcp_lease *lease;
|
|
|
e20e41 |
int clid_len, hw_len, hw_type;
|
|
|
e20e41 |
- FILE *leasestream;
|
|
|
e20e41 |
-
|
|
|
e20e41 |
- leases_left = daemon->dhcp_max;
|
|
|
e20e41 |
-
|
|
|
e20e41 |
- if (option_bool(OPT_LEASE_RO))
|
|
|
e20e41 |
- {
|
|
|
e20e41 |
- /* run "<lease_change_script> init" once to get the
|
|
|
e20e41 |
- initial state of the database. If leasefile-ro is
|
|
|
e20e41 |
- set without a script, we just do without any
|
|
|
e20e41 |
- lease database. */
|
|
|
e20e41 |
-#ifdef HAVE_SCRIPT
|
|
|
e20e41 |
- if (daemon->lease_change_command)
|
|
|
e20e41 |
- {
|
|
|
e20e41 |
- strcpy(daemon->dhcp_buff, daemon->lease_change_command);
|
|
|
e20e41 |
- strcat(daemon->dhcp_buff, " init");
|
|
|
e20e41 |
- leasestream = popen(daemon->dhcp_buff, "r");
|
|
|
e20e41 |
- }
|
|
|
e20e41 |
- else
|
|
|
e20e41 |
+ int items;
|
|
|
e20e41 |
+ char *domain = NULL;
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ *daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0';
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ /* client-id max length is 255 which is 255*2 digits + 254 colons
|
|
|
e20e41 |
+ borrow DNS packet buffer which is always larger than 1000 bytes
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ Check various buffers are big enough for the code below */
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+#if (DHCP_BUFF_SZ < 255) || (MAXDNAME < 64) || (PACKETSZ+MAXDNAME+RRFIXEDSZ < 764)
|
|
|
e20e41 |
+# error Buffer size breakage in leasefile parsing.
|
|
|
e20e41 |
#endif
|
|
|
e20e41 |
- {
|
|
|
e20e41 |
- file_dirty = dns_dirty = 0;
|
|
|
e20e41 |
- return;
|
|
|
e20e41 |
- }
|
|
|
e20e41 |
|
|
|
e20e41 |
- }
|
|
|
e20e41 |
- else
|
|
|
e20e41 |
- {
|
|
|
e20e41 |
- /* NOTE: need a+ mode to create file if it doesn't exist */
|
|
|
e20e41 |
- leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+");
|
|
|
e20e41 |
-
|
|
|
e20e41 |
- if (!leasestream)
|
|
|
e20e41 |
- die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE);
|
|
|
e20e41 |
-
|
|
|
e20e41 |
- /* a+ mode leaves pointer at end. */
|
|
|
e20e41 |
- rewind(leasestream);
|
|
|
e20e41 |
- }
|
|
|
e20e41 |
-
|
|
|
e20e41 |
- /* client-id max length is 255 which is 255*2 digits + 254 colons
|
|
|
e20e41 |
- borrow DNS packet buffer which is always larger than 1000 bytes */
|
|
|
e20e41 |
- if (leasestream)
|
|
|
e20e41 |
- while (fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2) == 2)
|
|
|
e20e41 |
+ while ((items=fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2)) == 2)
|
|
|
e20e41 |
{
|
|
|
e20e41 |
+ *daemon->namebuff = *daemon->dhcp_buff = *daemon->packet = '\0';
|
|
|
e20e41 |
+ hw_len = hw_type = clid_len = 0;
|
|
|
e20e41 |
+
|
|
|
e20e41 |
#ifdef HAVE_DHCP6
|
|
|
e20e41 |
if (strcmp(daemon->dhcp_buff3, "duid") == 0)
|
|
|
e20e41 |
{
|
|
|
e20e41 |
daemon->duid_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, 130, NULL, NULL);
|
|
|
e20e41 |
+ if (daemon->duid_len < 0)
|
|
|
e20e41 |
+ return 0;
|
|
|
e20e41 |
daemon->duid = safe_malloc(daemon->duid_len);
|
|
|
e20e41 |
memcpy(daemon->duid, daemon->dhcp_buff2, daemon->duid_len);
|
|
|
e20e41 |
continue;
|
|
|
e20e41 |
}
|
|
|
e20e41 |
#endif
|
|
|
e20e41 |
-
|
|
|
e20e41 |
- ei = atol(daemon->dhcp_buff3);
|
|
|
e20e41 |
|
|
|
e20e41 |
if (fscanf(leasestream, " %64s %255s %764s",
|
|
|
e20e41 |
daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
|
|
|
e20e41 |
- break;
|
|
|
e20e41 |
+ return 0;
|
|
|
e20e41 |
|
|
|
e20e41 |
- clid_len = 0;
|
|
|
e20e41 |
- if (strcmp(daemon->packet, "*") != 0)
|
|
|
e20e41 |
- clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
|
|
|
e20e41 |
-
|
|
|
e20e41 |
- if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4) &&
|
|
|
e20e41 |
- (lease = lease4_allocate(addr.addr.addr4)))
|
|
|
e20e41 |
+ if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4))
|
|
|
e20e41 |
{
|
|
|
e20e41 |
+ if ((lease = lease4_allocate(addr.addr.addr4)))
|
|
|
e20e41 |
+ domain = get_domain(lease->addr);
|
|
|
e20e41 |
+
|
|
|
e20e41 |
hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
|
|
|
e20e41 |
/* For backwards compatibility, no explict MAC address type means ether. */
|
|
|
e20e41 |
if (hw_type == 0 && hw_len != 0)
|
|
|
e20e41 |
hw_type = ARPHRD_ETHER;
|
|
|
e20e41 |
-
|
|
|
e20e41 |
- lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet,
|
|
|
e20e41 |
- hw_len, hw_type, clid_len, now, 0);
|
|
|
e20e41 |
-
|
|
|
e20e41 |
- if (strcmp(daemon->dhcp_buff, "*") != 0)
|
|
|
e20e41 |
- lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain(lease->addr), NULL);
|
|
|
e20e41 |
}
|
|
|
e20e41 |
#ifdef HAVE_DHCP6
|
|
|
e20e41 |
else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6))
|
|
|
e20e41 |
{
|
|
|
e20e41 |
char *s = daemon->dhcp_buff2;
|
|
|
e20e41 |
int lease_type = LEASE_NA;
|
|
|
e20e41 |
- int iaid;
|
|
|
e20e41 |
|
|
|
e20e41 |
if (s[0] == 'T')
|
|
|
e20e41 |
{
|
|
|
e20e41 |
@@ -116,23 +84,30 @@ void lease_init(time_t now)
|
|
|
e20e41 |
s++;
|
|
|
e20e41 |
}
|
|
|
e20e41 |
|
|
|
e20e41 |
- iaid = strtoul(s, NULL, 10);
|
|
|
e20e41 |
-
|
|
|
e20e41 |
if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
|
|
|
e20e41 |
{
|
|
|
e20e41 |
- lease_set_hwaddr(lease, NULL, (unsigned char *)daemon->packet, 0, 0, clid_len, now, 0);
|
|
|
e20e41 |
- lease_set_iaid(lease, iaid);
|
|
|
e20e41 |
- if (strcmp(daemon->dhcp_buff, "*") != 0)
|
|
|
e20e41 |
- lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain6((struct in6_addr *)lease->hwaddr), NULL);
|
|
|
e20e41 |
+ lease_set_iaid(lease, strtoul(s, NULL, 10));
|
|
|
e20e41 |
+ domain = get_domain6((struct in6_addr *)lease->hwaddr);
|
|
|
e20e41 |
}
|
|
|
e20e41 |
}
|
|
|
e20e41 |
#endif
|
|
|
e20e41 |
else
|
|
|
e20e41 |
- break;
|
|
|
e20e41 |
+ return 0;
|
|
|
e20e41 |
|
|
|
e20e41 |
if (!lease)
|
|
|
e20e41 |
die (_("too many stored leases"), NULL, EC_MISC);
|
|
|
e20e41 |
-
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ if (strcmp(daemon->packet, "*") != 0)
|
|
|
e20e41 |
+ clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet,
|
|
|
e20e41 |
+ hw_len, hw_type, clid_len, now, 0);
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ if (strcmp(daemon->dhcp_buff, "*") != 0)
|
|
|
e20e41 |
+ lease_set_hostname(lease, daemon->dhcp_buff, 0, domain, NULL);
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ ei = atol(daemon->dhcp_buff3);
|
|
|
e20e41 |
+
|
|
|
e20e41 |
#ifdef HAVE_BROKEN_RTC
|
|
|
e20e41 |
if (ei != 0)
|
|
|
e20e41 |
lease->expires = (time_t)ei + now;
|
|
|
e20e41 |
@@ -148,7 +123,62 @@ void lease_init(time_t now)
|
|
|
e20e41 |
/* set these correctly: the "old" events are generated later from
|
|
|
e20e41 |
the startup synthesised SIGHUP. */
|
|
|
e20e41 |
lease->flags &= ~(LEASE_NEW | LEASE_CHANGED);
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ *daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0';
|
|
|
e20e41 |
}
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ return (items == 0 || items == EOF);
|
|
|
e20e41 |
+}
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+void lease_init(time_t now)
|
|
|
e20e41 |
+{
|
|
|
e20e41 |
+ FILE *leasestream;
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ leases_left = daemon->dhcp_max;
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ if (option_bool(OPT_LEASE_RO))
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ /* run "<lease_change_script> init" once to get the
|
|
|
e20e41 |
+ initial state of the database. If leasefile-ro is
|
|
|
e20e41 |
+ set without a script, we just do without any
|
|
|
e20e41 |
+ lease database. */
|
|
|
e20e41 |
+#ifdef HAVE_SCRIPT
|
|
|
e20e41 |
+ if (daemon->lease_change_command)
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ strcpy(daemon->dhcp_buff, daemon->lease_change_command);
|
|
|
e20e41 |
+ strcat(daemon->dhcp_buff, " init");
|
|
|
e20e41 |
+ leasestream = popen(daemon->dhcp_buff, "r");
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
+ else
|
|
|
e20e41 |
+#endif
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ file_dirty = dns_dirty = 0;
|
|
|
e20e41 |
+ return;
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
+ else
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ /* NOTE: need a+ mode to create file if it doesn't exist */
|
|
|
e20e41 |
+ leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+");
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ if (!leasestream)
|
|
|
e20e41 |
+ die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE);
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ /* a+ mode leaves pointer at end. */
|
|
|
e20e41 |
+ rewind(leasestream);
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ if (leasestream)
|
|
|
e20e41 |
+ {
|
|
|
e20e41 |
+ if (!read_leases(now, leasestream))
|
|
|
e20e41 |
+ my_syslog(MS_DHCP | LOG_ERR, _("failed to parse lease database, invalid line: %s %s %s %s ..."),
|
|
|
e20e41 |
+ daemon->dhcp_buff3, daemon->dhcp_buff2,
|
|
|
e20e41 |
+ daemon->namebuff, daemon->dhcp_buff);
|
|
|
e20e41 |
+
|
|
|
e20e41 |
+ if (ferror(leasestream))
|
|
|
e20e41 |
+ die(_("failed to read lease file %s: %s"), daemon->lease_file, EC_FILE);
|
|
|
e20e41 |
+ }
|
|
|
e20e41 |
|
|
|
e20e41 |
#ifdef HAVE_SCRIPT
|
|
|
e20e41 |
if (!daemon->lease_stream)
|
|
|
e20e41 |
@@ -162,6 +192,7 @@ void lease_init(time_t now)
|
|
|
e20e41 |
errno = ENOENT;
|
|
|
e20e41 |
else if (WEXITSTATUS(rc) == 126)
|
|
|
e20e41 |
errno = EACCES;
|
|
|
e20e41 |
+
|
|
|
e20e41 |
die(_("cannot run lease-init script %s: %s"), daemon->lease_change_command, EC_FILE);
|
|
|
e20e41 |
}
|
|
|
e20e41 |
|
|
|
e20e41 |
diff --git a/src/log.c b/src/log.c
|
|
|
e20e41 |
index 8e66629..5fc860b 100644
|
|
|
e20e41 |
--- a/src/log.c
|
|
|
e20e41 |
+++ b/src/log.c
|
|
|
e20e41 |
@@ -288,7 +288,9 @@ void my_syslog(int priority, const char *format, ...)
|
|
|
e20e41 |
func = "-tftp";
|
|
|
e20e41 |
else if ((LOG_FACMASK & priority) == MS_DHCP)
|
|
|
e20e41 |
func = "-dhcp";
|
|
|
e20e41 |
-
|
|
|
e20e41 |
+ else if ((LOG_FACMASK & priority) == MS_SCRIPT)
|
|
|
e20e41 |
+ func = "-script";
|
|
|
e20e41 |
+
|
|
|
e20e41 |
#ifdef LOG_PRI
|
|
|
e20e41 |
priority = LOG_PRI(priority);
|
|
|
e20e41 |
#else
|
|
|
e20e41 |
diff --git a/src/rfc3315.c b/src/rfc3315.c
|
|
|
e20e41 |
index 3f4d69c..a3715cd 100644
|
|
|
e20e41 |
--- a/src/rfc3315.c
|
|
|
e20e41 |
+++ b/src/rfc3315.c
|
|
|
e20e41 |
@@ -1975,7 +1975,7 @@ static void log6_packet(struct state *state, char *type, struct in6_addr *addr,
|
|
|
e20e41 |
|
|
|
e20e41 |
if (addr)
|
|
|
e20e41 |
{
|
|
|
e20e41 |
- inet_ntop(AF_INET6, addr, daemon->dhcp_buff2, 255);
|
|
|
e20e41 |
+ inet_ntop(AF_INET6, addr, daemon->dhcp_buff2, DHCP_BUFF_SZ - 1);
|
|
|
e20e41 |
strcat(daemon->dhcp_buff2, " ");
|
|
|
e20e41 |
}
|
|
|
e20e41 |
else
|
|
|
e20e41 |
--
|
|
|
e20e41 |
2.9.3
|
|
|
e20e41 |
|