In testing it has been observed that remote desktop connections
authorJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 17 Apr 2007 18:06:15 +0000 (18:06 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 17 Apr 2007 18:06:15 +0000 (18:06 +0000)
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
src/windows/kfwlogon/kfwlogon.c
src/windows/kfwlogon/kfwlogon.h

index 23295b93bdb0bb71f2494f053fcaf04080829eb1..ea9410ea6168391c22c289cf92ed75f2347a027f 100644 (file)
@@ -38,6 +38,10 @@ SOFTWARE.
 #include <lm.h>\r
 #include <nb30.h>\r
 \r
+#include <errno.h>\r
+#include <malloc.h>\r
+\r
+\r
 /* Function Pointer Declarations for Delayed Loading */\r
 // CCAPI\r
 DECL_FUNC_PTR(cc_initialize);\r
@@ -908,7 +912,6 @@ int KFW_set_ccache_dacl_with_user_sid(char *filename, PSID pUserSID)
     DWORD SystemSIDlength = 0, UserSIDlength = 0;\r
     PACL ccacheACL = NULL;\r
     DWORD ccacheACLlength = 0;\r
-    DWORD retLen;\r
     DWORD gle;\r
     int ret = 0;  \r
 \r
@@ -1021,7 +1024,6 @@ int KFW_obtain_user_temp_directory(HANDLE hUserToken, char *newfilename, int siz
 void\r
 KFW_copy_cache_to_system_file(const char * user, const char * filename)\r
 {\r
-    DWORD count;\r
     char cachename[MAX_PATH + 8] = "FILE:";\r
     krb5_context               ctx = 0;\r
     krb5_error_code            code;\r
@@ -1279,3 +1281,72 @@ KFW_destroy_tickets_for_principal(char * user)
     return 0;\r
 }\r
 \r
+\r
+/* There are scenarios in which an interactive logon will not\r
+ * result in the LogonScript being executed.  This will result\r
+ * in orphaned cache files being left in the Temp directory.\r
+ * This function will search for cache files in the Temp \r
+ * directory and delete any that are older than five minutes.\r
+ */\r
+void\r
+KFW_cleanup_orphaned_caches(void)\r
+{\r
+    char * temppath = NULL;\r
+    char * curdir = NULL;\r
+    DWORD count, count2;\r
+    WIN32_FIND_DATA FindFileData;\r
+    HANDLE hFind = INVALID_HANDLE_VALUE;\r
+    FILETIME now;\r
+    ULARGE_INTEGER uli_now;\r
+    FILETIME expired;\r
+\r
+    count = GetTempPath(0, NULL);\r
+    if (count <= 0)\r
+        return;\r
+    temppath = (char *) malloc(count);\r
+    if (!temppath)\r
+        goto cleanup;\r
+    count2 = GetTempPath(count, temppath);\r
+    if (count2 <= 0 || count2 > count)\r
+        goto cleanup;\r
+\r
+    count = GetCurrentDirectory(0, NULL);\r
+    curdir = (char *)malloc(count);\r
+    if (!curdir)\r
+        goto cleanup;\r
+    count2 = GetCurrentDirectory(count, curdir);\r
+    if (count2 <= 0 || count2 > count)\r
+        goto cleanup;\r
+\r
+    if (!SetCurrentDirectory(temppath))\r
+        goto cleanup;\r
+\r
+    GetSystemTimeAsFileTime(&now);\r
+    uli_now.u.LowPart = now.dwLowDateTime;\r
+    uli_now.u.HighPart = now.dwHighDateTime;\r
+\r
+    uli_now.QuadPart -= 3000000000;        /* 5 minutes == 3 billion 100 nano seconds */\r
+\r
+    expired.dwLowDateTime = uli_now.u.LowPart;\r
+    expired.dwHighDateTime = uli_now.u.HighPart;\r
+\r
+    hFind = FindFirstFile("kfwlogon-*", &FindFileData);\r
+    if (hFind != INVALID_HANDLE_VALUE) {\r
+        do {\r
+            if (CompareFileTime(&FindFileData.ftCreationTime, &expired) < 0) {\r
+                DebugEvent("Deleting orphaned cache file: \"%s\"", FindFileData.cFileName);\r
+                DeleteFile(FindFileData.cFileName);\r
+            }\r
+        } while ( FindNextFile(hFind, &FindFileData) );\r
+    }\r
+\r
+    SetCurrentDirectory(curdir);\r
+\r
+  cleanup:\r
+    if (temppath)\r
+        free(temppath);\r
+    if (hFind != INVALID_HANDLE_VALUE)\r
+        FindClose(hFind);\r
+    if (curdir)\r
+        free(curdir);\r
+}\r
index b05e38fd8c5923ca4b9484a28aaf072c59a61878..f76da3cab3eed6f7b67c804167c63bcc2204143f 100644 (file)
@@ -207,6 +207,19 @@ DWORD APIENTRY NPLogonNotify(
     if ( !KFW_is_available() )\r
         return 0;\r
 \r
+    DebugEvent0("NPLogonNotify start");\r
+\r
+    /* Remote Desktop / Terminal Server connections to existing sessions \r
+     * are interactive logons.  Unfortunately, because the session already\r
+     * exists the logon script does not get executed and this prevents \r
+     * us from being able to execute the rundll32 entrypoint \r
+     * LogonEventHandlerA which would process the credential cache this\r
+     * routine will produce.  Therefore, we must cleanup orphaned cache\r
+     * files from this routine.  We will take care of it before doing\r
+     * anything else.\r
+     */\r
+    KFW_cleanup_orphaned_caches();\r
+\r
     /* Are we interactive? */\r
     if (lpStationName)\r
         interactive = (wcsicmp(lpStationName, L"WinSta0") == 0);\r
@@ -282,12 +295,13 @@ DWORD APIENTRY NPLogonNotify(
            goto cleanup;\r
        }\r
 \r
-       count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));\r
-       if ( count > sizeof(filename) || count == 0 ) {\r
-           GetWindowsDirectory(filename, sizeof(filename));\r
-       }\r
+       count = GetTempPath(sizeof(filename), filename);\r
+        if (count == 0 || count > (sizeof(filename)-1)) {\r
+            code = -1;\r
+            goto cleanup;\r
+        }\r
 \r
-       if (_snprintf(filename, sizeof(filename), "%s\\kfwlogon-%d.%d",\r
+       if (_snprintf(filename, sizeof(filename), "%s\\kfwlogon-%x.%x",\r
                       filename, lpLogonId->HighPart, lpLogonId->LowPart) < 0) \r
        {\r
            code = -1;\r
index 0d7ddd91fcdc2be39505f394b30d2c4ec65cb90d..cfbe4fd3815edd958615256e432850bd91334b06 100644 (file)
@@ -206,6 +206,7 @@ int KFW_destroy_tickets_for_principal(char * user);
 int KFW_set_ccache_dacl(char *filename, HANDLE hUserToken);\r
 int KFW_set_ccache_dacl_with_user_sid(char *filename, PSID pUserSID);\r
 int KFW_obtain_user_temp_directory(HANDLE hUserToken, char *newfilename, int size);\r
+void KFW_cleanup_orphaned_caches(void);\r
 \r
 void CALLBACK LogonEventHandlerA(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);\r
 \r