Checkpoint some working code.
authorKen Raeburn <raeburn@mit.edu>
Sat, 7 Jun 2003 00:45:41 +0000 (00:45 +0000)
committerKen Raeburn <raeburn@mit.edu>
Sat, 7 Jun 2003 00:45:41 +0000 (00:45 +0000)
A better solution is in the works, but may or may not make the deadline for
the next beta...

* RealmsConfig-glue.c: Include k5-int.h.
(dnscache): New variable.
(DNS_CACHE_TIMEOUT): New macro.
(krb_get_krbhst) [KRB5_DNS_LOOKUP]: If no krb.conf info is found, try DNS SRV
records for "kerberos-iv".  Cache results in case they're immediately requested
again.

ticket: 1550
status: open

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

src/lib/krb4/ChangeLog
src/lib/krb4/RealmsConfig-glue.c

index d779412b570a7706dd8e96e4a8424fd3ed89e5ae..78021caeec04c857a085d1a585714b8e081d36b4 100644 (file)
@@ -1,3 +1,12 @@
+2003-06-06  Ken Raeburn  <raeburn@mit.edu>
+
+       * RealmsConfig-glue.c: Include k5-int.h.
+       (dnscache): New variable.
+       (DNS_CACHE_TIMEOUT): New macro.
+       (krb_get_krbhst) [KRB5_DNS_LOOKUP]: If no krb.conf info is found,
+       try DNS SRV records for "kerberos-iv".  Cache results in case
+       they're immediately requested again.
+
 2003-06-06  Tom Yu  <tlyu@mit.edu>
 
        * g_cnffile.c (krb__get_srvtabname): Make retname be a static
index d58de963a1aa4883eee80608539fb3278bbe8de8..420f8b99baf394bc3cf242e3001c2e0eda37b468 100644 (file)
@@ -37,6 +37,7 @@
 #include "profile.h"
 #include "krb.h"
 #include "krb4int.h"
+#include "k5-int.h"            /* for accessor, addrlist stuff */
 #include "port-sockets.h"
 
 #define KRB5_PRIVATE 1
@@ -394,6 +395,15 @@ krb_get_kpasswdhst(
  * kerberos.  In the long run, this functionality will be provided by a
  * nameserver.
  */
+#ifdef KRB5_DNS_LOOKUP
+static struct {
+    time_t when;
+    char realm[REALM_SZ+1];
+    struct srv_dns_entry *srv;
+} dnscache = { 0, { 0 }, 0 };
+#define DNS_CACHE_TIMEOUT      60 /* seconds */
+#endif
+
 int KRB5_CALLCONV
 krb_get_krbhst(
     char       *host,
@@ -406,10 +416,36 @@ krb_get_krbhst(
     char       linebuf[BUFSIZ];
     char       tr[SCRATCHSZ];
     char       scratch[SCRATCHSZ];
+#ifdef KRB5_DNS_LOOKUP
+    time_t now;
+#endif
 
     if (n < 1 || host == NULL || realm == NULL)
        return KFAILURE;
 
+#ifdef KRB5_DNS_LOOKUP
+    /* We'll only have this realm's info in the DNS cache if there is
+       no data in the local config files.
+
+       XXX The files could've been updated in the last few seconds.
+       Do we care?  */
+    if (!strncmp(dnscache.realm, realm, REALM_SZ)
+       && (time(&now), abs(dnscache.when - now) < DNS_CACHE_TIMEOUT)) {
+       struct srv_dns_entry *entry;
+
+    get_from_dnscache:
+       /* n starts at 1, addrs indices run 0..naddrs */
+       for (i = 1, entry = dnscache.srv; i < n && entry; i++)
+           entry = entry->next;
+       if (entry == NULL)
+           return KFAILURE;
+       if (strlen(entry->host) + 6 >= MAXHOSTNAMELEN)
+           return KFAILURE;
+       sprintf(host, "%s:%d", entry->host, entry->port);
+       return KSUCCESS;
+    }
+#endif
+
     result = krb_prof_get_nth(host, MAXHOSTNAMELEN, realm, n,
                              REALMS_V4_PROF_REALMS_SECTION,
                              REALMS_V4_PROF_KDC);
@@ -444,12 +480,40 @@ krb_get_krbhst(
                i++;
        }
        fclose(cnffile);
-       if (result == KSUCCESS && strlen(scratch) < MAXHOSTNAMELEN)
+       if (result == KSUCCESS && strlen(scratch) < MAXHOSTNAMELEN) {
            strcpy(host, scratch);
-       else
-           result = KFAILURE;
+           return KSUCCESS;
+       }
     } while (0);
-    return result;
+#ifdef KRB5_DNS_LOOKUP
+    do {
+       krb5int_access k5;
+       krb5_error_code err;
+       krb5_data realmdat;
+       struct srv_dns_entry *srv;
+
+       err = krb5int_accessor(&k5, KRB5INT_ACCESS_VERSION);
+       if (err)
+           break;
+
+       realmdat.data = realm;
+       realmdat.length = strlen(realm);
+       err = k5.make_srv_query_realm(&realmdat, "_kerberos-iv", "_udp", &srv);
+       if (err)
+           break;
+
+       if (srv == 0)
+           break;
+
+       if (dnscache.srv)
+           k5.free_srv_dns_data(dnscache.srv);
+       dnscache.srv = srv;
+       strncpy(dnscache.realm, realm, REALM_SZ);
+       dnscache.when = now;
+       goto get_from_dnscache;
+    } while (0);
+#endif
+    return KFAILURE;
 }
 
 /*