Source code of Windows XP (NT5)
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.

1195 lines
37 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1985-1997 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: rtridobj
  7. //
  8. // Description: Support routines to manipulate router information in the
  9. // router object
  10. //
  11. // History: Feb 11,1998 NarenG Created original version.
  12. //
  13. #include "dimsvcp.h"
  14. #include <activeds.h>
  15. #include <adsi.h>
  16. #include <ntdsapi.h>
  17. #include <dsgetdc.h>
  18. #include <lmapibuf.h>
  19. #define SECURITY_WIN32
  20. #include <security.h>
  21. #include <routprot.h>
  22. #include <rtinfo.h>
  23. #include <dimsvc.h> // Generated by MIDL
  24. #define ROUTER_IDENTITY_OBJECT_NAME TEXT("CN=RouterIdentity")
  25. #define ROUTER_OBJECT_ATTRIBUTE_NAME TEXT("MsRRASAttribute")
  26. #define ROUTER_LDAP_PREFIX TEXT("LDAP://")
  27. #define ROUTER_CN_COMMA TEXT(",")
  28. #define ROUTER_IDENTITY_CLASS TEXT("RRASAdministrationConnectionPoint")
  29. LPWSTR RouterObjectAttributeNames[] =
  30. {
  31. ROUTER_OBJECT_ATTRIBUTE_NAME
  32. };
  33. //**
  34. //
  35. // Call: RouterIdentityObjectOpen
  36. //
  37. // Returns: NO_ERROR - Success
  38. // Non-zero returns - Failure
  39. //
  40. // Description: Given the machine name of the router, will return the handle
  41. // to the router's administration service point or router object.
  42. //
  43. DWORD
  44. RouterIdentityObjectOpen(
  45. IN LPWSTR lpwszRouterName,
  46. IN DWORD dwRouterType,
  47. OUT HANDLE * phObjectRouterIdentity
  48. )
  49. {
  50. DWORD dwRetCode;
  51. LPWSTR lpwszRouterIdentityObjectPath = NULL;
  52. LPWSTR lpwszComputerObjectPath = NULL;
  53. DOMAIN_CONTROLLER_INFO * pDomainControllerInfo = NULL;
  54. HRESULT hResult = HRESULT_FROM_WIN32(NO_ERROR);
  55. DWORD dwCharCount;
  56. do
  57. {
  58. dwRetCode = DsGetDcName( NULL,
  59. NULL,
  60. NULL,
  61. NULL,
  62. DS_DIRECTORY_SERVICE_REQUIRED |
  63. DS_WRITABLE_REQUIRED,
  64. &pDomainControllerInfo );
  65. if ( dwRetCode != NO_ERROR )
  66. {
  67. TracePrintfExA( gblDIMConfigInfo.dwTraceId,
  68. TRACE_DIM, "No DS located, DsGetDcName()=%d",
  69. dwRetCode );
  70. break;
  71. }
  72. if ( !( pDomainControllerInfo->Flags & DS_DS_FLAG ) )
  73. {
  74. TracePrintfExA( gblDIMConfigInfo.dwTraceId,
  75. TRACE_DIM, "No DS located");
  76. dwRetCode = ERROR_DOMAIN_CONTROLLER_NOT_FOUND;
  77. break;
  78. }
  79. //
  80. // Get the CN of the router object
  81. //
  82. dwCharCount = 200;
  83. lpwszComputerObjectPath = LOCAL_ALLOC(LPTR, dwCharCount*sizeof(WCHAR));
  84. if (lpwszComputerObjectPath == NULL)
  85. {
  86. TracePrintfExA( gblDIMConfigInfo.dwTraceId,
  87. TRACE_DIM, "Memory exhausted -- unable to continue");
  88. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  89. break;
  90. }
  91. if ( !GetComputerObjectName( NameFullyQualifiedDN,
  92. lpwszComputerObjectPath,
  93. &dwCharCount ) )
  94. {
  95. //
  96. // We failed for some other reason
  97. //
  98. LPWSTR lpwsComputerObjectPathReAlloc =
  99. LOCAL_REALLOC( lpwszComputerObjectPath,
  100. (++dwCharCount)*sizeof(WCHAR) );
  101. if ( lpwsComputerObjectPathReAlloc == NULL )
  102. {
  103. dwRetCode = GetLastError();
  104. break;
  105. }
  106. lpwszComputerObjectPath = lpwsComputerObjectPathReAlloc;
  107. if ( !GetComputerObjectName( NameFullyQualifiedDN,
  108. lpwszComputerObjectPath,
  109. &dwCharCount ) )
  110. {
  111. dwRetCode = GetLastError();
  112. break;
  113. }
  114. }
  115. lpwszRouterIdentityObjectPath =
  116. LOCAL_ALLOC( LPTR,
  117. sizeof( ROUTER_LDAP_PREFIX ) +
  118. sizeof( ROUTER_IDENTITY_OBJECT_NAME ) +
  119. sizeof( ROUTER_CN_COMMA ) +
  120. ((wcslen( lpwszComputerObjectPath )+1)* sizeof(WCHAR)));
  121. if ( lpwszRouterIdentityObjectPath == NULL )
  122. {
  123. dwRetCode = GetLastError();
  124. break;
  125. }
  126. wcscpy( lpwszRouterIdentityObjectPath, ROUTER_LDAP_PREFIX );
  127. wcscat( lpwszRouterIdentityObjectPath, ROUTER_IDENTITY_OBJECT_NAME );
  128. wcscat( lpwszRouterIdentityObjectPath, ROUTER_CN_COMMA );
  129. wcscat( lpwszRouterIdentityObjectPath, lpwszComputerObjectPath );
  130. //
  131. // Try to open the router identity object
  132. //
  133. hResult = ADSIOpenDSObject( lpwszRouterIdentityObjectPath,
  134. NULL,
  135. NULL,
  136. 0,
  137. phObjectRouterIdentity );
  138. if ( hResult == HRESULT_FROM_WIN32( ERROR_DS_NO_SUCH_OBJECT ) )
  139. {
  140. HANDLE hObjectComputer;
  141. ADS_ATTR_INFO AttributeEntries[2];
  142. ADSVALUE ObjectClassAttributeValue;
  143. ADSVALUE msRRASAttributeValues[3];
  144. WCHAR wchmsRRASAttributeValue1[50];
  145. WCHAR wchmsRRASAttributeValue2[50];
  146. WCHAR wchmsRRASAttributeValue3[50];
  147. DWORD dwIndex = 0;
  148. //
  149. // If we failed because it doesn't exist, then create it
  150. //
  151. wcscpy( lpwszRouterIdentityObjectPath, ROUTER_LDAP_PREFIX );
  152. wcscat( lpwszRouterIdentityObjectPath, lpwszComputerObjectPath );
  153. hResult = ADSIOpenDSObject(
  154. lpwszRouterIdentityObjectPath,
  155. NULL,
  156. NULL,
  157. 0,
  158. &hObjectComputer );
  159. if ( FAILED( hResult ) )
  160. {
  161. dwRetCode = HRESULT_CODE( hResult );
  162. break;
  163. }
  164. //
  165. // Set up attributes for this object
  166. //
  167. ObjectClassAttributeValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
  168. ObjectClassAttributeValue.CaseIgnoreString = ROUTER_IDENTITY_CLASS;
  169. AttributeEntries[0].pszAttrName = TEXT("ObjectClass");
  170. AttributeEntries[0].dwControlCode = ADS_ATTR_APPEND;
  171. AttributeEntries[0].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  172. AttributeEntries[0].pADsValues = &ObjectClassAttributeValue;
  173. AttributeEntries[0].dwNumValues = 1;
  174. if ( dwRouterType & ROUTER_ROLE_RAS )
  175. {
  176. wsprintf( wchmsRRASAttributeValue1,
  177. TEXT("%d:%d:%d"),
  178. DIM_MS_VENDOR_ID,
  179. 6,
  180. 602 );
  181. msRRASAttributeValues[dwIndex].dwType =
  182. ADSTYPE_CASE_IGNORE_STRING;
  183. msRRASAttributeValues[dwIndex].CaseIgnoreString =
  184. wchmsRRASAttributeValue1;
  185. dwIndex++;
  186. }
  187. if ( dwRouterType & ROUTER_ROLE_LAN )
  188. {
  189. wsprintf( wchmsRRASAttributeValue2,
  190. TEXT("%d:%d:%d"),
  191. DIM_MS_VENDOR_ID,
  192. 6,
  193. 601 );
  194. msRRASAttributeValues[dwIndex].dwType =
  195. ADSTYPE_CASE_IGNORE_STRING;
  196. msRRASAttributeValues[dwIndex].CaseIgnoreString =
  197. wchmsRRASAttributeValue2;
  198. dwIndex++;
  199. }
  200. if ( dwRouterType & ROUTER_ROLE_WAN )
  201. {
  202. wsprintf( wchmsRRASAttributeValue3,
  203. TEXT("%d:%d:%d"),
  204. DIM_MS_VENDOR_ID,
  205. 6,
  206. 603 );
  207. msRRASAttributeValues[dwIndex].dwType =
  208. ADSTYPE_CASE_IGNORE_STRING;
  209. msRRASAttributeValues[dwIndex].CaseIgnoreString =
  210. wchmsRRASAttributeValue3;
  211. dwIndex++;
  212. }
  213. AttributeEntries[1].pszAttrName = ROUTER_OBJECT_ATTRIBUTE_NAME;
  214. AttributeEntries[1].dwControlCode = ADS_ATTR_APPEND;
  215. AttributeEntries[1].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  216. AttributeEntries[1].pADsValues = msRRASAttributeValues;
  217. AttributeEntries[1].dwNumValues = dwIndex;
  218. hResult = ADSICreateDSObject(
  219. hObjectComputer,
  220. ROUTER_IDENTITY_OBJECT_NAME,
  221. AttributeEntries,
  222. 2 );
  223. ADSICloseDSObject( hObjectComputer );
  224. if ( FAILED( hResult ) )
  225. {
  226. dwRetCode = HRESULT_CODE( hResult );
  227. break;
  228. }
  229. wcscpy(lpwszRouterIdentityObjectPath, ROUTER_LDAP_PREFIX);
  230. wcscat(lpwszRouterIdentityObjectPath, ROUTER_IDENTITY_OBJECT_NAME);
  231. wcscat(lpwszRouterIdentityObjectPath, ROUTER_CN_COMMA );
  232. wcscat(lpwszRouterIdentityObjectPath, lpwszComputerObjectPath);
  233. //
  234. // Now open it to get the handle
  235. //
  236. hResult = ADSIOpenDSObject(
  237. lpwszRouterIdentityObjectPath,
  238. NULL,
  239. NULL,
  240. 0,
  241. phObjectRouterIdentity );
  242. }
  243. if ( FAILED( hResult ) )
  244. {
  245. dwRetCode = HRESULT_CODE( hResult );
  246. }
  247. else
  248. {
  249. dwRetCode = NO_ERROR;
  250. }
  251. } while( FALSE );
  252. if ( lpwszRouterIdentityObjectPath != NULL )
  253. {
  254. LOCAL_FREE( lpwszRouterIdentityObjectPath );
  255. }
  256. if ( lpwszComputerObjectPath != NULL )
  257. {
  258. LOCAL_FREE( lpwszComputerObjectPath );
  259. }
  260. if ( pDomainControllerInfo != NULL )
  261. {
  262. NetApiBufferFree( pDomainControllerInfo );
  263. }
  264. TracePrintfExA( gblDIMConfigInfo.dwTraceId, TRACE_DIM,
  265. "RouterIdentityObjectOpen returned %d", dwRetCode );
  266. return( dwRetCode );
  267. }
  268. //**
  269. //
  270. // Call: RouterIdentityObjectClose
  271. //
  272. // Returns: NO_ERROR - Success
  273. // Non-zero returns - Failure
  274. //
  275. // Description: Will close the router object.
  276. //
  277. VOID
  278. RouterIdentityObjectClose(
  279. IN HANDLE hObjectRouterIdentity
  280. )
  281. {
  282. ADSICloseDSObject( hObjectRouterIdentity );
  283. }
  284. //**
  285. //
  286. // Call: RouterIdentityObjectGetAttributes
  287. //
  288. // Returns: NO_ERROR - Success
  289. // Non-zero returns - Failure
  290. //
  291. // Description: Will retreive all the attributes of the give Router object
  292. //
  293. DWORD
  294. RouterIdentityObjectGetAttributes(
  295. IN HANDLE hRouterIdentityObject,
  296. OUT HANDLE * phRouterIdentityAttributes
  297. )
  298. {
  299. ADS_ATTR_INFO * pADSAttributes = NULL;
  300. DWORD dwNumAttributesReturned = 0;
  301. HRESULT hResult;
  302. *phRouterIdentityAttributes = NULL;
  303. //
  304. // Get all the attributes in this object
  305. //
  306. hResult = ADSIGetObjectAttributes(
  307. hRouterIdentityObject,
  308. RouterObjectAttributeNames,
  309. sizeof( RouterObjectAttributeNames ) / sizeof( LPWSTR ),
  310. &pADSAttributes,
  311. &dwNumAttributesReturned );
  312. if ( FAILED( hResult ) )
  313. {
  314. return( HRESULT_CODE( hResult ) );
  315. }
  316. if ( dwNumAttributesReturned > 0 )
  317. {
  318. *phRouterIdentityAttributes = (HANDLE)pADSAttributes;
  319. }
  320. else
  321. {
  322. TracePrintfExA( gblDIMConfigInfo.dwTraceId,
  323. TRACE_DIM, "No attributes in identity object" );
  324. }
  325. return( NO_ERROR );
  326. }
  327. //**
  328. //
  329. // Call: RouterIdentityObjectIsValueSet
  330. //
  331. // Returns: NO_ERROR - Success
  332. // Non-zero returns - Failure
  333. //
  334. // Description: Will check to see if a give value exists for the attribute
  335. //
  336. BOOL
  337. RouterIdentityObjectIsValueSet(
  338. IN HANDLE hRouterIdentityAttributes,
  339. IN DWORD dwVendorId,
  340. IN DWORD dwType,
  341. IN DWORD dwValue
  342. )
  343. {
  344. ADS_ATTR_INFO * pADSAttributes = (ADS_ATTR_INFO *)hRouterIdentityAttributes;
  345. DWORD dwIndex;
  346. WCHAR wchValue[100];
  347. CHAR chValue[100];
  348. if ( pADSAttributes == NULL )
  349. {
  350. return( FALSE );
  351. }
  352. if (_wcsicmp(pADSAttributes->pszAttrName, ROUTER_OBJECT_ATTRIBUTE_NAME)!=0)
  353. {
  354. return( FALSE );
  355. }
  356. wsprintf( wchValue, TEXT("%d:%d:%d"), dwVendorId, dwType, dwValue );
  357. sprintf( chValue, "%d:%d:%d", dwVendorId, dwType, dwValue );
  358. for( dwIndex = 0; dwIndex < pADSAttributes->dwNumValues; dwIndex ++ )
  359. {
  360. ADSVALUE * pADsValue = &(pADSAttributes->pADsValues[dwIndex]);
  361. switch (pADsValue->dwType) {
  362. case ADSTYPE_PROV_SPECIFIC:
  363. {
  364. ADS_PROV_SPECIFIC *pProviderSpecific;
  365. pProviderSpecific = &pADsValue->ProviderSpecific;
  366. if (strncmp( pProviderSpecific->lpValue, chValue,
  367. pProviderSpecific->dwLength) == 0 )
  368. {
  369. return( TRUE );
  370. }
  371. break;
  372. }
  373. case ADSTYPE_CASE_IGNORE_STRING:
  374. if ( _wcsicmp( pADsValue->CaseIgnoreString, wchValue ) == 0 )
  375. {
  376. return( TRUE );
  377. }
  378. break;
  379. default : //same as ADSTYPE_CASE_IGNORE_STRING
  380. if ( _wcsicmp( pADsValue->CaseIgnoreString, wchValue ) == 0 )
  381. {
  382. return( TRUE );
  383. }
  384. break;
  385. }
  386. }
  387. return( FALSE );
  388. }
  389. //**
  390. //
  391. // Call: RouterIdentityObjectGetValue
  392. //
  393. // Returns: NO_ERROR - Success
  394. // Non-zero returns - Failure
  395. //
  396. // Description: Will get the specified indexed value from the router object
  397. //
  398. DWORD
  399. RouterIdentityObjectGetValue(
  400. IN HANDLE hRouterIdentityAttributes,
  401. IN DWORD dwValueIndex,
  402. IN DWORD * lpdwVendorId,
  403. IN DWORD * lpdwType,
  404. IN DWORD * lpdwValue
  405. )
  406. {
  407. ADS_ATTR_INFO * pADSAttributes = (ADS_ATTR_INFO *)hRouterIdentityAttributes;
  408. DWORD dwIndex;
  409. ADSVALUE * pADsValue;
  410. if ( pADSAttributes == NULL )
  411. {
  412. return( ERROR_DS_NO_ATTRIBUTE_OR_VALUE );
  413. }
  414. if (_wcsicmp(pADSAttributes->pszAttrName, ROUTER_OBJECT_ATTRIBUTE_NAME)!=0)
  415. {
  416. return( ERROR_DS_NO_ATTRIBUTE_OR_VALUE );
  417. }
  418. if ( dwValueIndex >= pADSAttributes->dwNumValues )
  419. {
  420. *lpdwVendorId = (DWORD)-1;
  421. *lpdwType = (DWORD)-1;
  422. *lpdwValue = (DWORD)-1;
  423. return( NO_ERROR );
  424. }
  425. pADsValue = &(pADSAttributes->pADsValues[dwValueIndex]);
  426. switch (pADsValue->dwType) {
  427. case ADSTYPE_PROV_SPECIFIC:
  428. {
  429. ADS_PROV_SPECIFIC *pProviderSpecific;
  430. CHAR chValue[100];
  431. pProviderSpecific = &pADsValue->ProviderSpecific;
  432. strncpy(chValue, pProviderSpecific->lpValue,
  433. pProviderSpecific->dwLength);
  434. chValue[pProviderSpecific->dwLength] = 0;
  435. scanf( chValue,
  436. TEXT("%d:%d:%d"),
  437. lpdwVendorId,
  438. lpdwType,
  439. lpdwValue );
  440. break;
  441. }
  442. default :
  443. {
  444. swscanf( pADsValue->CaseIgnoreString,
  445. TEXT("%d:%d:%d"),
  446. lpdwVendorId,
  447. lpdwType,
  448. lpdwValue );
  449. break;
  450. }
  451. }
  452. return( NO_ERROR );
  453. }
  454. //**
  455. //
  456. // Call: RouterIdentityObjectAddRemoveValue
  457. //
  458. // Returns: NO_ERROR - Success
  459. // Non-zero returns - Failure
  460. //
  461. // Description: Will add or remove a value from the multi-valued attribute
  462. //
  463. DWORD
  464. RouterIdentityObjectAddRemoveValue(
  465. IN HANDLE hRouterIdentityObject,
  466. IN DWORD dwVendorId,
  467. IN DWORD dwType,
  468. IN DWORD dwValue,
  469. IN BOOL fAdd
  470. )
  471. {
  472. HRESULT hResult;
  473. DWORD dwNumAttributesModified;
  474. ADS_ATTR_INFO AttributeEntry[1];
  475. WCHAR wchValue[100];
  476. ADSVALUE AttributeValue;
  477. wsprintf( wchValue, TEXT("%d:%d:%d"), dwVendorId, dwType, dwValue );
  478. AttributeValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
  479. AttributeValue.CaseIgnoreString = wchValue;
  480. AttributeEntry[0].pszAttrName = ROUTER_OBJECT_ATTRIBUTE_NAME;
  481. AttributeEntry[0].dwControlCode = ( fAdd )
  482. ? ADS_ATTR_APPEND
  483. : ADS_ATTR_DELETE;
  484. AttributeEntry[0].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  485. AttributeEntry[0].pADsValues = &AttributeValue;
  486. AttributeEntry[0].dwNumValues = 1;
  487. if ( fAdd )
  488. {
  489. TracePrintfExA( gblDIMConfigInfo.dwTraceId,
  490. TRACE_DIM,
  491. "Adding value %ws in the Router Identity Object",
  492. wchValue );
  493. }
  494. else
  495. {
  496. TracePrintfExA( gblDIMConfigInfo.dwTraceId,
  497. TRACE_DIM,
  498. "Removing value %ws in the Router Identity Object",
  499. wchValue );
  500. }
  501. hResult = ADSISetObjectAttributes( hRouterIdentityObject,
  502. AttributeEntry,
  503. 1,
  504. &dwNumAttributesModified );
  505. if ( FAILED( hResult ) )
  506. {
  507. return( HRESULT_CODE( hResult ) );
  508. }
  509. return( NO_ERROR );
  510. }
  511. //**
  512. //
  513. // Call: RouterIdentityObjectFreeAttributes
  514. //
  515. // Returns: NO_ERROR - Success
  516. // Non-zero returns - Failure
  517. //
  518. // Description: Frees allocated set of attributes returned by
  519. // RouterIdentityObjectGetAttributes
  520. //
  521. VOID
  522. RouterIdentityObjectFreeAttributes(
  523. IN HANDLE hRouterIdentityAttributes
  524. )
  525. {
  526. if ( hRouterIdentityAttributes != NULL )
  527. {
  528. FreeADsMem( (ADS_ATTR_INFO *)hRouterIdentityAttributes );
  529. }
  530. }
  531. //**
  532. //
  533. // Call: RouterIdentityObjectSetAttributes
  534. //
  535. // Returns: NO_ERROR - Success
  536. // Non-zero returns - Failure
  537. //
  538. // Description: Will gather all current configuration information and plumb it
  539. // into the router identity object in the DS.
  540. //
  541. // Note:
  542. // This API first takes the lock on the interface table,
  543. // then it takes the lock around the device table to get the
  544. // installed device types. Hence this API MUST NOT be called
  545. // while holding a lock around the interface table since this
  546. // violates the design principal of first holding the
  547. // device lock before holding the interface lock.
  548. //
  549. DWORD
  550. RouterIdentityObjectSetAttributes(
  551. IN HANDLE hRouterIdentityObject
  552. )
  553. {
  554. DWORD dwRetCode;
  555. HANDLE hRouterIdentityAttributes;
  556. DWORD dwIndex = 0;
  557. ROUTER_IDENTITY_ATTRIBUTE RIAttributes[DIM_MAX_IDENTITY_ATTRS];
  558. DWORD dwXportIndex;
  559. //
  560. // Obtain router identity information plumbed in the DS currently
  561. //
  562. dwRetCode = RouterIdentityObjectGetAttributes(
  563. hRouterIdentityObject,
  564. &hRouterIdentityAttributes );
  565. if ( dwRetCode != NO_ERROR )
  566. {
  567. return( dwRetCode );
  568. }
  569. //
  570. // Now get the current running configuration of the router
  571. //
  572. //
  573. // First, what is our role?
  574. //
  575. if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_LAN )
  576. {
  577. RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID;
  578. RIAttributes[dwIndex].dwType = 6;
  579. RIAttributes[dwIndex].dwValue = 601;
  580. dwIndex++;
  581. }
  582. if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_RAS )
  583. {
  584. RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID;
  585. RIAttributes[dwIndex].dwType = 6;
  586. RIAttributes[dwIndex].dwValue = 602;
  587. dwIndex++;
  588. }
  589. if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_WAN )
  590. {
  591. RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID;
  592. RIAttributes[dwIndex].dwType = 6;
  593. RIAttributes[dwIndex].dwValue = 603;
  594. dwIndex++;
  595. }
  596. //
  597. // Check if a LAN interface exists
  598. //
  599. EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
  600. if ( IfObjectDoesLanInterfaceExist() )
  601. {
  602. RIAttributes[dwIndex].dwVendorId = 311;
  603. RIAttributes[dwIndex].dwType = 6;
  604. RIAttributes[dwIndex].dwValue = 712;
  605. dwIndex++;
  606. }
  607. //
  608. // Get all IP routing protocols
  609. //
  610. if ( ( dwXportIndex = GetTransportIndex( PID_IP ) ) != (DWORD)-1 )
  611. {
  612. BYTE * pGlobalInfo = NULL;
  613. DWORD dwGlobalInfoSize = 0;
  614. dwRetCode =
  615. gblRouterManagers[dwXportIndex].DdmRouterIf.GetGlobalInfo(
  616. pGlobalInfo,
  617. &dwGlobalInfoSize );
  618. if ( dwRetCode == ERROR_INSUFFICIENT_BUFFER )
  619. {
  620. if ( dwGlobalInfoSize > 0 )
  621. {
  622. pGlobalInfo = LOCAL_ALLOC( LPTR, dwGlobalInfoSize );
  623. if ( pGlobalInfo != NULL )
  624. {
  625. dwRetCode =
  626. gblRouterManagers[dwXportIndex].DdmRouterIf.GetGlobalInfo(
  627. pGlobalInfo,
  628. &dwGlobalInfoSize );
  629. if ( dwRetCode == NO_ERROR )
  630. {
  631. DWORD dwRoutingProtIndex;
  632. RTR_INFO_BLOCK_HEADER * pInfoBlock =
  633. (RTR_INFO_BLOCK_HEADER *)(pGlobalInfo);
  634. for ( dwRoutingProtIndex = 0;
  635. dwRoutingProtIndex < pInfoBlock->TocEntriesCount;
  636. dwRoutingProtIndex++ )
  637. {
  638. DWORD dwVendorId;
  639. RIAttributes[dwIndex].dwType
  640. = TYPE_FROM_PROTO_ID(
  641. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  642. //
  643. // Add unicast and multicast protocol ids
  644. //
  645. if ( ( RIAttributes[dwIndex].dwType
  646. == PROTO_TYPE_UCAST ) ||
  647. ( RIAttributes[dwIndex].dwType
  648. == PROTO_TYPE_MCAST ) )
  649. {
  650. DWORD dwProtoId;
  651. dwVendorId = VENDOR_FROM_PROTO_ID(
  652. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  653. dwProtoId = PROTO_FROM_PROTO_ID(
  654. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  655. //
  656. // Nothing defined for dhcp relay agent
  657. //
  658. if ( dwProtoId == PROTO_IP_BOOTP )
  659. {
  660. continue;
  661. }
  662. if ( ( dwVendorId == PROTO_VENDOR_MS0 ) ||
  663. ( dwVendorId == PROTO_VENDOR_MS1 ) ||
  664. ( dwVendorId == PROTO_VENDOR_MS2 ) )
  665. {
  666. RIAttributes[dwIndex].dwVendorId = 311;
  667. }
  668. else
  669. {
  670. RIAttributes[dwIndex].dwVendorId = dwVendorId;
  671. }
  672. RIAttributes[dwIndex].dwValue
  673. = PROTO_FROM_PROTO_ID(
  674. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  675. dwIndex++;
  676. }
  677. //
  678. // Add ms0 protocols
  679. //
  680. else if (RIAttributes[dwIndex].dwType ==
  681. PROTO_TYPE_MS0 )
  682. {
  683. DWORD dwProtoId;
  684. dwVendorId = VENDOR_FROM_PROTO_ID(
  685. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  686. dwProtoId = PROTO_FROM_PROTO_ID(
  687. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  688. //
  689. // Check for NAT
  690. // Vendor= MS, TypeMajor= 6, TypeMinor= 604
  691. //
  692. if ( ( dwVendorId == PROTO_VENDOR_MS1 ) &&
  693. ( dwProtoId == PROTO_IP_NAT)
  694. )
  695. {
  696. RIAttributes[dwIndex].dwVendorId =
  697. PROTO_VENDOR_MS1;
  698. RIAttributes[dwIndex].dwType =
  699. 6;
  700. RIAttributes[dwIndex].dwValue =
  701. 604;
  702. dwIndex++;
  703. }
  704. }
  705. }
  706. }
  707. LOCAL_FREE( pGlobalInfo );
  708. }
  709. }
  710. }
  711. // As per amritanr, if you have the ip router installed,
  712. // then ip forwarding is always turned on.
  713. //
  714. // Ip Fwd'ing Enabled: Vendor= MS, TypeMajor= 6, TypeMinor= 501
  715. //
  716. RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
  717. RIAttributes[dwIndex].dwType = 6;
  718. RIAttributes[dwIndex].dwValue = 501;
  719. dwIndex++;
  720. }
  721. //
  722. // Get all IPX routing protocols
  723. //
  724. if ( ( dwXportIndex = GetTransportIndex( PID_IPX ) ) != (DWORD)-1 )
  725. {
  726. // All nt5 ipx routers support rip and sap. Go ahead
  727. // and attributes for both.
  728. //
  729. // IPXRIP: Vendor= MS, TypeMajor= 5, TypeMinor= 1
  730. //
  731. RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
  732. RIAttributes[dwIndex].dwType = 5;
  733. RIAttributes[dwIndex].dwValue = 1;
  734. dwIndex++;
  735. // IPXSAP: Vendor= MS, TypeMajor= 5, TypeMinor= 2
  736. //
  737. RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
  738. RIAttributes[dwIndex].dwType = 5;
  739. RIAttributes[dwIndex].dwValue = 2;
  740. dwIndex++;
  741. // Ipx Fwd'ing Enabled: Vendor= MS, TypeMajor= 6, TypeMinor= 502
  742. //
  743. RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
  744. RIAttributes[dwIndex].dwType = 6;
  745. RIAttributes[dwIndex].dwValue = 502;
  746. dwIndex++;
  747. }
  748. LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
  749. RIAttributes[dwIndex].dwVendorId = (DWORD)-1;
  750. RIAttributes[dwIndex].dwType = (DWORD)-1;
  751. RIAttributes[dwIndex].dwValue = (DWORD)-1;
  752. //
  753. // Get all the RAS server information
  754. //
  755. if ( gblDIMConfigInfo.dwRouterRole & ( ROUTER_ROLE_RAS | ROUTER_ROLE_WAN ) )
  756. {
  757. DWORD (*DDMGetIdentityAttributes)( ROUTER_IDENTITY_ATTRIBUTE * ) =
  758. (DWORD(*)( ROUTER_IDENTITY_ATTRIBUTE * ))
  759. GetDDMEntryPoint("DDMGetIdentityAttributes");
  760. if(NULL != DDMGetIdentityAttributes)
  761. {
  762. dwRetCode = DDMGetIdentityAttributes( RIAttributes );
  763. }
  764. else
  765. {
  766. ASSERT(FALSE);
  767. }
  768. }
  769. //
  770. // Now obtain walk thru the current configration an make sure that
  771. // all of it is plumbed. If it is not then go ahead and set it.
  772. //
  773. for ( dwIndex = 0;
  774. RIAttributes[dwIndex].dwVendorId != (DWORD)-1;
  775. dwIndex++ )
  776. {
  777. //
  778. // If this attribute is not set, then set it
  779. //
  780. if ( !RouterIdentityObjectIsValueSet(
  781. hRouterIdentityAttributes,
  782. RIAttributes[dwIndex].dwVendorId,
  783. RIAttributes[dwIndex].dwType,
  784. RIAttributes[dwIndex].dwValue ) )
  785. {
  786. RouterIdentityObjectAddRemoveValue(
  787. hRouterIdentityObject,
  788. RIAttributes[dwIndex].dwVendorId,
  789. RIAttributes[dwIndex].dwType,
  790. RIAttributes[dwIndex].dwValue,
  791. TRUE );
  792. }
  793. }
  794. //
  795. // Now walk thru and remove attributes in the DS that are not in our
  796. // current configuration. We reconcile all attributes with
  797. // dwType values 0,1 or 5, and with dwVendorId of 311 (Microsoft) with
  798. // dwType value of 6.
  799. //
  800. for ( dwIndex = 0;; dwIndex++ )
  801. {
  802. DWORD dwVendorId;
  803. DWORD dwType;
  804. DWORD dwValue;
  805. DWORD dwCurrentValueIndex;
  806. BOOL fInCurrentConfiguration = FALSE;
  807. dwRetCode = RouterIdentityObjectGetValue( hRouterIdentityAttributes,
  808. dwIndex,
  809. &dwVendorId,
  810. &dwType,
  811. &dwValue );
  812. if ( dwRetCode != NO_ERROR )
  813. {
  814. break;
  815. }
  816. //
  817. // We are done
  818. //
  819. if ( dwVendorId == (DWORD)-1 )
  820. {
  821. break;
  822. }
  823. //
  824. // Ignore these types
  825. //
  826. if ( ( dwType != 0 ) && ( dwType != 1 ) && ( dwType != 5 ) &&
  827. ( !( ( dwType == 6 ) && ( dwVendorId == DIM_MS_VENDOR_ID ) ) ) )
  828. {
  829. continue;
  830. }
  831. //
  832. // Now check to see it this attribute is a member of our current
  833. // configuration
  834. //
  835. for ( dwCurrentValueIndex = 0;
  836. RIAttributes[dwCurrentValueIndex].dwVendorId != (DWORD)-1;
  837. dwCurrentValueIndex++ )
  838. {
  839. if ( (RIAttributes[dwCurrentValueIndex].dwVendorId == dwVendorId)&&
  840. (RIAttributes[dwCurrentValueIndex].dwType == dwType ) &&
  841. (RIAttributes[dwCurrentValueIndex].dwValue == dwValue ) )
  842. {
  843. //
  844. // Attribute is part of current configuration
  845. //
  846. fInCurrentConfiguration = TRUE;
  847. }
  848. }
  849. if ( !fInCurrentConfiguration )
  850. {
  851. //
  852. // Remove this attribute from the DS since it is not in our
  853. // current configuration
  854. //
  855. dwRetCode = RouterIdentityObjectAddRemoveValue(
  856. hRouterIdentityObject,
  857. dwVendorId,
  858. dwType,
  859. dwValue,
  860. FALSE );
  861. if ( dwRetCode != NO_ERROR )
  862. {
  863. break;
  864. }
  865. }
  866. }
  867. RouterIdentityObjectFreeAttributes( hRouterIdentityAttributes );
  868. return( dwRetCode );
  869. }
  870. //**
  871. //
  872. // Call: RouterIdentityObjectUpdateAttributes
  873. //
  874. // Returns: NO_ERROR - Success
  875. // Non-zero returns - Failure
  876. //
  877. // Description: Will be called to update the attributes currently set in the DS
  878. // or to set it if it was not able to be set originally
  879. //
  880. VOID
  881. RouterIdentityObjectUpdateAttributes(
  882. IN PVOID pParameter,
  883. IN BOOLEAN fTimedOut
  884. )
  885. {
  886. DWORD dwRetCode = NO_ERROR;
  887. BOOL fCalledFromTimer = (BOOL)PtrToUlong(pParameter);
  888. //
  889. // Make sure service is in the running state
  890. //
  891. if ( gblDIMConfigInfo.ServiceStatus.dwCurrentState != SERVICE_RUNNING )
  892. {
  893. return;
  894. }
  895. if ( fCalledFromTimer )
  896. {
  897. //
  898. // Always call DeleteTimer otherwise we will leak memory
  899. //
  900. RtlDeleteTimer( gblDIMConfigInfo.hTimerQ,
  901. gblDIMConfigInfo.hTimer,
  902. NULL );
  903. //
  904. // Called from timer thread so we first try to obtain a handle to
  905. // the router idenitity object
  906. //
  907. dwRetCode = RouterIdentityObjectOpen(
  908. NULL,
  909. ( gblDIMConfigInfo.dwRouterRole ),
  910. &(gblDIMConfigInfo.hObjectRouterIdentity) );
  911. if ( ( dwRetCode != NO_ERROR ) ||
  912. ( gblDIMConfigInfo.hObjectRouterIdentity == NULL ) )
  913. {
  914. //
  915. // Couldn't access DC, try again later for a max of once a day
  916. //
  917. if ( gblDIMConfigInfo.dwRouterIdentityDueTime < 24*60*60*1000 )
  918. {
  919. gblDIMConfigInfo.dwRouterIdentityDueTime *= 2;
  920. }
  921. TracePrintfExA(
  922. gblDIMConfigInfo.dwTraceId,
  923. TRACE_DIM,
  924. "Could not access DC, will set router attributes later");
  925. RtlCreateTimer( gblDIMConfigInfo.hTimerQ,
  926. &(gblDIMConfigInfo.hTimer),
  927. RouterIdentityObjectUpdateAttributes,
  928. (PVOID)TRUE,
  929. gblDIMConfigInfo.dwRouterIdentityDueTime,
  930. 0,
  931. WT_EXECUTEDEFAULT );
  932. return;
  933. }
  934. //
  935. // Otherwise we succeeded in opening the router identity object
  936. // and we set the identity information below.
  937. //
  938. }
  939. else
  940. {
  941. //
  942. // If we do not have a handle for the router identity object, then
  943. // either we are in the process of obtaining it or we are not
  944. // a member of the DS, so in both cases simply return
  945. //
  946. if ( gblDIMConfigInfo.hObjectRouterIdentity == NULL )
  947. {
  948. return;
  949. }
  950. }
  951. //
  952. // Can be called from different threads at the same time so we need
  953. // Critical section around this code so that we do not have 2 writers to
  954. // the DS at the same time that trample on each other. ex could be called
  955. // by DDM thread as well as the timer thread.
  956. //
  957. EnterCriticalSection( &(gblDIMConfigInfo.CSRouterIdentity) );
  958. TracePrintfExA( gblDIMConfigInfo.dwTraceId,
  959. TRACE_DIM,
  960. "Setting router attributes in the identity object" );
  961. RouterIdentityObjectSetAttributes( gblDIMConfigInfo.hObjectRouterIdentity );
  962. LeaveCriticalSection( &(gblDIMConfigInfo.CSRouterIdentity) );
  963. }
  964. //**
  965. //
  966. // Call: RouterIdentityObjectUpdateAttributesForDD
  967. //
  968. // Returns: None
  969. //
  970. // Description:
  971. //
  972. VOID
  973. RouterIdentityObjectUpdateAttributesForDDM(
  974. PVOID pParameter
  975. )
  976. {
  977. RouterIdentityObjectUpdateAttributes( (PVOID)NULL, FALSE );
  978. }
  979. //**
  980. //
  981. // Call: RouterIdentityObjectUpdateDDMAttributes
  982. //
  983. // Returns: None
  984. //
  985. // Description: Export this call to DDM. When DDM calls this call, it already
  986. // has taken a lock around it's device table and cannot make
  987. // the call to update attributes directly because the
  988. // RouterIdentityObjectUpdateAttributes call takes the
  989. // lock around the RouterIdentity object leading to a deadlock.
  990. // Hence we execute this call asynchronously using a worker
  991. // thread.
  992. //
  993. //
  994. VOID
  995. RouterIdentityObjectUpdateDDMAttributes(
  996. VOID
  997. )
  998. {
  999. RtlQueueWorkItem( RouterIdentityObjectUpdateAttributesForDDM,
  1000. NULL,
  1001. WT_EXECUTEDEFAULT );
  1002. }