NT4/private/ole32/com/rot/access.cxx
2020-09-30 17:12:29 +02:00

294 lines
7.9 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1993.
//
// File: access.cxx
//
// Contents: Methods used for building a security descriptor.
//
// History: 02-May-94 DonnaLi Created
//
//--------------------------------------------------------------------------
extern "C"
{
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntseapi.h>
}
#include <rpc.h>
#include <windows.h>
#include <except.hxx>
#include <ole2.h>
#include <memapi.hxx>
#include <access.hxx>
extern PSID psidMySid;
//+-------------------------------------------------------------------------
//
// Member: CAccessInfo::~CAccessInfo
//
// Synopsis: Clean up buffers allocated for building the security
// descriptor
//
// History: 08-Jun-94 DonnaLi Created
//
//--------------------------------------------------------------------------
CAccessInfo::~CAccessInfo (
void
)
{
if (_pAbsoluteSdBuffer != NULL)
{
PrivMemFree (_pAbsoluteSdBuffer);
}
if (_pDace != NULL && _pDace != (PACCESS_ALLOWED_ACE)&_aDace[0])
{
PrivMemFree (_pDace);
}
}
//+-------------------------------------------------------------------------
//
// Member: CAccessInfo::IdentifyAccess
//
// Synopsis: Build a security descriptor that identifies who has what
// access
//
// Arguments: [fScmIsOwner] - whether SCM is the owner
// [AppAccessMask] - access mask for the OLE application
// [ScmAccessMask] - access mask for the SCM
//
// Returns: NULL - an error has occurred
// ~NULL - pointer to the resulting security descriptor
//
// History: 08-Jun-94 DonnaLi Created
//
//--------------------------------------------------------------------------
PSECURITY_DESCRIPTOR
CAccessInfo::IdentifyAccess (
BOOL fScmIsOwner,
ACCESS_MASK AppAccessMask,
ACCESS_MASK ScmAccessMask
)
{
NTSTATUS NtStatus;
//
// Pointer to memory dynamically allocated by this routine to hold
// the absolute security descriptor, the DACL, the SACL, and all the ACEs.
//
//
// A security descriptor is of opaque data type but
// SECURITY_DESCRIPTOR_MIN_LENGTH is the right size.
//
DWORD dwAbsoluteSdLength = SECURITY_DESCRIPTOR_MIN_LENGTH;
PACL lpDacl = NULL; // Pointer to DACL portion of sid buffer
ULONG dwSize;
ULONG dwAppSid;
ULONG dwScmSid;
//
// Compute the total size of the DACL and SACL ACEs and the maximum
// size of any ACE.
//
dwAppSid = RtlLengthSid (_pAppSid);
dwScmSid = RtlLengthSid (psidMySid);
dwSize = sizeof(ACL) +
dwAppSid +
dwScmSid +
2 * sizeof(ACCESS_ALLOWED_ACE);
dwAbsoluteSdLength += dwSize;
_pAbsoluteSdBuffer = (PSECURITY_DESCRIPTOR) PrivMemAlloc (
dwAbsoluteSdLength
);
if (_pAbsoluteSdBuffer == NULL)
{
return NULL;
}
//
// Initialize the Dacl and Sacl
//
lpDacl = (PACL)((PCHAR)_pAbsoluteSdBuffer + SECURITY_DESCRIPTOR_MIN_LENGTH);
NtStatus = RtlCreateAcl (lpDacl, dwSize, ACL_REVISION);
if (!NT_SUCCESS(NtStatus))
{
return NULL;
}
//
// Get a buffer big enough for the biggest ACE.
//
dwSize = max(dwAppSid, dwScmSid) + sizeof(ACCESS_ALLOWED_ACE);
if (dwSize <= DACE_BUFFER_LENGTH)
{
_pDace = (PACCESS_ALLOWED_ACE)&_aDace[0];
}
else
{
_pDace = (PACCESS_ALLOWED_ACE) PrivMemAlloc (dwSize);
if (_pDace == NULL)
{
return NULL;
}
}
//
// Initialize each ACE, and append it onto the end of the DACL.
//
_pDace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
_pDace->Header.AceSize = (USHORT)(dwAppSid + sizeof(ACCESS_ALLOWED_ACE));
_pDace->Header.AceFlags = 0;
_pDace->Mask = AppAccessMask;
NtStatus = RtlCopySid (
dwAppSid, // ULONG DestinationSidLength
&(_pDace->SidStart), // PSID DestinationSid
_pAppSid // PSID SourceSid
);
if (!NT_SUCCESS(NtStatus))
{
return NULL;
}
NtStatus = RtlAddAce(
lpDacl, // PACL Acl
ACL_REVISION, // ULONG AceRevision
MAXULONG, // ULONG StartingAceIndex
_pDace, // PVOID AceList
dwAppSid + sizeof(ACCESS_ALLOWED_ACE) // ULONG AceListLength
);
if (!NT_SUCCESS(NtStatus))
{
return NULL;
}
_pDace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
_pDace->Header.AceSize = (USHORT)(dwScmSid + sizeof(ACCESS_ALLOWED_ACE));
_pDace->Header.AceFlags = 0;
_pDace->Mask = ScmAccessMask;
NtStatus = RtlCopySid (
dwScmSid, // ULONG DestinationSidLength
&(_pDace->SidStart), // PSID DestinationSid
psidMySid // PSID SourceSid
);
if (!NT_SUCCESS(NtStatus))
{
return NULL;
}
NtStatus = RtlAddAce(
lpDacl, // PACL Acl
ACL_REVISION, // ULONG AceRevision
MAXULONG, // ULONG StartingAceIndex
_pDace, // PVOID AceList
dwScmSid + sizeof(ACCESS_ALLOWED_ACE) // ULONG AceListLength
);
if (!NT_SUCCESS(NtStatus))
{
return NULL;
}
//
// Create the security descriptor with absolute pointers to SIDs
// and ACLs.
//
// Owner = Sid of SCM
// Group = Sid of SCM
// Dacl = lpDacl
// Sacl = nothing
//
NtStatus = RtlCreateSecurityDescriptor (
_pAbsoluteSdBuffer, // PSECURITY_DESCRIPTOR SecurityDescriptor
SECURITY_DESCRIPTOR_REVISION // ULONG Revision
);
if (!NT_SUCCESS(NtStatus))
{
return NULL;
}
if (fScmIsOwner)
{
NtStatus = RtlSetOwnerSecurityDescriptor (
_pAbsoluteSdBuffer, // PSECURITY_DESCRIPTOR SecurityDescriptor
psidMySid, // PSID Owner
FALSE // BOOLEAN OwnerDefaulted
);
if (!NT_SUCCESS(NtStatus))
{
return NULL;
}
NtStatus = RtlSetGroupSecurityDescriptor (
_pAbsoluteSdBuffer, // PSECURITY_DESCRIPTOR SecurityDescriptor
psidMySid, // PSID Group
FALSE // BOOLEAN GroupDefaulted
);
if (!NT_SUCCESS(NtStatus))
{
return NULL;
}
}
NtStatus = RtlSetDaclSecurityDescriptor (
_pAbsoluteSdBuffer, // PSECURITY_DESCRIPTOR SecurityDescriptor
TRUE, // BOOLEAN DaclPresent
lpDacl, // PACL Dacl
FALSE // BOOLEAN DaclDefaulted
);
if (!NT_SUCCESS(NtStatus))
{
return NULL;
}
NtStatus = RtlSetSaclSecurityDescriptor (
_pAbsoluteSdBuffer, // PSECURITY_DESCRIPTOR SecurityDescriptor
FALSE, // BOOLEAN SaclPresent
NULL, // PACL Sacl
FALSE // BOOLEAN SaclDefaulted
);
if (!NT_SUCCESS(NtStatus))
{
return NULL;
}
return _pAbsoluteSdBuffer;
}