Commit 945f7b7b authored by Adil's avatar Adil

dhcp

parents
#!/bin/bash
# run dhclient.d scripts in an emulated environment
PATH=/bin:/usr/bin:/sbin
ETCDIR=/etc/dhcp
SAVEDIR=/var/lib/dhclient
interface=$1
for optname in "${!DHCP4_@}"; do
newoptname=${optname,,};
newoptname=new_${newoptname#dhcp4_};
export "${newoptname}"="${!optname}";
done
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
[ -f /etc/sysconfig/network-scripts/ifcfg-"${interface}" ] && \
. /etc/sysconfig/network-scripts/ifcfg-"${interface}"
if [ -d $ETCDIR/dhclient.d ]; then
for f in $ETCDIR/dhclient.d/*.sh; do
if [ -x "${f}" ]; then
subsystem="${f%.sh}"
subsystem="${subsystem##*/}"
. "${f}"
if [ "$2" = "up" ]; then
"${subsystem}_config"
elif [ "$2" = "dhcp4-change" ]; then
if [ "$subsystem" = "chrony" -o "$subsystem" = "ntp" ]; then
"${subsystem}_config"
fi
elif [ "$2" = "down" ]; then
"${subsystem}_restore"
fi
fi
done
fi
#!/bin/bash
INTERFACE=$1 # The interface which is brought up or down
STATUS=$2 # The new state of the interface
# whenever interface is brought up by NM (rhbz #565921)
if [ "$STATUS" = "up" ]; then
# wait a few seconds to allow interface startup to complete
# (important at boot time without this the service still fails
# time-out for dispatcher script is 3s (rhbz#1003695#8)
sleep 2
# restart the services
# In case this dispatcher script is called several times in a short period of time, it might happen that
# systemd refuses to further restart the units. Therefore we use reset-failed command to prevent it.
systemctl -q is-enabled dhcpd.service && systemctl restart dhcpd.service && systemctl reset-failed dhcpd.service
systemctl -q is-enabled dhcpd6.service && systemctl restart dhcpd6.service && systemctl reset-failed dhcpd6.service
fi
exit 0
#!/bin/sh
# If we are running dhclient, shutdown running instances cleanly and
# bring them back up on resume.
. "${PM_FUNCTIONS}"
PM_DHCLIENT_RUNDIR="${PM_UTILS_RUNDIR}/network"
PM_DHCLIENT_SUSPEND="${PM_DHCLIENT_RUNDIR}/dhclient.suspend"
suspend_dhclient() {
[ ! -d /etc/sysconfig/network-scripts ] && return
[ ! -x /sbin/ifdown ] && return
[ ! -d ${PM_DHCLIENT_RUNDIR} ] && /bin/mkdir -p ${PM_DHCLIENT_RUNDIR}
[ -f ${PM_DHCLIENT_SUSPEND} ] && /bin/rm -f ${PM_DHCLIENT_SUSPEND}
cd /etc/sysconfig/network-scripts
for ifcfg in ifcfg-* ; do
# Clear relevant parameters set by previous interface
# (lo doesn't set them)
NM_CONTROLLED=
BOOTPROTO=
. ./"${ifcfg}"
if [ "${NM_CONTROLLED}" = "no" ] || [ "${NM_CONTROLLED}" = "n" ] || [ "${NM_CONTROLLED}" = "false" ]; then
if [ "${BOOTPROTO}" = "bootp" ] || [ "${BOOTPROTO}" = "dhcp" ] || [ -z "${BOOTPROTO}" ]; then
# device is not NetworkManager controlled and uses dhcp,
# now see if it's actually up at the moment
/sbin/ip link show ${DEVICE} | /bin/grep -qE "state (UP|UNKNOWN)" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "${DEVICE}" >> ${PM_DHCLIENT_SUSPEND}
/sbin/ifdown ${DEVICE}
fi
fi
fi
done
}
resume_dhclient() {
[ ! -f ${PM_DHCLIENT_SUSPEND} ] && return
[ ! -x /sbin/ifup ] && return
cd /etc/sysconfig/network-scripts
while read device ; do
/sbin/ifup ${device}
done < ${PM_DHCLIENT_SUSPEND}
/bin/rm -f ${PM_DHCLIENT_SUSPEND}
}
case "$1" in
hibernate|suspend)
suspend_dhclient
;;
thaw|resume)
resume_dhclient
;;
*) exit $NA
;;
esac
The /etc/dhcp/dhclient.d directory allows other packages and system
administrators to create application-specific option handlers for dhclient.
When dhclient is run, any option listed in the dhcp-options(5) man page can
be requested. dhclient-script does not handle every option available
because doing so would make the script unmaintainable as the components
using those options might change over time. The knowledge of how to handle
those options should be under the responsibility of the package maintainer
for that component (e.g., NTP options belong in a handler in the ntp
package).
To make maintenance easier, application specific DHCP options can be handled
by creating a bash script with two functions and placing it in /etc/dhcp/dhclient.d
The script must follow a specific form:
(1) The script must be named NAME.sh. NAME can be anything, but it makes
sense to name it for the service it handles. e.g., ntp.sh
(2) The script must provide a NAME_config() function to read the options and
do whatever it takes to put those options in place.
(3) The script must provide a NAME_restore() function to restore original
configuration state when dhclient stops.
(4) The script must be 'chmod +x' or dhclient-script will ignore it.
The scripts execute in the same environment as dhclient-script. That means
all of the functions and variables available to it are available to your
NAME.sh script. Things of note:
${SAVEDIR} is where original configuration files are saved. Save your
original configuration files here before you take the DHCP provided
values and generate new files.
Variables set in /etc/sysconfig/network, /etc/sysconfig/networking/network,
and /etc/sysconfig/network-scripts/ifcfg-$interface are available to
you.
See the scripts in /etc/dhcp/dhclient.d for examples.
NOTE: Do not use functions defined in /usr/sbin/dhclient-script. Consider
dhclient-script a black box. This script may change over time, so the
dhclient.d scripts should not be using functions defined in it.
--
David Cantrell <dcantrell@redhat.com>
This diff is collapsed.
diff -up dhcp-4.2.5/client/dhclient.c.orig dhcp-4.2.5/client/dhclient.c
--- dhcp-4.2.5/client/dhclient.c.orig 2018-11-07 14:21:16.756152614 +0100
+++ dhcp-4.2.5/client/dhclient.c 2018-11-08 17:30:15.754440523 +0100
@@ -1618,8 +1618,14 @@ void dhcpack (packet)
} else
client -> new -> renewal = 0;
- /* If it wasn't specified by the server, calculate it. */
- if (!client -> new -> renewal)
+ /*
+ * If it wasn't specified by the server, calculate it. Also use expiry
+ * instead of renewal time when it is shorter. This better follows
+ * RFC 2131 (section 4.4.5) when dealing with some DHCP servers.
+ */
+
+ if (!client -> new -> renewal ||
+ client -> new -> renewal > client -> new -> expiry)
client -> new -> renewal = client -> new -> expiry / 2 + 1;
if (client -> new -> renewal <= 0)
@@ -1645,7 +1651,9 @@ void dhcpack (packet)
} else
client -> new -> rebind = 0;
- if (client -> new -> rebind <= 0) {
+ /* Rebinding time must not be longer than expiry. */
+ if (client -> new -> rebind <= 0 ||
+ client -> new -> rebind > client -> new -> expiry) {
if (client -> new -> expiry <= TIME_MAX / 7)
client -> new -> rebind =
client -> new -> expiry * 7 / 8;
From c37721f799e6b32da156759a830011949311205a Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Fri, 16 Feb 2018 17:50:40 +0100
Subject: [PATCH] New bind includes never includes isc/util.h from any public
headers. Include them to all compiled files that require it.
---
client/dhclient.c | 1 +
common/execute.c | 1 +
common/parse.c | 1 +
common/socket.c | 1 +
omapip/connection.c | 1 +
5 files changed, 5 insertions(+)
diff --git a/client/dhclient.c b/client/dhclient.c
index 228b4fe..014365d 100644
--- a/client/dhclient.c
+++ b/client/dhclient.c
@@ -38,6 +38,7 @@
#include <sys/wait.h>
#include <limits.h>
#include <isc/file.h>
+#include <isc/util.h>
#include <dns/result.h>
#ifdef HAVE_LIBCAP_NG
diff --git a/common/execute.c b/common/execute.c
index fa4e0f8..1ee1e7d 100644
--- a/common/execute.c
+++ b/common/execute.c
@@ -28,6 +28,7 @@
#include "dhcpd.h"
#include <omapip/omapip_p.h>
+#include <isc/util.h>
#include <sys/types.h>
#include <sys/wait.h>
diff --git a/common/parse.c b/common/parse.c
index d08cd2c..729d442 100644
--- a/common/parse.c
+++ b/common/parse.c
@@ -27,6 +27,7 @@
*/
#include "dhcpd.h"
+#include <isc/util.h>
#include <syslog.h>
/* Enumerations can be specified in option formats, and are used for
diff --git a/common/socket.c b/common/socket.c
index 2b352a1..94ce334 100644
--- a/common/socket.c
+++ b/common/socket.c
@@ -35,6 +35,7 @@
*/
#include "dhcpd.h"
+#include <isc/util.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
diff --git a/omapip/connection.c b/omapip/connection.c
index 9aac0c8..a74becc 100644
--- a/omapip/connection.c
+++ b/omapip/connection.c
@@ -30,6 +30,7 @@
#include "dhcpd.h"
#include <omapip/omapip_p.h>
+#include <isc/util.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <errno.h>
--
2.14.3
commit ccff9ed69d0b26d33ce9cac8e83dab535b64d627
Author: Thomas Markwalder <tmark@isc.org>
Date: Tue Dec 5 15:12:34 2017 -0500
[46767] Plugged a socket descriptor leak in OMAPI
If disconnect is triggered by the reader closing the socket, while there
is data left to write, the socket would be orphaned.
omapip/buffer.c
omapi_connection_writea() - added logic to recall disconnect once
pending data has been written
omapip/message.c
Removed static declaration from omapi_message_unregister so you can
actually compile when DEBUG_PROTOCOL is defined.
Added a release note
diff --git a/omapip/buffer.c b/omapip/buffer.c
index 6e0621b..a21f0a8 100644
--- a/omapip/buffer.c
+++ b/omapip/buffer.c
@@ -565,6 +565,15 @@ isc_result_t omapi_connection_writer (omapi_object_t *h)
omapi_buffer_dereference (&buffer, MDL);
}
}
+
+ /* If we had data left to write when we're told to disconnect,
+ * we need recall disconnect, now that we're done writing.
+ * See rt46767. */
+ if (c->out_bytes == 0 && c->state == omapi_connection_disconnecting) {
+ omapi_disconnect (h, 1);
+ return ISC_R_SHUTTINGDOWN;
+ }
+
return ISC_R_SUCCESS;
}
diff --git a/omapip/message.c b/omapip/message.c
index ee15d82..37abbd2 100644
--- a/omapip/message.c
+++ b/omapip/message.c
@@ -339,7 +339,7 @@ isc_result_t omapi_message_unregister (omapi_object_t *mo)
}
#ifdef DEBUG_PROTOCOL
-static const char *omapi_message_op_name(int op) {
+const char *omapi_message_op_name(int op) {
switch (op) {
case OMAPI_OP_OPEN: return "OMAPI_OP_OPEN";
case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH";
diff --git a/common/options.c b/common/options.c
index 83e0384..8a1deca 100644
--- a/common/options.c
+++ b/common/options.c
@@ -1672,7 +1672,8 @@ format_min_length(format, oc)
/* Format the specified option so that a human can easily read it. */
-
+/* Maximum pretty printed size */
+#define MAX_OUTPUT_SIZE 32*1024
const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
struct option *option;
const unsigned char *data;
@@ -1680,8 +1681,9 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
int emit_commas;
int emit_quotes;
{
- static char optbuf [32768]; /* XXX */
- static char *endbuf = &optbuf[sizeof(optbuf)];
+ /* We add 128 byte pad so we don't have to add checks everywhere. */
+ static char optbuf [MAX_OUTPUT_SIZE + 128]; /* XXX */
+ static char *endbuf = optbuf + MAX_OUTPUT_SIZE;
int hunksize = 0;
int opthunk = 0;
int hunkinc = 0;
@@ -2132,7 +2134,14 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
log_error ("Unexpected format code %c",
fmtbuf [j]);
}
+
op += strlen (op);
+ if (op >= endbuf) {
+ log_error ("Option data exceeds"
+ " maximum size %d", MAX_OUTPUT_SIZE);
+ return ("<error>");
+ }
+
if (dp == data + len)
break;
if (j + 1 < numelem && comma != ':')
diff --git a/common/options.c b/common/options.c
index 83e0384..a58c5fc 100644
--- a/common/options.c
+++ b/common/options.c
@@ -189,6 +189,8 @@ int parse_option_buffer (options, buffer, length, universe)
/* If the length is outrageous, the options are bad. */
if (offset + len > length) {
+ /* Avoid reference count overflow */
+ option_dereference(&option, MDL);
reason = "option length exceeds option buffer length";
bogus:
log_error("parse_option_buffer: malformed option "
diff -up dhcp-4.3.0a1/common/parse.c.64-bit_lease_parse dhcp-4.3.0a1/common/parse.c
--- dhcp-4.3.0a1/common/parse.c.64-bit_lease_parse 2013-12-11 01:25:12.000000000 +0100
+++ dhcp-4.3.0a1/common/parse.c 2013-12-19 15:45:25.990771814 +0100
@@ -938,8 +938,8 @@ TIME
parse_date_core(cfile)
struct parse *cfile;
{
- int guess;
- int tzoff, year, mon, mday, hour, min, sec;
+ TIME guess;
+ long int tzoff, year, mon, mday, hour, min, sec;
const char *val;
enum dhcp_token token;
static int months[11] = { 31, 59, 90, 120, 151, 181,
@@ -965,7 +965,7 @@ parse_date_core(cfile)
}
skip_token(&val, NULL, cfile); /* consume number */
- guess = atoi(val);
+ guess = atol(val);
return((TIME)guess);
}
@@ -993,7 +993,7 @@ parse_date_core(cfile)
somebody invents a time machine, I think we can safely disregard
it. This actually works around a stupid Y2K bug that was present
in a very early beta release of dhcpd. */
- year = atoi(val);
+ year = atol(val);
if (year > 1900)
year -= 1900;
@@ -1039,7 +1039,7 @@ parse_date_core(cfile)
return((TIME)0);
}
skip_token(&val, NULL, cfile); /* consume day of month */
- mday = atoi(val);
+ mday = atol(val);
/* Hour... */
token = peek_token(&val, NULL, cfile);
@@ -1050,7 +1050,7 @@ parse_date_core(cfile)
return((TIME)0);
}
skip_token(&val, NULL, cfile); /* consume hour */
- hour = atoi(val);
+ hour = atol(val);
/* Colon separating hour from minute... */
token = peek_token(&val, NULL, cfile);
@@ -1072,7 +1072,7 @@ parse_date_core(cfile)
return((TIME)0);
}
skip_token(&val, NULL, cfile); /* consume minute */
- min = atoi(val);
+ min = atol(val);
/* Colon separating minute from second... */
token = peek_token(&val, NULL, cfile);
@@ -1094,13 +1094,13 @@ parse_date_core(cfile)
return((TIME)0);
}
skip_token(&val, NULL, cfile); /* consume second */
- sec = atoi(val);
+ sec = atol(val);
tzoff = 0;
token = peek_token(&val, NULL, cfile);
if (token == NUMBER) {
skip_token(&val, NULL, cfile); /* consume tzoff */
- tzoff = atoi(val);
+ tzoff = atol(val);
} else if (token != SEMI) {
skip_token(&val, NULL, cfile);
parse_warn(cfile,
diff -up dhcp-4.3.3b1/client/clparse.c.cloexec dhcp-4.3.3b1/client/clparse.c
--- dhcp-4.3.3b1/client/clparse.c.cloexec 2015-08-10 10:46:20.264755543 +0200
+++ dhcp-4.3.3b1/client/clparse.c 2015-08-10 10:46:20.274755510 +0200
@@ -247,7 +247,7 @@ int read_client_conf_file (const char *n
int token;
isc_result_t status;
- if ((file = open (name, O_RDONLY)) < 0)
+ if ((file = open (name, O_RDONLY | O_CLOEXEC)) < 0)
return uerr2isc (errno);
cfile = NULL;
@@ -323,7 +323,7 @@ void read_client_leases ()
/* Open the lease file. If we can't open it, just return -
we can safely trust the server to remember our state. */
- if ((file = open (path_dhclient_db, O_RDONLY)) < 0)
+ if ((file = open (path_dhclient_db, O_RDONLY | O_CLOEXEC)) < 0)
return;
cfile = NULL;
diff -up dhcp-4.3.3b1/client/dhclient.c.cloexec dhcp-4.3.3b1/client/dhclient.c
--- dhcp-4.3.3b1/client/dhclient.c.cloexec 2015-08-10 10:46:20.260755556 +0200
+++ dhcp-4.3.3b1/client/dhclient.c 2015-08-10 10:46:20.275755506 +0200
@@ -153,11 +153,11 @@ main(int argc, char **argv) {
/* Make sure that file descriptors 0 (stdin), 1, (stdout), and
2 (stderr) are open. To do this, we assume that when we
open a file the lowest available file descriptor is used. */
- fd = open("/dev/null", O_RDWR);
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
if (fd == 0)
- fd = open("/dev/null", O_RDWR);
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
if (fd == 1)
- fd = open("/dev/null", O_RDWR);
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
if (fd == 2)
log_perror = 0; /* No sense logging to /dev/null. */
else if (fd != -1)
@@ -519,7 +519,7 @@ main(int argc, char **argv) {
long temp;
int e;
- if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) {
+ if ((pidfd = fopen(path_dhclient_pid, "re")) != NULL) {
e = fscanf(pidfd, "%ld\n", &temp);
oldpid = (pid_t)temp;
@@ -574,7 +574,7 @@ main(int argc, char **argv) {
strncpy(new_path_dhclient_pid, path_dhclient_pid, pfx);
sprintf(new_path_dhclient_pid + pfx, "-%s.pid", ip->name);
- if ((pidfd = fopen(new_path_dhclient_pid, "r")) != NULL) {
+ if ((pidfd = fopen(new_path_dhclient_pid, "re")) != NULL) {
e = fscanf(pidfd, "%ld\n", &temp);
oldpid = (pid_t)temp;
@@ -599,7 +599,7 @@ main(int argc, char **argv) {
int dhc_running = 0;
char procfn[256] = "";
- if ((pidfp = fopen(path_dhclient_pid, "r")) != NULL) {
+ if ((pidfp = fopen(path_dhclient_pid, "re")) != NULL) {
if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
snprintf(procfn,256,"/proc/%u",dhcpid);
dhc_running = (access(procfn, F_OK) == 0);
@@ -3120,7 +3120,7 @@ void rewrite_client_leases ()
if (leaseFile != NULL)
fclose (leaseFile);
- leaseFile = fopen (path_dhclient_db, "w");
+ leaseFile = fopen (path_dhclient_db, "we");
if (leaseFile == NULL) {
log_error ("can't create %s: %m", path_dhclient_db);
return;
@@ -3313,7 +3313,7 @@ write_duid(struct data_string *duid)
return DHCP_R_INVALIDARG;
if (leaseFile == NULL) { /* XXX? */
- leaseFile = fopen(path_dhclient_db, "w");
+ leaseFile = fopen(path_dhclient_db, "we");
if (leaseFile == NULL) {
log_error("can't create %s: %m", path_dhclient_db);
return ISC_R_IOERROR;
@@ -3493,7 +3493,7 @@ int write_client_lease (client, lease, r
return 1;
if (leaseFile == NULL) { /* XXX */
- leaseFile = fopen (path_dhclient_db, "w");
+ leaseFile = fopen (path_dhclient_db, "we");
if (leaseFile == NULL) {
log_error ("can't create %s: %m", path_dhclient_db);
return 0;
@@ -4011,9 +4011,9 @@ void go_daemon ()
(void) close(2);
/* Reopen them on /dev/null. */
- (void) open("/dev/null", O_RDWR);
- (void) open("/dev/null", O_RDWR);
- (void) open("/dev/null", O_RDWR);
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
write_client_pid_file ();
@@ -4030,14 +4030,14 @@ void write_client_pid_file ()
return;
}
- pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
+ pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
if (pfdesc < 0) {
log_error ("Can't create %s: %m", path_dhclient_pid);
return;
}
- pf = fdopen (pfdesc, "w");
+ pf = fdopen (pfdesc, "we");
if (!pf) {
close(pfdesc);
log_error ("Can't fdopen %s: %m", path_dhclient_pid);
diff -up dhcp-4.3.3b1/common/bpf.c.cloexec dhcp-4.3.3b1/common/bpf.c
--- dhcp-4.3.3b1/common/bpf.c.cloexec 2015-07-30 15:17:16.000000000 +0200
+++ dhcp-4.3.3b1/common/bpf.c 2015-08-10 10:46:20.275755506 +0200
@@ -95,7 +95,7 @@ int if_register_bpf (info)
for (b = 0; 1; b++) {
/* %Audit% 31 bytes max. %2004.06.17,Safe% */
sprintf(filename, BPF_FORMAT, b);
- sock = open (filename, O_RDWR, 0);
+ sock = open (filename, O_RDWR | O_CLOEXEC, 0);
if (sock < 0) {
if (errno == EBUSY) {
continue;
diff -up dhcp-4.3.3b1/common/dlpi.c.cloexec dhcp-4.3.3b1/common/dlpi.c
--- dhcp-4.3.3b1/common/dlpi.c.cloexec 2015-07-30 15:17:16.000000000 +0200
+++ dhcp-4.3.3b1/common/dlpi.c 2015-08-10 10:46:20.275755506 +0200
@@ -804,7 +804,7 @@ dlpiopen(const char *ifname) {
}
*dp = '\0';
- return open (devname, O_RDWR, 0);
+ return open (devname, O_RDWR | O_CLOEXEC, 0);
}
/*
diff -up dhcp-4.3.3b1/common/nit.c.cloexec dhcp-4.3.3b1/common/nit.c
--- dhcp-4.3.3b1/common/nit.c.cloexec 2015-07-30 15:17:16.000000000 +0200
+++ dhcp-4.3.3b1/common/nit.c 2015-08-10 10:46:20.275755506 +0200
@@ -75,7 +75,7 @@ int if_register_nit (info)