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.
800 lines
23 KiB
800 lines
23 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
aclmgmt.cpp
|
|
|
|
Abstract:
|
|
|
|
Routines to manage access control lists
|
|
|
|
Geoffrey Guo (geoffguo) 26-Apr-2002 Created
|
|
|
|
Revision History:
|
|
|
|
<alias> <date> <comments>
|
|
|
|
--*/
|
|
|
|
#include "clmt.h"
|
|
#define STRSAFE_LIB
|
|
#include <strsafe.h>
|
|
|
|
DWORD ChangeOwner (
|
|
LPTSTR lpObjectName,
|
|
SE_OBJECT_TYPE ObjectType)
|
|
{
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
PSID psidAdministrators;
|
|
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
|
|
SECURITY_INFORMATION si = OWNER_SECURITY_INFORMATION;
|
|
|
|
if(!AllocateAndInitializeSid(&siaNtAuthority, 2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&psidAdministrators))
|
|
{
|
|
dwRet = GetLastError();
|
|
goto Exit;
|
|
}
|
|
|
|
EnablePrivilege(SE_TAKE_OWNERSHIP_NAME,TRUE);
|
|
si |= SI_OWNER_RECURSE;
|
|
|
|
dwRet = SetNamedSecurityInfo(lpObjectName,
|
|
ObjectType,
|
|
si,
|
|
psidAdministrators,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
|
|
EnablePrivilege(SE_TAKE_OWNERSHIP_NAME,FALSE);
|
|
FreeSid(psidAdministrators);
|
|
|
|
Exit:
|
|
return dwRet;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// CopyACL: Copy ACL
|
|
//
|
|
// OldACL: Pointer to source Access Control List
|
|
// NewACL: Pointer to destination Access Control List
|
|
//-----------------------------------------------------------------------//
|
|
DWORD
|
|
CopyACL (
|
|
PACL OldACL,
|
|
PACL NewACL)
|
|
{
|
|
ACL_SIZE_INFORMATION aclSizeInfo;
|
|
LPVOID ace;
|
|
ACE_HEADER *aceHeader;
|
|
ULONG i;
|
|
|
|
GetAclInformation (OldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (aclSizeInfo), AclSizeInformation);
|
|
|
|
//
|
|
// Copy all of the ACEs to the new ACL
|
|
//
|
|
|
|
for (i = 0; i < aclSizeInfo.AceCount; i++)
|
|
{
|
|
//
|
|
// Get the ACE and header info
|
|
//
|
|
|
|
if (!GetAce (OldACL, i, &ace))
|
|
return GetLastError();
|
|
|
|
aceHeader = (ACE_HEADER *) ace;
|
|
|
|
//
|
|
// Add the ACE to the new list
|
|
//
|
|
|
|
if (!AddAce (NewACL, ACL_REVISION, 0xffffffff, ace, aceHeader->AceSize))
|
|
return GetLastError();
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// AddAccessAllowedACEToACL: Add Administrator Allowed ACE to ACL
|
|
//
|
|
// Acl: Pointer to Access Control List
|
|
// PermissionMask: Permission will be set for new ACE
|
|
//-----------------------------------------------------------------------//
|
|
DWORD
|
|
AddAccessAllowedACEToACL (
|
|
PACL *Acl,
|
|
DWORD PermissionMask)
|
|
{
|
|
ACL_SIZE_INFORMATION aclSizeInfo;
|
|
int aclSize;
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
USHORT AceSize;
|
|
PSID psidAdministrators;
|
|
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
|
|
PACL oldACL, newACL;
|
|
ACCESS_ALLOWED_ACE *pAllowedAce;
|
|
|
|
|
|
oldACL = *Acl;
|
|
|
|
if(!AllocateAndInitializeSid(&siaNtAuthority, 2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&psidAdministrators))
|
|
{
|
|
dwRet = GetLastError();
|
|
goto Exit;
|
|
}
|
|
|
|
GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation);
|
|
|
|
aclSize = aclSizeInfo.AclBytesInUse +
|
|
sizeof (ACL) + sizeof (ACCESS_ALLOWED_ACE) +
|
|
GetLengthSid (psidAdministrators) - sizeof (DWORD);
|
|
|
|
newACL = (PACL) calloc(aclSize, 1);
|
|
|
|
if (!newACL)
|
|
{
|
|
dwRet = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Exit1;
|
|
}
|
|
|
|
if (!InitializeAcl (newACL, aclSize, ACL_REVISION))
|
|
{
|
|
dwRet = GetLastError();
|
|
free (newACL);
|
|
goto Exit1;
|
|
}
|
|
|
|
dwRet = CopyACL (oldACL, newACL);
|
|
if (dwRet != ERROR_SUCCESS)
|
|
{
|
|
free (newACL);
|
|
goto Exit1;
|
|
}
|
|
|
|
AceSize = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + (USHORT)GetLengthSid(psidAdministrators);
|
|
pAllowedAce = (ACCESS_ALLOWED_ACE *)calloc(AceSize, 1);
|
|
if (!(pAllowedAce))
|
|
{
|
|
dwRet = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Exit1;
|
|
}
|
|
|
|
pAllowedAce->Header.AceFlags = 0;
|
|
pAllowedAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
|
|
pAllowedAce->Header.AceSize = AceSize;
|
|
pAllowedAce->Mask = PermissionMask;
|
|
CopySid(GetLengthSid(psidAdministrators), &(pAllowedAce->SidStart), psidAdministrators);
|
|
if (!AddAce (newACL, ACL_REVISION, 0, pAllowedAce, AceSize))
|
|
{
|
|
dwRet = GetLastError();
|
|
free (newACL);
|
|
goto Exit1;
|
|
}
|
|
|
|
*Acl = newACL;
|
|
|
|
Exit1:
|
|
FreeSid(psidAdministrators);
|
|
Exit:
|
|
return dwRet;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// RestoreACE: Restore denied ACE
|
|
//
|
|
// pACE: Pointer to source Access Control Entry
|
|
// lpOnjectName: Pointer to the object name
|
|
//-----------------------------------------------------------------------//
|
|
DWORD
|
|
RestoreACE (
|
|
PACL *ppAcl,
|
|
LPTSTR lpObjectName)
|
|
{
|
|
DWORD dwRet = ERROR_INVALID_PARAMETER;
|
|
DWORD dwLen;
|
|
PACL newACL;
|
|
LPDENIED_ACE_LIST pList;
|
|
|
|
if (!*ppAcl)
|
|
goto Exit;
|
|
|
|
pList = g_DeniedACEList;
|
|
if (pList)
|
|
{
|
|
do
|
|
{
|
|
if (lstrcmp(lpObjectName, pList->lpObjectName) == 0)
|
|
{
|
|
newACL = (PACL) calloc(pList->dwAclSize, 1);
|
|
|
|
if (!newACL)
|
|
{
|
|
dwRet = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
if (!InitializeAcl (newACL, pList->dwAclSize, ACL_REVISION))
|
|
{
|
|
free(newACL);
|
|
dwRet = GetLastError();
|
|
goto Exit;
|
|
}
|
|
|
|
dwRet = CopyACL (*ppAcl, newACL);
|
|
if (dwRet != ERROR_SUCCESS)
|
|
{
|
|
free(newACL);
|
|
dwRet = GetLastError();
|
|
goto Exit;
|
|
}
|
|
|
|
if (!AddAce (newACL,
|
|
ACL_REVISION,
|
|
0,
|
|
pList->pace,
|
|
((PACE_HEADER)(pList->pace))->AceSize))
|
|
{
|
|
dwRet = GetLastError();
|
|
goto Exit;
|
|
}
|
|
else
|
|
DPF(REGmsg, L"Restore denied ACE to ACL: ObjectName=%s", lpObjectName);
|
|
|
|
if (pList->previous)
|
|
pList->previous->next = pList->next;
|
|
else
|
|
g_DeniedACEList = pList->next;
|
|
|
|
if (pList->next)
|
|
pList->next->previous = pList->previous;
|
|
*ppAcl = newACL;
|
|
free (pList->lpObjectName);
|
|
free (pList->pace);
|
|
free (pList);
|
|
break;
|
|
}
|
|
pList = pList->next;
|
|
} while (pList->next);
|
|
}
|
|
dwRet = ERROR_SUCCESS;
|
|
|
|
Exit:
|
|
return dwRet;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// RemoveACEFromACL: Remove Administrator ACE from ACL
|
|
//
|
|
// Acl: Pointer to Access Control List
|
|
//-----------------------------------------------------------------------//
|
|
DWORD
|
|
RemoveACEFromACL (
|
|
PACL Acl)
|
|
{
|
|
ACL_SIZE_INFORMATION aclSizeInfo;
|
|
ULONG i;
|
|
LPVOID ace;
|
|
ACCESS_ALLOWED_ACE *accessAllowedAce;
|
|
ACCESS_DENIED_ACE *accessDeniedAce;
|
|
SYSTEM_AUDIT_ACE *systemAuditAce;
|
|
PSID psidAdministrators;
|
|
DWORD returnValue;
|
|
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
|
|
ACE_HEADER *aceHeader;
|
|
|
|
if(!AllocateAndInitializeSid(&siaNtAuthority, 2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&psidAdministrators))
|
|
return GetLastError();
|
|
|
|
GetAclInformation (Acl, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation);
|
|
|
|
for (i = 0; i < aclSizeInfo.AceCount; i++)
|
|
{
|
|
if (!GetAce (Acl, i, &ace))
|
|
{
|
|
FreeSid(psidAdministrators);
|
|
return GetLastError();
|
|
}
|
|
|
|
aceHeader = (ACE_HEADER *) ace;
|
|
|
|
if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
|
|
{
|
|
accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace;
|
|
|
|
if (EqualSid (psidAdministrators, (PSID) &accessAllowedAce->SidStart))
|
|
{
|
|
DeleteAce (Acl, i);
|
|
FreeSid(psidAdministrators);
|
|
return ERROR_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
|
|
FreeSid(psidAdministrators);
|
|
return ERROR_NO_MORE_ITEMS;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// AddACE2List: Add ACE to the list
|
|
//
|
|
// pACE: Pointer to source Access Control Entry
|
|
// lpOnjectName: Pointer to the object name
|
|
//-----------------------------------------------------------------------//
|
|
DWORD
|
|
AddACE2List (
|
|
ACCESS_DENIED_ACE *pACE,
|
|
LPTSTR lpObjectName,
|
|
DWORD dwAclSize)
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
DWORD dwLen;
|
|
LPDENIED_ACE_LIST pList1;
|
|
LPDENIED_ACE_LIST pList2;
|
|
|
|
if (!pACE)
|
|
{
|
|
dwRet = ERROR_INVALID_PARAMETER;
|
|
goto Exit;
|
|
}
|
|
|
|
pList1 = (LPDENIED_ACE_LIST)calloc (sizeof(DENIED_ACE_LIST), 1);
|
|
if (!pList1)
|
|
{
|
|
dwRet = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
pList1->next = NULL;
|
|
pList1->dwAclSize = dwAclSize;
|
|
pList1->pace = (ACCESS_DENIED_ACE *)calloc(((PACE_HEADER)pACE)->AceSize, 1);
|
|
if (!(pList1->pace))
|
|
{
|
|
dwRet = ERROR_NOT_ENOUGH_MEMORY;
|
|
free (pList1);
|
|
goto Exit;
|
|
}
|
|
memcpy (pList1->pace, pACE, ((PACE_HEADER)pACE)->AceSize);
|
|
dwLen = lstrlen(lpObjectName)+1;
|
|
pList1->lpObjectName = (LPTSTR)calloc (dwLen, sizeof(TCHAR));
|
|
if (!(pList1->lpObjectName))
|
|
{
|
|
dwRet = ERROR_NOT_ENOUGH_MEMORY;
|
|
free (pList1);
|
|
free (pList1->pace);
|
|
goto Exit;
|
|
}
|
|
hr = StringCchCopy (pList1->lpObjectName, dwLen, lpObjectName);
|
|
if (hr != S_OK)
|
|
{
|
|
dwRet = HRESULT_CODE(hr);
|
|
free (pList1);
|
|
free (pList1->pace);
|
|
goto Exit;
|
|
}
|
|
|
|
pList2 = g_DeniedACEList;
|
|
if (pList2)
|
|
{
|
|
while (pList2->next)
|
|
pList2 = pList2->next;
|
|
|
|
pList2->next = pList1;
|
|
pList1->previous = pList2;
|
|
}
|
|
else
|
|
{
|
|
g_DeniedACEList = pList1;
|
|
pList1->previous = NULL;
|
|
}
|
|
|
|
Exit:
|
|
return dwRet;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// RemoveDeniedACEFromACL: Remove Denied ACE from ACL
|
|
//
|
|
// Acl: Pointer to Access Control List
|
|
// lpOnjectName: Pointer to the object name
|
|
//-----------------------------------------------------------------------//
|
|
DWORD
|
|
RemoveDeniedACEFromACL (
|
|
PACL Acl,
|
|
LPTSTR lpObjectName)
|
|
{
|
|
ACL_SIZE_INFORMATION aclSizeInfo;
|
|
ULONG i;
|
|
ACCESS_DENIED_ACE *accessDeniedAce;
|
|
LPVOID ace;
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
ACE_HEADER *aceHeader;
|
|
|
|
GetAclInformation (Acl, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation);
|
|
|
|
for (i = 0; i < aclSizeInfo.AceCount; i++)
|
|
{
|
|
if (!GetAce (Acl, i, &ace))
|
|
{
|
|
dwRet = GetLastError();
|
|
if (dwRet == ERROR_NO_MORE_ITEMS)
|
|
dwRet = ERROR_SUCCESS;
|
|
}
|
|
|
|
aceHeader = (ACE_HEADER *) ace;
|
|
|
|
if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE)
|
|
{
|
|
accessDeniedAce = (ACCESS_DENIED_ACE *) ace;
|
|
AddACE2List (accessDeniedAce, lpObjectName, aclSizeInfo.AclBytesInUse);
|
|
if (!DeleteAce (Acl, i))
|
|
dwRet = GetLastError();
|
|
else
|
|
DPF(REGmsg, L"Remove denied ACE from ACL: ObjectName=%s", lpObjectName);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// AdjustObjectSecurity: Add full control ACE for local administrator.
|
|
//
|
|
// lpObjectName: Object Name
|
|
// ObjectType: Object Type
|
|
// ppOldSidOwner: Current object owner
|
|
// bSetOrRestore: True --- Add ACE, FALSE --- Remove ACE
|
|
//-----------------------------------------------------------------------//
|
|
DWORD AdjustObjectSecurity (
|
|
LPTSTR lpObjectName,
|
|
SE_OBJECT_TYPE ObjectType,
|
|
BOOL bSetOrRestore)
|
|
{
|
|
DWORD dwErr;
|
|
HRESULT hr;
|
|
PSID psid = NULL;
|
|
PSECURITY_DESCRIPTOR pSD;
|
|
PACL pDacl = NULL;
|
|
PACL psidDacl = NULL;
|
|
SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION;
|
|
|
|
|
|
dwErr = GetNamedSecurityInfo(lpObjectName,
|
|
ObjectType,
|
|
secInfo,
|
|
NULL,
|
|
NULL,
|
|
&psidDacl,
|
|
NULL,
|
|
&pSD);
|
|
|
|
if (dwErr == ERROR_ACCESS_DENIED)
|
|
{
|
|
TCHAR szString[MAX_PATH*2];
|
|
TCHAR szCaption[MAX_PATH];
|
|
|
|
LoadString((HINSTANCE)g_hInstDll, IDS_OWNERSHIP, szCaption, MAX_PATH-1);
|
|
hr = StringCchPrintf(szString, MAX_PATH*2-1, szCaption, lpObjectName);
|
|
LoadString((HINSTANCE)g_hInstDll, IDS_MAIN_TITLE, szCaption, MAX_PATH-1);
|
|
|
|
if (SUCCEEDED(hr) && MessageBox(GetConsoleWindow(), szString, szCaption, MB_YESNO) == IDYES)
|
|
{
|
|
if (ChangeOwner(lpObjectName, ObjectType) == ERROR_SUCCESS)
|
|
{
|
|
DPF(REGmsg, L"Administrator takes over the ownership: ObjectName=%s", lpObjectName);
|
|
dwErr = GetNamedSecurityInfo(lpObjectName,
|
|
ObjectType,
|
|
secInfo,
|
|
NULL,
|
|
NULL,
|
|
&psidDacl,
|
|
NULL,
|
|
&pSD);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
pDacl = psidDacl;
|
|
|
|
if (bSetOrRestore)
|
|
{
|
|
dwErr = AddAccessAllowedACEToACL (&pDacl, GENERIC_ALL | SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL);
|
|
if (dwErr == ERROR_SUCCESS)
|
|
DPF(REGmsg, L"Add Administrator with full control to ACL: ObjectName=%s", lpObjectName);
|
|
else
|
|
DPF(REGerr, L"Fails to add Administrator with full control to ACL: ObjectName=%s", lpObjectName);
|
|
}
|
|
else
|
|
{
|
|
dwErr = RemoveACEFromACL(pDacl);
|
|
if (dwErr == ERROR_SUCCESS)
|
|
DPF(REGmsg, L"Remove Administrator with full control from ACL: ObjectName=%s", lpObjectName);
|
|
else
|
|
DPF(REGerr, L"Fails to remove Administrator with full control from ACL: ObjectName=%s", lpObjectName);
|
|
}
|
|
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
dwErr = SetNamedSecurityInfo(lpObjectName,
|
|
ObjectType,
|
|
secInfo,
|
|
NULL,
|
|
NULL,
|
|
pDacl,
|
|
NULL);
|
|
}
|
|
if (psidDacl != pDacl && pDacl)
|
|
free(pDacl);
|
|
|
|
LocalFree(pSD);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
#define ACCESS_STATUS_ALLOWED 0
|
|
#define ACCESS_STATUS_DENIED 1
|
|
#define ACCESS_STATUS_NOTPRESENT 2
|
|
|
|
HRESULT GetObjectAccessStatus(
|
|
LPTSTR lpObjectName,
|
|
SE_OBJECT_TYPE ObjectType,
|
|
PSID pOwnerSid,
|
|
PDWORD pdwStatus)
|
|
{
|
|
DWORD dwErr;
|
|
HRESULT hr;
|
|
PSECURITY_DESCRIPTOR pSD = NULL;
|
|
PACL psidDacl = NULL;
|
|
SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION;
|
|
|
|
ACL_SIZE_INFORMATION aclSizeInfo;
|
|
LPVOID ace;
|
|
ACE_HEADER *aceHeader;
|
|
ULONG i;
|
|
ACCESS_MASK dwAllowMask,dwDeniedMask;
|
|
|
|
|
|
|
|
if (!lpObjectName || !pOwnerSid || !pdwStatus)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto cleanup;
|
|
}
|
|
dwErr = GetNamedSecurityInfo(lpObjectName,
|
|
ObjectType,
|
|
secInfo,
|
|
NULL,
|
|
NULL,
|
|
&psidDacl,
|
|
NULL,
|
|
&pSD);
|
|
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
goto cleanup;
|
|
}
|
|
if (!psidDacl)
|
|
{
|
|
// in FS, this must be FAT/FAT32
|
|
hr = S_OK;
|
|
*pdwStatus = ACCESS_STATUS_ALLOWED;
|
|
goto cleanup;
|
|
}
|
|
if (!GetAclInformation (psidDacl,
|
|
(LPVOID) &aclSizeInfo,
|
|
(DWORD) sizeof (ACL_SIZE_INFORMATION),
|
|
AclSizeInformation))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
goto cleanup;
|
|
}
|
|
|
|
*pdwStatus = ACCESS_STATUS_NOTPRESENT;
|
|
dwAllowMask = dwDeniedMask = 0;
|
|
|
|
for (i = 0; i < aclSizeInfo.AceCount; i++)
|
|
{
|
|
ACCESS_ALLOWED_ACE *accessAllowedAce;
|
|
ACCESS_DENIED_ACE *accessDeniedAce;
|
|
PSID pAclSid;
|
|
|
|
if (!GetAce (psidDacl, i, &ace))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
goto cleanup;
|
|
}
|
|
|
|
aceHeader = (ACE_HEADER *) ace;
|
|
switch (aceHeader->AceType)
|
|
{
|
|
case ACCESS_ALLOWED_ACE_TYPE:
|
|
accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace;
|
|
pAclSid = (PSID) &accessAllowedAce->SidStart;
|
|
if (EqualSid (pOwnerSid, pAclSid))
|
|
{
|
|
dwAllowMask |= accessAllowedAce->Mask;
|
|
}
|
|
break;
|
|
case ACCESS_DENIED_ACE_TYPE:
|
|
accessDeniedAce = (ACCESS_DENIED_ACE *) ace;
|
|
pAclSid = (PSID) &accessDeniedAce->SidStart;
|
|
if (EqualSid (pOwnerSid, pAclSid))
|
|
{
|
|
dwDeniedMask |= accessDeniedAce->Mask;
|
|
}
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
}
|
|
GENERIC_MAPPING gm;
|
|
gm.GenericRead = FILE_GENERIC_READ ;
|
|
gm.GenericWrite = FILE_GENERIC_WRITE ;
|
|
gm.GenericExecute = FILE_GENERIC_EXECUTE ;
|
|
gm.GenericAll = FILE_ALL_ACCESS ;
|
|
|
|
DWORD dwExpected = GENERIC_ALL|GENERIC_WRITE|GENERIC_READ;
|
|
|
|
MapGenericMask(&dwExpected,&gm);
|
|
|
|
if (AreAnyAccessesGranted(dwDeniedMask,dwExpected))
|
|
{
|
|
*pdwStatus = ACCESS_STATUS_DENIED;
|
|
hr = S_OK;
|
|
goto cleanup;
|
|
}
|
|
dwExpected = GENERIC_ALL;
|
|
MapGenericMask(&dwExpected,&gm);
|
|
if (AreAllAccessesGranted(dwAllowMask,dwExpected))
|
|
{
|
|
*pdwStatus = ACCESS_STATUS_ALLOWED;
|
|
hr = S_OK;
|
|
goto cleanup;
|
|
}
|
|
dwExpected = GENERIC_WRITE|GENERIC_READ;
|
|
MapGenericMask(&dwExpected,&gm);
|
|
if (AreAllAccessesGranted(dwAllowMask,dwExpected))
|
|
{
|
|
*pdwStatus = ACCESS_STATUS_ALLOWED;
|
|
hr = S_OK;
|
|
goto cleanup;
|
|
}
|
|
*pdwStatus = ACCESS_STATUS_NOTPRESENT;
|
|
hr = S_OK;
|
|
|
|
cleanup:
|
|
if (pSD)
|
|
{
|
|
LocalFree(pSD);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT IsObjectAccessiablebyLocalSys(
|
|
LPTSTR lpObjectName,
|
|
SE_OBJECT_TYPE ObjectType,
|
|
PBOOL pbCanAccess)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
PSID pUserSid = NULL;
|
|
DWORD dwLocal,dwEveryone,dwAdmins;
|
|
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
|
|
|
|
*pbCanAccess = FALSE;
|
|
|
|
//Local System
|
|
if (!ConvertStringSidToSid(TEXT("S-1-5-18"),&pUserSid))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
pUserSid = NULL;
|
|
goto cleanup;
|
|
}
|
|
hr = GetObjectAccessStatus(lpObjectName,ObjectType,pUserSid,&dwLocal);
|
|
if (hr != S_OK)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
if (dwLocal == ACCESS_STATUS_DENIED)
|
|
{
|
|
*pbCanAccess = FALSE;
|
|
goto cleanup;
|
|
}
|
|
LocalFree(pUserSid);
|
|
pUserSid = NULL;
|
|
|
|
//Everyone
|
|
if (!ConvertStringSidToSid(TEXT("S-1-1-0"),&pUserSid))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
pUserSid = NULL;
|
|
goto cleanup;
|
|
}
|
|
hr = GetObjectAccessStatus(lpObjectName,ObjectType,pUserSid,&dwEveryone);
|
|
if (hr != S_OK)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
if (dwEveryone == ACCESS_STATUS_DENIED)
|
|
{
|
|
*pbCanAccess = FALSE;
|
|
goto cleanup;
|
|
}
|
|
LocalFree(pUserSid);
|
|
pUserSid = NULL;
|
|
|
|
//Local Admins
|
|
if(!AllocateAndInitializeSid(&siaNtAuthority, 2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&pUserSid))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
pUserSid = NULL;
|
|
goto cleanup;
|
|
}
|
|
hr = GetObjectAccessStatus(lpObjectName,ObjectType,pUserSid,&dwAdmins);
|
|
if (hr != S_OK)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
if (dwAdmins == ACCESS_STATUS_DENIED)
|
|
{
|
|
*pbCanAccess = FALSE;
|
|
goto cleanup;
|
|
}
|
|
LocalFree(pUserSid);
|
|
pUserSid = NULL;
|
|
if (dwEveryone == ACCESS_STATUS_ALLOWED)
|
|
{
|
|
*pbCanAccess = TRUE;
|
|
}
|
|
else if ( (dwAdmins ==ACCESS_STATUS_ALLOWED) && (dwLocal ==ACCESS_STATUS_ALLOWED) )
|
|
{
|
|
*pbCanAccess = TRUE;
|
|
}
|
|
else
|
|
{
|
|
*pbCanAccess = FALSE;
|
|
}
|
|
hr = S_OK;
|
|
|
|
cleanup:
|
|
if (pUserSid)
|
|
{
|
|
LocalFree(pUserSid);
|
|
}
|
|
return hr;
|
|
}
|
|
|