適切な 随意アクセス制御リスト (DACL) を作成することは、アプリケーション開発で必要かつ重要な部分です。 NULL DACL ではすべてのユーザーに対するすべての種類のアクセスが許可されるため、NULL DACL を使用しないでください。
Warning
NULL DACL は、信頼されていないユーザーやリモートの攻撃者を含むすべてのユーザーにフル アクセスを許可します。 セキュリティ保護可能なオブジェクトには NULL DACL を使用しないでください。 広範なアクセスを許可する必要がある場合は、必要な最小限のアクセス許可を付与する明示的な DACL を作成します。 空の DACL (0 個の ACE を持つ DACL) は、すべてのアクセスを拒否します。許可するアクセス許可がわからない場合は、これがセキュリティで保護された既定値です。
次の例は、DACL を適切に作成する方法を示しています。 この例には、 セキュリティ記述子定義言語 (SDDL) を使用して DACL で許可および拒否されたアクセス制御を定義する関数 CreateMyDACL が含まれています。 アプリケーションのオブジェクトに異なるアクセスを提供するには、必要に応じて CreateMyDACL 関数を変更します。
この例では、次のようになります。
main 関数は、 SECURITY_ATTRIBUTES 構造体のアドレスを CreateMyDACL 関数に渡します。
CreateMyDACL 関数は、SDDL 文字列を使用して次の操作を行います。
- ゲスト および匿名ログオン ユーザーへのアクセスを拒否します。
- 認証済みユーザーへの読み取り/書き込み/実行アクセスを許可します。
- 管理者に完全な制御を許可します。
SDDL 文字列形式の詳細については、「 セキュリティ記述子文字列形式」を参照してください。
CreateMyDACL 関数は 、ConvertStringSecurityDescriptorToSecurityDescriptor 関数を呼び出して、SDDL 文字列を セキュリティ記述子に変換します。 セキュリティ記述子は、SECURITY_ATTRIBUTES構造体の lpSecurityDescriptor メンバーによって指されます。 CreateMyDACL は 、ConvertStringSecurityDescriptorToSecurityDescriptor からの戻り値を main 関数に送信します。
main 関数は、更新された SECURITY_ATTRIBUTES 構造を使用して、 CreateDirectory 関数によって作成される新しいフォルダーの DACL を指定します。
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);
}