279 lines
7.6 KiB
C++
279 lines
7.6 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1996.
|
|
//
|
|
// File: security.cxx
|
|
//
|
|
// Contents: Security-related helper functions used by the Task Scheduler
|
|
// setup program to set security on the job folder.
|
|
//
|
|
// Classes: None.
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 23-Sep-96 AnirudhS Copied with minor modifications from
|
|
// ..\job\security.cxx.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <windows.h>
|
|
#include "..\inc\security.hxx"
|
|
|
|
#define schDebugOut(x)
|
|
#define schAssert(x)
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CreateSecurityDescriptor
|
|
//
|
|
// Synopsis: Create a security descriptor with the ACE information
|
|
// specified.
|
|
//
|
|
// Arguments: [AceCount] -- ACE count (no. of rgMyAce and rgAce elements).
|
|
// [rgMyAce] -- ACE specification array.
|
|
// [rgAce] -- Caller allocated array of ptrs to ACEs so
|
|
// this function doesn't have to allocate it.
|
|
//
|
|
// Returns: TRUE -- Function succeeded,
|
|
// FALSE -- Otherwise.
|
|
//
|
|
// Notes: None.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
PSECURITY_DESCRIPTOR
|
|
CreateSecurityDescriptor(
|
|
DWORD AceCount,
|
|
MYACE rgMyAce[],
|
|
PACCESS_ALLOWED_ACE rgAce[],
|
|
DWORD * pStatus)
|
|
{
|
|
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
|
|
PACL pAcl = NULL;
|
|
DWORD LengthAces = 0;
|
|
DWORD LengthAcl;
|
|
DWORD i;
|
|
DWORD Status;
|
|
|
|
for (i = 0; i < AceCount; i++)
|
|
{
|
|
rgAce[i] = CreateAccessAllowedAce(rgMyAce[i].pSid,
|
|
rgMyAce[i].AccessMask,
|
|
0,
|
|
rgMyAce[i].InheritFlags,
|
|
&Status);
|
|
|
|
if (rgAce[i] == NULL)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LengthAces += rgAce[i]->Header.AceSize;
|
|
}
|
|
|
|
//
|
|
// Calculate ACL and SD sizes
|
|
//
|
|
|
|
LengthAcl = sizeof(ACL) + LengthAces;
|
|
|
|
//
|
|
// Create the ACL.
|
|
//
|
|
|
|
pAcl = (PACL)LocalAlloc(LMEM_FIXED, LengthAcl);
|
|
|
|
if (pAcl == NULL)
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
schDebugOut((DEB_ERROR,
|
|
"CreateSecurityDescriptor, ACL allocation failed\n"));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (!InitializeAcl(pAcl, LengthAcl, ACL_REVISION))
|
|
{
|
|
Status = GetLastError();
|
|
schDebugOut((DEB_ERROR,
|
|
"CreateSecurityDescriptor, InitializeAcl failed, " \
|
|
"status = 0x%lx\n",
|
|
Status));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
for (i = 0; i < AceCount; i++)
|
|
{
|
|
if (!AddAce(pAcl,
|
|
ACL_REVISION,
|
|
0,
|
|
rgAce[i],
|
|
rgAce[i]->Header.AceSize))
|
|
{
|
|
Status = GetLastError();
|
|
schDebugOut((DEB_ERROR,
|
|
"CreateSecurityDescriptor, AddAce[%l] failed, " \
|
|
"status = 0x%lx\n", i, Status));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LocalFree(rgAce[i]);
|
|
rgAce[i] = NULL;
|
|
}
|
|
|
|
//
|
|
// Create the security descriptor.
|
|
//
|
|
|
|
pSecurityDescriptor = LocalAlloc(LMEM_FIXED,
|
|
SECURITY_DESCRIPTOR_MIN_LENGTH);
|
|
|
|
if (pSecurityDescriptor == NULL)
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
schDebugOut((DEB_ERROR,
|
|
"CreateSecurityDescriptor, SECURITY_DESCRIPTOR allocation " \
|
|
"failed\n"));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (!InitializeSecurityDescriptor(pSecurityDescriptor,
|
|
SECURITY_DESCRIPTOR_REVISION))
|
|
{
|
|
Status = GetLastError();
|
|
schDebugOut((DEB_ERROR,
|
|
"CreateSecurityDescriptor, InitializeSecurityDescriptor " \
|
|
"failed, status = 0x%lx\n",
|
|
Status));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (!SetSecurityDescriptorDacl(pSecurityDescriptor,
|
|
TRUE,
|
|
pAcl,
|
|
FALSE))
|
|
{
|
|
Status = GetLastError();
|
|
schDebugOut((DEB_ERROR,
|
|
"CreateSecurityDescriptor, SetSecurityDescriptorDacl " \
|
|
"failed, status = 0x%lx\n",
|
|
Status));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (pStatus != NULL) *pStatus = ERROR_SUCCESS;
|
|
|
|
return(pSecurityDescriptor);
|
|
|
|
ErrorExit:
|
|
for (i = 0; i < AceCount; i++)
|
|
{
|
|
if (rgAce[i] != NULL)
|
|
{
|
|
LocalFree(rgAce[i]);
|
|
rgAce[i] = NULL;
|
|
}
|
|
}
|
|
if (pAcl != NULL) LocalFree(pAcl);
|
|
if (pSecurityDescriptor != NULL) LocalFree(pSecurityDescriptor);
|
|
|
|
if (pStatus != NULL) *pStatus = Status;
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: DeleteSecurityDescriptor
|
|
//
|
|
// Synopsis: Deallocate the security descriptor allocated in
|
|
// CreateSecurityDescriptor.
|
|
//
|
|
// Arguments: [pSecurityDescriptor] -- SD returned from
|
|
// CreateSecurityDescriptor.
|
|
//
|
|
// Returns: None.
|
|
//
|
|
// Notes: None.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
DeleteSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor)
|
|
{
|
|
BOOL fPresent;
|
|
BOOL fDefaulted;
|
|
PACL pAcl;
|
|
|
|
schAssert(pSecurityDescriptor != NULL);
|
|
|
|
if (GetSecurityDescriptorDacl(pSecurityDescriptor,
|
|
&fPresent,
|
|
&pAcl,
|
|
&fDefaulted))
|
|
{
|
|
if (fPresent && pAcl != NULL)
|
|
{
|
|
LocalFree(pAcl);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
schDebugOut((DEB_ERROR,
|
|
"DeleteSecurityDescriptor, GetSecurityDescriptorDacl failed, " \
|
|
"status = 0x%lx\n",
|
|
GetLastError()));
|
|
}
|
|
|
|
LocalFree(pSecurityDescriptor);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CreateAccessAllowedAce
|
|
//
|
|
// Synopsis: Scavenged code from winlogon to create an access allowed ACE.
|
|
// Modified a bit to use Win32 vs. Rtl.
|
|
//
|
|
// Arguments: [pSid] -- Sid to which this ACE is applied.
|
|
// [AccessMask] -- ACE access mask value.
|
|
// [AceFlags] -- ACE flags value.
|
|
// [InheritFlags] -- ACE inherit flags value.
|
|
//
|
|
// Returns: Created ACE if successful.
|
|
// NULL on error.
|
|
//
|
|
// Notes: None.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
PACCESS_ALLOWED_ACE
|
|
CreateAccessAllowedAce(
|
|
PSID pSid,
|
|
ACCESS_MASK AccessMask,
|
|
UCHAR AceFlags,
|
|
UCHAR InheritFlags,
|
|
DWORD * pStatus)
|
|
{
|
|
ULONG LengthSid = GetLengthSid(pSid);
|
|
ULONG LengthACE = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + LengthSid;
|
|
PACCESS_ALLOWED_ACE Ace;
|
|
|
|
Ace = (PACCESS_ALLOWED_ACE)LocalAlloc(LMEM_FIXED, LengthACE);
|
|
|
|
if (Ace == NULL)
|
|
{
|
|
if (pStatus != NULL) *pStatus = ERROR_NOT_ENOUGH_MEMORY;
|
|
schDebugOut((DEB_ERROR,
|
|
"CreateAccessAllowedAce, ACE allocation failed\n"));
|
|
return(NULL);
|
|
}
|
|
|
|
Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
|
|
Ace->Header.AceSize = (UCHAR)LengthACE;
|
|
Ace->Header.AceFlags = AceFlags | InheritFlags;
|
|
Ace->Mask = AccessMask;
|
|
CopySid(LengthSid, (PSID)(&(Ace->SidStart)), pSid);
|
|
|
|
if (pStatus != NULL) *pStatus = ERROR_SUCCESS;
|
|
|
|
return(Ace);
|
|
}
|