summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2004-04-24 21:40:36 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2004-04-24 21:40:36 +0000
commit42090a4d22f5c1213635160510f17b68ce84eb73 (patch)
tree16da453bd097457ef4e69be3480cfbe720cebe99 /usr.sbin
parent22ed70ce27c4051e9a44bb6a89436e743b4e9de9 (diff)
Don't return NULL in getconfigent() when an unresolvable hostname
or unsupported address family is specified. This simplifies the hostname/address lookup loops and gets rid of the skip label. Found by mpech@. OK deraadt@ and otto@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/inetd/inetd.813
-rw-r--r--usr.sbin/inetd/inetd.c207
2 files changed, 91 insertions, 129 deletions
diff --git a/usr.sbin/inetd/inetd.8 b/usr.sbin/inetd/inetd.8
index a97cce77a88..0033aa5e3fa 100644
--- a/usr.sbin/inetd/inetd.8
+++ b/usr.sbin/inetd/inetd.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: inetd.8,v 1.25 2003/06/12 12:59:50 jmc Exp $
+.\" $OpenBSD: inetd.8,v 1.26 2004/04/24 21:40:35 millert Exp $
.\" Copyright (c) 1985, 1991 The Regents of the University of California.
.\" All rights reserved.
.\"
@@ -192,11 +192,18 @@ and
.Dq udp
will be recognized as
.Dq TCP or UDP over default IP version .
-It is currently IPv4, but in the future it will be IPv6.
+This is currently IPv4, but in the future it will be IPv6.
If you need to specify IPv4 or IPv6 explicitly, use something like
.Dq tcp4
or
.Dq udp6 .
+A
+.Em protocol
+of
+.Dq unix
+is used to specify a socket in the
+.Ux
+domain.
.Pp
The
.Em wait/nowait
@@ -377,7 +384,7 @@ command appeared in
Support for Sun-RPC
based services is modelled after that
provided by SunOS 4.1.
-IPv6 support and IPsec hack was made by KAME project, in 1999.
+IPv6 support was added by the KAME project in 1999.
.Sh BUGS
Host address specifiers, while they make conceptual sense for RPC
services, do not work entirely correctly.
diff --git a/usr.sbin/inetd/inetd.c b/usr.sbin/inetd/inetd.c
index b0598034dbe..4cd7165bcb6 100644
--- a/usr.sbin/inetd/inetd.c
+++ b/usr.sbin/inetd/inetd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: inetd.c,v 1.116 2004/03/31 19:12:22 millert Exp $ */
+/* $OpenBSD: inetd.c,v 1.117 2004/04/24 21:40:35 millert Exp $ */
/*
* Copyright (c) 1983,1991 The Regents of the University of California.
@@ -36,8 +36,8 @@ char copyright[] =
#endif /* not lint */
#ifndef lint
-/*static char sccsid[] = "from: @(#)inetd.c 5.30 (Berkeley) 6/3/91";*/
-static char rcsid[] = "$OpenBSD: inetd.c,v 1.116 2004/03/31 19:12:22 millert Exp $";
+/*static const char sccsid[] = "from: @(#)inetd.c 5.30 (Berkeley) 6/3/91";*/
+static const char rcsid[] = "$OpenBSD: inetd.c,v 1.117 2004/04/24 21:40:35 millert Exp $";
#endif /* not lint */
/*
@@ -682,7 +682,7 @@ doconfig(void)
if (matchconf(sep, cp))
break;
add = 0;
- if (sep != 0) {
+ if (sep != NULL) {
int i;
#define SWAP(type, a, b) {type c=(type)a; a=(type)b; b=(type)c;}
@@ -1162,12 +1162,9 @@ endconfig(void)
struct servtab *
getconfigent(void)
{
- struct servtab *sep;
+ struct servtab *sep, *tsep;
+ char *arg, *cp, *hostdelim, *s;
int argc;
- char *cp, *arg, *s;
- char *hostdelim;
- struct servtab *nsep;
- struct servtab *psep;
sep = (struct servtab *) malloc(sizeof(struct servtab));
if (sep == NULL) {
@@ -1200,7 +1197,9 @@ more:
if (arg[0] == '[' && hostdelim > arg && hostdelim[-1] == ']') {
hostdelim[-1] = '\0';
sep->se_hostaddr = newstr(arg + 1);
- } else
+ } else if (hostdelim == arg)
+ sep->se_hostaddr = newstr("*");
+ else
sep->se_hostaddr = newstr(arg);
arg = hostdelim + 1;
/*
@@ -1242,10 +1241,29 @@ more:
if (strcmp(sep->se_proto, "unix") == 0) {
sep->se_family = AF_UNIX;
+ if (sep->se_hostaddr != NULL) {
+ syslog(LOG_WARNING, "%s/%s: %s: host address "
+ "specifiers are not supported in the UNIX domain",
+ sep->se_service, sep->se_proto, sep->se_hostaddr);
+ goto more;
+ }
} else {
+ int s;
+
sep->se_family = AF_INET;
if (sep->se_proto[strlen(sep->se_proto) - 1] == '6')
sep->se_family = AF_INET6;
+
+ /* check if the family is supported */
+ s = socket(sep->se_family, SOCK_DGRAM, 0);
+ if (s < 0) {
+ syslog(LOG_WARNING, "%s/%s: %s: the address family is "
+ "not supported by the kernel", sep->se_service,
+ sep->se_proto, sep->se_hostaddr);
+ goto more;
+ }
+ close(s);
+
if (strncmp(sep->se_proto, "rpc/", 4) == 0) {
char *cp, *ccp;
long l;
@@ -1342,124 +1360,60 @@ more:
sep->se_argv[argc++] = NULL;
/*
- * Now that we've processed the entire line, check if the hostname
- * specifier was a comma separated list of hostnames. If so
- * we'll make new entries for each address.
+ * Resolve each hostname in the se_hostaddr list (if any)
+ * and create a new entry for each resolved address.
*/
- while ((hostdelim = strrchr(sep->se_hostaddr, ',')) != NULL) {
- nsep = dupconfig(sep);
-
- /*
- * NULL terminate the hostname field of the existing entry,
- * and make a dup for the new entry.
- */
- *hostdelim++ = '\0';
- nsep->se_hostaddr = newstr(hostdelim);
-
- nsep->se_next = sep->se_next;
- sep->se_next = nsep;
- }
-
- nsep = sep;
- while (nsep != NULL) {
- nsep->se_checked = 1;
- switch (nsep->se_family) {
- case AF_INET:
- case AF_INET6:
- {
- struct addrinfo hints, *res0, *res;
- char *host, *port;
- int error;
- int s;
-
- /* check if the family is supported */
- s = socket(nsep->se_family, SOCK_DGRAM, 0);
- if (s < 0) {
- syslog(LOG_WARNING,
- "%s/%s: %s: the address family is "
- "not supported by the kernel",
- nsep->se_service, nsep->se_proto,
- nsep->se_hostaddr);
- nsep->se_checked = 0;
- goto skip;
- }
- close(s);
+ if (sep->se_hostaddr != NULL) {
+ struct addrinfo hints, *res0, *res;
+ char *host, *hostlist0, *hostlist, *port;
+ int error;
+
+ hostlist = hostlist0 = sep->se_hostaddr;
+ sep->se_hostaddr = NULL;
+ sep->se_checked = -1;
+ while ((host = strsep(&hostlist, ",")) != NULL) {
+ if (*host == '\0')
+ continue;
memset(&hints, 0, sizeof(hints));
- hints.ai_family = nsep->se_family;
- hints.ai_socktype = nsep->se_socktype;
+ hints.ai_family = sep->se_family;
+ hints.ai_socktype = sep->se_socktype;
hints.ai_flags = AI_PASSIVE;
- if (!strcmp(nsep->se_hostaddr, "*"))
- host = NULL;
- else
- host = nsep->se_hostaddr;
port = "0";
/* XXX shortened IPv4 syntax is now forbidden */
- error = getaddrinfo(host, port, &hints, &res0);
+ error = getaddrinfo(strcmp(host, "*") ? host : NULL,
+ port, &hints, &res0);
if (error) {
syslog(LOG_ERR, "%s/%s: %s: %s",
- nsep->se_service, nsep->se_proto,
- nsep->se_hostaddr,
- gai_strerror(error));
- nsep->se_checked = 0;
- goto skip;
+ sep->se_service, sep->se_proto,
+ host, gai_strerror(error));
+ continue;
}
for (res = res0; res; res = res->ai_next) {
if (res->ai_addrlen >
- sizeof(nsep->se_ctrladdr_storage))
- continue;
- if (res == res0) {
- memcpy(&nsep->se_ctrladdr_storage,
- res->ai_addr, res->ai_addrlen);
+ sizeof(sep->se_ctrladdr_storage))
continue;
- }
-
- psep = dupconfig(nsep);
- psep->se_hostaddr = newstr(nsep->se_hostaddr);
- psep->se_checked = 1;
- memcpy(&psep->se_ctrladdr_storage, res->ai_addr,
- res->ai_addrlen);
- psep->se_ctrladdr_size = res->ai_addrlen;
-
/*
- * Prepend to list, don't want to look up its
- * hostname again.
+ * If sep is unused, store host in there.
+ * Otherwise, dup a new entry and prepend it.
*/
- psep->se_next = sep;
- sep = psep;
+ if (sep->se_checked == -1) {
+ sep->se_checked = 0;
+ } else {
+ tsep = dupconfig(sep);
+ tsep->se_next = sep;
+ sep = tsep;
+ }
+ sep->se_hostaddr = newstr(host);
+ memcpy(&sep->se_ctrladdr_storage,
+ res->ai_addr, res->ai_addrlen);
+ sep->se_ctrladdr_size = res->ai_addrlen;
}
freeaddrinfo(res0);
- break;
- }
- }
-skip:
- nsep = nsep->se_next;
- }
-
- /*
- * Finally, free any entries which failed the gethostbyname
- * check.
- */
- psep = NULL;
- nsep = sep;
- while (nsep != NULL) {
- struct servtab *tsep;
-
- if (nsep->se_checked == 0) {
- tsep = nsep;
- if (psep == NULL) {
- sep = nsep->se_next;
- nsep = sep;
- } else {
- nsep = nsep->se_next;
- psep->se_next = nsep;
- }
- freeconfig(tsep);
- } else {
- nsep->se_checked = 0;
- psep = nsep;
- nsep = nsep->se_next;
}
+ free(hostlist0);
+ if (sep->se_checked == -1)
+ goto more; /* no resolvable names/addresses */
}
return (sep);
@@ -1470,21 +1424,22 @@ freeconfig(struct servtab *cp)
{
int i;
- if (cp->se_hostaddr)
- free(cp->se_hostaddr);
- if (cp->se_service)
- free(cp->se_service);
- if (cp->se_proto)
- free(cp->se_proto);
- if (cp->se_user)
- free(cp->se_user);
- if (cp->se_group)
- free(cp->se_group);
- if (cp->se_server)
- free(cp->se_server);
- for (i = 0; i < MAXARGV; i++)
- if (cp->se_argv[i])
- free(cp->se_argv[i]);
+ free(cp->se_hostaddr);
+ cp->se_hostaddr = NULL;
+ free(cp->se_service);
+ cp->se_service = NULL;
+ free(cp->se_proto);
+ cp->se_proto = NULL;
+ free(cp->se_user);
+ cp->se_user = NULL;
+ free(cp->se_group);
+ cp->se_group = NULL;
+ free(cp->se_server);
+ cp->se_server = NULL;
+ for (i = 0; i < MAXARGV; i++) {
+ free(cp->se_argv[i]);
+ cp->se_argv[i] = NULL;
+ }
}
char *