337 lines
8.1 KiB
C++
337 lines
8.1 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;
|
||
|
}
|
||
|
|
||
|
|