summaryrefslogtreecommitdiffstats
path: root/contrib/bind/named/db_update.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/named/db_update.c')
-rw-r--r--contrib/bind/named/db_update.c110
1 files changed, 95 insertions, 15 deletions
diff --git a/contrib/bind/named/db_update.c b/contrib/bind/named/db_update.c
index c706c66..bacc7f7 100644
--- a/contrib/bind/named/db_update.c
+++ b/contrib/bind/named/db_update.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_update.c 4.28 (Berkeley) 3/21/91";
-static char rcsid[] = "$Id: db_update.c,v 8.12 1996/08/05 08:31:30 vixie Exp $";
+static char rcsid[] = "$Id: db_update.c,v 8.18 1996/10/08 04:51:03 vixie Exp $";
#endif /* not lint */
/*
@@ -72,8 +72,6 @@ static char rcsid[] = "$Id: db_update.c,v 8.12 1996/08/05 08:31:30 vixie Exp $";
#include "named.h"
static void fixttl __P((struct databuf *));
-static int db_cmp __P((struct databuf *,
- struct databuf *));
/* int
* isRefByNS(name, htp)
@@ -218,6 +216,7 @@ db_update(name, odp, newdp, flags, htp)
register struct databuf *dp, *pdp;
register struct namebuf *np;
int zn, isHintNS;
+ int check_ttl = 0;
const char *fname;
dprintf(3, (ddt, "db_update(%s, 0x%lx, 0x%lx, 0%o, 0x%lx)%s\n",
@@ -226,6 +225,9 @@ db_update(name, odp, newdp, flags, htp)
np = nlookup(name, &htp, &fname, newdp != NULL);
if (np == NULL || fname != name)
return (NONAME);
+
+ if (newdp && zones[newdp->d_zone].z_type == Z_PRIMARY)
+ check_ttl = 1;
/* don't let nonauthoritative updates write in authority zones */
if (newdp && ((zn = findMyZone(np, newdp->d_class)) != DB_Z_CACHE) &&
@@ -312,7 +314,7 @@ db_update(name, odp, newdp, flags, htp)
!= OK) {
dprintf(3, (ddt, "db_update: hint %lx freed\n",
(u_long)dp));
- (void) free((char *)dp);
+ db_free(dp);
}
}
@@ -325,10 +327,18 @@ db_update(name, odp, newdp, flags, htp)
/* {class,type} doesn't match. these are
* the aggregation cases.
*/
- if ((dp->d_type == T_CNAME ||
- odp->d_type == T_CNAME) &&
+ /* Check that CNAMEs are only accompanied by
+ * Secure DNS RR's (KEY, SIG, and NXT).
+ */
+ if (((dp->d_type == T_CNAME &&
+ odp->d_type != T_KEY &&
+ odp->d_type != T_SIG &&
+ odp->d_type != T_NXT) ||
+ (odp->d_type == T_CNAME &&
+ dp->d_type != T_KEY &&
+ dp->d_type != T_SIG &&
+ dp->d_type != T_NXT)) &&
odp->d_class == dp->d_class &&
- odp->d_mark == dp->d_mark &&
#ifdef NCACHE
/* neither the odp nor the new dp are
* negatively cached records...
@@ -338,7 +348,7 @@ db_update(name, odp, newdp, flags, htp)
#endif /*NCACHE*/
zones[odp->d_zone].z_type != Z_CACHE) {
syslog(LOG_INFO,
- "%s has CNAME and other data (illegal)\n",
+ "%s has CNAME and other data (invalid)\n",
name);
goto skip;
}
@@ -520,6 +530,19 @@ db_update(name, odp, newdp, flags, htp)
!bcmp(dp->d_data, newdp->d_data,
INT32SZ + sizeof(u_char)))
goto delete;
+ if (check_ttl) {
+ if (newdp->d_ttl != dp->d_ttl)
+ syslog(LOG_WARNING,
+ "%s %s %s differing ttls: corrected",
+ name[0]?name:".",
+ p_class(dp->d_class),
+ p_type(dp->d_type));
+ if (newdp->d_ttl > dp->d_ttl) {
+ newdp->d_ttl = dp->d_ttl;
+ } else {
+ dp->d_ttl = newdp->d_ttl;
+ }
+ }
}
if ((flags & DB_NODATA) && !db_cmp(dp, odp)) {
/* refresh ttl if cache entry */
@@ -552,6 +575,10 @@ db_update(name, odp, newdp, flags, htp)
if (odp->d_size > 0)
if (db_cmp(dp, odp))
goto skip;
+ if (odp->d_clev < dp->d_clev)
+ goto skip;
+ if (odp->d_cred < dp->d_cred)
+ goto skip;
foundRR = 1;
if (flags & DB_DELETE) {
delete: dp = rm_datum(dp, np, pdp);
@@ -588,9 +615,10 @@ db_update(name, odp, newdp, flags, htp)
/* Add to end of list, generally preserving order */
newdp->d_next = NULL;
if ((dp = np->n_data) == NULL) {
-#ifdef DATUMREFCNT
newdp->d_rcnt = 1;
-#endif
+ if (newdp->d_flags & DB_F_ACTIVE)
+ panic(-1, "db_update: DB_F_ACTIVE set");
+ newdp->d_flags |= DB_F_ACTIVE;
np->n_data = newdp;
return (OK);
}
@@ -601,9 +629,10 @@ db_update(name, odp, newdp, flags, htp)
}
if ((flags & DB_NODATA) && !db_cmp(dp, newdp))
return (DATAEXISTS);
-#ifdef DATUMREFCNT
newdp->d_rcnt = 1;
-#endif
+ if (newdp->d_flags & DB_F_ACTIVE)
+ panic(-1, "db_update: DB_F_ACTIVE set");
+ newdp->d_flags |= DB_F_ACTIVE;
dp->d_next = newdp;
return (OK);
}
@@ -628,7 +657,7 @@ fixttl(dp)
* Must be case insensitive for some domain names.
* Return 0 if equivalent, nonzero otherwise.
*/
-static int
+int
db_cmp(dp1, dp2)
register struct databuf *dp1, *dp2;
{
@@ -639,8 +668,6 @@ db_cmp(dp1, dp2)
return (1);
if (dp1->d_size != dp2->d_size)
return (1);
- if (dp1->d_mark != dp2->d_mark)
- return (1); /* old and new RR's are distinct */
#ifdef NCACHE
if (dp1->d_rcode && dp2->d_rcode)
return ((dp1->d_rcode == dp1->d_rcode)?0:1);
@@ -650,6 +677,8 @@ db_cmp(dp1, dp2)
switch (dp1->d_type) {
+ case T_SIG:
+ case T_KEY:
case T_A:
case T_UID:
case T_GID:
@@ -705,13 +734,64 @@ db_cmp(dp1, dp2)
cp2 += strlen((char *)cp2) + 1;
return (bcmp(cp1, cp2, INT32SZ * 5));
+ case T_NAPTR: {
+ int t1,t2;
+
+ if (dp1->d_size != dp2->d_size)
+ return (1);
+ cp1 = dp1->d_data;
+ cp2 = dp2->d_data;
+
+ /* Order */
+ if (*cp1++ != *cp2++ || *cp1++ != *cp2++)
+ return (1);
+
+ /* Preference */
+ if (*cp1++ != *cp2++ || *cp1++ != *cp2++)
+ return (1);
+
+ /* Flags */
+ t1 = *cp1++; t2 = *cp2++;
+ if (t1 != t2 || bcmp(cp1, cp2, t1))
+ return (1);
+ cp1 += t1; cp2 += t2;
+
+ /* Services */
+ t1 = *cp1++; t2 = *cp2++;
+ if (t1 != t2 || bcmp(cp1, cp2, t1))
+ return (1);
+ cp1 += t1; cp2 += t2;
+
+ /* Regexp */
+ t1 = *cp1++; t2 = *cp2++;
+ if (t1 != t2 || bcmp(cp1, cp2, t1))
+ return (1);
+ cp1 += t1; cp2 += t2;
+
+ /* Replacement */
+ t1 = strlen((char *)cp1); t2 = strlen((char *)cp2);
+ if (t1 != t2 || bcmp(cp1, cp2, t1))
+ return (1);
+ cp1 += t1 + 1; cp2 += t2 + 1;
+
+ /* they all checked out! */
+ return (0);
+ }
+
case T_MX:
case T_AFSDB:
case T_RT:
+ case T_SRV:
cp1 = dp1->d_data;
cp2 = dp2->d_data;
if (*cp1++ != *cp2++ || *cp1++ != *cp2++) /* cmp prio */
return (1);
+ if (dp1->d_type == T_SRV) {
+ if (*cp1++ != *cp2++ || *cp1++ != *cp2++) /* weight */
+ return (1);
+ if (*cp1++ != *cp2++ || *cp1++ != *cp2++) /* port */
+ return (1);
+ }
return (strcasecmp((char *)cp1, (char *)cp2));
case T_PX:
OpenPOWER on IntegriCloud