誰かが光を当ててくれることを望んでいる興味深い問題があります。私たちは次のことを行っています。
- レジストリ キーを作成します。
- SetSecurityDescriptorDacl を使用して、ACCESS_ALLOWED_ACE を DACL に追加します。
- Regedit でキーを表示 (権限は問題ないようです)
- Regedit で、新しいサブ キーを追加します。
- サブキーの権限を表示します。
Regedit は、アクセス許可が正しく順序付けされていないことを報告します (そして、いくつかの予期しないアクセス許可が追加されたようです)。
でも。
プログラムではなく Regedit で最初のキーを作成し、手順 3. ~ 5. を繰り返すと、サブ キーが正しく作成されます。
いくつかの追加コード (以下には含まれていません) を使用して、Regedit で作成されたキーとプログラムで作成されたキーの DACL を比較しましたが、それらは同一です。しかし、コードを介してキーを作成すると、何かが間違っているようです。
以下は、キーを作成してアクセスを変更するコードの例です。これは基本的に MSDN の例であり、レジストリ キーを変更するために微調整しただけです。繰り返しますが、キーは正しく作成されますが、サブ キーは正しくありません。
手がかりは大歓迎です。
#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;
}