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.

925 lines
24 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. #include <stdafx.h>
  6. #include <sdoias.h>
  7. #include "raputil.h"
  8. //////////
  9. // Extract an interface pointer from a VARIANT struct.
  10. //////////
  11. HRESULT
  12. GetInterfaceFromVariant(
  13. IN VARIANT *var,
  14. IN REFIID riid,
  15. OUT PVOID *ppv
  16. )
  17. {
  18. HRESULT hr;
  19. // Check the parameters.
  20. if (!var || !ppv) { return E_POINTER; }
  21. // Switch based on the VARIANT type.
  22. switch (V_VT(var))
  23. {
  24. case VT_UNKNOWN:
  25. hr = V_UNKNOWN(var)->QueryInterface(riid, ppv);
  26. break;
  27. case VT_DISPATCH:
  28. hr = V_DISPATCH(var)->QueryInterface(riid, ppv);
  29. break;
  30. default:
  31. hr = DISP_E_TYPEMISMATCH;
  32. }
  33. return hr;
  34. }
  35. //////////
  36. // Removes an integer value from a SAFEARRAY of VARIANTs.
  37. //////////
  38. HRESULT
  39. RemoveIntegerFromArray(
  40. IN VARIANT* array,
  41. IN LONG value
  42. )
  43. {
  44. VARIANT *begin, *end, *i;
  45. // Check the parameters.
  46. if (!array)
  47. {
  48. return E_POINTER;
  49. }
  50. else if (V_VT(array) == VT_EMPTY)
  51. {
  52. // If the VARIANT is empty, then the value doesn't exists, so there's
  53. // nothing to do.
  54. return S_OK;
  55. }
  56. else if (V_VT(array) != (VT_ARRAY | VT_VARIANT))
  57. {
  58. // The VARIANT doesn't contain a SAFEARRAY of VARIANTs.
  59. return DISP_E_TYPEMISMATCH;
  60. }
  61. // Compute the beginning and end of the array data.
  62. begin = (VARIANT*)V_ARRAY(array)->pvData;
  63. end = begin + V_ARRAY(array)->rgsabound[0].cElements;
  64. // Search for the value to be removed.
  65. for (i = begin; i != end && V_I4(i) != value; ++i)
  66. {
  67. if (V_VT(i) == VT_I4 && V_I4(i) == value)
  68. {
  69. // We found a match, so remove it from the array ...
  70. memmove(i, i + 1, ((end - i) - 1) * sizeof(VARIANT));
  71. // ... and decrement the number of elements.
  72. --(V_ARRAY(array)->rgsabound[0].cElements);
  73. // We don't allow duplicates, so we're done.
  74. break;
  75. }
  76. }
  77. return S_OK;
  78. }
  79. //////////
  80. // Adds an integer value to a SAFEARRAY of VARIANTs.
  81. //////////
  82. HRESULT
  83. AddIntegerToArray(
  84. IN VARIANT *array,
  85. IN LONG value
  86. )
  87. {
  88. ULONG nelem;
  89. VARIANT *begin, *end, *i;
  90. SAFEARRAY* psa;
  91. // Check the parameters.
  92. if (!array)
  93. {
  94. return E_POINTER;
  95. }
  96. else if (V_VT(array) == VT_EMPTY)
  97. {
  98. // The VARIANT is empty, so create a new array.
  99. psa = SafeArrayCreateVector(VT_VARIANT, 0, 1);
  100. if (!psa) { return E_OUTOFMEMORY; }
  101. // Set the value of the lone element.
  102. i = (VARIANT*)psa->pvData;
  103. V_VT(i) = VT_I4;
  104. V_I4(i) = value;
  105. // Store the SAFEARRAY in the VARIANT.
  106. V_VT(array) = (VT_ARRAY | VT_VARIANT);
  107. V_ARRAY(array) = psa;
  108. return S_OK;
  109. }
  110. else if (V_VT(array) != (VT_ARRAY | VT_VARIANT))
  111. {
  112. // The VARIANT doesn't contain a SAFEARRAY of VARIANTs.
  113. return DISP_E_TYPEMISMATCH;
  114. }
  115. // Compute the beginning and end of the array data.
  116. nelem = V_ARRAY(array)->rgsabound[0].cElements;
  117. begin = (VARIANT*)V_ARRAY(array)->pvData;
  118. end = begin + nelem;
  119. // See if the value already exists, ...
  120. for (i = begin; i != end; ++i)
  121. {
  122. if (V_I4(i) == value)
  123. {
  124. // ... and if it does, then there's nothing to do.
  125. return S_OK;
  126. }
  127. }
  128. // Create a new array with enough room for the new element.
  129. psa = SafeArrayCreateVector(VT_VARIANT, 0, nelem + 1);
  130. if (!psa) { return E_OUTOFMEMORY; }
  131. i = (VARIANT*)psa->pvData;
  132. // Copy in the old data.
  133. memcpy(i + 1, begin, nelem * sizeof(VARIANT));
  134. // Add the new element.
  135. V_VT(i) = VT_I4;
  136. V_I4(i) = value;
  137. // Destroy the old array ...
  138. SafeArrayDestroy(V_ARRAY(array));
  139. // ... and save the new one.
  140. V_ARRAY(array) = psa;
  141. return S_OK;
  142. }
  143. //////////
  144. // Create a machine SDO and attach to the local machine.
  145. //////////
  146. HRESULT
  147. OpenMachineSdo(
  148. IN LPWSTR wszMachineName,
  149. OUT ISdoMachine **ppMachine
  150. )
  151. {
  152. HRESULT hr;
  153. USES_CONVERSION;
  154. // Check the parameters.
  155. if (!ppMachine) { return E_POINTER; }
  156. // Create the SdoMachine object.
  157. hr = CoCreateInstance(
  158. CLSID_SdoMachine,
  159. NULL,
  160. CLSCTX_INPROC_SERVER,
  161. IID_ISdoMachine,
  162. (PVOID*)ppMachine
  163. );
  164. if (SUCCEEDED(hr))
  165. {
  166. // Attach to the local machine.
  167. BSTR bstrMachineName = W2BSTR(wszMachineName);
  168. hr = (*ppMachine)->Attach(bstrMachineName);
  169. if (FAILED(hr))
  170. {
  171. // We couldn't attach, so don't return the SDO to the caller.
  172. (*ppMachine)->Release();
  173. ppMachine = NULL;
  174. }
  175. SysFreeString(bstrMachineName);
  176. }
  177. return hr;
  178. }
  179. //////////
  180. // Given a machine SDO and a service name, retrieve the service SDO.
  181. //////////
  182. HRESULT
  183. OpenServiceSDO(
  184. IN ISdoMachine *pMachine,
  185. IN LPWSTR wszServiceName,
  186. OUT ISdo **ppService
  187. )
  188. {
  189. HRESULT hr;
  190. IUnknown* pUnk;
  191. BSTR bstrServiceName = NULL;
  192. // Create a BSTR for the service name
  193. bstrServiceName = SysAllocString(wszServiceName);
  194. if (bstrServiceName == NULL)
  195. return E_OUTOFMEMORY;
  196. // Check the parameters.
  197. if (!pMachine || !ppService) { return E_POINTER; }
  198. // Retrieve the service SDO ...
  199. hr = pMachine->GetServiceSDO(
  200. DATA_STORE_LOCAL,
  201. bstrServiceName,
  202. &pUnk
  203. );
  204. if (SUCCEEDED(hr))
  205. {
  206. // ... and query for the ISdo interface.
  207. hr = pUnk->QueryInterface(IID_ISdo, (PVOID*)ppService );
  208. pUnk->Release();
  209. }
  210. SysFreeString(bstrServiceName);
  211. return hr;
  212. }
  213. //////////
  214. // Given a machine SDO, retrieve the dictionary SDO.
  215. //////////
  216. HRESULT
  217. OpenDictionarySDO(
  218. IN ISdoMachine *pMachine,
  219. OUT ISdoDictionaryOld **ppDictionary
  220. )
  221. {
  222. HRESULT hr;
  223. IUnknown* pUnk;
  224. // Check the parameters.
  225. if (!ppDictionary) { return E_POINTER; }
  226. // Get the dictionary SDO ...
  227. hr = pMachine->GetDictionarySDO(&pUnk);
  228. if (SUCCEEDED(hr))
  229. {
  230. // ... and query for the ISdoDictionaryOld interface.
  231. hr = pUnk->QueryInterface(IID_ISdoDictionaryOld,
  232. (PVOID*)ppDictionary
  233. );
  234. pUnk->Release();
  235. }
  236. return hr;
  237. }
  238. //////////
  239. // Given a parent SDO, retrieve a child SDO with the given property ID.
  240. //////////
  241. HRESULT
  242. OpenChildObject(
  243. IN ISdo *pParent,
  244. IN LONG lProperty,
  245. IN REFIID riid,
  246. OUT PVOID *ppv
  247. )
  248. {
  249. HRESULT hr;
  250. VARIANT val;
  251. // Check the parameters.
  252. if (!pParent || !ppv) { return E_POINTER; }
  253. // ISdo::GetProperty requires the out parameters to be initialized.
  254. VariantInit(&val);
  255. // Get the property corresponding to the child object ...
  256. hr = pParent->GetProperty(
  257. lProperty,
  258. &val
  259. );
  260. if (SUCCEEDED(hr))
  261. {
  262. // ... and convert it to the desired interface.
  263. hr = GetInterfaceFromVariant(
  264. &val,
  265. riid,
  266. ppv
  267. );
  268. VariantClear(&val);
  269. }
  270. return hr;
  271. }
  272. //////////
  273. // Given a service SDO, retrieve the default profile. If more than one profile
  274. // exists, this function returns ERROR_NO_DEFAULT_PROFILE.
  275. //////////
  276. HRESULT
  277. GetDefaultProfile(
  278. IN ISdo* pService,
  279. OUT ISdo** ppProfile
  280. )
  281. {
  282. HRESULT hr;
  283. ISdoCollection* pProfiles;
  284. LONG count;
  285. ULONG ulCount;
  286. IUnknown* pUnk;
  287. IEnumVARIANT* pEnum;
  288. VARIANT val;
  289. // Check the parameters.
  290. if (!pService || !ppProfile) { return E_POINTER; }
  291. // Null this out, so we can safely release it on exit.
  292. pProfiles = NULL;
  293. do
  294. {
  295. // Get the profiles collection, which is a child of the service SDO.
  296. hr = OpenChildObject(
  297. pService,
  298. PROPERTY_IAS_PROFILES_COLLECTION,
  299. IID_ISdoCollection,
  300. (PVOID*)&pProfiles
  301. );
  302. if (FAILED(hr)) { break; }
  303. // How many profiles are there?
  304. hr = pProfiles->get_Count(
  305. &count
  306. );
  307. if (FAILED(hr)) { break; }
  308. // If there's more than one, then there's no default.
  309. if (count != 1)
  310. {
  311. hr = ERROR_NO_DEFAULT_PROFILE;
  312. break;
  313. }
  314. // Get an enumerator for the collection.
  315. hr = pProfiles->get__NewEnum(
  316. &pUnk
  317. );
  318. if (FAILED(hr)) { break; }
  319. hr = pUnk->QueryInterface(
  320. IID_IEnumVARIANT,
  321. (PVOID*)&pEnum
  322. );
  323. pUnk->Release();
  324. if (FAILED(hr)) { break; }
  325. // Get the first (and only) object in the collection.
  326. VariantInit(&val);
  327. hr = pEnum->Next(
  328. 1,
  329. &val,
  330. &ulCount
  331. );
  332. if (SUCCEEDED(hr))
  333. {
  334. if (ulCount == 1)
  335. {
  336. // Get the ISdo interface for the default profile.
  337. hr = GetInterfaceFromVariant(
  338. &val,
  339. IID_ISdo,
  340. (PVOID*)ppProfile
  341. );
  342. VariantClear(&val);
  343. }
  344. else
  345. {
  346. // This should never happen since we already checked the count.
  347. hr = ERROR_NO_DEFAULT_PROFILE;
  348. }
  349. pEnum->Release();
  350. }
  351. } while (FALSE);
  352. // Release the Profiles collection.
  353. if (pProfiles) { pProfiles->Release(); }
  354. return hr;
  355. }
  356. //////////
  357. // Get a particular attribute SDO from the collection. If the attribute doesn't
  358. // exist and pDictionary is non-NULL, then a new attribute will be created.
  359. //////////
  360. HRESULT
  361. GetAttribute(
  362. IN ISdoCollection *pAttributes,
  363. IN OPTIONAL ISdoDictionaryOld *pDictionary,
  364. IN PCWSTR wszName,
  365. OUT ISdo **ppAttribute
  366. )
  367. {
  368. HRESULT hr;
  369. VARIANT key;
  370. IDispatch* pDisp;
  371. ATTRIBUTEID attrId;
  372. // Check the parameters
  373. if (!pAttributes || !ppAttribute) { return E_POINTER; }
  374. // Create a VARIANT key to look up the attribute.
  375. VariantInit(&key);
  376. V_VT(&key) = VT_BSTR;
  377. V_BSTR(&key) = SysAllocString(wszName);
  378. if (!V_BSTR(&key)) { return E_OUTOFMEMORY; }
  379. // Retrieve the desired attribute.
  380. hr = pAttributes->Item(
  381. &key,
  382. &pDisp
  383. );
  384. // If it doesn't exist and me have a dictionary, create a new attribute.
  385. if (hr == DISP_E_MEMBERNOTFOUND && pDictionary)
  386. {
  387. // Look up the attribute ID.
  388. hr = pDictionary->GetAttributeID(
  389. V_BSTR(&key),
  390. &attrId
  391. );
  392. if (SUCCEEDED(hr))
  393. {
  394. // Create an attribute SDO.
  395. hr = pDictionary->CreateAttribute(
  396. attrId,
  397. &pDisp
  398. );
  399. if (SUCCEEDED(hr))
  400. {
  401. // Add it to the attributes collection.
  402. hr = pAttributes->Add(
  403. V_BSTR(&key),
  404. &pDisp
  405. );
  406. if (FAILED(hr))
  407. {
  408. // If we couldn't add it, then release the object.
  409. pDisp->Release();
  410. }
  411. }
  412. }
  413. }
  414. // If we successfully retrieved or created an attribute, then get it's
  415. // ISdo interface.
  416. if (SUCCEEDED(hr))
  417. {
  418. hr = pDisp->QueryInterface(
  419. IID_ISdo,
  420. (PVOID*)ppAttribute
  421. );
  422. pDisp->Release();
  423. }
  424. // We're done with the key.
  425. VariantClear(&key);
  426. return hr;
  427. }
  428. //////////
  429. // Sets/Adds a single-valued integer attribute in a profile.
  430. //////////
  431. HRESULT
  432. SetIntegerAttribute(
  433. IN ISdoCollection *pAttributes,
  434. IN OPTIONAL ISdoDictionaryOld *pDictionary,
  435. IN LPWSTR wszName,
  436. IN LONG lValue
  437. )
  438. {
  439. HRESULT hr;
  440. ISdo *pAttribute;
  441. VARIANT val;
  442. // Get the attribute SDO.
  443. hr = GetAttribute(
  444. pAttributes,
  445. pDictionary,
  446. wszName,
  447. &pAttribute
  448. );
  449. if (SUCCEEDED(hr))
  450. {
  451. // Initialize the attribute value ...
  452. VariantInit(&val);
  453. V_VT(&val) = VT_I4;
  454. V_I4(&val) = lValue;
  455. // ... and set the value property.
  456. hr = pAttribute->PutProperty(
  457. PROPERTY_ATTRIBUTE_VALUE,
  458. &val
  459. );
  460. pAttribute->Release();
  461. }
  462. return hr;
  463. }
  464. HRESULT
  465. SetBooleanAttribute (
  466. IN ISdoCollection *pAttributes,
  467. IN OPTIONAL ISdoDictionaryOld *pDictionary,
  468. IN LPWSTR wszName,
  469. IN BOOL lValue
  470. )
  471. {
  472. HRESULT hr;
  473. ISdo *pAttribute;
  474. VARIANT val;
  475. // Get the attribute SDO.
  476. hr = GetAttribute(
  477. pAttributes,
  478. pDictionary,
  479. wszName,
  480. &pAttribute
  481. );
  482. if (SUCCEEDED(hr))
  483. {
  484. // Initialize the attribute value ...
  485. VariantInit(&val);
  486. V_VT(&val) = VT_BOOL;
  487. V_BOOL(&val) = (VARIANT_BOOL)lValue;
  488. // ... and set the value property.
  489. hr = pAttribute->PutProperty(
  490. PROPERTY_ATTRIBUTE_VALUE,
  491. &val
  492. );
  493. pAttribute->Release();
  494. }
  495. return hr;
  496. }
  497. HRESULT SetDialinSetting( IN ISdoCollection *pAttributes,
  498. IN OPTIONAL ISdoDictionaryOld *pDictionary,
  499. BOOL fDialinAllowed)
  500. {
  501. long ulCount;
  502. ULONG ulCountReceived;
  503. HRESULT hr = S_OK;
  504. CComBSTR bstr;
  505. CComPtr<IUnknown> spUnknown;
  506. CComPtr<IEnumVARIANT> spEnumVariant;
  507. CComPtr<ISdoDictionaryOld> spDictionarySdo(pDictionary);
  508. CComVariant var;
  509. //
  510. // get the attribute collection of this profile
  511. //
  512. CComPtr<ISdoCollection> spProfAttrCollectionSdo ( pAttributes );
  513. // We check the count of items in our collection and don't bother getting the
  514. // enumerator if the count is zero.
  515. // This saves time and also helps us to a void a bug in the the enumerator which
  516. // causes it to fail if we call next when it is empty.
  517. hr = spProfAttrCollectionSdo->get_Count( & ulCount );
  518. if ( FAILED(hr) )
  519. {
  520. return hr;
  521. }
  522. if ( ulCount > 0)
  523. {
  524. // Get the enumerator for the attribute collection.
  525. hr = spProfAttrCollectionSdo->get__NewEnum( (IUnknown **) & spUnknown );
  526. if ( FAILED(hr) )
  527. {
  528. return hr;
  529. }
  530. hr = spUnknown->QueryInterface( IID_IEnumVARIANT, (void **) &spEnumVariant );
  531. spUnknown.Release();
  532. if ( FAILED(hr) )
  533. {
  534. return hr;
  535. }
  536. // Get the first item.
  537. hr = spEnumVariant->Next( 1, &var, &ulCountReceived );
  538. while( SUCCEEDED( hr ) && ulCountReceived == 1 )
  539. {
  540. // Get an sdo pointer from the variant we received.
  541. CComPtr<ISdo> spSdo;
  542. hr = V_DISPATCH(&var)->QueryInterface( IID_ISdo, (void **) &spSdo );
  543. if ( !SUCCEEDED(hr))
  544. {
  545. return hr;
  546. }
  547. //
  548. // get attribute ID
  549. //
  550. var.Clear();
  551. hr = spSdo->GetProperty(PROPERTY_ATTRIBUTE_ID, &var);
  552. if ( !SUCCEEDED(hr) )
  553. {
  554. return hr;
  555. }
  556. DWORD dwAttrId = V_I4(&var);
  557. if ( dwAttrId == (DWORD)IAS_ATTRIBUTE_ALLOW_DIALIN )
  558. {
  559. // found this one in the profile, check for its value
  560. var.Clear();
  561. V_VT(&var) = VT_BOOL;
  562. V_BOOL(&var) = fDialinAllowed ? VARIANT_TRUE: VARIANT_FALSE ;
  563. hr = spSdo->PutProperty(PROPERTY_ATTRIBUTE_VALUE, &var);
  564. if ( !SUCCEEDED(hr) )
  565. {
  566. return hr;
  567. }
  568. return S_OK;
  569. }
  570. // Clear the variant of whatever it had --
  571. // this will release any data associated with it.
  572. var.Clear();
  573. // Get the next item.
  574. hr = spEnumVariant->Next( 1, &var, &ulCountReceived );
  575. if ( !SUCCEEDED(hr))
  576. {
  577. return hr;
  578. }
  579. } // while
  580. } // if
  581. // if we reach here, it means we either haven't found the attribute,
  582. // or the profile doesn't have anything in its attribute collection.
  583. if ( !fDialinAllowed )
  584. {
  585. // we don't need to do anything if dialin is allowed, becuase if this
  586. // attribute is not in the profile, then dialin is by default allowed
  587. // but we need to add this attribute to the profile if it's DENIED
  588. // create the SDO for this attribute
  589. CComPtr<IDispatch> spDispatch;
  590. hr = spDictionarySdo->CreateAttribute( (ATTRIBUTEID)IAS_ATTRIBUTE_ALLOW_DIALIN,
  591. (IDispatch**)&spDispatch.p);
  592. if ( !SUCCEEDED(hr) )
  593. {
  594. return hr;
  595. }
  596. // add this node to profile attribute collection
  597. hr = spProfAttrCollectionSdo->Add(NULL, (IDispatch**)&spDispatch.p);
  598. if ( !SUCCEEDED(hr) )
  599. {
  600. return hr;
  601. }
  602. //
  603. // get the ISdo pointer
  604. //
  605. CComPtr<ISdo> spAttrSdo;
  606. hr = spDispatch->QueryInterface( IID_ISdo, (void **) &spAttrSdo);
  607. if ( !SUCCEEDED(hr) )
  608. {
  609. return hr;
  610. }
  611. // set sdo property for this attribute
  612. CComVariant var;
  613. // set value
  614. V_VT(&var) = VT_BOOL;
  615. V_BOOL(&var) = VARIANT_FALSE;
  616. hr = spAttrSdo->PutProperty(PROPERTY_ATTRIBUTE_VALUE, &var);
  617. if ( !SUCCEEDED(hr) )
  618. {
  619. return hr;
  620. }
  621. var.Clear();
  622. } // if (!dialinallowed)
  623. return hr;
  624. }
  625. //////////
  626. // Update the default policy based on the specified flags.
  627. //////////
  628. HRESULT
  629. UpdateDefaultPolicy(
  630. IN LPWSTR wszMachineName,
  631. IN BOOL fEnableMSCHAPv1,
  632. IN BOOL fEnableMSCHAPv2,
  633. IN BOOL fRequireEncryption
  634. )
  635. {
  636. HRESULT hr;
  637. ISdoMachine *pMachine;
  638. ISdo *pService, *pProfile, *pAuthType;
  639. ISdoDictionaryOld *pDictionary;
  640. ISdoCollection *pAttributes;
  641. VARIANT val;
  642. // Initialize the local variables, so we can safely clean up on exit.
  643. pMachine = NULL;
  644. pService = pProfile = pAuthType = NULL;
  645. pDictionary = NULL;
  646. pAttributes = NULL;
  647. VariantInit(&val);
  648. do
  649. {
  650. hr = OpenMachineSdo(wszMachineName, &pMachine);
  651. if (FAILED(hr)) { break; }
  652. hr = OpenServiceSDO(pMachine, L"RemoteAccess", &pService);
  653. if (FAILED(hr)) { break; }
  654. hr = OpenDictionarySDO(pMachine, &pDictionary);
  655. if (FAILED(hr)) { break; }
  656. hr = GetDefaultProfile(pService, &pProfile);
  657. if (FAILED(hr)) { break; }
  658. // Get the attributes collection, which is a child of the profile.
  659. hr = OpenChildObject(
  660. pProfile,
  661. PROPERTY_PROFILE_ATTRIBUTES_COLLECTION,
  662. IID_ISdoCollection,
  663. (PVOID*)&pAttributes
  664. );
  665. if (FAILED(hr)) { break; }
  666. // Get the current value of the NP-Authentication-Type attribute.
  667. hr = GetAttribute(
  668. pAttributes,
  669. pDictionary,
  670. L"NP-Authentication-Type",
  671. &pAuthType
  672. );
  673. if (FAILED(hr)) { break; }
  674. hr = pAuthType->GetProperty(
  675. PROPERTY_ATTRIBUTE_VALUE,
  676. &val
  677. );
  678. if (FAILED(hr)) { break; }
  679. // Update MS-CHAP v1
  680. if (fEnableMSCHAPv1)
  681. {
  682. hr = AddIntegerToArray(&val, 3);
  683. }
  684. else
  685. {
  686. hr = RemoveIntegerFromArray(&val, 3);
  687. }
  688. if (FAILED(hr)) { break; }
  689. // Update MS-CHAP v2
  690. if (fEnableMSCHAPv2)
  691. {
  692. hr = AddIntegerToArray(&val, 4);
  693. }
  694. else
  695. {
  696. hr = RemoveIntegerFromArray(&val, 4);
  697. }
  698. if (FAILED(hr)) { break; }
  699. // Write the new value back to the attribute.
  700. hr = pAuthType->PutProperty(
  701. PROPERTY_ATTRIBUTE_VALUE,
  702. &val
  703. );
  704. if (FAILED(hr)) { break; }
  705. // Update the encryption attributes if necessary.
  706. if (fRequireEncryption)
  707. {
  708. hr = SetIntegerAttribute(
  709. pAttributes,
  710. pDictionary,
  711. L"MS-MPPE-Encryption-Policy",
  712. 2
  713. );
  714. if (FAILED(hr)) { break; }
  715. hr = SetIntegerAttribute(
  716. pAttributes,
  717. pDictionary,
  718. L"MS-MPPE-Encryption-Types",
  719. 14
  720. );
  721. if (FAILED(hr)) { break; }
  722. }
  723. //
  724. //Update the default for msNPAllowDialin - This should be set
  725. //to deny permissions by default
  726. //
  727. hr = SetDialinSetting(pAttributes,pDictionary, FALSE);
  728. if (FAILED(hr)) { break; }
  729. hr = pProfile->Apply();
  730. } while (FALSE);
  731. // Clean up.
  732. VariantClear(&val);
  733. if (pAttributes)
  734. pAttributes->Release();
  735. if (pDictionary)
  736. pDictionary->Release();
  737. if (pAuthType)
  738. pAuthType->Release();
  739. if (pProfile)
  740. pProfile->Release();
  741. if (pService)
  742. pService->Release();
  743. if (pMachine)
  744. pMachine->Release();
  745. return hr;
  746. }
  747. #if 0
  748. #include <stdio.h>
  749. int __cdecl wmain(int argc, wchar_t *argv[])
  750. {
  751. HRESULT hr;
  752. BOOL fEnableMSCHAPv1, fEnableMSCHAPv2, fRequireEncryption;
  753. if (argc != 4)
  754. {
  755. wprintf(L"Usage: wizard <t|f> <t|f> <t|f>\n"
  756. L" 1st flag: MS-CHAP v1 enabled\n"
  757. L" 2nd flag: MS-CHAP v2 enabled\n"
  758. L" 3rd flag: Encryption required\n");
  759. return -1;
  760. }
  761. fEnableMSCHAPv1 = argv[1][0] == 't' ? TRUE : FALSE;
  762. fEnableMSCHAPv2 = argv[2][0] == 't' ? TRUE : FALSE;
  763. fRequireEncryption = argv[3][0] == 't' ? TRUE : FALSE;
  764. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  765. hr = UpdateDefaultPolicy(
  766. NULL, // Machine name.
  767. fEnableMSCHAPv1,
  768. fEnableMSCHAPv2,
  769. fRequireEncryption
  770. );
  771. if (SUCCEEDED(hr))
  772. {
  773. wprintf(L"UpdateDefaultPolicy succeeded.\n");
  774. }
  775. else
  776. {
  777. wprintf(L"UpdateDefaultPolicy returned: 0x%08X.\n", hr);
  778. }
  779. CoUninitialize();
  780. return 0;
  781. }
  782. #endif