One proposed patch attached.
? 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 <jaltman@mit.edu>
+
+ * 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 <jaltman@mit.edu>
* 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)