340 lines
8.6 KiB
C
340 lines
8.6 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);
|
|
|
|
if ( psec == NULL ) {
|
|
return 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);
|
|
|
|
if ( psec == NULL ) {
|
|
return 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);
|
|
|
|
if ( psec == NULL ) {
|
|
return 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()
|