/*\r
Copyright 2005,2006 by the Massachusetts Institute of Technology\r
+Copyright 2007 by Secure Endpoints Inc.\r
\r
All rights reserved.\r
\r
return 1;\r
}\r
\r
+ DebugEvent0("KFW_set_ccache_dacl");\r
+\r
/* Get System SID */\r
if (!ConvertStringSidToSid("S-1-5-18", &pSystemSID)) {\r
DebugEvent("KFW_set_ccache_dacl - ConvertStringSidToSid GLE = 0x%x", GetLastError());\r
ccacheACL,\r
NULL)) {\r
gle = GetLastError();\r
- DebugEvent("SetNamedSecurityInfo DACL failed: GLE = 0x%lX", gle);\r
+ DebugEvent("SetNamedSecurityInfo DACL (1) failed: GLE = 0x%lX", gle);\r
if (gle != ERROR_NO_TOKEN)\r
ret = 1;\r
}\r
NULL,\r
NULL)) {\r
gle = GetLastError();\r
- DebugEvent("SetNamedSecurityInfo DACL failed: GLE = 0x%lX", gle);\r
+ DebugEvent("SetNamedSecurityInfo OWNER (2) failed: GLE = 0x%lX", gle);\r
if (gle != ERROR_NO_TOKEN)\r
ret = 1;\r
}\r
ccacheACL,\r
NULL)) {\r
gle = GetLastError();\r
- DebugEvent("SetNamedSecurityInfo DACL failed: GLE = 0x%lX", gle);\r
+ DebugEvent("SetNamedSecurityInfo DACL (3) failed: GLE = 0x%lX", gle);\r
if (gle != ERROR_NO_TOKEN)\r
ret = 1;\r
}\r
return ret;\r
}\r
\r
+int KFW_set_ccache_dacl_with_user_sid(char *filename, PSID pUserSID)\r
+{\r
+ // SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_SID_AUTHORITY;\r
+ PSID pSystemSID = NULL;\r
+ 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
+ if (!filename) {\r
+ DebugEvent0("KFW_set_ccache_dacl_with_user_sid - invalid parms");\r
+ return 1;\r
+ }\r
+\r
+ DebugEvent0("KFW_set_ccache_dacl_with_user_sid");\r
+\r
+ /* Get System SID */\r
+ if (!ConvertStringSidToSid("S-1-5-18", &pSystemSID)) {\r
+ DebugEvent("KFW_set_ccache_dacl - ConvertStringSidToSid GLE = 0x%x", GetLastError());\r
+ ret = 1;\r
+ goto cleanup;\r
+ }\r
+\r
+ /* Create ACL */\r
+ SystemSIDlength = GetLengthSid(pSystemSID);\r
+ ccacheACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE)\r
+ + SystemSIDlength - sizeof(DWORD);\r
+\r
+ if (pUserSID) {\r
+ UserSIDlength = GetLengthSid(pUserSID);\r
+\r
+ ccacheACLlength += sizeof(ACCESS_ALLOWED_ACE) + UserSIDlength \r
+ - sizeof(DWORD);\r
+ }\r
+\r
+ ccacheACL = (PACL) LocalAlloc(LPTR, ccacheACLlength);\r
+ if (!ccacheACL) {\r
+ DebugEvent("KFW_set_ccache_dacl - LocalAlloc GLE = 0x%x", GetLastError());\r
+ ret = 1;\r
+ goto cleanup;\r
+ }\r
+\r
+ InitializeAcl(ccacheACL, ccacheACLlength, ACL_REVISION);\r
+ AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0,\r
+ STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,\r
+ pSystemSID);\r
+ if (pUserSID) {\r
+ AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0,\r
+ STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,\r
+ pUserSID);\r
+ if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,\r
+ DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,\r
+ NULL,\r
+ NULL, \r
+ ccacheACL,\r
+ NULL)) {\r
+ gle = GetLastError();\r
+ DebugEvent("SetNamedSecurityInfo DACL (4) failed: GLE = 0x%lX", gle);\r
+ if (gle != ERROR_NO_TOKEN)\r
+ ret = 1;\r
+ }\r
+ if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,\r
+ OWNER_SECURITY_INFORMATION,\r
+ pUserSID,\r
+ NULL, \r
+ NULL,\r
+ NULL)) {\r
+ gle = GetLastError();\r
+ DebugEvent("SetNamedSecurityInfo OWNER (5) failed: GLE = 0x%lX", gle);\r
+ if (gle != ERROR_NO_TOKEN)\r
+ ret = 1;\r
+ }\r
+ } else {\r
+ if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT,\r
+ DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,\r
+ NULL,\r
+ NULL, \r
+ ccacheACL,\r
+ NULL)) {\r
+ gle = GetLastError();\r
+ DebugEvent("SetNamedSecurityInfo DACL (6) failed: GLE = 0x%lX", gle);\r
+ if (gle != ERROR_NO_TOKEN)\r
+ ret = 1;\r
+ }\r
+ }\r
+\r
+ cleanup:\r
+ if (pSystemSID)\r
+ LocalFree(pSystemSID);\r
+ if (ccacheACL)\r
+ LocalFree(ccacheACL);\r
+ return ret;\r
+}\r
+\r
int KFW_obtain_user_temp_directory(HANDLE hUserToken, char *newfilename, int size)\r
{\r
int retval = 0;\r
}\r
\r
void\r
-KFW_copy_cache_to_system_file(char * user, char * szLogonId)\r
+KFW_copy_cache_to_system_file(char * user, char * filename)\r
{\r
- char filename[MAX_PATH] = "";\r
DWORD count;\r
char cachename[MAX_PATH + 8] = "FILE:";\r
krb5_context ctx = 0;\r
krb5_ccache ncc = 0;\r
PSECURITY_ATTRIBUTES pSA = NULL;\r
\r
- if (!pkrb5_init_context || !user || !szLogonId)\r
+ if (!pkrb5_init_context || !user || !filename)\r
return;\r
\r
- count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));\r
- if ( count > sizeof(filename) || count == 0 ) {\r
- GetWindowsDirectory(filename, sizeof(filename));\r
- }\r
-\r
- DebugEvent0(filename);\r
- if ( strlen(filename) + strlen(szLogonId) + 2 > sizeof(filename) ) {\r
- DebugEvent0("filename buffer too small");\r
- return;\r
- }\r
-\r
- strcat(filename, "\\");\r
- strcat(filename, szLogonId); \r
-\r
- strcat(cachename, filename);\r
+ strncat(cachename, filename, sizeof(cachename));\r
+ cachename[sizeof(cachename)-1] = '\0';\r
\r
DebugEvent("KFW_Logon_Event - ccache %s", cachename);\r
\r
/*\r
Copyright 2005,2006 by the Massachusetts Institute of Technology\r
+Copyright 2007 by Secure Endpoints Inc.\r
\r
All rights reserved.\r
\r
#include "kfwlogon.h"\r
\r
#include <io.h>\r
+#include <stdio.h>\r
#include <sys/stat.h>\r
#include <sys/types.h>\r
#include <fcntl.h>\r
} // UnicodeStringToANSI\r
\r
\r
+static BOOL\r
+is_windows_vista(void)\r
+{\r
+ static BOOL fChecked = FALSE;\r
+ static BOOL fIsWinVista = FALSE;\r
+\r
+ if (!fChecked)\r
+ {\r
+ OSVERSIONINFO Version;\r
+\r
+ memset (&Version, 0x00, sizeof(Version));\r
+ Version.dwOSVersionInfoSize = sizeof(Version);\r
+\r
+ if (GetVersionEx (&Version))\r
+ {\r
+ if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT &&\r
+ Version.dwMajorVersion >= 6)\r
+ fIsWinVista = TRUE;\r
+ }\r
+ fChecked = TRUE;\r
+ }\r
+\r
+ return fIsWinVista;\r
+}\r
+\r
+/* Construct a Logon Script that will cause the LogonEventHandler to be executed\r
+ * under in the logon session \r
+ */\r
+VOID \r
+ConfigureLogonScript(LPWSTR *lpLogonScript, char * filename) {\r
+ DWORD dwLogonScriptLen;\r
+ LPWSTR lpScript;\r
+ LPSTR lpTemp;\r
+ \r
+ if (!lpLogonScript)\r
+ return;\r
+ *lpLogonScript = NULL;\r
+\r
+ if (!filename)\r
+ return;\r
+\r
+ dwLogonScriptLen = strlen("rundll32.exe kfwlogon.dll,LogonEventHandler ") + strlen(filename) + 1;\r
+ lpTemp = (LPSTR) malloc(dwLogonScriptLen); \r
+ if (!lpTemp)\r
+ return;\r
+\r
+ _snprintf(lpTemp, dwLogonScriptLen, \r
+ "rundll32.exe kfwlogon.dll,LogonEventHandler %s",\r
+ filename);\r
+\r
+ SetLastError(0);\r
+ dwLogonScriptLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, lpTemp, strlen(lpTemp), NULL, 0);\r
+ DebugEvent("ConfigureLogonScript %s requires %d bytes gle=0x%x", lpTemp, dwLogonScriptLen, GetLastError());\r
+\r
+ lpScript = LocalAlloc(LMEM_ZEROINIT, dwLogonScriptLen * 2);\r
+ if (lpScript) {\r
+ if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, lpTemp, strlen(lpTemp), \r
+ lpScript, 2 * dwLogonScriptLen))\r
+ *lpLogonScript = lpScript;\r
+ else {\r
+ DebugEvent("ConfigureLogonScript - MultiByteToWideChar failed gle = 0x%x", GetLastError());\r
+ LocalFree(lpScript);\r
+ }\r
+ } else {\r
+ DebugEvent("LocalAlloc failed gle=0x%x", GetLastError());\r
+ }\r
+ free(lpTemp);\r
+}\r
+\r
DWORD APIENTRY NPLogonNotify(\r
PLUID lpLogonId,\r
LPCWSTR lpAuthentInfoType,\r
LPVOID StationHandle,\r
LPWSTR *lpLogonScript)\r
{\r
- char uname[MAX_USERNAME_LENGTH]="";\r
- char password[MAX_PASSWORD_LENGTH]="";\r
- char logonDomain[MAX_DOMAIN_LENGTH]="";\r
- char szLogonId[128] = "";\r
+ char uname[MAX_USERNAME_LENGTH+1]="";\r
+ char password[MAX_PASSWORD_LENGTH+1]="";\r
+ char logonDomain[MAX_DOMAIN_LENGTH+1]="";\r
\r
MSV1_0_INTERACTIVE_LOGON *IL;\r
\r
* for this user \r
*/\r
if (!code) {\r
- sprintf(szLogonId,"kfwlogon-%d.%d",lpLogonId->HighPart, lpLogonId->LowPart);\r
- KFW_copy_cache_to_system_file(uname, szLogonId);\r
+ char filename[MAX_PATH+1] = "";\r
+ char acctname[MAX_USERNAME_LENGTH+MAX_DOMAIN_LENGTH+3]="";\r
+ PSID pUserSid = NULL;\r
+ LPTSTR pReferencedDomainName = NULL;\r
+ DWORD dwSidLen = 0, dwDomainLen = 0, count;\r
+ SID_NAME_USE eUse;\r
+\r
+ if (_snprintf(acctname, sizeof(acctname), "%s\\%s", logonDomain, uname) < 0) {\r
+ code = -1;\r
+ 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
+\r
+ if (_snprintf(filename, sizeof(filename), "%s\\kfwlogon-%d.%d",\r
+ filename, lpLogonId->HighPart, lpLogonId->LowPart) < 0) \r
+ {\r
+ code = -1;\r
+ goto cleanup;\r
+ }\r
+\r
+ KFW_copy_cache_to_system_file(uname, filename);\r
+\r
+ /* Need to determine the SID */\r
+\r
+ /* First get the size of the required buffers */\r
+ LookupAccountName (NULL,\r
+ acctname,\r
+ pUserSid,\r
+ &dwSidLen,\r
+ pReferencedDomainName,\r
+ &dwDomainLen,\r
+ &eUse);\r
+ if(dwSidLen){\r
+ pUserSid = (PSID) malloc (dwSidLen);\r
+ memset(pUserSid,0,dwSidLen);\r
+ }\r
+\r
+ if(dwDomainLen){\r
+ pReferencedDomainName = (LPTSTR) malloc (dwDomainLen * sizeof(TCHAR));\r
+ memset(pReferencedDomainName,0,dwDomainLen * sizeof(TCHAR));\r
+ }\r
+ \r
+ //Now get the SID and the domain name\r
+ if (pUserSid && LookupAccountName( NULL,\r
+ acctname,\r
+ pUserSid,\r
+ &dwSidLen,\r
+ pReferencedDomainName,\r
+ &dwDomainLen,\r
+ &eUse)) \r
+ {\r
+ DebugEvent("LookupAccountName obtained user %s sid in domain %s", acctname, pReferencedDomainName);\r
+ code = KFW_set_ccache_dacl_with_user_sid(filename, pUserSid);\r
+\r
+ /* If we are on Vista, setup a LogonScript \r
+ * that will execute the LogonEventHandler entry point via rundll32.exe \r
+ */\r
+ if (is_windows_vista()) {\r
+ ConfigureLogonScript(lpLogonScript, filename);\r
+ if (*lpLogonScript)\r
+ DebugEvent("LogonScript \"%s\"", *lpLogonScript);\r
+ else\r
+ DebugEvent0("No Logon Script");\r
+\r
+ }\r
+ } else {\r
+ DebugEvent0("LookupAccountName failed");\r
+ DeleteFile(filename);\r
+ code = -1;\r
+ }\r
+\r
+ cleanup:\r
+ if (pUserSid)\r
+ free(pUserSid);\r
+ if (pReferencedDomainName)\r
+ free(pReferencedDomainName);\r
}\r
\r
KFW_destroy_tickets_for_principal(uname);\r
\r
h = RegisterEventSource(NULL, KFW_LOGON_EVENT_NAME);\r
ptbuf[0] = msg;\r
- ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1008, NULL,\r
- 1, 0, ptbuf, NULL);\r
+ ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1008, NULL, 1, 0, ptbuf, NULL);\r
DeregisterEventSource(h);\r
SetLastError(code);\r
}\r
LogonId = pLogonSessionData->LogonId;\r
DebugEvent("KFW_Logon_Event - LogonId(%d,%d)", LogonId.HighPart, LogonId.LowPart);\r
\r
- sprintf(szLogonId,"kfwlogon-%d.%d",LogonId.HighPart, LogonId.LowPart);\r
+ _snprintf(szLogonId, sizeof(szLogonId), "kfwlogon-%d.%d",LogonId.HighPart, LogonId.LowPart);\r
LsaFreeReturnBuffer( pLogonSessionData );\r
} else {\r
DebugEvent0("KFW_Logon_Event - Unable to determine LogonId");\r
return;\r
}\r
\r
- sprintf(commandline, "kfwcpcc.exe \"%s\"", newfilename);\r
+ _snprintf(commandline, sizeof(commandline), "kfwcpcc.exe \"%s\"", newfilename);\r
\r
GetStartupInfo(&startupinfo);\r
if (CreateProcessAsUser( pInfo->hToken,\r
DebugEvent0("KFW_Logon_Event - CreateProcessFailed");\r
}\r
\r
- DeleteFile(filename);\r
+ DeleteFile(newfilename);\r
\r
DebugEvent0("KFW_Logon_Event - End");\r
}\r
\r
+\r
+/* Documentation on the use of RunDll32 entrypoints can be found \r
+ * at http://support.microsoft.com/kb/164787 \r
+ */\r
+void CALLBACK\r
+LogonEventHandlerA(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)\r
+{\r
+ HANDLE hf = NULL;\r
+ char commandline[MAX_PATH+256] = "";\r
+ STARTUPINFO startupinfo;\r
+ PROCESS_INFORMATION procinfo;\r
+\r
+ DebugEvent0("LogonEventHandler - Start");\r
+\r
+ /* Validate lpszCmdLine as a file */\r
+ hf = CreateFile(lpszCmdLine, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, \r
+ FILE_ATTRIBUTE_NORMAL, NULL);\r
+ if (hf == INVALID_HANDLE_VALUE) {\r
+ DebugEvent0("LogonEventHandler - file cannot be opened");\r
+ return;\r
+ }\r
+ CloseHandle(hf);\r
+\r
+\r
+ _snprintf(commandline, sizeof(commandline), "kfwcpcc.exe \"%s\"", lpszCmdLine);\r
+\r
+ GetStartupInfo(&startupinfo);\r
+ if (CreateProcess( "kfwcpcc.exe",\r
+ commandline,\r
+ NULL,\r
+ NULL,\r
+ FALSE,\r
+ CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,\r
+ NULL,\r
+ NULL,\r
+ &startupinfo,\r
+ &procinfo)) \r
+ {\r
+ DebugEvent("KFW_Logon_Event - CommandLine %s", commandline);\r
+\r
+ WaitForSingleObject(procinfo.hProcess, 30000);\r
+\r
+ CloseHandle(procinfo.hThread);\r
+ CloseHandle(procinfo.hProcess);\r
+ } else {\r
+ DebugEvent0("KFW_Logon_Event - CreateProcessFailed");\r
+ }\r
+\r
+ DeleteFile(lpszCmdLine);\r
+\r
+ DebugEvent0("KFW_Logon_Event - End");\r
+}\r