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.

1011 lines
24 KiB

  1. /*
  2. File: sdo.c
  3. Function to interact with the SDO's
  4. Paul Mayfield, 5/7/98
  5. */
  6. #include <windows.h>
  7. #include <mprapi.h>
  8. #include <mprapip.h>
  9. #include <stdio.h>
  10. #include <ole2.h>
  11. #include "sdoias.h"
  12. #include "sdolib.h"
  13. #include "sdowrap.h"
  14. #include "dialinusr.h"
  15. const DWORD dwFramed = RAS_RST_FRAMED;
  16. const DWORD dwFramedCallback = RAS_RST_FRAMEDCALLBACK;
  17. #define SDO_ERROR(e) \
  18. ((HRESULT_FACILITY((e)) == FACILITY_WIN32) ? HRESULT_CODE((e)) : (e));
  19. #define SDO_PROPERTY_IS_EMPTY(_pVar) (V_VT((_pVar)) == VT_EMPTY)
  20. // Definitions
  21. #define SDO_MAX_AUTHS 7
  22. DWORD
  23. SdoSetProfileToForceEncryption(
  24. IN HANDLE hSdo,
  25. IN HANDLE hProfile,
  26. IN BOOL bStrong);
  27. //
  28. // Sends debug trace and returns the given error
  29. //
  30. DWORD SdoTraceEx (DWORD dwErr, LPSTR pszTrace, ...) {
  31. #if DBG
  32. va_list arglist;
  33. char szBuffer[1024], szTemp[1024];
  34. va_start(arglist, pszTrace);
  35. vsprintf(szTemp, pszTrace, arglist);
  36. va_end(arglist);
  37. sprintf(szBuffer, "Sdo: %s", szTemp);
  38. OutputDebugStringA(szBuffer);
  39. #endif
  40. return dwErr;
  41. }
  42. //
  43. // Allocation routine for sdo functions
  44. //
  45. PVOID SdoAlloc (
  46. IN DWORD dwSize,
  47. IN BOOL bZero)
  48. {
  49. return LocalAlloc ((bZero) ? LPTR : LMEM_FIXED, dwSize);
  50. }
  51. //
  52. // Free routine for sdo functions
  53. //
  54. VOID SdoFree (
  55. IN PVOID pvData)
  56. {
  57. LocalFree (pvData);
  58. }
  59. //
  60. // Releases any resources aquired by loading the SDO library.
  61. //
  62. DWORD SdoUnloadLibrary (
  63. IN HANDLE hData)
  64. {
  65. return NO_ERROR;
  66. }
  67. //
  68. // Loads the library that utilizes SDO's
  69. //
  70. DWORD SdoLoadLibrary (
  71. IN HANDLE hData)
  72. {
  73. return NO_ERROR;
  74. }
  75. typedef struct _tagSDOINFO
  76. {
  77. BOOL bComCleanup;
  78. } SDOINFO;
  79. //
  80. // Initialize and cleanup the sdo library
  81. //
  82. DWORD SdoInit (
  83. OUT PHANDLE phSdo)
  84. {
  85. DWORD dwErr = NO_ERROR;
  86. HRESULT hr = S_OK;
  87. SDOINFO* pInfo = NULL;
  88. BOOL bCom = FALSE;
  89. SdoTraceEx (0, "SdoInit: entered.\n");
  90. //For whistler bug 397815
  91. //We have to modify the CoIntialize() and CoUnitialize()
  92. //to avoid AV in rasdlg!netDbClose()
  93. //
  94. // Validate parameters
  95. //
  96. if ( NULL == phSdo )
  97. {
  98. return ERROR_INVALID_PARAMETER;
  99. }
  100. // Initialize
  101. //
  102. *phSdo = NULL;
  103. do
  104. {
  105. // Load in the sdo library
  106. dwErr = SdoLoadLibrary(NULL);
  107. if (NO_ERROR != dwErr )
  108. {
  109. SdoTraceEx(dwErr, "SdoInit: unabled to load library\n");
  110. break;
  111. }
  112. // Initialize Com
  113. //
  114. hr = CoInitializeEx (NULL, COINIT_MULTITHREADED);
  115. if ( RPC_E_CHANGED_MODE == hr )
  116. {
  117. hr = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
  118. }
  119. if (FAILED(hr))
  120. {
  121. dwErr = HRESULT_CODE(hr);
  122. break;
  123. }
  124. bCom = TRUE;
  125. pInfo = SdoAlloc(sizeof(SDOINFO), TRUE);
  126. if (pInfo == NULL)
  127. {
  128. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  129. break;
  130. }
  131. pInfo->bComCleanup = bCom;
  132. *phSdo = (HANDLE)pInfo;
  133. } while (FALSE);
  134. // Cleanup
  135. //
  136. {
  137. if ( NO_ERROR!= dwErr )
  138. {
  139. if (pInfo)
  140. {
  141. SdoFree(pInfo);
  142. }
  143. if (bCom)
  144. {
  145. CoUninitialize();
  146. }
  147. }
  148. }
  149. return dwErr;
  150. }
  151. //
  152. // Frees resources held by the SDO library
  153. DWORD SdoCleanup (
  154. IN HANDLE hSdo)
  155. {
  156. DWORD dwErr;
  157. SDOINFO* pInfo = (SDOINFO*)hSdo;
  158. SdoTraceEx (0, "SdoCleanup: entered.\n");
  159. if ( NULL == pInfo )
  160. {
  161. return ERROR_INVALID_PARAMETER;
  162. }
  163. // Unload the sdo library
  164. if ((dwErr = SdoUnloadLibrary(NULL)) != NO_ERROR)
  165. SdoTraceEx (dwErr, "SdoCleanup: %x on unload.\n", dwErr);
  166. // Unititialize com
  167. if (pInfo->bComCleanup)
  168. {
  169. CoUninitialize();
  170. }
  171. SdoFree(pInfo);
  172. return NO_ERROR;
  173. }
  174. //
  175. // Connects to an SDO server
  176. //
  177. DWORD SdoConnect (
  178. IN HANDLE hSdo,
  179. IN PWCHAR pszServer,
  180. IN BOOL bLocal,
  181. OUT PHANDLE phServer)
  182. {
  183. BSTR bstrComputer = NULL;
  184. HRESULT hr;
  185. SdoTraceEx (0, "SdoConnect: entered %S, %d\n",
  186. pszServer, bLocal);
  187. // Prepare a correctly formatted version of the server
  188. // name -- NULL for local, no "\\" for remote.
  189. if (pszServer) {
  190. WCHAR pszLocalComputer[1024];
  191. DWORD dwSize = sizeof(pszLocalComputer) / sizeof(WCHAR);
  192. if (*pszServer == 0)
  193. bstrComputer = NULL;
  194. else if (*pszServer == '\\')
  195. {
  196. bstrComputer = SysAllocString(pszServer + 2);
  197. if (bstrComputer == NULL)
  198. {
  199. return ERROR_NOT_ENOUGH_MEMORY;
  200. }
  201. }
  202. else
  203. {
  204. bstrComputer = SysAllocString(pszServer);
  205. if (bstrComputer == NULL)
  206. {
  207. return ERROR_NOT_ENOUGH_MEMORY;
  208. }
  209. }
  210. if ((bstrComputer) &&
  211. (GetComputerName(pszLocalComputer, &dwSize)))
  212. {
  213. if (lstrcmpi (pszLocalComputer, bstrComputer) == 0) {
  214. SysFreeString(bstrComputer);
  215. bstrComputer = NULL;
  216. }
  217. }
  218. }
  219. else
  220. bstrComputer = NULL;
  221. hr = SdoWrapOpenServer(
  222. bstrComputer,
  223. bLocal,
  224. phServer);
  225. if (FAILED (hr))
  226. SdoTraceEx (0, "SdoConnect: %x on OpenServer(%S) \n",
  227. hr, bstrComputer);
  228. if (bstrComputer)
  229. SysFreeString(bstrComputer);
  230. if (FAILED (hr))
  231. return hr;
  232. return NO_ERROR;
  233. }
  234. //
  235. // Disconnects from an SDO server
  236. //
  237. DWORD SdoDisconnect (
  238. IN HANDLE hSdo,
  239. IN HANDLE hServer)
  240. {
  241. SdoTraceEx (0, "SdoDisconnect: entered\n");
  242. return SdoWrapCloseServer(hServer);
  243. }
  244. //
  245. // Opens an Sdo user for manipulation
  246. //
  247. DWORD SdoOpenUser(
  248. IN HANDLE hSdo,
  249. IN HANDLE hServer,
  250. IN PWCHAR pszUser,
  251. OUT PHANDLE phUser)
  252. {
  253. DWORD dwErr;
  254. BSTR bstrUser;
  255. // Initailize the strings for COM
  256. bstrUser = SysAllocString(pszUser);
  257. if (bstrUser == NULL)
  258. return ERROR_NOT_ENOUGH_MEMORY;
  259. // Open the user's Sdo object
  260. dwErr = SdoWrapOpenUser(
  261. hServer,
  262. bstrUser,
  263. phUser);
  264. if (dwErr != NO_ERROR)
  265. SdoTraceEx (0, "SdoOpenUser: %x on OpenUser(%S)\n", dwErr, bstrUser);
  266. // Cleanup
  267. SysFreeString(bstrUser);
  268. if (dwErr != NO_ERROR)
  269. return dwErr;
  270. return NO_ERROR;
  271. }
  272. //
  273. // Closes an Sdo user
  274. //
  275. DWORD SdoCloseUser(
  276. IN HANDLE hSdo,
  277. IN HANDLE hUser)
  278. {
  279. if (hUser != NULL)
  280. return SdoWrapClose(hUser);
  281. return ERROR_INVALID_PARAMETER;
  282. }
  283. //
  284. // Commits an Sdo user
  285. //
  286. DWORD SdoCommitUser(
  287. IN HANDLE hSdo,
  288. IN HANDLE hUser,
  289. IN BOOL bCommit)
  290. {
  291. if (hUser != NULL)
  292. {
  293. return SdoWrapCommit(hUser, bCommit);
  294. }
  295. return ERROR_INVALID_PARAMETER;
  296. }
  297. //
  298. // SDO equivalent of MprAdminUserGetInfo
  299. //
  300. DWORD SdoUserGetInfo (
  301. IN HANDLE hSdo,
  302. IN HANDLE hUser,
  303. IN DWORD dwLevel,
  304. OUT LPBYTE pRasUser)
  305. {
  306. RAS_USER_0* pUserInfo = (RAS_USER_0*)pRasUser;
  307. VARIANT var, vCallback, vSavedCb;
  308. DWORD dwErr, dwCallback;
  309. HRESULT hr;
  310. // Validate -- we only handle level 0
  311. if ((!hUser) || (dwLevel != 0 && dwLevel != 1) || (!pUserInfo))
  312. return ERROR_INVALID_PARAMETER;
  313. // Initialize
  314. pUserInfo->bfPrivilege = 0;
  315. dwCallback = RAS_RST_FRAMED;
  316. // Read in the service type
  317. VariantInit (&var);
  318. hr = SdoWrapGetAttr(
  319. hUser,
  320. PROPERTY_USER_SERVICE_TYPE,
  321. &var);
  322. if (FAILED (hr))
  323. {
  324. return SdoTraceEx (hr, "SdoUserGetInfo: %x on GetAttr ST\n", hr);
  325. }
  326. // If the service type doesn't exist, return
  327. // set defaults.
  328. if (SDO_PROPERTY_IS_EMPTY(&var))
  329. {
  330. pUserInfo->bfPrivilege |= RASPRIV_NoCallback;
  331. wcscpy (pUserInfo->wszPhoneNumber, L"");
  332. }
  333. else
  334. {
  335. // Assign the callback flags from the service type
  336. dwCallback = V_I4(&var);
  337. }
  338. VariantClear (&var);
  339. // Readin the dialin flag
  340. hr = SdoWrapGetAttr(
  341. hUser,
  342. PROPERTY_USER_ALLOW_DIALIN,
  343. &var);
  344. if (FAILED (hr))
  345. {
  346. return SdoTraceEx (hr, "SdoUserGetInfo: %x on GetAttr DI\n", hr);
  347. }
  348. if (dwLevel == 1)
  349. {
  350. if (SDO_PROPERTY_IS_EMPTY(&var))
  351. {
  352. pUserInfo->bfPrivilege |= RASPRIV_DialinPolicy;
  353. }
  354. else if ((V_VT(&var) == VT_BOOL) && (V_BOOL(&var) == VARIANT_TRUE))
  355. {
  356. pUserInfo->bfPrivilege |= RASPRIV_DialinPrivilege;
  357. }
  358. }
  359. else if ((V_VT(&var) == VT_BOOL) && (V_BOOL(&var) == VARIANT_TRUE))
  360. {
  361. pUserInfo->bfPrivilege |= RASPRIV_DialinPrivilege;
  362. }
  363. // Read in the callback number and saved callback number
  364. VariantInit(&vCallback);
  365. VariantInit(&vSavedCb);
  366. hr = SdoWrapGetAttr(
  367. hUser, PROPERTY_USER_RADIUS_CALLBACK_NUMBER, &vCallback);
  368. if (FAILED (hr))
  369. {
  370. return SdoTraceEx (hr, "SdoUserGetInfo: %x on GetAttr CB\n", hr);
  371. }
  372. hr = SdoWrapGetAttr(
  373. hUser, PROPERTY_USER_SAVED_RADIUS_CALLBACK_NUMBER, &vSavedCb);
  374. if (FAILED (hr))
  375. {
  376. return SdoTraceEx (hr, "SdoUserGetInfo: %x on GetAttr SCB\n", hr);
  377. }
  378. // If there was a callback number, then this is definately,
  379. // admin assigned callback
  380. if ( (V_VT(&vCallback) == VT_BSTR) &&
  381. (V_BSTR(&vCallback)) )
  382. {
  383. pUserInfo->bfPrivilege |= RASPRIV_AdminSetCallback;
  384. }
  385. // Otherwise, the service type will tell us whether we have
  386. // caller settable callback or none.
  387. else
  388. {
  389. if (dwCallback == RAS_RST_FRAMEDCALLBACK)
  390. pUserInfo->bfPrivilege |= RASPRIV_CallerSetCallback;
  391. else
  392. pUserInfo->bfPrivilege |= RASPRIV_NoCallback;
  393. }
  394. // Now, assign the callback number accordingly
  395. if (pUserInfo->bfPrivilege & RASPRIV_AdminSetCallback)
  396. {
  397. wcscpy (pUserInfo->wszPhoneNumber, V_BSTR(&vCallback));
  398. }
  399. else if ((V_VT(&vSavedCb) == VT_BSTR) && (V_BSTR(&vSavedCb)))
  400. {
  401. wcscpy (pUserInfo->wszPhoneNumber, V_BSTR(&vSavedCb));
  402. }
  403. else
  404. {
  405. wcscpy (pUserInfo->wszPhoneNumber, L"");
  406. }
  407. VariantClear (&vSavedCb);
  408. VariantClear (&vCallback);
  409. return NO_ERROR;
  410. }
  411. //
  412. // SDO equivalent of MprAdminUserSetInfo
  413. //
  414. DWORD SdoUserSetInfo (
  415. IN HANDLE hSdo,
  416. IN HANDLE hUser,
  417. IN DWORD dwLevel,
  418. IN LPBYTE pRasUser)
  419. {
  420. RAS_USER_0* pUserInfo = (RAS_USER_0*)pRasUser;
  421. DWORD dwErr, dwCallback, dwCallbackId, dwSize, dwCbType;
  422. VARIANT var;
  423. HRESULT hr;
  424. // Validate -- we only handle level 0
  425. if ((!hUser) || (dwLevel != 0 && dwLevel != 1) || (!pUserInfo))
  426. return ERROR_INVALID_PARAMETER;
  427. // Initialize
  428. VariantInit (&var);
  429. dwCallback = 0;
  430. // Assign dialin flags
  431. if (!!(pUserInfo->bfPrivilege & RASPRIV_DialinPrivilege))
  432. {
  433. V_VT(&var) = VT_BOOL;
  434. V_BOOL(&var) = VARIANT_TRUE;
  435. }
  436. else
  437. {
  438. V_VT(&var) = VT_BOOL;
  439. V_BOOL(&var) = VARIANT_FALSE;
  440. }
  441. if (dwLevel == 1)
  442. {
  443. if (!!(pUserInfo->bfPrivilege & RASPRIV_DialinPolicy))
  444. {
  445. V_VT(&var) = VT_EMPTY;
  446. }
  447. }
  448. hr = SdoWrapPutAttr(
  449. hUser,
  450. PROPERTY_USER_ALLOW_DIALIN,
  451. &var);
  452. if (FAILED (hr))
  453. {
  454. SdoTraceEx (hr, "SdoUserSetInfo: %x on PutAttr DI\n", hr);
  455. }
  456. VariantClear(&var);
  457. // Assign the callback mode and read in the
  458. // callback number
  459. dwCbType = VT_EMPTY;
  460. if (pUserInfo->bfPrivilege & RASPRIV_AdminSetCallback)
  461. {
  462. dwCbType = VT_I4;
  463. dwCallback = RAS_RST_FRAMEDCALLBACK;
  464. dwCallbackId = PROPERTY_USER_RADIUS_CALLBACK_NUMBER;
  465. }
  466. else if (pUserInfo->bfPrivilege & RASPRIV_CallerSetCallback)
  467. {
  468. dwCbType = VT_I4;
  469. dwCallback = RAS_RST_FRAMEDCALLBACK;
  470. dwCallbackId = PROPERTY_USER_SAVED_RADIUS_CALLBACK_NUMBER;
  471. }
  472. else
  473. {
  474. dwCbType = VT_EMPTY;
  475. dwCallback = RAS_RST_FRAMED;
  476. dwCallbackId = PROPERTY_USER_SAVED_RADIUS_CALLBACK_NUMBER;
  477. }
  478. // Write out the callback number
  479. if (wcslen (pUserInfo->wszPhoneNumber) > 0)
  480. {
  481. V_VT(&var) = VT_BSTR;
  482. V_BSTR(&var) = SysAllocString (pUserInfo->wszPhoneNumber);
  483. if (V_BSTR(&var) == NULL)
  484. {
  485. return E_OUTOFMEMORY;
  486. }
  487. hr = SdoWrapPutAttr(hUser, dwCallbackId, &var);
  488. SysFreeString (V_BSTR(&var));
  489. if (FAILED (hr))
  490. return SdoTraceEx (hr, "SdoUserSetInfo: %x on PutAttr CB\n", hr);
  491. }
  492. // Write out the callback policy
  493. VariantInit(&var);
  494. V_VT(&var) = (USHORT)dwCbType;
  495. if (V_VT(&var) != VT_EMPTY)
  496. {
  497. V_I4(&var) = dwCallback;
  498. }
  499. hr = SdoWrapPutAttr(hUser, PROPERTY_USER_SERVICE_TYPE, &var);
  500. if (FAILED (hr))
  501. {
  502. return SdoTraceEx (hr, "SdoUserSetInfo: %x on PutAttr ST\n", hr);
  503. }
  504. // Remove the appropriate callback attribute
  505. dwCallbackId = (dwCallbackId == PROPERTY_USER_RADIUS_CALLBACK_NUMBER) ?
  506. PROPERTY_USER_SAVED_RADIUS_CALLBACK_NUMBER :
  507. PROPERTY_USER_RADIUS_CALLBACK_NUMBER;
  508. hr = SdoWrapRemoveAttr(hUser, dwCallbackId);
  509. if (FAILED (hr))
  510. {
  511. return SdoTraceEx (hr, "SdoUserSetInfo: %x on RemoveAttr CB\n", hr);
  512. }
  513. return NO_ERROR;
  514. }
  515. //
  516. // Opens the default profile
  517. //
  518. DWORD SdoOpenDefaultProfile(
  519. IN HANDLE hSdo,
  520. IN HANDLE hServer,
  521. OUT PHANDLE phProfile)
  522. {
  523. SdoTraceEx (0, "SdoOpenDefaultProfile: entered\n");
  524. if (phProfile == NULL)
  525. return ERROR_INVALID_PARAMETER;
  526. return SdoWrapOpenDefaultProfile(hServer, phProfile);
  527. }
  528. //
  529. // Closes a profile
  530. //
  531. DWORD SdoCloseProfile(
  532. IN HANDLE hSdo,
  533. IN HANDLE hProfile)
  534. {
  535. SdoTraceEx (0, "SdoCloseProfile: entered\n");
  536. if (hProfile == NULL)
  537. return ERROR_INVALID_PARAMETER;
  538. return SdoWrapCloseProfile(hProfile);
  539. }
  540. //
  541. // Converts a 1 demensional safe array of variant dwords
  542. // into an a array of dwords and a count
  543. //
  544. HRESULT SdoConvertSafeArrayDw (
  545. IN SAFEARRAY * pArray,
  546. OUT LPDWORD lpdwAuths,
  547. OUT LPDWORD lpdwAuthCount)
  548. {
  549. LONG lDim, lLBound, lRBound, lCount, i;
  550. HRESULT hr;
  551. VARIANT var;
  552. // Validate
  553. if (!pArray || !lpdwAuths || !lpdwAuthCount)
  554. return ERROR_INVALID_PARAMETER;
  555. // Verify dimensions
  556. lDim = (DWORD)SafeArrayGetDim(pArray);
  557. if (lDim != 1)
  558. return ERROR_INVALID_PARAMETER;
  559. // Get the bounds
  560. hr = SafeArrayGetLBound(pArray, 1, &lLBound);
  561. if (FAILED (hr))
  562. return hr;
  563. hr = SafeArrayGetUBound(pArray, 1, &lRBound);
  564. if (FAILED (hr))
  565. return hr;
  566. lCount = (lRBound - lLBound) + 1;
  567. *lpdwAuthCount = (DWORD)lCount;
  568. if (lCount == 0)
  569. return NO_ERROR;
  570. // Loop through
  571. for (i = 0; i < lCount; i++) {
  572. hr = SafeArrayGetElement(pArray, &i, (VOID*)&var);
  573. if (FAILED (hr))
  574. continue;
  575. lpdwAuths[i] = V_I4(&var);
  576. }
  577. return S_OK;
  578. }
  579. //
  580. // Converts a 1 demensional array of dwords to a
  581. // safe array of variant dwords.
  582. //
  583. HRESULT SdoCovertDwToSafeArray(
  584. IN SAFEARRAY ** ppArray,
  585. OUT LPDWORD lpdwAuths,
  586. OUT DWORD dwAuthCount)
  587. {
  588. HRESULT hr;
  589. SAFEARRAY * pArray;
  590. SAFEARRAYBOUND rgsabound[1];
  591. LONG i;
  592. VARIANT var;
  593. // Validate
  594. if (!lpdwAuths || !ppArray)
  595. return E_INVALIDARG;
  596. // Create the new array
  597. rgsabound[0].lLbound = 0;
  598. rgsabound[0].cElements = dwAuthCount;
  599. pArray = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
  600. // Fill in the array values
  601. for (i = 0; i < (LONG)dwAuthCount; i++) {
  602. hr = SafeArrayGetElement(pArray, &i, (VOID*)&var);
  603. if (FAILED (hr))
  604. continue;
  605. V_VT(&var) = VT_I4;
  606. V_I4(&var) = lpdwAuths[i];
  607. hr = SafeArrayPutElement(pArray, &i, (VOID*)&var);
  608. if (FAILED (hr))
  609. return hr;
  610. }
  611. *ppArray = pArray;
  612. return S_OK;
  613. }
  614. //
  615. // Sets data in the profile.
  616. //
  617. DWORD SdoSetProfileData(
  618. IN HANDLE hSdo,
  619. IN HANDLE hProfile,
  620. IN DWORD dwFlags)
  621. {
  622. DWORD dwAuthCount, dwAuths[SDO_MAX_AUTHS];
  623. VARIANT varEp, varEt, varAt;
  624. HRESULT hr;
  625. SdoTraceEx (0, "SdoSetProfileData: entered\n");
  626. if ((dwFlags & MPR_USER_PROF_FLAG_FORCE_STRONG_ENCRYPTION) ||
  627. (dwFlags & MPR_USER_PROF_FLAG_FORCE_ENCRYPTION))
  628. {
  629. return SdoSetProfileToForceEncryption(
  630. hSdo,
  631. hProfile,
  632. !!(dwFlags & MPR_USER_PROF_FLAG_FORCE_STRONG_ENCRYPTION));
  633. }
  634. // Initialize
  635. VariantInit (&varEp);
  636. VariantInit (&varEt);
  637. VariantInit (&varAt);
  638. do
  639. {
  640. // Set the encryption policy
  641. V_VT(&varEp) = VT_I4;
  642. if (dwFlags & MPR_USER_PROF_FLAG_SECURE)
  643. {
  644. V_I4(&varEp) = RAS_EP_REQUIRE;
  645. }
  646. else
  647. {
  648. V_I4(&varEp) = RAS_EP_ALLOW;
  649. }
  650. // Set the encryption type
  651. V_VT(&varEt) = VT_I4;
  652. if (dwFlags & MPR_USER_PROF_FLAG_SECURE)
  653. {
  654. V_I4(&varEt) = (RAS_ET_BASIC | RAS_ET_STRONGEST | RAS_ET_STRONG);
  655. }
  656. else
  657. {
  658. V_I4(&varEt) = (RAS_ET_BASIC | RAS_ET_STRONGEST | RAS_ET_STRONG);
  659. }
  660. // Set the authentication types
  661. if (dwFlags & MPR_USER_PROF_FLAG_SECURE)
  662. {
  663. dwAuthCount = 4;
  664. dwAuths[0] = IAS_AUTH_MSCHAP;
  665. dwAuths[1] = IAS_AUTH_MSCHAP2;
  666. dwAuths[2] = IAS_AUTH_MSCHAP_CPW;
  667. dwAuths[3] = IAS_AUTH_MSCHAP2_CPW;
  668. }
  669. else
  670. {
  671. dwAuthCount = 5;
  672. dwAuths[0] = IAS_AUTH_MSCHAP;
  673. dwAuths[1] = IAS_AUTH_MSCHAP2;
  674. dwAuths[2] = IAS_AUTH_PAP;
  675. dwAuths[3] = IAS_AUTH_MSCHAP_CPW;
  676. dwAuths[4] = IAS_AUTH_MSCHAP2_CPW;
  677. }
  678. V_VT(&varAt) = VT_ARRAY | VT_VARIANT;
  679. hr = SdoCovertDwToSafeArray(
  680. &(V_ARRAY(&varAt)),
  681. dwAuths,
  682. dwAuthCount);
  683. if (FAILED (hr))
  684. {
  685. break;
  686. }
  687. // Set the values in the profile
  688. hr = SdoWrapSetProfileValues(
  689. hProfile,
  690. &varEp,
  691. &varEt,
  692. &varAt);
  693. if (FAILED (hr))
  694. {
  695. break;
  696. }
  697. } while (FALSE);
  698. // Cleanup
  699. {
  700. VariantClear(&varEp);
  701. VariantClear(&varEt);
  702. VariantClear(&varAt);
  703. }
  704. return SDO_ERROR(hr);
  705. }
  706. //
  707. // Sets a profile to force strong encryption
  708. //
  709. DWORD
  710. SdoSetProfileToForceEncryption(
  711. IN HANDLE hSdo,
  712. IN HANDLE hProfile,
  713. IN BOOL bStrong)
  714. {
  715. VARIANT varEp, varEt;
  716. HRESULT hr = S_OK;
  717. SdoTraceEx (0, "SdoSetProfileToForceEncryption: entered (%d)\n", !!bStrong);
  718. // Initialize
  719. VariantInit (&varEp);
  720. VariantInit (&varEt);
  721. do
  722. {
  723. // Set the encryption policy
  724. V_VT(&varEp) = VT_I4;
  725. V_I4(&varEp) = RAS_EP_REQUIRE;
  726. // Set the encryption type
  727. V_VT(&varEt) = VT_I4;
  728. if (bStrong)
  729. {
  730. V_I4(&varEt) = RAS_ET_STRONGEST;
  731. }
  732. else
  733. {
  734. V_I4(&varEt) = RAS_ET_BASIC | RAS_ET_STRONG | RAS_ET_STRONGEST;
  735. }
  736. // Write out the values
  737. // Set the values in the profile
  738. hr = SdoWrapSetProfileValues(
  739. hProfile,
  740. &varEp,
  741. &varEt,
  742. NULL);
  743. if (FAILED (hr))
  744. {
  745. break;
  746. }
  747. } while (FALSE);
  748. // Cleanup
  749. {
  750. VariantClear(&varEp);
  751. VariantClear(&varEt);
  752. }
  753. return SDO_ERROR(hr);
  754. }
  755. //
  756. // Read information from the given profile
  757. //
  758. DWORD SdoGetProfileData(
  759. IN HANDLE hSdo,
  760. IN HANDLE hProfile,
  761. OUT LPDWORD lpdwFlags)
  762. {
  763. VARIANT varEp, varEt, varAt;
  764. HRESULT hr = S_OK;
  765. DWORD dwEncPolicy,
  766. dwAuthCount,
  767. dwAuths[SDO_MAX_AUTHS],
  768. i,
  769. dwEncType;
  770. SdoTraceEx (0, "SdoGetProfileData: entered\n");
  771. // Initialize
  772. ZeroMemory(dwAuths, sizeof(dwAuths));
  773. VariantInit(&varEp);
  774. VariantInit(&varEt);
  775. VariantInit(&varAt);
  776. do
  777. {
  778. // Read in the encryption values
  779. hr = SdoWrapGetProfileValues(hProfile, &varEp, &varEt, &varAt);
  780. if (FAILED (hr))
  781. {
  782. break;
  783. }
  784. // Parse the encryption policy
  785. if (SDO_PROPERTY_IS_EMPTY(&varEp))
  786. {
  787. dwEncPolicy = RAS_DEF_ENCRYPTIONPOLICY;
  788. }
  789. else
  790. {
  791. dwEncPolicy = V_I4(&varEp);
  792. }
  793. // Parse the encryption type
  794. if (SDO_PROPERTY_IS_EMPTY(&varEt))
  795. {
  796. dwEncType = RAS_DEF_ENCRYPTIONTYPE;
  797. }
  798. else
  799. {
  800. dwEncType = V_I4(&varEt);
  801. }
  802. // Parse in the allowed authentication types
  803. if (SDO_PROPERTY_IS_EMPTY(&varAt))
  804. {
  805. dwAuthCount = 1;
  806. dwAuths[0] = RAS_DEF_AUTHENTICATIONTYPE;
  807. }
  808. else
  809. {
  810. hr = SdoConvertSafeArrayDw (
  811. V_ARRAY(&varAt),
  812. dwAuths,
  813. &dwAuthCount);
  814. if (FAILED (hr))
  815. {
  816. break;
  817. }
  818. }
  819. // If the encryption type has been mucked with
  820. // then we can't tell if we're secure.
  821. if (dwEncType != (RAS_ET_STRONG |
  822. RAS_ET_STRONGEST |
  823. RAS_ET_BASIC))
  824. {
  825. *lpdwFlags = MPR_USER_PROF_FLAG_UNDETERMINED;
  826. }
  827. else
  828. {
  829. // If the encryption policy forces encryption
  830. // then we're secure if the only authentication
  831. // types are MSCHAP v1 or 2.
  832. if (dwEncPolicy == RAS_EP_REQUIRE)
  833. {
  834. *lpdwFlags = MPR_USER_PROF_FLAG_SECURE;
  835. for (i = 0; i < dwAuthCount; i++)
  836. {
  837. if ((dwAuths[i] != IAS_AUTH_MSCHAP) &&
  838. (dwAuths[i] != IAS_AUTH_MSCHAP2) &&
  839. (dwAuths[i] != IAS_AUTH_MSCHAP_CPW) &&
  840. (dwAuths[i] != IAS_AUTH_MSCHAP2_CPW))
  841. {
  842. *lpdwFlags = MPR_USER_PROF_FLAG_UNDETERMINED;
  843. }
  844. }
  845. }
  846. // We know that we're not secure all authentication
  847. // types are allowed
  848. else
  849. {
  850. if ( (dwAuthCount >= 3) && (dwAuthCount <= 5))
  851. {
  852. *lpdwFlags = 0;
  853. for (i = 0; i < dwAuthCount; i++)
  854. {
  855. if ((dwAuths[i] != IAS_AUTH_MSCHAP) &&
  856. (dwAuths[i] != IAS_AUTH_MSCHAP2) &&
  857. (dwAuths[i] != IAS_AUTH_MSCHAP_CPW) &&
  858. (dwAuths[i] != IAS_AUTH_MSCHAP2_CPW) &&
  859. (dwAuths[i] != IAS_AUTH_PAP))
  860. {
  861. *lpdwFlags = MPR_USER_PROF_FLAG_UNDETERMINED;
  862. }
  863. }
  864. }
  865. else
  866. {
  867. *lpdwFlags = MPR_USER_PROF_FLAG_UNDETERMINED;
  868. }
  869. }
  870. }
  871. } while (FALSE);
  872. // Cleanup
  873. {
  874. VariantClear(&varEp);
  875. VariantClear(&varEt);
  876. VariantClear(&varAt);
  877. }
  878. return SDO_ERROR(hr);
  879. }