reactos/rosapps/sysutils/regexpl/SecurityDescriptor.cpp
2001-07-14 07:01:38 +00:00

331 lines
8.9 KiB
C++

/* $Id: SecurityDescriptor.cpp,v 1.5 2001/07/14 07:01:38 narnaoud Exp $
*
* regexpl - Console Registry Explorer
*
* Copyright (C) 2000,2001 Nedko Arnaoudov <nedkohome@atia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
// SecurityDescriptor.cpp: implementation of the CSecurityDescriptor class.
//
//////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <assert.h>
#include <tchar.h>
#include "SecurityDescriptor.h"
#define ASSERT assert
// *** THIS SHOULD GO IN A MINGW/ROS HEADER - Begin
#if 1
//#define SID_REVISION (1) // Current revision level
//typedef struct _ACE_HEADER {
// BYTE AceType;
// BYTE AceFlags;
// WORD AceSize;
//} ACE_HEADER;
typedef ACE_HEADER * PACE_HEADER;
//#define ACCESS_ALLOWED_ACE_TYPE (0x0)
//#define ACCESS_DENIED_ACE_TYPE (0x1)
//#define SYSTEM_AUDIT_ACE_TYPE (0x2)
//#define SYSTEM_ALARM_ACE_TYPE (0x3)
//#define OBJECT_INHERIT_ACE (0x1)
//#define CONTAINER_INHERIT_ACE (0x2)
//#define NO_PROPAGATE_INHERIT_ACE (0x4)
//#define INHERIT_ONLY_ACE (0x8)
//#define VALID_INHERIT_FLAGS (0xF)
//#define SUCCESSFUL_ACCESS_ACE_FLAG (0x40)
//#define FAILED_ACCESS_ACE_FLAG (0x80)
//typedef struct _SYSTEM_AUDIT_ACE {
// ACE_HEADER Header;
// ACCESS_MASK Mask;
// DWORD SidStart;
//} SYSTEM_AUDIT_ACE;
#endif
// *** THIS SHOULD GO IN A MINGW/ROS HEADER - End
BOOL GetTextualSid(
PSID pSid, // binary Sid
LPTSTR TextualSid, // buffer for Textual representation of Sid
LPDWORD lpdwBufferLen // required/provided TextualSid buffersize
)
{
PSID_IDENTIFIER_AUTHORITY psia;
DWORD dwSubAuthorities;
DWORD dwSidRev=SID_REVISION;
DWORD dwCounter;
DWORD dwSidSize;
// Validate the binary SID.
if(!IsValidSid(pSid)) return FALSE;
// Get the identifier authority value from the SID.
psia = GetSidIdentifierAuthority(pSid);
// Get the number of subauthorities in the SID.
dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
// Compute the buffer length.
// S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
// Check input buffer length.
// If too small, indicate the proper size and set last error.
if (*lpdwBufferLen < dwSidSize)
{
*lpdwBufferLen = dwSidSize;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
// Add 'S' prefix and revision number to the string.
dwSidSize=wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev );
// Add SID identifier authority to the string.
if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
{
dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
(USHORT)psia->Value[0],
(USHORT)psia->Value[1],
(USHORT)psia->Value[2],
(USHORT)psia->Value[3],
(USHORT)psia->Value[4],
(USHORT)psia->Value[5]);
}
else
{
dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
TEXT("%lu"),
(ULONG)(psia->Value[5] ) +
(ULONG)(psia->Value[4] << 8) +
(ULONG)(psia->Value[3] << 16) +
(ULONG)(psia->Value[2] << 24) );
}
// Add SID subauthorities to the string.
//
for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
{
dwSidSize+=wsprintf(TextualSid + dwSidSize, TEXT("-%lu"),
*GetSidSubAuthority(pSid, dwCounter) );
}
return TRUE;
}
const TCHAR * GetSidTypeName(SID_NAME_USE Use)
{
switch(Use)
{
case SidTypeUser:
return _T("User SID");
case SidTypeGroup:
return _T("Group SID");
case SidTypeDomain:
return _T("Domain SID");
case SidTypeAlias:
return _T("Alias SID");
case SidTypeWellKnownGroup:
return _T("SID for a well-known group");
case SidTypeDeletedAccount:
return _T("SID for a deleted account");
case SidTypeInvalid:
return _T("Invalid SID");
case SidTypeUnknown:
return _T("Unknown SID type");
default:
return _T("Error. Cannot recognize SID type.");
}
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSecurityDescriptor::CSecurityDescriptor()
{
m_pSecurityDescriptor = NULL;
m_pCurrentACEHeader = NULL;
}
CSecurityDescriptor::~CSecurityDescriptor()
{
}
void CSecurityDescriptor::AssociateDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor)
{
m_pSecurityDescriptor = pSecurityDescriptor;
}
DWORD CSecurityDescriptor::BeginDACLInteration()
{
if (!GetSecurityDescriptorDacl(m_pSecurityDescriptor,&m_blnDACLPresent,&m_pDACL,&m_blnDACLDefaulted))
{
throw GetLastError();
}
return ERROR_SUCCESS;
}
BOOL CSecurityDescriptor::DescriptorContainsDACL()
{
return m_blnDACLPresent;
}
DWORD CSecurityDescriptor::BeginSACLInteration()
{
if (!GetSecurityDescriptorSacl(m_pSecurityDescriptor,&m_blnSACLPresent,&m_pSACL,&m_blnSACLDefaulted))
throw GetLastError();
return ERROR_SUCCESS;
}
BOOL CSecurityDescriptor::DescriptorContainsSACL()
{
return m_blnSACLPresent;
}
BOOL CSecurityDescriptor::HasNULLDACL()
{
ASSERT(m_blnDACLPresent);
return (m_pDACL == NULL);
}
BOOL CSecurityDescriptor::HasValidDACL()
{
ASSERT(m_blnDACLPresent);
ASSERT(m_pDACL != NULL);
return IsValidAcl(m_pDACL);
}
BOOL CSecurityDescriptor::HasNULLSACL()
{
ASSERT(m_blnSACLPresent);
return (m_pSACL == NULL);
}
BOOL CSecurityDescriptor::HasValidSACL()
{
ASSERT(m_blnSACLPresent);
ASSERT(m_pSACL != NULL);
return IsValidAcl(m_pSACL);
}
DWORD CSecurityDescriptor::GetDACLEntriesCount()
{
ACL_SIZE_INFORMATION SizeInfo;
if (!GetAclInformation(m_pDACL,&SizeInfo,sizeof(SizeInfo),AclSizeInformation))
throw GetLastError();
return SizeInfo.AceCount;
}
DWORD CSecurityDescriptor::GetSACLEntriesCount()
{
ACL_SIZE_INFORMATION SizeInfo;
if (!GetAclInformation(m_pSACL,&SizeInfo,sizeof(SizeInfo),AclSizeInformation))
throw GetLastError();
return SizeInfo.AceCount;
}
CSecurityDescriptor::ACEntryType CSecurityDescriptor::GetDACLEntry(DWORD nIndex)
{
void *pACE;
if (!GetAce(m_pDACL,nIndex,&pACE)) throw GetLastError();
m_pCurrentACEHeader = (PACE_HEADER)pACE;
if (m_pCurrentACEHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
{
return AccessAlowed;
}
if (m_pCurrentACEHeader->AceType == ACCESS_DENIED_ACE_TYPE)
{
return AccessDenied;
}
return Unknown;
}
CSecurityDescriptor::ACEntryType CSecurityDescriptor::GetSACLEntry(DWORD nIndex, BOOL& blnFailedAccess, BOOL& blnSeccessfulAccess)
{
void *pACE;
if (!GetAce(m_pSACL,nIndex,&pACE)) throw GetLastError();
m_pCurrentACEHeader = (PACE_HEADER)pACE;
if (m_pCurrentACEHeader->AceType == SYSTEM_AUDIT_ACE_TYPE)
{
blnFailedAccess = m_pCurrentACEHeader->AceFlags & FAILED_ACCESS_ACE_FLAG;
blnSeccessfulAccess = m_pCurrentACEHeader->AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG;
return SystemAudit;
}
return Unknown;
}
PSID CSecurityDescriptor::GetCurrentACE_SID()
{
ASSERT(m_pCurrentACEHeader != NULL);
switch(m_pCurrentACEHeader->AceType)
{
case ACCESS_ALLOWED_ACE_TYPE:
return ((PSID)&(((ACCESS_ALLOWED_ACE *)m_pCurrentACEHeader)->SidStart));
case ACCESS_DENIED_ACE_TYPE:
return ((PSID)&(((ACCESS_DENIED_ACE *)m_pCurrentACEHeader)->SidStart));
case SYSTEM_AUDIT_ACE_TYPE:
return ((PSID)&(((SYSTEM_AUDIT_ACE *)m_pCurrentACEHeader)->SidStart));
default:
ASSERT(FALSE); // Do not call this function for unknown ACE types !!!
return NULL;
}
}
void CSecurityDescriptor::GetCurrentACE_AccessMask(DWORD& dwMask)
{
ASSERT(m_pCurrentACEHeader != NULL);
switch(m_pCurrentACEHeader->AceType)
{
case ACCESS_ALLOWED_ACE_TYPE:
dwMask = (((ACCESS_ALLOWED_ACE *)m_pCurrentACEHeader)->Mask);
return;
case ACCESS_DENIED_ACE_TYPE:
dwMask = (((ACCESS_DENIED_ACE *)m_pCurrentACEHeader)->Mask);
return;
case SYSTEM_AUDIT_ACE_TYPE:
dwMask = (((SYSTEM_AUDIT_ACE *)m_pCurrentACEHeader)->Mask);
return;
default:
ASSERT(FALSE); // Do not call this function for unknown ACE types !!!
return;
}
}
void CSecurityDescriptor::GetCurrentACE_Flags(BYTE& bFlags)
{
ASSERT(m_pCurrentACEHeader != NULL);
bFlags = m_pCurrentACEHeader->AceFlags;
}