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.

337 lines
8.5 KiB

  1. #include <unk.h>
  2. #include <wbemcli.h>
  3. #include <wbemprov.h>
  4. #include <atlbase.h>
  5. #include <sync.h>
  6. #include <activeds.h>
  7. #include <genlex.h>
  8. #include <objpath.h>
  9. #include <Utility.h>
  10. #include <ql.h>
  11. #include "PolicStatus.h"
  12. #ifdef TIME_TRIALS
  13. #include <StopWatch.h>
  14. #pragma message("!! Including time trial code !!")
  15. StopWatch EvaluateTimer(L"Somfilter Evaluation", L"C:\\Som.Evaluate.log");
  16. #endif
  17. /******************************\
  18. **** POLICY PROVIDER HELPERS ***
  19. \******************************/
  20. #define SOM_RDN L"CN=SOM,CN=WMIPolicy,CN=System"
  21. // returns addref'd pointer back to WinMgmt
  22. CComPtr<IWbemServices>& CPolicyStatus::GetWMIServices()
  23. {
  24. CInCritSec lock(&m_CS);
  25. return m_pWMIMgmt;
  26. }
  27. IADsContainer *CPolicyStatus::GetADServices(wchar_t *pDomain, HRESULT &hres)
  28. {
  29. CInCritSec lock(&m_CS);
  30. IADsContainer *pADsContainer = NULL;
  31. QString
  32. SomDN(SOM_RDN),
  33. DistDomainName,
  34. ObjPath(L"LDAP://");
  35. if(NULL == pDomain) return NULL;
  36. hres = DistNameFromDomainName(QString(pDomain), DistDomainName);
  37. ObjPath << DistDomainName;
  38. hres = ADsGetObject(ObjPath, IID_IADsContainer, (void**) &pADsContainer);
  39. return pADsContainer;
  40. }
  41. IADsContainer *GetADSchemaContainer(wchar_t *pDomain, HRESULT &hres)
  42. {
  43. CComQIPtr<IADs>
  44. pRootDSE;
  45. CComVariant
  46. vSchemaPath;
  47. CComBSTR
  48. bstrSchemaPath(L"LDAP://");
  49. IADsContainer
  50. *pADsContainer = NULL;
  51. if(NULL == pDomain) return NULL;
  52. hres = ADsGetObject(L"LDAP://rootDSE", IID_IADs, (void **)&pRootDSE);
  53. if(FAILED(hres)) return NULL;
  54. hres = pRootDSE->Get(L"schemaNamingContext", &vSchemaPath);
  55. if(FAILED(hres)) return NULL;
  56. bstrSchemaPath.Append(vSchemaPath.bstrVal);
  57. hres = ADsGetObject(bstrSchemaPath, IID_IADsContainer, (void **)&pADsContainer);
  58. if(FAILED(hres)) return NULL;
  59. return pADsContainer;
  60. }
  61. // returns false if services pointer has already been set
  62. bool CPolicyStatus::SetWMIServices(IWbemServices* pServices)
  63. {
  64. CInCritSec lock(&m_CS);
  65. bool bOldOneNull = FALSE;
  66. if (bOldOneNull = (m_pWMIMgmt == NULL))
  67. {
  68. m_pWMIMgmt = pServices;
  69. }
  70. return bOldOneNull;
  71. }
  72. void* CPolicyStatus::GetInterface(REFIID riid)
  73. {
  74. if(riid == IID_IWbemServices)
  75. return &m_XProvider;
  76. else if(riid == IID_IWbemProviderInit)
  77. return &m_XInit;
  78. else return NULL;
  79. }
  80. /*********************************\
  81. *** Specific Implementation ***
  82. \*********************************/
  83. // returns addref'd pointer to class object
  84. IWbemClassObject* CPolicyStatus::GetStatusClass()
  85. {
  86. CInCritSec lock(&m_CS);
  87. if (m_pStatusClassObject == NULL)
  88. {
  89. CComPtr<IWbemServices> pWinMgmt = GetWMIServices();
  90. if (pWinMgmt != NULL)
  91. {
  92. pWinMgmt->GetObject(STATUS_CLASS, WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &m_pStatusClassObject, NULL);
  93. }
  94. }
  95. return m_pStatusClassObject;
  96. }
  97. // returns addref'd pointer to emply class instance
  98. IWbemClassObject* CPolicyStatus::GetStatusInstance()
  99. {
  100. CComPtr<IWbemClassObject> pClass;
  101. IWbemClassObject *pObj = NULL;
  102. pClass = GetStatusClass();
  103. if(pClass != NULL)
  104. pClass->SpawnInstance(0, &pObj);
  105. return pObj;
  106. }
  107. /*************************\
  108. *** IWbemProviderInit ***
  109. \*************************/
  110. STDMETHODIMP CPolicyStatus::XInit::Initialize(
  111. LPWSTR, LONG, LPWSTR, LPWSTR, IWbemServices* pServices, IWbemContext* pCtxt,
  112. IWbemProviderInitSink* pSink)
  113. {
  114. HRESULT
  115. hres = WBEM_S_NO_ERROR,
  116. hres2 = WBEM_S_NO_ERROR;
  117. // **** impersonate client for security
  118. hres = CoImpersonateClient();
  119. if(FAILED(hres))
  120. {
  121. ERRORTRACE((LOG_ESS, "POLICMAN: (CoImpersonateClient) could not assume client permissions, 0x%08X\n", hres));
  122. return WBEM_S_ACCESS_DENIED;
  123. }
  124. else
  125. {
  126. // **** save WMI name space pointer
  127. m_pObject->SetWMIServices(pServices);
  128. }
  129. hres2 = pSink->SetStatus(hres, 0);
  130. if(FAILED(hres2))
  131. {
  132. ERRORTRACE((LOG_ESS, "POLICMAN: could not set return status\n"));
  133. if(SUCCEEDED(hres)) hres = hres2;
  134. }
  135. return hres;
  136. }
  137. /*******************\
  138. *** IWbemServices ***
  139. \*******************/
  140. STDMETHODIMP CPolicyStatus::XProvider::GetObjectAsync(
  141. /* [in] */ const BSTR ObjectPath,
  142. /* [in] */ long lFlags,
  143. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  144. /* [in] */ IWbemObjectSink __RPC_FAR *pResponseHandler)
  145. {
  146. HRESULT
  147. hres = WBEM_S_NO_ERROR,
  148. hres2 = WBEM_S_NO_ERROR;
  149. CComPtr<IWbemServices>
  150. pNamespace;
  151. CComPtr<IADsContainer>
  152. pADsSchemaContainer,
  153. pADsContainer;
  154. VARIANT
  155. *vDomain;
  156. // **** impersonate client for security
  157. hres = CoImpersonateClient();
  158. if (FAILED(hres))
  159. {
  160. ERRORTRACE((LOG_ESS, "POLICMAN: (CoImpersonateClient) could not assume callers permissions, 0x%08X\n",hres));
  161. hres = WBEM_E_ACCESS_DENIED;
  162. }
  163. else
  164. {
  165. // **** Check arguments
  166. if(ObjectPath == NULL || pResponseHandler == NULL)
  167. {
  168. ERRORTRACE((LOG_ESS, "POLICMAN: object path and/or return object are NULL\n"));
  169. hres = WBEM_E_INVALID_PARAMETER;
  170. }
  171. else
  172. {
  173. // **** parse object path
  174. CObjectPathParser
  175. ObjPath(e_ParserAcceptRelativeNamespace);
  176. ParsedObjectPath
  177. *pParsedObjectPath = NULL;
  178. if((ObjPath.NoError != ObjPath.Parse(ObjectPath, &pParsedObjectPath)) ||
  179. (0 != _wcsicmp(STATUS_CLASS, pParsedObjectPath->m_pClass)) ||
  180. (1 != pParsedObjectPath->m_dwNumKeys))
  181. {
  182. ERRORTRACE((LOG_ESS, "POLICMAN: Parse error for object: %S\n", ObjectPath));
  183. hres = WBEM_E_INVALID_QUERY;
  184. }
  185. else
  186. {
  187. int x;
  188. for(x = 0; x < pParsedObjectPath->m_dwNumKeys; x++)
  189. {
  190. if(0 == _wcsicmp((*(pParsedObjectPath->m_paKeys + x))->m_pName, g_bstrDomain))
  191. vDomain = &((*(pParsedObjectPath->m_paKeys + x))->m_vValue);
  192. }
  193. if(vDomain->bstrVal == NULL)
  194. hres = WBEM_E_FAILED;
  195. else
  196. {
  197. pNamespace = m_pObject->GetWMIServices();
  198. pADsContainer.Attach(m_pObject->GetADServices(vDomain->bstrVal, hres));
  199. pADsSchemaContainer.Attach(GetADSchemaContainer(vDomain->bstrVal, hres));
  200. }
  201. if((FAILED(hres)) || (pNamespace == NULL) || (pADsContainer == NULL))
  202. {
  203. ERRORTRACE((LOG_ESS, "POLICMAN: WMI and/or AD services not initialized\n"));
  204. hres = ADSIToWMIErrorCodes(hres);
  205. }
  206. else
  207. {
  208. try
  209. {
  210. CComPtr<IWbemClassObject>
  211. pStatusObj;
  212. CComQIPtr<IDispatch, &IID_IDispatch>
  213. pDisp1, pDisp2;
  214. CComQIPtr<IDirectoryObject, &IID_IDirectoryObject>
  215. pDirectoryObj;
  216. VARIANT
  217. vContainerPresent = {VT_BOOL, 0, 0, 0},
  218. vSchemaPresent = {VT_BOOL, 0, 0, 0};
  219. pStatusObj.Attach(m_pObject->GetStatusInstance());
  220. if(pStatusObj != NULL)
  221. {
  222. // **** test for existence of containers
  223. hres = pADsContainer->GetObject(L"Container", L"CN=SOM,CN=WMIPolicy,CN=System", &pDisp1);
  224. if(SUCCEEDED(hres) && (pDisp1.p != NULL)) vContainerPresent.boolVal = -1;
  225. // **** test for existence of schema object
  226. hres = pADsSchemaContainer->GetObject(L"classSchema", L"CN=ms-WMI-Som", &pDisp2);
  227. if(SUCCEEDED(hres) && (pDisp2.p != NULL)) vSchemaPresent.boolVal = -1;
  228. // **** build status object
  229. hres = pStatusObj->Put(L"Domain", 0, vDomain, 0);
  230. hres = pStatusObj->Put(L"ContainerAvailable", 0, &vContainerPresent, 0);
  231. hres = pStatusObj->Put(L"SchemaAvailable", 0, &vSchemaPresent, 0);
  232. hres = pResponseHandler->Indicate(1, &pStatusObj);
  233. }
  234. else
  235. hres = WBEM_E_FAILED;
  236. }
  237. catch(long hret)
  238. {
  239. hres = ADSIToWMIErrorCodes(hret);
  240. ERRORTRACE((LOG_ESS, "POLICMAN: Translation of Policy object from AD to WMI generated HRESULT 0x%08X\n", hres));
  241. }
  242. catch(wchar_t *swErrString)
  243. {
  244. ERRORTRACE((LOG_ESS, "POLICMAN: Caught Exception: %S\n", swErrString));
  245. hres = WBEM_E_FAILED;
  246. }
  247. catch(...)
  248. {
  249. ERRORTRACE((LOG_ESS, "POLICMAN: Caught UNKNOWN Exception\n"));
  250. hres = WBEM_E_FAILED;
  251. }
  252. }
  253. }
  254. ObjPath.Free(pParsedObjectPath);
  255. hres2 = pResponseHandler->SetStatus(0,hres, NULL, NULL);
  256. if(FAILED(hres2))
  257. {
  258. ERRORTRACE((LOG_ESS, "POLICMAN: could not set return status\n"));
  259. if(SUCCEEDED(hres)) hres = hres2;
  260. }
  261. }
  262. CoRevertToSelf();
  263. }
  264. return hres;
  265. }