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 中定義的非零錯誤碼。
言論
信任者的群組許可權是由本機計算機上的 GetEffectiveRightsFromAcl 所列舉,即使信任項正在遠端電腦上存取物件也一樣。 此函式不會評估遠端電腦上的群組許可權。
GetEffectiveRightsFromAcl 函式不會考慮下列事項:
- 判斷有效許可權時,針對對象的擁有者隱含授與訪問許可權,例如READ_CONTROL和WRITE_DAC。
- 在決定有效訪問許可權時,受託人持有的許可權。
- 在判斷有效訪問許可權時,與 登入會話相關聯的群組許可權,例如互動式、網路、已驗證的使用者等等。
- Resource Manager 原則。 例如,對於檔案物件,即使父代已拒絕,也可以由父代提供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 預處理器常數的定義,將 GetEffectiveRightsFromAcl 定義為自動選取此函式的 ANSI 或 Unicode 版本。 混合使用編碼中性別名與非編碼中性的程序代碼,可能會導致編譯或運行時間錯誤不符。 如需詳細資訊,請參閱函式原型的
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | Windows XP [僅限傳統型應用程式] |
支援的最低伺服器 | Windows Server 2003 [僅限傳統型應用程式] |
目標平臺 | 窗戶 |
標頭 | aclapi.h |
連結庫 | Advapi32.lib |
DLL | Advapi32.dll |