? obj Index: ChangeLog =================================================================== RCS file: /cvs/krbdev/krb5/src/windows/ms2mit/ChangeLog,v retrieving revision 1.3.2.1 diff -c -w -r1.3.2.1 ChangeLog *** ChangeLog 2003/06/24 02:31:23 1.3.2.1 --- ChangeLog 2003/07/16 17:11:35 *************** *** 1,3 **** --- 1,22 ---- + 2003-07-16 Jeffrey Altman + + * ms2mit.c: + (1) do not restrict ourselves to DES-CBC-CRC instead support any + ticket with an enctype we support. as of this date (rev 1.3) + this includes all but RC4-MD4. + (2) do not accept invalid tickets + (3) when attempting to retrieve tickets do not specify either the + enctype or cache options (if possible). doing so will force a + TGS request and prevent the results from being stored into the + cache. + (4) when the cache contains a TGT which has expired Microsoft will + not perform a new TGS request until the cache has been purged. + Instead the expired ticket continues to be used along with its + embedded authorization data. When PURGE_ENABLED is defined, if the + tickets are expired, the cache will be purged before requesting + new tickets, else we ignore the contents of the cache and force + a new TGS request. + 2003-06-20 Jeffrey Altman * ms2mit.c: Windows Credentials are addressless. Do not store the Index: ms2mit.c =================================================================== RCS file: /cvs/krbdev/krb5/src/windows/ms2mit/ms2mit.c,v retrieving revision 1.2.2.1 diff -c -w -r1.2.2.1 ms2mit.c *** ms2mit.c 2003/06/24 02:31:43 1.2.2.1 --- ms2mit.c 2003/07/16 17:11:36 *************** *** 338,343 **** --- 338,352 ---- return ERROR_SUCCESS; } + // + // #define ENABLE_PURGING + // to allow the purging of expired tickets from LSA cache. This is necessary + // to force the retrieval of new TGTs. Microsoft does not appear to retrieve + // new tickets when they expire. Instead they continue to accept the expired + // tickets. I do not want to enable purging of the LSA cache without testing + // the side effects in a Windows domain with a machine which has been suspended, + // removed from the network, and resumed after ticket expiration. + // BOOL GetMSTGT( HANDLE LogonHandle, *************** *** 372,377 **** --- 381,392 ---- ULONG RequestSize; ULONG ResponseSize; USHORT TargetSize; + #ifdef ENABLE_PURGING + KERB_PURGE_TKT_CACHE_REQUEST PurgeRequest; + int purge_cache = 0; + #else + int ignore_cache = 0; + #endif /* ENABLE_PURGING */ CacheRequest.MessageType = KerbRetrieveTicketMessage; CacheRequest.LogonId.LowPart = 0; *************** *** 395,405 **** goto cleanup; } ! if (pTicketResponse->Ticket.SessionKey.KeyType == KERB_ETYPE_DES_CBC_CRC) ! { ! // all done! ! goto cleanup; } // // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we --- 410,470 ---- goto cleanup; } ! switch (pTicketResponse->Ticket.SessionKey.KeyType) { ! case KERB_ETYPE_DES_CBC_CRC: ! case KERB_ETYPE_DES_CBC_MD4: ! case KERB_ETYPE_DES_CBC_MD5: ! case KERB_ETYPE_NULL: ! case KERB_ETYPE_RC4_HMAC_NT: { ! FILETIME Now, EndTime, LocalEndTime; ! GetSystemTimeAsFileTime(&Now); ! EndTime.dwLowDateTime=pTicketResponse->Ticket.EndTime.LowPart; ! EndTime.dwHighDateTime=pTicketResponse->Ticket.EndTime.HighPart; ! FileTimeToLocalFileTime(&EndTime, &LocalEndTime); ! if (CompareFileTime(&Now, &LocalEndTime) >= 0) { ! #ifdef ENABLE_PURGING ! purge_cache = 1; ! #else ! ignore_cache = 1; ! #endif /* ENABLE_PURGING */ ! break; ! } ! if (pTicketResponse->Ticket.TicketFlags & KERB_TICKET_FLAGS_invalid) ! break; // invalid, need to attempt a TGT request ! goto cleanup; // all done ! } ! case KERB_ETYPE_RC4_MD4: ! default: ! // not supported ! break; ! } ! ! #ifdef ENABLE_PURGING ! if ( purge_cache ) { ! // ! // Purge the existing tickets which we cannot use so new ones can ! // be requested. ! // ! PurgeRequest.MessageType = KerbPurgeTicketCacheMessage; ! PurgeRequest.LogonId.LowPart = 0; ! PurgeRequest.LogonId.HighPart = 0; ! PurgeRequest.ServerName.Buffer = L""; ! PurgeRequest.ServerName.Length = 0; ! PurgeRequest.ServerName.MaximumLength = 0; ! PurgeRequest.RealmName.Buffer = L""; ! PurgeRequest.RealmName.Length = 0; ! PurgeRequest.RealmName.MaximumLength = 0; ! ! Status = LsaCallAuthenticationPackage(LogonHandle, ! PackageId, ! &PurgeRequest, ! sizeof(PurgeRequest), ! NULL, ! NULL, ! &SubStatus ! ); } + #endif /* ENABLE_PURGING */ // // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we *************** *** 462,470 **** pTicketRequest->LogonId.LowPart = 0; pTicketRequest->LogonId.HighPart = 0; // Note: pTicketRequest->TargetName set up above ! pTicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_DONT_USE_CACHE; pTicketRequest->TicketFlags = 0L; ! pTicketRequest->EncryptionType = ENCTYPE_DES_CBC_CRC; // // Free the previous response buffer so we can get the new response. --- 527,539 ---- pTicketRequest->LogonId.LowPart = 0; pTicketRequest->LogonId.HighPart = 0; // Note: pTicketRequest->TargetName set up above ! #ifdef ENABLE_PURGING ! pTicketRequest->CacheOptions = (purge_cache ? 0L : KERB_RETRIEVE_TICKET_DONT_USE_CACHE); ! #else ! pTicketRequest->CacheOptions = (ignore_cache ? KERB_RETRIEVE_TICKET_DONT_USE_CACHE : 0L); ! #endif /* ENABLE_PURGING */ pTicketRequest->TicketFlags = 0L; ! pTicketRequest->EncryptionType = 0L; // // Free the previous response buffer so we can get the new response. *************** *** 489,495 **** --- 558,609 ---- goto cleanup; } + // + // Check to make sure the new tickets we received are of a type we support + // + + switch (pTicketResponse->Ticket.SessionKey.KeyType) { + case KERB_ETYPE_DES_CBC_CRC: + case KERB_ETYPE_DES_CBC_MD4: + case KERB_ETYPE_DES_CBC_MD5: + case KERB_ETYPE_NULL: + case KERB_ETYPE_RC4_HMAC_NT: + goto cleanup; // all done + case KERB_ETYPE_RC4_MD4: + default: + // not supported + break; + } + + // + // Try once more but this time specify the Encryption Type + // + pTicketRequest->EncryptionType = ENCTYPE_DES_CBC_CRC; + + memset(pTicketResponse,0,sizeof(KERB_RETRIEVE_TKT_RESPONSE)); + LsaFreeReturnBuffer(pTicketResponse); + pTicketResponse = NULL; + + Status = LsaCallAuthenticationPackage( + LogonHandle, + PackageId, + pTicketRequest, + RequestSize, + &pTicketResponse, + &ResponseSize, + &SubStatus + ); + + if (FAILED(Status) || FAILED(SubStatus)) + { + bIsLsaError = TRUE; + goto cleanup; + } + cleanup: + if ( pTicketRequest ) + LsaFreeReturnBuffer(pTicketRequest); + if (FAILED(Status) || FAILED(SubStatus)) { if (bIsLsaError)