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.
300 lines
7.3 KiB
300 lines
7.3 KiB
/*++
|
|
|
|
Copyright (c) 1990 - 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
mapsd.c
|
|
|
|
Abstract:
|
|
|
|
Mapping Security Descriptors
|
|
|
|
|
|
Author:
|
|
|
|
Dave Snipp (DaveSn) 15-Mar-1991
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <precomp.h>
|
|
|
|
// Object types
|
|
//
|
|
|
|
|
|
extern GENERIC_MAPPING GenericMapping[];
|
|
|
|
PSECURITY_DESCRIPTOR
|
|
MapPrinterSDToShareSD(
|
|
PSECURITY_DESCRIPTOR pPrinterSD
|
|
);
|
|
|
|
BOOL
|
|
ProcessSecurityDescriptorDacl(
|
|
PSECURITY_DESCRIPTOR pSourceSD,
|
|
PACL *ppDacl,
|
|
LPBOOL pDefaulted
|
|
);
|
|
|
|
DWORD
|
|
MapPrinterMaskToShareMask(
|
|
DWORD PrinterMask
|
|
);
|
|
|
|
PSECURITY_DESCRIPTOR
|
|
MapPrinterSDToShareSD(
|
|
PSECURITY_DESCRIPTOR pPrinterSD
|
|
)
|
|
{
|
|
SECURITY_DESCRIPTOR AbsoluteSD;
|
|
PSECURITY_DESCRIPTOR pRelative;
|
|
BOOL Defaulted = FALSE;
|
|
PSID pOwnerSid = NULL;
|
|
PSID pGroupSid = NULL;
|
|
PACL pDacl = NULL;
|
|
BOOL ErrorOccurred = FALSE;
|
|
DWORD SDLength = 0;
|
|
|
|
|
|
if (!IsValidSecurityDescriptor(pPrinterSD)) {
|
|
return(NULL);
|
|
}
|
|
if (!InitializeSecurityDescriptor (&AbsoluteSD ,SECURITY_DESCRIPTOR_REVISION1)) {
|
|
return(NULL);
|
|
}
|
|
|
|
if(GetSecurityDescriptorOwner( pPrinterSD,
|
|
&pOwnerSid, &Defaulted ) )
|
|
SetSecurityDescriptorOwner( &AbsoluteSD,
|
|
pOwnerSid, Defaulted );
|
|
else
|
|
ErrorOccurred = TRUE;
|
|
|
|
if( GetSecurityDescriptorGroup( pPrinterSD,
|
|
&pGroupSid, &Defaulted ) )
|
|
SetSecurityDescriptorGroup( &AbsoluteSD,
|
|
pGroupSid, Defaulted );
|
|
else
|
|
ErrorOccurred = TRUE;
|
|
|
|
if (ProcessSecurityDescriptorDacl(pPrinterSD, &pDacl, &Defaulted)) {
|
|
(VOID)SetSecurityDescriptorDacl (&AbsoluteSD, TRUE, pDacl, FALSE );
|
|
}
|
|
else
|
|
ErrorOccurred = TRUE;
|
|
|
|
if (ErrorOccurred) {
|
|
if (pDacl) {
|
|
LocalFree(pDacl);
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
SDLength = GetSecurityDescriptorLength( &AbsoluteSD);
|
|
pRelative = LocalAlloc(LPTR, SDLength);
|
|
if (!pRelative) {
|
|
LocalFree(pDacl);
|
|
return(NULL);
|
|
}
|
|
if (!MakeSelfRelativeSD (&AbsoluteSD, pRelative, &SDLength)) {
|
|
LocalFree(pRelative);
|
|
LocalFree(pDacl);
|
|
return(NULL);
|
|
}
|
|
LocalFree(pDacl);
|
|
return(pRelative);
|
|
}
|
|
|
|
BOOL
|
|
ProcessSecurityDescriptorDacl(
|
|
PSECURITY_DESCRIPTOR pSourceSD,
|
|
PACL *ppDacl,
|
|
LPBOOL pDefaulted
|
|
)
|
|
|
|
{
|
|
BOOL DaclPresent = FALSE;
|
|
BOOL bRet = FALSE;
|
|
DWORD DestAceCount = 0;
|
|
DWORD DaclLength = 0;
|
|
PACL TmpAcl = NULL;
|
|
PACL pDacl = NULL;
|
|
PSID *ppSid = NULL;
|
|
ACCESS_MASK *pAccessMask = NULL;
|
|
BYTE *pInheritFlags = NULL;
|
|
UCHAR *pAceType = NULL;
|
|
PACCESS_ALLOWED_ACE pAce = NULL;
|
|
DWORD dwLengthSid = 0;
|
|
PSID pSourceSid = NULL;
|
|
PSID pDestSid = NULL;
|
|
DWORD i = 0;
|
|
PACCESS_ALLOWED_ACE TmpAce = NULL;
|
|
ACL_SIZE_INFORMATION AclSizeInfo;
|
|
|
|
|
|
*ppDacl = NULL;
|
|
|
|
bRet = GetSecurityDescriptorDacl( pSourceSD, &DaclPresent, &pDacl, pDefaulted );
|
|
|
|
if (bRet) {
|
|
|
|
bRet = DaclPresent;
|
|
|
|
//
|
|
// NULL is a valid DACL
|
|
//
|
|
if (!pDacl)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if (bRet) {
|
|
|
|
GetAclInformation(pDacl, &AclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
|
|
|
|
ppSid = LocalAlloc(LPTR, sizeof(PSID)* AclSizeInfo.AceCount);
|
|
pAccessMask = LocalAlloc(LPTR, sizeof(ACCESS_MASK)* AclSizeInfo.AceCount);
|
|
pInheritFlags = LocalAlloc(LPTR, sizeof(BYTE)*AclSizeInfo.AceCount);
|
|
pAceType = LocalAlloc(LPTR, sizeof(UCHAR)*AclSizeInfo.AceCount);
|
|
|
|
bRet = ppSid && pAccessMask && pInheritFlags && pAceType;
|
|
}
|
|
|
|
for (i = 0 ; bRet && i < AclSizeInfo.AceCount; i++) {
|
|
GetAce(pDacl, i, (LPVOID *)&pAce);
|
|
//
|
|
// Skip the Ace if it is inherit only
|
|
//
|
|
if ( ((PACE_HEADER)pAce)->AceFlags & INHERIT_ONLY_ACE ) {
|
|
continue;
|
|
}
|
|
|
|
*(pAceType + DestAceCount) = ((PACE_HEADER)pAce)->AceType;
|
|
*(pAccessMask + DestAceCount) = MapPrinterMaskToShareMask(((PACCESS_ALLOWED_ACE)pAce)->Mask);
|
|
*(pInheritFlags + DestAceCount) = ((PACE_HEADER)pAce)->AceFlags;
|
|
//
|
|
// Copy the sid information
|
|
//
|
|
pSourceSid = (PSID)(&(((PACCESS_ALLOWED_ACE)pAce)->SidStart));
|
|
dwLengthSid = GetLengthSid(pSourceSid);
|
|
pDestSid = (LPBYTE)LocalAlloc(LPTR, dwLengthSid);
|
|
|
|
if (pDestSid) {
|
|
|
|
CopySid(dwLengthSid, pDestSid, pSourceSid);
|
|
|
|
*(ppSid + DestAceCount) = pDestSid;
|
|
|
|
} else {
|
|
|
|
//
|
|
// We failed to allocate the memory, we signal that we failed and
|
|
// fall down to the cleanup code below.
|
|
//
|
|
bRet = FALSE;
|
|
|
|
break;
|
|
}
|
|
|
|
DestAceCount++;
|
|
}
|
|
|
|
//
|
|
// Compute size of the Dacl
|
|
//
|
|
if (bRet) {
|
|
|
|
DaclLength = (DWORD)sizeof(ACL);
|
|
for (i = 0; i < DestAceCount; i++) {
|
|
|
|
DaclLength += GetLengthSid( *(ppSid + i)) +
|
|
(DWORD)sizeof(ACCESS_ALLOWED_ACE) -
|
|
(DWORD)sizeof(DWORD); //Subtract out SidStart field length
|
|
}
|
|
|
|
TmpAcl = LocalAlloc(LPTR, DaclLength);
|
|
|
|
bRet = (TmpAcl != NULL);
|
|
}
|
|
|
|
if (bRet) {
|
|
|
|
bRet = InitializeAcl(TmpAcl, DaclLength, ACL_REVISION2);
|
|
}
|
|
|
|
for (i = 0; bRet && i < DestAceCount; i++) {
|
|
if( *(pAceType +i) == ACCESS_ALLOWED_ACE_TYPE )
|
|
(VOID)AddAccessAllowedAce ( TmpAcl, ACL_REVISION2, *(pAccessMask + i), *(ppSid + i));
|
|
else
|
|
(VOID)AddAccessDeniedAce ( TmpAcl, ACL_REVISION2, *(pAccessMask + i), *(ppSid + i));
|
|
if (*(pInheritFlags + i) != 0) {
|
|
(VOID)GetAce( TmpAcl, i, (LPVOID *)&TmpAce );
|
|
TmpAce->Header.AceFlags = *(pInheritFlags + i);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Write the Dacl back from the TmpAcl.
|
|
//
|
|
if (bRet) {
|
|
|
|
*ppDacl = TmpAcl;
|
|
|
|
TmpAcl = NULL;
|
|
}
|
|
|
|
//
|
|
// Free all of our temporary space.
|
|
//
|
|
if (ppSid) {
|
|
|
|
for (i = 0; i < DestAceCount; i++) {
|
|
LocalFree(*(ppSid + i));
|
|
}
|
|
|
|
LocalFree(ppSid);
|
|
}
|
|
|
|
if (pAccessMask) {
|
|
|
|
LocalFree(pAccessMask);
|
|
}
|
|
|
|
if (pInheritFlags) {
|
|
|
|
LocalFree(pInheritFlags);
|
|
}
|
|
|
|
if (pAceType) {
|
|
|
|
LocalFree(pAceType);
|
|
}
|
|
|
|
if (TmpAcl) {
|
|
|
|
LocalFree(TmpAcl);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
DWORD
|
|
MapPrinterMaskToShareMask(
|
|
DWORD PrinterMask
|
|
)
|
|
{
|
|
DWORD ReturnMask = 0;
|
|
|
|
MapGenericMask(&PrinterMask, &GenericMapping[SPOOLER_OBJECT_PRINTER]);
|
|
|
|
if ((PrinterMask & PRINTER_ACCESS_ADMINISTER)
|
|
|| (PrinterMask & PRINTER_ACCESS_USE)) {
|
|
ReturnMask |= GENERIC_ALL;
|
|
}
|
|
return(ReturnMask);
|
|
}
|