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.

1120 lines
42 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. // Do the NT4 CORP migration first if needed
  655. if ( m_Utils.IsNT4Corp() )
  656. {
  657. // This is NT4 CORP. migrate the default profile into
  658. // the default policy/profile (not the proxy default)
  659. _bstr_t Description = m_GlobalData.m_pProviders->
  660. GetProviderDescription(DPUserDefinedName);
  661. MigrateCorpProfile(ProfileName, Description);
  662. // stop here
  663. return;
  664. }
  665. // Now that is not a NT4 CORP migration
  666. // Delete the default Proxy Policy / profile
  667. const WCHAR ProxyPoliciesPath[] =
  668. L"Root\0"
  669. L"Microsoft Internet Authentication Service\0"
  670. L"Proxy Policies\0";
  671. LONG ProxyPolicyIdentity;
  672. m_GlobalData.m_pObjects->WalkPath(ProxyPoliciesPath, ProxyPolicyIdentity);
  673. // Now get the first profile: that's the default (localized) RAS policy
  674. _bstr_t DefaultPolicyName;
  675. LONG DefaultPolicyIdentity;
  676. m_GlobalData.m_pObjects->GetObject(
  677. DefaultPolicyName,
  678. DefaultPolicyIdentity,
  679. ProxyPolicyIdentity
  680. );
  681. m_GlobalData.m_pObjects->DeleteObject(DefaultPolicyIdentity);
  682. // From now on the default proxy policy / profile is deleted
  683. // Now empty the default RAS profiles attributes
  684. const WCHAR RASProfilePath[] =
  685. L"Root\0"
  686. L"Microsoft Internet Authentication Service\0"
  687. L"RadiusProfiles\0";
  688. LONG RASProfileIdentity;
  689. m_GlobalData.m_pObjects->WalkPath(RASProfilePath, RASProfileIdentity);
  690. // Now get the first profile: that's the default (localized) RAS profile
  691. _bstr_t DefaultProfileName;
  692. LONG DefaultProfileIdentity;
  693. m_GlobalData.m_pObjects->GetObject(
  694. DefaultProfileName,
  695. DefaultProfileIdentity,
  696. RASProfileIdentity
  697. );
  698. // Clean the default attributes
  699. m_GlobalData.m_pProperties->DeleteProperty(
  700. DefaultProfileIdentity,
  701. L"msRADIUSServiceType"
  702. );
  703. m_GlobalData.m_pProperties->DeleteProperty(
  704. DefaultProfileIdentity,
  705. L"msRADIUSFramedProtocol"
  706. );
  707. // from now on the default RAS profile has its default attributes (the one
  708. // in the Advanced tab in the UI) deleted.
  709. HRESULT hr;
  710. LONG Sequence = 1;
  711. // Get the list of the profiles
  712. do
  713. {
  714. LONG RealmIndex = 0;
  715. ProfileName = m_GlobalData.m_pProfiles->GetProfileName();
  716. // Note: hr should be set only by GetRealmIndex
  717. do
  718. {
  719. // Get the realms associated with that profile
  720. CPolicy TempPolicy;
  721. hr = m_GlobalData.m_pRealms->GetRealmIndex(ProfileName,RealmIndex);
  722. if ( hr != S_OK )
  723. {
  724. // exit that internal do / while to get the next profile
  725. break;
  726. }
  727. _bstr_t RealmName = m_GlobalData.m_pRealms->GetRealmName();
  728. TempPolicy.SetmsNPAction(RealmName);
  729. ++RealmIndex;
  730. // That will set the realm part of the profile based on the
  731. // values in NT4 as well as the reg keys values
  732. m_GlobalData.m_pRealms->SetRealmDetails(
  733. TempPolicy,
  734. m_Utils
  735. );
  736. _bstr_t UserDefinedName = m_GlobalData.m_pRealms
  737. ->GetUserDefinedName();
  738. // Look up the provider in the providers table. Note: Assume
  739. // the proxy servers (and groups) are already migrated.
  740. _bstr_t ProviderDescription = m_GlobalData.m_pProviders
  741. ->GetProviderDescription(UserDefinedName);
  742. // Set the sequence order
  743. TempPolicy.SetmsNPSequence(Sequence);
  744. // Now set the authentication provider
  745. if ( ProviderDescription == RemoteRADIUSServers )
  746. {
  747. TempPolicy.SetmsAuthProviderType(
  748. AUTH_PROVIDER_RADIUS_PROXY,
  749. UserDefinedName
  750. );
  751. }
  752. else if ( ( ProviderDescription == MCIS ) ||
  753. ( ProviderDescription == MCISv2 ) ||
  754. ( ProviderDescription == WindowsNT ) )
  755. {
  756. TempPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
  757. }
  758. else if ( ProviderDescription == ODBC )
  759. {
  760. // If ODBC is the authentication provider,
  761. // then convert that realm into a policy that would never match.
  762. // Authentication provider should be NT Domain.
  763. TempPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
  764. const _bstr_t MatchNothing = L"TIMEOFDAY(\"\")";
  765. TempPolicy.SetmsNPConstraint(MatchNothing);
  766. }
  767. else
  768. {
  769. _com_issue_error(E_INVALIDARG);
  770. }
  771. // persist the policy
  772. LONG ProfileIdentity = TempPolicy.Persist(m_GlobalData);
  773. // migrate the profile associated with that policy
  774. MigrateOtherProfile(ProfileName, ProfileIdentity);
  775. ++Sequence;
  776. } while (hr == S_OK);
  777. hr = m_GlobalData.m_pProfiles->GetNext();
  778. } while ( hr == S_OK );
  779. if ( DPUserDefinedName.length() )
  780. {
  781. // there is a default provider: a default policy needs to be created
  782. // same logic as above (mostly)
  783. CPolicy DefaultPolicy;
  784. DefaultPolicy.SetmsNPAction(DPProfile);
  785. _bstr_t ProviderDescription = m_GlobalData.m_pProviders
  786. ->GetProviderDescription(DPUserDefinedName);
  787. if ( ProviderDescription == RemoteRADIUSServers )
  788. {
  789. DefaultPolicy.SetmsAuthProviderType(
  790. AUTH_PROVIDER_RADIUS_PROXY,
  791. DPUserDefinedName
  792. );
  793. DefaultPolicy.SetmsNPConstraint(MatchAll);
  794. }
  795. else if ( ( ProviderDescription == MCIS ) ||
  796. ( ProviderDescription == MCISv2 ) ||
  797. ( ProviderDescription == WindowsNT ) )
  798. {
  799. DefaultPolicy.SetmsNPConstraint(MatchAll);
  800. DefaultPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
  801. }
  802. else if ( ProviderDescription == ODBC )
  803. {
  804. // If ODBC is the authentication provider,
  805. // then convert that realm into a policy that would never match.
  806. // Authentication provider should be NT Domain.
  807. DefaultPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
  808. const _bstr_t MatchNothing = L"TIMEOFDAY(\"\")";
  809. DefaultPolicy.SetmsNPConstraint(MatchNothing);
  810. }
  811. else
  812. {
  813. _com_issue_error(E_INVALIDARG);
  814. }
  815. DefaultPolicy.SetmsNPSequence(Sequence);
  816. if ( DPForwardAccounting )
  817. {
  818. DefaultPolicy.SetmsAcctProviderType(ACCT_PROVIDER_RADIUS_PROXY);
  819. }
  820. LONG ProfileIdentity = DefaultPolicy.Persist(m_GlobalData);
  821. MigrateOtherProfile(DPProfile, ProfileIdentity);
  822. }
  823. // else no default provider: no default policy
  824. }
  825. //////////////////////////////////////////////////////////////////////////////
  826. // NewMigrateAccounting
  827. //////////////////////////////////////////////////////////////////////////////
  828. void CMigrateMdb::NewMigrateAccounting()
  829. {
  830. const WCHAR AccountingPath[] =
  831. L"Root\0"
  832. L"Microsoft Internet Authentication Service\0"
  833. L"RequestHandlers\0"
  834. L"Microsoft Accounting\0";
  835. LONG AccountingIdentity;
  836. m_GlobalData.m_pObjects->WalkPath(AccountingPath, AccountingIdentity);
  837. _bstr_t MaxLogSize = m_GlobalData.m_pServiceConfiguration->GetMaxLogSize();
  838. _bstr_t LogFrequency = m_GlobalData.m_pServiceConfiguration->
  839. GetLogFrequency();
  840. _bstr_t PropertyName = L"New Log Frequency";
  841. m_GlobalData.m_pProperties->UpdateProperty(
  842. AccountingIdentity,
  843. PropertyName,
  844. VT_I4,
  845. LogFrequency
  846. );
  847. PropertyName = L"New Log Size";
  848. m_GlobalData.m_pProperties->UpdateProperty(
  849. AccountingIdentity,
  850. PropertyName,
  851. VT_I4,
  852. MaxLogSize
  853. );
  854. DWORD Value;
  855. m_Utils.NewGetAuthSrvParameter(L"LogAuthentications", Value);
  856. _bstr_t LogAuth;
  857. Value ? LogAuth = L"-1": LogAuth = L"0";
  858. PropertyName = L"Log Authentication Packets";
  859. m_GlobalData.m_pProperties->UpdateProperty(
  860. AccountingIdentity,
  861. PropertyName,
  862. VT_BOOL,
  863. LogAuth
  864. );
  865. m_Utils.NewGetAuthSrvParameter(L"LogAccounting", Value);
  866. _bstr_t LogAcct;
  867. Value ? LogAcct = L"-1": LogAcct = L"0";
  868. PropertyName = L"Log Accounting Packets";
  869. m_GlobalData.m_pProperties->UpdateProperty(
  870. AccountingIdentity,
  871. PropertyName,
  872. VT_BOOL,
  873. LogAcct
  874. );
  875. _bstr_t FormatIAS1 = L"0";
  876. PropertyName = L"Log Format";
  877. m_GlobalData.m_pProperties->UpdateProperty(
  878. AccountingIdentity,
  879. PropertyName,
  880. VT_I4,
  881. FormatIAS1
  882. );
  883. }
  884. //////////////////////////////////////////////////////////////////////////////
  885. // NewMigrateEventLog
  886. //////////////////////////////////////////////////////////////////////////////
  887. void CMigrateMdb::NewMigrateEventLog()
  888. {
  889. const WCHAR EventLogPath[] =
  890. L"Root\0"
  891. L"Microsoft Internet Authentication Service\0"
  892. L"Auditors\0"
  893. L"Microsoft NT Event Log Auditor\0";
  894. LONG EventLogIdentity;
  895. m_GlobalData.m_pObjects->WalkPath(EventLogPath, EventLogIdentity);
  896. DWORD Value;
  897. m_Utils.NewGetAuthSrvParameter(L"LogData", Value);
  898. _bstr_t LogData;
  899. Value ? LogData = L"-1": LogData = L"0";
  900. _bstr_t PropertyName = L"Log Verbose";
  901. m_GlobalData.m_pProperties->UpdateProperty(
  902. EventLogIdentity,
  903. PropertyName,
  904. VT_BOOL,
  905. LogData
  906. );
  907. m_Utils.NewGetAuthSrvParameter(L"LogBogus", Value);
  908. _bstr_t LogBogus;
  909. Value ? LogBogus = L"-1": LogBogus = L"0";
  910. PropertyName = L"Log Malformed Packets";
  911. m_GlobalData.m_pProperties->UpdateProperty(
  912. EventLogIdentity,
  913. PropertyName,
  914. VT_BOOL,
  915. LogBogus
  916. );
  917. }
  918. //////////////////////////////////////////////////////////////////////////////
  919. // NewMigrateService
  920. //////////////////////////////////////////////////////////////////////////////
  921. void CMigrateMdb::NewMigrateService()
  922. {
  923. const LONG PORT_SIZE_MAX = 34;
  924. const WCHAR ServicePath[] =
  925. L"Root\0"
  926. L"Microsoft Internet Authentication Service\0"
  927. L"Protocols\0"
  928. L"Microsoft Radius Protocol\0";
  929. LONG ServiceIdentity;
  930. m_GlobalData.m_pObjects->WalkPath(ServicePath, ServiceIdentity);
  931. DWORD Value;
  932. m_Utils.NewGetAuthSrvParameter(L"RadiusPort", Value);
  933. WCHAR TempString[PORT_SIZE_MAX];
  934. _bstr_t RadiusPort = _ultow(Value, TempString, 10);
  935. _bstr_t PropertyName = L"Authentication Port";
  936. m_GlobalData.m_pProperties->UpdateProperty(
  937. ServiceIdentity,
  938. PropertyName,
  939. VT_BSTR,
  940. RadiusPort
  941. );
  942. m_Utils.NewGetAuthSrvParameter(L"AcctPort", Value);
  943. _bstr_t AcctPort = _ltow(Value, TempString, 10);
  944. PropertyName = L"Accounting Port";
  945. m_GlobalData.m_pProperties->UpdateProperty(
  946. ServiceIdentity,
  947. PropertyName,
  948. VT_BSTR,
  949. AcctPort
  950. );
  951. }
  952. //////////////////////////////////////////////////////////////////////////////
  953. // NewMigrate
  954. //////////////////////////////////////////////////////////////////////////////
  955. void CMigrateMdb::NewMigrate()
  956. {
  957. NewMigrateClients();
  958. if ( !m_Utils.IsNT4Corp() ) // it's either Win2k or NT4 ISP
  959. {
  960. // the proxy servers must be migrated before the policies and
  961. // profiles
  962. MigrateProxyServers();
  963. }
  964. NewMigrateProfiles();
  965. NewMigrateAccounting();
  966. NewMigrateEventLog();
  967. NewMigrateService();
  968. /////////////////////////////
  969. // Migrate the Registry Keys
  970. /////////////////////////////
  971. CMigrateRegistry MigrateRegistry(m_Utils);
  972. MigrateRegistry.MigrateProviders();
  973. //////////////////////////////////////////////////////
  974. // Update the MSChap Authentication types (password)
  975. //////////////////////////////////////////////////////
  976. CUpdateMSCHAP UpdateMSCHAP(m_GlobalData);
  977. UpdateMSCHAP.Execute();
  978. }