2004-01-30 Jeffrey Altman <jaltman@mit.edu>
authorJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 31 Jan 2004 01:40:58 +0000 (01:40 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 31 Jan 2004 01:40:58 +0000 (01:40 +0000)
   * cc_mslsa.c: As per extensive conversations with Doug Engert we have
     concluded that MS is not specifying a complete set of domain information
     when it comes to service tickets other than the initial TGT.  What happens
     is the client principal domain cannot be derived from the fields they
     export.  Code has now been added to obtain the domain from the initial
     TGT and use that when constructing the client principals for all tickets.

     This behavior can be turned off by setting a registry either on a per-user
     or a system-wide basis:

        {HKCU,HKLM}\Software\MIT\Kerberos5
            PreserveInitialTicketIdentity = 0x0 (DWORD)

ticket: 2139
tags: pullup

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

src/lib/krb5/ccache/ChangeLog
src/lib/krb5/ccache/cc_mslsa.c

index e6cb33895796aceb2d1cc8711a32583c5a6a0fe3..cca7ecb01338b53e1f5f1a0b81bf07ee3d8407fc 100644 (file)
@@ -1,3 +1,19 @@
+2004-01-30  Jeffrey Altman <jaltman@mit.edu>
+
+   * cc_mslsa.c: As per extensive conversations with Doug Engert we have
+     concluded that MS is not specifying a complete set of domain information
+     when it comes to service tickets other than the initial TGT.  What happens
+     is the client principal domain cannot be derived from the fields they
+     export.  Code has now been added to obtain the domain from the initial
+     TGT and use that when constructing the client principals for all tickets.
+
+     This behavior can be turned off by setting a registry either on a per-user
+     or a system-wide basis:
+
+        {HKCU,HKLM}\Software\MIT\Kerberos5
+            PreserveInitialTicketIdentity = 0x0 (DWORD)
+           
+
 2004-01-06  Jeffrey Altman <jaltman@mit.edu>
 
    * cc_file.c, cc_memory.c:
index d0b7ac34d5d2f797c7261ab70314032a37ab46a6..243a86ab19c9e0edec319b934f1821f39793880a 100644 (file)
@@ -231,25 +231,78 @@ MSTicketToMITTicket(KERB_EXTERNAL_TICKET *msticket, krb5_context context, krb5_d
     tmpdata.magic=KV5M_DATA;
     tmpdata.length=msticket->EncodedTicketSize;
     tmpdata.data=msticket->EncodedTicket;
-    // todo: fix this up a little. this is ugly and will break krb_free_data()
+
+    // TODO: fix this up a little. this is ugly and will break krb5_free_data()
     krb5_copy_data(context, &tmpdata, &newdata);
     memcpy(ticket, newdata, sizeof(krb5_data));
 }
 
+/*
+ * PreserveInitialTicketIdentity()
+ *
+ * This will find the "PreserveInitialTicketIdentity" key in the registry.  
+ * Returns 1 to preserve and 0 to not.
+ */
+
+static DWORD
+PreserveInitialTicketIdentity(void)
+{
+    HKEY hKey;
+    DWORD size = sizeof(DWORD);
+    const char *key_path = "Software\\MIT\\Kerberos5";
+    const char *value_name = "PreserveInitialTicketIdentity";
+    DWORD retval = 1;     /* default to Preserve */
+
+  userkey:
+    if (RegOpenKeyEx(HKEY_CURRENT_USER, key_path, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+        goto syskey;
+    if (RegQueryValueEx(hKey, value_name, 0, REG_DWORD, &retval, &size) != ERROR_SUCCESS)
+    {
+        RegCloseKey(hKey);
+        goto syskey;
+    }
+    RegCloseKey(hKey);
+    goto done;
+
+  syskey:
+    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key_path, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+        goto done;
+    if (RegQueryValueEx(hKey, value_name, 0, REG_DWORD, &retval, &size) != ERROR_SUCCESS)
+    {
+        RegCloseKey(hKey);
+        goto done;
+    }
+    RegCloseKey(hKey);
+
+  done:
+    return retval;
+}
+
+
 static void
-MSCredToMITCred(KERB_EXTERNAL_TICKET *msticket, krb5_context context, krb5_creds *creds)
+MSCredToMITCred(KERB_EXTERNAL_TICKET *msticket, UNICODE_STRING InitialTicketDomain, 
+                krb5_context context, krb5_creds *creds)
 {
-    WCHAR wtmp[128];
+    WCHAR wrealm[128];
     ZeroMemory(creds, sizeof(krb5_creds));
     creds->magic=KV5M_CREDS;
-    wcsncpy(wtmp, msticket->TargetDomainName.Buffer,
-            msticket->TargetDomainName.Length/sizeof(WCHAR));
-    wtmp[msticket->TargetDomainName.Length/sizeof(WCHAR)]=0;
-    MSPrincToMITPrinc(msticket->ClientName, wtmp, context, &creds->client);
-    wcsncpy(wtmp, msticket->DomainName.Buffer,
+
+    // construct Client Principal
+    if ( PreserveInitialTicketIdentity ) {
+        wcsncpy(wrealm, InitialTicketDomain.Buffer, InitialTicketDomain.Length/sizeof(WCHAR));
+        wrealm[InitialTicketDomain.Length/sizeof(WCHAR)]=0;
+    } else {
+        wcsncpy(wrealm, msticket->DomainName.Buffer, msticket->DomainName.Length/sizeof(WCHAR));
+        wrealm[msticket->DomainName.Length/sizeof(WCHAR)]=0;
+    }
+    MSPrincToMITPrinc(msticket->ClientName, wrealm, context, &creds->client);
+
+    // construct Service Principal
+    wcsncpy(wrealm, msticket->DomainName.Buffer,
             msticket->DomainName.Length/sizeof(WCHAR));
-    wtmp[msticket->DomainName.Length/sizeof(WCHAR)]=0;
-    MSPrincToMITPrinc(msticket->ServiceName, wtmp, context, &creds->server);
+    wrealm[msticket->DomainName.Length/sizeof(WCHAR)]=0;
+    MSPrincToMITPrinc(msticket->ServiceName, wrealm, context, &creds->server);
+
     MSSessionKeyToMITKeyblock(&msticket->SessionKey, context, 
                               &creds->keyblock);
     MSFlagsToMITFlags(msticket->TicketFlags, &creds->ticket_flags);
@@ -1015,8 +1068,8 @@ typedef struct _krb5_lcc_cursor {
  * id
  * 
  * Effects:
- * creates a file-based cred cache that will reside in the file
- * residual.  The cache is not opened, but the filename is reserved.
+ * Acccess the MS Kerberos LSA cache in the current logon session
+ * Ignore the residual.
  * 
  * Returns:
  * A filled in krb5_ccache structure "id".
@@ -1077,7 +1130,7 @@ krb5_lcc_resolve (krb5_context context, krb5_ccache *id, const char *residual)
     if (GetMSTGT(data->LogonHandle, data->PackageId, &msticket)) {
         /* convert the ticket */
         krb5_creds creds;
-        MSCredToMITCred(msticket, context, &creds);
+        MSCredToMITCred(msticket, msticket->DomainName, context, &creds);
         LsaFreeReturnBuffer(msticket);
 
         krb5_copy_principal(context, creds.client, &data->princ);
@@ -1205,7 +1258,7 @@ krb5_lcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor,
 {
     krb5_lcc_cursor *lcursor = (krb5_lcc_cursor *) *cursor;
     krb5_lcc_data *data = (krb5_lcc_data *)id->data;
-    KERB_EXTERNAL_TICKET *msticket;
+    KERB_EXTERNAL_TICKET *msticket, * mstgt;
 
     if ( lcursor->index >= lcursor->response->CountOfTickets )
         return KRB5_CC_END;
@@ -1215,10 +1268,15 @@ krb5_lcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor,
         return KRB5_FCC_INTERNAL;
 
     /* convert the ticket */
-    MSCredToMITCred(msticket, context, creds);
-
-    LsaFreeReturnBuffer(msticket);
-    return KRB5_OK;
+    if (GetMSTGT(data->LogonHandle, data->PackageId, &mstgt)) {
+        MSCredToMITCred(msticket, mstgt->DomainName, context, creds);
+        LsaFreeReturnBuffer(mstgt);
+        LsaFreeReturnBuffer(msticket);
+        return KRB5_OK;
+    } else {
+        LsaFreeReturnBuffer(msticket);
+        return KRB5_FCC_INTERNAL;
+    }
 }
 
 /*
@@ -1297,7 +1355,7 @@ krb5_lcc_retrieve(krb5_context context, krb5_ccache id, krb5_flags whichfields,
 {
     krb5_error_code kret = KRB5_OK;
     krb5_lcc_data *data = (krb5_lcc_data *)id->data;
-    KERB_EXTERNAL_TICKET *msticket = 0;
+    KERB_EXTERNAL_TICKET *msticket = 0, *mstgt = 0;
     krb5_creds * mcreds_noflags;
     krb5_creds   fetchcreds;
 
@@ -1337,7 +1395,9 @@ krb5_lcc_retrieve(krb5_context context, krb5_ccache id, krb5_flags whichfields,
     }
 
     /* convert the ticket */
-    MSCredToMITCred(msticket, context, &fetchcreds);
+    GetMSTGT(data->LogonHandle, data->PackageId, &mstgt);
+
+    MSCredToMITCred(msticket, mstgt ? mstgt->DomainName : msticket->DomainName, context, &fetchcreds);
 
     /* check to see if this ticket matches the request using logic from
      * krb5_cc_retrieve_cred_default()
@@ -1350,6 +1410,8 @@ krb5_lcc_retrieve(krb5_context context, krb5_ccache id, krb5_flags whichfields,
     }
 
   cleanup:
+    if ( mstgt )
+        LsaFreeReturnBuffer(mstgt);
     if ( msticket )
         LsaFreeReturnBuffer(msticket);
     if ( mcreds_noflags )