aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid E. O'Brien <obrien@FreeBSD.org>2000-07-20 08:36:42 +0000
committerDavid E. O'Brien <obrien@FreeBSD.org>2000-07-20 08:36:42 +0000
commit134783f7a807bdea4f5dcb14cf47f3d917fd76b9 (patch)
tree74fa317603829de6b9ba9165393c99dd06763841
parent46050c08041a49a0a7b3d3b8943c8d381a52e6ac (diff)
downloadsrc-134783f7a807bdea4f5dcb14cf47f3d917fd76b9.tar.gz
src-134783f7a807bdea4f5dcb14cf47f3d917fd76b9.zip
Import Patchlevel 3 of the ISC 2.0 dhcp client.
Notes
Notes: svn path=/vendor/isc-dhcp/dist/; revision=63616
-rw-r--r--contrib/isc-dhcp/Makefile.conf1
-rw-r--r--contrib/isc-dhcp/README6
-rw-r--r--contrib/isc-dhcp/RELNOTES11
-rw-r--r--contrib/isc-dhcp/client/Makefile.dist3
-rw-r--r--contrib/isc-dhcp/client/clparse.c6
-rw-r--r--contrib/isc-dhcp/client/dhclient.c231
-rw-r--r--contrib/isc-dhcp/includes/dhcpd.h7
-rw-r--r--contrib/isc-dhcp/includes/version.h2
8 files changed, 173 insertions, 94 deletions
diff --git a/contrib/isc-dhcp/Makefile.conf b/contrib/isc-dhcp/Makefile.conf
index d2fb53499fc5..509e32f823a3 100644
--- a/contrib/isc-dhcp/Makefile.conf
+++ b/contrib/isc-dhcp/Makefile.conf
@@ -46,6 +46,7 @@ MANCAT = cat
ETC = /etc
VARRUN = /var/run
VARDB = /var/db
+CLIENT_PATH = '"PATH=/usr/ucb:/usr/bin:/usr/sbin:/bin:/sbin"'
# Major version number (if applicable)
##--majver--
diff --git a/contrib/isc-dhcp/README b/contrib/isc-dhcp/README
index 03f308f91036..cf1fa6032bd6 100644
--- a/contrib/isc-dhcp/README
+++ b/contrib/isc-dhcp/README
@@ -1,6 +1,6 @@
<C><H4>Internet Software Consortium</H4></C>
<C><H4>Dynamic Host Configuration Protocol Distribution</H4></C>
-<C><H4>Version 2 Patchlevel 2</H4></C>
+<C><H4>Version 2 Patchlevel 3</H4></C>
<C><H4>June 30, 2000</H4></C>
<C><H4>README FILE</H4></C>
@@ -135,13 +135,13 @@ information. On Digital Unix, type ``man pfilt''.</P>
the tar utility and the gzip command - type something like:</P>
<BLOCKQUOTE>
- zcat dhcp-2.0pl2.tar.gz |tar xvf -
+ zcat dhcp-2.0pl3.tar.gz |tar xvf -
</BLOCKQUOTE>
<P>On BSD/OS, you have to type gzcat, not zcat, and you may run into
similar problems on other operating systems.</P>
-<P>Now, cd to the dhcp-2.0pl2 subdirectory that you've just created and
+<P>Now, cd to the dhcp-2.0pl3 subdirectory that you've just created and
configure the source tree by typing:</P>
<BLOCKQUOTE>
diff --git a/contrib/isc-dhcp/RELNOTES b/contrib/isc-dhcp/RELNOTES
index 7e7a5c3c81ee..60d2958de6ec 100644
--- a/contrib/isc-dhcp/RELNOTES
+++ b/contrib/isc-dhcp/RELNOTES
@@ -1,7 +1,7 @@
Internet Software Consortium
Dynamic Host Configuration Protocol Distribution
- Version 2 Patchlevel 2
- June 30, 2000
+ Version 2 Patchlevel 3
+ July 19, 2000
Release Notes
@@ -22,6 +22,13 @@ the README file.
This log describes the changes that have been made in version 2.0
since June of 1997.
+ CHANGES FROM VERSION 2.0 PATCHLEVEL 2
+
+- Rather than calling a client environment setup script, set the
+ environment up directly, so as to avoid any possible exploit making
+ use of clever shell metacharacter hacks. This is a security fix
+ that applies to the DHCP client *only*.
+
CHANGES FROM VERSION 2.0 PATCHLEVEL 1
- Fix a case where an unitialized pointer could result from an exceptional
diff --git a/contrib/isc-dhcp/client/Makefile.dist b/contrib/isc-dhcp/client/Makefile.dist
index 2109d3977c83..2b261a7e4610 100644
--- a/contrib/isc-dhcp/client/Makefile.dist
+++ b/contrib/isc-dhcp/client/Makefile.dist
@@ -42,7 +42,8 @@ MAN = dhclient.8 dhclient.conf.5 dhclient-script.8 dhclient.leases.5
DEBUG = -g
INCLUDES = -I.. -I../includes
DHCPLIB = ../common/libdhcp.a
-CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS)
+CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS) \
+ -DCLIENT_PATH=${CLIENT_PATH}
all: $(PROG) $(CATMANPAGES)
diff --git a/contrib/isc-dhcp/client/clparse.c b/contrib/isc-dhcp/client/clparse.c
index 65acbc803cb3..9af7744f8765 100644
--- a/contrib/isc-dhcp/client/clparse.c
+++ b/contrib/isc-dhcp/client/clparse.c
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: clparse.c,v 1.13.2.4 1999/03/29 21:21:37 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
+"$Id: clparse.c,v 1.13.2.5 2000/07/20 05:06:40 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -50,6 +50,8 @@ static char copyright[] =
struct client_config top_level_config;
+char client_script_name [] = "/etc/dhclient-script";
+
/* client-conf-file :== client-declarations EOF
client-declarations :== <nil>
| client-declaration
@@ -79,7 +81,7 @@ int read_client_conf ()
top_level_config.backoff_cutoff = 15;
top_level_config.initial_interval = 3;
top_level_config.bootp_policy = ACCEPT;
- top_level_config.script_name = "/etc/dhclient-script";
+ top_level_config.script_name = client_script_name;
top_level_config.requested_options
[top_level_config.requested_option_count++] =
DHO_SUBNET_MASK;
diff --git a/contrib/isc-dhcp/client/dhclient.c b/contrib/isc-dhcp/client/dhclient.c
index 30424f6a36eb..4110ad5f9198 100644
--- a/contrib/isc-dhcp/client/dhclient.c
+++ b/contrib/isc-dhcp/client/dhclient.c
@@ -56,7 +56,7 @@
#ifndef lint
static char ocopyright[] =
-"$Id: dhclient.c,v 1.44.2.44 2000/01/26 12:51:11 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhclient.c,v 1.44.2.45 2000/07/20 05:06:41 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -139,6 +139,10 @@ int main (argc, argv, envp)
no_daemon = 1;
} else if (!strcmp (argv [i], "-D")) {
save_scripts = 1;
+ } else if (!strcmp (argv [i], "-cf")) {
+ if (++i == argc)
+ usage (s);
+ path_dhclient_conf = argv [i];
} else if (!strcmp (argv [i], "-pf")) {
if (++i == argc)
usage (s);
@@ -1899,38 +1903,24 @@ void script_init (ip, reason, medium)
char *reason;
struct string_list *medium;
{
- int fd;
-#ifndef HAVE_MKSTEMP
-
- do {
-#endif
- strcpy (scriptName, "/tmp/dcsXXXXXX");
-#ifdef HAVE_MKSTEMP
- fd = mkstemp (scriptName);
-#else
- if (!mktemp (scriptName))
- error ("can't create temporary client script %s: %m",
- scriptName);
- fd = open (scriptName, O_EXCL | O_CREAT | O_WRONLY, 0600);
- } while (fd < 0 && errno == EEXIST);
-#endif
- if (fd < 0)
- error ("can't create temporary script %s: %m", scriptName);
+ struct string_list *sl, *next;
- scriptFile = fdopen (fd, "w");
- if (!scriptFile)
- error ("can't write script file: %m");
- fprintf (scriptFile, "#!/bin/sh\n\n");
if (ip) {
- fprintf (scriptFile, "interface=\"%s\"\n", ip -> name);
- fprintf (scriptFile, "export interface\n");
- }
- if (medium) {
- fprintf (scriptFile, "medium=\"%s\"\n", medium -> string);
- fprintf (scriptFile, "export medium\n");
+ for (sl = ip -> client -> env; sl; sl = next) {
+ next = sl -> next;
+ dfree (sl, "script_init");
+ }
+ ip -> client -> env = (struct string_list *)0;
+ ip -> client -> envc = 0;
+
+ client_envadd (ip -> client, "", "interface", "%s",
+ ip -> name);
+ if (medium)
+ client_envadd (ip -> client,
+ "", "medium", "%s", medium -> string);
+
+ client_envadd (ip -> client, "", "reason", "%s", reason);
}
- fprintf (scriptFile, "reason=\"%s\"\n", reason);
- fprintf (scriptFile, "export reason\n");
}
void script_write_params (ip, prefix, lease)
@@ -1942,9 +1932,8 @@ void script_write_params (ip, prefix, lease)
u_int8_t dbuf [1500];
int len;
- fprintf (scriptFile, "%sip_address=\"%s\"\n",
- prefix, piaddr (lease -> address));
- fprintf (scriptFile, "export %sip_address\n", prefix);
+ client_envadd (ip -> client,
+ prefix, "ip_address", "%s", piaddr (lease -> address));
/* For the benefit of Linux (and operating systems which may
have similar needs), compute the network address based on
@@ -1965,36 +1954,26 @@ void script_write_params (ip, prefix, lease)
subnet = subnet_number (lease -> address, netmask);
if (subnet.len) {
- fprintf (scriptFile, "%snetwork_number=\"%s\";\n",
- prefix, piaddr (subnet));
- fprintf (scriptFile, "export %snetwork_number\n",
- prefix);
+ client_envadd (ip -> client, prefix, "network_number",
+ "%s", piaddr (subnet));
if (!lease -> options [DHO_BROADCAST_ADDRESS].len) {
broadcast = broadcast_addr (subnet, netmask);
if (broadcast.len) {
- fprintf (scriptFile,
- "%s%s=\"%s\";\n", prefix,
- "broadcast_address",
- piaddr (broadcast));
- fprintf (scriptFile,
- "export %s%s\n", prefix,
- "broadcast_address");
+ client_envadd (ip -> client,
+ prefix, "broadcast_address",
+ "%s", piaddr (subnet));
}
}
}
}
- if (lease -> filename) {
- fprintf (scriptFile, "%sfilename=\"%s\";\n",
- prefix, lease -> filename);
- fprintf (scriptFile, "export %sfilename\n", prefix);
- }
- if (lease -> server_name) {
- fprintf (scriptFile, "%sserver_name=\"%s\";\n",
- prefix, lease -> server_name);
- fprintf (scriptFile, "export %sserver_name\n", prefix);
- }
+ if (lease -> filename)
+ client_envadd (ip -> client,
+ prefix, "filename", "%s", lease -> filename);
+ if (lease -> server_name)
+ client_envadd (ip -> client, prefix, "server_name",
+ "%s", lease -> server_name);
for (i = 0; i < 256; i++) {
u_int8_t *dp;
@@ -2067,57 +2046,141 @@ void script_write_params (ip, prefix, lease)
len = 0;
}
if (len) {
- char *s = dhcp_option_ev_name (&dhcp_options [i]);
-
- fprintf (scriptFile, "%s%s=\"%s\"\n", prefix, s,
- pretty_print_option (i, dp, len, 0, 0));
- fprintf (scriptFile, "export %s%s\n", prefix, s);
+ char name [256];
+ if (dhcp_option_ev_name (name, sizeof name,
+ &dhcp_options [i])) {
+ client_envadd (ip -> client, prefix, name, "%s",
+ (pretty_print_option (i, dp,
+ len, 0, 0)));
+ }
}
}
- fprintf (scriptFile, "%sexpiry=\"%d\"\n",
- prefix, (int)lease -> expiry); /* XXX */
- fprintf (scriptFile, "export %sexpiry\n", prefix);
+ client_envadd (ip -> client,
+ prefix, "expiry", "%d", (int)(lease -> expiry));
}
int script_go (ip)
struct interface_info *ip;
{
int rval;
+ char *scriptName;
+ char *argv [2];
+ char **envp;
+ char *epp [3];
+ char reason [] = "REASON=NBI";
+ static char client_path [] = CLIENT_PATH;
+ int i;
+ struct string_list *sp, *next;
+ int pid, wpid, wstatus;
- if (ip)
- fprintf (scriptFile, "%s\n",
- ip -> client -> config -> script_name);
- else
- fprintf (scriptFile, "%s\n",
- top_level_config.script_name);
- fprintf (scriptFile, "exit $?\n");
- fclose (scriptFile);
- chmod (scriptName, 0700);
- rval = system (scriptName);
- if (!save_scripts)
- unlink (scriptName);
- return rval;
+ if (ip) {
+ scriptName = ip -> client -> config -> script_name;
+ envp = dmalloc ((ip -> client -> envc + 2) * sizeof (char *),
+ "script_go");
+ if (!envp) {
+ error ("No memory for client script environment.");
+ return 0;
+ }
+ i = 0;
+ for (sp = ip -> client -> env; sp; sp = sp -> next) {
+ envp [i++] = sp -> string;
+ }
+ envp [i++] = client_path;
+ envp [i] = (char *)0;
+ } else {
+ scriptName = top_level_config.script_name;
+ epp [0] = reason;
+ epp [1] = client_path;
+ epp [2] = (char *)0;
+ envp = epp;
+ }
+
+ argv [0] = scriptName;
+ argv [1] = (char *)0;
+
+ pid = fork ();
+ if (pid < 0) {
+ error ("fork: %m");
+ wstatus = 0;
+ } else if (pid) {
+ do {
+ wpid = wait (&wstatus);
+ } while (wpid != pid && wpid > 0);
+ if (wpid < 0) {
+ error ("wait: %m");
+ wstatus = 0;
+ }
+ } else {
+ execve (scriptName, argv, envp);
+ error ("execve (%s, ...): %m", scriptName);
+ exit (0);
+ }
+
+ if (ip) {
+ for (sp = ip -> client -> env; sp; sp = next) {
+ next = sp -> next;
+ dfree (sp, "script_go");
+ }
+ ip -> client -> env = (struct string_list *)0;
+ ip -> client -> envc = 0;
+ dfree (envp, "script_go");
+ }
+ return wstatus & 0xff;
}
-char *dhcp_option_ev_name (option)
+void client_envadd (struct client_state *client,
+ const char *prefix, const char *name, const char *fmt, ...)
+{
+ char spbuf [1024];
+ char *s;
+ unsigned len, i;
+ struct string_list *val;
+ va_list list;
+
+ va_start (list, fmt);
+ len = vsnprintf (spbuf, sizeof spbuf, fmt, list);
+ va_end (list);
+
+ val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ +
+ len + sizeof *val, "client_envadd");
+ if (!val)
+ return;
+ s = val -> string;
+ strcpy (s, prefix);
+ strcat (s, name);
+ s += strlen (s);
+ *s++ = '=';
+ if (len >= sizeof spbuf) {
+ va_start (list, fmt);
+ vsnprintf (s, len + 1, fmt, list);
+ va_end (list);
+ } else
+ strcpy (s, spbuf);
+ val -> next = client -> env;
+ client -> env = val;
+ client -> envc++;
+}
+
+int dhcp_option_ev_name (buf, buflen, option)
+ char *buf;
+ unsigned buflen;
struct option *option;
{
- static char evbuf [256];
int i;
- if (strlen (option -> name) + 1 > sizeof evbuf)
- error ("option %s name is larger than static buffer.");
for (i = 0; option -> name [i]; i++) {
+ if (i + 1 == buflen)
+ return 0;
if (option -> name [i] == '-')
- evbuf [i] = '_';
+ buf [i] = '_';
else
- evbuf [i] = option -> name [i];
+ buf [i] = option -> name [i];
}
- evbuf [i] = 0;
- return evbuf;
+ buf [i] = 0;
+ return 1;
}
-
+
void go_daemon ()
{
static int state = 0;
diff --git a/contrib/isc-dhcp/includes/dhcpd.h b/contrib/isc-dhcp/includes/dhcpd.h
index ddf34f0ef154..d46ddf1bfae5 100644
--- a/contrib/isc-dhcp/includes/dhcpd.h
+++ b/contrib/isc-dhcp/includes/dhcpd.h
@@ -356,6 +356,9 @@ struct client_state {
struct iaddr requested_address; /* Address we would like to get. */
struct client_config *config; /* Information from config file. */
+
+ struct string_list *env; /* Client script environment. */
+ int envc; /* Number of entries in environment. */
};
/* Information about each network interface. */
@@ -895,13 +898,15 @@ void free_client_lease PROTO ((struct client_lease *));
void rewrite_client_leases PROTO ((void));
void write_client_lease PROTO ((struct interface_info *,
struct client_lease *, int));
-char *dhcp_option_ev_name PROTO ((struct option *));
void script_init PROTO ((struct interface_info *, char *,
struct string_list *));
void script_write_params PROTO ((struct interface_info *,
char *, struct client_lease *));
int script_go PROTO ((struct interface_info *));
+void client_envadd PROTO ((struct client_state *,
+ const char *, const char *, const char *, ...));
+int dhcp_option_ev_name (char *, size_t, struct option *);
struct client_lease *packet_to_lease PROTO ((struct packet *));
void go_daemon PROTO ((void));
diff --git a/contrib/isc-dhcp/includes/version.h b/contrib/isc-dhcp/includes/version.h
index ccda68fa1618..70d3d0675177 100644
--- a/contrib/isc-dhcp/includes/version.h
+++ b/contrib/isc-dhcp/includes/version.h
@@ -1,3 +1,3 @@
/* Current version of ISC DHCP Distribution. */
-#define DHCP_VERSION "2.0pl2"
+#define DHCP_VERSION "2.0pl3"