Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

377 lines
9.0 KiB

/*
IisRsta.cpp
Implementation of WinMain for COM IIisServiceControl handler
FILE HISTORY:
Phillich 06-Oct-1998 Created
*/
#include "stdafx.h"
#include "resource.h"
#include <initguid.h>
#include "iisrsta.h"
#include <secfcns.h>
#include <Aclapi.h>
#include "IisRestart.h"
const DWORD dwTimeOut = 5000; // time for EXE to be idle before shutting down
const DWORD dwPause = 1000; // time to wait for threads to finish up
HRESULT
AddLaunchPermissionsAcl(
PSECURITY_DESCRIPTOR pSD
);
// Passed to CreateThread to monitor the shutdown event
static DWORD WINAPI MonitorProc(void* pv)
{
CExeModule* p = (CExeModule*)pv;
p->MonitorShutdown();
return 0;
}
LONG CExeModule::Unlock()
{
LONG l = CComModule::Unlock();
if (l == 0)
{
bActivity = true;
SetEvent(hEventShutdown); // tell monitor that we transitioned to zero
}
return l;
}
//Monitors the shutdown event
void CExeModule::MonitorShutdown()
{
while (1)
{
WaitForSingleObject(hEventShutdown, INFINITE);
DWORD dwWait=0;
do
{
bActivity = false;
dwWait = WaitForSingleObject(hEventShutdown, dwTimeOut);
} while (dwWait == WAIT_OBJECT_0);
// timed out
if (!bActivity && m_nLockCnt == 0) // if no activity let's really bail
{
break;
}
}
CloseHandle(hEventShutdown);
PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
}
bool CExeModule::StartMonitor()
{
hEventShutdown = CreateEvent(NULL, false, false, NULL);
if (hEventShutdown == NULL)
return false;
DWORD dwThreadID;
HANDLE h = CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
return (h != NULL);
}
CExeModule _Module;
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_IisServiceControl, CIisRestart)
END_OBJECT_MAP()
LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
{
while (p1 != NULL && *p1 != NULL)
{
LPCTSTR p = p2;
while (p != NULL && *p != NULL)
{
if (*p1 == *p)
return CharNext(p1);
p = CharNext(p);
}
p1 = CharNext(p1);
}
return NULL;
}
/////////////////////////////////////////////////////////////////////////////
//
int _cdecl
main(
int,
char
)
{
LPTSTR lpCmdLine = GetCommandLine(); // necessary for minimal CRT
HRESULT hRes = S_OK;
DWORD dwErr = ERROR_SUCCESS;
PSID psidAdmin = NULL;
PACL pACL = NULL;
EXPLICIT_ACCESS ea;
SECURITY_DESCRIPTOR sd = {0};
BOOL fCoInitialized = FALSE;
hRes = CoInitializeEx(NULL,COINIT_MULTITHREADED);
if (FAILED(hRes)) {
goto exit;
}
fCoInitialized = TRUE;
//
// Get a sid that represents the Administrators group.
//
dwErr = AllocateAndCreateWellKnownSid( WinBuiltinAdministratorsSid,
&psidAdmin );
if ( dwErr != ERROR_SUCCESS )
{
hRes = HRESULT_FROM_WIN32(dwErr);
goto exit;
}
// Initialize an EXPLICIT_ACCESS structure for an ACE.
SecureZeroMemory(&ea, sizeof(ea));
//
// Setup Administrators for read access.
//
SetExplicitAccessSettings( &ea,
COM_RIGHTS_EXECUTE,
SET_ACCESS,
psidAdmin );
//
// Create a new ACL that contains the new ACEs.
//
dwErr = SetEntriesInAcl(sizeof(ea)/sizeof(EXPLICIT_ACCESS), &ea, NULL, &pACL);
if ( dwErr != ERROR_SUCCESS )
{
hRes = HRESULT_FROM_WIN32(dwErr);
goto exit;
}
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
{
hRes = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
if (!SetSecurityDescriptorDacl(&sd,
TRUE, // fDaclPresent flag
pACL,
FALSE)) // not a default DACL
{
hRes = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
if (!SetSecurityDescriptorOwner(&sd,
psidAdmin, // fDaclPresent flag
FALSE)) // not a default DACL
{
hRes = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
if (!SetSecurityDescriptorGroup(&sd,
psidAdmin, // fDaclPresent flag
FALSE)) // not a default DACL
{
hRes = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
hRes = CoInitializeSecurity(
&sd,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_ANONYMOUS,
NULL,
EOAC_DYNAMIC_CLOAKING |
EOAC_DISABLE_AAA |
EOAC_NO_CUSTOM_MARSHAL,
NULL );
if (FAILED(hRes))
{
goto exit;
}
_ASSERTE(SUCCEEDED(hRes));
_Module.Init(ObjectMap,GetModuleHandle(NULL));
_Module.dwThreadID = GetCurrentThreadId();
TCHAR szTokens[] = _T("-/");
BOOL bRun = TRUE;
LPCTSTR lpszToken = FindOneOf(lpCmdLine,szTokens);
while (lpszToken != NULL)
{
#pragma prefast(push)
#pragma prefast(disable:400, "Don't complain about case insensitive compares")
if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
{
_Module.UpdateRegistryFromResource(IDR_IISRESTART, FALSE);
bRun = FALSE;
break;
}
if (lstrcmpi(lpszToken, _T("RegServer"))==0)
{
_Module.UpdateRegistryFromResource(IDR_IISRESTART, TRUE);
// we need to do the Module.Terminate so we
// will just flow on with a bad hresult, however
// it will end up getting returned to the user
// so it is ok.
hRes = AddLaunchPermissionsAcl(&sd);
bRun = FALSE;
break;
}
lpszToken = FindOneOf(lpszToken, szTokens);
#pragma prefast(pop)
}
if (bRun) {
_Module.StartMonitor();
hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE);
_ASSERTE(SUCCEEDED(hRes));
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
{
DispatchMessage(&msg);
}
_Module.RevokeClassObjects();
Sleep(dwPause); //wait for any threads to finish
}
_Module.Term();
exit:
FreeWellKnownSid(&psidAdmin);
if (pACL)
{
LocalFree(pACL);
pACL = NULL;
}
if ( fCoInitialized )
{
CoUninitialize();
}
return (hRes);
}
HRESULT
AddLaunchPermissionsAcl(
PSECURITY_DESCRIPTOR pSD
)
{
DWORD Win32Error = NO_ERROR;
HRESULT hr = S_OK;
HKEY KeyHandle = NULL;
PSECURITY_DESCRIPTOR pSDRelative = NULL;
DWORD dwBytesNeeded = 0;
if ( MakeSelfRelativeSD( pSD,
pSDRelative,
&dwBytesNeeded ) )
{
// If this passes, then there is a real problem because
// we didn't give it anywhere to copy to. So
// we fail here.
return E_FAIL;
}
Win32Error = GetLastError();
if ( Win32Error != ERROR_INSUFFICIENT_BUFFER )
{
return HRESULT_FROM_WIN32(Win32Error);
}
// At this point we know the size of the data
// that we are going to receive, so we can allocated
// enough space.
pSDRelative = ( PSECURITY_DESCRIPTOR ) new BYTE[ dwBytesNeeded ];
if ( pSDRelative == NULL )
{
return E_OUTOFMEMORY;
}
if ( !MakeSelfRelativeSD( pSD,
pSDRelative,
&dwBytesNeeded ) )
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
Win32Error = RegOpenKeyEx(
HKEY_CLASSES_ROOT,
L"AppID\\{E8FB8615-588F-11D2-9D61-00C04F79C5FE}",
NULL,
KEY_WRITE,
&KeyHandle
);
if ( Win32Error != NO_ERROR )
{
hr = HRESULT_FROM_WIN32( Win32Error );
goto exit;
}
Win32Error = RegSetValueEx(
KeyHandle,
L"LaunchPermission",
NULL,
REG_BINARY,
reinterpret_cast<BYTE *>( pSDRelative ),
dwBytesNeeded
);
if ( Win32Error != NO_ERROR )
{
hr = HRESULT_FROM_WIN32( Win32Error );
goto exit;
}
exit:
if ( KeyHandle != NULL )
{
RegCloseKey( KeyHandle );
}
if ( pSDRelative != NULL )
{
delete [] pSDRelative;
}
return hr;
}