Поделиться через


Проверка клиентского доступа с помощью списков управления доступом в 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;
}