Handle SRV RR target of "." by returning a new error code.
authorKen Raeburn <raeburn@mit.edu>
Wed, 4 Jun 2003 02:57:11 +0000 (02:57 +0000)
committerKen Raeburn <raeburn@mit.edu>
Wed, 4 Jun 2003 02:57:11 +0000 (02:57 +0000)
May have memory leaks -- needs checking before pullup.

* locate_kdc.c (struct srv_dns_entry): Move to top level.
(make_srv_query_realm): Separate from krb5_locate_srv_dns_1; just do query and
return results.
(krb5_locate_srv_dns_1): Call it, and build addlist entries.  Check for one RR
with a target of ".", and return an error.
(krb5_locate_srv_dns): Deleted.

ticket: 1549
status: open

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15560 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/os/ChangeLog
src/lib/krb5/os/locate_kdc.c

index f859c27cb1089e142e6cca8faf33b9a2f5c6e03d..e18b95f32d2b039f6bc62f0e71d6e659da2dc273 100644 (file)
@@ -1,5 +1,12 @@
 2003-06-03  Ken Raeburn  <raeburn@mit.edu>
 
+       * locate_kdc.c (struct srv_dns_entry): Move to top level.
+       (make_srv_query_realm): Separate from krb5_locate_srv_dns_1; just
+       do query and return results.
+       (krb5_locate_srv_dns_1): Call it, and build addlist entries.
+       Check for one RR with a target of ".", and return an error.
+       (krb5_locate_srv_dns): Deleted.
+
        * t_locate_kdc.c (main): Call krb5_locate_srv_dns_1.
 
        * changepw.c (krb5_locate_kpasswd): Check specifically for certain
index 9c9fed4d1b1a916cd81c05fb326590b5c86c78c7..6aaa98018ec34de67fbafd57334597862c65f22d 100644 (file)
@@ -508,12 +508,19 @@ krb5_locate_srv_conf(krb5_context context, const krb5_data *realm,
  * Lookup a KDC via DNS SRV records
  */
 
+struct srv_dns_entry {
+    struct srv_dns_entry *next;
+    int priority;
+    int weight;
+    unsigned short port;
+    char *host;
+};
+
 static krb5_error_code
-krb5_locate_srv_dns_1 (const krb5_data *realm,
-                      const char *service,
-                      const char *protocol,
-                      struct addrlist *addrlist,
-                      int family)
+make_srv_query_realm(const krb5_data *realm,
+                    const char *service,
+                    const char *protocol,
+                    struct srv_dns_entry **answers)
 {
     union {
         unsigned char bytes[2048];
@@ -525,13 +532,6 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
     int priority, weight, size, len, numanswers, numqueries, rdlen;
     unsigned short port;
     const int hdrsize = sizeof(HEADER);
-    struct srv_dns_entry {
-       struct srv_dns_entry *next;
-       int priority;
-       int weight;
-       unsigned short port;
-       char *host;
-    };
 
     struct srv_dns_entry *head = NULL;
     struct srv_dns_entry *srv = NULL, *entry = NULL;
@@ -548,9 +548,12 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
      *
      */
 
+    *answers = 0;
+    if (memchr(realm->data, 0, realm->length))
+       return 0;
     if ( strlen(service) + strlen(protocol) + realm->length + 6 
          > MAX_DNS_NAMELEN )
-        goto out;
+       return 0;
     sprintf(host, "%s.%s.%.*s", service, protocol, (int) realm->length,
            realm->data);
 
@@ -564,7 +567,7 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
        the local domain or domain search lists to be expanded.  */
 
     h = host + strlen (host);
-    if ((h > host) && (h[-1] != '.') && ((h - host + 1) < sizeof(host)))
+    if ((h[-1] != '.') && ((h - host + 1) < sizeof(host)))
         strcpy (h, ".");
 
 #ifdef TEST
@@ -705,6 +708,38 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
            INCR_CHECK(p, rdlen);
     }
        
+    *answers = head;
+
+  out:
+    return code;
+}
+
+static krb5_error_code
+krb5_locate_srv_dns_1 (const krb5_data *realm,
+                      const char *service,
+                      const char *protocol,
+                      struct addrlist *addrlist,
+                      int family)
+{
+    struct srv_dns_entry *head = NULL;
+    struct srv_dns_entry *entry = NULL;
+    krb5_error_code code = 0;
+
+    /*
+     * First off, build a query of the form:
+     *
+     * service.protocol.realm
+     *
+     * which will most likely be something like:
+     *
+     * _kerberos._udp.REALM
+     *
+     */
+
+    code = make_srv_query_realm(realm, service, protocol, &head);
+    if (code)
+       goto out;
+
     /*
      * Okay!  Now we've got a linked list of entries sorted by
      * priority.  Start looking up A records and returning
@@ -714,6 +749,12 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
     if (head == NULL)
        goto out;
 
+    /* Check for the "." case indicating no support.  */
+    if (head->next == 0 && head->host[0] == 0) {
+       code = KRB5_ERR_NO_SERVICE;
+       goto out;
+    }
+
 #ifdef TEST
     fprintf (stderr, "walking answer list:\n");
 #endif
@@ -732,31 +773,19 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
     fprintf (stderr, "[end]\n");
 #endif
 
+  out:
+
     for (entry = head; entry != NULL; ) {
+       struct srv_dns_entry *srv;
        free(entry->host);
         entry->host = NULL;
        srv = entry;
        entry = entry->next;
        free(srv);
-        srv = NULL;
     }
 
-  out:
-    if (srv)
-        free(srv);
-
     return code;
 }
-
-#ifdef TEST
-static krb5_error_code
-krb5_locate_srv_dns(const krb5_data *realm,
-                   const char *service, const char *protocol,
-                   struct addrlist *al)
-{
-    return krb5_locate_srv_dns_1 (realm, service, protocol, al, 0);
-}
-#endif
 #endif /* KRB5_DNS_LOOKUP */
 
 /*