windows-nt/Source/XPSP1/NT/base/cluster/clusrtl/fixup.c
2020-09-26 16:20:57 +08:00

331 lines
8.4 KiB
C

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
FixUp.c
Abstract:
This module contains common security routines for
NT Clusters rolling upgrade and backward compatibility.
Author:
Galen Barbee (galenb) 31-Mar-1998
--*/
#include "clusrtlp.h"
PSECURITY_DESCRIPTOR
ClRtlConvertClusterSDToNT4Format(
IN PSECURITY_DESCRIPTOR psd
)
/*++
Routine Description:
Convert the SD from nt 5 to nt 4 format. This means enforcing the
following rules:
1. Convert denied ACE to allowed ACE. Convert "Full Control" access
mask to CLUAPI_NO_ACCESS.
Arguments:
psd [IN] Security descriptor.
Return Value:
The new SD in self-Relative format
--*/
{
PACL pacl;
BOOL bHasDACL;
BOOL bDACLDefaulted;
PSECURITY_DESCRIPTOR psec = NULL;
if (NULL == psd) {
return NULL;
}
psec = ClRtlCopySecurityDescriptor(psd);
ASSERT(psec != NULL);
if ( (GetSecurityDescriptorDacl(psec, (LPBOOL) &bHasDACL, (PACL *) &pacl, (LPBOOL) &bDACLDefaulted)) &&
( bHasDACL != FALSE ) ) {
ACL_SIZE_INFORMATION asiAclSize;
DWORD dwBufLength;
dwBufLength = sizeof(asiAclSize);
if (GetAclInformation(pacl, &asiAclSize, dwBufLength, AclSizeInformation)) {
ACCESS_DENIED_ACE * pAce;
DWORD dwIndex;
for (dwIndex = 0; dwIndex < asiAclSize.AceCount; dwIndex++) {
if (GetAce(pacl, dwIndex, (LPVOID *) &pAce)) {
if (pAce->Header.AceType == ACCESS_DENIED_ACE_TYPE) {
if (pAce->Mask & SPECIFIC_RIGHTS_ALL) {
pAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
pAce->Mask = CLUSAPI_NO_ACCESS;
}
} // end if (pAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
} // end if (GetAce())
} // end for
} // end if (GetAclInformation())
} // end if (HrGetSecurityDescriptorDacl()) and DACL is present
ASSERT(IsValidSecurityDescriptor(psec));
return psec;
} //*** ClRtlConvertClusterSDToNT4Format()
PSECURITY_DESCRIPTOR
ClRtlConvertClusterSDToNT5Format(
IN PSECURITY_DESCRIPTOR psd
)
/*++
Routine Description:
Convert the SD from nt 5 to nt 4 format. This means enforcing the
following rules:
1. Convert allowed ACE with mask CLUAPI_NO_ACCESS to denied ACE mask full control.
Arguments:
psd [IN] Security descriptor.
Return Value:
The new SD in self-Relative format
--*/
{
PACL pacl;
BOOL bHasDACL;
BOOL bDACLDefaulted;
PSECURITY_DESCRIPTOR psec = NULL;
if (NULL == psd) {
return NULL;
}
psec = ClRtlCopySecurityDescriptor(psd);
ASSERT(psec != NULL);
if ( (GetSecurityDescriptorDacl(psec, (LPBOOL) &bHasDACL, (PACL *) &pacl, (LPBOOL) &bDACLDefaulted)) &&
( bHasDACL != FALSE ) ) {
ACL_SIZE_INFORMATION asiAclSize;
DWORD dwBufLength;
dwBufLength = sizeof(asiAclSize);
if (GetAclInformation(pacl, &asiAclSize, dwBufLength, AclSizeInformation)) {
ACCESS_DENIED_ACE * pAce;
DWORD dwIndex;
for (dwIndex = 0; dwIndex < asiAclSize.AceCount; dwIndex++) {
if (GetAce(pacl, dwIndex, (LPVOID *) &pAce)) {
if (pAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) {
if (pAce->Mask & CLUSAPI_NO_ACCESS) {
pAce->Header.AceType = ACCESS_DENIED_ACE_TYPE;
pAce->Mask = SPECIFIC_RIGHTS_ALL;
}
} // end if (pAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
} // end if (GetAce())
} // end for
} // end if (GetAclInformation())
} // end if (HrGetSecurityDescriptorDacl()) and DACL is present
ASSERT(IsValidSecurityDescriptor(psec));
return psec;
} //*** ClRtlConvertClusterSDToNT5Format()
static GENERIC_MAPPING gmFileShareMap =
{
FILE_GENERIC_READ,
FILE_GENERIC_WRITE,
FILE_GENERIC_EXECUTE,
FILE_ALL_ACCESS
};
#define SPECIFIC_CHANGE (DELETE | FILE_GENERIC_WRITE)
#define SPECIFIC_READ (FILE_GENERIC_READ | FILE_LIST_DIRECTORY | FILE_EXECUTE)
#define GENERIC_CHANGE (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE)
PSECURITY_DESCRIPTOR
ClRtlConvertFileShareSDToNT4Format(
IN PSECURITY_DESCRIPTOR psd
)
/*++
Routine Description:
Convert the SD from nt 5 to nt 4 format. This means enforcing the
following rules:
Arguments:
psd [IN] Security descriptor.
Return Value:
The new SD in self-Relative format
--*/
{
PACL pacl;
BOOL bHasDACL;
BOOL bDACLDefaulted;
PSECURITY_DESCRIPTOR psec = NULL;
if (NULL == psd) {
return NULL;
}
psec = ClRtlCopySecurityDescriptor(psd);
ASSERT(psec != NULL);
if ( (GetSecurityDescriptorDacl(psec, (LPBOOL) &bHasDACL, (PACL *) &pacl, (LPBOOL) &bDACLDefaulted)) &&
( bHasDACL != FALSE ) ) {
ACL_SIZE_INFORMATION asiAclSize;
DWORD dwBufLength;
ACCESS_MASK amTemp1;
ACCESS_MASK amTemp2;
dwBufLength = sizeof(asiAclSize);
if (GetAclInformation(pacl, &asiAclSize, dwBufLength, AclSizeInformation)) {
ACCESS_DENIED_ACE * pAce;
DWORD dwSid;
DWORD dwIndex;
for (dwIndex = 0; dwIndex < asiAclSize.AceCount; dwIndex++) {
amTemp1 = 0;
amTemp2 = 0;
if (GetAce(pacl, dwIndex, (LPVOID *) &pAce)) {
// delete deny read ACEs since they don't mean anything to AclEdit
if ((pAce->Header.AceType == ACCESS_DENIED_ACE_TYPE) &&
(pAce->Mask == SPECIFIC_READ)) {
dwSid = pAce->SidStart;
if (DeleteAce(pacl, dwIndex)) {
asiAclSize.AceCount -= 1;
dwIndex -= 1;
}
else {
ClRtlDbgPrint(LOG_UNUSUAL,
"[ClRtl] DeteteAce failed removing ACE #%1!d! due to error %2!d!\n",
dwIndex,
GetLastError());
}
continue;
}
// convert deny change deny read ACEs to deny all ACEs
if ((pAce->Header.AceType == ACCESS_DENIED_ACE_TYPE) &&
(pAce->Mask == (SPECIFIC_CHANGE | SPECIFIC_READ))) {
pAce->Mask = GENERIC_ALL;
continue;
}
// convert deny change ACEs to allow read (read only) ACEs
if ((pAce->Header.AceType == ACCESS_DENIED_ACE_TYPE) &&
(pAce->Mask == SPECIFIC_CHANGE)) {
pAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
pAce->Mask = GENERIC_READ | GENERIC_EXECUTE;
continue;
}
// convert specific allow change to generic allow change
if ((pAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) &&
(pAce->Mask == SPECIFIC_CHANGE)) {
pAce->Mask = GENERIC_CHANGE;
continue;
}
// convert specific all to generic all
if ((pAce->Mask & gmFileShareMap.GenericAll) == gmFileShareMap.GenericAll) {
amTemp1 |= GENERIC_ALL;
amTemp2 |= gmFileShareMap.GenericAll;
}
else {
// convert specific read to generic read
if ((pAce->Mask & gmFileShareMap.GenericRead) == gmFileShareMap.GenericRead) {
amTemp1 |= GENERIC_READ;
amTemp2 |= gmFileShareMap.GenericRead;
}
// convert specific write to generic write which includes delete
if ((pAce->Mask & gmFileShareMap.GenericWrite) == gmFileShareMap.GenericWrite) {
amTemp1 |= (GENERIC_WRITE | DELETE);
amTemp2 |= gmFileShareMap.GenericWrite;
}
// convert specific execute to generic execute
if ((pAce->Mask & gmFileShareMap.GenericExecute) == gmFileShareMap.GenericExecute) {
amTemp1 |= GENERIC_EXECUTE;
amTemp2 |= gmFileShareMap.GenericExecute;
}
}
pAce->Mask &= ~amTemp2; // turn off specific bits
pAce->Mask |= amTemp1; // turn on generic bits
} // end if (GetAce())
} // end for
} // end if (GetAclInformation())
} // end if (HrGetSecurityDescriptorDacl()) and DACL is present
ASSERT(IsValidSecurityDescriptor(psec));
return psec;
} //*** ClRtlConvertFileShareSDToNT4Format()