Issues with sending TSIG updates

Brian J. Murrell bind-workers-in at interlinx.bc.ca
Fri Sep 3 17:17:55 UTC 1999


I have a few questions regarding BIND 8.2.1.  Firstly, I am glad to see
TSIG support in the resolver.  I want to add signing ability to
nsupdate.  Seems pretty simple at first glance, but it gets a little
hairy.

First of all, there does not seem to be a "res_nupdatesigned()"
counterpart to "res_nupdate()".  It would seem that to send a signed
update one must resort to "res_nsendupdate()" which also requires the
caller to hunt down the primary nameserver.  Is all of this intentional?
 Should there not be a "res_nupdatesigned()" which would work just like
"res_nupdate()" with the addition of taking a key and signing the
update?  If the answer is yes, I will write one.  Actually I think I
have one I can dig out of another branch on my CVS tree.

In dealing with the above, I found "res_nfindprimary()".  This function
does not seem to work quite right.  First of all, right at the start of
the function the following happens:

res_nfindprimary(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key,
         char *zonename, int zsize, struct in_addr *addr)
{

[ variable declaration/initializations ]
    struct zonegrp *zptr = NULL, *tmpzptr, *prevzptr, *zgrp_start =
NULL;
[ more variable declaration/initializations ]

    for (rrecp = rrecp_in; rrecp; rrecp = rrecp->r_next) {
        dname = rrecp->r_dname;
        n = strlen(dname);
        if (dname[n-1] == '.')
            dname[n-1] = '\0';
        qtype = T_SOA;
        qclass = rrecp->r_class;
        done = 0;
        seen_before = 0;

        while (!done && dname) {
            if (qtype == T_SOA) {
            for (tmpzptr = zgrp_start;
                 tmpzptr && !seen_before;
                 tmpzptr = tmpzptr->z_next) {
[ rest of function not included ]

The problem is that "for (tmpzptr = zgrp_start; ...)" loop will NEVER
actually happen.  The predicate "tmpzptr && !seen_before;" will ALWAYS
be false because "tmpzptr" which is intialized with "zgrp_start" will
ALWAYS be null because "zgrp_start" is initialized with NULL and not
given another value before the loop starts.

There is another such loop right after the "} else if (qtype == T_A) {".

Additionally, "res_nfindprimary()" never does actually return with a
successful result.  That is because it iterates over every record in the
update packet and tries to look for the soa of the record.  The
"res_nsend[signed]()" fails when it tries to send the query where
"rrecp->r_dname" is not actually a domain name, which is going to happen
in nearly *every* update request.

I would simply fix "res_nfindprimary()" and report here with a patch,
but I am not even sure of the algorithm/methodology.  What is it
expecting to be included in "rrecp_in" such that it's rrecp->r_dname
will successfully find the SOA.  A "S_PREREQ" section with a "YXDOMAIN"
would provide the rrecp->r_dname needed to get an SOA, but is that the
requirement of "res_nfindprimary()"?


--
Brian J. Murrell                              InterLinx Support Services, Inc.
North Vancouver, B.C.                                             604 983 UNIX
        Platform and Brand Independent UNIX Support - R3.2 - R4 - BSD


More information about the bind-workers mailing list