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.

697 lines
27 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright(C) 2000 Microsoft Corporation all rights reserved.
  4. //
  5. // Module: migratecontent.cpp
  6. //
  7. // Project: Windows 2000 IAS
  8. //
  9. // Description: Win2k and early Whistler DB to Whistler DB Migration
  10. //
  11. // Author: tperraut 06/08/2000
  12. //
  13. // Revision
  14. //
  15. /////////////////////////////////////////////////////////////////////////////
  16. #include "stdafx.h"
  17. #include "GlobalData.h"
  18. #include "migratecontent.h"
  19. #include "Objects.h"
  20. #include "Properties.h"
  21. #include "updatemschap.h"
  22. //////////////////////////////////////////////////////////////////////////////
  23. // CopyTree
  24. //
  25. // Param:
  26. // - the Id in the Reference (Ref) database: place to read from (iasold.mdb)
  27. // - the parent of that same node but in the Standard (Std) database:
  28. // the place to write to (ias.mdb)
  29. //
  30. //////////////////////////////////////////////////////////////////////////////
  31. HRESULT CMigrateContent::CopyTree(LONG RefId, LONG ParentParam)
  32. {
  33. /////////////////////////////////////////
  34. // get the name and Parent in the Ref DB
  35. /////////////////////////////////////////
  36. _bstr_t Name;
  37. LONG Parent;
  38. HRESULT hr = m_GlobalData.m_pRefObjects->GetObjectIdentity(
  39. Name,
  40. Parent,
  41. RefId
  42. );
  43. if ( FAILED(hr) )
  44. {
  45. return hr;
  46. }
  47. ///////////////////////////////////////////////////////
  48. // insert the object (gives an Identity) in the Std DB
  49. ///////////////////////////////////////////////////////
  50. LONG NewIdentity;
  51. BOOL InsertOk = m_GlobalData.m_pObjects->InsertObject(
  52. Name,
  53. ParentParam,
  54. NewIdentity
  55. );
  56. if ( !InsertOk )
  57. {
  58. ///////////////////////////////////////////////
  59. // the object already exists don't do anything
  60. ///////////////////////////////////////////////
  61. return S_OK;
  62. }
  63. _bstr_t PropertyName;
  64. _bstr_t StrVal;
  65. LONG Type;
  66. /////////////////////////////////////////////////////////////////
  67. // Copy the properties of that object from the Ref to the Std DB
  68. /////////////////////////////////////////////////////////////////
  69. hr = m_GlobalData.m_pRefProperties->GetProperty(
  70. RefId,
  71. PropertyName,
  72. Type,
  73. StrVal
  74. );
  75. LONG IndexProperty = 1;
  76. while ( hr == S_OK )
  77. {
  78. m_GlobalData.m_pProperties->InsertProperty(
  79. NewIdentity,
  80. PropertyName,
  81. Type,
  82. StrVal
  83. );
  84. hr = m_GlobalData.m_pRefProperties->GetNextProperty(
  85. RefId,
  86. PropertyName,
  87. Type,
  88. StrVal,
  89. IndexProperty
  90. );
  91. ++IndexProperty;
  92. }
  93. // here safely ignore hr
  94. //////////////////////////////////////////////////////////
  95. // get all the childs of the object in the Ref DB (RefId)
  96. //////////////////////////////////////////////////////////
  97. _bstr_t ObjectName;
  98. LONG ObjectIdentity;
  99. hr = m_GlobalData.m_pRefObjects->GetObject(
  100. ObjectName,
  101. ObjectIdentity,
  102. RefId
  103. );
  104. LONG IndexObject = 1;
  105. while ( SUCCEEDED(hr) )
  106. {
  107. ///////////////////////////////////////////////////////////
  108. // and for each, call CopyTree(ChildIdentity, NewIdentity)
  109. ///////////////////////////////////////////////////////////
  110. hr = CopyTree(ObjectIdentity, NewIdentity);
  111. if ( FAILED(hr) ){return hr;}
  112. hr = m_GlobalData.m_pRefObjects->GetNextObject(
  113. ObjectName,
  114. ObjectIdentity,
  115. RefId,
  116. IndexObject
  117. );
  118. ++IndexObject;
  119. }
  120. ///////////////////////////////////////////////
  121. // if no child: return S_Ok. hr safely ignored
  122. ///////////////////////////////////////////////
  123. return S_OK;
  124. }
  125. //////////////////////////////////////////////////////////////////////////////
  126. // MigrateXXX functions
  127. // Description:
  128. // These functions follow the same model:
  129. // - Get the ID of a container in iasold.mdb
  130. // - Get the ID of the same container in ias.mdb
  131. // - Get the ID of that container's parent in ias.mdb
  132. // - Recursively deletes the container in ias.mdb
  133. // - Then copy the content of that container from iasold.mdb into ias.mdb
  134. // using the parent's container as the place to attach the result.
  135. //
  136. // Some functions also update some specific properties without doing
  137. // a full copy
  138. //
  139. //////////////////////////////////////////////////////////////////////////////
  140. //////////////////////////////////////////////////////////////////////////////
  141. // MigrateClients
  142. //////////////////////////////////////////////////////////////////////////////
  143. void CMigrateContent::MigrateClients()
  144. {
  145. const WCHAR ClientPath[] = L"Root\0"
  146. L"Microsoft Internet Authentication Service\0"
  147. L"Protocols\0"
  148. L"Microsoft Radius Protocol\0"
  149. L"Clients\0";
  150. LONG ClientIdentity;
  151. m_GlobalData.m_pRefObjects->WalkPath(ClientPath, ClientIdentity);
  152. const WCHAR RadiusProtocolPath[] =
  153. L"Root\0"
  154. L"Microsoft Internet Authentication Service\0"
  155. L"Protocols\0"
  156. L"Microsoft Radius Protocol\0";
  157. LONG RadiusProtocolIdentity;
  158. m_GlobalData.m_pObjects->WalkPath(
  159. RadiusProtocolPath,
  160. RadiusProtocolIdentity
  161. );
  162. // delete the clients container and its content
  163. LONG DestClientIdentity;
  164. m_GlobalData.m_pObjects->WalkPath(ClientPath, DestClientIdentity);
  165. _com_util::CheckError(m_GlobalData.m_pObjects->DeleteObject(
  166. DestClientIdentity));
  167. // for each client in src, copy it in dest with its properties.
  168. _com_util::CheckError(CopyTree(ClientIdentity, RadiusProtocolIdentity));
  169. }
  170. //////////////////////////////////////////////////////////////////////////////
  171. // MigrateProfilesPolicies
  172. //////////////////////////////////////////////////////////////////////////////
  173. void CMigrateContent::MigrateProfilesPolicies()
  174. {
  175. const WCHAR ProfilesPath[] =
  176. L"Root\0"
  177. L"Microsoft Internet Authentication Service\0"
  178. L"RadiusProfiles\0";
  179. LONG DestProfilesIdentity;
  180. m_GlobalData.m_pObjects->WalkPath(ProfilesPath, DestProfilesIdentity);
  181. const WCHAR PoliciesPath[] =
  182. L"Root\0"
  183. L"Microsoft Internet Authentication Service\0"
  184. L"NetworkPolicy\0";
  185. LONG DestPoliciesIdentity;
  186. m_GlobalData.m_pObjects->WalkPath(PoliciesPath, DestPoliciesIdentity);
  187. // Delete the profiles and policies containers from ias.mdb
  188. _com_util::CheckError(m_GlobalData.m_pObjects->DeleteObject(
  189. DestProfilesIdentity));
  190. _com_util::CheckError(m_GlobalData.m_pObjects->DeleteObject(
  191. DestPoliciesIdentity));
  192. // default profiles and policies deleted from now on
  193. LONG ProfilesIdentity;
  194. m_GlobalData.m_pRefObjects->WalkPath(ProfilesPath, ProfilesIdentity);
  195. LONG PoliciesIdentity;
  196. m_GlobalData.m_pRefObjects->WalkPath(PoliciesPath, PoliciesIdentity);
  197. const WCHAR IASPath[] = L"Root\0"
  198. L"Microsoft Internet Authentication Service\0";
  199. LONG IASIdentity;
  200. m_GlobalData.m_pObjects->WalkPath(IASPath, IASIdentity);
  201. // for each profiles and policies in iasold.mdb,
  202. // copy it in dest with its properties.
  203. _com_util::CheckError(CopyTree(ProfilesIdentity, IASIdentity));
  204. _com_util::CheckError(CopyTree(PoliciesIdentity, IASIdentity));
  205. }
  206. //////////////////////////////////////////////////////////////////////////////
  207. // MigrateProxyProfilesPolicies
  208. //////////////////////////////////////////////////////////////////////////////
  209. void CMigrateContent::MigrateProxyProfilesPolicies()
  210. {
  211. const WCHAR ProfilesPath[] =
  212. L"Root\0"
  213. L"Microsoft Internet Authentication Service\0"
  214. L"Proxy Profiles\0";
  215. LONG DestProfilesIdentity;
  216. m_GlobalData.m_pObjects->WalkPath(ProfilesPath, DestProfilesIdentity);
  217. const WCHAR PoliciesPath[] =
  218. L"Root\0"
  219. L"Microsoft Internet Authentication Service\0"
  220. L"Proxy Policies\0";
  221. LONG DestPoliciesIdentity;
  222. m_GlobalData.m_pObjects->WalkPath(PoliciesPath, DestPoliciesIdentity);
  223. // Delete the profiles and policies containers from ias.mdb
  224. _com_util::CheckError(m_GlobalData.m_pObjects->DeleteObject(
  225. DestProfilesIdentity));
  226. _com_util::CheckError(m_GlobalData.m_pObjects->DeleteObject(
  227. DestPoliciesIdentity));
  228. // default profiles and policies deleted from now on
  229. LONG ProfilesIdentity;
  230. m_GlobalData.m_pRefObjects->WalkPath(ProfilesPath, ProfilesIdentity);
  231. LONG PoliciesIdentity;
  232. m_GlobalData.m_pRefObjects->WalkPath(PoliciesPath, PoliciesIdentity);
  233. const WCHAR IASPath[] = L"Root\0"
  234. L"Microsoft Internet Authentication Service\0";
  235. LONG IASIdentity;
  236. m_GlobalData.m_pObjects->WalkPath(IASPath, IASIdentity);
  237. // for each profiles and policies in iasold.mdb,
  238. // copy it in dest with its properties.
  239. _com_util::CheckError(CopyTree(ProfilesIdentity, IASIdentity));
  240. _com_util::CheckError(CopyTree(PoliciesIdentity, IASIdentity));
  241. }
  242. //////////////////////////////////////////////////////////////////////////////
  243. // MigrateAccounting
  244. //////////////////////////////////////////////////////////////////////////////
  245. void CMigrateContent::MigrateAccounting()
  246. {
  247. const WCHAR AccountingPath[] =
  248. L"Root\0"
  249. L"Microsoft Internet Authentication Service\0"
  250. L"RequestHandlers\0"
  251. L"Microsoft Accounting\0";
  252. LONG AccountingIdentity;
  253. m_GlobalData.m_pRefObjects->WalkPath(AccountingPath, AccountingIdentity);
  254. const WCHAR RequestHandlerPath[] =
  255. L"Root\0"
  256. L"Microsoft Internet Authentication Service\0"
  257. L"RequestHandlers\0";
  258. LONG RequestHandlerIdentity;
  259. m_GlobalData.m_pObjects->WalkPath(
  260. RequestHandlerPath,
  261. RequestHandlerIdentity
  262. );
  263. // delete the Accounting container and its content in ias.mdb
  264. LONG DestAccountingIdentity;
  265. m_GlobalData.m_pObjects->WalkPath(
  266. AccountingPath,
  267. DestAccountingIdentity
  268. );
  269. _com_util::CheckError(m_GlobalData.m_pObjects->DeleteObject(
  270. DestAccountingIdentity));
  271. // for each accounting in src, copy it in dest with its properties.
  272. _com_util::CheckError(CopyTree(
  273. AccountingIdentity,
  274. RequestHandlerIdentity
  275. ));
  276. }
  277. //////////////////////////////////////////////////////////////////////////////
  278. // MigrateEventLog
  279. //////////////////////////////////////////////////////////////////////////////
  280. void CMigrateContent::MigrateEventLog()
  281. {
  282. const WCHAR EventLogPath[] = L"Root\0"
  283. L"Microsoft Internet Authentication Service\0"
  284. L"Auditors\0"
  285. L"Microsoft NT Event Log Auditor\0";
  286. LONG EventLogIdentity;
  287. m_GlobalData.m_pRefObjects->WalkPath(EventLogPath, EventLogIdentity);
  288. const WCHAR AuditorsPath[] = L"Root\0"
  289. L"Microsoft Internet Authentication Service\0"
  290. L"Auditors\0";
  291. LONG AuditorsIdentity;
  292. m_GlobalData.m_pObjects->WalkPath(AuditorsPath, AuditorsIdentity);
  293. // delete the Auditors container and its content in ias.mdb
  294. LONG DestEventLogIdentity;
  295. m_GlobalData.m_pObjects->WalkPath(EventLogPath, DestEventLogIdentity);
  296. _com_util::CheckError(m_GlobalData.m_pObjects->DeleteObject(
  297. DestEventLogIdentity));
  298. // for each EventLog in src, copy it in dest with its properties.
  299. _com_util::CheckError(CopyTree(EventLogIdentity, AuditorsIdentity));
  300. }
  301. //////////////////////////////////////////////////////////////////////////////
  302. // MigrateService
  303. //////////////////////////////////////////////////////////////////////////////
  304. void CMigrateContent::MigrateService()
  305. {
  306. const LONG PORT_SIZE_MAX = 34;
  307. const WCHAR ServicePath[] = L"Root\0"
  308. L"Microsoft Internet Authentication Service\0"
  309. L"Protocols\0"
  310. L"Microsoft Radius Protocol\0";
  311. LONG RefServiceIdentity;
  312. m_GlobalData.m_pRefObjects->WalkPath(ServicePath, RefServiceIdentity);
  313. LONG DestServiceIdentity;
  314. m_GlobalData.m_pObjects->WalkPath(ServicePath, DestServiceIdentity);
  315. _bstr_t PropertyName = L"Authentication Port";
  316. _bstr_t RadiusPort;
  317. LONG Type = 0;
  318. m_GlobalData.m_pRefProperties->GetPropertyByName(
  319. RefServiceIdentity,
  320. PropertyName,
  321. Type,
  322. RadiusPort
  323. );
  324. if ( Type != VT_BSTR )
  325. {
  326. _com_issue_error(E_UNEXPECTED);
  327. }
  328. m_GlobalData.m_pProperties->UpdateProperty(
  329. DestServiceIdentity,
  330. PropertyName,
  331. VT_BSTR,
  332. RadiusPort
  333. );
  334. _bstr_t AcctPort;
  335. PropertyName = L"Accounting Port";
  336. Type = 0;
  337. m_GlobalData.m_pRefProperties->GetPropertyByName(
  338. RefServiceIdentity,
  339. PropertyName,
  340. Type,
  341. AcctPort
  342. );
  343. if ( Type != VT_BSTR )
  344. {
  345. _com_issue_error(E_UNEXPECTED);
  346. }
  347. m_GlobalData.m_pProperties->UpdateProperty(
  348. DestServiceIdentity,
  349. PropertyName,
  350. VT_BSTR,
  351. AcctPort
  352. );
  353. // Now update the service description (name)
  354. const WCHAR IASPath[] =
  355. L"Root\0"
  356. L"Microsoft Internet Authentication Service\0";
  357. LONG RefIASIdentity;
  358. m_GlobalData.m_pRefObjects->WalkPath(IASPath, RefIASIdentity);
  359. LONG DestIASIdentity;
  360. m_GlobalData.m_pObjects->WalkPath(IASPath, DestIASIdentity);
  361. PropertyName = L"Description";
  362. _bstr_t Description;
  363. Type = 0;
  364. m_GlobalData.m_pRefProperties->GetPropertyByName(
  365. RefIASIdentity,
  366. PropertyName,
  367. Type,
  368. Description
  369. );
  370. if ( Type != VT_BSTR )
  371. {
  372. _com_issue_error(E_UNEXPECTED);
  373. }
  374. m_GlobalData.m_pProperties->UpdateProperty(
  375. DestIASIdentity,
  376. PropertyName,
  377. VT_BSTR,
  378. Description
  379. );
  380. }
  381. //////////////////////////////////////////////////////////////////////////////
  382. // MigrateWin2kRealms
  383. //
  384. // Not used: msUserIdentityAlgorithm
  385. // msManipulationRule
  386. // msManipulationTarget (enum: 1, 30 or 31)
  387. //////////////////////////////////////////////////////////////////////////////
  388. void CMigrateContent::MigrateWin2kRealms()
  389. {
  390. const WCHAR DEFAULT_REALM_TARGET[] = L"1";
  391. const int MAX_LONG_SIZE = 32;
  392. /////////////////////////////////////////////////
  393. // Get the Microsoft Realms Evaluator's Identity
  394. /////////////////////////////////////////////////
  395. LPCWSTR RealmPath = L"Root\0"
  396. L"Microsoft Internet Authentication Service\0"
  397. L"RequestHandlers\0"
  398. L"Microsoft Realms Evaluator\0";
  399. LONG RealmIdentity;
  400. m_GlobalData.m_pRefObjects->WalkPath(RealmPath, RealmIdentity);
  401. ///////////////////////////////////////////////
  402. // Get the Proxy Profiles container's Identity
  403. ///////////////////////////////////////////////
  404. LPCWSTR ProxyProfilePath =
  405. L"Root\0"
  406. L"Microsoft Internet Authentication Service\0"
  407. L"Proxy Profiles\0";
  408. LONG ProxyContainerIdentity;
  409. m_GlobalData.m_pObjects->WalkPath(
  410. ProxyProfilePath,
  411. ProxyContainerIdentity
  412. );
  413. //////////////////////////////////////////////////////////////////////
  414. // Now get the first Object with the above container as parent.
  415. // this is the default proxy profile (it's localized: I can't search
  416. // for the name directly).
  417. //////////////////////////////////////////////////////////////////////
  418. _bstr_t ObjectName;
  419. LONG ProxyProfileIdentity;
  420. HRESULT hr = m_GlobalData.m_pObjects->GetObject(
  421. ObjectName,
  422. ProxyProfileIdentity,
  423. ProxyContainerIdentity
  424. );
  425. _com_util::CheckError(hr);
  426. _bstr_t PropertyName;
  427. LONG Type;
  428. _bstr_t StrVal;
  429. //////////////////////////
  430. // get all the properties
  431. //////////////////////////
  432. _com_util::CheckError(m_GlobalData.m_pRefProperties->GetProperty(
  433. RealmIdentity,
  434. PropertyName,
  435. Type,
  436. StrVal
  437. ));
  438. LONG IndexProperty = 1;
  439. LONG NbPropertiesInserted = 0;
  440. _bstr_t NewName = L"msManipulationRule";
  441. while ( hr == S_OK )
  442. {
  443. /////////////////////////////////////////
  444. // for each, if Name == L"Realms"
  445. // then add to the default proxy profile
  446. /////////////////////////////////////////
  447. if ( !lstrcmpiW(PropertyName, L"Realms") )
  448. {
  449. m_GlobalData.m_pProperties->InsertProperty(
  450. ProxyProfileIdentity,
  451. NewName,
  452. Type,
  453. StrVal
  454. );
  455. ++NbPropertiesInserted;
  456. }
  457. hr = m_GlobalData.m_pRefProperties->GetNextProperty(
  458. RealmIdentity,
  459. PropertyName,
  460. Type,
  461. StrVal,
  462. IndexProperty
  463. );
  464. ++IndexProperty;
  465. };
  466. hr = S_OK;
  467. ////////////////////////////////////////////////////////////////
  468. // Check that an even number of msManipulationRule was inserted
  469. ////////////////////////////////////////////////////////////////
  470. if ( (NbPropertiesInserted % 2) )
  471. {
  472. /////////////////////////
  473. // Inconsistent database
  474. /////////////////////////
  475. _com_issue_error(E_FAIL);
  476. }
  477. //////////////////////////////////////////
  478. // No realm migrated: nothing else to set.
  479. //////////////////////////////////////////
  480. if ( !NbPropertiesInserted )
  481. {
  482. return;
  483. }
  484. /////////////////////////////////////
  485. // Now process the reg keys settings
  486. /////////////////////////////////////
  487. BOOL OverRide = m_Utils.OverrideUserNameSet();
  488. DWORD IdentityAtt = m_Utils.GetUserIdentityAttribute();
  489. BOOL UserIdentSet = m_Utils.UserIdentityAttributeSet();
  490. if ( (IdentityAtt != 1) && (!OverRide) )
  491. {
  492. // log a warning / error for the user?
  493. // the new behavior will not be exactly the same as before
  494. }
  495. //////////////////////////////////////////////////
  496. // insert the UserIdentityAttribute if it was set.
  497. //////////////////////////////////////////////////
  498. _bstr_t TargetName = L"msManipulationTarget";
  499. _bstr_t TargetStrVal;
  500. if ( UserIdentSet )
  501. {
  502. WCHAR TempString[MAX_LONG_SIZE];
  503. _ltow(IdentityAtt, TempString, 10); // base 10 will never change
  504. // Add the msManipulationTarget Property based on the reg key
  505. // "SYSTEM\\CurrentControlSet\\Services\\RemoteAccess\\Policy";
  506. // "User Identity Attribute"; // Attribute used to identify the user.
  507. // If not set then default to RADIUS_ATTRIBUTE_USER_NAME
  508. // (1: "User-Name")
  509. TargetStrVal = TempString;
  510. }
  511. else
  512. {
  513. // Not set in the registry: write the default
  514. TargetStrVal = DEFAULT_REALM_TARGET;
  515. }
  516. m_GlobalData.m_pProperties->InsertProperty(
  517. ProxyProfileIdentity,
  518. TargetName,
  519. VT_I4,
  520. TargetStrVal
  521. );
  522. }
  523. //////////////////////////////////////////////////////////////////////////////
  524. // MigrateServerGroups
  525. //////////////////////////////////////////////////////////////////////////////
  526. void CMigrateContent::MigrateServerGroups()
  527. {
  528. const WCHAR SvrGroupPath[] =
  529. L"Root\0"
  530. L"Microsoft Internet Authentication Service\0"
  531. L"RADIUS Server Groups\0";
  532. LONG SvrGroupIdentity;
  533. m_GlobalData.m_pRefObjects->WalkPath(SvrGroupPath, SvrGroupIdentity);
  534. const WCHAR IASPath[] = L"Root\0"
  535. L"Microsoft Internet Authentication Service\0";
  536. LONG IASIdentity;
  537. m_GlobalData.m_pObjects->WalkPath(IASPath, IASIdentity);
  538. // delete the SvrGroups container and its content
  539. LONG DestSvrGroupIdentity;
  540. m_GlobalData.m_pObjects->WalkPath(SvrGroupPath, DestSvrGroupIdentity);
  541. _com_util::CheckError(m_GlobalData.m_pObjects->DeleteObject(
  542. DestSvrGroupIdentity));
  543. // for each SvrGroup in src, copy it in dest with its properties.
  544. _com_util::CheckError(CopyTree(SvrGroupIdentity, IASIdentity));
  545. }
  546. //////////////////////////////////////////////////////////////////////////////
  547. // Migrate
  548. // migrate the content of a Win2k or Whistler DB before the proxy feature
  549. // into a whistler DB.
  550. //////////////////////////////////////////////////////////////////////////////
  551. void CMigrateContent::Migrate()
  552. {
  553. MigrateClients();
  554. MigrateProfilesPolicies();
  555. MigrateAccounting();
  556. MigrateEventLog();
  557. MigrateService();
  558. MigrateWin2kRealms();
  559. //////////////////////////////////////////////////////
  560. // Update the MSChap Authentication types (password)
  561. //////////////////////////////////////////////////////
  562. CUpdateMSCHAP UpdateMSCHAP(m_GlobalData);
  563. UpdateMSCHAP.Execute();
  564. }
  565. //////////////////////////////////////////////////////////////////////////////
  566. // UpdateWhistler
  567. // migrate the content from a Whistler DB to a whistler DB.
  568. // This is used by the netshell aaaa context
  569. //////////////////////////////////////////////////////////////////////////////
  570. void CMigrateContent::UpdateWhistler(const bool UpdateChapPasswords)
  571. {
  572. MigrateClients();
  573. MigrateProfilesPolicies();
  574. MigrateAccounting();
  575. MigrateEventLog();
  576. MigrateService();
  577. MigrateProxyProfilesPolicies();
  578. MigrateServerGroups();
  579. if (UpdateChapPasswords)
  580. {
  581. //////////////////////////////////////////////////////
  582. // Update the MSChap Authentication types (password)
  583. //////////////////////////////////////////////////////
  584. CUpdateMSCHAP UpdateMSCHAP(m_GlobalData);
  585. UpdateMSCHAP.Execute();
  586. }
  587. }