aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/named/ns_validate.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/named/ns_validate.c')
-rw-r--r--usr.sbin/named/ns_validate.c195
1 files changed, 140 insertions, 55 deletions
diff --git a/usr.sbin/named/ns_validate.c b/usr.sbin/named/ns_validate.c
index 46095180f6f4..358fcb8557de 100644
--- a/usr.sbin/named/ns_validate.c
+++ b/usr.sbin/named/ns_validate.c
@@ -52,21 +52,21 @@ static int VQcount;
* pseudocode for function validate is as follows:
* validate(domain, server, type, class, data, dlen, rcode) {
*
- * if(dname or a higher level name not found in cache)
+ * if (dname or a higher level name not found in cache)
* return INVALID;
* if (NS records for "domain" found in cache){
*
- * if(we are authoritative) /findns() returned NXDOMAIN;/
- * if(we did not have an exact match on names)
+ * if (we are authoritative) /findns() returned NXDOMAIN;/
+ * if (we did not have an exact match on names)
* =>the name does not exist in our database
* => data is bad: return INVALID
- * if(data agrees with what we have)
+ * if (data agrees with what we have)
* return VALID_NO_CACHE;
* else return INVALID;
*
- * if(we are not authoritative) /findns() returned OK;/
+ * if (we are not authoritative) /findns() returned OK;/
* if (address records for NS's found in cache){
- * if("server" = one of the addresses){
+ * if ("server" = one of the addresses){
* return VALID_CACHE;
* }else{
* stick in queue of "to_validate" data;
@@ -121,7 +121,7 @@ validate(dname, server, type, class, data, dlen
/* everything from forwarders is the GOSPEL */
for (fwd = fwdtab; fwd != NULL; fwd = fwd->next) {
if (server->sin_addr.s_addr == fwd->fwdaddr.sin_addr.s_addr)
- return(VALID_CACHE);
+ return (VALID_CACHE);
}
htp = hashtab;
@@ -138,16 +138,15 @@ validate(dname, server, type, class, data, dlen
fname[0] = '\0';
}
dprintf(5, (ddt,
- "validate:namebuf found np:0x%x, d:\"%s\", f:\"%s\"\n",
- np, dname, fname));
+ "validate:namebuf found np:%#lx, d:\"%s\", f:\"%s\"\n",
+ (u_long)np, dname, fname));
/* save the namebuf if we were able to locate the exact dname */
if (!strcasecmp(dname, fname)) {
dnamep = np;
exactmatch = 1;
}
- if (np == NULL && fname != NULL) {
+ if (np == NULL && fname != NULL)
free((char *)fname);
- }
switch (findns(&np, class, nsp, &count, 0)) {
case NXDOMAIN:
/** we are authoritative for this domain, lookup name
@@ -162,19 +161,19 @@ validate(dname, server, type, class, data, dlen
needs_prime_cache = 0;
#ifdef NCACHE
- if(rcode == NXDOMAIN) {
+ if (rcode == NXDOMAIN) {
/* If we had an exactmatch on the name, we found the
* name in our authority database, so this couldn't
* have been a bad name. INVALID data, say so
*/
if (exactmatch)
- return INVALID;
+ return (INVALID);
else
/* we did not have an exactmatch, the data is
* good, we do not NCACHE stuff we are
* authoritative for, though.
*/
- return VALID_NO_CACHE;
+ return (VALID_NO_CACHE);
}
#endif
if (!strcasecmp(dname, np->n_dname)) {
@@ -185,9 +184,9 @@ validate(dname, server, type, class, data, dlen
* doesn't, invalid.
*/
if (isvalid(np, type, class, data, dlen))
- return VALID_NO_CACHE;
+ return (VALID_NO_CACHE);
else
- return INVALID;
+ return (INVALID);
}
/* we found ns records in a higher level, if we were unable to
@@ -196,16 +195,16 @@ validate(dname, server, type, class, data, dlen
* this name. this name is obviously invalid
*/
if (!exactmatch)
- return INVALID;
+ return (INVALID);
/* we found the exact name earlier and we are obviously
* authoritative so check for data records and see if any
* match.
*/
if (isvalid(dnamep, type, class, data, dlen))
- return VALID_NO_CACHE;
+ return (VALID_NO_CACHE);
else
- return INVALID;
+ return (INVALID);
case SERVFAIL:/* could not find name server records*/
/* stick_in_queue(dname, type, class, data); */
@@ -214,7 +213,7 @@ validate(dname, server, type, class, data, dlen
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
- return INVALID;
+ return (INVALID);
case OK: /*proceed */
dprintf(5,
@@ -226,19 +225,19 @@ validate(dname, server, type, class, data, dlen
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
- return VALID_CACHE;
+ return (VALID_CACHE);
}
/* server is not one of those we know of */
/* stick_in_queue(dname, type, class, data); */
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
- return INVALID;
+ return (INVALID);
default:
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
- return INVALID;
+ return (INVALID);
} /*switch*/
} /*validate*/
@@ -262,7 +261,7 @@ isvalid(np, type, class, data, dlen)
if (!wanted(dp, class, type)) {
if ((type == T_CNAME) && (class == dp->d_class)) {
/* if a cname exists, any other will not */
- return(0);
+ return (0);
/* we come here only for zone info,
* so -ve $ed info can't be
*/
@@ -277,12 +276,10 @@ isvalid(np, type, class, data, dlen)
* we should return FAILURE since we should not have found
* data here.
*/
- if ((data == NULL) || (dlen == 0)) {
- return 0;
- }
+ if ((data == NULL) || (dlen == 0))
+ return (0);
- /* XXX: why aren't we just calling db_cmp() ?
- */
+ /* XXX: why aren't we just calling db_cmp()? */
switch (type) {
char *td;
@@ -298,6 +295,7 @@ isvalid(np, type, class, data, dlen)
case T_TXT:
case T_X25:
case T_ISDN:
+ case T_LOC:
#ifdef ALLOW_T_UNSPEC
case T_UNSPEC:
#endif
@@ -378,6 +376,29 @@ isvalid(np, type, class, data, dlen)
break;
return (1);
+ case T_PX:
+ x = memcmp(dp->d_data, data,
+ INT16SZ);
+ if (x != 0)
+ break;
+ td = data + INT16SZ;
+ tdp = dp->d_data + INT16SZ;
+
+ /* compare first string */
+ x = strncasecmp(td, (char *)tdp,
+ strlen((char *)td) + 1);
+ if (x != 0)
+ break;
+ td += (strlen(td) + 1);
+ tdp += (strlen(tdp) + 1);
+
+ /* compare second string */
+ x = strncasecmp(td, (char *)tdp,
+ strlen((char *)td+1));
+ if (x != 0)
+ break;
+ return (1);
+
default:
dprintf(3, (ddt, "unknown type %d\n", type));
return (0);
@@ -390,7 +411,7 @@ isvalid(np, type, class, data, dlen)
*/
if ((data == NULL) || (dlen == 0)) {
/* negative data, report success */
- return 1;
+ return (1);
}
/* positive data, no such RR, validation failed */
return (0);
@@ -512,7 +533,7 @@ check_in_tables(nsp, server, syslogdname)
void
store_name_addr(servername, serveraddr, syslogdname, sysloginfo)
char *servername;
- struct in_addr *serveraddr;
+ struct in_addr serveraddr;
char *syslogdname;
char *sysloginfo;
{
@@ -520,21 +541,21 @@ store_name_addr(servername, serveraddr, syslogdname, sysloginfo)
dprintf(3, (ddt,
"store_name_addr:s:%s, a:[%s]\n",
- servername, inet_ntoa(*serveraddr)));
+ servername, inet_ntoa(serveraddr)));
/* if we already have the name address pair in cache, return */
for (i = lastNA; i != firstNA; i = (i+1) % MAXNAMECACHE) {
if (strcasecmp(servername, nameaddrlist[i].nsname) == 0) {
- if (serveraddr->s_addr
+ if (serveraddr.s_addr
==
nameaddrlist[i].ns_addr.s_addr) {
dprintf(5, (ddt,
"store_name_addr:found n and a [%s] [%s] in our $\n",
inet_ntoa(nameaddrlist[i].ns_addr),
- inet_ntoa(*serveraddr)));
+ inet_ntoa(serveraddr)));
return;
} /* if */
- } else if (serveraddr->s_addr
+ } else if (serveraddr.s_addr
==
nameaddrlist[i].ns_addr.s_addr) {
#ifdef BAD_IDEA
@@ -543,20 +564,15 @@ store_name_addr(servername, serveraddr, syslogdname, sysloginfo)
* replace old name by new, next query likely to have
* NS record matching new
*/
- if (!haveComplained(
- (char*)dhash((u_char*)nameaddrlist[i].nsname,
- strlen(nameaddrlist[i].nsname)),
- (char*)dhash((u_char*)servername,
- strlen(servername))
- )
- ) {
+ if (!haveComplained((char*)
+ nhash(nameaddrlist[i].nsname),
+ (char*)nhash(servername)))
syslog(LOG_INFO,
"%s: server name mismatch for [%s]: (%s != %s) (server for %s)",
sysloginfo,
- inet_ntoa(*serveraddr),
+ inet_ntoa(serveraddr),
nameaddrlist[i].nsname, servername,
syslogdname);
- }
#endif
free(nameaddrlist[i].nsname);
nameaddrlist[i].nsname =
@@ -570,7 +586,7 @@ store_name_addr(servername, serveraddr, syslogdname, sysloginfo)
nameaddrlist[firstNA].nsname =
(char *)malloc((unsigned)strlen(servername)+1);
strcpy(nameaddrlist[firstNA].nsname, servername);
- bcopy((char *)serveraddr,
+ bcopy((char *)&serveraddr,
(char *)&(nameaddrlist[firstNA].ns_addr),
INADDRSZ);
@@ -616,7 +632,7 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
zone, flags));
#ifdef DEBUG
if (debug >= 10)
- fp_query(msg, ddt);
+ fp_nquery(msg, msglen, ddt);
#endif
cp = rrp;
@@ -646,6 +662,7 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
case T_TXT:
case T_X25:
case T_ISDN:
+ case T_LOC:
#ifdef ALLOW_T_UNSPEC
case T_UNSPEC:
#endif
@@ -714,7 +731,7 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
(char *)cp1, sizeof(data) - INT16SZ);
if (n < 0) {
hp->rcode = FORMERR;
- return(-1);
+ return (-1);
}
cp += n;
@@ -725,6 +742,35 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
cp1 = data;
break;
+ case T_PX:
+ /* grab preference */
+ bcopy((char *)cp, data, INT16SZ);
+ cp1 = data + INT16SZ;
+ cp += INT16SZ;
+
+ /* get first name */
+ n = dn_expand(msg, msg + msglen, cp,
+ (char *)cp1, sizeof(data) - INT16SZ);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ cp1 += (n = strlen((char *)cp1) + 1);
+ n1 = sizeof(data) - n;
+
+ /* get second name */
+ n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ cp1 += strlen((char *)cp1) + 1;
+ n = cp1 - data;
+ cp1 = data;
+ break;
+
default:
dprintf(3, (ddt, "unknown type %d\n", type));
return ((cp - rrp) + dlen);
@@ -733,8 +779,8 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
dprintf(2, (ddt,
"update type %d: %d bytes is too much data\n",
type, n));
- hp->rcode = NOCHANGE; /* XXX - FORMERR ??? */
- return(-1);
+ hp->rcode = FORMERR;
+ return (-1);
}
*VCode = validate(dname, server, type, class,(char *)cp1, n
@@ -751,7 +797,7 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
"validation succeeded d:%s, t:%d, c:%d\n",
dname, type, class));
}
- return(cp -rrp);
+ return (cp - rrp);
}
#if 0
@@ -871,7 +917,7 @@ update_msg(msg, msglen, Vlist, c)
if (debug) {
fprintf(ddt, "update_msg: msglen:%d, c:%d\n", *msglen, c);
if (debug >= 10)
- fp_query(msg, ddt);
+ fp_nquery(msg, *msglen, ddt);
}
#endif
/* just making sure we do not do all the work for nothing */
@@ -942,7 +988,7 @@ update_msg(msg, msglen, Vlist, c)
dprintf(3, (ddt,
"newlen:%d, if no RR is INVALID == msglen\n", newlen));
newmsg = (u_char *)calloc(1,newlen + MAXDNAME);
- if(newmsg == NULL)
+ if (newmsg == NULL)
goto badend;
dpp = dnptrs;
*dpp++ = newmsg;
@@ -1022,6 +1068,7 @@ update_msg(msg, msglen, Vlist, c)
case T_TXT:
case T_X25:
case T_ISDN:
+ case T_LOC:
#ifdef ALLOW_T_UNSPEC
case T_UNSPEC:
#endif
@@ -1128,6 +1175,44 @@ update_msg(msg, msglen, Vlist, c)
rembuflen -= n_new+INT16SZ;
break;
+ case T_PX:
+ /* grab preference */
+ bcopy(cp, newcp, INT16SZ);
+ cp += INT16SZ;
+ newcp += INT16SZ;
+
+ /* get first name */
+ n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ goto badend;
+ }
+ cp += n;
+ n_new = dn_comp((char *)data, newcp, rembuflen,
+ dnptrs, edp);
+ if (n_new < 0)
+ goto badend;
+ newcp += n_new;
+ newlen += n_new+INT16SZ;
+ rembuflen -= n_new+INT16SZ;
+ dlen = n_new+INT16SZ;
+ n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ goto badend;
+ }
+ cp += n;
+ n_new = dn_comp((char *)data, newcp, rembuflen,
+ dnptrs, edp);
+ if (n_new < 0)
+ goto badend;
+ newcp += n_new;
+ newlen += n_new;
+ rembuflen -= n_new;
+ dlen += n_new;
+ PUTSHORT(dlen, tempcp);
+ break;
+
default:
dprintf(3, (ddt, "unknown type %d\n", type));
goto badend;
@@ -1148,14 +1233,14 @@ update_msg(msg, msglen, Vlist, c)
#ifdef DEBUG
if (debug >= 10)
- fp_query(msg, ddt);
+ fp_nquery(msg, *msglen, ddt);
#endif
free((char *)RRlen);
- return(n);
+ return (n);
badend:
dprintf(2, (ddt, "encountered problems: UPDATE_MSG\n"));
free((char *)RRlen);
- return(-1);
+ return (-1);
}
#endif /*VALIDATE*/