Checking A Client's Access

The following example shows how a server could check the access rights that a security descriptor allows for a client. The example uses the ImpersonateNamedPipeClient function, but it would work the same if you used any of the other impersonation functions. After impersonating the client, the example calls the OpenThreadToken function to get the impersonation token. It calls the MapGenericMask function to convert any generic access rights to the corresponding specific and standard rights according to the mapping specified in the GENERIC_MAPPING structure.

The AccessCheck function checks the requested access rights against the rights allowed for the client in the DACL of the security descriptor. To check access and generate an entry in the security event log, use the AccessCheckAndAuditAlarm function.

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;

}