DACL の作成

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

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

この例では次のとおりです。

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

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

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

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

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

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

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

注意

ConvertStringSecurityDescriptorToSecurityDescriptor などの SDDL 関数を正常にコンパイルするには、_WIN32_WINNT定数を 0x0500 以上として定義する必要があります。

 

#define _WIN32_WINNT 0x0500

#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);
}