You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1235 lines
32 KiB
1235 lines
32 KiB
/********************************************************************/
|
|
/** Copyright(c) 1995 Microsoft Corporation. **/
|
|
/********************************************************************/
|
|
|
|
//***
|
|
//
|
|
// Filename: ntauth.c
|
|
//
|
|
// Description: Contains entrypoints to do NT back-end authentication for
|
|
// ppp.
|
|
//
|
|
// History: Feb 11,1997 NarenG Created original version.
|
|
//
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <ntlsa.h>
|
|
#include <ntmsv1_0.h>
|
|
#include <ntsamp.h>
|
|
#include <crypt.h>
|
|
|
|
#include <crypt.h>
|
|
#define INC_OLE2
|
|
#include <windows.h>
|
|
#include <lmcons.h>
|
|
#include <netlib.h> // For NetpGetDomainNameEx
|
|
#include <lmapibuf.h>
|
|
#include <lmaccess.h>
|
|
#include <raserror.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <locale.h>
|
|
#include <shlobj.h>
|
|
#include <dsclient.h>
|
|
#include <dsgetdc.h>
|
|
#include <ntdsapi.h>
|
|
#include <rasman.h>
|
|
#include <rasppp.h>
|
|
#include <mprerror.h>
|
|
#include <rasauth.h>
|
|
#include <mprlog.h>
|
|
#include <pppcp.h>
|
|
#include <rtutils.h>
|
|
#define INCL_RASAUTHATTRIBUTES
|
|
#define INCL_HOSTWIRE
|
|
#define INCL_MISC
|
|
#include <ppputil.h>
|
|
#define ALLOCATE_GLOBALS
|
|
#include "ntauth.h"
|
|
#include "resource.h"
|
|
|
|
//**
|
|
//
|
|
// Call: RasAuthDllEntry
|
|
//
|
|
// Returns: TRUE - Success
|
|
// FALSE - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
BOOL
|
|
RasAuthDllEntry(
|
|
HANDLE hinstDll,
|
|
DWORD fdwReason,
|
|
LPVOID lpReserved
|
|
)
|
|
{
|
|
switch (fdwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
{
|
|
DisableThreadLibraryCalls( hinstDll );
|
|
|
|
g_hInstance = hinstDll;
|
|
|
|
break;
|
|
}
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
{
|
|
g_hInstance = NULL;
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAuthProviderInitialize
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD APIENTRY
|
|
RasAuthProviderInitialize(
|
|
IN RAS_AUTH_ATTRIBUTE * pServerAttributes,
|
|
IN HANDLE hEventLog,
|
|
IN DWORD dwLoggingLevel
|
|
)
|
|
{
|
|
DWORD dwRetCode = NO_ERROR;
|
|
HRESULT hResult;
|
|
NT_PRODUCT_TYPE NtProductType = NtProductLanManNt;
|
|
LPWSTR lpwstrDomainNamePtr = NULL;
|
|
BOOLEAN fIsWorkgroupName = FALSE;
|
|
|
|
//
|
|
// If already initalized, we return
|
|
//
|
|
|
|
if ( g_fInitialized )
|
|
{
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
g_dwTraceIdNt = INVALID_TRACEID;
|
|
|
|
setlocale( LC_ALL,"" );
|
|
|
|
g_dwTraceIdNt = TraceRegisterA( "RASAUTH" );
|
|
|
|
hResult = CoInitializeEx( NULL, COINIT_MULTITHREADED );
|
|
|
|
if ( FAILED( hResult ) )
|
|
{
|
|
return( HRESULT_CODE( hResult ) );
|
|
}
|
|
|
|
hResult = InitializeIas( TRUE );
|
|
|
|
if ( FAILED( hResult ) )
|
|
{
|
|
dwRetCode = HRESULT_CODE( hResult );
|
|
|
|
TRACE1("Initialize Ias failed with %d", dwRetCode );
|
|
|
|
CoUninitialize();
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
g_hEventLog = hEventLog;
|
|
|
|
g_LoggingLevel = dwLoggingLevel;
|
|
|
|
if (!LoadString(g_hInstance, IDS_UNAUTHENTICATED_USER,
|
|
g_aszUnauthenticatedUser, MaxCharsUnauthUser_c))
|
|
{
|
|
g_aszUnauthenticatedUser[0] = 0;
|
|
}
|
|
|
|
g_fInitialized = TRUE;
|
|
|
|
TRACE("RasAuthProviderInitialize succeeded");
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAuthProviderTerminate
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD APIENTRY
|
|
RasAuthProviderTerminate(
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// If already terminated, we return
|
|
//
|
|
|
|
if ( !g_fInitialized )
|
|
{
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
g_fInitialized = FALSE;
|
|
|
|
if ( g_dwTraceIdNt != INVALID_TRACEID )
|
|
{
|
|
TraceDeregisterA( g_dwTraceIdNt );
|
|
}
|
|
|
|
ShutdownIas();
|
|
|
|
CoUninitialize();
|
|
|
|
TRACE("RasAuthTerminate succeeded");
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAcctProviderInitialize
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD APIENTRY
|
|
RasAcctProviderInitialize(
|
|
IN RAS_AUTH_ATTRIBUTE * pServerAttributes,
|
|
IN HANDLE hEventLog,
|
|
IN DWORD dwLoggingLevel
|
|
)
|
|
{
|
|
RAS_AUTH_ATTRIBUTE * pOutAttributes = NULL;
|
|
DWORD dwResultCode;
|
|
|
|
DWORD dwRetCode = RasAuthProviderInitialize( pServerAttributes,
|
|
hEventLog,
|
|
dwLoggingLevel );
|
|
|
|
if ( dwRetCode == NO_ERROR )
|
|
{
|
|
dwRetCode = IASSendReceiveAttributes( RAS_IAS_ACCOUNTING_ON,
|
|
pServerAttributes,
|
|
&pOutAttributes,
|
|
&dwResultCode );
|
|
|
|
if ( pOutAttributes != NULL )
|
|
{
|
|
RasAuthAttributeDestroy( pOutAttributes );
|
|
}
|
|
|
|
if ( dwRetCode == NO_ERROR )
|
|
{
|
|
//
|
|
// Make a copy of the Server attributes
|
|
//
|
|
|
|
g_pServerAttributes = RasAuthAttributeCopy( pServerAttributes );
|
|
|
|
if ( g_pServerAttributes == NULL )
|
|
{
|
|
dwRetCode = GetLastError();
|
|
}
|
|
}
|
|
}
|
|
|
|
g_hEventLog = hEventLog;
|
|
|
|
g_LoggingLevel = dwLoggingLevel;
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAcctProviderTerminate
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD APIENTRY
|
|
RasAcctProviderTerminate(
|
|
VOID
|
|
)
|
|
{
|
|
RAS_AUTH_ATTRIBUTE * pOutAttributes = NULL;
|
|
DWORD dwResultCode;
|
|
|
|
IASSendReceiveAttributes( RAS_IAS_ACCOUNTING_OFF,
|
|
g_pServerAttributes,
|
|
&pOutAttributes,
|
|
&dwResultCode );
|
|
|
|
if ( pOutAttributes != NULL )
|
|
{
|
|
RasAuthAttributeDestroy( pOutAttributes );
|
|
}
|
|
|
|
if ( g_pServerAttributes != NULL )
|
|
{
|
|
RasAuthAttributeDestroy( g_pServerAttributes );
|
|
|
|
g_pServerAttributes = NULL;
|
|
}
|
|
|
|
RasAuthProviderTerminate();
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAcctProviderStartAccounting
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD APIENTRY
|
|
RasAcctProviderStartAccounting(
|
|
IN RAS_AUTH_ATTRIBUTE * pInAttributes,
|
|
OUT PRAS_AUTH_ATTRIBUTE * ppOutAttributes
|
|
)
|
|
{
|
|
DWORD dwResultCode = NO_ERROR;
|
|
|
|
TRACE("RasStartAccounting called");
|
|
|
|
return( IASSendReceiveAttributes( RAS_IAS_START_ACCOUNTING,
|
|
pInAttributes,
|
|
ppOutAttributes,
|
|
&dwResultCode ) );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAcctProviderStopAccounting
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD APIENTRY
|
|
RasAcctProviderStopAccounting(
|
|
IN RAS_AUTH_ATTRIBUTE * pInAttributes,
|
|
OUT PRAS_AUTH_ATTRIBUTE * ppOutAttributes
|
|
)
|
|
{
|
|
DWORD dwResultCode = NO_ERROR;
|
|
|
|
TRACE("RasStopAccounting called");
|
|
|
|
return( IASSendReceiveAttributes( RAS_IAS_STOP_ACCOUNTING,
|
|
pInAttributes,
|
|
ppOutAttributes,
|
|
&dwResultCode ) );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAcctConfigChangeNotification
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description: Reloads config information dynamically
|
|
//
|
|
DWORD APIENTRY
|
|
RasAcctConfigChangeNotification(
|
|
IN DWORD dwLoggingLevel
|
|
)
|
|
{
|
|
TRACE("RasAcctConfigChangeNotification called");
|
|
|
|
g_LoggingLevel = dwLoggingLevel;
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAcctProviderInterimAccounting
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD APIENTRY
|
|
RasAcctProviderInterimAccounting(
|
|
IN RAS_AUTH_ATTRIBUTE * pInAttributes,
|
|
OUT PRAS_AUTH_ATTRIBUTE * ppOutAttributes
|
|
)
|
|
{
|
|
DWORD dwResultCode = NO_ERROR;
|
|
|
|
TRACE("RasInterimAccounting called");
|
|
|
|
return( IASSendReceiveAttributes( RAS_IAS_INTERIM_ACCOUNTING,
|
|
pInAttributes,
|
|
ppOutAttributes,
|
|
&dwResultCode ) );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAuthConfigChangeNotification
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description: Reloads config information dynamically
|
|
//
|
|
DWORD APIENTRY
|
|
RasAuthConfigChangeNotification(
|
|
IN DWORD dwLoggingLevel
|
|
)
|
|
{
|
|
TRACE("RasAuthConfigChangeNotification called");
|
|
|
|
g_LoggingLevel = dwLoggingLevel;
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: MapIasRetCodeToRasError
|
|
//
|
|
// Description: Maps IAS_RETCODE to an error in raserror.h or mprerror.h
|
|
//
|
|
DWORD
|
|
MapIasRetCodeToRasError(
|
|
IN LONG lFailureReason
|
|
)
|
|
{
|
|
DWORD dwError;
|
|
|
|
switch ( lFailureReason )
|
|
{
|
|
case IAS_CHANGE_PASSWORD_FAILURE:
|
|
dwError = ERROR_CHANGING_PASSWORD;
|
|
break;
|
|
|
|
case IAS_ACCOUNT_DISABLED:
|
|
dwError = ERROR_ACCT_DISABLED;
|
|
break;
|
|
|
|
case IAS_ACCOUNT_EXPIRED:
|
|
dwError = ERROR_ACCT_EXPIRED;
|
|
break;
|
|
|
|
case IAS_INVALID_LOGON_HOURS:
|
|
case IAS_INVALID_DIALIN_HOURS:
|
|
dwError = ERROR_DIALIN_HOURS_RESTRICTION;
|
|
break;
|
|
|
|
case IAS_DIALIN_DISABLED:
|
|
dwError = ERROR_NO_DIALIN_PERMISSION;
|
|
break;
|
|
|
|
case IAS_SESSION_TIMEOUT:
|
|
dwError = ERROR_AUTH_SERVER_TIMEOUT;
|
|
break;
|
|
|
|
case IAS_INVALID_PORT_TYPE:
|
|
dwError = ERROR_ALLOWED_PORT_TYPE_RESTRICTION;
|
|
break;
|
|
|
|
case IAS_INVALID_AUTH_TYPE:
|
|
dwError = ERROR_AUTH_PROTOCOL_RESTRICTION;
|
|
break;
|
|
|
|
default:
|
|
dwError = ERROR_AUTHENTICATION_FAILURE;
|
|
break;
|
|
}
|
|
|
|
return( dwError );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: IASSendReceiveAttributes
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description: Will send attributes to and receive attributes from IAS
|
|
//
|
|
DWORD
|
|
IASSendReceiveAttributes(
|
|
IN RAS_IAS_REQUEST_TYPE RequestType,
|
|
IN RAS_AUTH_ATTRIBUTE * pInAttributes,
|
|
OUT PRAS_AUTH_ATTRIBUTE * ppOutAttributes,
|
|
OUT DWORD * lpdwResultCode
|
|
)
|
|
{
|
|
DWORD dwIndex;
|
|
HRESULT hResult;
|
|
LONG IasResponse;
|
|
LONG IasRequest;
|
|
DWORD dwInAttributeCount = 0;
|
|
DWORD dwTotalInAttributeCount = 0;
|
|
PIASATTRIBUTE * ppInIasAttributes = NULL;
|
|
DWORD dwOutAttributeCount = 0;
|
|
PIASATTRIBUTE * ppOutIasAttributes = NULL;
|
|
IAS_INET_ADDR InetAddr = 0;
|
|
RAS_AUTH_ATTRIBUTE * pNASIdentifier = NULL;
|
|
RAS_AUTH_ATTRIBUTE * pCallingStationId = NULL;
|
|
DWORD dwLength;
|
|
PVOID pValue;
|
|
BOOL fConvertToAnsi;
|
|
DWORD dwRetCode = NO_ERROR;
|
|
LPSTR lpsUserName = g_aszUnauthenticatedUser;
|
|
LONG lFailureReason;
|
|
|
|
RasAuthAttributesPrint( g_dwTraceIdNt, TRACE_NTAUTH, pInAttributes );
|
|
|
|
switch( RequestType )
|
|
{
|
|
case RAS_IAS_START_ACCOUNTING:
|
|
case RAS_IAS_STOP_ACCOUNTING:
|
|
case RAS_IAS_INTERIM_ACCOUNTING:
|
|
case RAS_IAS_ACCOUNTING_ON:
|
|
case RAS_IAS_ACCOUNTING_OFF:
|
|
|
|
IasRequest = IAS_REQUEST_ACCOUNTING;
|
|
break;
|
|
|
|
case RAS_IAS_ACCESS_REQUEST:
|
|
IasRequest = IAS_REQUEST_ACCESS_REQUEST;
|
|
break;
|
|
|
|
default:
|
|
ASSERT( FALSE );
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
*ppOutAttributes = NULL;
|
|
*lpdwResultCode = ERROR_AUTHENTICATION_FAILURE;
|
|
|
|
hResult = CoInitializeEx( NULL, COINIT_MULTITHREADED );
|
|
|
|
if ( FAILED( hResult ) )
|
|
{
|
|
return( HRESULT_CODE( hResult ) );
|
|
}
|
|
|
|
do
|
|
{
|
|
//
|
|
// First findout how many attributes there are
|
|
//
|
|
|
|
for ( dwInAttributeCount = 0;
|
|
pInAttributes[dwInAttributeCount].raaType != raatMinimum;
|
|
dwInAttributeCount++);
|
|
|
|
dwTotalInAttributeCount = dwInAttributeCount;
|
|
|
|
if ( IasRequest == IAS_REQUEST_ACCOUNTING )
|
|
{
|
|
//
|
|
// Add one more of the Acct-Status-Type attribute
|
|
//
|
|
|
|
dwTotalInAttributeCount++;
|
|
}
|
|
|
|
//
|
|
// Add two more for Client-IP-Address and Client-Friendly-Name
|
|
//
|
|
|
|
dwTotalInAttributeCount += 2;
|
|
|
|
//
|
|
// Now allocate an array of pointer to attributes
|
|
//
|
|
|
|
ppInIasAttributes =
|
|
(PIASATTRIBUTE *)
|
|
MemAllocIas(sizeof(PIASATTRIBUTE) * dwTotalInAttributeCount);
|
|
|
|
if ( ppInIasAttributes == NULL )
|
|
{
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
break;
|
|
}
|
|
|
|
ZeroMemory( ppInIasAttributes,
|
|
sizeof(PIASATTRIBUTE) * dwTotalInAttributeCount );
|
|
|
|
//
|
|
// Now allocate the attributes
|
|
//
|
|
|
|
hResult = AllocateAttributes( dwTotalInAttributeCount,
|
|
ppInIasAttributes );
|
|
|
|
if ( FAILED( hResult ) )
|
|
{
|
|
dwRetCode = HRESULT_CODE( hResult );
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Convert to IAS attributes
|
|
//
|
|
|
|
for ( dwIndex = 0; dwIndex < dwInAttributeCount; dwIndex++ )
|
|
{
|
|
switch( pInAttributes[dwIndex].raaType )
|
|
{
|
|
case raatNASPort:
|
|
case raatServiceType:
|
|
case raatFramedProtocol:
|
|
|
|
//
|
|
// arap connection? it's an access-request
|
|
//
|
|
|
|
if ((pInAttributes[dwIndex].raaType == raatFramedProtocol) &&
|
|
(pInAttributes[dwIndex].Value == (LPVOID)3))
|
|
{
|
|
IasRequest = IAS_REQUEST_ACCESS_REQUEST;
|
|
}
|
|
|
|
//
|
|
// fall through
|
|
//
|
|
|
|
case raatFramedRouting:
|
|
case raatFramedMTU:
|
|
case raatFramedCompression:
|
|
case raatLoginIPHost:
|
|
case raatLoginService:
|
|
case raatLoginTCPPort:
|
|
case raatFramedIPXNetwork:
|
|
case raatSessionTimeout:
|
|
case raatIdleTimeout:
|
|
case raatTerminationAction:
|
|
case raatFramedAppleTalkLink:
|
|
case raatFramedAppleTalkNetwork:
|
|
case raatNASPortType:
|
|
case raatPortLimit:
|
|
case raatTunnelType:
|
|
case raatTunnelMediumType:
|
|
case raatAcctStatusType:
|
|
case raatAcctDelayTime:
|
|
case raatAcctInputOctets:
|
|
case raatAcctOutputOctets:
|
|
case raatAcctAuthentic:
|
|
case raatAcctSessionTime:
|
|
case raatAcctInputPackets:
|
|
case raatAcctOutputPackets:
|
|
case raatAcctTerminateCause:
|
|
case raatAcctLinkCount:
|
|
case raatFramedIPNetmask:
|
|
case raatPrompt:
|
|
case raatPasswordRetry:
|
|
case raatARAPZoneAccess:
|
|
case raatARAPSecurity:
|
|
case raatAcctEventTimeStamp:
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.itType = IASTYPE_INTEGER;
|
|
(ppInIasAttributes[dwIndex])->Value.Integer =
|
|
PtrToUlong(pInAttributes[dwIndex].Value);
|
|
break;
|
|
|
|
case raatNASIPAddress:
|
|
|
|
InetAddr = PtrToUlong(pInAttributes[dwIndex].Value);
|
|
|
|
//
|
|
// Fall through
|
|
//
|
|
|
|
case raatFramedIPAddress:
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.itType = IASTYPE_INET_ADDR;
|
|
(ppInIasAttributes[dwIndex])->Value.InetAddr =
|
|
PtrToUlong(pInAttributes[dwIndex].Value);
|
|
|
|
break;
|
|
|
|
case raatUserPassword:
|
|
case raatMD5CHAPPassword:
|
|
case raatARAPPassword:
|
|
case raatEAPMessage:
|
|
|
|
|
|
//
|
|
// If any passwords are present then we want authentication
|
|
// as well.
|
|
//
|
|
|
|
IasRequest = IAS_REQUEST_ACCESS_REQUEST;
|
|
|
|
//
|
|
// Fall thru
|
|
//
|
|
|
|
case raatVendorSpecific:
|
|
|
|
//
|
|
// Is this the MS-CHAP password ?
|
|
//
|
|
|
|
if ( ( pInAttributes[dwIndex].raaType == raatVendorSpecific ) &&
|
|
( pInAttributes[dwIndex].dwLength >= 8 ) )
|
|
{
|
|
//
|
|
// Does the Vendor Id match Microsoft's ?
|
|
//
|
|
|
|
if ( WireToHostFormat32(
|
|
(PBYTE)(pInAttributes[dwIndex].Value)) == 311 )
|
|
{
|
|
//
|
|
// Does the vendor type match MS-CHAP password's,
|
|
// change pasword V1 or V2 ?
|
|
//
|
|
|
|
switch( *(((PBYTE)(pInAttributes[dwIndex].Value))+4) )
|
|
{
|
|
//
|
|
// is this is an MS-CHAP password?
|
|
//
|
|
case 1:
|
|
case 3:
|
|
case 4:
|
|
|
|
|
|
//
|
|
// is this is an ARAP password?
|
|
//
|
|
case raatARAPOldPassword:
|
|
case raatARAPNewPassword:
|
|
|
|
IasRequest = IAS_REQUEST_ACCESS_REQUEST;
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fall thru
|
|
//
|
|
|
|
default:
|
|
|
|
if ( pInAttributes[dwIndex].raaType == raatUserName )
|
|
{
|
|
//
|
|
// Save pointer for logging purposes
|
|
//
|
|
|
|
lpsUserName = (PBYTE)(pInAttributes[dwIndex].Value);
|
|
}
|
|
|
|
{
|
|
DWORD dwLength1 = pInAttributes[dwIndex].dwLength;
|
|
PBYTE pValue1 = (PBYTE)MemAllocIas( dwLength1 );
|
|
|
|
if ( pValue1 == NULL )
|
|
{
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
if ( raatNASIdentifier == pInAttributes[dwIndex].raaType )
|
|
{
|
|
pNASIdentifier = pInAttributes + dwIndex;
|
|
}
|
|
|
|
if ( raatCallingStationId == pInAttributes[dwIndex].raaType )
|
|
{
|
|
pCallingStationId = pInAttributes + dwIndex;
|
|
}
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.itType =
|
|
IASTYPE_OCTET_STRING;
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.OctetString.dwLength =
|
|
dwLength1;
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.OctetString.lpValue =
|
|
pValue1;
|
|
|
|
CopyMemory( pValue1,
|
|
(PBYTE)(pInAttributes[dwIndex].Value),
|
|
dwLength1 );
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Set the attribute Id
|
|
//
|
|
|
|
(ppInIasAttributes[dwIndex])->dwId = pInAttributes[dwIndex].raaType;
|
|
|
|
TRACE1( "Inserting attribute type %d",
|
|
pInAttributes[dwIndex].raaType );
|
|
}
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// If accounting type of request then we need to add the
|
|
// Acct-Status-Type attribute
|
|
//
|
|
|
|
if ( IasRequest == IAS_REQUEST_ACCOUNTING )
|
|
{
|
|
(ppInIasAttributes[dwIndex])->dwId = raatAcctStatusType;
|
|
(ppInIasAttributes[dwIndex])->Value.itType = IASTYPE_INTEGER;
|
|
|
|
switch ( RequestType )
|
|
{
|
|
case RAS_IAS_START_ACCOUNTING:
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.Integer = (DWORD)1;
|
|
break;
|
|
|
|
case RAS_IAS_STOP_ACCOUNTING:
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.Integer = (DWORD)2;
|
|
break;
|
|
|
|
case RAS_IAS_INTERIM_ACCOUNTING:
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.Integer = (DWORD)3;
|
|
break;
|
|
|
|
case RAS_IAS_ACCOUNTING_ON:
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.Integer = (DWORD)7;
|
|
break;
|
|
|
|
case RAS_IAS_ACCOUNTING_OFF:
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.Integer = (DWORD)8;
|
|
break;
|
|
}
|
|
|
|
dwIndex++;
|
|
}
|
|
|
|
//
|
|
// Insert Client-IP-Address and Client-Friendly-Name
|
|
//
|
|
|
|
if ( 0 != InetAddr )
|
|
{
|
|
(ppInIasAttributes[dwIndex])->dwId = 4108; // Client-IP-Address
|
|
(ppInIasAttributes[dwIndex])->Value.itType = IASTYPE_INET_ADDR;
|
|
(ppInIasAttributes[dwIndex])->Value.InetAddr = InetAddr;
|
|
dwIndex++;
|
|
|
|
TRACE( "Inserting attribute type 4108" );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Decrement the count since we added this to count
|
|
// before
|
|
//
|
|
dwTotalInAttributeCount--;
|
|
}
|
|
|
|
if ( NULL != pNASIdentifier )
|
|
{
|
|
DWORD dwLength1 = pNASIdentifier->dwLength;
|
|
PBYTE pValue1 = (PBYTE)MemAllocIas( dwLength1 );
|
|
|
|
if ( pValue1 == NULL )
|
|
{
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
(ppInIasAttributes[dwIndex])->dwId = 4128; // Client-Friendly-Name
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.itType =
|
|
IASTYPE_OCTET_STRING;
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.OctetString.dwLength =
|
|
dwLength1;
|
|
|
|
(ppInIasAttributes[dwIndex])->Value.OctetString.lpValue =
|
|
pValue1;
|
|
|
|
CopyMemory( pValue1,
|
|
(PBYTE)(pNASIdentifier->Value),
|
|
dwLength1 );
|
|
|
|
dwIndex++;
|
|
|
|
TRACE( "Inserting attribute type 4128" );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Decrement the count since we added this to the count
|
|
// before.
|
|
//
|
|
dwTotalInAttributeCount--;
|
|
}
|
|
|
|
//
|
|
// process the filled attributes
|
|
//
|
|
|
|
hResult = DoRequest(
|
|
dwTotalInAttributeCount,
|
|
ppInIasAttributes,
|
|
&dwOutAttributeCount,
|
|
&ppOutIasAttributes,
|
|
IasRequest,
|
|
&IasResponse,
|
|
IAS_PROTOCOL_RAS,
|
|
&lFailureReason,
|
|
TRUE );
|
|
|
|
if ( FAILED( hResult ) )
|
|
{
|
|
dwRetCode = HRESULT_CODE( hResult );
|
|
|
|
TRACE1( "IAS->DoRequest failed with %d", dwRetCode );
|
|
|
|
break;
|
|
}
|
|
|
|
switch( IasResponse )
|
|
{
|
|
case IAS_RESPONSE_ACCESS_ACCEPT:
|
|
|
|
TRACE( "IASResponse = ACCESS_ACCEPT");
|
|
|
|
*lpdwResultCode = NO_ERROR;
|
|
|
|
break;
|
|
|
|
case IAS_RESPONSE_ACCESS_CHALLENGE:
|
|
|
|
TRACE( "IASResponse = ACCESS_CHALLENGE");
|
|
|
|
*lpdwResultCode = NO_ERROR;
|
|
|
|
break;
|
|
|
|
case IAS_RESPONSE_DISCARD_PACKET:
|
|
|
|
TRACE1( "IASResponse = DISCARD_PACKET. Failurereason=0x%x",
|
|
lFailureReason);
|
|
|
|
*lpdwResultCode = MapIasRetCodeToRasError( lFailureReason );
|
|
dwRetCode = *lpdwResultCode;
|
|
|
|
break;
|
|
|
|
case IAS_RESPONSE_ACCESS_REJECT:
|
|
|
|
{
|
|
WCHAR *lpwsSubStringArray[3];
|
|
WCHAR wchInsertionString[13];
|
|
WCHAR wchUserName[UNLEN+1];
|
|
WCHAR wchCallerId[100];
|
|
|
|
MultiByteToWideChar( CP_ACP,
|
|
0,
|
|
lpsUserName,
|
|
-1,
|
|
wchUserName,
|
|
UNLEN+1 );
|
|
|
|
wsprintfW( wchInsertionString, L"%%%%%lu", lFailureReason + 0x1000 );
|
|
|
|
|
|
if ( pCallingStationId != NULL )
|
|
{
|
|
lpwsSubStringArray[0] = wchUserName;
|
|
lpwsSubStringArray[1] = wchCallerId;
|
|
lpwsSubStringArray[2] = wchInsertionString;
|
|
|
|
MultiByteToWideChar( CP_ACP,
|
|
0,
|
|
(PBYTE)(pCallingStationId->Value),
|
|
-1,
|
|
wchCallerId,
|
|
100 );
|
|
|
|
NtAuthLogWarning( ROUTERLOG_NTAUTH_FAILURE_EX, 3, lpwsSubStringArray);
|
|
}
|
|
else
|
|
{
|
|
lpwsSubStringArray[0] = wchUserName;
|
|
lpwsSubStringArray[1] = wchInsertionString;
|
|
|
|
NtAuthLogWarning( ROUTERLOG_NTAUTH_FAILURE, 2, lpwsSubStringArray );
|
|
}
|
|
|
|
*lpdwResultCode = MapIasRetCodeToRasError( lFailureReason );
|
|
}
|
|
|
|
default:
|
|
|
|
TRACE2( "IASResponse = %d, FailureReason = 0x%x",
|
|
IasResponse, lFailureReason );
|
|
|
|
break;
|
|
}
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( dwOutAttributeCount > 0 )
|
|
{
|
|
//
|
|
// Convert from IAS attributes
|
|
//
|
|
|
|
*ppOutAttributes = RasAuthAttributeCreate( dwOutAttributeCount );
|
|
|
|
if ( *ppOutAttributes == NULL )
|
|
{
|
|
dwRetCode = GetLastError();
|
|
|
|
break;
|
|
}
|
|
|
|
for ( dwIndex = 0; dwIndex < dwOutAttributeCount; dwIndex++ )
|
|
{
|
|
IASVALUE IasValue = (ppOutIasAttributes[dwIndex])->Value;
|
|
|
|
fConvertToAnsi = FALSE;
|
|
|
|
switch ( IasValue.itType )
|
|
{
|
|
case IASTYPE_INTEGER:
|
|
|
|
dwLength = sizeof( DWORD );
|
|
pValue = (LPVOID) ULongToPtr(IasValue.Integer);
|
|
break;
|
|
|
|
case IASTYPE_BOOLEAN:
|
|
|
|
dwLength = sizeof( DWORD );
|
|
pValue = (LPVOID)ULongToPtr(IasValue.Boolean);
|
|
break;
|
|
|
|
case IASTYPE_ENUM:
|
|
|
|
dwLength = sizeof( DWORD );
|
|
pValue = (LPVOID)ULongToPtr(IasValue.Enumerator);
|
|
break;
|
|
|
|
case IASTYPE_INET_ADDR:
|
|
|
|
dwLength = sizeof( DWORD );
|
|
pValue = (LPVOID)ULongToPtr(IasValue.InetAddr);
|
|
break;
|
|
|
|
case IASTYPE_STRING:
|
|
|
|
if ( NULL != IasValue.String.pszAnsi )
|
|
{
|
|
dwLength = strlen( IasValue.String.pszAnsi );
|
|
pValue = (LPVOID)( IasValue.String.pszAnsi );
|
|
}
|
|
else if ( NULL != IasValue.String.pszWide )
|
|
{
|
|
dwLength = wcslen( IasValue.String.pszWide );
|
|
pValue = (LPVOID)( IasValue.String.pszWide );
|
|
fConvertToAnsi = TRUE;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
|
|
case IASTYPE_OCTET_STRING:
|
|
|
|
dwLength = IasValue.OctetString.dwLength;
|
|
pValue = IasValue.OctetString.lpValue;
|
|
break;
|
|
|
|
default:
|
|
|
|
continue;
|
|
}
|
|
|
|
dwRetCode =
|
|
RasAuthAttributeInsert(
|
|
dwIndex,
|
|
*ppOutAttributes,
|
|
(ppOutIasAttributes[dwIndex])->dwId,
|
|
fConvertToAnsi,
|
|
dwLength,
|
|
pValue );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
TRACE1( "Received attribute %d",
|
|
(ppOutIasAttributes[dwIndex])->dwId );
|
|
}
|
|
|
|
RasAuthAttributesPrint( g_dwTraceIdNt, TRACE_NTAUTH,
|
|
*ppOutAttributes );
|
|
}
|
|
|
|
} while( FALSE );
|
|
|
|
//
|
|
// Free all the IAS attributes allocated earlier
|
|
//
|
|
|
|
if ( ppInIasAttributes != NULL )
|
|
{
|
|
if(NO_ERROR == dwRetCode)
|
|
{
|
|
FreeAttributes( dwTotalInAttributeCount, ppInIasAttributes );
|
|
}
|
|
|
|
MemFreeIas( ppInIasAttributes );
|
|
}
|
|
|
|
if ( ppOutIasAttributes != NULL )
|
|
{
|
|
FreeAttributes( dwOutAttributeCount, ppOutIasAttributes );
|
|
|
|
MemFreeIas( ppOutIasAttributes );
|
|
}
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
if ( *ppOutAttributes != NULL )
|
|
{
|
|
RasAuthAttributeDestroy( *ppOutAttributes );
|
|
|
|
*ppOutAttributes = NULL;
|
|
}
|
|
}
|
|
|
|
CoUninitialize();
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAuthProviderAuthenticateUser
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
DWORD APIENTRY
|
|
RasAuthProviderAuthenticateUser(
|
|
IN RAS_AUTH_ATTRIBUTE * pInAttributes,
|
|
OUT PRAS_AUTH_ATTRIBUTE * ppOutAttributes,
|
|
OUT DWORD * lpdwResultCode
|
|
)
|
|
{
|
|
*ppOutAttributes = NULL;
|
|
*lpdwResultCode = NO_ERROR;
|
|
|
|
TRACE("RasAuthProviderAuthenticateUser called");
|
|
|
|
return( IASSendReceiveAttributes( RAS_IAS_ACCESS_REQUEST,
|
|
pInAttributes,
|
|
ppOutAttributes,
|
|
lpdwResultCode ) );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAuthProviderFreeAttributes
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD APIENTRY
|
|
RasAuthProviderFreeAttributes(
|
|
IN RAS_AUTH_ATTRIBUTE * pAttributes
|
|
)
|
|
{
|
|
RasAuthAttributeDestroy( pAttributes );
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RasAcctProviderFreeAttributes
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD APIENTRY
|
|
RasAcctProviderFreeAttributes(
|
|
IN RAS_AUTH_ATTRIBUTE * pAttributes
|
|
)
|
|
{
|
|
RasAuthAttributeDestroy( pAttributes );
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|