windows-nim-plugin-krb5-referrals-compat-20070209
authorJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 9 Feb 2007 19:56:47 +0000 (19:56 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 9 Feb 2007 19:56:47 +0000 (19:56 +0000)
MIT Kerberos version 5 release 1.6 adds support for referrals in the
client.  As a result krb5_get_host_realm() returns the nul-string for
the realm whenever there is no local domain-realm mapping in the
profile.

aklog must now manually perform the fallback to using the domain of
the vlserver as basis for the realm name if referrals fail.

This will be required for KFW 3.2 support.

src/WINNT/netidmgr_plugin/afsfuncs.c
src/WINNT/netidmgr_plugin/afsfuncs.h

index 421fc24..7e09b4e 100644 (file)
@@ -727,8 +727,8 @@ afs_klog(khm_handle identity,
     char       RealmName[128];
     char       CellName[128];
     char       ServiceName[128];
-       khm_handle      confighandle;
-       khm_int32       supports_krb4 = 1;
+    khm_handle confighandle;
+    khm_int32  supports_krb4 = 1;
 
     /* signalling */
     BOOL        bGotCreds = FALSE; /* got creds? */
@@ -767,7 +767,7 @@ afs_klog(khm_handle identity,
     }
 
     StringCbCopyA(realm_of_cell, sizeof(realm_of_cell), 
-                  afs_realm_of_cell(&ak_cellconfig));
+                  afs_realm_of_cell(&ak_cellconfig, FALSE));
 
     if (strlen(service) == 0)
         StringCbCopyA(ServiceName, sizeof(ServiceName), "afs");
@@ -844,7 +844,24 @@ afs_klog(khm_handle identity,
         r = pkrb5_cc_set_flags(context, k5cc, flags);
 #endif
         r = pkrb5_get_credentials(context, 0, k5cc, &increds, &k5creds);
-        if (r == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
+       if ((r == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
+             r == KRB5KRB_ERR_GENERIC /* Heimdal */) &&
+            !RealmName[0]) {
+           StringCbCopyA(RealmName, sizeof(RealmName), 
+                         afs_realm_of_cell(&ak_cellconfig, TRUE));
+
+            pkrb5_free_principal(context, increds.server);
+           r = (*pkrb5_build_principal)(context, &increds.server,
+                                        (int) strlen(RealmName),
+                                        RealmName,
+                                        ServiceName,
+                                        CellName,
+                                        0);
+            if (r == 0)
+                r = pkrb5_get_credentials(context, 0, k5cc, 
+                                          &increds, &k5creds);
+       }
+       if (r == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
             r == KRB5KRB_ERR_GENERIC /* Heimdal */) {
             /* Next try Service@REALM */
             pkrb5_free_principal(context, increds.server);
@@ -1168,7 +1185,7 @@ afs_klog(khm_handle identity,
 /* afs_realm_of_cell():               */
 /**************************************/
 static char *
-afs_realm_of_cell(afs_conf_cell *cellconfig)
+afs_realm_of_cell(afs_conf_cell *cellconfig, BOOL referral_fallback)
 {
     char krbhst[MAX_HSTNM]="";
     static char krbrlm[REALM_SZ+1]="";
@@ -1179,36 +1196,45 @@ afs_realm_of_cell(afs_conf_cell *cellconfig)
     if (!cellconfig)
         return 0;
 
-    if ( pkrb5_init_context ) {
-        r = pkrb5_init_context(&ctx); 
-        if ( !r )
-            r = pkrb5_get_host_realm(ctx, cellconfig->hostName[0], &realmlist);
-        if ( !r && realmlist && realmlist[0] ) {
-            StringCbCopyA(krbrlm, sizeof(krbrlm), realmlist[0]);
-            pkrb5_free_host_realm(ctx, realmlist);
-        }
-        if (ctx)
-            pkrb5_free_context(ctx);
-    }
-
-    if ( !krbrlm[0] ) {
-        StringCbCopyA(krbrlm, sizeof(krbrlm), 
-                      (char *)(*pkrb_realmofhost)(cellconfig->hostName[0]));
-        if ((*pkrb_get_krbhst)(krbhst, krbrlm, 1) != KSUCCESS)
-            krbrlm[0] = '\0';
-    }
-
-    if ( !krbrlm[0] ) {
-        char *s = krbrlm;
-        char *t = cellconfig->name;
-        int c;
-
-        while (c = *t++)
-        {
-            if (islower(c)) c=toupper(c);
-            *s++ = c;
-        }
-        *s++ = 0;
+    if (referral_fallback) {
+       char * p;
+       p = strchr(cellconfig->hostName[0], '.');
+       if (p++)
+           StringCbCopyA(krbrlm, sizeof(krbrlm), p);
+       else
+           StringCbCopyA(krbrlm, sizeof(krbrlm), cellconfig->name);
+       strupr(krbrlm);
+    } else {
+       if ( pkrb5_init_context ) {
+           r = pkrb5_init_context(&ctx); 
+           if ( !r )
+               r = pkrb5_get_host_realm(ctx, cellconfig->hostName[0], &realmlist);
+           if ( !r && realmlist && realmlist[0] ) {
+               StringCbCopyA(krbrlm, sizeof(krbrlm), realmlist[0]);
+               pkrb5_free_host_realm(ctx, realmlist);
+           }
+           if (ctx)
+               pkrb5_free_context(ctx);
+       }
+
+       if (r) {
+           if (pkrb_get_krbhst && pkrb_realmofhost) {
+               StringCbCopyA(krbrlm, sizeof(krbrlm), 
+                              (char *)(*pkrb_realmofhost)(cellconfig->hostName[0]));
+               if ((*pkrb_get_krbhst)(krbhst, krbrlm, 1) != KSUCCESS)
+                   krbrlm[0] = '\0';
+           }
+
+           if ( !krbrlm[0] ) {
+               char * p;
+               p = strchr(cellconfig->hostName[0], '.');
+               if (p++)
+                   StringCbCopyA(krbrlm, sizeof(krbrlm), p);
+               else
+                   StringCbCopyA(krbrlm, sizeof(krbrlm), cellconfig->name);
+               strupr(krbrlm);
+           }
+       }
     }
     return(krbrlm);
 }
index 5f6ee3f..b1ba8f1 100644 (file)
@@ -73,7 +73,7 @@ ServiceControl(LPSTR lpszMachineName,
 
 void afs_report_error(LONG rc, LPCSTR FailedFunctionName);
 
-static char *afs_realm_of_cell(afs_conf_cell *);
+static char *afs_realm_of_cell(afs_conf_cell *, BOOL);
 static long afs_get_cellconfig_callback(void *, struct sockaddr_in *, char *);
 static int afs_get_cellconfig(char *, afs_conf_cell *, char *);