windows-nim-afscred-referrals-two-20080105
[openafs.git] / src / WINNT / netidmgr_plugin / afsfuncs.c
index 223fba2..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
@@ -521,7 +521,7 @@ _no_krb5:
                                      &krb4_credtype_id);
             }
 
-            if (krb4_credtype_id > 0 &&
+            if (krb4_credtype_id >= 0 &&
                 KHM_SUCCEEDED(kcdb_credset_find_filtered(NULL, -1,
                                                          afs_filter_krb4_tkt,
                                                          (void *) cell,
@@ -593,11 +593,11 @@ _no_krb5:
                            &aserver, sizeof(aserver));
 
         if(cell) {
-            kcdb_cred_set_attr(cred, afs_attr_cell, cell, KCDB_CBSIZE_AUTO);
+            kcdb_cred_set_attr(cred, afs_attr_cell, cell, (khm_size)KCDB_CBSIZE_AUTO);
         }
 
         kcdb_cred_set_attr(cred, KCDB_ATTR_LOCATION, 
-                           location, KCDB_CBSIZE_AUTO);
+                           location, (khm_size)KCDB_CBSIZE_AUTO);
 
         kcdb_credset_add_cred(afs_credset, cred, -1);
 
@@ -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 */
@@ -840,12 +858,12 @@ afs_klog(khm_handle identity,
         increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
 
 #ifdef KRB5_TC_NOTICKET
-        flags = 0;
+        flags = KRB5_TC_OPENCLOSE;
         r = pkrb5_cc_set_flags(context, k5cc, flags);
 #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,11 +905,14 @@ 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;
 #ifdef KRB5_TC_NOTICKET
-        flags = KRB5_TC_NOTICKET;
+        flags = KRB5_TC_OPENCLOSE | KRB5_TC_NOTICKET;
         pkrb5_cc_set_flags(context, k5cc, flags);
 #endif
 
@@ -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 ||
@@ -1112,7 +1135,7 @@ afs_klog(khm_handle identity,
         StringCchCopyA(aserver.cell, MAXKTCREALMLEN, CellName);
 
         memset(&atoken, '\0', sizeof(atoken));
-        atoken.kvno = creds.kvno;
+        atoken.kvno = (short)creds.kvno;
         atoken.startTime = creds.issue_date;
         atoken.endTime = (*pkrb_life_to_time)(creds.issue_date,creds.lifetime);
         memcpy(&atoken.sessionKey, creds.session, 8);
@@ -1199,7 +1222,7 @@ afs_realm_of_cell(afs_conf_cell *cellconfig, BOOL referral_fallback)
     static char krbrlm[REALM_SZ+1]="";
     krb5_context  ctx = 0;
     char ** realmlist=NULL;
-    krb5_error_code r;
+    krb5_error_code r = 0;
 
     if (!cellconfig)
         return 0;
@@ -1211,7 +1234,11 @@ afs_realm_of_cell(afs_conf_cell *cellconfig, BOOL referral_fallback)
            StringCbCopyA(krbrlm, sizeof(krbrlm), p);
        else
            StringCbCopyA(krbrlm, sizeof(krbrlm), cellconfig->name);
-       strupr(krbrlm);
+#if _MSC_VER >= 1400
+        _strupr_s(krbrlm, sizeof(krbrlm));
+#else
+        _strupr(krbrlm);
+#endif
     } else {
        if ( pkrb5_init_context ) {
            r = pkrb5_init_context(&ctx); 
@@ -1240,7 +1267,11 @@ afs_realm_of_cell(afs_conf_cell *cellconfig, BOOL referral_fallback)
                    StringCbCopyA(krbrlm, sizeof(krbrlm), p);
                else
                    StringCbCopyA(krbrlm, sizeof(krbrlm), cellconfig->name);
-               strupr(krbrlm);
+#if _MSC_VER >= 1400
+               _strupr_s(krbrlm, sizeof(krbrlm));
+#else
+                _strupr(krbrlm);
+#endif
            }
        }
     }
@@ -1493,7 +1524,7 @@ afs_check_for_cell_realm_match(khm_handle identity, char * cell) {
     kcdb_identity_get_name(identity, idname, &cb);
 
     atsign = wcschr(idname, L'@');
-    if (atsign && atsign[1] && !wcsicmp(atsign + 1, wrealm)) {
+    if (atsign && atsign[1] && !_wcsicmp(atsign + 1, wrealm)) {
         return TRUE;
     } else {
         return FALSE;