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.
378 lines
8.4 KiB
378 lines
8.4 KiB
/*****************************************************************************/
|
|
|
|
/* Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved /
|
|
/*****************************************************************************/
|
|
|
|
|
|
/*
|
|
* SecurityDescriptor.cpp - implementation file for CSecureKernelObj class.
|
|
*
|
|
* Created: 11-27-00 by Kevin Hughes
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
#include "AccessEntry.h" // CAccessEntry class
|
|
#include "AccessEntryList.h"
|
|
#include "aclapi.h"
|
|
#include "DACL.h" // CDACL class
|
|
#include "SACL.h" // CSACL class
|
|
|
|
|
|
#include "SecurityDescriptor.h"
|
|
#include "securefile.h"
|
|
#include "tokenprivilege.h"
|
|
#include "ImpLogonUser.h"
|
|
#include "AdvApi32Api.h"
|
|
#include "smartptr.h"
|
|
#include "SecureKernelObj.h"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CSecureKernelObj::CSecureKernelObj
|
|
//
|
|
// Default class constructor.
|
|
//
|
|
// Inputs:
|
|
// None.
|
|
//
|
|
// Outputs:
|
|
// None.
|
|
//
|
|
// Returns:
|
|
// None.
|
|
//
|
|
// Comments:
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
CSecureKernelObj::CSecureKernelObj()
|
|
: CSecurityDescriptor()
|
|
{
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CSecureKernelObj::CSecureKernelObj
|
|
//
|
|
// Alternate Class CTOR
|
|
//
|
|
// Inputs:
|
|
// LPCWSTR wszObjName - The kernel object to handle
|
|
// security for.
|
|
// BOOL fGetSACL - Should we get the SACL?
|
|
//
|
|
// Outputs:
|
|
// None.
|
|
//
|
|
// Returns:
|
|
// None.
|
|
//
|
|
// Comments:
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
CSecureKernelObj::CSecureKernelObj(
|
|
HANDLE hObject,
|
|
BOOL fGetSACL /*= TRUE*/ )
|
|
: CSecurityDescriptor()
|
|
{
|
|
SetObject(hObject, fGetSACL);
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CSecureKernelObj::CSecureKernelObj
|
|
//
|
|
// Alternate Class CTOR
|
|
//
|
|
// Inputs:
|
|
// LPCWSTR wszObjName - The object name to handle
|
|
// security for.
|
|
//
|
|
// PSECURITY_DESCRIPTOR pSD - The Security Descriptor to associate with this object
|
|
//
|
|
// Outputs:
|
|
// None.
|
|
//
|
|
// Returns:
|
|
// None.
|
|
//
|
|
// Comments:
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
CSecureKernelObj::CSecureKernelObj(
|
|
HANDLE hObject,
|
|
PSECURITY_DESCRIPTOR pSD)
|
|
: CSecurityDescriptor()
|
|
{
|
|
if(InitSecurity(pSD))
|
|
{
|
|
// we just get a copy - we don't take ownership.
|
|
m_hObject = hObject;
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CSecureKernelObj::~CSecureKernelObj
|
|
//
|
|
// Class Destructor.
|
|
//
|
|
// Inputs:
|
|
// None.
|
|
//
|
|
// Outputs:
|
|
// None.
|
|
//
|
|
// Returns:
|
|
// None.
|
|
//
|
|
// Comments:
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
CSecureKernelObj::~CSecureKernelObj(void)
|
|
{
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CSecureKernelObj::SetObject
|
|
//
|
|
// Public Entry point to set which object this instance
|
|
// of the class is to supply security for.
|
|
//
|
|
// Inputs:
|
|
// HANDLE hObject - The object to handle
|
|
// security for.
|
|
// BOOL fGetSACL - Should we get the SACL?
|
|
//
|
|
// Outputs:
|
|
// None.
|
|
//
|
|
// Returns:
|
|
// DWORD ERROR_SUCCESS if successful
|
|
//
|
|
// Comments:
|
|
//
|
|
// This will clear any previously set filenames and/or security
|
|
// information.
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
DWORD CSecureKernelObj::SetObject(
|
|
HANDLE hObject,
|
|
BOOL fGetSACL /*= TRUE*/ )
|
|
{
|
|
DWORD dwError = ERROR_SUCCESS;
|
|
SECURITY_INFORMATION siFlags = OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
|
|
|
|
|
|
// We must have the security privilege enabled in order to access the object's SACL
|
|
CTokenPrivilege securityPrivilege( SE_SECURITY_NAME );
|
|
BOOL fDisablePrivilege = FALSE;
|
|
|
|
if ( fGetSACL )
|
|
{
|
|
fDisablePrivilege = (securityPrivilege.Enable() == ERROR_SUCCESS);
|
|
siFlags |= SACL_SECURITY_INFORMATION;
|
|
}
|
|
|
|
|
|
// Determine the length needed for self-relative SD
|
|
DWORD dwLengthNeeded = 0;
|
|
|
|
BOOL fSuccess = ::GetKernelObjectSecurity(
|
|
hObject,
|
|
siFlags,
|
|
NULL,
|
|
0,
|
|
&dwLengthNeeded);
|
|
|
|
dwError = ::GetLastError();
|
|
|
|
// It is possible that the user lacked the permissions required to obtain the SACL,
|
|
// even though we set the token's SE_SECURITY_NAME privilege. So if we obtained an
|
|
// access denied error, try it again, this time without requesting the SACL.
|
|
if(dwError == ERROR_ACCESS_DENIED || dwError == ERROR_PRIVILEGE_NOT_HELD)
|
|
{
|
|
siFlags = OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
|
|
fSuccess = ::GetKernelObjectSecurity(
|
|
hObject,
|
|
siFlags,
|
|
NULL,
|
|
0,
|
|
&dwLengthNeeded);
|
|
|
|
dwError = ::GetLastError();
|
|
}
|
|
|
|
// The only expected error at this point is insuficient buffer
|
|
if(!fSuccess && ERROR_INSUFFICIENT_BUFFER == dwError)
|
|
{
|
|
PSECURITY_DESCRIPTOR pSD = NULL;
|
|
try
|
|
{
|
|
pSD = new BYTE[dwLengthNeeded];
|
|
if(pSD)
|
|
{
|
|
// Now obtain security descriptor
|
|
if(::GetKernelObjectSecurity(
|
|
hObject,
|
|
siFlags,
|
|
pSD,
|
|
dwLengthNeeded,
|
|
&dwLengthNeeded))
|
|
{
|
|
|
|
dwError = ERROR_SUCCESS;
|
|
|
|
if(InitSecurity(pSD))
|
|
{
|
|
m_hObject = hObject;
|
|
}
|
|
else
|
|
{
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwError = ::GetLastError();
|
|
}
|
|
|
|
// free up the security descriptor
|
|
delete pSD;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
delete pSD;
|
|
throw;
|
|
}
|
|
|
|
}
|
|
|
|
// Cleanup the Name Privilege as necessary.
|
|
if(fDisablePrivilege)
|
|
{
|
|
securityPrivilege.Enable(FALSE);
|
|
}
|
|
|
|
return dwError;
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CSecureKernelObj::WriteAcls
|
|
//
|
|
// Protected entry point called by CSecurityDescriptor when
|
|
// a user Applies Security and wants to apply security for
|
|
// the DACL and/or SACL.
|
|
//
|
|
// Inputs:
|
|
// PSECURITY_DESCRIPTOR pAbsoluteSD - Security
|
|
// descriptor to apply to
|
|
// the object.
|
|
// SECURITY_INFORMATION securityinfo - Flags
|
|
// indicating which ACL(s)
|
|
// to set.
|
|
//
|
|
// Outputs:
|
|
// None.
|
|
//
|
|
// Returns:
|
|
// DWORD ERROR_SUCCESS if successful
|
|
//
|
|
// Comments:
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
DWORD CSecureKernelObj::WriteAcls(
|
|
PSECURITY_DESCRIPTOR pAbsoluteSD,
|
|
SECURITY_INFORMATION securityinfo)
|
|
{
|
|
DWORD dwError = ERROR_SUCCESS;
|
|
|
|
// We must have the security privilege enabled in order to access the object's SACL
|
|
CTokenPrivilege securityPrivilege( SE_SECURITY_NAME );
|
|
BOOL fDisablePrivilege = FALSE;
|
|
|
|
if(securityinfo & SACL_SECURITY_INFORMATION ||
|
|
securityinfo & PROTECTED_SACL_SECURITY_INFORMATION ||
|
|
securityinfo & UNPROTECTED_SACL_SECURITY_INFORMATION)
|
|
{
|
|
fDisablePrivilege = (securityPrivilege.Enable() == ERROR_SUCCESS);
|
|
}
|
|
|
|
if(!::SetKernelObjectSecurity(
|
|
m_hObject,
|
|
securityinfo,
|
|
pAbsoluteSD))
|
|
{
|
|
dwError = ::GetLastError();
|
|
}
|
|
|
|
|
|
// Cleanup the Name Privilege as necessary.
|
|
if(fDisablePrivilege)
|
|
{
|
|
securityPrivilege.Enable(FALSE);
|
|
}
|
|
|
|
return dwError;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function: CSecureKernelObj::WriteOwner
|
|
//
|
|
// Protected entry point called by CSecurityDescriptor when
|
|
// a user Applies Security and wants to apply security for
|
|
// the owner.
|
|
//
|
|
// Inputs:
|
|
// PSECURITY_DESCRIPTOR pAbsoluteSD - Security
|
|
// descriptor to apply to
|
|
// the object.
|
|
//
|
|
// Outputs:
|
|
// None.
|
|
//
|
|
// Returns:
|
|
// DWORD ERROR_SUCCESS if successful
|
|
//
|
|
// Comments:
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
DWORD CSecureKernelObj::WriteOwner(PSECURITY_DESCRIPTOR pAbsoluteSD)
|
|
{
|
|
DWORD dwError = ERROR_SUCCESS;
|
|
|
|
// Open with the appropriate access, set the security and leave
|
|
if(!::SetKernelObjectSecurity(
|
|
m_hObject,
|
|
OWNER_SECURITY_INFORMATION,
|
|
pAbsoluteSD))
|
|
{
|
|
dwError = ::GetLastError();
|
|
}
|
|
|
|
return dwError;
|
|
}
|
|
|
|
|
|
|
|
DWORD CSecureKernelObj::AllAccessMask(void)
|
|
{
|
|
// File specific All Access Mask
|
|
return TOKEN_ALL_ACCESS;
|
|
}
|