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