282 lines
5.6 KiB
C++
282 lines
5.6 KiB
C++
/*++
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name :
|
|
certmapprovider.cxx
|
|
|
|
Abstract:
|
|
Active Directory Certificate Mapper provider
|
|
|
|
Author:
|
|
Bilal Alam (balam) 10-Jan-2000
|
|
|
|
Environment:
|
|
Win32 - User Mode
|
|
|
|
Project:
|
|
ULW3.DLL
|
|
--*/
|
|
|
|
#include "precomp.hxx"
|
|
#include "certmapprovider.hxx"
|
|
|
|
HRESULT
|
|
CERTMAP_AUTH_PROVIDER::DoesApply(
|
|
W3_MAIN_CONTEXT * pMainContext,
|
|
BOOL * pfApplies
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Does certificate map authentication apply?
|
|
|
|
Arguments:
|
|
|
|
pMainContext - Main context
|
|
pfApplies - Set to TRUE if cert map auth applies
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
CERTIFICATE_CONTEXT * pCertificateContext;
|
|
URL_CONTEXT * pUrlContext = NULL;
|
|
W3_METADATA * pMetaData = NULL;
|
|
BOOL fApplies = FALSE;
|
|
|
|
if ( pMainContext == NULL ||
|
|
pfApplies == NULL )
|
|
{
|
|
DBG_ASSERT( FALSE );
|
|
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
//
|
|
// If cert mapping is not allowed for this vroot, then ignore client
|
|
// cert token and let other authentication mechanisms do their thing
|
|
//
|
|
|
|
pUrlContext = pMainContext->QueryUrlContext();
|
|
DBG_ASSERT( pUrlContext != NULL );
|
|
|
|
pMetaData = pUrlContext->QueryMetaData();
|
|
DBG_ASSERT( pMetaData != NULL );
|
|
|
|
DBG_ASSERT( pMainContext->QuerySite() );
|
|
|
|
if ( !pMainContext->QuerySite()->QueryUseDSMapper() )
|
|
{
|
|
fApplies = FALSE;
|
|
}
|
|
else if ( pMetaData->QuerySslAccessPerms() & VROOT_MASK_MAP_CERT )
|
|
{
|
|
pCertificateContext = pMainContext->QueryCertificateContext();
|
|
if ( pCertificateContext != NULL )
|
|
{
|
|
if ( pCertificateContext->QueryImpersonationToken() != NULL )
|
|
{
|
|
fApplies = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
*pfApplies = fApplies;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
HRESULT
|
|
CERTMAP_AUTH_PROVIDER::DoAuthenticate(
|
|
W3_MAIN_CONTEXT * pMainContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create a user context representing a cert mapped token
|
|
|
|
Arguments:
|
|
|
|
pMainContext - Main context
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
CERTMAP_USER_CONTEXT * pUserContext = NULL;
|
|
CERTIFICATE_CONTEXT * pCertificateContext = NULL;
|
|
HANDLE hImpersonation;
|
|
BOOL fDelegatable = FALSE;
|
|
HRESULT hr = NO_ERROR;
|
|
|
|
if ( pMainContext == NULL )
|
|
{
|
|
DBG_ASSERT( FALSE );
|
|
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
pCertificateContext = pMainContext->QueryCertificateContext();
|
|
DBG_ASSERT( pCertificateContext != NULL );
|
|
|
|
hImpersonation = pCertificateContext->QueryImpersonationToken();
|
|
DBG_ASSERT( hImpersonation != NULL );
|
|
|
|
//
|
|
// Create the user context for this request
|
|
//
|
|
|
|
pUserContext = new CERTMAP_USER_CONTEXT( this );
|
|
if ( pUserContext == NULL )
|
|
{
|
|
return HRESULT_FROM_WIN32( GetLastError() );
|
|
}
|
|
|
|
//
|
|
// Is this a delegatable token? Put another way is this token mapped
|
|
// using an IIS cert mapper (IIS cert mapper creates delegatable token,
|
|
// the DS mapper does not)
|
|
//
|
|
|
|
fDelegatable = FALSE;
|
|
|
|
hr = pUserContext->Create( hImpersonation, fDelegatable );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
pUserContext->DereferenceUserContext();
|
|
pUserContext = NULL;
|
|
return hr;
|
|
}
|
|
|
|
pMainContext->SetUserContext( pUserContext );
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
HRESULT
|
|
CERTMAP_AUTH_PROVIDER::OnAccessDenied(
|
|
W3_MAIN_CONTEXT * pMainContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
NOP since we have nothing to do on access denied
|
|
|
|
Arguments:
|
|
|
|
pMainContext - Main context
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// No headers to add
|
|
//
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
HRESULT
|
|
CERTMAP_USER_CONTEXT::Create(
|
|
HANDLE hImpersonation,
|
|
BOOL fDelegatable
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create a certificate mapped user context
|
|
|
|
Arguments:
|
|
|
|
hImpersonation - Impersonation token
|
|
fDelegatable - Is this token delegatable?
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
DWORD cchUserName = sizeof( _achUserName ) / sizeof( WCHAR );
|
|
|
|
if ( hImpersonation == NULL )
|
|
{
|
|
DBG_ASSERT( FALSE );
|
|
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
//
|
|
// First the easy stuff
|
|
//
|
|
|
|
_fDelegatable = fDelegatable;
|
|
|
|
_hImpersonationToken = hImpersonation;
|
|
|
|
//
|
|
// Now get the user name
|
|
//
|
|
|
|
if ( !SetThreadToken( NULL, _hImpersonationToken ) )
|
|
{
|
|
return HRESULT_FROM_WIN32( GetLastError() );
|
|
}
|
|
|
|
if ( !GetUserNameEx( NameSamCompatible,
|
|
_achUserName,
|
|
&cchUserName ) )
|
|
{
|
|
RevertToSelf();
|
|
return HRESULT_FROM_WIN32( GetLastError() );
|
|
}
|
|
|
|
RevertToSelf();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
HANDLE
|
|
CERTMAP_USER_CONTEXT::QueryPrimaryToken(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get a primary token
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HANDLE
|
|
|
|
--*/
|
|
{
|
|
if ( _hPrimaryToken == NULL )
|
|
{
|
|
if ( DuplicateTokenEx( _hImpersonationToken,
|
|
TOKEN_ALL_ACCESS,
|
|
NULL,
|
|
SecurityImpersonation,
|
|
TokenPrimary,
|
|
&_hPrimaryToken ) )
|
|
{
|
|
DBG_ASSERT( _hPrimaryToken != NULL );
|
|
}
|
|
}
|
|
|
|
return _hPrimaryToken;
|
|
}
|