GetEffectiveRightsFromAclA 関数 (aclapi.h)
[GetEffectiveRightsFromAcl は、[要件] セクションで指定されたオペレーティング システムで使用できます。 今後のバージョンでは変更されるか、利用できなくなる場合もあります。 代わりに、次の例で示すメソッドを使用します。
GetEffectiveRightsFromAcl 関数は、ACL 構造体が指定したトラスティに付与する有効なアクセス権を取得します。 トラスティの有効なアクセス権は、 ACL がトラスティまたはトラスティがメンバーである任意のグループに付与するアクセス権です。
構文
DWORD GetEffectiveRightsFromAclA(
[in] PACL pacl,
[in] PTRUSTEE_A pTrustee,
[out] PACCESS_MASK pAccessRights
);
パラメーター
[in] pacl
トラスティの有効なアクセス権を取得する ACL 構造へのポインター。
[in] pTrustee
トラスティを識別する トラスティ 構造体へのポインター。 トラスティには、ユーザー、グループ、またはプログラム (Windows サービスなど) を指定できます。 名前またはセキュリティ識別子 (SID) を使用して、トラスティを識別できます。
[out] pAccessRights
トラスティの有効なアクセス権を受け取る ACCESS_MASK 変数へのポインター。
戻り値
関数が成功した場合、関数はERROR_SUCCESSを返します。
関数が失敗した場合、WinError.h で定義されている 0 以外のエラー コードが返されます。
注釈
GetEffectiveRightsFromAcl 関数は、アクセス制御リスト (ACL) 内のすべてのアクセス許可およびアクセス拒否アクセス制御エントリ (ACE) をチェックして、トラスティの有効な権限を決定します。 グループに対する権限を許可または拒否するすべての ACE について、 GetEffectiveRightsFromAcl はグループのメンバーを列挙して、トラスティがメンバーであるかどうかを判断します。 この関数は、グループのメンバーを列挙できない場合にエラーを返します。
トラスティのグループ権限は、トラスティがリモート コンピューター上のオブジェクトにアクセスしている場合でも、ローカル コンピューター上の GetEffectiveRightsFromAcl によって列挙されます。 この関数は、リモート コンピューターのグループ権限を評価しません。
GetEffectiveRightsFromAcl 関数では、次の点は考慮されません。
- 有効な権限を決定するときに、オブジェクトの所有者に対して、READ_CONTROLやWRITE_DACなどのアクセス権を暗黙的に付与します。
- トラスティが有効なアクセス権を決定する際に保持される特権。
- ログオン セッションに関連付けられているグループ権限 (対話型、ネットワーク、認証されたユーザーなど) は、有効なアクセス権を決定します。
- リソース マネージャー ポリシー。 たとえば、ファイル オブジェクトの場合、Delete 属性と Read 属性は、オブジェクトに対して拒否された場合でも親から提供できます。
例
次の例は、 Authz API を使用して ACL から有効なアクセス権を取得する方法を示しています。
// Copyright (C) Microsoft. All rights reserved.
#include <windows.h>
#include <stdio.h>
#include <aclapi.h>
#include <tchar.h>
#include <strsafe.h> // for proper buffer handling
#include <authz.h>
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "authz.lib")
LPTSTR lpServerName = NULL;
PSID ConvertNameToBinarySid(LPTSTR pAccountName)
{
LPTSTR pDomainName = NULL;
DWORD dwDomainNameSize = 0;
PSID pSid = NULL;
DWORD dwSidSize = 0;
SID_NAME_USE sidType;
BOOL fSuccess = FALSE;
HRESULT hr = S_OK;
__try
{
LookupAccountName(
lpServerName, // look up on local system
pAccountName,
pSid, // buffer to receive name
&dwSidSize,
pDomainName,
&dwDomainNameSize,
&sidType);
// If the Name cannot be resolved, LookupAccountName will fail with
// ERROR_NONE_MAPPED.
if (GetLastError() == ERROR_NONE_MAPPED)
{
wprintf_s(_T("LookupAccountName failed with %d\n"), GetLastError());
__leave;
}
else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
pSid = (LPTSTR)LocalAlloc(LPTR, dwSidSize * sizeof(TCHAR));
if (pSid == NULL)
{
wprintf_s(_T("LocalAlloc failed with %d\n"), GetLastError());
__leave;
}
pDomainName = (LPTSTR)LocalAlloc(LPTR, dwDomainNameSize * sizeof(TCHAR));
if (pDomainName == NULL)
{
wprintf_s(_T("LocalAlloc failed with %d\n"), GetLastError());
__leave;
}
if (!LookupAccountName(
lpServerName, // look up on local system
pAccountName,
pSid, // buffer to receive name
&dwSidSize,
pDomainName,
&dwDomainNameSize,
&sidType))
{
wprintf_s(_T("LookupAccountName failed with %d\n"), GetLastError());
__leave;
}
}
// Any other error code
else
{
wprintf_s(_T("LookupAccountName failed with %d\n"), GetLastError());
__leave;
}
fSuccess = TRUE;
}
__finally
{
if(pDomainName != NULL)
{
LocalFree(pDomainName);
pDomainName = NULL;
}
// Free pSid only if failed;
// otherwise, the caller has to free it after use.
if (fSuccess == FALSE)
{
if(pSid != NULL)
{
LocalFree(pSid);
pSid = NULL;
}
}
}
return pSid;
}
void DisplayError(char* pszAPI, DWORD dwError)
{
LPVOID lpvMessageBuffer;
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM,
GetModuleHandle(L"Kernel32.dll"), dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // the user default language
(LPTSTR)&lpvMessageBuffer, 0, NULL))
{
wprintf_s(L"FormatMessage failed with %d\n", GetLastError());
ExitProcess(GetLastError());
}
// ...now display this string.
wprintf_s(L"ERROR: API = %s.\n", (char *)pszAPI);
wprintf_s(L" error code = %08X.\n", dwError);
wprintf_s(L" message = %s.\n", (char *)lpvMessageBuffer);
// Free the buffer allocated by the system.
LocalFree(lpvMessageBuffer);
ExitProcess(GetLastError());
}
void DisplayAccessMask(ACCESS_MASK Mask)
{
// This evaluation of the ACCESS_MASK is an example.
// Applications should evaluate the ACCESS_MASK as necessary.
wprintf_s(L"Effective Allowed Access Mask : %8X\n", Mask);
if (((Mask & GENERIC_ALL) == GENERIC_ALL)
|| ((Mask & FILE_ALL_ACCESS) == FILE_ALL_ACCESS))
{
wprintf_s(L"Full Control\n");
return;
}
if (((Mask & GENERIC_READ) == GENERIC_READ)
|| ((Mask & FILE_GENERIC_READ) == FILE_GENERIC_READ))
wprintf_s(L"Read\n");
if (((Mask & GENERIC_WRITE) == GENERIC_WRITE)
|| ((Mask & FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE))
wprintf_s(L"Write\n");
if (((Mask & GENERIC_EXECUTE) == GENERIC_EXECUTE)
|| ((Mask & FILE_GENERIC_EXECUTE) == FILE_GENERIC_EXECUTE))
wprintf_s(L"Execute\n");
}
void GetAccess(AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClient, PSECURITY_DESCRIPTOR psd)
{
AUTHZ_ACCESS_REQUEST AccessRequest = {0};
AUTHZ_ACCESS_REPLY AccessReply = {0};
BYTE Buffer[1024];
BOOL bRes = FALSE; // assume error
// Do AccessCheck.
AccessRequest.DesiredAccess = MAXIMUM_ALLOWED;
AccessRequest.PrincipalSelfSid = NULL;
AccessRequest.ObjectTypeList = NULL;
AccessRequest.ObjectTypeListLength = 0;
AccessRequest.OptionalArguments = NULL;
RtlZeroMemory(Buffer, sizeof(Buffer));
AccessReply.ResultListLength = 1;
AccessReply.GrantedAccessMask = (PACCESS_MASK) (Buffer);
AccessReply.Error = (PDWORD) (Buffer + sizeof(ACCESS_MASK));
if (!AuthzAccessCheck( 0,
hAuthzClient,
&AccessRequest,
NULL,
psd,
NULL,
0,
&AccessReply,
NULL) ) {
wprintf_s(_T("AuthzAccessCheck failed with %d\n"), GetLastError());
}
else
DisplayAccessMask(*(PACCESS_MASK)(AccessReply.GrantedAccessMask));
return;
}
BOOL GetEffectiveRightsForUser(AUTHZ_RESOURCE_MANAGER_HANDLE hManager,
PSECURITY_DESCRIPTOR psd,
LPTSTR lpszUserName)
{
PSID pSid = NULL;
BOOL bResult = FALSE;
LUID unusedId = { 0 };
AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext = NULL;
pSid = ConvertNameToBinarySid(lpszUserName);
if (pSid != NULL)
{
bResult = AuthzInitializeContextFromSid(0,
pSid,
hManager,
NULL,
unusedId,
NULL,
&hAuthzClientContext);
if (bResult)
{
GetAccess(hAuthzClientContext, psd);
AuthzFreeContext(hAuthzClientContext);
}
else
wprintf_s(_T("AuthzInitializeContextFromSid failed with %d\n"), GetLastError());
}
if(pSid != NULL)
{
LocalFree(pSid);
pSid = NULL;
}
return bResult;
}
void UseAuthzSolution(PSECURITY_DESCRIPTOR psd, LPTSTR lpszUserName)
{
AUTHZ_RESOURCE_MANAGER_HANDLE hManager;
BOOL bResult = FALSE;
bResult = AuthzInitializeResourceManager(AUTHZ_RM_FLAG_NO_AUDIT,
NULL, NULL, NULL, NULL, &hManager);
if (bResult)
{
bResult = GetEffectiveRightsForUser(hManager, psd, lpszUserName);
AuthzFreeResourceManager(hManager);
}
else
wprintf_s(_T("AuthzInitializeResourceManager failed with %d\n"), GetLastError());
}
void wmain(int argc, wchar_t *argv[])
{
DWORD dw;
PACL pacl;
PSECURITY_DESCRIPTOR psd;
PSID psid = NULL;
if (argc != 3)
{
wprintf_s(L"Usage: FileOrFolderName UserOrGroupName\n");
wprintf_s(L"Usage: FileOrFolderName UserOrGroupName\n");
return;
}
dw = GetNamedSecurityInfo(argv[1], SE_FILE_OBJECT, DACL_SECURITY_INFORMATION |
OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION, NULL, NULL, &pacl, NULL, &psd);
if (dw != ERROR_SUCCESS)
{ printf("couldn't do getnamedsecinfo \n");
DisplayError("GetNamedSecurityInfo", dw);
}
UseAuthzSolution(psd, argv[2]);
if(psid != NULL)
{
LocalFree(psid);
psid = NULL;
};
LocalFree(psd);
}
注意
aclapi.h ヘッダーは、Unicode プリプロセッサ定数の定義に基づいて、この関数の ANSI または Unicode バージョンを自動的に選択するエイリアスとして GetEffectiveRightsFromAcl を定義します。 encoding-neutral エイリアスの使用を encoding-neutral ではないコードと混在すると、コンパイル エラーまたはランタイム エラーが発生する不一致が発生する可能性があります。 詳細については、「 関数プロトタイプの規則」を参照してください。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows XP (デスクトップ アプリのみ) |
サポートされている最小のサーバー | Windows Server 2003 (デスクトップ アプリのみ) |
対象プラットフォーム | Windows |
ヘッダー | aclapi.h |
Library | Advapi32.lib |
[DLL] | Advapi32.dll |