diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/krb5/ccache/ChangeLog | 16 | ||||
| -rw-r--r-- | src/lib/krb5/ccache/cc_mslsa.c | 102 |
2 files changed, 98 insertions, 20 deletions
diff --git a/src/lib/krb5/ccache/ChangeLog b/src/lib/krb5/ccache/ChangeLog index e6cb33895..cca7ecb01 100644 --- a/src/lib/krb5/ccache/ChangeLog +++ b/src/lib/krb5/ccache/ChangeLog @@ -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: diff --git a/src/lib/krb5/ccache/cc_mslsa.c b/src/lib/krb5/ccache/cc_mslsa.c index d0b7ac34d..243a86ab1 100644 --- a/src/lib/krb5/ccache/cc_mslsa.c +++ b/src/lib/krb5/ccache/cc_mslsa.c @@ -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 ) |
