//*************************************************************************** // // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved // // CreateMutexAsProcess.CPP // // Purpose: Create a mutex NOT using impersonation // //*************************************************************************** #include "precomp.h" #include #include #include "MultiPlat.h" CreateMutexAsProcess::CreateMutexAsProcess(const WCHAR *cszMutexName) { m_hMutex = NULL; bool bUseMutex = false; DWORD dwOSMajorVersion; dwOSMajorVersion = CWbemProviderGlue::GetOSMajorVersion(); // HACK HACK HACK - special case for security mutex. // TODO: remove special case, make special class, see RAID 38371 if (wcscmp(cszMutexName, SECURITYAPIMUTEXNAME) == 0) { //Work out if we need the mutex... if (CWbemProviderGlue::GetPlatform() == VER_PLATFORM_WIN32_NT) { if (dwOSMajorVersion < 5) //if (dwOSMajorVersion < 4) // see comment below { bUseMutex = true; } // Code changed from using the mutex if nt4sp4 or earlier, to plain old use it if less // than nt5 because some security issues have not been fixed in nt4, even up to sp6. /* else if (dwOSMajorVersion == 4) { LPCWSTR pcwstrCSDVersion = CWbemProviderGlue::GetCSDVersion(); if ((pcwstrCSDVersion == NULL) || (pcwstrCSDVersion == L'\0')) { bUseMutex = true; } else { //Need to determine if we are SP4 or above as there is no need to use the //mutex if this is the case... bUseMutex = true; for (int i = 0; pcwstrCSDVersion[i] != '\0'; i++) { if (isdigit(pcwstrCSDVersion[i])) { if (_wtoi(&(pcwstrCSDVersion[i])) >= 4) { bUseMutex = false; } break; } } } } else { bUseMutex = true; } */ } } else { bUseMutex = true; } if (bUseMutex) { HANDLE hThreadToken = INVALID_HANDLE_VALUE; // The mutex will need to be opened in the process's context. If two impersonated // threads need the mutex, we can't have the second one get an access denied when // opening the mutex. // If the OpenThreadToken fails, it is most likely due to already having reverted // to self. If so, no RevertToSelf is necessary. if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, TRUE, &hThreadToken)) { LONG lRet = GetLastError(); // Get the value while the gettins good. LogMessage2(L"Failed to open thread token: (%d)", lRet); hThreadToken = INVALID_HANDLE_VALUE; } else { RevertToSelf(); } m_hMutex = FRCreateMutex(NULL, FALSE, cszMutexName); LONG lRet = GetLastError(); // Get the value while the gettins good. LogMessage2(L"Status of mutex creation: (%d)", lRet); // Back to the original user. Apparently, security is only checked on the open. if (hThreadToken != INVALID_HANDLE_VALUE) { if (!ImpersonateLoggedOnUser(hThreadToken)) { LogErrorMessage2(L"Failed to return to impersonation (0x%x)", GetLastError()); } CloseHandle(hThreadToken); } if (m_hMutex) { WaitForSingleObject(m_hMutex, INFINITE); } else { LogErrorMessage3(L"Failed to open mutex: %s (%d)", cszMutexName, lRet); } } } CreateMutexAsProcess::~CreateMutexAsProcess() { if (m_hMutex) { ReleaseMutex(m_hMutex); CloseHandle(m_hMutex); } }