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.

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