295 lines
7 KiB
C++
295 lines
7 KiB
C++
/*++
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name :
|
|
anonymousprovider.cxx
|
|
|
|
Abstract:
|
|
Anonymous authentication provider
|
|
|
|
Author:
|
|
Bilal Alam (balam) 10-Jan-2000
|
|
|
|
Environment:
|
|
Win32 - User Mode
|
|
|
|
Project:
|
|
ULW3.DLL
|
|
--*/
|
|
|
|
#include "precomp.hxx"
|
|
#include "anonymousprovider.hxx"
|
|
|
|
HRESULT
|
|
ANONYMOUS_AUTH_PROVIDER::DoesApply(
|
|
W3_MAIN_CONTEXT * pMainContext,
|
|
BOOL * pfApplies
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Does anonymous apply to this request?
|
|
|
|
Arguments:
|
|
|
|
pMainContext - Main context representing request
|
|
pfApplies - Set to true if SSPI is applicable
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
if ( pfApplies == NULL )
|
|
{
|
|
DBG_ASSERT( FALSE );
|
|
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
//
|
|
// Anonymous ALWAYS applies!
|
|
//
|
|
|
|
*pfApplies = TRUE;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
HRESULT
|
|
ANONYMOUS_AUTH_PROVIDER::DoAuthenticate(
|
|
W3_MAIN_CONTEXT * pMainContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Do anonymous authentication (trivial)
|
|
|
|
Arguments:
|
|
|
|
pMainContext - Main context representing request
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
W3_METADATA * pMetaData = NULL;
|
|
TOKEN_CACHE_ENTRY * pCachedToken = NULL;
|
|
HRESULT hr;
|
|
ANONYMOUS_USER_CONTEXT* pUserContext = NULL;
|
|
// add 1 to strUserDomain for separator "\"
|
|
STACK_STRA( strUserDomain, UNLEN + IIS_DNLEN + 1 + 1 );
|
|
STACK_STRA( strPassword, PWLEN + 1 );
|
|
// add 1 to strUserDomainW for separator "\"
|
|
STACK_STRU( strUserDomainW, UNLEN + IIS_DNLEN + 1 + 1 );
|
|
STACK_STRU( strPasswordW, PWLEN + 1 );
|
|
STACK_STRU( strDomainNameW, IIS_DNLEN + 1 );
|
|
STACK_STRU( strUserNameW, UNLEN + 1 );
|
|
BOOL fFinished;
|
|
BOOL fRet;
|
|
DWORD dwLogonError;
|
|
BOOL fPossibleUPNLogon = FALSE;
|
|
|
|
if ( pMainContext == NULL )
|
|
{
|
|
DBG_ASSERT( FALSE );
|
|
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
pMetaData = pMainContext->QueryUrlContext()->QueryMetaData();
|
|
DBG_ASSERT( pMetaData != NULL );
|
|
|
|
//
|
|
// Notify authentication filters
|
|
//
|
|
|
|
if ( pMainContext->IsNotificationNeeded( SF_NOTIFY_AUTHENTICATION ) )
|
|
{
|
|
HTTP_FILTER_AUTHENT filterAuthent;
|
|
|
|
DBG_ASSERT( strUserDomain.IsEmpty() );
|
|
hr = strUserDomain.Resize( SF_MAX_USERNAME );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
DBG_ASSERT( strPassword.IsEmpty() );
|
|
hr = strPassword.Resize( SF_MAX_PASSWORD );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
filterAuthent.pszUser = strUserDomain.QueryStr();
|
|
filterAuthent.cbUserBuff = SF_MAX_USERNAME;
|
|
|
|
filterAuthent.pszPassword = strPassword.QueryStr();
|
|
filterAuthent.cbPasswordBuff = SF_MAX_PASSWORD;
|
|
|
|
fRet = pMainContext->NotifyFilters( SF_NOTIFY_AUTHENTICATION,
|
|
&filterAuthent,
|
|
&fFinished );
|
|
|
|
if ( !fRet )
|
|
{
|
|
return HRESULT_FROM_WIN32( GetLastError() );
|
|
}
|
|
|
|
if ( fFinished )
|
|
{
|
|
pMainContext->SetFinishedResponse();
|
|
return NO_ERROR;
|
|
}
|
|
|
|
strUserDomain.SetLen( strlen( strUserDomain.QueryStr() ) );
|
|
strPassword.SetLen( strlen( strPassword.QueryStr() ) );
|
|
}
|
|
|
|
//
|
|
// If the filter set a user/password, then use it
|
|
//
|
|
|
|
if ( strUserDomain.QueryCCH() > 0 )
|
|
{
|
|
//
|
|
// Convert to unicode
|
|
//
|
|
|
|
hr = strUserDomainW.CopyA( strUserDomain.QueryStr() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = strPasswordW.CopyA( strPassword.QueryStr() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Get username/domain out of domain\username
|
|
//
|
|
|
|
hr = W3_STATE_AUTHENTICATION::SplitUserDomain( strUserDomainW,
|
|
&strUserNameW,
|
|
&strDomainNameW,
|
|
pMetaData->QueryDomainName(),
|
|
&fPossibleUPNLogon );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Try to get the token
|
|
//
|
|
|
|
DBG_ASSERT( g_pW3Server->QueryTokenCache() != NULL );
|
|
|
|
hr = g_pW3Server->QueryTokenCache()->GetCachedToken(
|
|
strUserNameW.QueryStr(),
|
|
strDomainNameW.QueryStr(),
|
|
strPasswordW.QueryStr(),
|
|
pMetaData->QueryLogonMethod(),
|
|
fPossibleUPNLogon,
|
|
&pCachedToken,
|
|
&dwLogonError );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Use the IUSR account
|
|
//
|
|
pCachedToken = pMetaData->QueryAnonymousToken();
|
|
|
|
if ( pCachedToken != NULL )
|
|
{
|
|
//
|
|
// Reference cached token because the metadata may go away from us
|
|
// if AUTH_COMPLETE backed up the state machine
|
|
//
|
|
|
|
pCachedToken->ReferenceCacheEntry();
|
|
}
|
|
}
|
|
|
|
if ( pCachedToken == NULL )
|
|
{
|
|
//
|
|
// Bogus anonymous account
|
|
//
|
|
|
|
pMainContext->QueryResponse()->SetStatus( HttpStatusUnauthorized,
|
|
Http401BadLogon );
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// For perf reasons, the anonymous user context is inline
|
|
//
|
|
|
|
pUserContext = new (pMainContext) ANONYMOUS_USER_CONTEXT( this );
|
|
DBG_ASSERT( pUserContext != NULL );
|
|
|
|
hr = pUserContext->Create( pCachedToken,
|
|
pMetaData->QueryLogonMethod() );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
pMainContext->SetUserContext( pUserContext );
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
HRESULT
|
|
ANONYMOUS_USER_CONTEXT::Create(
|
|
TOKEN_CACHE_ENTRY * pCachedToken,
|
|
DWORD dwLogonMethod
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize anonymous context
|
|
|
|
Arguments:
|
|
|
|
pCachedToken - anonymous user token
|
|
dwLogonMethod - logon method
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
if ( pCachedToken == NULL )
|
|
{
|
|
DBG_ASSERT( FALSE );
|
|
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
if ( dwLogonMethod == LOGON32_LOGON_INTERACTIVE ||
|
|
dwLogonMethod == LOGON32_LOGON_BATCH )
|
|
{
|
|
_fDelegatable = TRUE;
|
|
}
|
|
|
|
_pCachedToken = pCachedToken;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|