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.

1143 lines
44 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright(C) 1999-2000 Microsoft Corporation all rights reserved.
  4. //
  5. // Module: migratemdb.cpp
  6. //
  7. // Project: Windows 2000 IAS
  8. //
  9. // Description: IAS NT 4 MDB to IAS W2K MDB Migration Logic
  10. //
  11. // Author: TLP 1/13/1999
  12. //
  13. //
  14. // Revision 02/24/2000 Moved to a separate dll
  15. // 03/15/2000 Almost completely rewritten
  16. //
  17. /////////////////////////////////////////////////////////////////////////////
  18. #include "stdafx.h"
  19. #include "Attributes.h"
  20. #include "Clients.h"
  21. #include "DefaultProvider.h"
  22. #include "GlobalData.h"
  23. #include "migratemdb.h"
  24. #include "migrateregistry.h"
  25. #include "Objects.h"
  26. #include "Policy.h"
  27. #include "Properties.h"
  28. #include "Profiles.h"
  29. #include "profileattributelist.h"
  30. #include "Providers.h"
  31. #include "proxyservergroupcollection.h"
  32. #include "RadiusAttributeValues.h"
  33. #include "Realms.h"
  34. #include "RemoteRadiusServers.h"
  35. #include "ServiceConfiguration.h"
  36. #include "Version.h"
  37. #include "updatemschap.h"
  38. // To remember:
  39. // IAS_MAX_VSA_LENGTH = (253 * 2);
  40. // 1.0 Format Offsets
  41. //VSA_OFFSET = 0;
  42. //VSA_OFFSET_ID = 0;
  43. //VSA_OFFSET_TYPE = 8;
  44. //VSA_OFFSET_LENGTH = 10;
  45. //VSA_OFFSET_VALUE_RFC = 12;
  46. //VSA_OFFSET_VALUE_NONRFC = 8;
  47. // 2.0 Format Offsets
  48. //VSA_OFFSET_NEW = 2;
  49. //VSA_OFFSET_ID_NEW = 2;
  50. //VSA_OFFSET_TYPE_NEW = 10;
  51. //VSA_OFFSET_LENGTH_NEW = 12;
  52. //VSA_OFFSET_VALUE_NONRFC_NEW = 10;
  53. //////////////////////////////////////////////////////////////////////////////
  54. // Helper Functions
  55. //////////////////////////////////////////////////////////////////////////////
  56. /////// From inet.c in ias util directory /////////////
  57. //////////
  58. // Macro to test if a character is a digit.
  59. //////////
  60. #define IASIsDigit(p) ((_TUCHAR)(p - _T('0')) <= 9)
  61. //////////
  62. // Macro to strip one byte of an IP address from a character string.
  63. // 'p' pointer to the string to be parsed
  64. // 'ul' unsigned long that will receive the result.
  65. //////////
  66. #define STRIP_BYTE(p,ul) { \
  67. if (!IASIsDigit(*p)) goto error; \
  68. ul = *p++ - _T('0'); \
  69. if (IASIsDigit(*p)) { \
  70. ul *= 10; ul += *p++ - _T('0'); \
  71. if (IASIsDigit(*p)) { \
  72. ul *= 10; ul += *p++ - _T('0'); \
  73. } \
  74. } \
  75. if (ul > 0xff) goto error; \
  76. }
  77. ///////////////////////////////////////////////////////////////////////////////
  78. //
  79. // FUNCTION
  80. //
  81. // ias_inet_addr
  82. //
  83. // DESCRIPTION
  84. //
  85. // This function is similar to the WinSock inet_addr function (q.v.) except
  86. // it returns the address in host order and it can operate on both ANSI
  87. // and UNICODE strings.
  88. //
  89. ///////////////////////////////////////////////////////////////////////////////
  90. unsigned long __stdcall ias_inet_addr(const WCHAR* cp)
  91. {
  92. unsigned long token;
  93. unsigned long addr;
  94. STRIP_BYTE(cp,addr);
  95. if (*cp++ != _T('.')) goto error;
  96. STRIP_BYTE(cp,token);
  97. if (*cp++ != _T('.')) goto error;
  98. addr <<= 8;
  99. addr |= token;
  100. STRIP_BYTE(cp,token);
  101. if (*cp++ != _T('.')) goto error;
  102. addr <<= 8;
  103. addr |= token;
  104. STRIP_BYTE(cp,token);
  105. addr <<= 8;
  106. return addr | token;
  107. error:
  108. return 0xffffffff;
  109. }
  110. //////////////////////////////////////////////////////////////////////////////
  111. // ConvertVSA
  112. //////////////////////////////////////////////////////////////////////////////
  113. void CMigrateMdb::ConvertVSA(
  114. /*[in]*/ LPCWSTR pAttributeValueName,
  115. /*[in]*/ LPCWSTR pAttrValue,
  116. _bstr_t& NewString
  117. )
  118. {
  119. const long IAS_MAX_VSA_LENGTH = (253 * 2);
  120. const byte VSA_OFFSET = 0;
  121. const byte VSA_OFFSET_NEW = 2;
  122. const byte VSA_OFFSET_VALUE_RFC_NEW = 14;
  123. wchar_t szNewValue[IAS_MAX_VSA_LENGTH + 1];
  124. szNewValue[0] = '\0';
  125. // RFC compliant integer
  126. if ( ! lstrcmp(pAttributeValueName, L"URDecimal or Hexadecimal (0x.. "
  127. L"format) Integer") )
  128. {
  129. // Add the "02" as the type to the head of the string
  130. lstrcat(szNewValue,L"02");
  131. // Copy the old value to the new
  132. lstrcpy(szNewValue + VSA_OFFSET_NEW, pAttrValue + VSA_OFFSET);
  133. // Strip of the "0x" if necessary and convert to decimal
  134. if ( ! wcsncmp(&szNewValue[VSA_OFFSET_VALUE_RFC_NEW], L"0x", 2) )
  135. {
  136. lstrcpy(&szNewValue[VSA_OFFSET_VALUE_RFC_NEW],
  137. &szNewValue[VSA_OFFSET_VALUE_RFC_NEW + 2] );
  138. }
  139. }
  140. // RFC compliant string
  141. else if ( ! lstrcmp(pAttributeValueName, L"URString") )
  142. {
  143. // Set the new string type to "01"
  144. lstrcat(szNewValue,L"01");
  145. // Copy the old string to the new
  146. lstrcpy(szNewValue + VSA_OFFSET_NEW, pAttrValue + VSA_OFFSET);
  147. // Convert the old hex formatted string to a BSTR (in place)
  148. wchar_t wcSaved;
  149. wchar_t* pXlatPos = &szNewValue[VSA_OFFSET_VALUE_RFC_NEW];
  150. wchar_t* pNewCharPos = pXlatPos;
  151. wchar_t* pEnd;
  152. while ( *pXlatPos != '\0' )
  153. {
  154. wcSaved = *(pXlatPos + 2);
  155. *(pXlatPos + 2) = '\0';
  156. *pNewCharPos = (wchar_t) wcstol(pXlatPos, &pEnd, 16);
  157. *(pXlatPos + 2) = wcSaved;
  158. pXlatPos += 2;
  159. ++pNewCharPos;
  160. }
  161. *pNewCharPos = '\0';
  162. }
  163. // RFC compliant hex
  164. else if ( ! lstrcmp(pAttributeValueName, L"URHexadecimal") )
  165. {
  166. // Set the new type and copy the old string to the new
  167. lstrcat(szNewValue,L"03");
  168. lstrcpy(szNewValue + VSA_OFFSET_NEW, pAttrValue + VSA_OFFSET);
  169. }
  170. // Non RFC compliant (always hex)
  171. else if ( ! lstrcmp(pAttributeValueName, L"UHHexadecimal") )
  172. {
  173. // Set the new type and copy the old string to the new
  174. lstrcat(szNewValue,L"00");
  175. lstrcpy(szNewValue + VSA_OFFSET_NEW, pAttrValue + VSA_OFFSET);
  176. }
  177. // Error
  178. else
  179. {
  180. _ASSERT(FALSE);
  181. }
  182. // Return the new string
  183. NewString = szNewValue;
  184. }
  185. //////////////////////////////////////////////////////////////////////////////
  186. // MigrateProxyServers
  187. //////////////////////////////////////////////////////////////////////////////
  188. void CMigrateMdb::MigrateProxyServers()
  189. {
  190. const long DEFAULT_PRIORITY = 1;
  191. const long DEFAULT_WEIGHT = 50;
  192. // If there isn't any servers.
  193. if ( m_GlobalData.m_pRadiusServers->IsEmpty() )
  194. {
  195. return;
  196. }
  197. CProxyServerGroupCollection& ServerCollection
  198. = CProxyServerGroupCollection::Instance();
  199. // Do a loop on the RadiusServers sorted by server group
  200. _bstr_t CurrentGroupName;
  201. CProxyServersGroupHelper* pCurrentServerGroup = NULL; //avoid warning
  202. // CurrentGroupName will never match a name received therefore
  203. // pCurrentServerGroup will always be initialized before being used
  204. HRESULT hr;
  205. do
  206. {
  207. _bstr_t GroupName = m_GlobalData.m_pRadiusServers->GetGroupName();
  208. if ( CurrentGroupName != GroupName )
  209. {
  210. CProxyServersGroupHelper ServerGroup(m_GlobalData);
  211. CurrentGroupName = GroupName;
  212. ServerGroup.SetName(GroupName);
  213. // Add a server to the collection
  214. pCurrentServerGroup = ServerCollection.Add(ServerGroup);
  215. }
  216. if ( !pCurrentServerGroup )
  217. {
  218. _com_issue_error(E_FAIL);
  219. }
  220. CProxyServerHelper Server(m_GlobalData);
  221. _bstr_t ServerName = m_GlobalData.m_pRadiusServers->
  222. GetProxyServerName();
  223. Server.SetAddress(ServerName);
  224. Server.SetAuthenticationPort(
  225. m_GlobalData.m_pRadiusServers->GetAuthenticationPortNumber()
  226. );
  227. Server.SetAccountingPort(
  228. m_GlobalData.m_pRadiusServers->GetAccountingPortNumber()
  229. );
  230. _bstr_t Secret = m_GlobalData.m_pRadiusServers->GetSharedSecret();
  231. Server.SetAuthenticationSecret(Secret);
  232. Server.SetPriority(DEFAULT_PRIORITY);
  233. Server.SetWeight(DEFAULT_WEIGHT);
  234. pCurrentServerGroup->Add(Server); // cannot be NULL pointer
  235. hr = m_GlobalData.m_pRadiusServers->GetNext();
  236. }
  237. while (hr == S_OK);
  238. // persist everything in the database
  239. ServerCollection.Persist();
  240. _com_util::CheckError(hr);
  241. }
  242. //////////////////////////////////////////////////////////////////////////////
  243. // NewMigrateClients
  244. //////////////////////////////////////////////////////////////////////////////
  245. void CMigrateMdb::NewMigrateClients()
  246. {
  247. // If there isn't any client, return
  248. if ( m_GlobalData.m_pClients->IsEmpty() )
  249. {
  250. return;
  251. }
  252. // for each client in the client table, add it (blindly) to the dest table
  253. // i.e. walkpath to find the clients container
  254. // create the properties for that containes (clients).
  255. const WCHAR ClientContainerPath[] =
  256. L"Root\0"
  257. L"Microsoft Internet Authentication Service\0"
  258. L"Protocols\0"
  259. L"Microsoft Radius Protocol\0"
  260. L"Clients\0";
  261. LONG ClientContainerIdentity;
  262. m_GlobalData.m_pObjects->WalkPath(
  263. ClientContainerPath,
  264. ClientContainerIdentity
  265. );
  266. HRESULT hr;
  267. do
  268. {
  269. _bstr_t ClientName = m_GlobalData.m_pClients->GetHostName();
  270. _bstr_t ClientSecret = m_GlobalData.m_pClients->GetSecret();
  271. LONG ClientIdentity;
  272. m_GlobalData.m_pObjects->InsertObject(
  273. ClientName,
  274. ClientContainerIdentity,
  275. ClientIdentity
  276. );
  277. // Now insert the properties:
  278. // IP Address
  279. _bstr_t PropertyName = L"IP Address";
  280. m_GlobalData.m_pProperties->InsertProperty(
  281. ClientIdentity,
  282. PropertyName,
  283. VT_BSTR,
  284. ClientName
  285. );
  286. // NAS Manufacturer
  287. PropertyName = L"NAS Manufacturer";
  288. _bstr_t StrValZero = L"0"; // RADIUS Standard
  289. m_GlobalData.m_pProperties->InsertProperty(
  290. ClientIdentity,
  291. PropertyName,
  292. VT_I4,
  293. StrValZero
  294. );
  295. // Require Signature
  296. PropertyName = L"Require Signature";
  297. m_GlobalData.m_pProperties->InsertProperty(
  298. ClientIdentity,
  299. PropertyName,
  300. VT_BOOL,
  301. StrValZero
  302. );
  303. // Shared Secret
  304. PropertyName = L"Shared Secret";
  305. m_GlobalData.m_pProperties->InsertProperty(
  306. ClientIdentity,
  307. PropertyName,
  308. VT_BSTR,
  309. ClientSecret
  310. );
  311. hr = m_GlobalData.m_pClients->GetNext();
  312. }
  313. while ( hr == S_OK );
  314. _com_util::CheckError(hr);
  315. }
  316. //////////////////////////////////////////////////////////////////////////////
  317. // ConvertAttribute
  318. //////////////////////////////////////////////////////////////////////////////
  319. void CMigrateMdb::ConvertAttribute(
  320. const _bstr_t& Value,
  321. LONG Syntax,
  322. LONG& Type,
  323. bstr_t& StrVal
  324. )
  325. {
  326. const size_t SIZE_LONG_MAX = 14;
  327. switch (Syntax)
  328. {
  329. case IAS_SYNTAX_OCTETSTRING:
  330. {
  331. // abinary => OctetString
  332. Type = VT_BSTR;
  333. StrVal = Value;
  334. break;
  335. }
  336. case IAS_SYNTAX_STRING:
  337. case IAS_SYNTAX_UTCTIME:
  338. case IAS_SYNTAX_PROVIDERSPECIFIC:
  339. {
  340. Type = VT_BSTR;
  341. StrVal = Value;
  342. break;
  343. }
  344. case IAS_SYNTAX_INETADDR:
  345. {
  346. unsigned long ulValue = ias_inet_addr(Value);
  347. _ASSERT( ulValue != 0xffffffff );
  348. Type = VT_I4;
  349. WCHAR TempString[SIZE_LONG_MAX];
  350. StrVal = _ultow(ulValue, TempString, 10);
  351. break;
  352. }
  353. case IAS_SYNTAX_BOOLEAN:
  354. {
  355. LONG lValue = _wtol(Value);
  356. Type = VT_BOOL;
  357. StrVal = lValue? L"-1":L"0";
  358. break;
  359. }
  360. case IAS_SYNTAX_INTEGER:
  361. case IAS_SYNTAX_UNSIGNEDINTEGER:
  362. case IAS_SYNTAX_ENUMERATOR:
  363. {
  364. Type = VT_I4;
  365. StrVal = Value;
  366. break;
  367. }
  368. default:
  369. {
  370. _com_issue_error(E_INVALIDARG);
  371. }
  372. }
  373. }
  374. //////////////////////////////////////////////////////////////////////////////
  375. // MigrateAttribute
  376. //////////////////////////////////////////////////////////////////////////////
  377. void CMigrateMdb::MigrateAttribute(
  378. const _bstr_t& Attribute,
  379. LONG AttributeNumber,
  380. const _bstr_t& AttributeValueName,
  381. const _bstr_t& StringValue,
  382. LONG RASProfileIdentity
  383. )
  384. {
  385. // Note: Order might not be needed if the previous DB is always sorted
  386. const size_t SIZE_LONG_MAX = 14;
  387. _bstr_t LDAPName, StrVal;
  388. LONG Syntax, Type; // Type: VT_BSTR, VT_I4, VT_BOOL
  389. BOOL IsMultiValued;
  390. HRESULT hr = m_GlobalData.m_pAttributes->GetAttribute(
  391. AttributeNumber,
  392. LDAPName,
  393. Syntax,
  394. IsMultiValued
  395. );
  396. if ( FAILED(hr) )
  397. {
  398. // Attribute unknown in the new dictionary
  399. // that should never happen
  400. return;
  401. }
  402. const LONG VSA = 26; //Vendor-Specific-Attribute
  403. if ( StringValue.length() && ( AttributeNumber != VSA) )
  404. {
  405. // ordinary attribute, not an enumerator
  406. ConvertAttribute(
  407. StringValue,
  408. Syntax,
  409. Type,
  410. StrVal
  411. );
  412. if ( IsMultiValued )
  413. {
  414. // If the attribute is multivalued then we need to add the value
  415. // Otherwise we just update the attribute value
  416. m_GlobalData.m_pProperties->InsertProperty(
  417. RASProfileIdentity,
  418. LDAPName,
  419. Type,
  420. StrVal
  421. );
  422. }
  423. else
  424. {
  425. m_GlobalData.m_pProperties->UpdateProperty(
  426. RASProfileIdentity,
  427. LDAPName,
  428. Type,
  429. StrVal
  430. );
  431. }
  432. }
  433. else if ( StringValue.length() && ( AttributeNumber == VSA) )
  434. {
  435. // VSA Attribute (convert...)
  436. if ( !AttributeValueName )
  437. {
  438. _com_issue_error(E_INVALIDARG);
  439. }
  440. ConvertVSA(AttributeValueName, StringValue, StrVal);
  441. Type = VT_BSTR;
  442. m_GlobalData.m_pProperties->InsertProperty(
  443. RASProfileIdentity,
  444. LDAPName,
  445. Type,
  446. StrVal
  447. );
  448. }
  449. else if ( !StringValue.length() )
  450. {
  451. // Multivalued attribute.
  452. Type = VT_I4;
  453. // Get the number associated with it from the RadiusAttributeValues
  454. // table
  455. LONG Number = m_GlobalData.m_pRADIUSAttributeValues->GetAttributeNumber
  456. (
  457. Attribute,
  458. AttributeValueName
  459. );
  460. WCHAR TempString[SIZE_LONG_MAX ];
  461. StrVal = _ltow(Number, TempString, 10);
  462. // The attribute should be multivalued
  463. _ASSERTE(IsMultiValued);
  464. m_GlobalData.m_pProperties->InsertProperty(
  465. RASProfileIdentity,
  466. LDAPName,
  467. Type,
  468. StrVal
  469. );
  470. }
  471. else
  472. {
  473. // other (unknown)
  474. _com_issue_error(E_FAIL);
  475. }
  476. }
  477. //////////////////////////////////////////////////////////////////////////////
  478. // MigrateOtherProfile
  479. //////////////////////////////////////////////////////////////////////////////
  480. void CMigrateMdb::MigrateOtherProfile(
  481. const _bstr_t& ProfileName,
  482. LONG ProfileIdentity
  483. )
  484. {
  485. _bstr_t Attribute, AttributeValueName, StringValue;
  486. LONG Order, AttributeNumber;
  487. // Now add the attributes from the NT4 file
  488. HRESULT hr = m_GlobalData.m_pProfileAttributeList->GetAttribute(
  489. ProfileName,
  490. Attribute,
  491. AttributeNumber,
  492. AttributeValueName,
  493. StringValue,
  494. Order
  495. );
  496. LONG IndexAttribute = 1;
  497. // For each attribute in the Profile Attribute List
  498. // with szProfile = ProfileName
  499. while ( SUCCEEDED(hr) )
  500. {
  501. // migrate it to the default RAS profile in IAS.mdb
  502. MigrateAttribute(
  503. Attribute,
  504. AttributeNumber,
  505. AttributeValueName,
  506. StringValue,
  507. ProfileIdentity
  508. );
  509. hr = m_GlobalData.m_pProfileAttributeList->GetAttribute(
  510. ProfileName,
  511. Attribute,
  512. AttributeNumber,
  513. AttributeValueName,
  514. StringValue,
  515. Order,
  516. IndexAttribute
  517. );
  518. ++IndexAttribute;
  519. }
  520. }
  521. //////////////////////////////////////////////////////////////////////////////
  522. // MigrateCorpProfile
  523. //////////////////////////////////////////////////////////////////////////////
  524. void CMigrateMdb::MigrateCorpProfile(
  525. const _bstr_t& ProfileName,
  526. const _bstr_t& Description
  527. )
  528. {
  529. _bstr_t Attribute, AttributeValueName, StringValue;
  530. LONG Order, AttributeNumber;
  531. // empty the default profiles attributes
  532. const WCHAR RASProfilePath[] =
  533. L"Root\0"
  534. L"Microsoft Internet Authentication Service\0"
  535. L"RadiusProfiles\0";
  536. LONG RASProfileIdentity;
  537. m_GlobalData.m_pObjects->WalkPath(RASProfilePath, RASProfileIdentity);
  538. // Now get the first profile: that's the default (localized) RAS profile
  539. _bstr_t DefaultProfileName;
  540. LONG DefaultProfileIdentity;
  541. m_GlobalData.m_pObjects->GetObject(
  542. DefaultProfileName,
  543. DefaultProfileIdentity,
  544. RASProfileIdentity
  545. );
  546. // Clean the default attributes
  547. m_GlobalData.m_pProperties->DeleteProperty(
  548. DefaultProfileIdentity,
  549. L"msRADIUSServiceType"
  550. );
  551. m_GlobalData.m_pProperties->DeleteProperty(
  552. DefaultProfileIdentity,
  553. L"msRADIUSFramedProtocol"
  554. );
  555. // Now add the attributes from the NT4 file
  556. HRESULT hr = m_GlobalData.m_pProfileAttributeList->GetAttribute(
  557. ProfileName,
  558. Attribute,
  559. AttributeNumber,
  560. AttributeValueName,
  561. StringValue,
  562. Order
  563. );
  564. LONG IndexAttribute = 1;
  565. // For each attribute in the Profile Attribute List
  566. // with szProfile = ProfileName
  567. while ( SUCCEEDED(hr) )
  568. {
  569. // migrate it to the default RAS profile in IAS.mdb
  570. MigrateAttribute(
  571. Attribute,
  572. AttributeNumber,
  573. AttributeValueName,
  574. StringValue,
  575. DefaultProfileIdentity
  576. );
  577. hr = m_GlobalData.m_pProfileAttributeList->GetAttribute(
  578. ProfileName,
  579. Attribute,
  580. AttributeNumber,
  581. AttributeValueName,
  582. StringValue,
  583. Order,
  584. IndexAttribute
  585. );
  586. ++IndexAttribute;
  587. }
  588. // now not matter what, if Description == ODBC,
  589. // Then the policy should have a condition to never match.
  590. // (update msNPConstraint
  591. const _bstr_t BadProvider = L"ODBC";
  592. if ( Description == BadProvider ) //safe compare
  593. {
  594. // Get the Policy container
  595. const WCHAR RASPolicyPath[] =
  596. L"Root\0"
  597. L"Microsoft Internet Authentication Service\0"
  598. L"NetworkPolicy\0";
  599. // Get its (unique) child
  600. LONG RASPolicyIdentity;
  601. m_GlobalData.m_pObjects->WalkPath(RASPolicyPath, RASPolicyIdentity);
  602. // Now get the first policy: that's the default (localized) RAS policy
  603. _bstr_t DefaultPolicyName;
  604. LONG DefaultPolicyIdentity;
  605. m_GlobalData.m_pObjects->GetObject(
  606. DefaultPolicyName,
  607. DefaultPolicyIdentity,
  608. RASPolicyIdentity
  609. );
  610. // delete the msNPConstraint (s)
  611. const _bstr_t Constraint = L"msNPConstraint";
  612. m_GlobalData.m_pProperties->DeleteProperty(
  613. DefaultPolicyIdentity,
  614. Constraint
  615. );
  616. // add a TIMEOFDAY that never matches
  617. const _bstr_t DumbTime = L"TIMEOFDAY(\"\")";
  618. m_GlobalData.m_pProperties->InsertProperty(
  619. RASPolicyIdentity,
  620. Constraint,
  621. VT_BSTR,
  622. DumbTime
  623. );
  624. }
  625. }
  626. //////////////////////////////////////////////////////////////////////////////
  627. // NewMigrateProfiles
  628. //////////////////////////////////////////////////////////////////////////////
  629. void CMigrateMdb::NewMigrateProfiles()
  630. {
  631. const LONG AUTH_PROVIDER_WINDOWS = 1;
  632. const LONG AUTH_PROVIDER_RADIUS_PROXY = 2;
  633. const LONG ACCT_PROVIDER_RADIUS_PROXY = 2;
  634. const _bstr_t RemoteRADIUSServers = L"Remote RADIUS Servers";
  635. const _bstr_t MCIS = L"MCIS";
  636. const _bstr_t MCISv2 = L"MCIS version 2.0";
  637. const _bstr_t ODBC = L"ODBC";
  638. const _bstr_t WindowsNT = L"Windows NT";
  639. const _bstr_t MatchAll = L"TIMEOFDAY(\"0 00:00-24:00; 1 00:00"
  640. L"-24:00; 2 00:00-24:00; 3 00:00-24:00; 4 00:00-24:00; 5 00:"
  641. L"00-24:00; 6 00:00-24:00\")";
  642. // Get the Default Provider's data
  643. _bstr_t DPUserDefinedName, DPProfile;
  644. VARIANT_BOOL DPForwardAccounting, DPSupressAccounting
  645. , DPLogoutAccounting;
  646. m_GlobalData.m_pDefaultProvider->GetDefaultProvider(
  647. DPUserDefinedName,
  648. DPProfile,
  649. DPForwardAccounting,
  650. DPSupressAccounting,
  651. DPLogoutAccounting
  652. );
  653. _bstr_t ProfileName = m_GlobalData.m_pProfiles->GetProfileName();
  654. // Delete the RRAS specific policy.
  655. m_GlobalData.m_pObjects->DeleteObject(203);
  656. m_GlobalData.m_pObjects->DeleteObject(204);
  657. // Do the NT4 CORP migration first if needed
  658. if ( m_Utils.IsNT4Corp() )
  659. {
  660. // This is NT4 CORP. migrate the default profile into
  661. // the default policy/profile (not the proxy default)
  662. _bstr_t Description = m_GlobalData.m_pProviders->
  663. GetProviderDescription(DPUserDefinedName);
  664. MigrateCorpProfile(ProfileName, Description);
  665. // stop here
  666. return;
  667. }
  668. // Now that is not a NT4 CORP migration
  669. // Delete the default Proxy Policy / profile
  670. const WCHAR ProxyPoliciesPath[] =
  671. L"Root\0"
  672. L"Microsoft Internet Authentication Service\0"
  673. L"Proxy Policies\0";
  674. LONG ProxyPolicyIdentity;
  675. m_GlobalData.m_pObjects->WalkPath(ProxyPoliciesPath, ProxyPolicyIdentity);
  676. // Now get the first profile: that's the default (localized) RAS policy
  677. _bstr_t DefaultPolicyName;
  678. LONG DefaultPolicyIdentity;
  679. m_GlobalData.m_pObjects->GetObject(
  680. DefaultPolicyName,
  681. DefaultPolicyIdentity,
  682. ProxyPolicyIdentity
  683. );
  684. m_GlobalData.m_pObjects->DeleteObject(DefaultPolicyIdentity);
  685. // From now on the default proxy policy / profile is deleted
  686. // Now empty the default RAS profiles attributes
  687. const WCHAR RASProfilePath[] =
  688. L"Root\0"
  689. L"Microsoft Internet Authentication Service\0"
  690. L"RadiusProfiles\0";
  691. LONG RASProfileIdentity;
  692. m_GlobalData.m_pObjects->WalkPath(RASProfilePath, RASProfileIdentity);
  693. // Now get the first profile: that's the default (localized) RAS profile
  694. _bstr_t DefaultProfileName;
  695. LONG DefaultProfileIdentity;
  696. m_GlobalData.m_pObjects->GetObject(
  697. DefaultProfileName,
  698. DefaultProfileIdentity,
  699. RASProfileIdentity
  700. );
  701. // Clean the default attributes
  702. m_GlobalData.m_pProperties->DeleteProperty(
  703. DefaultProfileIdentity,
  704. L"msRADIUSServiceType"
  705. );
  706. m_GlobalData.m_pProperties->DeleteProperty(
  707. DefaultProfileIdentity,
  708. L"msRADIUSFramedProtocol"
  709. );
  710. // from now on the default RAS profile has its default attributes (the one
  711. // in the Advanced tab in the UI) deleted.
  712. HRESULT hr;
  713. LONG Sequence = 1;
  714. // Get the list of the profiles
  715. do
  716. {
  717. LONG RealmIndex = 0;
  718. ProfileName = m_GlobalData.m_pProfiles->GetProfileName();
  719. // Note: hr should be set only by GetRealmIndex
  720. do
  721. {
  722. // Get the realms associated with that profile
  723. CPolicy TempPolicy;
  724. hr = m_GlobalData.m_pRealms->GetRealmIndex(ProfileName,RealmIndex);
  725. if ( hr != S_OK )
  726. {
  727. // exit that internal do / while to get the next profile
  728. break;
  729. }
  730. _bstr_t RealmName = m_GlobalData.m_pRealms->GetRealmName();
  731. TempPolicy.SetmsNPAction(RealmName);
  732. ++RealmIndex;
  733. // That will set the realm part of the profile based on the
  734. // values in NT4 as well as the reg keys values
  735. m_GlobalData.m_pRealms->SetRealmDetails(
  736. TempPolicy,
  737. m_Utils
  738. );
  739. _bstr_t UserDefinedName = m_GlobalData.m_pRealms
  740. ->GetUserDefinedName();
  741. // Look up the provider in the providers table. Note: Assume
  742. // the proxy servers (and groups) are already migrated.
  743. _bstr_t ProviderDescription = m_GlobalData.m_pProviders
  744. ->GetProviderDescription(UserDefinedName);
  745. // Set the sequence order
  746. TempPolicy.SetmsNPSequence(Sequence);
  747. // Now set the authentication provider
  748. if ( ProviderDescription == RemoteRADIUSServers )
  749. {
  750. TempPolicy.SetmsAuthProviderType(
  751. AUTH_PROVIDER_RADIUS_PROXY,
  752. UserDefinedName
  753. );
  754. }
  755. else if ( ( ProviderDescription == MCIS ) ||
  756. ( ProviderDescription == MCISv2 ) ||
  757. ( ProviderDescription == WindowsNT ) )
  758. {
  759. TempPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
  760. }
  761. else if ( ProviderDescription == ODBC )
  762. {
  763. // If ODBC is the authentication provider,
  764. // then convert that realm into a policy that would never match.
  765. // Authentication provider should be NT Domain.
  766. TempPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
  767. const _bstr_t MatchNothing = L"TIMEOFDAY(\"\")";
  768. TempPolicy.SetmsNPConstraint(MatchNothing);
  769. }
  770. else
  771. {
  772. _com_issue_error(E_INVALIDARG);
  773. }
  774. // persist the policy
  775. LONG ProfileIdentity = TempPolicy.Persist(m_GlobalData);
  776. // migrate the profile associated with that policy
  777. MigrateOtherProfile(ProfileName, ProfileIdentity);
  778. ++Sequence;
  779. } while (hr == S_OK);
  780. hr = m_GlobalData.m_pProfiles->GetNext();
  781. } while ( hr == S_OK );
  782. if ( DPUserDefinedName.length() )
  783. {
  784. // there is a default provider: a default policy needs to be created
  785. // same logic as above (mostly)
  786. CPolicy DefaultPolicy;
  787. DefaultPolicy.SetmsNPAction(DPProfile);
  788. _bstr_t ProviderDescription = m_GlobalData.m_pProviders
  789. ->GetProviderDescription(DPUserDefinedName);
  790. if ( ProviderDescription == RemoteRADIUSServers )
  791. {
  792. DefaultPolicy.SetmsAuthProviderType(
  793. AUTH_PROVIDER_RADIUS_PROXY,
  794. DPUserDefinedName
  795. );
  796. DefaultPolicy.SetmsNPConstraint(MatchAll);
  797. }
  798. else if ( ( ProviderDescription == MCIS ) ||
  799. ( ProviderDescription == MCISv2 ) ||
  800. ( ProviderDescription == WindowsNT ) )
  801. {
  802. DefaultPolicy.SetmsNPConstraint(MatchAll);
  803. DefaultPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
  804. }
  805. else if ( ProviderDescription == ODBC )
  806. {
  807. // If ODBC is the authentication provider,
  808. // then convert that realm into a policy that would never match.
  809. // Authentication provider should be NT Domain.
  810. DefaultPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
  811. const _bstr_t MatchNothing = L"TIMEOFDAY(\"\")";
  812. DefaultPolicy.SetmsNPConstraint(MatchNothing);
  813. }
  814. else
  815. {
  816. _com_issue_error(E_INVALIDARG);
  817. }
  818. DefaultPolicy.SetmsNPSequence(Sequence);
  819. if ( DPForwardAccounting )
  820. {
  821. DefaultPolicy.SetmsAcctProviderType(ACCT_PROVIDER_RADIUS_PROXY);
  822. }
  823. LONG ProfileIdentity = DefaultPolicy.Persist(m_GlobalData);
  824. MigrateOtherProfile(DPProfile, ProfileIdentity);
  825. }
  826. // else no default provider: no default policy
  827. }
  828. //////////////////////////////////////////////////////////////////////////////
  829. // NewMigrateAccounting
  830. //////////////////////////////////////////////////////////////////////////////
  831. void CMigrateMdb::NewMigrateAccounting()
  832. {
  833. const WCHAR AccountingPath[] =
  834. L"Root\0"
  835. L"Microsoft Internet Authentication Service\0"
  836. L"RequestHandlers\0"
  837. L"Microsoft Accounting\0";
  838. LONG AccountingIdentity;
  839. m_GlobalData.m_pObjects->WalkPath(AccountingPath, AccountingIdentity);
  840. _bstr_t MaxLogSize = m_GlobalData.m_pServiceConfiguration->GetMaxLogSize();
  841. _bstr_t LogFrequency = m_GlobalData.m_pServiceConfiguration->
  842. GetLogFrequency();
  843. _bstr_t PropertyName = L"New Log Frequency";
  844. m_GlobalData.m_pProperties->UpdateProperty(
  845. AccountingIdentity,
  846. PropertyName,
  847. VT_I4,
  848. LogFrequency
  849. );
  850. PropertyName = L"New Log Size";
  851. m_GlobalData.m_pProperties->UpdateProperty(
  852. AccountingIdentity,
  853. PropertyName,
  854. VT_I4,
  855. MaxLogSize
  856. );
  857. DWORD Value;
  858. m_Utils.NewGetAuthSrvParameter(L"LogAuthentications", Value);
  859. _bstr_t LogAuth;
  860. Value ? LogAuth = L"-1": LogAuth = L"0";
  861. PropertyName = L"Log Authentication Packets";
  862. m_GlobalData.m_pProperties->UpdateProperty(
  863. AccountingIdentity,
  864. PropertyName,
  865. VT_BOOL,
  866. LogAuth
  867. );
  868. m_Utils.NewGetAuthSrvParameter(L"LogAccounting", Value);
  869. _bstr_t LogAcct;
  870. Value ? LogAcct = L"-1": LogAcct = L"0";
  871. PropertyName = L"Log Accounting Packets";
  872. m_GlobalData.m_pProperties->UpdateProperty(
  873. AccountingIdentity,
  874. PropertyName,
  875. VT_BOOL,
  876. LogAcct
  877. );
  878. _bstr_t FormatIAS1 = L"0";
  879. PropertyName = L"Log Format";
  880. m_GlobalData.m_pProperties->UpdateProperty(
  881. AccountingIdentity,
  882. PropertyName,
  883. VT_I4,
  884. FormatIAS1
  885. );
  886. _bstr_t DeleteIfFull = L"0";
  887. PropertyName = L"Delete If Full";
  888. m_GlobalData.m_pProperties->UpdateProperty(
  889. AccountingIdentity,
  890. PropertyName,
  891. VT_BOOL,
  892. DeleteIfFull
  893. );
  894. PropertyName = L"Log File Directory";
  895. _bstr_t LogFileDir =
  896. m_GlobalData.m_pServiceConfiguration->GetLogFileDirectory();
  897. m_GlobalData.m_pProperties->UpdateProperty(
  898. AccountingIdentity,
  899. PropertyName,
  900. VT_BSTR,
  901. LogFileDir
  902. );
  903. }
  904. //////////////////////////////////////////////////////////////////////////////
  905. // NewMigrateEventLog
  906. //////////////////////////////////////////////////////////////////////////////
  907. void CMigrateMdb::NewMigrateEventLog()
  908. {
  909. const WCHAR EventLogPath[] =
  910. L"Root\0"
  911. L"Microsoft Internet Authentication Service\0"
  912. L"Auditors\0"
  913. L"Microsoft NT Event Log Auditor\0";
  914. LONG EventLogIdentity;
  915. m_GlobalData.m_pObjects->WalkPath(EventLogPath, EventLogIdentity);
  916. DWORD Value;
  917. m_Utils.NewGetAuthSrvParameter(L"LogData", Value);
  918. _bstr_t LogData;
  919. Value ? LogData = L"-1": LogData = L"0";
  920. _bstr_t PropertyName = L"Log Verbose";
  921. m_GlobalData.m_pProperties->UpdateProperty(
  922. EventLogIdentity,
  923. PropertyName,
  924. VT_BOOL,
  925. LogData
  926. );
  927. m_Utils.NewGetAuthSrvParameter(L"LogBogus", Value);
  928. _bstr_t LogBogus;
  929. Value ? LogBogus = L"-1": LogBogus = L"0";
  930. PropertyName = L"Log Malformed Packets";
  931. m_GlobalData.m_pProperties->UpdateProperty(
  932. EventLogIdentity,
  933. PropertyName,
  934. VT_BOOL,
  935. LogBogus
  936. );
  937. }
  938. //////////////////////////////////////////////////////////////////////////////
  939. // NewMigrateService
  940. //////////////////////////////////////////////////////////////////////////////
  941. void CMigrateMdb::NewMigrateService()
  942. {
  943. const LONG PORT_SIZE_MAX = 34;
  944. const WCHAR ServicePath[] =
  945. L"Root\0"
  946. L"Microsoft Internet Authentication Service\0"
  947. L"Protocols\0"
  948. L"Microsoft Radius Protocol\0";
  949. LONG ServiceIdentity;
  950. m_GlobalData.m_pObjects->WalkPath(ServicePath, ServiceIdentity);
  951. DWORD Value;
  952. m_Utils.NewGetAuthSrvParameter(L"RadiusPort", Value);
  953. WCHAR TempString[PORT_SIZE_MAX];
  954. _bstr_t RadiusPort = _ultow(Value, TempString, 10);
  955. _bstr_t PropertyName = L"Authentication Port";
  956. m_GlobalData.m_pProperties->UpdateProperty(
  957. ServiceIdentity,
  958. PropertyName,
  959. VT_BSTR,
  960. RadiusPort
  961. );
  962. m_Utils.NewGetAuthSrvParameter(L"AcctPort", Value);
  963. _bstr_t AcctPort = _ltow(Value, TempString, 10);
  964. PropertyName = L"Accounting Port";
  965. m_GlobalData.m_pProperties->UpdateProperty(
  966. ServiceIdentity,
  967. PropertyName,
  968. VT_BSTR,
  969. AcctPort
  970. );
  971. }
  972. //////////////////////////////////////////////////////////////////////////////
  973. // NewMigrate
  974. //////////////////////////////////////////////////////////////////////////////
  975. void CMigrateMdb::NewMigrate()
  976. {
  977. NewMigrateClients();
  978. if ( !m_Utils.IsNT4Corp() ) // it's either Win2k or NT4 ISP
  979. {
  980. // the proxy servers must be migrated before the policies and
  981. // profiles
  982. MigrateProxyServers();
  983. }
  984. NewMigrateProfiles();
  985. NewMigrateAccounting();
  986. NewMigrateEventLog();
  987. NewMigrateService();
  988. /////////////////////////////
  989. // Migrate the Registry Keys
  990. /////////////////////////////
  991. CMigrateRegistry MigrateRegistry(m_Utils);
  992. MigrateRegistry.MigrateProviders();
  993. //////////////////////////////////////////////////////
  994. // Update the MSChap Authentication types (password)
  995. //////////////////////////////////////////////////////
  996. CUpdateMSCHAP UpdateMSCHAP(m_GlobalData);
  997. UpdateMSCHAP.Execute();
  998. }