windows-nt/Source/XPSP1/NT/inetsrv/iis/iisrearc/iisplus/ulw3/anonymousprovider.cxx
2020-09-26 16:20:57 +08:00

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;
}