Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

273 lines
6.5 KiB

/****************************** Module Header ******************************\
* Module Name: secdesc.c
*
* Copyright (c) 1991, Microsoft Corporation
*
* Routines that support creation and deletion of security descriptors
*
* History:
* 02-06-92 Davidc Created.
\***************************************************************************/
#include "sec.h"
//
// Private prototypes
//
PVOID
CreateAccessAllowedAce(
PSID Sid,
ACCESS_MASK AccessMask,
UCHAR AceFlags,
UCHAR InheritFlags
);
VOID
DestroyAce(
PVOID Ace
);
/***************************************************************************\
* CreateSecurityDescriptor
*
* Creates a security descriptor containing an ACL containing the specified ACEs
*
* A SD created with this routine should be destroyed using
* DeleteSecurityDescriptor
*
* Returns a pointer to the security descriptor or NULL on failure.
*
* 02-06-92 Davidc Created.
\***************************************************************************/
PSECURITY_DESCRIPTOR
CreateSecurityDescriptor(
PMYACE MyAce,
ACEINDEX AceCount
)
{
NTSTATUS Status;
ACEINDEX AceIndex;
PACCESS_ALLOWED_ACE *Ace;
PACL Acl = NULL;
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
DWORD LengthAces;
DWORD LengthAcl;
DWORD LengthSd;
//
// Allocate space for the ACE pointer array
//
Ace = (PACCESS_ALLOWED_ACE *)Alloc(sizeof(PACCESS_ALLOWED_ACE) * AceCount);
if (Ace == NULL) {
DbgOnlyPrint("progman failed to allocated ACE array\n\r");
return(NULL);
}
//
// Create the ACEs and calculate total ACE size
//
LengthAces = 0;
for (AceIndex=0; AceIndex < AceCount; AceIndex ++) {
Ace[AceIndex] = CreateAccessAllowedAce(MyAce[AceIndex].Sid,
MyAce[AceIndex].AccessMask,
0,
MyAce[AceIndex].InheritFlags);
if (Ace[AceIndex] == NULL) {
DbgOnlyPrint("progman : Failed to allocate ace\n\r");
} else {
LengthAces += Ace[AceIndex]->Header.AceSize;
}
}
//
// Calculate ACL and SD sizes
//
LengthAcl = sizeof(ACL) + LengthAces;
LengthSd = SECURITY_DESCRIPTOR_MIN_LENGTH;
//
// Create the ACL
//
Acl = Alloc(LengthAcl);
if (Acl != NULL) {
Status = RtlCreateAcl(Acl, LengthAcl, ACL_REVISION);
if (NT_SUCCESS(Status))
{
//
// Add the ACES to the ACL and destroy the ACEs
//
for (AceIndex = 0; AceIndex < AceCount; AceIndex ++) {
if (Ace[AceIndex] != NULL) {
Status = RtlAddAce(Acl, ACL_REVISION, 0, Ace[AceIndex],
Ace[AceIndex]->Header.AceSize);
if (!NT_SUCCESS(Status)) {
DbgOnlyPrint("progman : AddAce failed, status = 0x%lx\n\r", Status);
}
DestroyAce(Ace[AceIndex]);
}
}
}
else
{
Free(Acl);
Acl = NULL;
}
} else {
DbgOnlyPrint("progman : Failed to allocate ACL\n\r");
}
//
// Free the ACE pointer array
//
Free(Ace);
//
// Create the security descriptor
//
SecurityDescriptor = Alloc(LengthSd);
if (SecurityDescriptor != NULL) {
Status = RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
ASSERT(NT_SUCCESS(Status));
//
// Set the DACL on the security descriptor
//
Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, TRUE, Acl, FALSE);
if (!NT_SUCCESS(Status)) {
DbgOnlyPrint("progman : SetDACLSD failed, status = 0x%lx\n\r", Status);
}
} else {
DbgOnlyPrint("progman : Failed to allocate security descriptor\n\r");
}
//
// Return with our spoils
//
return(SecurityDescriptor);
}
/***************************************************************************\
* DeleteSecurityDescriptor
*
* Deletes a security descriptor created using CreateSecurityDescriptor
*
* Returns TRUE on success, FALSE on failure
*
* 02-06-92 Davidc Created.
\***************************************************************************/
BOOL
DeleteSecurityDescriptor(
PSECURITY_DESCRIPTOR SecurityDescriptor
)
{
NTSTATUS Status;
PACL Acl;
BOOLEAN Present;
BOOLEAN Defaulted;
ASSERT(SecurityDescriptor != NULL);
//
// Get the ACL
//
Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
&Present, &Acl, &Defaulted);
if (NT_SUCCESS(Status)) {
//
// Destroy the ACL
//
if (Present && (Acl != NULL)) {
Free(Acl);
}
} else {
DbgOnlyPrint("progman : Failed to get DACL from security descriptor being destroyed, Status = 0x%lx\n\r", Status);
}
//
// Destroy the Security Descriptor
//
Free(SecurityDescriptor);
return(TRUE);
}
/***************************************************************************\
* CreateAccessAllowedAce
*
* Allocates memory for an ACCESS_ALLOWED_ACE and fills it in.
* The memory should be freed by calling DestroyACE.
*
* Returns pointer to ACE on success, NULL on failure
*
* History:
* 12-05-91 Davidc Created
\***************************************************************************/
PVOID
CreateAccessAllowedAce(
PSID Sid,
ACCESS_MASK AccessMask,
UCHAR AceFlags,
UCHAR InheritFlags
)
{
DWORD LengthSid = RtlLengthSid(Sid);
DWORD LengthACE = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + LengthSid;
PACCESS_ALLOWED_ACE Ace;
Ace = (PACCESS_ALLOWED_ACE)Alloc(LengthACE);
if (Ace == NULL) {
DbgOnlyPrint("progman : CreateAccessAllowedAce : Failed to allocate ace\n\r");
return NULL;
}
Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
Ace->Header.AceSize = (USHORT)LengthACE;
Ace->Header.AceFlags = AceFlags | InheritFlags;
Ace->Mask = AccessMask;
RtlCopySid(LengthSid, (PSID)(&(Ace->SidStart)), Sid );
return(Ace);
}
/***************************************************************************\
* DestroyAce
*
* Frees the memory allocate for an ACE
*
* History:
* 12-05-91 Davidc Created
\***************************************************************************/
VOID
DestroyAce(
PVOID Ace
)
{
Free(Ace);
}