Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

798 lines
19 KiB

  1. //////////////////////////////////////////////////////////////////////
  2. // globals.cpp : Implementation for the globals
  3. // Copyright (c)1997-2001 Microsoft Corporation
  4. //
  5. // Original Create Date: 2/21/2001
  6. // Original Author: shawnwu
  7. //////////////////////////////////////////////////////////////////////
  8. #include "globals.h"
  9. LPCWSTR pszRollbackAll = L"RollbackAll";
  10. LPCWSTR pszEmptyRollbackToken = L"EmptyRollbackToken";
  11. LPCWSTR pszCreateDefaultPolicy = L"CreateDefaultPolicy";
  12. LPCWSTR pszGetDefaultPolicyName = L"GetDefaultPolicyName";
  13. //
  14. // these are WMI class names to support IPSec
  15. //
  16. LPCWSTR pszNspGeneral = L"Nsp_GeneralSettings";
  17. LPCWSTR pszNspTcp = L"Nsp_TcpSettings";
  18. LPCWSTR pszNspIPConfigure = L"Nsp_IPConfigSettings";
  19. LPCWSTR pszNspFilter = L"Nsp_FilterSettings";
  20. LPCWSTR pszNspTransportFilter = L"Nsp_TransportFilterSettings";
  21. LPCWSTR pszNspTunnelFilter = L"Nsp_TunnelFilterSettings";
  22. LPCWSTR pszNspMMFilter = L"Nsp_MMFilterSettings";
  23. LPCWSTR pszNspQMPolicy = L"Nsp_QMPolicySettings";
  24. LPCWSTR pszNspMMPolicy = L"Nsp_MMPolicySettings";
  25. LPCWSTR pszNspMMAuth = L"Nsp_MMAuthSettings";
  26. LPCWSTR pszNspExceptionPorts = L"Nsp_ExceptionPorts";
  27. LPCWSTR pszNspRollbackFilter = L"Nsp_RollbackFilter";
  28. LPCWSTR pszNspRollbackPolicy = L"Nsp_RollbackPolicy";
  29. LPCWSTR pszNspRollbackMMAuth = L"Nsp_RollbackMMAuth";
  30. LPCWSTR pszNspTranxManager = L"Nsp_TranxManager";
  31. //
  32. // These are WMI class names to support SCW (Security Configuration Wizard)
  33. //
  34. LPCWSTR pszScwActiveSocket = L"SCW_ActiveSocket";
  35. //
  36. // these are WMI class property names for IPSec
  37. //
  38. LPCWSTR g_pszFilterName = L"FilterName";
  39. LPCWSTR g_pszDirection = L"Direction";
  40. LPCWSTR g_pszFilterType = L"FilterType";
  41. LPCWSTR g_pszInterfaceType = L"InterfaceType";
  42. //LPCWSTR g_pszGenericFilter = L"GenericFilter";
  43. LPCWSTR g_pszCreateMirror = L"CreateMirror";
  44. LPCWSTR g_pszSrcAddr = L"SrcAddr";
  45. LPCWSTR g_pszSrcSubnetMask = L"SrcSubnetMask";
  46. LPCWSTR g_pszSrcAddrType = L"SrcAddrType";
  47. LPCWSTR g_pszDestAddr = L"DestAddr";
  48. LPCWSTR g_pszDestSubnetMask = L"DestSubnetMask";
  49. LPCWSTR g_pszDestAddrType = L"DestAddrType";
  50. LPCWSTR g_pszMMPolicyName = L"MMPolicyName";
  51. LPCWSTR g_pszMMAuthName = L"MMAuthName";
  52. LPCWSTR g_pszInboundFlag = L"InboundFilterFlag";
  53. LPCWSTR g_pszOutboundFlag = L"OutboundFilterFlag";
  54. LPCWSTR g_pszProtocol = L"Protocol";
  55. LPCWSTR g_pszSrcPort = L"SrcPort";
  56. LPCWSTR g_pszDestPort = L"DestPort";
  57. LPCWSTR g_pszQMPolicyName = L"QMPolicyName";
  58. LPCWSTR g_pszTunnelSrcAddr = L"TunnelSrcAddr";
  59. LPCWSTR g_pszTunnelSrcSubnetMask = L"TunnelSrcSubnetMask";
  60. LPCWSTR g_pszTunnelSrcAddrType = L"TunnelSrcAddrType";
  61. LPCWSTR g_pszTunnelDestAddr = L"TunnelDestAddr";
  62. LPCWSTR g_pszTunnelDestSubnetMask = L"TunnelDestSubnetMask";
  63. LPCWSTR g_pszTunnelDestAddrType = L"TunnelDestAddrType";
  64. LPCWSTR g_pszPolicyName = L"PolicyName";
  65. LPCWSTR g_pszPolicyFlag = L"Flag";
  66. LPCWSTR g_pszOfferCount = L"OfferCount";
  67. LPCWSTR g_pszKeyLifeTime = L"KeyLifeTime";
  68. LPCWSTR g_pszKeyLifeTimeKBytes = L"KeyLifeTimeKBytes";
  69. LPCWSTR g_pszSoftSAExpTime = L"SoftSAExpTime";
  70. LPCWSTR g_pszQMLimit = L"QMLimit";
  71. LPCWSTR g_pszDHGroup = L"DHGroup";
  72. LPCWSTR g_pszEncryptID = L"EncryptID";
  73. LPCWSTR g_pszHashID = L"HashID";
  74. LPCWSTR g_pszPFSRequired = L"PFSRequired";
  75. LPCWSTR g_pszPFSGroup = L"PFSGroup";
  76. LPCWSTR g_pszNumAlgos = L"NumAlgos";
  77. LPCWSTR g_pszAlgoOp = L"AlgoOp";
  78. LPCWSTR g_pszAlgoID = L"AlgoID";
  79. LPCWSTR g_pszAlgoSecID = L"AlgoSecID";
  80. LPCWSTR g_pszAuthMethodID = L"AuthMethodID";
  81. LPCWSTR g_pszNumAuthInfos = L"NumAuthInfos";
  82. LPCWSTR g_pszAuthMethod = L"AuthMethod";
  83. LPCWSTR g_pszAuthInfoSize = L"AuthInfoSize";
  84. LPCWSTR g_pszAuthInfo = L"AuthInfo";
  85. LPCWSTR g_pszTokenGuid = L"TokenGuid";
  86. LPCWSTR g_pszAction = L"Action";
  87. LPCWSTR g_pszPreviousData = L"PreviousData";
  88. LPCWSTR g_pszFilterGuid = L"FilterGuid";
  89. LPCWSTR g_pszPolicyType = L"PolicyType";
  90. LPCWSTR g_pszRollback = L"Rollback";
  91. LPCWSTR g_pszClearAll = L"ClearAll";
  92. LPCWSTR g_pszEncryption = L"Encryption";
  93. //
  94. // constant strings for SPD data
  95. //
  96. LPCWSTR g_pszIP_ADDRESS_ME = L"IP_ADDRESS_ME";
  97. LPCWSTR g_pszIP_ADDRESS_MASK_NONE = L"IP_ADDRESS_MASK_NONE";
  98. LPCWSTR g_pszSUBNET_ADDRESS_ANY = L"SUBNET_ADDRESS_ANY";
  99. LPCWSTR g_pszSUBNET_MASK_ANY = L"SUBNET_MASK_ANY";
  100. //
  101. // these are WMI class property names for SCW
  102. //
  103. LPCWSTR g_pszPort = L"Port";
  104. //LPCWSTR g_pszProtocol = L"Protocol";
  105. LPCWSTR g_pszAddress = L"Address";
  106. LPCWSTR g_pszForeignAddress = L"ForeignAddress";
  107. LPCWSTR g_pszForeignPort = L"ForeignPort";
  108. LPCWSTR g_pszState = L"State"; //Listening, Established, TIME_WAIT
  109. LPCWSTR g_pszProcessID = L"ProcessID";
  110. LPCWSTR g_pszImageName = L"ImageName";
  111. LPCWSTR g_pszImageTitleBar = L"ImageTitleBar";
  112. LPCWSTR g_pszNTService = L"NTService";
  113. //
  114. // these are default quick mode policy names
  115. //
  116. LPCWSTR g_pszDefQMPolicyNegNone = L"SSR_DEFAULT_QM_POLICY_NEG_NONE";
  117. LPCWSTR g_pszDefQMPolicyNegRequest = L"SSR_DEFAULT_QM_POLICY_NEG_REQUEST";
  118. LPCWSTR g_pszDefQMPolicyNegRequire = L"SSR_DEFAULT_QM_POLICY_NEG_REQUIRE";
  119. LPCWSTR g_pszDefQMPolicyNegMax = L"SSR_DEFAULT_QM_POLICY_NEG_MAX";
  120. /*
  121. Routine Description:
  122. Name:
  123. CheckImpersonationLevel
  124. Functionality:
  125. Check the impersonation level of the thread to see if the level is at least SecurityImpersonation.
  126. Virtual:
  127. No.
  128. Arguments:
  129. None.
  130. Return Value:
  131. Success:
  132. WBEM_NO_ERROR if the impersonation level is at least SecurityImpersonation.
  133. Failure:
  134. (1) WBEM_E_ACCESS_DENIED.
  135. (2) WBEM_E_FAILED if somehow the thread token can't opened or the token information
  136. can't be queried.
  137. Notes:
  138. Make sure that you call this function at the begining of each provider's public interface function.
  139. $undone:shawnwu, is there a performance concern?
  140. */
  141. HRESULT
  142. CheckImpersonationLevel ()
  143. {
  144. HRESULT hr = WBEM_E_ACCESS_DENIED;
  145. if (SUCCEEDED(::CoImpersonateClient()))
  146. {
  147. //
  148. // Now, let's check the impersonation level. First, get the thread token
  149. //
  150. HANDLE hThreadTok;
  151. DWORD dwImp, dwBytesReturned;
  152. if(!::OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hThreadTok ))
  153. {
  154. hr = WBEM_E_FAILED;
  155. }
  156. else
  157. {
  158. if(::GetTokenInformation(hThreadTok, TokenImpersonationLevel, &dwImp, sizeof(DWORD), &dwBytesReturned))
  159. {
  160. //
  161. // Is the impersonation level Impersonate?
  162. //
  163. if (dwImp >= SecurityImpersonation)
  164. {
  165. hr = WBEM_NO_ERROR;
  166. }
  167. else
  168. {
  169. hr = WBEM_E_ACCESS_DENIED;
  170. }
  171. }
  172. else
  173. {
  174. hr = WBEM_E_FAILED;
  175. }
  176. ::CloseHandle(hThreadTok);
  177. }
  178. }
  179. return hr;
  180. }
  181. /*
  182. Routine Description:
  183. Name:
  184. CheckSafeArraySize
  185. Functionality:
  186. Check to see if the variant has really what the caller wants: a safearray with given count of elements.
  187. Virtual:
  188. No.
  189. Arguments:
  190. pVar - The variant.
  191. lCount - The claimed size of the variant's array.
  192. plLB - Receives the lower bound of the variant's array.
  193. plUB - Receives the upper bound of the variant's array.
  194. Return Value:
  195. Success:
  196. WBEM_NO_ERROR.
  197. Failure:
  198. (1) WBEM_E_VALUE_OUT_OF_RANGE if the claimed size for the variant doesn't match
  199. what it really holds.
  200. (2) WBEM_E_INVALID_PARAMETER if input parameters are not valid.
  201. Notes:
  202. */
  203. HRESULT
  204. CheckSafeArraySize (
  205. IN VARIANT * pVar,
  206. IN long lCount,
  207. OUT long * plLB,
  208. OUT long * plUB
  209. )
  210. {
  211. //
  212. // we must have a valid variant, and its type must be an array,
  213. // and its array value must not be null.
  214. //
  215. if (pVar == NULL ||
  216. (pVar->vt & VT_ARRAY) != VT_ARRAY ||
  217. pVar->parray == NULL ||
  218. plLB == NULL ||
  219. plUB == NULL)
  220. {
  221. return WBEM_E_INVALID_PARAMETER;
  222. }
  223. *plLB = 0;
  224. *plUB = 0;
  225. HRESULT hr = ::SafeArrayGetLBound(pVar->parray, 1, plLB);
  226. if (SUCCEEDED(hr))
  227. {
  228. hr = ::SafeArrayGetUBound(pVar->parray, 1, plUB);
  229. }
  230. if (SUCCEEDED(hr) && lCount != (*plUB - *plLB + 1) )
  231. {
  232. hr = WBEM_E_VALUE_OUT_OF_RANGE;
  233. }
  234. return SUCCEEDED(hr) ? WBEM_NO_ERROR : hr;
  235. }
  236. /*
  237. Routine Description:
  238. Name:
  239. GetDWORDSafeArrayElements
  240. Functionality:
  241. Get all DWORD safearray elements from the variant to the provided DWORD array buffer.
  242. Virtual:
  243. No.
  244. Arguments:
  245. pVar - The variant.
  246. lCount - The count the caller wants.
  247. ppValArray - Receives the wanted number of DWORD from the variant.
  248. Return Value:
  249. Success:
  250. WBEM_NO_ERROR.
  251. Failure:
  252. (1) WBEM_E_VALUE_OUT_OF_RANGE if the claimed size for the variant doesn't match
  253. what it really holds.
  254. (2) WBEM_E_INVALID_PARAMETER if input parameters are not valid.
  255. Notes:
  256. (1) Caller should call CheckSafeArraySize to make sure that this variant does have
  257. that many elements.
  258. (2) Caller is resonsible for making sure that pValArray has enough room for the dwords
  259. */
  260. HRESULT
  261. GetDWORDSafeArrayElements (
  262. IN VARIANT * pVar,
  263. IN long lCount,
  264. OUT DWORD * pValArray
  265. )
  266. {
  267. //
  268. // sanity check
  269. //
  270. if (pVar == NULL ||
  271. (pVar->vt & VT_ARRAY) != VT_ARRAY ||
  272. pVar->parray == NULL ||
  273. (lCount > 0 && pValArray == NULL) )
  274. {
  275. return WBEM_E_INVALID_PARAMETER;
  276. }
  277. long lLB;
  278. HRESULT hr = ::SafeArrayGetLBound(pVar->parray, 1, &lLB);
  279. long lIndexes[1];
  280. //
  281. // get the values from the safearray. Since safearray's index may not be 0-based,
  282. // we have to start from its lower bound. But our out parameter (array) is 0-based.
  283. // Be aware of this offset!
  284. //
  285. for (long l = lLB; l < lLB + lCount; l++)
  286. {
  287. lIndexes[0] = l;
  288. hr = ::SafeArrayGetElement(pVar->parray, lIndexes, &(pValArray[l - lLB]));
  289. //
  290. // we don't try to continue if we can't get one of them
  291. //
  292. if (FAILED(hr))
  293. {
  294. break;
  295. }
  296. }
  297. return hr;
  298. }
  299. /*
  300. Routine Description:
  301. Name:
  302. FindMMAuthMethodsByID
  303. Functionality:
  304. Given a guid, we will try to find all the main mode auth methods using the resume handle,
  305. which is a opaque data.
  306. Virtual:
  307. No.
  308. Arguments:
  309. pszGuid - The Main Mode Authentication Method's ID. This should be represent a guid.
  310. ppAuthMethod - Receives the MM_AUTH_METHODS data.
  311. pdwResumeHandle - In-bound: the current handle for this call. Out-bound: the next handle for the call.
  312. Return Value:
  313. Success:
  314. Various success codes. Use SUCCEEDED(hr) to test.
  315. Failure:
  316. Various error codes.
  317. Notes:
  318. */
  319. HRESULT
  320. FindMMAuthMethodsByID (
  321. IN LPCWSTR pszGuid,
  322. OUT PMM_AUTH_METHODS * ppAuthMethod,
  323. IN OUT DWORD * pdwResumeHandle
  324. )
  325. {
  326. GUID gID = GUID_NULL;
  327. //
  328. // We allow pssGuid to be invalid, in that case, we simply return any mm auth method.
  329. //
  330. HRESULT hr = WBEM_NO_ERROR;
  331. *ppAuthMethod = NULL;
  332. if (pszGuid != NULL && *pszGuid != L'\0')
  333. {
  334. hr = ::CLSIDFromString((LPWSTR)pszGuid, &gID);
  335. }
  336. if (SUCCEEDED(hr))
  337. {
  338. DWORD dwCount = 0;
  339. //
  340. // Enumerate all mm auth methods in a hope to find a matching one.
  341. //
  342. DWORD dwResult = ::EnumMMAuthMethods(NULL, ppAuthMethod, 1, &dwCount, pdwResumeHandle);
  343. hr = WBEM_E_NOT_FOUND;
  344. while (dwResult == ERROR_SUCCESS && dwCount > 0)
  345. {
  346. if (gID == GUID_NULL || (*ppAuthMethod)->gMMAuthID == gID)
  347. {
  348. hr = WBEM_NO_ERROR;
  349. break;
  350. }
  351. else
  352. {
  353. //
  354. // not this one, then release this one and find the next
  355. //
  356. ::SPDApiBufferFree(*ppAuthMethod);
  357. *ppAuthMethod = NULL;
  358. dwCount = 0;
  359. dwResult = ::EnumMMAuthMethods(NULL, ppAuthMethod, 1, &dwCount, pdwResumeHandle);
  360. }
  361. }
  362. }
  363. return hr;
  364. }
  365. /*
  366. Routine Description:
  367. Name:
  368. GetClassEnum
  369. Functionality:
  370. A helper function to create a class numeration object for the given name.
  371. Virtual:
  372. No.
  373. Arguments:
  374. pNamespace - The namespace where the enum object is requested.
  375. pszClassName - The class we want to enumerate.
  376. ppEnum - Receives the enumerator.
  377. Return Value:
  378. Other than WBEM_E_INVALID_PARAMETER and WBEM_E_OUT_OF_MEMORY,
  379. it returns whatever pNamespace->ExecQuery returns.
  380. Notes:
  381. */
  382. HRESULT
  383. GetClassEnum (
  384. IN IWbemServices * pNamespace,
  385. IN LPCWSTR pszClassName,
  386. OUT IEnumWbemClassObject ** ppEnum
  387. )
  388. {
  389. if ( NULL == pNamespace ||
  390. NULL == ppEnum ||
  391. NULL == pszClassName ||
  392. L'\0' == *pszClassName )
  393. {
  394. return WBEM_E_INVALID_PARAMETER;
  395. }
  396. *ppEnum = NULL;
  397. //
  398. // format the query
  399. //
  400. LPCWSTR pszQueryFmt = L"SELECT * FROM %s";
  401. DWORD dwLength = wcslen(pszQueryFmt) + wcslen(pszClassName) + 1;
  402. CComBSTR bstrQuery;
  403. bstrQuery.m_str = ::SysAllocStringLen(NULL, dwLength);
  404. if (bstrQuery.m_str == NULL)
  405. {
  406. return WBEM_E_OUT_OF_MEMORY;
  407. }
  408. swprintf(bstrQuery.m_str, pszQueryFmt, pszClassName);
  409. //
  410. // execute the query
  411. //
  412. return pNamespace->ExecQuery(L"WQL",
  413. bstrQuery,
  414. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
  415. NULL,
  416. ppEnum
  417. );
  418. }
  419. /*
  420. Routine Description:
  421. Name:
  422. DeleteRollbackObjects
  423. Functionality:
  424. Given the class name for rollback objects, we will delete all such rollback objects from WMI.
  425. Virtual:
  426. No.
  427. Arguments:
  428. pNamespace - The namespace the objects belong.
  429. pszClassName - The name of the class of the objects to be deleted.
  430. Return Value:
  431. Success:
  432. WBEM_NO_ERROR
  433. Failure:
  434. Various error codes.
  435. Notes:
  436. If during deletion we see an error, the deletion will continue, but we will return the first
  437. such error.
  438. */
  439. HRESULT
  440. DeleteRollbackObjects (
  441. IN IWbemServices * pNamespace,
  442. IN LPCWSTR pszClassName
  443. )
  444. {
  445. if ( NULL == pNamespace ||
  446. NULL == pszClassName ||
  447. L'\0' == *pszClassName )
  448. {
  449. return WBEM_E_INVALID_PARAMETER;
  450. }
  451. CComPtr<IEnumWbemClassObject> srpEnum;
  452. HRESULT hr = ::GetClassEnum(pNamespace, pszClassName, &srpEnum);
  453. if (FAILED(hr))
  454. {
  455. return hr;
  456. }
  457. //
  458. // go through all found classes
  459. //
  460. CComPtr<IWbemClassObject> srpObj;
  461. ULONG nEnum = 0;
  462. //
  463. // This will keep track of the first error
  464. //
  465. HRESULT hrError = WBEM_NO_ERROR;
  466. //
  467. // srpEnum->Next returns WBEM_S_FALSE once the end has reached.
  468. //
  469. hr = srpEnum->Next(WBEM_INFINITE, 1, &srpObj, &nEnum);
  470. while (SUCCEEDED(hr) && hr != WBEM_S_FALSE && srpObj)
  471. {
  472. CComVariant varPath;
  473. if (SUCCEEDED(srpObj->Get(L"__RelPath", 0, &varPath, NULL, NULL)) && varPath.vt == VT_BSTR)
  474. {
  475. //
  476. // now delete the instance
  477. //
  478. hr = pNamespace->DeleteInstance(varPath.bstrVal, 0, NULL, NULL);
  479. if (FAILED(hr) && SUCCEEDED(hrError))
  480. {
  481. hrError = hr;
  482. }
  483. }
  484. //
  485. // so that we can reuse it
  486. //
  487. srpObj.Release();
  488. //
  489. // next object
  490. //
  491. hr = srpEnum->Next(WBEM_INFINITE, 1, &srpObj, &nEnum);
  492. }
  493. //
  494. // make our return code easy since we are not going to pass different success codes
  495. //
  496. if (SUCCEEDED(hr))
  497. {
  498. hr = WBEM_NO_ERROR;
  499. }
  500. //
  501. // we will return the first error
  502. //
  503. return FAILED(hrError) ? hrError : hr;
  504. }
  505. /*
  506. Routine Description:
  507. Name:
  508. IPSecErrorToWbemError
  509. Functionality:
  510. Translate IPSec error into Wbem error
  511. Virtual:
  512. No.
  513. Arguments:
  514. dwErr - Error code from IPSec APIs
  515. Return Value:
  516. various Wbem error code
  517. Notes:
  518. WMI team simply can't give us enough information as how we can provide our own error text.
  519. This is not a good translation. Need more support from WMI team in order for us to support
  520. custom error information.
  521. */
  522. HRESULT IPSecErrorToWbemError (
  523. IN DWORD dwErr
  524. )
  525. {
  526. //
  527. // this is the last resort, not a good code at all
  528. //
  529. HRESULT hr = WBEM_E_FAILED;
  530. switch (dwErr)
  531. {
  532. case ERROR_IPSEC_QM_POLICY_EXISTS:
  533. case ERROR_IPSEC_MM_POLICY_EXISTS:
  534. case ERROR_IPSEC_MM_FILTER_EXISTS:
  535. case ERROR_IPSEC_TRANSPORT_FILTER_EXISTS:
  536. case ERROR_IPSEC_MM_AUTH_EXISTS:
  537. case ERROR_IPSEC_TUNNEL_FILTER_EXISTS:
  538. hr = WBEM_E_ALREADY_EXISTS;
  539. break;
  540. case ERROR_IPSEC_QM_POLICY_NOT_FOUND:
  541. case ERROR_IPSEC_MM_POLICY_NOT_FOUND:
  542. case ERROR_IPSEC_MM_FILTER_NOT_FOUND:
  543. case ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND:
  544. case ERROR_IPSEC_MM_AUTH_NOT_FOUND:
  545. case ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND:
  546. case ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND:
  547. case ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND:
  548. case ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND:
  549. hr = WBEM_E_NOT_FOUND;
  550. break;
  551. case ERROR_IPSEC_QM_POLICY_IN_USE:
  552. case ERROR_IPSEC_MM_POLICY_IN_USE:
  553. case ERROR_IPSEC_MM_AUTH_IN_USE:
  554. hr = WBEM_E_OVERRIDE_NOT_ALLOWED;
  555. }
  556. return hr;
  557. }