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.
336 lines
8.4 KiB
336 lines
8.4 KiB
/*===================================================================
|
|
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;
|
|
}
|
|
|
|
|