windows-nt/Source/XPSP1/NT/inetsrv/query/cifrmwrk/dll/secutil.cxx
2020-09-26 16:20:57 +08:00

348 lines
12 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998 - 1999.
//
// File: secutil.cxx
//
// Contents: security utility routines
//
// History: 10-April-98 dlee Created from 4 other copies in NT
//
//--------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include "secutil.hxx"
//+-------------------------------------------------------------------------
//
// Function: InitAllowedAce
//
// Synopsis: Assignes the ACE values into the allowed ACE
//
// Arguments: [pAllowedAce] - Supplies a pointer to the ACE that is
// initialized.
// [AceSize] - Supplies the size of the ACE in bytes.
// [InheritFlags] - Supplies ACE inherit flags.
// [AceFlags] - Supplies ACE type specific control flags.
// [Mask] - Supplies the allowed access masks.
// [pAllowedSid] - Supplies the pointer to the SID of user/
// group which is allowed the specified access.
//
// History: 10-April-98 dlee Stole from 4 other places in NT
//
//--------------------------------------------------------------------------
void InitAllowedAce(
ACCESS_ALLOWED_ACE * pAllowedAce,
USHORT AceSize,
BYTE InheritFlags,
BYTE AceFlags,
ACCESS_MASK Mask,
SID * pAllowedSid )
{
pAllowedAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
pAllowedAce->Header.AceSize = AceSize;
pAllowedAce->Header.AceFlags = AceFlags | InheritFlags;
pAllowedAce->Mask = Mask;
if ( !CopySid( GetLengthSid( pAllowedSid ),
&(pAllowedAce->SidStart),
pAllowedSid ) )
THROW( CException() );
} //InitAllowedAce
//+-------------------------------------------------------------------------
//
// Function: InitDeniedAce
//
// Synopsis: Assignes the ACE values into the denied ACE
//
// Arguments: [pDeniedAce] - Supplies a pointer to the ACE that is
// initialized.
// [AceSize] - Supplies the size of the ACE in bytes.
// [InheritFlags] - Supplies ACE inherit flags.
// [AceFlags] - Supplies ACE type specific control flags.
// [Mask] - Supplies the allowed access masks.
// [pDeniedSid] - Supplies the pointer to the SID of user/
// group which is denied the specified access.
//
// History: 10-April-98 dlee Stole from 4 other places in NT
//
//--------------------------------------------------------------------------
void InitDeniedAce(
ACCESS_DENIED_ACE * pDeniedAce,
USHORT AceSize,
BYTE InheritFlags,
BYTE AceFlags,
ACCESS_MASK Mask,
SID * pDeniedSid )
{
pDeniedAce->Header.AceType = ACCESS_DENIED_ACE_TYPE;
pDeniedAce->Header.AceSize = AceSize;
pDeniedAce->Header.AceFlags = AceFlags | InheritFlags;
pDeniedAce->Mask = Mask;
if( !CopySid( GetLengthSid( pDeniedSid ),
&(pDeniedAce->SidStart),
pDeniedSid ) )
THROW( CException() );
} //InitDeniedAce
//+-------------------------------------------------------------------------
//
// Function: InitAuditAce
//
// Synopsis: Assignes the ACE values into the audit ACE
//
// Arguments: [pAuditAce] - Supplies a pointer to the ACE that is
// initialized.
// [AceSize] - Supplies the size of the ACE in bytes.
// [InheritFlags] - Supplies ACE inherit flags.
// [AceFlags] - Supplies ACE type specific control flags.
// [Mask] - Supplies the allowed access masks.
// [pAuditSid] - Supplies the pointer to the SID of user/
// group which is audited
//
// History: 10-April-98 dlee Stole from 4 other places in NT
//
//--------------------------------------------------------------------------
void InitAuditAce(
ACCESS_ALLOWED_ACE * pAuditAce,
USHORT AceSize,
BYTE InheritFlags,
BYTE AceFlags,
ACCESS_MASK Mask,
SID * pAuditSid )
{
pAuditAce->Header.AceType = SYSTEM_AUDIT_ACE_TYPE;
pAuditAce->Header.AceSize = AceSize;
pAuditAce->Header.AceFlags = AceFlags | InheritFlags;
pAuditAce->Mask = Mask;
if ( !CopySid( GetLengthSid( pAuditSid ),
&(pAuditAce->SidStart),
pAuditSid ) )
THROW( CException() );
} //InitAuditAce
//+-------------------------------------------------------------------------
//
// Function: CiCreateSecurityDescriptor
//
// Synopsis: Creates a security descriptor from input data
//
// Arguments: [pAceData] - Array of input data
// [cAces] - Count of items in pAceData
// [OwnerSid] - 0 or the owner of the descriptor
// [GroupSid] - 0 or group of the descriptor
// [xAcls] - Resulting absolute SECURITY_DESCRIPTOR,
// allocated to the required size.
//
// History: 10-April-98 dlee Stole from 4 other places in NT
//
//--------------------------------------------------------------------------
void CiCreateSecurityDescriptor( ACE_DATA const * const pAceData,
ULONG cAces,
SID * pOwnerSid,
SID * pGroupSid,
XArray<BYTE> & xAcls )
{
//
// This function returns a pointer to memory dynamically allocated to
// hold the absolute security descriptor, the DACL, the SACL, and all
// the ACEs:
//
// +---------------------------------------------------------------+
// | Security Descriptor |
// +-------------------------------+-------+---------------+-------+
// | DACL | ACE 1 | . . . | ACE n |
// +-------------------------------+-------+---------------+-------+
// | SACL | ACE 1 | . . . | ACE n |
// +-------------------------------+-------+---------------+-------+
//
DWORD cbDacl = sizeof ACL;
DWORD cbSacl = sizeof ACL;
DWORD cbMaxAce = 0;
//
// Compute the total size of the DACL and SACL ACEs and the maximum
// size of any ACE.
//
for ( DWORD i = 0; i < cAces; i++ )
{
DWORD cbAce = GetLengthSid( pAceData[i].pSid );
switch (pAceData[i].AceType)
{
case ACCESS_ALLOWED_ACE_TYPE:
cbAce += sizeof ACCESS_ALLOWED_ACE;
cbDacl += cbAce;
break;
case ACCESS_DENIED_ACE_TYPE:
cbAce += sizeof ACCESS_DENIED_ACE;
cbDacl += cbAce;
break;
case SYSTEM_AUDIT_ACE_TYPE:
cbAce += sizeof SYSTEM_AUDIT_ACE;
cbSacl += cbAce;
break;
default:
Win4Assert( FALSE );
}
cbMaxAce = __max( cbMaxAce, cbAce );
}
//
// Allocate a chunk of memory large enough the security descriptor
// the DACL, the SACL and all ACEs.
// A security descriptor is of opaque data type but
// SECURITY_DESCRIPTOR_MIN_LENGTH is the right size.
//
DWORD cbTotal = SECURITY_DESCRIPTOR_MIN_LENGTH;
if ( cbDacl != sizeof ACL )
cbTotal += cbDacl;
if ( cbSacl != sizeof ACL )
cbTotal += cbSacl;
xAcls.Init( cbTotal );
SECURITY_DESCRIPTOR *pAbsoluteSd = (SECURITY_DESCRIPTOR *) xAcls.Get();
//
// Initialize the Dacl and Sacl
//
BYTE *pbCurrent = (BYTE *) pAbsoluteSd + SECURITY_DESCRIPTOR_MIN_LENGTH;
ACL *pDacl = 0; // Pointer to the DACL portion of above buffer
ACL *pSacl = 0; // Pointer to the SACL portion of above buffer
if ( sizeof ACL != cbDacl )
{
pDacl = (ACL *) pbCurrent;
pbCurrent += cbDacl;
if( !InitializeAcl( pDacl, cbDacl, ACL_REVISION ) )
THROW( CException() );
}
if ( sizeof ACL != cbSacl )
{
pSacl = (ACL *) pbCurrent;
pbCurrent += cbSacl;
if ( !InitializeAcl( pSacl, cbSacl, ACL_REVISION ) )
THROW( CException() );
}
//
// Allocate a temporary buffer big enough for the biggest ACE.
// This is usually pretty small
//
XGrowable<BYTE> xMaxAce( cbMaxAce );
//
// Initialize each ACE, and append it into the end of the DACL or SACL.
//
for ( i = 0; i < cAces; i++ )
{
DWORD cbAce = GetLengthSid( pAceData[i].pSid );
ACL *pCurrentAcl;
switch (pAceData[i].AceType)
{
case ACCESS_ALLOWED_ACE_TYPE:
cbAce += sizeof ACCESS_ALLOWED_ACE;
pCurrentAcl = pDacl;
InitAllowedAce( (ACCESS_ALLOWED_ACE *) xMaxAce.Get(),
(USHORT) cbAce,
pAceData[i].InheritFlags,
pAceData[i].AceFlags,
pAceData[i].Mask,
pAceData[i].pSid );
break;
case ACCESS_DENIED_ACE_TYPE:
cbAce += sizeof ACCESS_DENIED_ACE;
pCurrentAcl = pDacl;
InitDeniedAce( (ACCESS_DENIED_ACE *) xMaxAce.Get(),
(USHORT) cbAce,
pAceData[i].InheritFlags,
pAceData[i].AceFlags,
pAceData[i].Mask,
pAceData[i].pSid );
break;
case SYSTEM_AUDIT_ACE_TYPE:
cbAce += sizeof SYSTEM_AUDIT_ACE;
pCurrentAcl = pSacl;
// Audit uses ACCESS_ALLOWED_ACE
InitAuditAce( (ACCESS_ALLOWED_ACE *) xMaxAce.Get(),
(USHORT) cbAce,
pAceData[i].InheritFlags,
pAceData[i].AceFlags,
pAceData[i].Mask,
pAceData[i].pSid );
break;
}
//
// Append the initialized ACE to the end of DACL or SACL
//
if ( !AddAce( pCurrentAcl,
ACL_REVISION,
MAXULONG,
xMaxAce.Get(),
cbAce ) )
THROW( CException() );
}
//
// Create the security descriptor with absolute pointers to SIDs
// and ACLs.
//
// Owner = pOwnerSid
// Group = pGroupSid
// Dacl = Dacl
// Sacl = Sacl
//
if ( !InitializeSecurityDescriptor( pAbsoluteSd,
SECURITY_DESCRIPTOR_REVISION ) ||
!SetSecurityDescriptorOwner( pAbsoluteSd,
pOwnerSid,
FALSE ) ||
!SetSecurityDescriptorGroup( pAbsoluteSd,
pGroupSid,
FALSE ) ||
!SetSecurityDescriptorDacl( pAbsoluteSd,
TRUE,
pDacl,
FALSE ) ||
!SetSecurityDescriptorSacl( pAbsoluteSd,
FALSE,
pSacl,
FALSE ) )
THROW( CException() );
} //CiCreateSecurityDescriptor