Leaked source code of windows server 2003
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.
 
 
 
 
 
 

364 lines
11 KiB

//+----------------------------------------------------------------------------
//
// File: allowaccess.cpp
//
// Module: Common Code
//
// Synopsis: Implements the function AllowAccessToWorld.
//
// Copyright (c) 1999 Microsoft Corporation
//
// Author: quintinb Created 12/04/01
//
//+----------------------------------------------------------------------------
LPCSTR apszAdvapi32[] = {
"GetSidLengthRequired",
"InitializeSid",
"GetSidSubAuthority",
"InitializeAcl",
"AddAccessAllowedAceEx",
"InitializeSecurityDescriptor",
"SetSecurityDescriptorDacl",
"SetSecurityDescriptorOwner",
"SetSecurityDescriptorGroup",
"GetSecurityDescriptorDacl",
#ifdef UNICODE
"SetNamedSecurityInfoW",
#else
"SetNamedSecurityInfoA",
#endif
NULL
};
//+----------------------------------------------------------------------------
//
// Function: LinkToAdavapi32
//
// Synopsis: This function links to advapi32.dll and loads the entry points
// specified in the above array of function name strings. If it returns
// success (TRUE) then the array has all of the requested function
// pointers in it. If it returns failure (FALSE), it zeros the structure.
//
// Arguments: AdvapiLinkageStruct* pAdvapiLink - Pointer struct to fill in
//
// Returns: BOOL - returns TRUE if successfull
//
// History: 12/05/01 quintinb created
//
//+----------------------------------------------------------------------------
BOOL LinkToAdavapi32(AdvapiLinkageStruct* pAdvapiLink)
{
BOOL bReturn = FALSE;
if (pAdvapiLink)
{
ZeroMemory(pAdvapiLink, sizeof(*pAdvapiLink));
//
// Do the link, but make it obvious if it fails
//
if (LinkToDll(&(pAdvapiLink->hAdvapi32), "advapi32.dll", apszAdvapi32, pAdvapiLink->apvPfnAdvapi32))
{
bReturn = TRUE;
}
else
{
if (pAdvapiLink->hAdvapi32)
{
FreeLibrary(pAdvapiLink->hAdvapi32);
}
ZeroMemory(pAdvapiLink, sizeof(*pAdvapiLink));
}
}
return bReturn;
}
//+----------------------------------------------------------------------------
//
// Function: UnlinkFromAdvapi32
//
// Synopsis: This function frees the link to advapi32.dll and zeros the passed
// in linkage struct.
//
// Arguments: AdvapiLinkageStruct* pAdvapiLink - Pointer struct to free
//
// Returns: Nothing
//
// History: 12/05/01 quintinb created
//
//+----------------------------------------------------------------------------
void UnlinkFromAdvapi32(AdvapiLinkageStruct* pAdvapiLink)
{
if (pAdvapiLink)
{
if (pAdvapiLink->hAdvapi32)
{
FreeLibrary(pAdvapiLink->hAdvapi32);
}
ZeroMemory(pAdvapiLink, sizeof(*pAdvapiLink));
}
}
//+----------------------------------------------------------------------------
//
// Function: AllocateSecurityDescriptorAllowAccessToWorld
//
// Synopsis: This function allocates a security descriptor for all users.
// This function was taken directly from RAS when they create their
// phonebook. This has to be before GetPhoneBookPath otherwise it
// causes compile errors in other components since we don't have a
// function prototype anywhere and cmcfg just includes this (getpbk.cpp)
// file. This function is also in common\source\getpbk.cpp
//
// Arguments: PSECURITY_DESCRIPTOR *ppSd - Pointer to a pointer to the SD struct
//
// Returns: DWORD - returns ERROR_SUCCESS if successfull
//
// History: 06/27/2001 tomkel Taken from RAS ui\common\pbk\file.c
//
//+----------------------------------------------------------------------------
#define SIZE_ALIGNED_FOR_TYPE(_size, _type) \
(((_size) + sizeof(_type)-1) & ~(sizeof(_type)-1))
DWORD AllocateSecurityDescriptorAllowAccessToWorld(PSECURITY_DESCRIPTOR *ppSd, AdvapiLinkageStruct* pAdvapiLink)
{
PSECURITY_DESCRIPTOR pSd;
PSID pSid;
PACL pDacl;
DWORD dwErr = ERROR_SUCCESS;
DWORD dwAlignSdSize;
DWORD dwAlignDaclSize;
DWORD dwSidSize;
PVOID pvBuffer;
DWORD dwAcls = 0;
// Here is the buffer we are building.
//
// |<- a ->|<- b ->|<- c ->|
// +-------+--------+------+
// | p| p| |
// | SD a| DACL a| SID |
// | d| d| |
// +-------+-------+-------+
// ^ ^ ^
// | | |
// | | +--pSid
// | |
// | +--pDacl
// |
// +--pSd (this is returned via *ppSd)
//
// pad is so that pDacl and pSid are aligned properly.
//
// a = dwAlignSdSize
// b = dwAlignDaclSize
// c = dwSidSize
//
if (NULL == ppSd)
{
return ERROR_INVALID_PARAMETER;
}
// Initialize output parameter.
//
*ppSd = NULL;
// Compute the size of the SID. The SID is the well-known SID for World
// (S-1-1-0).
//
dwSidSize = pAdvapiLink->pfnGetSidLengthRequired(1);
// Compute the size of the DACL. It has an inherent copy of SID within
// it so add enough room for it. It also must sized properly so that
// a pointer to a SID structure can come after it. Hence, we use
// SIZE_ALIGNED_FOR_TYPE.
//
dwAlignDaclSize = SIZE_ALIGNED_FOR_TYPE(
sizeof(ACCESS_ALLOWED_ACE) + sizeof(ACL) + dwSidSize,
PSID);
// Compute the size of the SD. It must be sized propertly so that a
// pointer to a DACL structure can come after it. Hence, we use
// SIZE_ALIGNED_FOR_TYPE.
//
dwAlignSdSize = SIZE_ALIGNED_FOR_TYPE(
sizeof(SECURITY_DESCRIPTOR),
PACL);
// Allocate the buffer big enough for all.
//
dwErr = ERROR_OUTOFMEMORY;
pvBuffer = CmMalloc(dwSidSize + dwAlignDaclSize + dwAlignSdSize);
if (pvBuffer)
{
SID_IDENTIFIER_AUTHORITY SidIdentifierWorldAuth
= SECURITY_WORLD_SID_AUTHORITY;
PULONG pSubAuthority;
dwErr = NOERROR;
// Setup the pointers into the buffer.
//
pSd = pvBuffer;
pDacl = (PACL)((PBYTE)pvBuffer + dwAlignSdSize);
pSid = (PSID)((PBYTE)pDacl + dwAlignDaclSize);
// Initialize pSid as S-1-1-0.
//
if (!pAdvapiLink->pfnInitializeSid(
pSid,
&SidIdentifierWorldAuth,
1)) // 1 sub-authority
{
dwErr = GetLastError();
goto finish;
}
pSubAuthority = pAdvapiLink->pfnGetSidSubAuthority(pSid, 0);
*pSubAuthority = SECURITY_WORLD_RID;
// Initialize pDacl.
//
if (!pAdvapiLink->pfnInitializeAcl(
pDacl,
dwAlignDaclSize,
ACL_REVISION))
{
dwErr = GetLastError();
goto finish;
}
dwAcls = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
dwAcls &= ~(WRITE_DAC | WRITE_OWNER);
if(!pAdvapiLink->pfnAddAccessAllowedAceEx(
pDacl,
ACL_REVISION,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
dwAcls,
pSid))
{
dwErr = GetLastError();
goto finish;
}
// Initialize pSd.
//
if (!pAdvapiLink->pfnInitializeSecurityDescriptor(
pSd,
SECURITY_DESCRIPTOR_REVISION))
{
dwErr = GetLastError();
goto finish;
}
// Set pSd to use pDacl.
//
if (!pAdvapiLink->pfnSetSecurityDescriptorDacl(
pSd,
TRUE,
pDacl,
FALSE))
{
dwErr = GetLastError();
goto finish;
}
// Set the owner for pSd.
//
if (!pAdvapiLink->pfnSetSecurityDescriptorOwner(
pSd,
NULL,
TRUE))
{
dwErr = GetLastError();
goto finish;
}
// Set the group for pSd.
//
if (!pAdvapiLink->pfnSetSecurityDescriptorGroup(
pSd,
NULL,
FALSE))
{
dwErr = GetLastError();
goto finish;
}
finish:
if (!dwErr)
{
*ppSd = pSd;
}
else
{
CmFree(pvBuffer);
}
}
return dwErr;
}
//+----------------------------------------------------------------------------
//
// Function: AllowAccessToWorld
//
// Synopsis: Assigns world access to the directory or filename passed in.
//
// Arguments: LPCTSTR pszDirOrFile - Directory or file to assign AllowAccessToWorld permissions
//
// Returns: BOOL - FALSE on Falure, non-zero on Success.
//
// History: koryg Created 12/03/2001
//
//+----------------------------------------------------------------------------
BOOL AllowAccessToWorld(LPTSTR pszDirOrFile)
{
AdvapiLinkageStruct AdvapiLink;
BOOL bReturn = FALSE;
if (pszDirOrFile && pszDirOrFile[0])
{
if (LinkToAdavapi32(&AdvapiLink))
{
PSECURITY_DESCRIPTOR pSd = NULL;
DWORD dwErr = AllocateSecurityDescriptorAllowAccessToWorld(&pSd, &AdvapiLink);
if ((ERROR_SUCCESS == dwErr) && (NULL != pSd))
{
BOOL fDaclPresent;
BOOL fDaclDefaulted;
PACL pDacl = NULL;
if (AdvapiLink.pfnGetSecurityDescriptorDacl(pSd, &fDaclPresent, &pDacl, &fDaclDefaulted))
{
dwErr = AdvapiLink.pfnSetNamedSecurityInfo(pszDirOrFile,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION,
NULL, // psidOwner
NULL, // psidGroup
pDacl, // pDacl
NULL); // pSacl
if (ERROR_SUCCESS == dwErr)
{
bReturn = TRUE;
}
}
}
CmFree(pSd);
UnlinkFromAdvapi32(&AdvapiLink);
}
}
return bReturn;
}