summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ypserv
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1996-12-24 02:44:52 +0000
committerwpaul <wpaul@FreeBSD.org>1996-12-24 02:44:52 +0000
commitd99939c736aca9e71967d283a2ca32bb8ba0c564 (patch)
treee2cd5added12483e83950c4fdd1088c6a9f1d241 /usr.sbin/ypserv
parent4ab0d63c8aed49b7d37e4c8f3557febdad48a701 (diff)
downloadFreeBSD-src-d99939c736aca9e71967d283a2ca32bb8ba0c564.zip
FreeBSD-src-d99939c736aca9e71967d283a2ca32bb8ba0c564.tar.gz
Fix some bugs:
- Don't dereference a NULL hostent pointer (if T_PTR lookup fails). - Today I asked myself: "Self, you wrote this nifty async resolver that does a great job handling delayed replies to clients using the UDP transport, and the yplib code in libc always uses UDP (except for yp_all()). But what if some dork makes a DNS lookup using TCP?" Being the only dork on hand at the time, I tried it and was enlightened. As I suspected, my transaction ID frobbing hacks cause fireworks if called on a TCP transport handle (duh: the structures are different). Fix: check the type of socket in xprt->xp_sock using getsockopt() and don't use svcudp_get_xid() and svcudp_set_xid() for anything except SOCK_DGRAM sockets. (Since accept() gives you a new socket for each connection, the transaction ID munging isn't needed for TCP anyway.)
Diffstat (limited to 'usr.sbin/ypserv')
-rw-r--r--usr.sbin/ypserv/yp_dnslookup.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/usr.sbin/ypserv/yp_dnslookup.c b/usr.sbin/ypserv/yp_dnslookup.c
index 7b0acbb..7e350a2 100644
--- a/usr.sbin/ypserv/yp_dnslookup.c
+++ b/usr.sbin/ypserv/yp_dnslookup.c
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: yp_dnslookup.c,v 1.5 1996/12/22 15:45:33 wpaul Exp $
+ * $Id: yp_dnslookup.c,v 1.4 1996/12/22 22:30:54 wpaul Exp $
*/
/*
@@ -65,7 +65,7 @@
#include "yp_extern.h"
#ifndef lint
-static const char rcsid[] = "$Id: yp_dnslookup.c,v 1.5 1996/12/22 15:45:33 wpaul Exp $";
+static const char rcsid[] = "$Id: yp_dnslookup.c,v 1.4 1996/12/22 22:30:54 wpaul Exp $";
#endif
static char *parse(hp)
@@ -110,6 +110,7 @@ struct circleq_dnsentry {
unsigned long ttl;
unsigned long sent;
unsigned long type;
+ unsigned short prot_type;
char **domain;
char *name;
struct in_addr addr;
@@ -243,12 +244,17 @@ static void yp_send_dns_reply(q, buf)
* way we found 'em. This is _INCREDIBLY_ non-portable; it's
* not even supported by the RPC library.
*/
- xid = svcudp_set_xid(q->xprt, q->xid);
+ /*
+ * XXX Don't from the transaction ID for TCP handles.
+ */
+ if (q->prot_type == SOCK_DGRAM)
+ xid = svcudp_set_xid(q->xprt, q->xid);
client_addr = q->xprt->xp_raddr;
q->xprt->xp_raddr = q->client_addr;
if (!svc_sendreply(q->xprt, xdr_ypresp_val, (char *)&result))
yp_error("svc_sendreply failed");
- svcudp_set_xid(q->xprt, xid);
+ if (q->prot_type == SOCK_DGRAM)
+ svcudp_set_xid(q->xprt, xid);
q->xprt->xp_raddr = client_addr;
return;
}
@@ -311,7 +317,7 @@ void yp_run_dnsq()
if (hent == NULL) {
char retrybuf[MAXHOSTNAMELEN];
- if (q->domain && *q->domain) {
+ if (h_errno == TRY_AGAIN && q->domain && *q->domain) {
snprintf(retrybuf, sizeof(retrybuf), "%s.%s",
q->name, *q->domain);
if (debug)
@@ -321,12 +327,13 @@ void yp_run_dnsq()
q->domain++;
return;
}
+ } else {
+ if (q->type == T_PTR) {
+ hent->h_addr = (char *)&q->addr.s_addr;
+ hent->h_length = sizeof(struct in_addr);
+ }
}
- if (q->type == T_PTR) {
- hent->h_addr = (char *)&q->addr.s_addr;
- hent->h_length = sizeof(struct in_addr);
- }
yp_send_dns_reply(q, parse(hent));
pending--;
@@ -344,6 +351,7 @@ ypstat yp_async_lookup_name(xprt, name)
char *name;
{
register struct circleq_dnsentry *q;
+ int type, len;
if ((q = yp_malloc_dnsent()) == NULL)
return(YP_YPERR);
@@ -352,7 +360,14 @@ ypstat yp_async_lookup_name(xprt, name)
q->ttl = DEF_TTL;
q->sent = 1;
q->xprt = xprt;
- q->xid = svcudp_get_xid(xprt);
+ type = -1; len = sizeof(type);
+ if (getsockopt(xprt->xp_sock,SOL_SOCKET,SO_TYPE,&type,&len) == -1) {
+ yp_error("getsockopt failed: %s", strerror(errno));
+ return(YP_YPERR);
+ }
+ q->prot_type = type;
+ if (q->prot_type == SOCK_DGRAM)
+ q->xid = svcudp_get_xid(xprt);
q->client_addr = xprt->xp_raddr;
if (!strchr(name, '.'))
q->domain = _res.dnsrch;
@@ -383,6 +398,7 @@ ypstat yp_async_lookup_addr(xprt, addr)
register struct circleq_dnsentry *q;
char buf[MAXHOSTNAMELEN];
int a, b, c, d;
+ int type, len;
if ((q = yp_malloc_dnsent()) == NULL)
return(YP_YPERR);
@@ -401,7 +417,14 @@ ypstat yp_async_lookup_addr(xprt, addr)
q->sent = 1;
q->xprt = xprt;
q->domain = NULL;
- q->xid = svcudp_get_xid(xprt);
+ type = -1; len = sizeof(type);
+ if (getsockopt(xprt->xp_sock,SOL_SOCKET,SO_TYPE,&type,&len) == -1) {
+ yp_error("getsockopt failed: %s", strerror(errno));
+ return(YP_YPERR);
+ }
+ q->prot_type = type;
+ if (q->prot_type == SOCK_DGRAM)
+ q->xid = svcudp_get_xid(xprt);
q->client_addr = xprt->xp_raddr;
q->id = yp_send_dns_query(buf, q->type);
OpenPOWER on IntegriCloud