Leaked source code of windows server 2003
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

/*****************************************************************************/
/* 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;
}