From 6e0fcb6312775f242a98da89dfb6db05d1381eb4 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 17 Apr 2007 18:06:15 +0000 Subject: In testing it has been observed that remote desktop connections will execute the NPLogonNotify function but if the logon is re-connecting to an existing session, the LogonScript is ignored. This leaves orphaned credential cache files. This commit adds a function, KFW_cleanup_orphaned_caches, which is called by NPLogonNotify to delete any orphaned cache files. An orphaned cache file is one that is older than five minutes. ticket: 5532 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19477 dc483132-0cff-0310-8789-dd5450dbe970 --- src/windows/kfwlogon/kfwcommon.c | 75 ++++++++++++++++++++++++++++++++++++++-- src/windows/kfwlogon/kfwlogon.c | 24 ++++++++++--- src/windows/kfwlogon/kfwlogon.h | 1 + 3 files changed, 93 insertions(+), 7 deletions(-) (limited to 'src/windows') diff --git a/src/windows/kfwlogon/kfwcommon.c b/src/windows/kfwlogon/kfwcommon.c index 23295b93bd..ea9410ea61 100644 --- a/src/windows/kfwlogon/kfwcommon.c +++ b/src/windows/kfwlogon/kfwcommon.c @@ -38,6 +38,10 @@ SOFTWARE. #include #include +#include +#include + + /* Function Pointer Declarations for Delayed Loading */ // CCAPI DECL_FUNC_PTR(cc_initialize); @@ -908,7 +912,6 @@ int KFW_set_ccache_dacl_with_user_sid(char *filename, PSID pUserSID) DWORD SystemSIDlength = 0, UserSIDlength = 0; PACL ccacheACL = NULL; DWORD ccacheACLlength = 0; - DWORD retLen; DWORD gle; int ret = 0; @@ -1021,7 +1024,6 @@ int KFW_obtain_user_temp_directory(HANDLE hUserToken, char *newfilename, int siz void KFW_copy_cache_to_system_file(const char * user, const char * filename) { - DWORD count; char cachename[MAX_PATH + 8] = "FILE:"; krb5_context ctx = 0; krb5_error_code code; @@ -1279,3 +1281,72 @@ KFW_destroy_tickets_for_principal(char * user) return 0; } + +/* There are scenarios in which an interactive logon will not + * result in the LogonScript being executed. This will result + * in orphaned cache files being left in the Temp directory. + * This function will search for cache files in the Temp + * directory and delete any that are older than five minutes. + */ +void +KFW_cleanup_orphaned_caches(void) +{ + char * temppath = NULL; + char * curdir = NULL; + DWORD count, count2; + WIN32_FIND_DATA FindFileData; + HANDLE hFind = INVALID_HANDLE_VALUE; + FILETIME now; + ULARGE_INTEGER uli_now; + FILETIME expired; + + count = GetTempPath(0, NULL); + if (count <= 0) + return; + temppath = (char *) malloc(count); + if (!temppath) + goto cleanup; + count2 = GetTempPath(count, temppath); + if (count2 <= 0 || count2 > count) + goto cleanup; + + count = GetCurrentDirectory(0, NULL); + curdir = (char *)malloc(count); + if (!curdir) + goto cleanup; + count2 = GetCurrentDirectory(count, curdir); + if (count2 <= 0 || count2 > count) + goto cleanup; + + if (!SetCurrentDirectory(temppath)) + goto cleanup; + + GetSystemTimeAsFileTime(&now); + uli_now.u.LowPart = now.dwLowDateTime; + uli_now.u.HighPart = now.dwHighDateTime; + + uli_now.QuadPart -= 3000000000; /* 5 minutes == 3 billion 100 nano seconds */ + + expired.dwLowDateTime = uli_now.u.LowPart; + expired.dwHighDateTime = uli_now.u.HighPart; + + hFind = FindFirstFile("kfwlogon-*", &FindFileData); + if (hFind != INVALID_HANDLE_VALUE) { + do { + if (CompareFileTime(&FindFileData.ftCreationTime, &expired) < 0) { + DebugEvent("Deleting orphaned cache file: \"%s\"", FindFileData.cFileName); + DeleteFile(FindFileData.cFileName); + } + } while ( FindNextFile(hFind, &FindFileData) ); + } + + SetCurrentDirectory(curdir); + + cleanup: + if (temppath) + free(temppath); + if (hFind != INVALID_HANDLE_VALUE) + FindClose(hFind); + if (curdir) + free(curdir); +} diff --git a/src/windows/kfwlogon/kfwlogon.c b/src/windows/kfwlogon/kfwlogon.c index b05e38fd8c..f76da3cab3 100644 --- a/src/windows/kfwlogon/kfwlogon.c +++ b/src/windows/kfwlogon/kfwlogon.c @@ -207,6 +207,19 @@ DWORD APIENTRY NPLogonNotify( if ( !KFW_is_available() ) return 0; + DebugEvent0("NPLogonNotify start"); + + /* Remote Desktop / Terminal Server connections to existing sessions + * are interactive logons. Unfortunately, because the session already + * exists the logon script does not get executed and this prevents + * us from being able to execute the rundll32 entrypoint + * LogonEventHandlerA which would process the credential cache this + * routine will produce. Therefore, we must cleanup orphaned cache + * files from this routine. We will take care of it before doing + * anything else. + */ + KFW_cleanup_orphaned_caches(); + /* Are we interactive? */ if (lpStationName) interactive = (wcsicmp(lpStationName, L"WinSta0") == 0); @@ -282,12 +295,13 @@ DWORD APIENTRY NPLogonNotify( goto cleanup; } - count = GetEnvironmentVariable("TEMP", filename, sizeof(filename)); - if ( count > sizeof(filename) || count == 0 ) { - GetWindowsDirectory(filename, sizeof(filename)); - } + count = GetTempPath(sizeof(filename), filename); + if (count == 0 || count > (sizeof(filename)-1)) { + code = -1; + goto cleanup; + } - if (_snprintf(filename, sizeof(filename), "%s\\kfwlogon-%d.%d", + if (_snprintf(filename, sizeof(filename), "%s\\kfwlogon-%x.%x", filename, lpLogonId->HighPart, lpLogonId->LowPart) < 0) { code = -1; diff --git a/src/windows/kfwlogon/kfwlogon.h b/src/windows/kfwlogon/kfwlogon.h index 0d7ddd91fc..cfbe4fd381 100644 --- a/src/windows/kfwlogon/kfwlogon.h +++ b/src/windows/kfwlogon/kfwlogon.h @@ -206,6 +206,7 @@ int KFW_destroy_tickets_for_principal(char * user); int KFW_set_ccache_dacl(char *filename, HANDLE hUserToken); int KFW_set_ccache_dacl_with_user_sid(char *filename, PSID pUserSID); int KFW_obtain_user_temp_directory(HANDLE hUserToken, char *newfilename, int size); +void KFW_cleanup_orphaned_caches(void); void CALLBACK LogonEventHandlerA(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow); -- cgit