以编程方式设置ACCESS\u ALLOWED\u ACE,得到与RegEdit不同的结果
我有一个有趣的问题,我希望有人能解释一下。我们正在做以下工作:以编程方式设置ACCESS\u ALLOWED\u ACE,得到与RegEdit不同的结果,c,windows,permissions,registrykey,C,Windows,Permissions,Registrykey,我有一个有趣的问题,我希望有人能解释一下。我们正在做以下工作: 创建一个注册表项 使用SetSecurityDescriptorDacl向DACL添加允许的访问权限 查看注册表中的注册表项(权限看起来很好) 在Regedit中,添加新的子项 查看子密钥的权限 Regedit报告权限顺序不正确(并且似乎添加了一些意外的权限) 不过 如果在Regedit中创建第一个键而不是以编程方式创建,然后重复步骤3-5,则子键创建正确 使用一些额外的代码(下面不包括),我比较了来自Regedit创建的键和通过编
#include "stdafx.h"
#include <Windows.h>
#include <Sddl.h>
BOOL AddAceToKey(HKEY hKey, PSID psid)
{
ACCESS_ALLOWED_ACE *pace = NULL;
ACL_SIZE_INFORMATION aclSizeInfo;
BOOL bDaclExist;
BOOL bDaclPresent;
BOOL bSuccess = FALSE;
DWORD dwNewAclSize;
DWORD dwSidSize = 0;
DWORD dwSdSizeNeeded = 0;
PACL pacl;
PACL pNewAcl = NULL;
PSECURITY_DESCRIPTOR psd = NULL;
PSECURITY_DESCRIPTOR psdNew = NULL;
PVOID pTempAce;
SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
unsigned int i;
__try
{
// Obtain the DACL for the key.
LONG lResult = RegGetKeySecurity
( hKey
, si
, 0
, &dwSdSizeNeeded
);
if ( lResult != ERROR_SUCCESS )
if ( lResult == ERROR_INSUFFICIENT_BUFFER)
{
psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwSdSizeNeeded);
if (psd == NULL)
__leave;
psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwSdSizeNeeded);
if (psdNew == NULL)
__leave;
dwSidSize = dwSdSizeNeeded;
if (RegGetKeySecurity(
hKey,
si,
psd,
&dwSdSizeNeeded) != ERROR_SUCCESS
)
__leave;
}
else
__leave;
// Create a new DACL.
if (!InitializeSecurityDescriptor(
psdNew,
SECURITY_DESCRIPTOR_REVISION)
)
__leave;
// Get the DACL from the security descriptor.
if (!GetSecurityDescriptorDacl(
psd,
&bDaclPresent,
&pacl,
&bDaclExist)
)
__leave;
// Initialize the ACL.
ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
aclSizeInfo.AclBytesInUse = sizeof(ACL);
// Call only if the DACL is not NULL.
if (pacl != NULL)
{
// get the file ACL size info
if (!GetAclInformation(
pacl,
(LPVOID)&aclSizeInfo,
sizeof(ACL_SIZE_INFORMATION),
AclSizeInformation)
)
__leave;
}
// Compute the size of the new ACL.
dwNewAclSize = aclSizeInfo.AclBytesInUse +
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD);
// Allocate memory for the new ACL.
pNewAcl = (PACL)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwNewAclSize);
if (pNewAcl == NULL)
__leave;
// Initialize the new DACL.
if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
__leave;
// Add the ACE to the key
pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) -
sizeof(DWORD));
if (pace == NULL)
__leave;
pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
pace->Header.AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
pace->Header.AceSize = LOWORD(sizeof(ACCESS_ALLOWED_ACE) +
GetLengthSid(psid) - sizeof(DWORD));
pace->Mask = KEY_ALL_ACCESS;
if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))
__leave;
if (!AddAce(
pNewAcl,
ACL_REVISION,
MAXDWORD,
(LPVOID)pace,
pace->Header.AceSize)
)
__leave;
// If DACL is present, copy it to a new DACL.
if (bDaclPresent)
{
// Copy the ACEs to the new ACL.
if (aclSizeInfo.AceCount)
{
for (i=0; i < aclSizeInfo.AceCount; i++)
{
// Get an ACE.
if (!GetAce(pacl, i, &pTempAce))
__leave;
// Add the ACE to the new ACL.
if (!AddAce(
pNewAcl,
ACL_REVISION,
MAXDWORD,
pTempAce,
((PACE_HEADER)pTempAce)->AceSize)
)
__leave;
}
}
}
// Set a new DACL for the security descriptor.
if (!SetSecurityDescriptorDacl(
psdNew,
TRUE,
pNewAcl,
FALSE)
)
__leave;
// Set the new security descriptor for the window station.
if (RegSetKeySecurity( hKey, si, psdNew ) != ERROR_SUCCESS)
__leave;
// Indicate success.
bSuccess = TRUE;
}
__finally
{
// Free the allocated buffers.
if (pace != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)pace);
if (pNewAcl != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
if (psd != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
if (psdNew != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
}
return bSuccess;
}
int _tmain(int argc, _TCHAR* argv[])
{
HKEY hKey;
DWORD dwDisposition;
LONG lResult = RegCreateKeyEx
( HKEY_LOCAL_MACHINE
, L"SOFTWARE\\MyCompany"
, 0
, NULL
, REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS | KEY_WOW64_64KEY
, NULL
, &hKey
, &dwDisposition
);
if ( lResult != ERROR_SUCCESS )
{
return 1;
}
PSID pSid;
// The 'Users' SID.
ConvertStringSidToSid( L"S-1-5-32-545", &pSid );
AddAceToKey( hKey, pSid );
LocalFree( pSid );
RegCloseKey( hKey );
return 0;
}
#包括“stdafx.h”
#包括
#包括
BOOL AddAceToKey(HKEY HKEY,PSID PSID)
{
允许访问\u ACE*pace=NULL;
ACL_SIZE_信息aclSizeInfo;
布尔·比塔克西斯特;
BOOL-bdacl-present;
BOOL bsucces=假;
DWORD dwNewAclSize;
DWORD dwSidSize=0;
DWORD DWSDSIZENEDED=0;
PACL-PACL;
PACL pNewAcl=NULL;
PSECURITY_描述符psd=NULL;
PSECURITY_描述符psdNew=NULL;
PVOID;
安全信息si=DACL安全信息;
无符号整数i;
__试一试
{
//获取密钥的DACL。
LONG lResult=RegGetKeySecurity
(hKey)
,si
, 0
,&dwsdsizeneed
);
如果(lResult!=错误\u成功)
如果(lResult==错误\u缓冲区不足)
{
psd=(PSECURITY\u描述符)HeapAlloc(
GetProcessHeap(),
堆零内存,
dwsdsizeneed);
如果(psd==NULL)
__离开;
psdNew=(PSECURITY_描述符)HeapAlloc(
GetProcessHeap(),
堆零内存,
dwsdsizeneed);
if(psdNew==NULL)
__离开;
dwSidSize=DWSDSIZENEED;
if(RegGetKeySecurity(
香港大学,
硅,
psd,
&dwSdSizeNeeded)!=错误\u成功
)
__离开;
}
其他的
__离开;
//创建一个新的DACL。
如果(!InitializeSecurityDescriptor(
psdNew,
安全性(描述符(修订版)
)
__离开;
//从安全描述符获取DACL。
如果(!GetSecurityDescriptorDacl(
psd,
&现在,
&pacl,
&b(马克思主义)
)
__离开;
//初始化ACL。
零内存(&aclSizeInfo,sizeof(ACL_SIZE_信息));
aclSizeInfo.AclBytesInUse=sizeof(ACL);
//仅当DACL不为空时调用。
如果(pacl!=NULL)
{
//获取文件ACL大小信息
如果(!GetAclInformation(
pacl,
(LPVOID)和aclSizeInfo,
sizeof(ACL大小信息),
ACLSIZE信息)
)
__离开;
}
//计算新ACL的大小。
dwNewAclSize=aclSizeInfo.AclBytesInUse+
sizeof(允许访问)+GetLengthSid(psid)-sizeof(DWORD);
//为新ACL分配内存。
pNewAcl=(PACL)HeapAlloc(
GetProcessHeap(),
堆零内存,
dw(新尺寸);
如果(pNewAcl==NULL)
__离开;
//初始化新的DACL。
如果(!InitializeCal(pNewAcl、dwNewAclSize、ACL_修订版))
__离开;
//将ACE添加到密钥中
速度=(允许访问速度*)HeapAlloc(
GetProcessHeap(),
堆零内存,
sizeof(允许访问)+GetLengthSid(psid)-
西泽夫(德沃德));
如果(速度==NULL)
__离开;
pace->Header.AceType=ACCESS\u ALLOWED\u ACE\u TYPE;
pace->Header.AceFlags=容器_继承|对象_继承_ACE;
pace->Header.AceSize=LOWORD(sizeof(允许访问)+
GetLengthSid(psid)-sizeof(DWORD));
速度->掩码=键所有访问;
if(!CopySid(GetLengthSid(psid),&pace->SidStart,psid))
__离开;
如果(!AddAce(
pNewAcl,
ACL_修订版,
马克斯沃德,
(LPVOID)速度,
速度->页眉.AceSize)
)
__离开;
//如果存在DACL,请将其复制到新的DACL。
如果(bDaclPresent)
{
//将ACE复制到新ACL。
if(aclSizeInfo.acecont)
{
对于(i=0;iAceSize)
)
__离开;
}
}
}
//为安全描述符设置新的DACL。
如果(!SetSecurityDescriptorDacl(
psdNew,
是的,
pNewAcl,
(错误)
)
__离开;
//为窗口站设置新的安全描述符。
if(RegSetKeySecurity(hKey、si、psdNew)!=错误\成功)
__离开;
//表示成功。
B