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
트러스티를 식별하는 TRUSTEE 구조체에 대한 포인터입니다. 수탁자는 사용자, 그룹 또는 프로그램(예: Windows 서비스)일 수 있습니다. 이름 또는 SID(보안 식별자)를 사용하여 수탁자를 식별할 수 있습니다.
[out] pAccessRights
트러스티의 유효 액세스 권한을 받는 ACCESS_MASK 변수에 대한 포인터입니다.
반환 값
함수가 성공하면 함수는 ERROR_SUCCESS 반환합니다.
함수가 실패하면 WinError.h에 정의된 0이 아닌 오류 코드를 반환합니다.
설명
GetEffectiveRightsFromAcl 함수는 ACL(액세스 제어 목록)의 모든 액세스 허용 및 액세스 거부 액세스 제어 항목(ACL)을 확인하여 수탁자의 유효 권한을 확인합니다. 그룹에 대한 권한을 허용하거나 거부하는 모든 ACE의 경우 GetEffectiveRightsFromAcl 은 그룹의 멤버를 열거하여 트러스티가 멤버인지 여부를 확인합니다. 함수는 그룹의 멤버를 열거할 수 없는 경우 오류를 반환합니다.
트러스티의 그룹 권한은 트러스티가 원격 컴퓨터의 개체에 액세스하는 경우에도 로컬 컴퓨터의 GetEffectiveRightsFromAcl 에 의해 열거됩니다. 이 함수는 원격 컴퓨터에서 그룹 권한을 평가하지 않습니다.
GetEffectiveRightsFromAcl 함수는 다음을 고려하지 않습니다.
- 유효 권한을 결정할 때 개체 소유자에 대한 액세스 권한(예: READ_CONTROL 및 WRITE_DAC)이 암시적으로 부여됩니다.
- 유효 액세스 권한을 결정할 때 트러스티가 보유하는 권한입니다.
- 효과적인 액세스 권한을 결정할 때 대화형, 네트워크, 인증된 사용자 등 로그 온 세션과 관련된 그룹 권한입니다.
- 리소스 관리자 정책. 예를 들어 파일 개체의 경우 개체에서 거부된 경우에도 부모가 삭제 및 읽기 특성을 제공할 수 있습니다.
예제
다음 예제에서는 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 헤더는 GETEffectiveRightsFromAcl을 유니코드 전처리기 상수의 정의에 따라 이 함수의 ANSI 또는 유니코드 버전을 자동으로 선택하는 별칭으로 정의합니다. 인코딩 중립 별칭을 인코딩 중립이 아닌 코드와 혼합하면 컴파일 또는 런타임 오류가 발생하는 불일치가 발생할 수 있습니다. 자세한 내용은 함수 프로토타입에 대한 규칙을 참조하세요.
요구 사항
요구 사항 | 값 |
---|---|
지원되는 최소 클라이언트 | Windows XP [데스크톱 앱만 해당] |
지원되는 최소 서버 | Windows Server 2003 [데스크톱 앱만 해당] |
대상 플랫폼 | Windows |
헤더 | aclapi.h |
라이브러리 | Advapi32.lib |
DLL | Advapi32.dll |