windows-nim-afscred-referrals-two-20080105
[openafs.git] / src / WINNT / netidmgr_plugin / afsfuncs.c
index 8b80732..66eab2a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005,2006 Secure Endpoints Inc.
+ * Copyright (c) 2005,2006,2007, 2008 Secure Endpoints Inc.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -703,6 +703,24 @@ ViceIDToUsername(char *username,
 }
 
 
+static void
+copy_realm_of_ticket(krb5_context context, char * dest, size_t destlen, krb5_creds *v5cred) {
+    krb5_error_code code;
+    krb5_ticket *ticket;
+    size_t len;
+
+    code = pkrb5_decode_ticket(&v5cred->ticket, &ticket);
+    if (code == 0) {
+        len = krb5_princ_realm(context, ticket->server)->length;
+        if (len > destlen - 1)
+            len = destlen - 1;
+
+        StringCbCopyA(dest, len, krb5_princ_realm(context, ticket->server)->data);
+
+        pkrb5_free_ticket(context, ticket);
+    }
+}
+
 int
 afs_klog(khm_handle identity,
          char *service,
@@ -727,7 +745,7 @@ afs_klog(khm_handle identity,
     char       CellName[128];
     char       ServiceName[128];
     khm_handle confighandle = NULL;
-    khm_int32  supports_krb4 = 1;
+    khm_int32  supports_krb4 = (pkrb_get_tf_realm == NULL ? 0 : 1);
     khm_int32   got524cred = 0;
 
     /* signalling */
@@ -845,7 +863,7 @@ afs_klog(khm_handle identity,
 #endif
       retry_retcred:
         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), 
@@ -887,6 +905,9 @@ afs_klog(khm_handle identity,
            goto retry_retcred;
        }
 
+        if (r == 0 && strlen(RealmName) == 0) 
+            copy_realm_of_ticket(context, realm_of_cell, sizeof(realm_of_cell), k5creds);
+
         pkrb5_free_principal(context, increds.server);
         pkrb5_free_principal(context, client_principal);
         client_principal = 0;
@@ -900,6 +921,7 @@ afs_klog(khm_handle identity,
 
         if (r) {
             _reportf(L"Code %d while getting credentials", r);
+            k5creds = NULL;
             goto end_krb5;
         }
 
@@ -1008,8 +1030,8 @@ afs_klog(khm_handle identity,
 
         _reportf(L"Trying Krb524");
 
-        if (method == AFS_TOKEN_AUTO ||
-            method == AFS_TOKEN_KRB524) {
+        if (pkrb524_convert_creds_kdc && 
+            (method == AFS_TOKEN_AUTO || method == AFS_TOKEN_KRB524)) {
             /* This requires krb524d to be running with the KDC */
             r = pkrb524_convert_creds_kdc(context, k5creds, &creds);
             if (r) {
@@ -1035,13 +1057,14 @@ afs_klog(khm_handle identity,
     /* Kerberos 4 */
  try_krb4:
 
-    kcdb_identity_get_config(identity, 0, &confighandle);
-    khc_read_int32(confighandle, L"Krb4Cred\\Krb4NewCreds", &supports_krb4);
-    khc_close_space(confighandle);
+    if (supports_krb4) {
+       kcdb_identity_get_config(identity, 0, &confighandle);
+       khc_read_int32(confighandle, L"Krb4Cred\\Krb4NewCreds", &supports_krb4);
+       khc_close_space(confighandle); 
+    }
 
-    if (!supports_krb4) {
+    if (!supports_krb4)
         _reportf(L"Kerberos 4 not configured");
-    }
 
     if (!bGotCreds && supports_krb4 && 
         (method == AFS_TOKEN_AUTO ||