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

  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 = ERROR_NOT_ENOUGH_MEMORY;
  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 = ERROR_NOT_ENOUGH_MEMORY;
  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. if (scanf( chValue,
  436. TEXT("%d:%d:%d"),
  437. lpdwVendorId,
  438. lpdwType,
  439. lpdwValue ) == EOF)
  440. {
  441. return ERROR_DS_INVALID_ATTRIBUTE_SYNTAX;
  442. }
  443. break;
  444. }
  445. default :
  446. {
  447. if (swscanf( pADsValue->CaseIgnoreString,
  448. TEXT("%d:%d:%d"),
  449. lpdwVendorId,
  450. lpdwType,
  451. lpdwValue ) == EOF)
  452. {
  453. return ERROR_DS_INVALID_ATTRIBUTE_SYNTAX;
  454. }
  455. break;
  456. }
  457. }
  458. return( NO_ERROR );
  459. }
  460. //**
  461. //
  462. // Call: RouterIdentityObjectAddRemoveValue
  463. //
  464. // Returns: NO_ERROR - Success
  465. // Non-zero returns - Failure
  466. //
  467. // Description: Will add or remove a value from the multi-valued attribute
  468. //
  469. DWORD
  470. RouterIdentityObjectAddRemoveValue(
  471. IN HANDLE hRouterIdentityObject,
  472. IN DWORD dwVendorId,
  473. IN DWORD dwType,
  474. IN DWORD dwValue,
  475. IN BOOL fAdd
  476. )
  477. {
  478. HRESULT hResult;
  479. DWORD dwNumAttributesModified;
  480. ADS_ATTR_INFO AttributeEntry[1];
  481. WCHAR wchValue[100];
  482. ADSVALUE AttributeValue;
  483. wsprintf( wchValue, TEXT("%d:%d:%d"), dwVendorId, dwType, dwValue );
  484. AttributeValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
  485. AttributeValue.CaseIgnoreString = wchValue;
  486. AttributeEntry[0].pszAttrName = ROUTER_OBJECT_ATTRIBUTE_NAME;
  487. AttributeEntry[0].dwControlCode = ( fAdd )
  488. ? ADS_ATTR_APPEND
  489. : ADS_ATTR_DELETE;
  490. AttributeEntry[0].dwADsType = ADSTYPE_CASE_IGNORE_STRING;
  491. AttributeEntry[0].pADsValues = &AttributeValue;
  492. AttributeEntry[0].dwNumValues = 1;
  493. if ( fAdd )
  494. {
  495. TracePrintfExA( gblDIMConfigInfo.dwTraceId,
  496. TRACE_DIM,
  497. "Adding value %ws in the Router Identity Object",
  498. wchValue );
  499. }
  500. else
  501. {
  502. TracePrintfExA( gblDIMConfigInfo.dwTraceId,
  503. TRACE_DIM,
  504. "Removing value %ws in the Router Identity Object",
  505. wchValue );
  506. }
  507. hResult = ADSISetObjectAttributes( hRouterIdentityObject,
  508. AttributeEntry,
  509. 1,
  510. &dwNumAttributesModified );
  511. if ( FAILED( hResult ) )
  512. {
  513. return( HRESULT_CODE( hResult ) );
  514. }
  515. return( NO_ERROR );
  516. }
  517. //**
  518. //
  519. // Call: RouterIdentityObjectFreeAttributes
  520. //
  521. // Returns: NO_ERROR - Success
  522. // Non-zero returns - Failure
  523. //
  524. // Description: Frees allocated set of attributes returned by
  525. // RouterIdentityObjectGetAttributes
  526. //
  527. VOID
  528. RouterIdentityObjectFreeAttributes(
  529. IN HANDLE hRouterIdentityAttributes
  530. )
  531. {
  532. if ( hRouterIdentityAttributes != NULL )
  533. {
  534. FreeADsMem( (ADS_ATTR_INFO *)hRouterIdentityAttributes );
  535. }
  536. }
  537. //**
  538. //
  539. // Call: RouterIdentityObjectSetAttributes
  540. //
  541. // Returns: NO_ERROR - Success
  542. // Non-zero returns - Failure
  543. //
  544. // Description: Will gather all current configuration information and plumb it
  545. // into the router identity object in the DS.
  546. //
  547. // Note:
  548. // This API first takes the lock on the interface table,
  549. // then it takes the lock around the device table to get the
  550. // installed device types. Hence this API MUST NOT be called
  551. // while holding a lock around the interface table since this
  552. // violates the design principal of first holding the
  553. // device lock before holding the interface lock.
  554. //
  555. DWORD
  556. RouterIdentityObjectSetAttributes(
  557. IN HANDLE hRouterIdentityObject
  558. )
  559. {
  560. DWORD dwRetCode;
  561. HANDLE hRouterIdentityAttributes;
  562. DWORD dwIndex = 0;
  563. ROUTER_IDENTITY_ATTRIBUTE RIAttributes[DIM_MAX_IDENTITY_ATTRS];
  564. DWORD dwXportIndex;
  565. //
  566. // Obtain router identity information plumbed in the DS currently
  567. //
  568. dwRetCode = RouterIdentityObjectGetAttributes(
  569. hRouterIdentityObject,
  570. &hRouterIdentityAttributes );
  571. if ( dwRetCode != NO_ERROR )
  572. {
  573. return( dwRetCode );
  574. }
  575. //
  576. // Now get the current running configuration of the router
  577. //
  578. //
  579. // First, what is our role?
  580. //
  581. if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_LAN )
  582. {
  583. RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID;
  584. RIAttributes[dwIndex].dwType = 6;
  585. RIAttributes[dwIndex].dwValue = 601;
  586. dwIndex++;
  587. }
  588. if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_RAS )
  589. {
  590. RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID;
  591. RIAttributes[dwIndex].dwType = 6;
  592. RIAttributes[dwIndex].dwValue = 602;
  593. dwIndex++;
  594. }
  595. if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_WAN )
  596. {
  597. RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID;
  598. RIAttributes[dwIndex].dwType = 6;
  599. RIAttributes[dwIndex].dwValue = 603;
  600. dwIndex++;
  601. }
  602. //
  603. // Check if a LAN interface exists
  604. //
  605. EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
  606. if ( IfObjectDoesLanInterfaceExist() )
  607. {
  608. RIAttributes[dwIndex].dwVendorId = 311;
  609. RIAttributes[dwIndex].dwType = 6;
  610. RIAttributes[dwIndex].dwValue = 712;
  611. dwIndex++;
  612. }
  613. //
  614. // Get all IP routing protocols
  615. //
  616. if ( ( dwXportIndex = GetTransportIndex( PID_IP ) ) != (DWORD)-1 )
  617. {
  618. BYTE * pGlobalInfo = NULL;
  619. DWORD dwGlobalInfoSize = 0;
  620. dwRetCode =
  621. gblRouterManagers[dwXportIndex].DdmRouterIf.GetGlobalInfo(
  622. pGlobalInfo,
  623. &dwGlobalInfoSize );
  624. if ( dwRetCode == ERROR_INSUFFICIENT_BUFFER )
  625. {
  626. if ( dwGlobalInfoSize > 0 )
  627. {
  628. pGlobalInfo = LOCAL_ALLOC( LPTR, dwGlobalInfoSize );
  629. if ( pGlobalInfo != NULL )
  630. {
  631. dwRetCode =
  632. gblRouterManagers[dwXportIndex].DdmRouterIf.GetGlobalInfo(
  633. pGlobalInfo,
  634. &dwGlobalInfoSize );
  635. if ( dwRetCode == NO_ERROR )
  636. {
  637. DWORD dwRoutingProtIndex;
  638. RTR_INFO_BLOCK_HEADER * pInfoBlock =
  639. (RTR_INFO_BLOCK_HEADER *)(pGlobalInfo);
  640. for ( dwRoutingProtIndex = 0;
  641. dwRoutingProtIndex < pInfoBlock->TocEntriesCount;
  642. dwRoutingProtIndex++ )
  643. {
  644. DWORD dwVendorId;
  645. RIAttributes[dwIndex].dwType
  646. = TYPE_FROM_PROTO_ID(
  647. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  648. //
  649. // Add unicast and multicast protocol ids
  650. //
  651. if ( ( RIAttributes[dwIndex].dwType
  652. == PROTO_TYPE_UCAST ) ||
  653. ( RIAttributes[dwIndex].dwType
  654. == PROTO_TYPE_MCAST ) )
  655. {
  656. DWORD dwProtoId;
  657. dwVendorId = VENDOR_FROM_PROTO_ID(
  658. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  659. dwProtoId = PROTO_FROM_PROTO_ID(
  660. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  661. //
  662. // Nothing defined for dhcp relay agent
  663. //
  664. if ( dwProtoId == PROTO_IP_BOOTP )
  665. {
  666. continue;
  667. }
  668. if ( ( dwVendorId == PROTO_VENDOR_MS0 ) ||
  669. ( dwVendorId == PROTO_VENDOR_MS1 ) ||
  670. ( dwVendorId == PROTO_VENDOR_MS2 ) )
  671. {
  672. RIAttributes[dwIndex].dwVendorId = 311;
  673. }
  674. else
  675. {
  676. RIAttributes[dwIndex].dwVendorId = dwVendorId;
  677. }
  678. RIAttributes[dwIndex].dwValue
  679. = PROTO_FROM_PROTO_ID(
  680. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  681. dwIndex++;
  682. }
  683. //
  684. // Add ms0 protocols
  685. //
  686. else if (RIAttributes[dwIndex].dwType ==
  687. PROTO_TYPE_MS0 )
  688. {
  689. DWORD dwProtoId;
  690. dwVendorId = VENDOR_FROM_PROTO_ID(
  691. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  692. dwProtoId = PROTO_FROM_PROTO_ID(
  693. pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
  694. //
  695. // Check for NAT
  696. // Vendor= MS, TypeMajor= 6, TypeMinor= 604
  697. //
  698. if ( ( dwVendorId == PROTO_VENDOR_MS1 ) &&
  699. ( dwProtoId == PROTO_IP_NAT)
  700. )
  701. {
  702. RIAttributes[dwIndex].dwVendorId =
  703. PROTO_VENDOR_MS1;
  704. RIAttributes[dwIndex].dwType =
  705. 6;
  706. RIAttributes[dwIndex].dwValue =
  707. 604;
  708. dwIndex++;
  709. }
  710. }
  711. }
  712. }
  713. LOCAL_FREE( pGlobalInfo );
  714. }
  715. }
  716. }
  717. // As per amritanr, if you have the ip router installed,
  718. // then ip forwarding is always turned on.
  719. //
  720. // Ip Fwd'ing Enabled: Vendor= MS, TypeMajor= 6, TypeMinor= 501
  721. //
  722. RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
  723. RIAttributes[dwIndex].dwType = 6;
  724. RIAttributes[dwIndex].dwValue = 501;
  725. dwIndex++;
  726. }
  727. //
  728. // Get all IPX routing protocols
  729. //
  730. if ( ( dwXportIndex = GetTransportIndex( PID_IPX ) ) != (DWORD)-1 )
  731. {
  732. // All nt5 ipx routers support rip and sap. Go ahead
  733. // and attributes for both.
  734. //
  735. // IPXRIP: Vendor= MS, TypeMajor= 5, TypeMinor= 1
  736. //
  737. RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
  738. RIAttributes[dwIndex].dwType = 5;
  739. RIAttributes[dwIndex].dwValue = 1;
  740. dwIndex++;
  741. // IPXSAP: Vendor= MS, TypeMajor= 5, TypeMinor= 2
  742. //
  743. RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
  744. RIAttributes[dwIndex].dwType = 5;
  745. RIAttributes[dwIndex].dwValue = 2;
  746. dwIndex++;
  747. // Ipx Fwd'ing Enabled: Vendor= MS, TypeMajor= 6, TypeMinor= 502
  748. //
  749. RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1;
  750. RIAttributes[dwIndex].dwType = 6;
  751. RIAttributes[dwIndex].dwValue = 502;
  752. dwIndex++;
  753. }
  754. LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
  755. RIAttributes[dwIndex].dwVendorId = (DWORD)-1;
  756. RIAttributes[dwIndex].dwType = (DWORD)-1;
  757. RIAttributes[dwIndex].dwValue = (DWORD)-1;
  758. //
  759. // Get all the RAS server information
  760. //
  761. if ( gblDIMConfigInfo.dwRouterRole & ( ROUTER_ROLE_RAS | ROUTER_ROLE_WAN ) )
  762. {
  763. DWORD (*DDMGetIdentityAttributes)( ROUTER_IDENTITY_ATTRIBUTE * ) =
  764. (DWORD(*)( ROUTER_IDENTITY_ATTRIBUTE * ))
  765. GetDDMEntryPoint("DDMGetIdentityAttributes");
  766. if(NULL != DDMGetIdentityAttributes)
  767. {
  768. dwRetCode = DDMGetIdentityAttributes( RIAttributes );
  769. }
  770. else
  771. {
  772. ASSERT(FALSE);
  773. }
  774. }
  775. //
  776. // Now obtain walk thru the current configration an make sure that
  777. // all of it is plumbed. If it is not then go ahead and set it.
  778. //
  779. for ( dwIndex = 0;
  780. RIAttributes[dwIndex].dwVendorId != (DWORD)-1;
  781. dwIndex++ )
  782. {
  783. //
  784. // If this attribute is not set, then set it
  785. //
  786. if ( !RouterIdentityObjectIsValueSet(
  787. hRouterIdentityAttributes,
  788. RIAttributes[dwIndex].dwVendorId,
  789. RIAttributes[dwIndex].dwType,
  790. RIAttributes[dwIndex].dwValue ) )
  791. {
  792. RouterIdentityObjectAddRemoveValue(
  793. hRouterIdentityObject,
  794. RIAttributes[dwIndex].dwVendorId,
  795. RIAttributes[dwIndex].dwType,
  796. RIAttributes[dwIndex].dwValue,
  797. TRUE );
  798. }
  799. }
  800. //
  801. // Now walk thru and remove attributes in the DS that are not in our
  802. // current configuration. We reconcile all attributes with
  803. // dwType values 0,1 or 5, and with dwVendorId of 311 (Microsoft) with
  804. // dwType value of 6.
  805. //
  806. for ( dwIndex = 0;; dwIndex++ )
  807. {
  808. DWORD dwVendorId;
  809. DWORD dwType;
  810. DWORD dwValue;
  811. DWORD dwCurrentValueIndex;
  812. BOOL fInCurrentConfiguration = FALSE;
  813. dwRetCode = RouterIdentityObjectGetValue( hRouterIdentityAttributes,
  814. dwIndex,
  815. &dwVendorId,
  816. &dwType,
  817. &dwValue );
  818. if ( dwRetCode != NO_ERROR )
  819. {
  820. break;
  821. }
  822. //
  823. // We are done
  824. //
  825. if ( dwVendorId == (DWORD)-1 )
  826. {
  827. break;
  828. }
  829. //
  830. // Ignore these types
  831. //
  832. if ( ( dwType != 0 ) && ( dwType != 1 ) && ( dwType != 5 ) &&
  833. ( !( ( dwType == 6 ) && ( dwVendorId == DIM_MS_VENDOR_ID ) ) ) )
  834. {
  835. continue;
  836. }
  837. //
  838. // Now check to see it this attribute is a member of our current
  839. // configuration
  840. //
  841. for ( dwCurrentValueIndex = 0;
  842. RIAttributes[dwCurrentValueIndex].dwVendorId != (DWORD)-1;
  843. dwCurrentValueIndex++ )
  844. {
  845. if ( (RIAttributes[dwCurrentValueIndex].dwVendorId == dwVendorId)&&
  846. (RIAttributes[dwCurrentValueIndex].dwType == dwType ) &&
  847. (RIAttributes[dwCurrentValueIndex].dwValue == dwValue ) )
  848. {
  849. //
  850. // Attribute is part of current configuration
  851. //
  852. fInCurrentConfiguration = TRUE;
  853. }
  854. }
  855. if ( !fInCurrentConfiguration )
  856. {
  857. //
  858. // Remove this attribute from the DS since it is not in our
  859. // current configuration
  860. //
  861. dwRetCode = RouterIdentityObjectAddRemoveValue(
  862. hRouterIdentityObject,
  863. dwVendorId,
  864. dwType,
  865. dwValue,
  866. FALSE );
  867. if ( dwRetCode != NO_ERROR )
  868. {
  869. break;
  870. }
  871. }
  872. }
  873. RouterIdentityObjectFreeAttributes( hRouterIdentityAttributes );
  874. return( dwRetCode );
  875. }
  876. //**
  877. //
  878. // Call: RouterIdentityObjectUpdateAttributes
  879. //
  880. // Returns: NO_ERROR - Success
  881. // Non-zero returns - Failure
  882. //
  883. // Description: Will be called to update the attributes currently set in the DS
  884. // or to set it if it was not able to be set originally
  885. //
  886. VOID
  887. RouterIdentityObjectUpdateAttributes(
  888. IN PVOID pParameter,
  889. IN BOOLEAN fTimedOut
  890. )
  891. {
  892. DWORD dwRetCode = NO_ERROR;
  893. BOOL fCalledFromTimer = (BOOL)PtrToUlong(pParameter);
  894. //
  895. // Make sure service is in the running state
  896. //
  897. if ( gblDIMConfigInfo.ServiceStatus.dwCurrentState != SERVICE_RUNNING )
  898. {
  899. if(fCalledFromTimer)
  900. {
  901. //
  902. // Delete the timer if theres one queued before we
  903. // return from here otherwise DeleteTimerQ in
  904. // DimCleanup will hang.
  905. //
  906. RtlDeleteTimer(gblDIMConfigInfo.hTimerQ,
  907. gblDIMConfigInfo.hTimer,
  908. NULL);
  909. gblDIMConfigInfo.hTimer = NULL;
  910. }
  911. return;
  912. }
  913. if ( fCalledFromTimer )
  914. {
  915. //
  916. // Always call DeleteTimer otherwise we will leak memory
  917. //
  918. RtlDeleteTimer( gblDIMConfigInfo.hTimerQ,
  919. gblDIMConfigInfo.hTimer,
  920. NULL );
  921. gblDIMConfigInfo.hTimer = NULL;
  922. //
  923. // Called from timer thread so we first try to obtain a handle to
  924. // the router idenitity object
  925. //
  926. dwRetCode = RouterIdentityObjectOpen(
  927. NULL,
  928. ( gblDIMConfigInfo.dwRouterRole ),
  929. &(gblDIMConfigInfo.hObjectRouterIdentity) );
  930. if ( ( dwRetCode != NO_ERROR ) ||
  931. ( gblDIMConfigInfo.hObjectRouterIdentity == NULL ) )
  932. {
  933. //
  934. // Check to see if service is stopping and create a timer for this
  935. // only if it is in running state.
  936. //
  937. if(gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_RUNNING)
  938. {
  939. //
  940. // Couldn't access DC, try again later for a max of once a day
  941. //
  942. if ( gblDIMConfigInfo.dwRouterIdentityDueTime < 24*60*60*1000 )
  943. {
  944. gblDIMConfigInfo.dwRouterIdentityDueTime *= 2;
  945. }
  946. TracePrintfExA(
  947. gblDIMConfigInfo.dwTraceId,
  948. TRACE_DIM,
  949. "Could not access DC, will set router attributes later");
  950. RtlCreateTimer( gblDIMConfigInfo.hTimerQ,
  951. &(gblDIMConfigInfo.hTimer),
  952. RouterIdentityObjectUpdateAttributes,
  953. (PVOID)TRUE,
  954. gblDIMConfigInfo.dwRouterIdentityDueTime,
  955. 0,
  956. WT_EXECUTEDEFAULT );
  957. }
  958. return;
  959. }
  960. //
  961. // Otherwise we succeeded in opening the router identity object
  962. // and we set the identity information below.
  963. //
  964. }
  965. else
  966. {
  967. //
  968. // If we do not have a handle for the router identity object, then
  969. // either we are in the process of obtaining it or we are not
  970. // a member of the DS, so in both cases simply return
  971. //
  972. if ( gblDIMConfigInfo.hObjectRouterIdentity == NULL )
  973. {
  974. return;
  975. }
  976. }
  977. //
  978. // Can be called from different threads at the same time so we need
  979. // Critical section around this code so that we do not have 2 writers to
  980. // the DS at the same time that trample on each other. ex could be called
  981. // by DDM thread as well as the timer thread.
  982. //
  983. EnterCriticalSection( &(gblDIMConfigInfo.CSRouterIdentity) );
  984. TracePrintfExA( gblDIMConfigInfo.dwTraceId,
  985. TRACE_DIM,
  986. "Setting router attributes in the identity object" );
  987. RouterIdentityObjectSetAttributes( gblDIMConfigInfo.hObjectRouterIdentity );
  988. LeaveCriticalSection( &(gblDIMConfigInfo.CSRouterIdentity) );
  989. }
  990. //**
  991. //
  992. // Call: RouterIdentityObjectUpdateAttributesForDD
  993. //
  994. // Returns: None
  995. //
  996. // Description:
  997. //
  998. VOID
  999. RouterIdentityObjectUpdateAttributesForDDM(
  1000. PVOID pParameter
  1001. )
  1002. {
  1003. RouterIdentityObjectUpdateAttributes( (PVOID)NULL, FALSE );
  1004. }
  1005. //**
  1006. //
  1007. // Call: RouterIdentityObjectUpdateDDMAttributes
  1008. //
  1009. // Returns: None
  1010. //
  1011. // Description: Export this call to DDM. When DDM calls this call, it already
  1012. // has taken a lock around it's device table and cannot make
  1013. // the call to update attributes directly because the
  1014. // RouterIdentityObjectUpdateAttributes call takes the
  1015. // lock around the RouterIdentity object leading to a deadlock.
  1016. // Hence we execute this call asynchronously using a worker
  1017. // thread.
  1018. //
  1019. //
  1020. VOID
  1021. RouterIdentityObjectUpdateDDMAttributes(
  1022. VOID
  1023. )
  1024. {
  1025. RtlQueueWorkItem( RouterIdentityObjectUpdateAttributesForDDM,
  1026. NULL,
  1027. WT_EXECUTEDEFAULT );
  1028. }