2

我有一个有趣的问题,我希望有人能解释一下。我们正在做以下事情:

  1. 创建一个注册表项。
  2. 使用 SetSecurityDescriptorDacl 将 ACCESS_ALLOWED_ACE 添加到 DACL。
  3. 在 Regedit 中查看密钥(权限看起来不错)
  4. 在 Regedit 中,添加一个新的子键。
  5. 查看子键的权限。

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;
}
4

0 回答 0