以下示例演示服务器如何检查安全描述符允许客户端的访问权限。 该示例使用 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;
}