Проверка клиентского доступа с помощью списков управления доступом в C++
В следующем примере показано, как сервер может проверить права доступа, которые дескриптор безопасности позволяет клиенту. В примере используется функция ImpersonateNamedPipeClient; однако она будет работать так же при использовании любых других функций олицетворения. После олицетворения клиента пример вызывает функцию OpenThreadToken, чтобы получить маркер олицетворения. Затем он вызывает функцию MapGenericMask, чтобы преобразовать все универсальные права доступа в соответствующие и стандартные права в соответствии с сопоставлением, указанным в структуре GENERIC_MAPPING.
Функция AccessCheck проверяет запрошенные права доступа на наличие прав, разрешенных клиенту в DACL дескриптора безопасности. Чтобы проверить доступ и создать запись в журнале событий безопасности, используйте функцию AccessCheckAndAuditAlarm.
#include <windows.h>
#pragma comment(lib, "advapi32.lib")
BOOL ImpersonateAndCheckAccess(
HANDLE hNamedPipe, // handle of pipe to impersonate
PSECURITY_DESCRIPTOR pSD, // security descriptor to check
DWORD dwAccessDesired, // access rights to check
PGENERIC_MAPPING pGeneric, // generic mapping for object
PDWORD pdwAccessAllowed // returns allowed access rights
)
{
HANDLE hToken;
PRIVILEGE_SET PrivilegeSet;
DWORD dwPrivSetSize = sizeof( PRIVILEGE_SET );
BOOL fAccessGranted=FALSE;
// Impersonate the client.
if (! ImpersonateNamedPipeClient(hNamedPipe) )
return FALSE;
// Get an impersonation token with the client's security context.
if (! OpenThreadToken( GetCurrentThread(), TOKEN_ALL_ACCESS,
TRUE, &hToken ))
{
goto Cleanup;
}
// Use the GENERIC_MAPPING structure to convert any
// generic access rights to object-specific access rights.
MapGenericMask( &dwAccessDesired, pGeneric );
// Check the client's access rights.
if( !AccessCheck(
pSD, // security descriptor to check
hToken, // impersonation token
dwAccessDesired, // requested access rights
pGeneric, // pointer to GENERIC_MAPPING
&PrivilegeSet, // receives privileges used in check
&dwPrivSetSize, // size of PrivilegeSet buffer
pdwAccessAllowed, // receives mask of allowed access rights
&fAccessGranted )) // receives results of access check
{
goto Cleanup;
}
Cleanup:
RevertToSelf();
if (hToken != INVALID_HANDLE_VALUE)
CloseHandle(hToken);
return fAccessGranted;
}