WindowsXP-SP1/inetsrv/iis/svcs/infocomm/common/tokenacl.cxx
2020-09-30 16:53:49 +02:00

337 lines
8.4 KiB
C++

/*===================================================================
Microsoft Internet Information Server
Microsoft Confidential.
Copyright 1997 Microsoft Corporation. All Rights Reserved.
File: TokenAcl.cxx
Owner: AndrewS
This file contains code related to NT security on impersonation tokens
===================================================================*/
#include "tcpdllp.hxx"
#pragma hdrstop
// Local Defines
// Local functions
HRESULT ExpandAcl(PACL paclOld, ULONG cbAclOld, PACL *ppAclNew, PSID psid);
HRESULT AddSidToTokenAcl(HANDLE hToken, PSID pSid, ACCESS_MASK amDesiredAccess);
HRESULT GetEveryoneSid(PSID *ppSidEveryone);
/*===================================================================
GrantAllAccessToToken
Given an impersonation token, grant "Everyone" permissions to that
token so that Out Of Proc ISAPIs will be able to do a GetThreadToken call.
Parameters:
HANDLE hToken - handle to impersonation token for a user
Returns:
HRESULT NOERROR on success
===================================================================*/
HRESULT GrantAllAccessToToken
(
HANDLE hToken
)
{
HRESULT hr = NOERROR;
DWORD err;
PSID pSidEveryone;
hr = GetEveryoneSid(&pSidEveryone);
if (FAILED(hr))
goto LExit;
hr = AddSidToTokenAcl(hToken, pSidEveryone, TOKEN_ALL_ACCESS);
FreeSid( pSidEveryone );
LExit:
DBG_ASSERT(SUCCEEDED(hr));
return(hr);
}
/*===================================================================
AddSidToTokenAcl
When creating Local server objects (e.g. EXE's) we have some problems because of DCOM security.
The user creating the object must have appropriate permissions on the IIS process WindowStation (bug 549)
and the Desktop.
Add ACE's on the ACL for our WindowStation & Desktop for the current user.
Parameters:
HANDLE hImpersonate - handle to impersonation token for the current user
Returns:
HRESULT NOERROR on success
===================================================================*/
HRESULT AddSidToTokenAcl
(
HANDLE hToken,
PSID pSid,
ACCESS_MASK amDesiredAccess
)
{
HRESULT hr;
DWORD err;
PSECURITY_DESCRIPTOR psdRelative = NULL;
SECURITY_DESCRIPTOR sdAbsolute;
ULONG cbSdPost;
PACL pDacl = NULL;
PACL pDaclNew = NULL;
ULONG cbSD;
ULONG cbDacl;
ULONG cbSacl;
ULONG cbOwner;
ULONG cbGroup;
ACL_SIZE_INFORMATION AclSize;
//
// Get the SD of the token.
// Call this twice; once to get the size, then again to get the info
//
GetKernelObjectSecurity(hToken,
DACL_SECURITY_INFORMATION,
NULL,
0,
&cbSD);
psdRelative = (PSECURITY_DESCRIPTOR) new BYTE[cbSD];
if (psdRelative == NULL)
{
hr = E_OUTOFMEMORY;
goto LExit;
}
if (!GetKernelObjectSecurity(hToken,
DACL_SECURITY_INFORMATION,
psdRelative,
cbSD,
&cbSD))
{
DBG_ASSERT(FALSE);
err = GetLastError();
hr = HRESULT_FROM_WIN32(err);
goto LExit;
}
//
// Allocate a new Dacl
//
pDacl = (PACL) new BYTE[cbSD];
if (pDacl == NULL)
{
hr = E_OUTOFMEMORY;
goto LExit;
}
//
// Make an absolute SD from the relative SD we have, and get the Dacl at the same time
//
cbSdPost = sizeof(sdAbsolute);
cbDacl = cbSD;
cbSacl = 0;
cbOwner = 0;
cbGroup = 0;
if (!MakeAbsoluteSD(psdRelative,
&sdAbsolute,
&cbSdPost,
pDacl,
&cbDacl,
NULL,
&cbSacl,
NULL,
&cbOwner,
NULL,
&cbGroup))
{
DBG_ASSERT(FALSE);
err = GetLastError();
hr = HRESULT_FROM_WIN32(err);
goto LExit;
}
//
// Copy ACEs over
//
hr = ExpandAcl(pDacl, cbSD, &pDaclNew, pSid);
if (FAILED(hr))
goto LExit;
//
// Add ACE to allow access
//
if (!AddAccessAllowedAce(pDaclNew, ACL_REVISION, amDesiredAccess, pSid))
{
DBG_ASSERT(FALSE);
err = GetLastError();
hr = HRESULT_FROM_WIN32(err);
goto LExit;
}
//
// Set the new DACL in the SD
//
if (!SetSecurityDescriptorDacl(&sdAbsolute, TRUE, pDaclNew, FALSE))
{
DBG_ASSERT(FALSE);
err = GetLastError();
hr = HRESULT_FROM_WIN32(err);
goto LExit;
}
//
// Set the new SD on the token object
//
if (!SetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION, &sdAbsolute))
{
DBG_ASSERT(FALSE);
err = GetLastError();
hr = HRESULT_FROM_WIN32(err);
goto LExit;
}
LExit:
delete pDacl;
delete pDaclNew;
delete psdRelative;
return hr;
}
/*===================================================================
GetEveryoneSid
Get a sid for "Everyone"
Parameters:
PSID pSidEveryone
Returns:
HRESULT NOERROR on success
===================================================================*/
HRESULT GetEveryoneSid
(
PSID *ppSidEveryone
)
{
BOOL fT;
SID_IDENTIFIER_AUTHORITY sidWorldAuthority = SECURITY_WORLD_SID_AUTHORITY;
fT = AllocateAndInitializeSid(
&sidWorldAuthority, // pIdentifierAuthority
1, // nSubAuthorityCount
SECURITY_WORLD_RID, // nSubAuthority0
0, // nSubAuthority1
0, // nSubAuthority2
0, // nSubAuthority3
0, // nSubAuthority4
0, // nSubAuthority5
0, // nSubAuthority6
0, // nSubAuthority7
ppSidEveryone // pSid
);
if( !fT )
return HRESULT_FROM_WIN32(GetLastError());
else
return NOERROR;
}
/*===================================================================
ExpandAcl
Support routine for AddWindowStationSecurity.
Expands the given ACL so that there is room for an additional ACE
Parameters:
paclOld - the old ACL to expand
ppAclNew - the newly allocated expanded acl
psid - the sid to use
Returns:
HRESULT NOERROR on success
===================================================================*/
HRESULT ExpandAcl
(
PACL paclOld,
ULONG cbAclOld,
PACL *ppAclNew,
PSID psid
)
{
HRESULT hr;
DWORD err;
PACL pAclNew = NULL;
ACL_SIZE_INFORMATION asi;
int dwAclSize;
DWORD iAce;
LPVOID pAce;
DBG_ASSERT(paclOld != NULL);
DBG_ASSERT(ppAclNew != NULL);
//
// Create a new ACL to play with
//
if (!GetAclInformation (paclOld, (LPVOID) &asi, (DWORD) sizeof (asi), AclSizeInformation))
goto LExit;
dwAclSize = cbAclOld + GetLengthSid(psid) + (8 * sizeof(DWORD));
pAclNew = (PACL) new BYTE[dwAclSize];
if (pAclNew == NULL)
{
return(E_OUTOFMEMORY);
}
if (!InitializeAcl(pAclNew, dwAclSize, ACL_REVISION))
goto LExit;
//
// Copy all of the ACEs to the new ACL
//
for (iAce = 0; iAce < asi.AceCount; iAce++)
{
//
// Get the ACE and header info
//
if (!GetAce(paclOld, iAce, &pAce))
goto LExit;
//
// Add the ACE to the new list
//
if (!AddAce(pAclNew, ACL_REVISION, iAce, pAce, ((ACE_HEADER *)pAce)->AceSize))
goto LExit;
}
*ppAclNew = pAclNew;
return(NOERROR);
LExit:
if (pAclNew != NULL)
delete pAclNew;
DBG_ASSERT(FALSE);
err = GetLastError();
hr = HRESULT_FROM_WIN32(err);
return hr;
}