Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1223 lines
39 KiB

/********************************************************************/
/** Copyright(c) 1985-1997 Microsoft Corporation. **/
/********************************************************************/
//***
//
// Filename: rtridobj
//
// Description: Support routines to manipulate router information in the
// router object
//
// History: Feb 11,1998 NarenG Created original version.
//
#include "dimsvcp.h"
#include <activeds.h>
#include <adsi.h>
#include <ntdsapi.h>
#include <dsgetdc.h>
#include <lmapibuf.h>
#define SECURITY_WIN32
#include <security.h>
#include <routprot.h>
#include <rtinfo.h>
#include <dimsvc.h> // Generated by MIDL
#define ROUTER_IDENTITY_OBJECT_NAME TEXT("CN=RouterIdentity")
#define ROUTER_OBJECT_ATTRIBUTE_NAME TEXT("MsRRASAttribute")
#define ROUTER_LDAP_PREFIX TEXT("LDAP://")
#define ROUTER_CN_COMMA TEXT(",")
#define ROUTER_IDENTITY_CLASS TEXT("RRASAdministrationConnectionPoint")
LPWSTR RouterObjectAttributeNames[] =
{
ROUTER_OBJECT_ATTRIBUTE_NAME
};
//**
//
// Call: RouterIdentityObjectOpen
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Given the machine name of the router, will return the handle
// to the router's administration service point or router object.
//
DWORD
RouterIdentityObjectOpen(
IN LPWSTR lpwszRouterName,
IN DWORD dwRouterType,
OUT HANDLE * phObjectRouterIdentity
)
{
DWORD dwRetCode;
LPWSTR lpwszRouterIdentityObjectPath = NULL;
LPWSTR lpwszComputerObjectPath = NULL;
DOMAIN_CONTROLLER_INFO * pDomainControllerInfo = NULL;
HRESULT hResult = HRESULT_FROM_WIN32(NO_ERROR);
DWORD dwCharCount;
do
{
dwRetCode = DsGetDcName( NULL,
NULL,
NULL,
NULL,
DS_DIRECTORY_SERVICE_REQUIRED |
DS_WRITABLE_REQUIRED,
&pDomainControllerInfo );
if ( dwRetCode != NO_ERROR )
{
TracePrintfExA( gblDIMConfigInfo.dwTraceId,
TRACE_DIM, "No DS located, DsGetDcName()=%d",
dwRetCode );
break;
}
if ( !( pDomainControllerInfo->Flags & DS_DS_FLAG ) )
{
TracePrintfExA( gblDIMConfigInfo.dwTraceId,
TRACE_DIM, "No DS located");
dwRetCode = ERROR_DOMAIN_CONTROLLER_NOT_FOUND;
break;
}
//
// Get the CN of the router object
//
dwCharCount = 200;
lpwszComputerObjectPath = LOCAL_ALLOC(LPTR, dwCharCount*sizeof(WCHAR));
if (lpwszComputerObjectPath == NULL)
{
TracePrintfExA( gblDIMConfigInfo.dwTraceId,
TRACE_DIM, "Memory exhausted -- unable to continue");
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
if ( !GetComputerObjectName( NameFullyQualifiedDN,
lpwszComputerObjectPath,
&dwCharCount ) )
{
//
// We failed for some other reason
//
LPWSTR lpwsComputerObjectPathReAlloc =
LOCAL_REALLOC( lpwszComputerObjectPath,
(++dwCharCount)*sizeof(WCHAR) );
if ( lpwsComputerObjectPathReAlloc == NULL )
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
lpwszComputerObjectPath = lpwsComputerObjectPathReAlloc;
if ( !GetComputerObjectName( NameFullyQualifiedDN,
lpwszComputerObjectPath,
&dwCharCount ) )
{
dwRetCode = GetLastError();
break;
}
}
lpwszRouterIdentityObjectPath =
LOCAL_ALLOC( LPTR,
sizeof( ROUTER_LDAP_PREFIX ) +
sizeof( ROUTER_IDENTITY_OBJECT_NAME ) +
sizeof( ROUTER_CN_COMMA ) +
((wcslen( lpwszComputerObjectPath )+1)* sizeof(WCHAR)));
if ( lpwszRouterIdentityObjectPath == NULL )
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
wcscpy( lpwszRouterIdentityObjectPath, ROUTER_LDAP_PREFIX );
wcscat( lpwszRouterIdentityObjectPath, ROUTER_IDENTITY_OBJECT_NAME );
wcscat( lpwszRouterIdentityObjectPath, ROUTER_CN_COMMA );
wcscat( lpwszRouterIdentityObjectPath, lpwszComputerObjectPath );
//
// Try to open the router identity object
//
hResult = ADSIOpenDSObject( lpwszRouterIdentityObjectPath,
NULL,
NULL,
0,
phObjectRouterIdentity );
if ( hResult == HRESULT_FROM_WIN32( ERROR_DS_NO_SUCH_OBJECT ) )
{
HANDLE hObjectComputer;
ADS_ATTR_INFO AttributeEntries[2];
ADSVALUE ObjectClassAttributeValue;
ADSVALUE msRRASAttributeValues[3];
WCHAR wchmsRRASAttributeValue1[50];
WCHAR wchmsRRASAttributeValue2[50];
WCHAR wchmsRRASAttributeValue3[50];
DWORD dwIndex = 0;
//
// If we failed because it doesn't exist, then create it
//
wcscpy( lpwszRouterIdentityObjectPath, ROUTER_LDAP_PREFIX );
wcscat( lpwszRouterIdentityObjectPath, lpwszComputerObjectPath );
hResult = ADSIOpenDSObject(
lpwszRouterIdentityObjectPath,
NULL,
NULL,
0,
&hObjectComputer );
if ( FAILED( hResult ) )
{
dwRetCode = HRESULT_CODE( hResult );
break;
}
//
// Set up attributes for this object
//
ObjectClassAttributeValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
ObjectClassAttributeValue.CaseIgnoreString = ROUTER_IDENTITY_CLASS;
AttributeEntries[0].pszAttrName = TEXT("ObjectClass");
AttributeEntries[0].dwControlCode = ADS_ATTR_APPEND;
AttributeEntries[0].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
AttributeEntries[0].pADsValues = &ObjectClassAttributeValue;
AttributeEntries[0].dwNumValues = 1;
if ( dwRouterType & ROUTER_ROLE_RAS )
{
wsprintf( wchmsRRASAttributeValue1,
TEXT("%d:%d:%d"),
DIM_MS_VENDOR_ID,
6,
602 );
msRRASAttributeValues[dwIndex].dwType =
ADSTYPE_CASE_IGNORE_STRING;
msRRASAttributeValues[dwIndex].CaseIgnoreString =
wchmsRRASAttributeValue1;
dwIndex++;
}
if ( dwRouterType & ROUTER_ROLE_LAN )
{
wsprintf( wchmsRRASAttributeValue2,
TEXT("%d:%d:%d"),
DIM_MS_VENDOR_ID,
6,
601 );
msRRASAttributeValues[dwIndex].dwType =
ADSTYPE_CASE_IGNORE_STRING;
msRRASAttributeValues[dwIndex].CaseIgnoreString =
wchmsRRASAttributeValue2;
dwIndex++;
}
if ( dwRouterType & ROUTER_ROLE_WAN )
{
wsprintf( wchmsRRASAttributeValue3,
TEXT("%d:%d:%d"),
DIM_MS_VENDOR_ID,
6,
603 );
msRRASAttributeValues[dwIndex].dwType =
ADSTYPE_CASE_IGNORE_STRING;
msRRASAttributeValues[dwIndex].CaseIgnoreString =
wchmsRRASAttributeValue3;
dwIndex++;
}
AttributeEntries[1].pszAttrName = ROUTER_OBJECT_ATTRIBUTE_NAME;
AttributeEntries[1].dwControlCode = ADS_ATTR_APPEND;
AttributeEntries[1].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
AttributeEntries[1].pADsValues = msRRASAttributeValues;
AttributeEntries[1].dwNumValues = dwIndex;
hResult = ADSICreateDSObject(
hObjectComputer,
ROUTER_IDENTITY_OBJECT_NAME,
AttributeEntries,
2 );
ADSICloseDSObject( hObjectComputer );
if ( FAILED( hResult ) )
{
dwRetCode = HRESULT_CODE( hResult );
break;
}
wcscpy(lpwszRouterIdentityObjectPath, ROUTER_LDAP_PREFIX);
wcscat(lpwszRouterIdentityObjectPath, ROUTER_IDENTITY_OBJECT_NAME);
wcscat(lpwszRouterIdentityObjectPath, ROUTER_CN_COMMA );
wcscat(lpwszRouterIdentityObjectPath, lpwszComputerObjectPath);
//
// Now open it to get the handle
//
hResult = ADSIOpenDSObject(
lpwszRouterIdentityObjectPath,
NULL,
NULL,
0,
phObjectRouterIdentity );
}
if ( FAILED( hResult ) )
{
dwRetCode = HRESULT_CODE( hResult );
}
else
{
dwRetCode = NO_ERROR;
}
} while( FALSE );
if ( lpwszRouterIdentityObjectPath != NULL )
{
LOCAL_FREE( lpwszRouterIdentityObjectPath );
}
if ( lpwszComputerObjectPath != NULL )
{
LOCAL_FREE( lpwszComputerObjectPath );
}
if ( pDomainControllerInfo != NULL )
{
NetApiBufferFree( pDomainControllerInfo );
}
TracePrintfExA( gblDIMConfigInfo.dwTraceId, TRACE_DIM,
"RouterIdentityObjectOpen returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: RouterIdentityObjectClose
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will close the router object.
//
VOID
RouterIdentityObjectClose(
IN HANDLE hObjectRouterIdentity
)
{
ADSICloseDSObject( hObjectRouterIdentity );
}
//**
//
// Call: RouterIdentityObjectGetAttributes
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will retreive all the attributes of the give Router object
//
DWORD
RouterIdentityObjectGetAttributes(
IN HANDLE hRouterIdentityObject,
OUT HANDLE * phRouterIdentityAttributes
)
{
ADS_ATTR_INFO * pADSAttributes = NULL;
DWORD dwNumAttributesReturned = 0;
HRESULT hResult;
*phRouterIdentityAttributes = NULL;
//
// Get all the attributes in this object
//
hResult = ADSIGetObjectAttributes(
hRouterIdentityObject,
RouterObjectAttributeNames,
sizeof( RouterObjectAttributeNames ) / sizeof( LPWSTR ),
&pADSAttributes,
&dwNumAttributesReturned );
if ( FAILED( hResult ) )
{
return( HRESULT_CODE( hResult ) );
}
if ( dwNumAttributesReturned > 0 )
{
*phRouterIdentityAttributes = (HANDLE)pADSAttributes;
}
else
{
TracePrintfExA( gblDIMConfigInfo.dwTraceId,
TRACE_DIM, "No attributes in identity object" );
}
return( NO_ERROR );
}
//**
//
// Call: RouterIdentityObjectIsValueSet
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will check to see if a give value exists for the attribute
//
BOOL
RouterIdentityObjectIsValueSet(
IN HANDLE hRouterIdentityAttributes,
IN DWORD dwVendorId,
IN DWORD dwType,
IN DWORD dwValue
)
{
ADS_ATTR_INFO * pADSAttributes = (ADS_ATTR_INFO *)hRouterIdentityAttributes;
DWORD dwIndex;
WCHAR wchValue[100];
CHAR chValue[100];
if ( pADSAttributes == NULL )
{
return( FALSE );
}
if (_wcsicmp(pADSAttributes->pszAttrName, ROUTER_OBJECT_ATTRIBUTE_NAME)!=0)
{
return( FALSE );
}
wsprintf( wchValue, TEXT("%d:%d:%d"), dwVendorId, dwType, dwValue );
sprintf( chValue, "%d:%d:%d", dwVendorId, dwType, dwValue );
for( dwIndex = 0; dwIndex < pADSAttributes->dwNumValues; dwIndex ++ )
{
ADSVALUE * pADsValue = &(pADSAttributes->pADsValues[dwIndex]);
switch (pADsValue->dwType) {
case ADSTYPE_PROV_SPECIFIC:
{
ADS_PROV_SPECIFIC *pProviderSpecific;
pProviderSpecific = &pADsValue->ProviderSpecific;
if (strncmp( pProviderSpecific->lpValue, chValue,
pProviderSpecific->dwLength) == 0 )
{
return( TRUE );
}
break;
}
case ADSTYPE_CASE_IGNORE_STRING:
if ( _wcsicmp( pADsValue->CaseIgnoreString, wchValue ) == 0 )
{
return( TRUE );
}
break;
default : //same as ADSTYPE_CASE_IGNORE_STRING
if ( _wcsicmp( pADsValue->CaseIgnoreString, wchValue ) == 0 )
{
return( TRUE );
}
break;
}
}
return( FALSE );
}
//**
//
// Call: RouterIdentityObjectGetValue
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will get the specified indexed value from the router object
//
DWORD
RouterIdentityObjectGetValue(
IN HANDLE hRouterIdentityAttributes,
IN DWORD dwValueIndex,
IN DWORD * lpdwVendorId,
IN DWORD * lpdwType,
IN DWORD * lpdwValue
)
{
ADS_ATTR_INFO * pADSAttributes = (ADS_ATTR_INFO *)hRouterIdentityAttributes;
DWORD dwIndex;
ADSVALUE * pADsValue;
if ( pADSAttributes == NULL )
{
return( ERROR_DS_NO_ATTRIBUTE_OR_VALUE );
}
if (_wcsicmp(pADSAttributes->pszAttrName, ROUTER_OBJECT_ATTRIBUTE_NAME)!=0)
{
return( ERROR_DS_NO_ATTRIBUTE_OR_VALUE );
}
if ( dwValueIndex >= pADSAttributes->dwNumValues )
{
*lpdwVendorId = (DWORD)-1;
*lpdwType = (DWORD)-1;
*lpdwValue = (DWORD)-1;
return( NO_ERROR );
}
pADsValue = &(pADSAttributes->pADsValues[dwValueIndex]);
switch (pADsValue->dwType) {
case ADSTYPE_PROV_SPECIFIC:
{
ADS_PROV_SPECIFIC *pProviderSpecific;
CHAR chValue[100];
pProviderSpecific = &pADsValue->ProviderSpecific;
strncpy(chValue, pProviderSpecific->lpValue,
pProviderSpecific->dwLength);
chValue[pProviderSpecific->dwLength] = 0;
if (scanf( chValue,
TEXT("%d:%d:%d"),
lpdwVendorId,
lpdwType,
lpdwValue ) == EOF)
{
return ERROR_DS_INVALID_ATTRIBUTE_SYNTAX;
}
break;
}
default :
{
if (swscanf( pADsValue->CaseIgnoreString,
TEXT("%d:%d:%d"),
lpdwVendorId,
lpdwType,
lpdwValue ) == EOF)
{
return ERROR_DS_INVALID_ATTRIBUTE_SYNTAX;
}
break;
}
}
return( NO_ERROR );
}
//**
//
// Call: RouterIdentityObjectAddRemoveValue
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will add or remove a value from the multi-valued attribute
//
DWORD
RouterIdentityObjectAddRemoveValue(
IN HANDLE hRouterIdentityObject,
IN DWORD dwVendorId,
IN DWORD dwType,
IN DWORD dwValue,
IN BOOL fAdd
)
{
HRESULT hResult;
DWORD dwNumAttributesModified;
ADS_ATTR_INFO AttributeEntry[1];
WCHAR wchValue[100];
ADSVALUE AttributeValue;
wsprintf( wchValue, TEXT("%d:%d:%d"), dwVendorId, dwType, dwValue );
AttributeValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
AttributeValue.CaseIgnoreString = wchValue;
AttributeEntry[0].pszAttrName = ROUTER_OBJECT_ATTRIBUTE_NAME;
AttributeEntry[0].dwControlCode = ( fAdd )
? ADS_ATTR_APPEND
: ADS_ATTR_DELETE;
AttributeEntry[0].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
AttributeEntry[0].pADsValues = &AttributeValue;
AttributeEntry[0].dwNumValues = 1;
if ( fAdd )
{
TracePrintfExA( gblDIMConfigInfo.dwTraceId,
TRACE_DIM,
"Adding value %ws in the Router Identity Object",
wchValue );
}
else
{
TracePrintfExA( gblDIMConfigInfo.dwTraceId,
TRACE_DIM,
"Removing value %ws in the Router Identity Object",
wchValue );
}
hResult = ADSISetObjectAttributes( hRouterIdentityObject,
AttributeEntry,
1,
&dwNumAttributesModified );
if ( FAILED( hResult ) )
{
return( HRESULT_CODE( hResult ) );
}
return( NO_ERROR );
}
//**
//
// Call: RouterIdentityObjectFreeAttributes
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Frees allocated set of attributes returned by
// RouterIdentityObjectGetAttributes
//
VOID
RouterIdentityObjectFreeAttributes(
IN HANDLE hRouterIdentityAttributes
)
{
if ( hRouterIdentityAttributes != NULL )
{
FreeADsMem( (ADS_ATTR_INFO *)hRouterIdentityAttributes );
}
}
//**
//
// Call: RouterIdentityObjectSetAttributes
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will gather all current configuration information and plumb it
// into the router identity object in the DS.
//
// Note:
// This API first takes the lock on the interface table,
// then it takes the lock around the device table to get the
// installed device types. Hence this API MUST NOT be called
// while holding a lock around the interface table since this
// violates the design principal of first holding the
// device lock before holding the interface lock.
//
DWORD
RouterIdentityObjectSetAttributes(
IN HANDLE hRouterIdentityObject
)
{
DWORD dwRetCode;
HANDLE hRouterIdentityAttributes;
DWORD dwIndex = 0;
ROUTER_IDENTITY_ATTRIBUTE RIAttributes[DIM_MAX_IDENTITY_ATTRS];
DWORD dwXportIndex;
//
// Obtain router identity information plumbed in the DS currently
//
dwRetCode = RouterIdentityObjectGetAttributes(
hRouterIdentityObject,
&hRouterIdentityAttributes );
if ( dwRetCode != NO_ERROR )
{
return( dwRetCode );
}
//
// Now get the current running configuration of the router
//
//
// First, what is our role?
//
if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_LAN )
{
RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID;
RIAttributes[dwIndex].dwType = 6;
RIAttributes[dwIndex].dwValue = 601;
dwIndex++;
}
if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_RAS )
{
RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID;
RIAttributes[dwIndex].dwType = 6;
RIAttributes[dwIndex].dwValue = 602;
dwIndex++;
}
if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_WAN )
{
RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID;
RIAttributes[dwIndex].dwType = 6;
RIAttributes[dwIndex].dwValue = 603;
dwIndex++;
}
//
// Check if a LAN interface exists
//
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
if ( IfObjectDoesLanInterfaceExist() )
{
RIAttributes[dwIndex].dwVendorId = 311;
RIAttributes[dwIndex].dwType = 6;
RIAttributes[dwIndex].dwValue = 712;
dwIndex++;
}
//
// Get all IP routing protocols
//
if ( ( dwXportIndex = GetTransportIndex( PID_IP ) ) != (DWORD)-1 )
{
BYTE * pGlobalInfo = NULL;
DWORD dwGlobalInfoSize = 0;
dwRetCode =
gblRouterManagers[dwXportIndex].DdmRouterIf.GetGlobalInfo(
pGlobalInfo,
&dwGlobalInfoSize );
if ( dwRetCode == ERROR_INSUFFICIENT_BUFFER )
{
if ( dwGlobalInfoSize > 0 )
{
pGlobalInfo = LOCAL_ALLOC( LPTR, dwGlobalInfoSize );
if ( pGlobalInfo != NULL )
{
dwRetCode =
gblRouterManagers[dwXportIndex].DdmRouterIf.GetGlobalInfo(
pGlobalInfo,
&dwGlobalInfoSize );
if ( dwRetCode == NO_ERROR )
{
DWORD dwRoutingProtIndex;
RTR_INFO_BLOCK_HEADER * pInfoBlock =
(RTR_INFO_BLOCK_HEADER *)(pGlobalInfo);
for ( dwRoutingProtIndex = 0;
dwRoutingProtIndex < pInfoBlock->TocEntriesCount;
dwRoutingProtIndex++ )
{
DWORD dwVendorId;
RIAttributes[dwIndex].dwType
= TYPE_FROM_PROTO_ID(
pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
//
// Add unicast and multicast protocol ids
//
if ( ( RIAttributes[dwIndex].dwType
== PROTO_TYPE_UCAST ) ||
( RIAttributes[dwIndex].dwType
== PROTO_TYPE_MCAST ) )
{
DWORD dwProtoId;
dwVendorId = VENDOR_FROM_PROTO_ID(
pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
dwProtoId = PROTO_FROM_PROTO_ID(
pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
//
// Nothing defined for dhcp relay agent
//
if ( dwProtoId == PROTO_IP_BOOTP )
{
continue;
}
if ( ( dwVendorId == PROTO_VENDOR_MS0 ) ||
( dwVendorId == PROTO_VENDOR_MS1 ) ||
( dwVendorId == PROTO_VENDOR_MS2 ) )
{
RIAttributes[dwIndex].dwVendorId = 311;
}
else
{
RIAttributes[dwIndex].dwVendorId = dwVendorId;
}
RIAttributes[dwIndex].dwValue
= PROTO_FROM_PROTO_ID(
pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
dwIndex++;
}
//
// Add ms0 protocols
//
else if (RIAttributes[dwIndex].dwType ==
PROTO_TYPE_MS0 )
{
DWORD dwProtoId;
dwVendorId = VENDOR_FROM_PROTO_ID(
pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
dwProtoId = PROTO_FROM_PROTO_ID(
pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
//
// Check for NAT
// Vendor= MS, TypeMajor= 6, TypeMinor= 604
//
if ( ( dwVendorId == PROTO_VENDOR_MS1 ) &&
( dwProtoId == PROTO_IP_NAT)
)
{
RIAttributes[dwIndex].dwVendorId =
PROTO_VENDOR_MS1;
RIAttributes[dwIndex].dwType =
6;
RIAttributes[dwIndex].dwValue =
604;
dwIndex++;
}
}
}
}
LOCAL_FREE( pGlobalInfo );
}
}
}
// As per amritanr, if you have the ip router installed,
// then ip forwarding is always turned on.
//
// Ip Fwd'ing Enabled: Vendor= MS, TypeMajor= 6, TypeMinor= 501
//
RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
RIAttributes[dwIndex].dwType = 6;
RIAttributes[dwIndex].dwValue = 501;
dwIndex++;
}
//
// Get all IPX routing protocols
//
if ( ( dwXportIndex = GetTransportIndex( PID_IPX ) ) != (DWORD)-1 )
{
// All nt5 ipx routers support rip and sap. Go ahead
// and attributes for both.
//
// IPXRIP: Vendor= MS, TypeMajor= 5, TypeMinor= 1
//
RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
RIAttributes[dwIndex].dwType = 5;
RIAttributes[dwIndex].dwValue = 1;
dwIndex++;
// IPXSAP: Vendor= MS, TypeMajor= 5, TypeMinor= 2
//
RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
RIAttributes[dwIndex].dwType = 5;
RIAttributes[dwIndex].dwValue = 2;
dwIndex++;
// Ipx Fwd'ing Enabled: Vendor= MS, TypeMajor= 6, TypeMinor= 502
//
RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
RIAttributes[dwIndex].dwType = 6;
RIAttributes[dwIndex].dwValue = 502;
dwIndex++;
}
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
RIAttributes[dwIndex].dwVendorId = (DWORD)-1;
RIAttributes[dwIndex].dwType = (DWORD)-1;
RIAttributes[dwIndex].dwValue = (DWORD)-1;
//
// Get all the RAS server information
//
if ( gblDIMConfigInfo.dwRouterRole & ( ROUTER_ROLE_RAS | ROUTER_ROLE_WAN ) )
{
DWORD (*DDMGetIdentityAttributes)( ROUTER_IDENTITY_ATTRIBUTE * ) =
(DWORD(*)( ROUTER_IDENTITY_ATTRIBUTE * ))
GetDDMEntryPoint("DDMGetIdentityAttributes");
if(NULL != DDMGetIdentityAttributes)
{
dwRetCode = DDMGetIdentityAttributes( RIAttributes );
}
else
{
ASSERT(FALSE);
}
}
//
// Now obtain walk thru the current configration an make sure that
// all of it is plumbed. If it is not then go ahead and set it.
//
for ( dwIndex = 0;
RIAttributes[dwIndex].dwVendorId != (DWORD)-1;
dwIndex++ )
{
//
// If this attribute is not set, then set it
//
if ( !RouterIdentityObjectIsValueSet(
hRouterIdentityAttributes,
RIAttributes[dwIndex].dwVendorId,
RIAttributes[dwIndex].dwType,
RIAttributes[dwIndex].dwValue ) )
{
RouterIdentityObjectAddRemoveValue(
hRouterIdentityObject,
RIAttributes[dwIndex].dwVendorId,
RIAttributes[dwIndex].dwType,
RIAttributes[dwIndex].dwValue,
TRUE );
}
}
//
// Now walk thru and remove attributes in the DS that are not in our
// current configuration. We reconcile all attributes with
// dwType values 0,1 or 5, and with dwVendorId of 311 (Microsoft) with
// dwType value of 6.
//
for ( dwIndex = 0;; dwIndex++ )
{
DWORD dwVendorId;
DWORD dwType;
DWORD dwValue;
DWORD dwCurrentValueIndex;
BOOL fInCurrentConfiguration = FALSE;
dwRetCode = RouterIdentityObjectGetValue( hRouterIdentityAttributes,
dwIndex,
&dwVendorId,
&dwType,
&dwValue );
if ( dwRetCode != NO_ERROR )
{
break;
}
//
// We are done
//
if ( dwVendorId == (DWORD)-1 )
{
break;
}
//
// Ignore these types
//
if ( ( dwType != 0 ) && ( dwType != 1 ) && ( dwType != 5 ) &&
( !( ( dwType == 6 ) && ( dwVendorId == DIM_MS_VENDOR_ID ) ) ) )
{
continue;
}
//
// Now check to see it this attribute is a member of our current
// configuration
//
for ( dwCurrentValueIndex = 0;
RIAttributes[dwCurrentValueIndex].dwVendorId != (DWORD)-1;
dwCurrentValueIndex++ )
{
if ( (RIAttributes[dwCurrentValueIndex].dwVendorId == dwVendorId)&&
(RIAttributes[dwCurrentValueIndex].dwType == dwType ) &&
(RIAttributes[dwCurrentValueIndex].dwValue == dwValue ) )
{
//
// Attribute is part of current configuration
//
fInCurrentConfiguration = TRUE;
}
}
if ( !fInCurrentConfiguration )
{
//
// Remove this attribute from the DS since it is not in our
// current configuration
//
dwRetCode = RouterIdentityObjectAddRemoveValue(
hRouterIdentityObject,
dwVendorId,
dwType,
dwValue,
FALSE );
if ( dwRetCode != NO_ERROR )
{
break;
}
}
}
RouterIdentityObjectFreeAttributes( hRouterIdentityAttributes );
return( dwRetCode );
}
//**
//
// Call: RouterIdentityObjectUpdateAttributes
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will be called to update the attributes currently set in the DS
// or to set it if it was not able to be set originally
//
VOID
RouterIdentityObjectUpdateAttributes(
IN PVOID pParameter,
IN BOOLEAN fTimedOut
)
{
DWORD dwRetCode = NO_ERROR;
BOOL fCalledFromTimer = (BOOL)PtrToUlong(pParameter);
//
// Make sure service is in the running state
//
if ( gblDIMConfigInfo.ServiceStatus.dwCurrentState != SERVICE_RUNNING )
{
if(fCalledFromTimer)
{
//
// Delete the timer if theres one queued before we
// return from here otherwise DeleteTimerQ in
// DimCleanup will hang.
//
RtlDeleteTimer(gblDIMConfigInfo.hTimerQ,
gblDIMConfigInfo.hTimer,
NULL);
gblDIMConfigInfo.hTimer = NULL;
}
return;
}
if ( fCalledFromTimer )
{
//
// Always call DeleteTimer otherwise we will leak memory
//
RtlDeleteTimer( gblDIMConfigInfo.hTimerQ,
gblDIMConfigInfo.hTimer,
NULL );
gblDIMConfigInfo.hTimer = NULL;
//
// Called from timer thread so we first try to obtain a handle to
// the router idenitity object
//
dwRetCode = RouterIdentityObjectOpen(
NULL,
( gblDIMConfigInfo.dwRouterRole ),
&(gblDIMConfigInfo.hObjectRouterIdentity) );
if ( ( dwRetCode != NO_ERROR ) ||
( gblDIMConfigInfo.hObjectRouterIdentity == NULL ) )
{
//
// Check to see if service is stopping and create a timer for this
// only if it is in running state.
//
if(gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
//
// Couldn't access DC, try again later for a max of once a day
//
if ( gblDIMConfigInfo.dwRouterIdentityDueTime < 24*60*60*1000 )
{
gblDIMConfigInfo.dwRouterIdentityDueTime *= 2;
}
TracePrintfExA(
gblDIMConfigInfo.dwTraceId,
TRACE_DIM,
"Could not access DC, will set router attributes later");
RtlCreateTimer( gblDIMConfigInfo.hTimerQ,
&(gblDIMConfigInfo.hTimer),
RouterIdentityObjectUpdateAttributes,
(PVOID)TRUE,
gblDIMConfigInfo.dwRouterIdentityDueTime,
0,
WT_EXECUTEDEFAULT );
}
return;
}
//
// Otherwise we succeeded in opening the router identity object
// and we set the identity information below.
//
}
else
{
//
// If we do not have a handle for the router identity object, then
// either we are in the process of obtaining it or we are not
// a member of the DS, so in both cases simply return
//
if ( gblDIMConfigInfo.hObjectRouterIdentity == NULL )
{
return;
}
}
//
// Can be called from different threads at the same time so we need
// Critical section around this code so that we do not have 2 writers to
// the DS at the same time that trample on each other. ex could be called
// by DDM thread as well as the timer thread.
//
EnterCriticalSection( &(gblDIMConfigInfo.CSRouterIdentity) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId,
TRACE_DIM,
"Setting router attributes in the identity object" );
RouterIdentityObjectSetAttributes( gblDIMConfigInfo.hObjectRouterIdentity );
LeaveCriticalSection( &(gblDIMConfigInfo.CSRouterIdentity) );
}
//**
//
// Call: RouterIdentityObjectUpdateAttributesForDD
//
// Returns: None
//
// Description:
//
VOID
RouterIdentityObjectUpdateAttributesForDDM(
PVOID pParameter
)
{
RouterIdentityObjectUpdateAttributes( (PVOID)NULL, FALSE );
}
//**
//
// Call: RouterIdentityObjectUpdateDDMAttributes
//
// Returns: None
//
// Description: Export this call to DDM. When DDM calls this call, it already
// has taken a lock around it's device table and cannot make
// the call to update attributes directly because the
// RouterIdentityObjectUpdateAttributes call takes the
// lock around the RouterIdentity object leading to a deadlock.
// Hence we execute this call asynchronously using a worker
// thread.
//
//
VOID
RouterIdentityObjectUpdateDDMAttributes(
VOID
)
{
RtlQueueWorkItem( RouterIdentityObjectUpdateAttributesForDDM,
NULL,
WT_EXECUTEDEFAULT );
}