]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Incorporate a bunch of changes from Brian Murrell.
authorTed Lemon <source@isc.org>
Mon, 4 Oct 1999 23:15:43 +0000 (23:15 +0000)
committerTed Lemon <source@isc.org>
Mon, 4 Oct 1999 23:15:43 +0000 (23:15 +0000)
common/nsupdate.c
common/tree.c

index f6b214706904511387800404ae039cba42262297..3945f8596f1bbfd4a74a4154b9a8a1c1f6e42cb4 100644 (file)
@@ -25,7 +25,7 @@
 
 #ifndef lint
 static char copyright[] =
-"$Id: nsupdate.c,v 1.8 1999/09/16 01:14:52 mellon Exp $ Copyright (c) 1999 The Internet Software Consortium.  All rights reserved.\n";
+"$Id: nsupdate.c,v 1.9 1999/10/04 23:14:58 mellon Exp $ Copyright (c) 1999 The Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -36,7 +36,14 @@ static char copyright[] =
    done.  This can be done by figuring out the hostname.domain and revname
    and then comparing them to the lease->ddns* values.  Only make the changes
    necessary which can be any combination and number of remove A, add A,
-   remove PTR, add PTR */
+   remove PTR, add PTR.
+
+   Wed Sep 29 02:06:33 PDT 1999
+   SCRAP THAT!  Let the DNS server determine whether an add/delete should
+   be done by giving it pre-requisites to the add/delete.
+ */
+
+#define NAME(x)        (x) ? (char *)(x) : "(null)"
 
 #if 0
 /* Return the reverse name of a lease. */
@@ -183,90 +190,153 @@ char *ddns_fwd_name(lease, state, packet)
 #endif
        return hostname;
 }
-#endif
+#endif /* 0 */
 
-static int nsupdateA(hostname, ip_addr, ttl, opcode)
-       char *hostname;
-       unsigned char *ip_addr;
+int nsupdateA (hostname, ip_addr, ttl, opcode)
+       const char *hostname;
+       const unsigned char *ip_addr;
        u_int32_t ttl;
-       int     opcode;
+       int opcode;
 {
-       int     z;
-       ns_updrec       *u, *n;
+       int z;
+       ns_updrec *p, *u;
+
+       /* set up update section */
+       if (!(u = res_mkupdrec (S_UPDATE, hostname, C_IN, T_A, ttl)))
+               return 0;
+       u -> r_opcode = opcode;
+       u -> r_data = (char *)ip_addr;
+
+#if 0 /* no PREREQUISITES are needed for adds and deletes, as there is no zone
+        churn when you add a record that exists or delete a record that
+        doesn't exist */
+
+       /* set up the prerequisite section */
+       if (!(p = res_mkupdrec (S_PREREQ, hostname, C_IN, T_A, 0))) {
+               res_freeupdrec (u);
+               return 0;
+       }
+       p -> r_next = u;
+       p -> r_data = (char *)ip_addr;
+#endif
 
        switch (opcode) {
-       case ADD:
-               if (!(u = res_mkupdrec(S_PREREQ, hostname, C_IN, T_A, 0))) 
-                       return 0;
-               u->r_opcode = NXRRSET; u->r_data = NULL; u->r_size = 0;
-               if (!(n = res_mkupdrec(S_UPDATE, hostname, C_IN, T_A, ttl))) {
-                       res_freeupdrec(u);
+             case ADD:
+               if (!ip_addr) {         /* can't have NULL ip_addr for an ADD */
+#if 0
+                       res_freeupdrec (p);
+#endif
+                       res_freeupdrec (u);
                        return 0;
                }
-               n->r_opcode = opcode;
-               n->r_data = ip_addr;
-               n->r_size = strlen((const char *)n->r_data);
-               u->r_next = n;
-               z = res_update(u);
-               log_info("add %s: %s %d IN A %s",
-                        z == 1 ? "succeeded" : "failed", hostname, ttl,
-                        n->r_data);
-               res_freeupdrec(u); 
-               res_freeupdrec(n);
-/* do we really need to do this?  If so, it needs to be done elsewehere as
-   this function is strictly for manipulating the A record
-               if (z < 1) 
-                       return 0;
-*/
-               /* delete all PTR RRs with the same ip address. Wow! */
-/*
-               if (!(u = res_mkupdrec(S_UPDATE, revname, C_IN, T_PTR, 0)))
-                       return 0;
-               u->r_opcode = DELETE; u->r_data = NULL; u->r_size = 0;
-               log_info("cleaning all PTR RRs for %s", revname);
-               res_update(u);
-               res_freeupdrec(u);
-*/
+#if 0
+               /* PREQUISITE: add only if the RR is not there already */
+               p -> r_opcode = NXRRSET;
+               p -> r_size = strlen ((const char *)p -> r_data);
+#endif
+               u -> r_size = strlen ((const char *)u -> r_data);
                break;
-       case    DELETE:
-               ttl = 0;
-               if (!(u = res_mkupdrec(S_UPDATE, hostname, C_IN, T_A, ttl)))
-                       return 0;
-               u->r_opcode = opcode;
-               u->r_data = ip_addr;
-               u->r_size = strlen((const char *)u->r_data);
-               z = res_update(u);
-               log_info("delete %s: %s %d IN A %s",
-                        z == 1 ? "succeeded" : "failed",
-                        hostname, ttl, u->r_data);
-               res_freeupdrec(u);
+             case DELETE:
+               ttl = 0;        /* delete updates ALWAYS have a 0 TTL */
+#if 0
+               /* PREQUISITE: delete only if the RR to be deleted is there */
+               p -> r_opcode = YXRRSET;
+#endif
+               /* NOTE: ip_addr could be NULL for a "DELETE all records" */
+               if (u -> r_data) {
+#if 0
+                       p -> r_size = strlen ((const char *)n -> r_data);
+#endif
+                       u -> r_size = strlen ((const char *)u -> r_data);
+               } else {
+#if 0
+                       p -> r_size = 0;
+#endif
+                       u -> r_size = 0;
+               }
                break;
        }
+       z = res_update (u);
+       log_info ("%s %s: %s %d IN A %s", opcode == ADD ? "add" : "delete",
+                 z == 1 ? "succeeded" : "failed", NAME (hostname), ttl,
+                 NAME (u -> r_data));
+#if 0
+       res_freeupdrec (p);
+#endif
+       res_freeupdrec (u);
        return z;
 }
 
-static int nsupdatePTR(revname, hostname, ttl, opcode)
-       unsigned char *hostname;
-       char *revname;
+int nsupdatePTR (revname, hostname, ttl, opcode)
+       const char *revname;
+       const unsigned char *hostname;
        u_int32_t ttl;
-       int     opcode;
+       int opcode;
 {
-       int     z;
-       ns_updrec       *u;
+       int z;
+       ns_updrec *u, *p;
 
-       if (opcode == DELETE)
-               ttl = 0;
-       if (!(u = res_mkupdrec(S_UPDATE, revname, C_IN, T_PTR, ttl)))
+       /* set up update section */
+       if (!(u = res_mkupdrec (S_UPDATE, revname, C_IN, T_PTR, ttl)))
+               return 0;
+       u -> r_opcode = opcode;
+       u -> r_data = (char *)hostname;
+
+#if 0 /* don't need PREREQUISITES */
+       /* set up the prerequisite section */
+       if (!(p = res_mkupdrec (S_PREREQ, revname, C_IN, T_PTR, 0))) {
+               res_freeupdrec (u);
                return 0;
-       u->r_opcode = opcode;
-       u->r_data = hostname;
-       u->r_size = strlen((const char *)u->r_data);
+       }
+       p -> r_next = u;
+       p -> r_data = (char *)hostname;
+#endif
+       
+       switch (opcode) {
+             case ADD:
+               if (!hostname) {        /* can't have NULL ip_addr for an ADD */
+#if 0
+                       res_freeupdrec (p);
+#endif
+                       res_freeupdrec (u);
+                       return 0;
+               }
+#if 0
+               /* PREQUISITE: add only if the RR is not there already */
+               p -> r_opcode = NXRRSET;
+               p -> r_size = strlen ((const char *)p -> r_data);
+#endif
+               u -> r_size = strlen ((const char *)u -> r_data);
+               
+               break;
+             case DELETE:
+               ttl = 0;        /* delete updates ALWAYS have a 0 TTL */        
+#if 0
+               /* PREQUISITE: delete only if the RR to be deleted is there */
+               p->r_opcode = YXRRSET;
+               /* NOTE: hostname could be NULL for a "DELETE all records" */
+#endif
+               if (u -> r_data) {
+#if 0
+                       p -> r_size = strlen ((const char *)p -> r_data);
+#endif
+                       u -> r_size = strlen ((const char *)u -> r_data);
+               } else {
+#if 0
+                       p -> r_size = 0;
+#endif
+                       u -> r_size = 0;
+               }
+               break;
+       }
        z = res_update(u);
-       log_info("%s %s: %s %d IN PTR %s", 
-                opcode == ADD ? "add" : 
-                                "delete", z == 1 ? "succeeded" : "failed",
-                revname, ttl, hostname);
-       res_freeupdrec(u);
+       log_info ("%s %s: %s %d IN PTR %s", opcode == ADD ? "add" : 
+                 "delete", z == 1 ? "succeeded" : "failed",
+                 NAME (revname), ttl, NAME (u -> r_data));
+#if 0
+       res_freeupdrec (p);
+#endif
+       res_freeupdrec (u);
        return z;
 }
 
@@ -417,93 +487,99 @@ return;
 }
 #endif
 
-/* public function to update an A record if needed */
-int updateA(struct data_string *lhs, struct data_string *rhs, unsigned int ttl,
-       struct lease *lease)
+/* public function to update an A record */
+int updateA (lhs, rhs, ttl, lease)
+       const struct data_string *lhs;
+       const struct data_string *rhs;
+       unsigned int ttl;
+       struct lease *lease;
 {
 
        static char hostname[MAXDNAME];
        static char ipaddr[MAXDNAME];
+       int y;
 
        hostname[0] = '\0';
-       strncat(hostname, (const char *)lhs->data, lhs->len);
-       hostname[lhs->len] = '\0';
+       strncat(hostname, (const char *)lhs -> data, lhs -> len);
+       hostname[lhs -> len] = '\0';
        
        ipaddr[0] = '\0';
-       strncat(ipaddr, (const char *)rhs->data, rhs->len);
-       ipaddr[rhs->len] = '\0';
-       
-       /* delete an existing A if the one to be added is different */
-       if (lease -> ddns_fwd_name &&
-           strcmp(hostname, lease -> ddns_fwd_name)) {
-               int y;
-               y=nsupdateA(lease -> ddns_fwd_name, ipaddr, 0, DELETE);
-
-               if (y) {
-                       /* clear the forward DNS name pointer */
-                       if (lease -> ddns_fwd_name)
-                               dfree(lease -> ddns_fwd_name, "nsupdate");
-                       lease -> ddns_fwd_name = 0;
-               }
-       }
-       /* only update if there is no A record there already */
-       if (!lease -> ddns_fwd_name) {
-               int y;
-               y=nsupdateA(hostname, ipaddr, ttl, ADD);
-               if (y < 1)
-                       return 0;
+       strncat(ipaddr, (const char *)rhs -> data, rhs -> len);
+       ipaddr[rhs -> len] = '\0';
+
+#if 0  /* Wrong!  This causes zone churn on every DHCPREQUEST!
+          Besides, it is perfectly legal for a DHCP client to have more
+          than one lease, if (say) it was being served by two+ DHCP servers
+          serving the same subnet with different (i.e. disjoint) pools.
+          The right thing to do is have the A records cleaned by either a
+          DHCPRELEASE or the lease expiry.  */
+    
+       /* delete all existing A records for this host */
+       nsupdateA (hostname, NULL, 0, DELETE);
+#endif
 
-               /* remember this in the lease structure for release */
-               lease -> ddns_fwd_name = dmalloc(strlen(hostname) + 1,
-                                                "nsupdate");
-               strcpy (lease -> ddns_fwd_name, hostname);
-       }
+       /* clear the forward DNS name pointer */
+       if (lease -> ddns_fwd_name)
+               dfree (lease -> ddns_fwd_name, "nsupdate");
+       lease -> ddns_fwd_name = 0;
+
+       y=nsupdateA (hostname, ipaddr, ttl, ADD);
+       if (y < 1)
+               return 0;
+
+       /* remember this in the lease structure for release */
+       lease -> ddns_fwd_name = dmalloc (strlen(hostname) + 1, "nsupdate");
+       strcpy (lease -> ddns_fwd_name, hostname);
 
        return 1;
 }
 
-/* public function to update an A record if needed */
-int updatePTR(struct data_string *lhs, struct data_string *rhs,
-             unsigned int ttl, struct lease *lease)
+/* public function to update an PTR record */
+int updatePTR (lhs, rhs, ttl, lease)
+       const struct data_string *lhs;
+       const struct data_string *rhs;
+       unsigned int ttl;
+       struct lease *lease;
 {
 
        static char hostname[MAXDNAME];
        static char revname[MAXDNAME];
+       int y;
 
        revname[0] = '\0';
-       strncat(revname, (const char *)lhs->data, lhs->len);
-       revname[lhs->len] = '\0';
+       strncat(revname, (const char *)lhs -> data, lhs -> len);
+       revname[lhs -> len] = '\0';
 
        hostname[0] = '\0';
-       strncat(hostname, (const char *)rhs->data, rhs->len);
-       hostname[rhs->len] = '\0';
-       
-       /* delete an existing PTR if the one to be added is different */
-       if (lease -> ddns_rev_name &&
-           strcmp(revname, lease -> ddns_rev_name)) {
-               int y;
-               y=nsupdatePTR(revname, hostname, 0, DELETE);
-
-               if (y) {
-                       /* clear the reverse DNS name pointer */
-                       if (lease -> ddns_rev_name)
-                               dfree(lease -> ddns_rev_name, "nsupdate");
-                       lease -> ddns_rev_name = 0;
-               }
-       }
-       /* only update if there is no PTR record there already */
-       if (!lease -> ddns_rev_name) {
-               int y;
-               y=nsupdatePTR(revname, hostname, ttl, ADD);
-               if (y < 1)
-                       return 0;
+       strncat(hostname, (const char *)rhs -> data, rhs -> len);
+       hostname[rhs -> len] = '\0';
+
+#if 0  /* Wrong!  This causes zone churn on every DHCPREQUEST!
+          Besides, it is perfectly legal for a DHCP client to have more
+          than one lease, if (say) it was being served by two+ DHCP servers
+          serving the same subnet with different (i.e. disjoint) pools.
+          The right thing to do is have the PTR records cleaned by either a
+          DHCPRELEASE or the lease expiry.  */
+       
+       /* delete all existing PTR records */
+       nsupdatePTR (revname, NULL, 0, DELETE);
+#endif
 
-               /* remember this in the lease structure for release */
-               lease -> ddns_rev_name = dmalloc(strlen(revname) + 1,
-                                                "nsupdate");
-               strcpy (lease -> ddns_rev_name, revname);
-       }
+       /* clear the reverse DNS name pointer */
+       if (lease -> ddns_rev_name)
+               dfree (lease -> ddns_rev_name, "nsupdate");
+       lease -> ddns_rev_name = 0;
+
+       y=nsupdatePTR (revname, hostname, ttl, ADD);
+       if (y < 1)
+               return 0;
+
+       /* remember this in the lease structure for release */
+       lease -> ddns_rev_name = dmalloc (strlen(revname) + 1, "nsupdate");
+       strcpy (lease -> ddns_rev_name, revname);
 
        return 1;
 }
 #endif /* defined (NSUPDATE) */
+
+/* vim: set tabstop=8: */
index 55bc6b464858de7da926ffb33d3443c6526b1f61..0e6dbbd9ce3f5c020739790bd18ac8bd8e681570 100644 (file)
@@ -22,7 +22,7 @@
 
 #ifndef lint
 static char copyright[] =
-"$Id: tree.c,v 1.51 1999/09/24 19:04:30 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.  All rights reserved.\n";
+"$Id: tree.c,v 1.52 1999/10/04 23:15:43 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -575,15 +575,16 @@ int evaluate_boolean_expression (result, packet, lease, in_options,
                                log_debug("calling updateA(%s, %s, %d, lease)",
                                          expr1.data , expr2.data, ttl);
 #endif
-                               updateA(expr1, expr2, ttl, lease);
+                               updateA(&expr1, &expr2, ttl, lease);
                        } else if (rrtype.len == 3 &&
-                                  strncmp((const char *)rrtype.data, "ptr", 3) == 0) {
+                                  strncmp((const char *)rrtype.data,
+                                           "ptr", 3) == 0) {
 #if defined (DEBUG_EXPRESSIONS)
                                log_debug ("%s updatePTR(%s, %s, %d, lease)",
                                           "calling", expr1.data,
                                           expr2.data, ttl);
 #endif
-                               updatePTR(expr1, expr2, ttl, lease);
+                               updatePTR(&expr1, &expr2, ttl, lease);
                        }
                        *result = 1;
                } else {
@@ -2182,3 +2183,4 @@ int write_expression (file, expr, col, indent)
        }
        return col;
 }
+/* vim: set tabstop=8: */