740 lines
21 KiB
C++
740 lines
21 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 1998 Microsoft Corporation
|
||
|
|
||
|
Module Name :
|
||
|
iiscertmap.cxx
|
||
|
|
||
|
Abstract:
|
||
|
IIS Certificate mapping
|
||
|
|
||
|
|
||
|
Author:
|
||
|
Bilal Alam (BAlam) 19-Apr-2000
|
||
|
|
||
|
Environment:
|
||
|
Win32 - User Mode
|
||
|
|
||
|
Project:
|
||
|
Stream Filter Worker Process
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.hxx"
|
||
|
#include <mbstring.h>
|
||
|
|
||
|
|
||
|
|
||
|
IIS_CERTIFICATE_MAPPING::IIS_CERTIFICATE_MAPPING( VOID )
|
||
|
: _pCert11Mapper( NULL ),
|
||
|
_pCertWildcardMapper( NULL ),
|
||
|
_cRefs( 1 )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
IIS_CERTIFICATE_MAPPING::~IIS_CERTIFICATE_MAPPING( VOID )
|
||
|
{
|
||
|
if ( _pCert11Mapper != NULL )
|
||
|
{
|
||
|
delete _pCert11Mapper;
|
||
|
_pCert11Mapper = NULL;
|
||
|
}
|
||
|
|
||
|
if ( _pCertWildcardMapper != NULL )
|
||
|
{
|
||
|
delete _pCertWildcardMapper;
|
||
|
_pCertWildcardMapper = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
IIS_CERTIFICATE_MAPPING::Read11Mappings(
|
||
|
DWORD dwSiteId
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Read 1-1 mappings from metabase
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
dwSiteId - Site ID (duh)
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
MB mb( g_pW3Server->QueryMDObject() );
|
||
|
WCHAR achMBPath[ 256 ];
|
||
|
HRESULT hr = NO_ERROR;
|
||
|
WCHAR achMappingName[ MAX_PATH + 1 ];
|
||
|
BOOL fRet;
|
||
|
DWORD dwIndex;
|
||
|
BYTE abBuffer[ 1024 ];
|
||
|
BUFFER buff( abBuffer, sizeof( abBuffer ) );
|
||
|
DWORD cbRequired;
|
||
|
STACK_STRU( strTemp, 64 );
|
||
|
STACK_STRU( strUserName, 64 );
|
||
|
STACK_STRU( strPassword, 64 );
|
||
|
DWORD dwEnabled;
|
||
|
CIisMapping * pCertMapping;
|
||
|
|
||
|
//
|
||
|
// Setup the NSEPM path to get at 1-1 mappings
|
||
|
//
|
||
|
|
||
|
_snwprintf( achMBPath,
|
||
|
sizeof( achMBPath ) / sizeof( WCHAR ) - 1,
|
||
|
L"/LM/W3SVC/%d/<nsepm>/Cert11/Mappings",
|
||
|
dwSiteId );
|
||
|
|
||
|
//
|
||
|
// Open the metabase and read 1-1 mapping properties
|
||
|
//
|
||
|
|
||
|
fRet = mb.Open( achMBPath,
|
||
|
METADATA_PERMISSION_READ );
|
||
|
if ( fRet )
|
||
|
{
|
||
|
dwIndex = 0;
|
||
|
achMappingName[ 0 ] = L'/';
|
||
|
|
||
|
for ( ; ; )
|
||
|
{
|
||
|
//
|
||
|
// We will need to prepend the object name with '/'. Hence
|
||
|
// goofyness of sending an offseted pointed to name
|
||
|
//
|
||
|
|
||
|
fRet = mb.EnumObjects( L"",
|
||
|
achMappingName + 1,
|
||
|
dwIndex );
|
||
|
if ( !fRet )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get certificate blob
|
||
|
//
|
||
|
|
||
|
cbRequired = buff.QuerySize();
|
||
|
|
||
|
fRet = mb.GetData( achMappingName,
|
||
|
MD_MAPCERT,
|
||
|
IIS_MD_UT_SERVER,
|
||
|
BINARY_METADATA,
|
||
|
buff.QueryPtr(),
|
||
|
&cbRequired,
|
||
|
METADATA_NO_ATTRIBUTES );
|
||
|
if ( !fRet )
|
||
|
{
|
||
|
if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
|
||
|
{
|
||
|
DBG_ASSERT( cbRequired > buff.QuerySize() );
|
||
|
|
||
|
if ( !buff.Resize( cbRequired ) )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
fRet = mb.GetData( achMappingName,
|
||
|
MD_MAPCERT,
|
||
|
IIS_MD_UT_SERVER,
|
||
|
BINARY_METADATA,
|
||
|
buff.QueryPtr(),
|
||
|
&cbRequired,
|
||
|
METADATA_NO_ATTRIBUTES );
|
||
|
if ( !fRet )
|
||
|
{
|
||
|
DBG_ASSERT( GetLastError() != ERROR_INSUFFICIENT_BUFFER );
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get NT account name
|
||
|
//
|
||
|
|
||
|
if ( !mb.GetStr( achMappingName,
|
||
|
MD_MAPNTACCT,
|
||
|
IIS_MD_UT_SERVER,
|
||
|
&strUserName ) )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get NT password
|
||
|
//
|
||
|
|
||
|
if ( !mb.GetStr( achMappingName,
|
||
|
MD_MAPNTPWD,
|
||
|
IIS_MD_UT_SERVER,
|
||
|
&strPassword ) )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Is this mapping enabled?
|
||
|
//
|
||
|
|
||
|
if ( !mb.GetDword( achMappingName,
|
||
|
MD_MAPENABLED,
|
||
|
IIS_MD_UT_SERVER,
|
||
|
&dwEnabled ) )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If this mapping is enabled, add it to 1-1 mapper
|
||
|
//
|
||
|
|
||
|
if ( dwEnabled )
|
||
|
{
|
||
|
if ( _pCert11Mapper == NULL )
|
||
|
{
|
||
|
_pCert11Mapper = new CIisCert11Mapper();
|
||
|
if ( _pCert11Mapper == NULL )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Reset() will configure default hierarchies
|
||
|
// If hierarchies are not configured then comparison (CIisMapping::Cmp() function
|
||
|
// implemented in iismap.cxx) will fail
|
||
|
// (and mapper will always incorrectly map to first available 1to1 mapping)
|
||
|
//
|
||
|
|
||
|
if(!_pCert11Mapper->Reset())
|
||
|
{
|
||
|
delete _pCert11Mapper;
|
||
|
_pCert11Mapper = NULL;
|
||
|
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DBG_ASSERT( _pCert11Mapper != NULL );
|
||
|
|
||
|
pCertMapping = _pCert11Mapper->CreateNewMapping();
|
||
|
if ( pCertMapping == NULL )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( !pCertMapping->MappingSetField( IISMDB_INDEX_CERT11_CERT,
|
||
|
(CHAR*)buff.QueryPtr(),
|
||
|
cbRequired,
|
||
|
FALSE ) )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Encrypted metabase stuff returned as ANSI (LAME!!!!!)
|
||
|
//
|
||
|
|
||
|
if ( !pCertMapping->MappingSetField( IISMDB_INDEX_CERT11_NT_ACCT,
|
||
|
(CHAR*) strUserName.QueryStr() ) )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( !pCertMapping->MappingSetField( IISMDB_INDEX_CERT11_NT_PWD,
|
||
|
(CHAR*) strPassword.QueryStr() ) )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( !((CIisAcctMapper*)_pCert11Mapper)->Add( pCertMapping, FALSE ) )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dwIndex++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
IIS_CERTIFICATE_MAPPING::ReadWildcardMappings(
|
||
|
DWORD dwSiteId
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Read wildcard mappings from metabase
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
dwSiteId - Site ID (duh)
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
MB mb( g_pW3Server->QueryMDObject() );
|
||
|
WCHAR achMBPath[ 256 ];
|
||
|
BOOL fRet;
|
||
|
BYTE abBuffer[ 1024 ];
|
||
|
BUFFER buff( abBuffer, sizeof( abBuffer ) );
|
||
|
DWORD cbRequired;
|
||
|
PUCHAR pLamePointer;
|
||
|
|
||
|
//
|
||
|
// Setup the NSEPM path to get at wildcard mappings
|
||
|
//
|
||
|
|
||
|
_snwprintf( achMBPath,
|
||
|
sizeof( achMBPath ) / sizeof( WCHAR ) - 1,
|
||
|
L"/LM/W3SVC/%d/<nsepm>/CertW",
|
||
|
dwSiteId );
|
||
|
|
||
|
//
|
||
|
// Open the metabase and read wildcard mappings
|
||
|
//
|
||
|
|
||
|
fRet = mb.Open( achMBPath,
|
||
|
METADATA_PERMISSION_READ );
|
||
|
if ( fRet )
|
||
|
{
|
||
|
cbRequired = buff.QuerySize();
|
||
|
|
||
|
fRet = mb.GetData( L"",
|
||
|
MD_SERIAL_CERTW,
|
||
|
IIS_MD_UT_SERVER,
|
||
|
BINARY_METADATA,
|
||
|
buff.QueryPtr(),
|
||
|
&cbRequired,
|
||
|
METADATA_NO_ATTRIBUTES );
|
||
|
if ( !fRet )
|
||
|
{
|
||
|
if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
|
||
|
{
|
||
|
DBG_ASSERT( cbRequired > buff.QuerySize() );
|
||
|
|
||
|
if ( !buff.Resize( cbRequired ) )
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32( GetLastError() );
|
||
|
}
|
||
|
|
||
|
fRet = mb.GetData( L"",
|
||
|
MD_SERIAL_CERTW,
|
||
|
IIS_MD_UT_SERVER,
|
||
|
BINARY_METADATA,
|
||
|
buff.QueryPtr(),
|
||
|
&cbRequired,
|
||
|
METADATA_NO_ATTRIBUTES );
|
||
|
if ( !fRet )
|
||
|
{
|
||
|
DBG_ASSERT( GetLastError() != ERROR_INSUFFICIENT_BUFFER );
|
||
|
|
||
|
return HRESULT_FROM_WIN32( GetLastError() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Thanx to the man, I can just unserialize. XBF rocks ;-)
|
||
|
//
|
||
|
|
||
|
DBG_ASSERT( _pCertWildcardMapper == NULL );
|
||
|
|
||
|
_pCertWildcardMapper = new CIisRuleMapper();
|
||
|
if ( _pCertWildcardMapper == NULL )
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32( GetLastError() );
|
||
|
}
|
||
|
|
||
|
pLamePointer = (PUCHAR) buff.QueryPtr();
|
||
|
|
||
|
fRet = _pCertWildcardMapper->Unserialize( &pLamePointer,
|
||
|
&cbRequired );
|
||
|
if ( !fRet )
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32( GetLastError() );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
|
||
|
}
|
||
|
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
//static
|
||
|
HRESULT
|
||
|
IIS_CERTIFICATE_MAPPING::GetCertificateMapping(
|
||
|
DWORD dwSiteId,
|
||
|
IIS_CERTIFICATE_MAPPING ** ppCertificateMapping
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Read appropriate metabase configuration to get configured IIS
|
||
|
certificate mapping
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
dwSiteId - Site ID (duh)
|
||
|
ppCertificateMapping - Filled with certificate mapping descriptor on
|
||
|
success
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
IIS_CERTIFICATE_MAPPING * pCertMapping = NULL;
|
||
|
HRESULT hr = NO_ERROR;
|
||
|
|
||
|
if ( ppCertificateMapping == NULL )
|
||
|
{
|
||
|
DBG_ASSERT( FALSE );
|
||
|
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
||
|
}
|
||
|
*ppCertificateMapping = NULL;
|
||
|
|
||
|
//
|
||
|
// Create a certificate mapping descriptor
|
||
|
//
|
||
|
|
||
|
pCertMapping = new IIS_CERTIFICATE_MAPPING();
|
||
|
if ( pCertMapping == NULL )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
goto Finished;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Read 1-1 mappings
|
||
|
//
|
||
|
|
||
|
hr = pCertMapping->Read11Mappings( dwSiteId );
|
||
|
if ( FAILED( hr ) &&
|
||
|
hr != HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) )
|
||
|
{
|
||
|
goto Finished;
|
||
|
}
|
||
|
hr = NO_ERROR;
|
||
|
|
||
|
//
|
||
|
// Read wildcards
|
||
|
//
|
||
|
|
||
|
hr = pCertMapping->ReadWildcardMappings( dwSiteId );
|
||
|
if ( FAILED( hr ) &&
|
||
|
hr != HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) )
|
||
|
{
|
||
|
goto Finished;
|
||
|
}
|
||
|
hr = NO_ERROR;
|
||
|
|
||
|
Finished:
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
if ( pCertMapping != NULL )
|
||
|
{
|
||
|
delete pCertMapping;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DBG_ASSERT( pCertMapping != NULL );
|
||
|
*ppCertificateMapping = pCertMapping;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
IIS_CERTIFICATE_MAPPING::DoMapCredential(
|
||
|
PBYTE pClientCertBlob,
|
||
|
DWORD cbClientCertBlob,
|
||
|
TOKEN_CACHE_ENTRY ** ppCachedToken,
|
||
|
BOOL * pfClientCertDeniedByMapper
|
||
|
)
|
||
|
{
|
||
|
CIisMapping * pQuery;
|
||
|
CIisMapping * pResult;
|
||
|
CHAR achUserName[ UNLEN + 1 ];
|
||
|
LPSTR pszUserName;
|
||
|
DWORD cbUserName;
|
||
|
CHAR achPassword[ PWLEN + 1 ];
|
||
|
LPSTR pszPassword;
|
||
|
DWORD cbPassword;
|
||
|
CHAR * pszDomain;
|
||
|
DWORD dwEnabled = 0;
|
||
|
DWORD cbEnabled;
|
||
|
BOOL fMatch = FALSE;
|
||
|
DWORD dwLogonError = NO_ERROR;
|
||
|
HRESULT hr = S_OK;
|
||
|
//
|
||
|
// add 1 to strUserDomainW for separator "\"
|
||
|
//
|
||
|
STACK_STRU( strUserDomainW, UNLEN + IIS_DNLEN + 1 + 1 );
|
||
|
STACK_STRU( strUserNameW, UNLEN + 1 );
|
||
|
STACK_STRU( strPasswordW, PWLEN + 1 );
|
||
|
|
||
|
DBG_ASSERT( pClientCertBlob != NULL );
|
||
|
DBG_ASSERT( cbClientCertBlob != 0 );
|
||
|
DBG_ASSERT( ppCachedToken != NULL );
|
||
|
DBG_ASSERT( pfClientCertDeniedByMapper != NULL );
|
||
|
|
||
|
|
||
|
//
|
||
|
// First try the 1-1 mapper
|
||
|
//
|
||
|
|
||
|
|
||
|
if ( _pCert11Mapper != NULL )
|
||
|
{
|
||
|
//
|
||
|
// Build a query mapping to check
|
||
|
//
|
||
|
|
||
|
pQuery = _pCert11Mapper->CreateNewMapping( pClientCertBlob,
|
||
|
cbClientCertBlob );
|
||
|
if ( pQuery == NULL )
|
||
|
{
|
||
|
return SEC_E_INTERNAL_ERROR;
|
||
|
}
|
||
|
|
||
|
_pCert11Mapper->Lock();
|
||
|
|
||
|
if ( _pCert11Mapper->FindMatch( pQuery,
|
||
|
&pResult ) )
|
||
|
{
|
||
|
//
|
||
|
// Awesome. We found a match. Do the deed if the rule is
|
||
|
// enabled
|
||
|
//
|
||
|
|
||
|
if ( pResult->MappingGetField( IISMDB_INDEX_CERT11_NT_ACCT,
|
||
|
&pszUserName,
|
||
|
&cbUserName,
|
||
|
FALSE ) &&
|
||
|
pResult->MappingGetField( IISMDB_INDEX_CERT11_NT_PWD,
|
||
|
&pszPassword,
|
||
|
&cbPassword,
|
||
|
FALSE ) )
|
||
|
{
|
||
|
//
|
||
|
// No need to check for Enabled (IISMDB_INDEX_CERT11_ENABLED)
|
||
|
// since Read11Mappings() will build mapping table consisting only
|
||
|
// of enabled mappings
|
||
|
//
|
||
|
|
||
|
strncpy( achUserName,
|
||
|
pszUserName,
|
||
|
UNLEN );
|
||
|
achUserName[ UNLEN ] = '\0';
|
||
|
|
||
|
strncpy( achPassword,
|
||
|
pszPassword,
|
||
|
PWLEN );
|
||
|
achPassword[ PWLEN ] = '\0';
|
||
|
|
||
|
fMatch = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_pCert11Mapper->Unlock();
|
||
|
|
||
|
delete pQuery;
|
||
|
pQuery = NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Try the wildcard mapper if we still haven't found a match
|
||
|
//
|
||
|
|
||
|
if ( !fMatch &&
|
||
|
_pCertWildcardMapper != NULL )
|
||
|
{
|
||
|
|
||
|
PCCERT_CONTEXT pClientCert = CertCreateCertificateContext(
|
||
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||
|
pClientCertBlob,
|
||
|
cbClientCertBlob );
|
||
|
if ( pClientCert == NULL )
|
||
|
{
|
||
|
DBG_ASSERT( pClientCert != NULL );
|
||
|
}
|
||
|
else if ( !_pCertWildcardMapper->Match( (PCERT_CONTEXT) (pClientCert),
|
||
|
NULL, // legacy value
|
||
|
achUserName,
|
||
|
achPassword ) )
|
||
|
{
|
||
|
//
|
||
|
// If the mapping rule is denied then return
|
||
|
// a NULL pointer through ppCachedToken with SEC_E_OK.
|
||
|
// That indicated to caller that mapping was denied
|
||
|
//
|
||
|
|
||
|
if ( GetLastError() == ERROR_ACCESS_DENIED )
|
||
|
{
|
||
|
*ppCachedToken = NULL;
|
||
|
*pfClientCertDeniedByMapper = TRUE;
|
||
|
|
||
|
if ( pClientCert != NULL )
|
||
|
{
|
||
|
CertFreeCertificateContext( pClientCert );
|
||
|
pClientCert = NULL;
|
||
|
}
|
||
|
|
||
|
return SEC_E_OK;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fMatch = TRUE;
|
||
|
}
|
||
|
|
||
|
if ( pClientCert != NULL )
|
||
|
{
|
||
|
CertFreeCertificateContext( pClientCert );
|
||
|
pClientCert = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If we still haven't found a match, then return error
|
||
|
//
|
||
|
|
||
|
if ( fMatch )
|
||
|
{
|
||
|
//
|
||
|
// Split up the user name into domain/user if needed
|
||
|
//
|
||
|
|
||
|
pszUserName = (LPSTR) _mbspbrk( (UCHAR*) achUserName, (UCHAR*) "/\\" );
|
||
|
if ( pszUserName == NULL )
|
||
|
{
|
||
|
//
|
||
|
// No domain in the user name. First try the metabase domain
|
||
|
// name
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// BUGBUG: DefaultLogonDomain is not used for cert mapping at all
|
||
|
//
|
||
|
|
||
|
pszDomain = "";
|
||
|
pszUserName = achUserName;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*pszUserName = '\0';
|
||
|
pszDomain = achUserName;
|
||
|
pszUserName = pszUserName + 1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Convert domain, user and password to unicode
|
||
|
//
|
||
|
|
||
|
hr = strUserNameW.CopyA( pszUserName );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
hr = strUserDomainW.CopyA( pszDomain );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
hr = strPasswordW.CopyA( achPassword );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// We should have valid credentials to call LogonUser()
|
||
|
//
|
||
|
DBG_ASSERT( g_pW3Server->QueryTokenCache() != NULL );
|
||
|
|
||
|
hr = g_pW3Server->QueryTokenCache()->GetCachedToken(
|
||
|
strUserNameW.QueryStr(),
|
||
|
strUserDomainW.QueryStr(),
|
||
|
strPasswordW.QueryStr(),
|
||
|
LOGON32_LOGON_INTERACTIVE,
|
||
|
FALSE, // BUGBUG not UPN logon
|
||
|
ppCachedToken,
|
||
|
&dwLogonError );
|
||
|
if ( FAILED( hr ) )
|
||
|
{
|
||
|
return SEC_E_UNKNOWN_CREDENTIALS;
|
||
|
}
|
||
|
//
|
||
|
// If *ppCachedToken is NULL, then logon failed
|
||
|
//
|
||
|
|
||
|
if ( *ppCachedToken == NULL )
|
||
|
{
|
||
|
//
|
||
|
// Note: With IIS5 we used to log logon failure to event log
|
||
|
// however it doesn't seem to be necessary because if logon/logoff auditing is enabled
|
||
|
// then security log would have relevant information about the logon failure
|
||
|
//
|
||
|
DBG_ASSERT( dwLogonError != ERROR_SUCCESS );
|
||
|
return SEC_E_UNKNOWN_CREDENTIALS;
|
||
|
}
|
||
|
|
||
|
DBG_ASSERT( (*ppCachedToken)->CheckSignature() );
|
||
|
*pfClientCertDeniedByMapper = FALSE;
|
||
|
return SEC_E_OK;
|
||
|
}
|
||
|
|
||
|
return SEC_E_UNKNOWN_CREDENTIALS;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|