437 lines
10 KiB
C++
437 lines
10 KiB
C++
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name :
|
|
ooptoken.cpp
|
|
|
|
Abstract:
|
|
Implementation of the CWamOopTokenInfo object
|
|
|
|
Author:
|
|
Taylor Weiss ( TaylorW ) 15-Feb-1999
|
|
|
|
Environment:
|
|
User Mode - Win32
|
|
|
|
Project:
|
|
iis\svcs\wam\object
|
|
|
|
--*/
|
|
|
|
#include <isapip.hxx>
|
|
#include "ooptoken.h"
|
|
|
|
/************************ CWamOopTokenInfo ****************************/
|
|
|
|
CWamOopTokenInfo * CWamOopTokenInfo::ms_pInstance = NULL;
|
|
|
|
HRESULT
|
|
CWamOopTokenInfo::Create( VOID )
|
|
/*++
|
|
Routine Description:
|
|
|
|
Create and initialize ms_pInstance. Get the wam and system SIDs.
|
|
|
|
The IWAM_* user sid is obtained from the process token. This
|
|
only works if we are running OOP. The alternative is to put this
|
|
in w3svc or infocomm and get the SID from the metabase. The downside
|
|
to that is the account for the application package is exposed
|
|
through the com+ UI, so it can be changed without a metabase update.
|
|
|
|
Parameters
|
|
|
|
Return Value
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
DBG_ASSERT( CWamOopTokenInfo::ms_pInstance == NULL );
|
|
|
|
HRESULT hr = NOERROR;
|
|
HANDLE hProcessToken = NULL;
|
|
LPVOID pvUserBuffer = NULL;
|
|
PSID pSidSys = NULL;
|
|
CWamOopTokenInfo * pInstance = NULL;
|
|
|
|
do
|
|
{
|
|
BOOL fNoError = FALSE;
|
|
DWORD cbUserBuffer = 0;
|
|
|
|
// Allocate instance
|
|
pInstance = new CWamOopTokenInfo();
|
|
|
|
DBG_ASSERT( pInstance != NULL );
|
|
if( !pInstance )
|
|
{
|
|
DBG_ASSERT( pInstance );
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get a SID for the IWAM_* user.
|
|
//
|
|
fNoError = OpenProcessToken( GetCurrentProcess(),
|
|
TOKEN_QUERY,
|
|
&hProcessToken
|
|
);
|
|
if( !fNoError )
|
|
{
|
|
DBG_ASSERT( fNoError );
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
break;
|
|
}
|
|
|
|
// Get buffer size
|
|
fNoError = GetTokenInformation( hProcessToken,
|
|
TokenUser,
|
|
NULL,
|
|
0,
|
|
&cbUserBuffer
|
|
);
|
|
DBG_ASSERT( fNoError == FALSE );
|
|
|
|
pvUserBuffer = LocalAlloc( LPTR, cbUserBuffer );
|
|
DBG_ASSERT( pvUserBuffer != NULL );
|
|
if( !pvUserBuffer )
|
|
{
|
|
DBG_ASSERT( pvUserBuffer );
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
// Get user info
|
|
fNoError = GetTokenInformation( hProcessToken,
|
|
TokenUser,
|
|
pvUserBuffer,
|
|
cbUserBuffer,
|
|
&cbUserBuffer
|
|
);
|
|
if( !fNoError )
|
|
{
|
|
DBG_ASSERT( fNoError );
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
break;
|
|
}
|
|
|
|
hr = pInstance->SetIWAMUserSid( ((TOKEN_USER *)pvUserBuffer)->User.Sid );
|
|
if( FAILED(hr) ) break;
|
|
|
|
//
|
|
// Create a SID for the local system
|
|
//
|
|
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
|
|
fNoError = AllocateAndInitializeSid( &siaNtAuthority,
|
|
1,
|
|
SECURITY_LOCAL_SYSTEM_RID,
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
&pSidSys
|
|
);
|
|
if( !fNoError )
|
|
{
|
|
DBG_ASSERT( fNoError );
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
break;
|
|
}
|
|
|
|
hr = pInstance->SetSystemSid( pSidSys );
|
|
if( FAILED(hr) ) break;
|
|
|
|
CWamOopTokenInfo::ms_pInstance = pInstance;
|
|
|
|
} while( FALSE );
|
|
|
|
if( hProcessToken )
|
|
{
|
|
CloseHandle( hProcessToken );
|
|
}
|
|
if( pvUserBuffer )
|
|
{
|
|
LocalFree( pvUserBuffer );
|
|
}
|
|
if( pSidSys )
|
|
{
|
|
FreeSid( pSidSys );
|
|
}
|
|
if( CWamOopTokenInfo::ms_pInstance == NULL )
|
|
{
|
|
// We hit some break, need to dealloc local pointer
|
|
delete pInstance;
|
|
}
|
|
|
|
DBG_ASSERT( CWamOopTokenInfo::ms_pInstance != NULL );
|
|
DBG_ASSERT( SUCCEEDED(hr) );
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CWamOopTokenInfo::SetIWAMUserSid( PSID pSid )
|
|
/*++
|
|
Routine Description:
|
|
|
|
Make a local copy of the SID. Called during instance create.
|
|
|
|
Probably should avoid the extra duplication.
|
|
|
|
Parameters
|
|
|
|
pSid - The IWAM_* user sid.
|
|
|
|
Return Value
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
DBG_ASSERT( pSid );
|
|
DBG_ASSERT( m_pIWAMUserSid == NULL );
|
|
DBG_ASSERT( m_cbIWAMUserSid == 0 );
|
|
|
|
HRESULT hr = NOERROR;
|
|
|
|
m_cbIWAMUserSid = GetLengthSid( pSid );
|
|
|
|
m_pIWAMUserSid = LocalAlloc( LPTR, m_cbIWAMUserSid );
|
|
|
|
if( m_pIWAMUserSid )
|
|
{
|
|
if( !CopySid( m_cbIWAMUserSid, m_pIWAMUserSid, pSid ) )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
m_cbIWAMUserSid = 0;
|
|
}
|
|
|
|
DBG_ASSERT( m_pIWAMUserSid );
|
|
DBG_ASSERT( m_cbIWAMUserSid > 0 );
|
|
DBG_ASSERT( SUCCEEDED(hr) );
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CWamOopTokenInfo::SetSystemSid( PSID pSid )
|
|
/*++
|
|
Routine Description:
|
|
|
|
Make a local copy of the SID. Called during instance create.
|
|
|
|
Probably should avoid the extra duplication.
|
|
|
|
Parameters
|
|
|
|
pSid - The system sid.
|
|
|
|
Return Value
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
DBG_ASSERT( pSid );
|
|
DBG_ASSERT( m_pSystemSid == NULL );
|
|
DBG_ASSERT( m_cbSystemSid == 0 );
|
|
|
|
HRESULT hr = NOERROR;
|
|
|
|
m_cbSystemSid = GetLengthSid( pSid );
|
|
|
|
m_pSystemSid = LocalAlloc( LPTR, m_cbSystemSid );
|
|
|
|
if( m_pSystemSid )
|
|
{
|
|
if( !CopySid( m_cbSystemSid, m_pSystemSid, pSid ) )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
m_cbSystemSid = 0;
|
|
}
|
|
|
|
DBG_ASSERT( m_pSystemSid );
|
|
DBG_ASSERT( m_cbSystemSid > 0 );
|
|
DBG_ASSERT( SUCCEEDED(hr) );
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CWamOopTokenInfo::ModifyTokenForOop
|
|
(
|
|
HANDLE hThreadToken
|
|
)
|
|
/*++
|
|
Routine Description
|
|
|
|
Add the IWAM_* ace to the token.
|
|
|
|
Prameters
|
|
|
|
HANDLE hThreadToken - The token to modify.
|
|
|
|
Return Value
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
DBG_ASSERT( m_pIWAMUserSid );
|
|
DBG_ASSERT( m_pSystemSid );
|
|
|
|
HRESULT hr = NOERROR;
|
|
|
|
DWORD cbTokenUserBuffer = 0;
|
|
LPVOID pvTokenUserBuffer = NULL;
|
|
|
|
DWORD cbNewAcl = 0;
|
|
PACL pNewAcl = NULL;
|
|
|
|
do
|
|
{
|
|
BOOL bRet;
|
|
|
|
//
|
|
// Get the User SID from the token
|
|
//
|
|
|
|
// Get buffer size
|
|
bRet = GetTokenInformation( hThreadToken,
|
|
TokenUser,
|
|
NULL,
|
|
0,
|
|
&cbTokenUserBuffer
|
|
);
|
|
DBG_ASSERT( bRet == FALSE );
|
|
|
|
pvTokenUserBuffer = LocalAlloc( LPTR, cbTokenUserBuffer );
|
|
if( !pvTokenUserBuffer )
|
|
{
|
|
DBG_ASSERT( pvTokenUserBuffer );
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
// Get TokenUser
|
|
bRet = GetTokenInformation( hThreadToken,
|
|
TokenUser,
|
|
pvTokenUserBuffer,
|
|
cbTokenUserBuffer,
|
|
&cbTokenUserBuffer
|
|
);
|
|
if( !bRet )
|
|
{
|
|
DBG_ASSERT( bRet );
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
break;
|
|
}
|
|
|
|
PSID pSidUser = ((TOKEN_USER *)pvTokenUserBuffer)->User.Sid;
|
|
|
|
DBG_ASSERT( pSidUser );
|
|
|
|
//
|
|
// Allocate and init our new ACL
|
|
//
|
|
cbNewAcl = sizeof(ACL) +
|
|
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pSidUser) - sizeof(DWORD) +
|
|
sizeof(ACCESS_ALLOWED_ACE) + m_cbSystemSid - sizeof(DWORD) +
|
|
sizeof(ACCESS_ALLOWED_ACE) + m_cbIWAMUserSid - sizeof(DWORD);
|
|
|
|
pNewAcl = (PACL)LocalAlloc( LPTR, cbNewAcl );
|
|
if( !pNewAcl )
|
|
{
|
|
DBG_ASSERT( pNewAcl );
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
bRet = InitializeAcl( pNewAcl, cbNewAcl, ACL_REVISION );
|
|
if( !bRet )
|
|
{
|
|
DBG_ASSERT( bRet );
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Add the aces
|
|
//
|
|
bRet = AddAccessAllowedAce( pNewAcl,
|
|
ACL_REVISION,
|
|
GENERIC_ALL | STANDARD_RIGHTS_ALL,
|
|
pSidUser
|
|
);
|
|
if( !bRet )
|
|
{
|
|
DBG_ASSERT( bRet );
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
break;
|
|
}
|
|
|
|
bRet = AddAccessAllowedAce( pNewAcl,
|
|
ACL_REVISION,
|
|
GENERIC_ALL | STANDARD_RIGHTS_ALL,
|
|
m_pSystemSid
|
|
);
|
|
if( !bRet )
|
|
{
|
|
DBG_ASSERT( bRet );
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
break;
|
|
}
|
|
|
|
bRet = AddAccessAllowedAce( pNewAcl,
|
|
ACL_REVISION,
|
|
GENERIC_ALL | STANDARD_RIGHTS_ALL,
|
|
m_pIWAMUserSid
|
|
);
|
|
if( !bRet )
|
|
{
|
|
DBG_ASSERT( bRet );
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
break;
|
|
}
|
|
|
|
// Blast the new DACL into our token
|
|
TOKEN_DEFAULT_DACL tddNew;
|
|
tddNew.DefaultDacl = pNewAcl;
|
|
|
|
bRet = SetTokenInformation( hThreadToken,
|
|
TokenDefaultDacl,
|
|
&tddNew,
|
|
cbNewAcl
|
|
);
|
|
if( !bRet )
|
|
{
|
|
DBG_ASSERT( bRet );
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
break;
|
|
}
|
|
|
|
}while(FALSE);
|
|
|
|
if( pvTokenUserBuffer )
|
|
{
|
|
LocalFree( pvTokenUserBuffer );
|
|
}
|
|
if( pNewAcl )
|
|
{
|
|
LocalFree( pNewAcl );
|
|
}
|
|
|
|
DBG_ASSERT( SUCCEEDED(hr) );
|
|
return hr;
|
|
}
|