DACL の作成

適切な 随意アクセス制御リスト (DACL) を作成することは、アプリケーション開発で必要かつ重要な部分です。 NULL DACL ではすべてのユーザーに対するすべての種類のアクセスが許可されるため、NULL DACL を使用しないでください。

Warning

NULL DACL は、信頼されていないユーザーやリモートの攻撃者を含むすべてのユーザーにフル アクセスを許可します。 セキュリティ保護可能なオブジェクトには NULL DACL を使用しないでください。 広範なアクセスを許可する必要がある場合は、必要な最小限のアクセス許可を付与する明示的な DACL を作成します。 空の DACL (0 個の ACE を持つ DACL) は、すべてのアクセスを拒否します。許可するアクセス許可がわからない場合は、これがセキュリティで保護された既定値です。

次の例は、DACL を適切に作成する方法を示しています。 この例には、 セキュリティ記述子定義言語 (SDDL) を使用して DACL で許可および拒否されたアクセス制御を定義する関数 CreateMyDACL が含まれています。 アプリケーションのオブジェクトに異なるアクセスを提供するには、必要に応じて CreateMyDACL 関数を変更します。

この例では、次のようになります。

  1. main 関数は、 SECURITY_ATTRIBUTES 構造体のアドレスを CreateMyDACL 関数に渡します。

  2. CreateMyDACL 関数は、SDDL 文字列を使用して次の操作を行います。

    • ゲスト および匿名ログオン ユーザーへのアクセスを拒否します。
    • 認証済みユーザーへの読み取り/書き込み/実行アクセスを許可します。
    • 管理者に完全な制御を許可します。

    SDDL 文字列形式の詳細については、「 セキュリティ記述子文字列形式」を参照してください。

  3. CreateMyDACL 関数は 、ConvertStringSecurityDescriptorToSecurityDescriptor 関数を呼び出して、SDDL 文字列を セキュリティ記述子に変換します。 セキュリティ記述子は、SECURITY_ATTRIBUTES構造体の lpSecurityDescriptor メンバーによって指されます。 CreateMyDACL は 、ConvertStringSecurityDescriptorToSecurityDescriptor からの戻り値を main 関数に送信します。

  4. main 関数は、更新された SECURITY_ATTRIBUTES 構造を使用して、 CreateDirectory 関数によって作成される新しいフォルダーの DACL を指定します。

  5. main 関数が SECURITY_ATTRIBUTES 構造体を使用して終了すると、main 関数は LocalFree 関数を呼び出すことによって lpSecurityDescriptor メンバーに割り当てられたメモリを解放します。

Note

ConvertStringSecurityDescriptorToSecurityDescriptor などの SDDL 関数を正常にコンパイルするには、_WIN32_WINNT定数を 0x0500 以上として定義する必要があります。 最新のアプリケーションの場合は、少なくともWindows 10 (0x0A00) をターゲットにします。

#include <windows.h>
#include <sddl.h>
#include <stdio.h>

#pragma comment(lib, "advapi32.lib")

BOOL CreateMyDACL(SECURITY_ATTRIBUTES *);

void main()
{
     SECURITY_ATTRIBUTES  sa;
      
     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
     sa.bInheritHandle = FALSE;  

     // Call function to set the DACL. The DACL
     // is set in the SECURITY_ATTRIBUTES 
     // lpSecurityDescriptor member.
     if (!CreateMyDACL(&sa))
     {
         // Error encountered; generate message and exit.
         printf("Failed CreateMyDACL\n");
         exit(1);
     }

     // Use the updated SECURITY_ATTRIBUTES to specify
     // security attributes for securable objects.
     // This example uses security attributes during
     // creation of a new directory.
     if (0 == CreateDirectory(TEXT("C:\\MyFolder"), &sa))
     {
         // Error encountered; generate message and exit.
         printf("Failed CreateDirectory\n");
         exit(1);
     }

     // Free the memory allocated for the SECURITY_DESCRIPTOR.
     if (NULL != LocalFree(sa.lpSecurityDescriptor))
     {
         // Error encountered; generate message and exit.
         printf("Failed LocalFree\n");
         exit(1);
     }
}


// CreateMyDACL.
//    Create a security descriptor that contains the DACL 
//    you want.
//    This function uses SDDL to make Deny and Allow ACEs.
//
// Parameter:
//    SECURITY_ATTRIBUTES * pSA
//    Pointer to a SECURITY_ATTRIBUTES structure. It is your
//    responsibility to properly initialize the 
//    structure and to free the structure's 
//    lpSecurityDescriptor member when you have
//    finished using it. To free the structure's 
//    lpSecurityDescriptor member, call the 
//    LocalFree function.
// 
// Return value:
//    FALSE if the address to the structure is NULL. 
//    Otherwise, this function returns the value from the
//    ConvertStringSecurityDescriptorToSecurityDescriptor 
//    function.
BOOL CreateMyDACL(SECURITY_ATTRIBUTES * pSA)
{
     // Define the SDDL for the DACL. This example sets 
     // the following access:
     //     Built-in guests are denied all access.
     //     Anonymous logon is denied all access.
     //     Authenticated users are allowed 
     //     read/write/execute access.
     //     Administrators are allowed full control.
     // Modify these values as needed to generate the proper
     // DACL for your application. 
     TCHAR * szSD = TEXT("D:")       // Discretionary ACL
        TEXT("(D;OICI;GA;;;BG)")     // Deny access to 
                                     // built-in guests
        TEXT("(D;OICI;GA;;;AN)")     // Deny access to 
                                     // anonymous logon
        TEXT("(A;OICI;GRGWGX;;;AU)") // Allow 
                                     // read/write/execute 
                                     // to authenticated 
                                     // users
        TEXT("(A;OICI;GA;;;BA)");    // Allow full control 
                                     // to administrators

    if (NULL == pSA)
        return FALSE;

     return ConvertStringSecurityDescriptorToSecurityDescriptor(
                szSD,
                SDDL_REVISION_1,
                &(pSA->lpSecurityDescriptor),
                NULL);
}