Click here to Skip to main content
15,893,663 members
Articles / Programming Languages / C++

Low-level Security Classes

Rate me:
Please Sign up or sign in to vote.
4.73/5 (13 votes)
1 Mar 2000 147.1K   2.4K   31  
A set of classes to encapsulate the Win32 Security APIs
// secdesc.cpp
//
// Wrapper classes for the Win32 low-level security APIs.
// (C) 1999 Peter Kenyon <Peter@bizinf.co.nz>
//
//////////////////////////////////////////////////////////////////////

#include "secdesc.h"

// CAcl
CAcl::CAcl()
{
	m_pACL = NULL;
}

// Allocates and initializes an empty ACL.
// Use the helper function GetLengthAcl to calculate the size needed
// eg:		GetLengthAcl(3, pSids, sizeof(ACCESS_DENIED_ACE));
BOOL CAcl::InitializeAcl(DWORD nAclLength)
{ 
	if(m_pACL)
		::LocalFree(m_pACL);

	m_pACL = (PACL) LocalAlloc(LMEM_FIXED, nAclLength);

	if(!m_pACL)
		return FALSE;

	return ::InitializeAcl(m_pACL, nAclLength, ACL_REVISION); 
}

CAcl::~CAcl()
{
	::LocalFree(m_pACL);
}

// Re-allocates an ACL and merges it with an array of EXPLICIT_ACCESS entries
DWORD CAcl::SetEntriesInAcl(ULONG cCountOfExplicitEntries, PEXPLICIT_ACCESS pListOfExplicitEntries)
{
	PACL paclNew;
	DWORD dwRes = ::SetEntriesInAcl(cCountOfExplicitEntries, pListOfExplicitEntries, m_pACL, &paclNew);

	if(dwRes == ERROR_SUCCESS)
	{
		::LocalFree(m_pACL);
		m_pACL = paclNew;
	}

	return dwRes;
}

// CSid
CSid::CSid()
{
	m_pSid = NULL;
	m_dwSidSize = 0;
	m_bSystemAllocated = FALSE;
}

CSid::CSid(WELLKNOWN_SID_TYPE type)
{
	m_pSid = NULL;
	m_dwSidSize = 0;
	m_bSystemAllocated = FALSE;

	switch(type)
	{
	case WST_NULL:
		CreateNullSid();
		break;

	case WST_EVERYONE:
		CreateEveryoneSid();
		break;
		
	case WST_CREATOROWNER:
		CreateCreatorOwnerSid();
		break;

	case WST_CREATORGROUP:
		CreateCreatorGroupSid();
		break;

	case WST_INTERACTIVE:
		CreateInteractiveUserSid();
		break;

	case WST_LOCALUSERS:
		CreateLocalUserSid();
		break;

	case WST_LOCALADMINS:
		CreateLocalAdminSid();
		break;

	case WST_LOCALGUESTS:
		CreateLocalGuestSid();
		break;

	case WST_LOCALPOWERUSERS:
		CreateLocalPowerUserSid();
		break;

	}
}

CSid::~CSid()
{
	FreeSid();
}

BOOL CSid::LookupAccountName(
							 LPCTSTR lpSystemName, 
							 LPCTSTR lpAccountName, 
							 LPTSTR lpReferencedDomainName, 
							 LPDWORD cbReferencedDomainName, 
							 PSID_NAME_USE peUse)
{
	// Retrieves the SID for the specified account name.

	return ::LookupAccountName(
			lpSystemName,
			lpAccountName,
			m_pSid,
			&m_dwSidSize,
			lpReferencedDomainName,
			cbReferencedDomainName,
			peUse);
}


void CSid::FromSid(PSID pSid)
{
	FreeSid();

	m_pSid = pSid;
}

void CSid::FreeSid()
{
	if(m_pSid)
	{
		if(m_bSystemAllocated)
			::FreeSid(m_pSid);
		else
			delete m_pSid;
	}
}

// Allocates a SID but does not initialize it.
void CSid::AllocateSid(DWORD dwSize)
{
	FreeSid();

	char * pNewBuffer = new char[dwSize];
	
	if(pNewBuffer)
	{
		m_pSid = (PSID)pNewBuffer;
		m_dwSidSize = dwSize;
	}
	else
		m_dwSidSize = 0;

	m_bSystemAllocated = FALSE;
	
}

// Creates a SID representing anybody who is a member of the built-in
// Administrators group on the local computer.
BOOL CSid::CreateLocalAdminSid()
{
	SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
	return AllocateAndInitializeSid(
		&sidAuth,
		2,
        SECURITY_BUILTIN_DOMAIN_RID,
        DOMAIN_ALIAS_RID_ADMINS,
        0, 0, 0, 0, 0, 0);
}

// Creates a SID representing all users on the local machine
BOOL CSid::CreateLocalUserSid()
{
	SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
	return AllocateAndInitializeSid(
		&sidAuth,
		2,
        SECURITY_BUILTIN_DOMAIN_RID,
        DOMAIN_ALIAS_RID_USERS,
        0, 0, 0, 0, 0, 0);
}

// Creates a SID representing all users everywhere.
BOOL CSid::CreateEveryoneSid()
{
	SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_WORLD_SID_AUTHORITY;
	return AllocateAndInitializeSid(
		&sidAuth,
		1,
        SECURITY_WORLD_RID,
        0, 0, 0, 0, 0, 0, 0);
}

// Creates a SID with no members
BOOL CSid::CreateNullSid()
{
	SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NULL_SID_AUTHORITY;
	return AllocateAndInitializeSid(
		&sidAuth,
		1,
        SECURITY_NULL_RID,
        0, 0, 0, 0, 0, 0, 0);
}

// Creates a SID representing the user who created an object
BOOL CSid::CreateCreatorOwnerSid()
{
	SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_CREATOR_SID_AUTHORITY;
	return AllocateAndInitializeSid(
		&sidAuth,
		1,
        SECURITY_CREATOR_OWNER_RID,
        0, 0, 0, 0, 0, 0, 0);
}

// Creates a SID representing the group the user who who created an 
// object belongs to.
BOOL CSid::CreateCreatorGroupSid()
{
	SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_CREATOR_SID_AUTHORITY;
	return AllocateAndInitializeSid(
		&sidAuth,
		1,
        SECURITY_CREATOR_GROUP_RID,
        0, 0, 0, 0, 0, 0, 0);
}

// Creates a SID representing the built-in Guests group.
BOOL CSid::CreateLocalGuestSid()
{
	SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
	return AllocateAndInitializeSid(
		&sidAuth,
		2,
        SECURITY_BUILTIN_DOMAIN_RID,
        DOMAIN_ALIAS_RID_GUESTS,
        0, 0, 0, 0, 0, 0);
}

// A Power User is a user who "expects to treat a system as if it 	
// were their personal computer rather than as a workstation for 
// multiple users" - Platform SDK
BOOL CSid::CreateLocalPowerUserSid()
{
	SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
	return AllocateAndInitializeSid(
		&sidAuth,
		2,
        SECURITY_BUILTIN_DOMAIN_RID,
        DOMAIN_ALIAS_RID_POWER_USERS,
        0, 0, 0, 0, 0, 0);
}

// This SID represents any user physically logged into the current workstation.
// Can be used to grant access to logged-on users as opposed to users
// accessing data across the network.
BOOL CSid::CreateInteractiveUserSid()
{
	SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
	return AllocateAndInitializeSid(
		&sidAuth,
		1,
        SECURITY_INTERACTIVE_RID,
        0, 0, 0, 0, 0, 0, 0);
}

// CSecurityDescriptor
CSecurityDescriptor::CSecurityDescriptor()
{
	m_pSD = (PSECURITY_DESCRIPTOR) new char[SECURITY_DESCRIPTOR_MIN_LENGTH];
	
	if(m_pSD)
		::InitializeSecurityDescriptor(m_pSD, SECURITY_DESCRIPTOR_REVISION);
}

CSecurityDescriptor::CSecurityDescriptor(PSECURITY_DESCRIPTOR pSD)
{
	m_pSD = pSD;
}

CSecurityDescriptor::~CSecurityDescriptor()
{
	delete m_pSD;
}

// Calculates the size needed for an ACL, given
// an array of SIDs and the size of an ACE type.
int GetLengthAcl(int nAceCount, PSID pAceSid[], size_t sizeAce)
{
	int cbAcl = sizeof (ACL);
	for (int i = 0 ; i < nAceCount ; i++) 
	{
		// subtract ACE.SidStart from the size
		int cbAce = sizeAce - sizeof(DWORD);
		// add this ACE's SID length
		cbAce += ::GetLengthSid(pAceSid[i]);
		// add the length of each ACE to the total ACL length
		cbAcl += cbAce;
	}

	return cbAcl;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
New Zealand New Zealand
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions