1196 lines
37 KiB
C
1196 lines
37 KiB
C
/********************************************************************/
|
||
/** 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 = GetLastError();
|
||
|
||
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 = GetLastError();
|
||
|
||
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;
|
||
|
||
scanf( chValue,
|
||
TEXT("%d:%d:%d"),
|
||
lpdwVendorId,
|
||
lpdwType,
|
||
lpdwValue );
|
||
break;
|
||
}
|
||
default :
|
||
{
|
||
swscanf( pADsValue->CaseIgnoreString,
|
||
TEXT("%d:%d:%d"),
|
||
lpdwVendorId,
|
||
lpdwType,
|
||
lpdwValue );
|
||
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 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
if ( fCalledFromTimer )
|
||
{
|
||
//
|
||
// Always call DeleteTimer otherwise we will leak memory
|
||
//
|
||
|
||
RtlDeleteTimer( gblDIMConfigInfo.hTimerQ,
|
||
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 ) )
|
||
{
|
||
//
|
||
// 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 );
|
||
}
|