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.

1034 lines
30 KiB

  1. #undef _WIN32_WINNT
  2. #define _WIN32_WINNT 0x0500
  3. #include <wbemcli.h>
  4. #include <wbemprov.h>
  5. #include <atlbase.h>
  6. #include <stdio.h> // fprintf
  7. #include <stdlib.h>
  8. #include <locale.h>
  9. #include <genlex.h>
  10. #include <qllex.h>
  11. #include <ql.h>
  12. #include <ntdsapi.h>
  13. #include "objpath.h"
  14. #include "iads.h"
  15. #include "adshlp.h"
  16. #include "Utility.h"
  17. #include <SDDL.H>
  18. BSTR
  19. // **** misc names
  20. g_bstrEmptyString = NULL,
  21. g_bstrEmptyDate = NULL,
  22. // **** AD schema names
  23. g_bstrADAuthor = NULL,
  24. g_bstrADChangeDate = NULL,
  25. g_bstrADClassDefinition = NULL,
  26. g_bstrADCreationDate = NULL,
  27. g_bstrADDescription = NULL,
  28. g_bstrADIntDefault = NULL,
  29. g_bstrADInt8Default = NULL,
  30. g_bstrADID = NULL,
  31. g_bstrADIntMax = NULL,
  32. g_bstrADInt8Max = NULL,
  33. g_bstrADIntMin = NULL,
  34. g_bstrADInt8Min = NULL,
  35. g_bstrADIntValidValues = NULL,
  36. g_bstrADName = NULL,
  37. g_bstrADNormalizedClass = NULL,
  38. g_bstrADObjectClass = NULL,
  39. g_bstrADParam2 = NULL,
  40. g_bstrADPolicyType = NULL,
  41. g_bstrADPropertyName = NULL,
  42. g_bstrADQuery = NULL,
  43. g_bstrADQueryLanguage = NULL,
  44. g_bstrADSourceOrganization = NULL,
  45. g_bstrADStringDefault = NULL,
  46. g_bstrADStringValidValues = NULL,
  47. g_bstrADTargetClass = NULL,
  48. g_bstrADTargetNameSpace = NULL,
  49. g_bstrADTargetObject = NULL,
  50. g_bstrADTargetPath = NULL,
  51. g_bstrADTargetType = NULL,
  52. // **** AD class names
  53. g_bstrADClassMergeablePolicy = NULL,
  54. g_bstrADClassRangeParam = NULL,
  55. g_bstrADClassRangeSint32 = NULL,
  56. g_bstrADClassRangeUint32 = NULL,
  57. g_bstrADClassRangeReal = NULL,
  58. g_bstrADClassParamUnknown = NULL,
  59. g_bstrADClassSetSint32 = NULL,
  60. g_bstrADClassSetUint32 = NULL,
  61. g_bstrADClassSetString = NULL,
  62. g_bstrADClassSimplePolicy = NULL,
  63. g_bstrADClassRule = NULL,
  64. g_bstrADClassSom = NULL,
  65. g_bstrADClassPolicyType = NULL,
  66. g_bstrADClassWMIGPO = NULL,
  67. // **** CIM schema names
  68. g_bstrAuthor = NULL,
  69. g_bstrChangeDate = NULL,
  70. g_bstrClassDefinition = NULL,
  71. g_bstrCreationDate = NULL,
  72. g_bstrDefault = NULL,
  73. g_bstrDescription = NULL,
  74. g_bstrDsPath = NULL,
  75. g_bstrDomain = NULL,
  76. g_bstrID = NULL,
  77. g_bstrMax = NULL,
  78. g_bstrMin = NULL,
  79. g_bstrName = NULL,
  80. g_bstrPolicyType = NULL,
  81. g_bstrPropertyName = NULL,
  82. g_bstrQuery = NULL,
  83. g_bstrQueryLanguage = NULL,
  84. g_bstrRangeSettings = NULL,
  85. g_bstrRules = NULL,
  86. g_bstrSourceOrganization = NULL,
  87. g_bstrTargetClass = NULL,
  88. g_bstrTargetNameSpace = NULL,
  89. g_bstrTargetObject = NULL,
  90. g_bstrTargetPath = NULL,
  91. g_bstrTargetType = NULL,
  92. g_bstrValidValues = NULL,
  93. // **** CIM class names
  94. g_bstrClassMergeablePolicy = NULL,
  95. g_bstrClassRangeParam = NULL,
  96. g_bstrClassRangeSint32 = NULL,
  97. g_bstrClassRangeUint32 = NULL,
  98. g_bstrClassRangeReal = NULL,
  99. g_bstrClassSetSint32 = NULL,
  100. g_bstrClassSetUint32 = NULL,
  101. g_bstrClassSetString = NULL,
  102. g_bstrClassSimplePolicy = NULL,
  103. g_bstrClassRule = NULL,
  104. g_bstrClassSom = NULL,
  105. g_bstrClassPolicyType = NULL,
  106. g_bstrClassWMIGPO = NULL;
  107. void InitGlobalNames(void)
  108. {
  109. // **** misc names
  110. g_bstrEmptyString = SysAllocString(L" ");
  111. g_bstrEmptyDate = SysAllocString(L"00000000000000.000000-000");
  112. // **** AD schema names
  113. g_bstrADAuthor = SysAllocString(L"msWMI-Author");
  114. g_bstrADChangeDate = SysAllocString(L"msWMI-ChangeDate");
  115. g_bstrADClassDefinition = SysAllocString(L"msWMI-ClassDefinition"),
  116. g_bstrADCreationDate = SysAllocString(L"msWMI-CreationDate");
  117. g_bstrADDescription = SysAllocString(L"msWMI-Parm1");
  118. g_bstrADIntDefault = SysAllocString(L"msWMI-IntDefault");
  119. g_bstrADInt8Default = SysAllocString(L"msWMI-Int8Default");
  120. g_bstrADID = SysAllocString(L"msWMI-ID");
  121. g_bstrADIntMax = SysAllocString(L"msWMI-IntMax");
  122. g_bstrADInt8Max = SysAllocString(L"msWMI-Int8Max");
  123. g_bstrADIntMin = SysAllocString(L"msWMI-IntMin");
  124. g_bstrADInt8Min = SysAllocString(L"msWMI-Int8Min");
  125. g_bstrADIntValidValues = SysAllocString(L"msWMI-IntValidValues");
  126. g_bstrADName = SysAllocString(L"msWMI-Name");
  127. g_bstrADNormalizedClass = SysAllocString(L"msWMI-NormalizedClass");
  128. g_bstrADObjectClass = SysAllocString(L"objectClass"),
  129. g_bstrADParam2 = SysAllocString(L"msWMI-Parm2"),
  130. g_bstrADPolicyType = SysAllocString(L"msWMI-PolicyType");
  131. g_bstrADPropertyName = SysAllocString(L"msWMI-PropertyName");
  132. g_bstrADQuery = SysAllocString(L"msWMI-Query"),
  133. g_bstrADQueryLanguage = SysAllocString(L"msWMI-QueryLanguage"),
  134. g_bstrADStringDefault = SysAllocString(L"msWMI-StringDefault");
  135. g_bstrADStringValidValues = SysAllocString(L"msWMI-StringValidValues");
  136. g_bstrADSourceOrganization = SysAllocString(L"msWMI-SourceOrganization");
  137. g_bstrADTargetClass = SysAllocString(L"msWMI-TargetClass");
  138. g_bstrADTargetNameSpace = SysAllocString(L"msWMI-TargetNameSpace");
  139. g_bstrADTargetObject = SysAllocString(L"msWMI-TargetObject"),
  140. g_bstrADTargetPath = SysAllocString(L"msWMI-TargetPath"),
  141. g_bstrADTargetType = SysAllocString(L"msWMI-TargetType"),
  142. // **** AD class names
  143. g_bstrADClassMergeablePolicy = SysAllocString(L"msWMI-MergeablePolicyTemplate");
  144. g_bstrADClassRangeParam = SysAllocString(L"msWMI-RangeParam");
  145. g_bstrADClassRangeSint32 = SysAllocString(L"msWMI-IntRangeParam");
  146. g_bstrADClassRangeUint32 = SysAllocString(L"msWMI-UintRangeParam");
  147. g_bstrADClassRangeReal = SysAllocString(L"msWMI-RealRangeParam");
  148. g_bstrADClassParamUnknown = SysAllocString(L"msWMI-UnknownRangeParam");
  149. g_bstrADClassSetSint32 = SysAllocString(L"msWMI-IntSetParam");
  150. g_bstrADClassSetUint32 = SysAllocString(L"msWMI-UintSetParam");
  151. g_bstrADClassSetString = SysAllocString(L"msWMI-StringSetParam");
  152. g_bstrADClassSimplePolicy = SysAllocString(L"msWMI-SimplePolicyTemplate");
  153. g_bstrADClassRule = SysAllocString(L"msWMI-Rule");
  154. g_bstrADClassSom = SysAllocString(L"msWMI-SOM");
  155. g_bstrADClassPolicyType = SysAllocString(L"msWMI-PolicyType");
  156. g_bstrADClassWMIGPO = SysAllocString(L"msWMI-WMIGPO");
  157. // **** CIM Attribute Names
  158. g_bstrAuthor = SysAllocString(L"Author");
  159. g_bstrChangeDate = SysAllocString(L"ChangeDate");
  160. g_bstrClassDefinition = SysAllocString(L"ClassDefinition"),
  161. g_bstrCreationDate = SysAllocString(L"CreationDate");
  162. g_bstrDefault = SysAllocString(L"Default");
  163. g_bstrDescription = SysAllocString(L"Description");
  164. g_bstrDsPath = SysAllocString(L"DsPath");
  165. g_bstrDomain = SysAllocString(L"Domain");
  166. g_bstrID = SysAllocString(L"ID");
  167. g_bstrMax = SysAllocString(L"Max");
  168. g_bstrMin = SysAllocString(L"Min");
  169. g_bstrName = SysAllocString(L"Name");
  170. g_bstrPolicyType = SysAllocString(L"PolicyType");
  171. g_bstrPropertyName = SysAllocString(L"PropertyName");
  172. g_bstrQuery = SysAllocString(L"query");
  173. g_bstrQueryLanguage = SysAllocString(L"QueryLanguage");
  174. g_bstrRangeSettings = SysAllocString(L"RangeSettings");
  175. g_bstrRules = SysAllocString(L"Rules");
  176. g_bstrSourceOrganization = SysAllocString(L"SourceOrganization");
  177. g_bstrTargetClass = SysAllocString(L"TargetClass"),
  178. g_bstrTargetNameSpace = SysAllocString(L"TargetNamespace");
  179. g_bstrTargetObject = SysAllocString(L"TargetObject"),
  180. g_bstrTargetPath = SysAllocString(L"TargetPath"),
  181. g_bstrTargetType = SysAllocString(L"TargetType"),
  182. g_bstrValidValues = SysAllocString(L"ValidValues");
  183. // **** CIM class names
  184. g_bstrClassMergeablePolicy = SysAllocString(L"MSFT_MergeablePolicyTemplate");
  185. g_bstrClassRangeParam = SysAllocString(L"MSFT_RangeParam");
  186. g_bstrClassRangeSint32 = SysAllocString(L"MSFT_SintRangeParam");
  187. g_bstrClassRangeUint32 = SysAllocString(L"MSFT_UintRangeParam");
  188. g_bstrClassRangeReal = SysAllocString(L"MSFT_RealRangeParam");
  189. g_bstrClassSetSint32 = SysAllocString(L"MSFT_SintSetParam");
  190. g_bstrClassSetUint32 = SysAllocString(L"MSFT_UintSetParam");
  191. g_bstrClassSetString = SysAllocString(L"MSFT_StringSetParam");
  192. g_bstrClassSimplePolicy = SysAllocString(L"MSFT_SimplePolicyTemplate");
  193. g_bstrClassRule = SysAllocString(L"MSFT_Rule");
  194. g_bstrClassSom = SysAllocString(L"MSFT_SomFilter");
  195. g_bstrClassPolicyType = SysAllocString(L"MSFT_PolicyType");
  196. g_bstrClassWMIGPO = SysAllocString(L"MSFT_WMIGPO");
  197. }
  198. void FreeGlobalNames(void)
  199. {
  200. // **** misc names
  201. SysFreeString(g_bstrEmptyString);
  202. SysFreeString(g_bstrEmptyDate);
  203. // **** AD schema names
  204. SysFreeString(g_bstrADAuthor);
  205. SysFreeString(g_bstrADChangeDate);
  206. SysFreeString(g_bstrADClassDefinition);
  207. SysFreeString(g_bstrADCreationDate);
  208. SysFreeString(g_bstrADIntDefault);
  209. SysFreeString(g_bstrADInt8Default);
  210. SysFreeString(g_bstrADID);
  211. SysFreeString(g_bstrADIntMax);
  212. SysFreeString(g_bstrADInt8Max);
  213. SysFreeString(g_bstrADIntMin);
  214. SysFreeString(g_bstrADInt8Min);
  215. SysFreeString(g_bstrADIntValidValues);
  216. SysFreeString(g_bstrADName);
  217. SysFreeString(g_bstrADNormalizedClass);
  218. SysFreeString(g_bstrADObjectClass);
  219. SysFreeString(g_bstrADParam2),
  220. SysFreeString(g_bstrADPolicyType);
  221. SysFreeString(g_bstrADPropertyName);
  222. SysFreeString(g_bstrADQuery);
  223. SysFreeString(g_bstrADQueryLanguage);
  224. SysFreeString(g_bstrADStringDefault);
  225. SysFreeString(g_bstrADStringValidValues);
  226. SysFreeString(g_bstrADSourceOrganization);
  227. SysFreeString(g_bstrADTargetClass);
  228. SysFreeString(g_bstrADTargetNameSpace);
  229. SysFreeString(g_bstrADTargetObject);
  230. SysFreeString(g_bstrADTargetPath);
  231. SysFreeString(g_bstrADTargetType);
  232. // **** AD class names
  233. SysFreeString(g_bstrADClassMergeablePolicy);
  234. SysFreeString(g_bstrADClassRangeParam);
  235. SysFreeString(g_bstrADClassRangeSint32);
  236. SysFreeString(g_bstrADClassRangeUint32);
  237. SysFreeString(g_bstrADClassRangeReal);
  238. SysFreeString(g_bstrADClassParamUnknown);
  239. SysFreeString(g_bstrADClassSetSint32);
  240. SysFreeString(g_bstrADClassSetUint32);
  241. SysFreeString(g_bstrADClassSetString);
  242. SysFreeString(g_bstrADClassSimplePolicy);
  243. SysFreeString(g_bstrADClassRule);
  244. SysFreeString(g_bstrADClassSom);
  245. SysFreeString(g_bstrADClassPolicyType);
  246. SysFreeString(g_bstrADClassWMIGPO);
  247. // **** CIM Attribute Names
  248. SysFreeString(g_bstrAuthor);
  249. SysFreeString(g_bstrChangeDate);
  250. SysFreeString(g_bstrClassDefinition);
  251. SysFreeString(g_bstrCreationDate);
  252. SysFreeString(g_bstrDefault);
  253. SysFreeString(g_bstrDsPath);
  254. SysFreeString(g_bstrDomain);
  255. SysFreeString(g_bstrID);
  256. SysFreeString(g_bstrMax);
  257. SysFreeString(g_bstrMin);
  258. SysFreeString(g_bstrName);
  259. SysFreeString(g_bstrPolicyType);
  260. SysFreeString(g_bstrPropertyName);
  261. SysFreeString(g_bstrQuery);
  262. SysFreeString(g_bstrQueryLanguage);
  263. SysFreeString(g_bstrRangeSettings);
  264. SysFreeString(g_bstrRules);
  265. SysFreeString(g_bstrSourceOrganization);
  266. SysFreeString(g_bstrTargetClass);
  267. SysFreeString(g_bstrTargetNameSpace);
  268. SysFreeString(g_bstrTargetObject);
  269. SysFreeString(g_bstrTargetPath);
  270. SysFreeString(g_bstrTargetType);
  271. SysFreeString(g_bstrValidValues);
  272. // **** CIM class names
  273. SysFreeString(g_bstrClassMergeablePolicy);
  274. SysFreeString(g_bstrClassRangeParam);
  275. SysFreeString(g_bstrClassRangeSint32);
  276. SysFreeString(g_bstrClassRangeUint32);
  277. SysFreeString(g_bstrClassRangeReal);
  278. SysFreeString(g_bstrClassSetSint32);
  279. SysFreeString(g_bstrClassSetUint32);
  280. SysFreeString(g_bstrClassSetString);
  281. SysFreeString(g_bstrClassSimplePolicy);
  282. SysFreeString(g_bstrClassRule);
  283. SysFreeString(g_bstrClassSom);
  284. SysFreeString(g_bstrClassPolicyType);
  285. SysFreeString(g_bstrClassWMIGPO);
  286. }
  287. // TODO: attempt to create namespace if not available.
  288. HRESULT GetNamespace(BSTR namespaceName, IWbemServices*& pNamespace, bool bInProc)
  289. {
  290. HRESULT hr = WBEM_E_FAILED;
  291. IWbemLocator* pLoc = NULL;
  292. if (FAILED(hr = CoCreateInstance(bInProc ? CLSID_WbemAdministrativeLocator : CLSID_WbemLocator,
  293. 0, CLSCTX_ALL, IID_IWbemLocator,
  294. (LPVOID*) &pLoc)))
  295. ERRORTRACE((LOG_ESS, "Could not create wbem locator (0x%08X)\n", hr));
  296. else
  297. {
  298. DEBUGTRACE((LOG_ESS, "Created Locator\n"));
  299. if (FAILED(hr = pLoc->ConnectServer(namespaceName, NULL,NULL, 0,0,0,0,&pNamespace)))
  300. ERRORTRACE((LOG_ESS, "ConnectServer(%S) failed (0x%08X)\n", namespaceName, hr));
  301. else
  302. DEBUGTRACE((LOG_ESS, "ConnectServer(%S) succeeded (0x%08X)\n", namespaceName, hr));
  303. pLoc->Release();
  304. }
  305. return hr;
  306. }
  307. // make sure that the ID property of pObj has a value
  308. // assumes property is a BSTR!
  309. // will generate GUID if not
  310. // if pName == NULL, assumes property name is "ID"
  311. // returns WBEM_S_NO_ERROR if ID generated
  312. // WBEM_S_FALSE if no ID generated (already has a value)
  313. // WBEM_E_NOT_FOUND if ID property is not
  314. // some error if error of some sort
  315. HRESULT EnsureID(IWbemClassObject* pObj, WCHAR* pName)
  316. {
  317. HRESULT hr = WBEM_S_NO_ERROR;
  318. WCHAR* pKeyName = (pName == NULL) ? L"ID" : pName;
  319. CComVariant
  320. v;
  321. if (SUCCEEDED(hr = pObj->Get(pKeyName, 0, &v, NULL, NULL)))
  322. {
  323. if ((v.vt == VT_NULL) || (v.bstrVal == NULL))
  324. {
  325. GUID guid;
  326. CoCreateGuid(&guid);
  327. BSTR guidStr = SysAllocStringByteLen(NULL, 129);
  328. if (guidStr == NULL)
  329. hr = WBEM_E_OUT_OF_MEMORY;
  330. else
  331. {
  332. StringFromGUID2(guid, guidStr, 128);
  333. VARIANT v;
  334. VariantInit(&v);
  335. v.vt = VT_BSTR;
  336. v.bstrVal = guidStr;
  337. pObj->Put(pKeyName, 0, &v, NULL);
  338. SysFreeString(guidStr);
  339. }
  340. }
  341. else
  342. {
  343. VariantClear(&v);
  344. hr = WBEM_S_FALSE;
  345. }
  346. }
  347. return hr;
  348. }
  349. void Init_AdsAttrInfo(ADS_ATTR_INFO *pAdsAttrInfo,
  350. LPWSTR bstrName,
  351. DWORD control,
  352. ADSTYPE type,
  353. PADSVALUE pVals,
  354. DWORD nVals)
  355. {
  356. unsigned long c1;
  357. if(NULL == pAdsAttrInfo) return;
  358. pAdsAttrInfo->pszAttrName = bstrName;
  359. pAdsAttrInfo->dwControlCode = control;
  360. pAdsAttrInfo->dwADsType = type;
  361. if(nVals > 0)
  362. {
  363. pAdsAttrInfo->dwNumValues = nVals;
  364. if(NULL != pVals)
  365. {
  366. pAdsAttrInfo->pADsValues = pVals;
  367. }
  368. else
  369. {
  370. throw L"could not init ADS_ATTR_INFO structure";
  371. }
  372. for(c1 = 0; c1 < nVals; c1++)
  373. {
  374. (pAdsAttrInfo->pADsValues + c1)->dwType = type;
  375. }
  376. }
  377. else
  378. {
  379. pAdsAttrInfo->dwNumValues = 0;
  380. pAdsAttrInfo->pADsValues = NULL;
  381. }
  382. }
  383. HRESULT DomainNameFromDistName(QString &DomainName, QString &DistName)
  384. {
  385. UINT
  386. lDCStart = 0,
  387. lDCEnd = 0;
  388. while(QString::NOT_FOUND != DistName.NextPattern(lDCEnd, L"DC=", lDCStart))
  389. {
  390. if(QString::NOT_FOUND != DistName.NextChar(lDCStart, L",", lDCEnd))
  391. DomainName.SubStrCat(DistName, lDCStart + 3, lDCEnd - 1) << L".";
  392. else
  393. {
  394. lDCEnd = DistName.StringLength();
  395. DomainName.SubStrCat(DistName, lDCStart + 3, lDCEnd);
  396. }
  397. }
  398. return WBEM_S_NO_ERROR;
  399. }
  400. HRESULT DistNameFromDomainName(QString &DomainName, QString &DistName)
  401. {
  402. if(0 == DomainName.StringLength())
  403. return WBEM_E_FAILED;
  404. UINT
  405. lStart = 0,
  406. lEnd = 0;
  407. while(QString::NOT_FOUND != DomainName.NextChar(lStart, L".", lEnd))
  408. {
  409. if(lEnd)
  410. {
  411. DistName << L"DC=";
  412. DistName.SubStrCat(DomainName, lStart, lEnd - 1);
  413. lStart = lEnd + 1;
  414. DistName << L",";
  415. }
  416. }
  417. if(0 < lEnd)
  418. {
  419. DistName << L"DC=";
  420. DistName.SubStrCat(DomainName, lStart, DomainName.StringLength());
  421. }
  422. return WBEM_S_NO_ERROR;
  423. }
  424. IADsContainer *CreateContainer(BSTR bstrPath, BSTR bstrName)
  425. {
  426. HRESULT hres;
  427. CComPtr<IDispatch>
  428. pDisp;
  429. CComPtr<IDirectoryObject>
  430. pDirObj;
  431. IADsContainer
  432. *pADsContainer = NULL;
  433. ADSVALUE
  434. AdsValue[2];
  435. ADS_ATTR_INFO
  436. attrInfo[] =
  437. {
  438. { g_bstrADObjectClass, ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &AdsValue[0], 1},
  439. { L"ntSecurityDescriptor", ADS_ATTR_UPDATE, ADSTYPE_NT_SECURITY_DESCRIPTOR, &AdsValue[1], 1}
  440. };
  441. CNtSecurityDescriptor
  442. cSD;
  443. hres = CreateDefaultSecurityDescriptor(cSD);
  444. if (FAILED(hres))
  445. {
  446. ERRORTRACE((LOG_ESS, "POLICMAN: could not create security descriptor\n"));
  447. return NULL;
  448. }
  449. AdsValue[0].dwType = ADSTYPE_CASE_IGNORE_STRING;
  450. AdsValue[0].CaseIgnoreString = L"Container";
  451. AdsValue[1].dwType = ADSTYPE_NT_SECURITY_DESCRIPTOR;
  452. AdsValue[1].SecurityDescriptor.dwLength = cSD.GetSize();
  453. AdsValue[1].SecurityDescriptor.lpValue = (LPBYTE)cSD.GetPtr();
  454. hres = ADsGetObject(bstrPath, IID_IDirectoryObject, (void**) &pDirObj);
  455. if (FAILED(hres))
  456. {
  457. ERRORTRACE((LOG_ESS, "POLICMAN: (ADsGetObject) could not get AD object: %S, 0x%08X\n", bstrPath, hres));
  458. return NULL;
  459. }
  460. else
  461. {
  462. hres = pDirObj->CreateDSObject(bstrName, attrInfo, 2, &pDisp);
  463. if(FAILED(hres))
  464. {
  465. ERRORTRACE((LOG_ESS, "POLICMAN: could not create AD object: %S, 0x%08X\n", bstrName, hres));
  466. return NULL;
  467. }
  468. hres = pDisp->QueryInterface(IID_IADsContainer, (void**)&pADsContainer);
  469. }
  470. return pADsContainer;
  471. }
  472. IADsContainer *CreateContainers(QString &pDomain, QString &pPath)
  473. {
  474. HRESULT
  475. hres = WBEM_S_NO_ERROR;
  476. CComVariant
  477. v1;
  478. IADsContainer
  479. *pADsContainer_return = NULL;
  480. CComPtr<IADsContainer>
  481. pADsContainer,
  482. pADsContainer2;
  483. UINT
  484. iIndex = 0,
  485. iIndex2 = 0;
  486. CComPtr<IDispatch>
  487. pDisp;
  488. // **** get root of domain
  489. hres = ADsGetObject(QString(L"LDAP://") << pDomain, IID_IADsContainer, (void**)&pADsContainer);
  490. if(FAILED(hres))
  491. {
  492. ERRORTRACE((LOG_ESS, "POLICMAN: (ADsGetObject) could not connect to domain %S, 0x%08X\n", pDomain, hres));
  493. return NULL;
  494. }
  495. // **** find most derived element of pPath
  496. while(QString::OK == pPath.NextPattern(iIndex, L"CN=", iIndex))
  497. {
  498. hres = pADsContainer->GetObject(NULL, &pPath[iIndex], &pDisp);
  499. if(FAILED(hres) || (pDisp == NULL))
  500. iIndex += 1;
  501. else
  502. break;
  503. }
  504. if(pDisp == NULL)
  505. {
  506. ERRORTRACE((LOG_ESS, "POLICMAN: (IADs::GetObject) could not get container %S\n", pDomain));
  507. return NULL;
  508. }
  509. // **** now, backtrack up pPath creating each container as we go
  510. while(QString::OK == pPath.PrevPattern(iIndex, L"CN=", iIndex))
  511. {
  512. if(NULL != pADsContainer_return)
  513. pADsContainer_return->Release();
  514. pADsContainer_return = NULL;
  515. pPath.NextChar(iIndex, L",", iIndex2);
  516. // **** isolate name to create
  517. pPath[iIndex2] = L'\0';
  518. pADsContainer_return = CreateContainer(QString(L"LDAP://") << &pPath[iIndex2 + 1] << L"," << pDomain, &pPath[iIndex]);
  519. pPath[iIndex2] = L',';
  520. if(pADsContainer_return == NULL)
  521. {
  522. ERRORTRACE((LOG_ESS, "POLICMAN: (ADsGetObject) could not get AD object: %S, 0x%08X\n", (wchar_t*)pPath, hres));
  523. return NULL;
  524. }
  525. }
  526. return pADsContainer_return;
  527. }
  528. HRESULT ADSIToWMIErrorCodes(HRESULT hresAD)
  529. {
  530. if(((hresAD & 0x800FF000) == 0x80041000) ||
  531. ((hresAD & 0x800FF000) == 0x80042000) ||
  532. ((hresAD & 0x800FF000) == 0x80044000)) return hresAD;
  533. if(hresAD != WBEM_S_NO_ERROR) switch(hresAD)
  534. {
  535. case S_ADS_ERRORSOCCURRED : return WBEM_E_FAILED ;
  536. case S_ADS_NOMORE_ROWS : return WBEM_S_NO_MORE_DATA ;
  537. case S_ADS_NOMORE_COLUMNS : return WBEM_S_NO_MORE_DATA ;
  538. case E_ADS_UNKNOWN_OBJECT : return WBEM_E_NOT_FOUND ;
  539. case E_ADS_OBJECT_EXISTS : return WBEM_E_ALREADY_EXISTS;
  540. case 0x80070005 : return WBEM_E_ACCESS_DENIED; // LDAP_INSUFFICIENT_RIGHTS
  541. case 0x80072030 : return WBEM_E_NOT_FOUND ; // LDAP_NO_SUCH_OBJECT
  542. case 0x8007200a : return WBEM_E_FAILED; //LDAP_NO_SUCH_ATTRIBUTE
  543. default : return WBEM_E_FAILED;
  544. }
  545. return WBEM_S_NO_ERROR;
  546. }
  547. int IsEmpty(VARIANT &v)
  548. {
  549. if((v.vt == VT_NULL) || (v.vt == VT_EMPTY)) return 1;
  550. if((v.vt == VT_UNKNOWN) || (v.vt == VT_DISPATCH))
  551. { if(NULL == v.punkVal)
  552. return 1;
  553. }
  554. return 0;
  555. }
  556. // Creates the default security descriptor for WMI policy *containers*
  557. // Full Control - Domain & Enterprise Admins & GPO Creator-Owner group
  558. // Read Access - authenticated users
  559. // assumes input pointer is NULL or uninitialized or some such
  560. HRESULT CreateDefaultSecurityDescriptor(CNtSecurityDescriptor& cSD)
  561. {
  562. HRESULT hr = WBEM_S_NO_ERROR;
  563. CNtSid sidWorld(L"Authenticated Users");
  564. CNtSid sidSystem(L"System");
  565. CNtSid sidAdmins(L"Domain Admins");
  566. CNtSid sidEnterpriseAdmins(L"Enterprise Admins");
  567. CNtSid sidAdministrators(L"Administrators");
  568. CNtSid sidGPO(L"Group Policy Creator Owners");
  569. CNtSid sidOwner(L"CREATOR OWNER");
  570. // hmmm - does six aces beat four aces?
  571. // a smith and wesson beats four of a kind...
  572. DWORD full = FULL_CONTROL | DS_GENERIC_ALL;
  573. CNtAce aceEnterpriseAdmins(full, ACCESS_ALLOWED_ACE_TYPE, ADS_ACEFLAG_INHERIT_ACE, sidEnterpriseAdmins);
  574. CNtAce aceOwner(full, ACCESS_ALLOWED_ACE_TYPE, ADS_ACEFLAG_INHERIT_ACE | ADS_ACEFLAG_INHERIT_ONLY_ACE, sidOwner);
  575. CNtAce aceAdminsObject(full, ACCESS_ALLOWED_ACE_TYPE, ADS_ACEFLAG_INHERIT_ACE | ADS_ACEFLAG_INHERIT_ONLY_ACE, sidAdmins);
  576. DWORD write = DS_GENERIC_READ | DS_GENERIC_WRITE | ACTRL_DS_CREATE_CHILD;
  577. CNtAce aceAdmins(write | ACTRL_DS_DELETE_CHILD, ACCESS_ALLOWED_ACE_TYPE, 0, sidAdmins);
  578. CNtAce aceAdministrators(write, ACCESS_ALLOWED_ACE_TYPE, 0, sidAdministrators);
  579. CNtAce aceGPO(write, ACCESS_ALLOWED_ACE_TYPE, 0, sidGPO);
  580. DWORD read = DS_GENERIC_READ;
  581. CNtAce aceWorld(read, ACCESS_ALLOWED_ACE_TYPE, ADS_ACEFLAG_INHERIT_ACE, sidWorld);
  582. CNtAce aceSystem(read, ACCESS_ALLOWED_ACE_TYPE, ADS_ACEFLAG_INHERIT_ACE, sidSystem);
  583. CNtAcl ackl;
  584. if (!ackl.AddAce(&aceWorld)) hr = WBEM_E_FAILED;
  585. if (!ackl.AddAce(&aceSystem)) hr = WBEM_E_FAILED;
  586. if (!ackl.AddAce(&aceAdmins)) hr = WBEM_E_FAILED;
  587. if (!ackl.AddAce(&aceEnterpriseAdmins)) hr = WBEM_E_FAILED;
  588. if (!ackl.AddAce(&aceAdministrators)) hr = WBEM_E_FAILED;
  589. if (!ackl.AddAce(&aceGPO)) hr = WBEM_E_FAILED;
  590. if (!ackl.AddAce(&aceOwner)) hr = WBEM_E_FAILED;
  591. if (!ackl.AddAce(&aceAdminsObject)) hr = WBEM_E_FAILED;
  592. if (!ackl.Resize(CNtAcl::MinimumSize)) hr = WBEM_E_FAILED;
  593. if (!cSD.SetDacl(&ackl)) hr = WBEM_E_FAILED;
  594. if (!cSD.SetOwner(&sidEnterpriseAdmins)) hr = WBEM_E_FAILED;
  595. if (!SetSecurityDescriptorControl(cSD.GetPtr(), SE_DACL_PROTECTED, SE_DACL_PROTECTED)) hr = WBEM_E_FAILED;
  596. return hr;
  597. }
  598. // given an input security descriptor
  599. // add owner from thread
  600. HRESULT GetOwnerSecurityDescriptor(CNtSecurityDescriptor& SD)
  601. {
  602. HRESULT hr = WBEM_S_NO_ERROR;
  603. CNtSid sidOwner(CNtSid::CURRENT_THREAD);
  604. if (!SD.SetOwner(&sidOwner)) hr = WBEM_E_FAILED;
  605. /***********************
  606. CNtSid sidOwner(CNtSid::CURRENT_THREAD);
  607. CNtAcl ackl;
  608. if (!SD.GetDacl(ackl)) hr = WBEM_E_FAILED;
  609. if (!SD.SetOwner(&sidOwner)) hr = WBEM_E_FAILED;
  610. if (SUCCEEDED(hr))
  611. {
  612. CNtSid sidGPO(L"Group Policy Creator Owners");
  613. int nAces = ackl.GetNumAces();
  614. CNtAce* pAce = NULL;
  615. CNtSid* pSid = NULL;
  616. // walk through all the aces, find GPO owner creators & kill them
  617. for (int i = 0; i < nAces; i++)
  618. if ((pAce = ackl.GetAce(i)) && (pSid = pAce->GetSid()))
  619. {
  620. if ((*pSid == sidGPO) && (pAce->GetType() == ACCESS_ALLOWED_ACE_TYPE))
  621. {
  622. ackl.DeleteAce(i);
  623. delete pAce;
  624. delete pSid;
  625. break;
  626. }
  627. delete pAce;
  628. delete pSid;
  629. }
  630. else
  631. //
  632. {
  633. hr = WBEM_E_CRITICAL_ERROR;
  634. break;
  635. }
  636. }
  637. if (SUCCEEDED(hr))
  638. {
  639. CNtAce aceOwner(FULL_CONTROL, ACCESS_ALLOWED_ACE_TYPE, 0, sidOwner);
  640. if (ackl.AddAce(&aceOwner) && SD.SetDacl(&ackl))
  641. hr = WBEM_S_NO_ERROR;
  642. else
  643. hr = WBEM_E_FAILED;
  644. }
  645. ******************/
  646. return hr;
  647. }
  648. PSECURITY_DESCRIPTOR GetADSecurityDescriptor(IDirectoryObject *pIDirectoryObject)
  649. {
  650. HRESULT
  651. hres;
  652. LPWSTR
  653. pAttrNames[] = { L"ntSecurityDescriptor" };
  654. ADsStruct<ADS_ATTR_INFO>
  655. pAttrInfo;
  656. PSECURITY_DESCRIPTOR
  657. pSD = NULL;
  658. DWORD
  659. dwReturn,
  660. dwLength;
  661. hres = pIDirectoryObject->GetObjectAttributes(pAttrNames, 1, &pAttrInfo, &dwReturn);
  662. if(SUCCEEDED(hres) && (1 == dwReturn))
  663. {
  664. dwLength = pAttrInfo->pADsValues->SecurityDescriptor.dwLength;
  665. pSD = new BYTE[dwLength];
  666. if(NULL == pSD) return NULL;
  667. ZeroMemory(pSD, dwLength);
  668. memcpy(pSD, pAttrInfo->pADsValues->SecurityDescriptor.lpValue, dwLength);
  669. }
  670. return pSD;
  671. }
  672. HRESULT GetADContainerInDomain(wchar_t *wcsDomain, wchar_t *wcsPath, IDirectorySearch **pObj)
  673. {
  674. HRESULT
  675. hres = WBEM_E_FAILED;
  676. QString
  677. DomainDistName,
  678. LDAPPath(L"LDAP://");
  679. // **** check args
  680. if(NULL == pObj)
  681. return WBEM_E_FAILED;
  682. // **** build Path
  683. hres = DistNameFromDomainName(QString(wcsDomain), DomainDistName);
  684. LDAPPath << wcsPath << L"," << DomainDistName;
  685. // **** attempt to connect to container in AD
  686. hres = ADsGetObject(LDAPPath, IID_IDirectorySearch, (void**)pObj);
  687. return ADSIToWMIErrorCodes(hres);
  688. }
  689. HRESULT ExecuteWQLQuery(wchar_t *wcsPath,
  690. wchar_t *wcsWQLStmt,
  691. IWbemObjectSink *pResponseHandler,
  692. IWbemServices *pWbemServices,
  693. BSTR bstrADClassName,
  694. functTyp pf_ADToCIM)
  695. {
  696. HRESULT
  697. hres = WBEM_E_FAILED;
  698. int
  699. nRes;
  700. QL_LEVEL_1_TOKEN
  701. *pToken = NULL;
  702. CComPtr<IDirectorySearch>
  703. pDirectorySearch;
  704. QString
  705. LDAPQuery;
  706. wchar_t
  707. objPath[1024];
  708. ADS_SEARCH_HANDLE
  709. searchHandle;
  710. ADS_SEARCH_COLUMN
  711. searchColumn;
  712. wchar_t
  713. *pszDistName[] = { L"distinguishedName" };
  714. // **** parse WQL expression
  715. CTextLexSource
  716. src(wcsWQLStmt);
  717. QL1_Parser
  718. parser(&src);
  719. QL_LEVEL_1_RPN_EXPRESSION
  720. *pExp = NULL;
  721. AutoDelete<QL_LEVEL_1_RPN_EXPRESSION>
  722. AutoExp(&pExp);
  723. if(nRes = parser.Parse(&pExp))
  724. return WBEM_E_INVALID_QUERY;
  725. // **** find domain attribute
  726. for(int iToken = 0; (iToken < pExp->nNumTokens) && (NULL == pToken); iToken++)
  727. {
  728. pToken = &pExp->pArrayOfTokens[iToken];
  729. if(_wcsicmp(g_bstrDomain, pToken->PropertyName.GetStringAt(pToken->PropertyName.GetNumElements() - 1)))
  730. pToken = NULL;
  731. }
  732. if(NULL == pToken)
  733. return WBEMESS_E_REGISTRATION_TOO_BROAD;
  734. if((QL_LEVEL_1_TOKEN::OP_EXPRESSION != pToken->nTokenType) ||
  735. (QL_LEVEL_1_TOKEN::OP_EQUAL != pToken->nOperator) ||
  736. (TRUE == pToken->m_bPropComp) ||
  737. (VT_BSTR != pToken->vConstValue.vt))
  738. return WBEM_E_INVALID_QUERY;
  739. if((NULL == bstrADClassName) || (NULL == pf_ADToCIM))
  740. return WBEM_E_INVALID_QUERY;
  741. // **** connect to LDAP location
  742. hres = GetADContainerInDomain(pToken->vConstValue.bstrVal, wcsPath, &pDirectorySearch);
  743. if(FAILED(hres))
  744. {
  745. if(WBEM_E_NOT_FOUND == hres)
  746. return WBEM_S_NO_ERROR;
  747. return hres;
  748. }
  749. else if(pDirectorySearch == NULL)
  750. return WBEM_E_FAILED;
  751. // **** build LDAP query to execute on container pADs
  752. LDAPQuery << L"(objectCategory=" << bstrADClassName << L")";
  753. // **** set search preferences
  754. ADS_SEARCHPREF_INFO
  755. SearchPreferences[1];
  756. SearchPreferences[0].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
  757. SearchPreferences[0].vValue.dwType = ADSTYPE_INTEGER;
  758. SearchPreferences[0].vValue.Integer = 1000;
  759. hres = pDirectorySearch->SetSearchPreference(SearchPreferences, 1);
  760. if(FAILED(hres))
  761. {
  762. ERRORTRACE((LOG_ESS, "POLICMAN: Could not set search preferences, returned error: 0x%08X\n", (LPWSTR)LDAPQuery, hres));
  763. return WBEM_E_FAILED;
  764. }
  765. // **** execute query
  766. hres = pDirectorySearch->ExecuteSearch(LDAPQuery, pszDistName, 1, &searchHandle);
  767. if(FAILED(hres))
  768. {
  769. ERRORTRACE((LOG_ESS, "POLICMAN: Could execute query: (%s) returned error: 0x%08X\n", (LPWSTR)LDAPQuery, hres));
  770. return WBEM_E_FAILED;
  771. }
  772. // **** build result list
  773. try
  774. {
  775. while(SUCCEEDED(hres = pDirectorySearch->GetNextRow(searchHandle)) && (S_ADS_NOMORE_ROWS != hres))
  776. {
  777. CComPtr<IDirectoryObject>
  778. pDirectoryObject;
  779. CComPtr<IWbemClassObject>
  780. pWbemClassObject;
  781. // **** get path to object
  782. hres = pDirectorySearch->GetColumn(searchHandle, pszDistName[0], &searchColumn);
  783. if(FAILED(hres)) return ADSIToWMIErrorCodes(hres);
  784. // **** get pointer to object
  785. wcscpy(objPath, L"LDAP://");
  786. wcscat(objPath, searchColumn.pADsValues->CaseIgnoreString);
  787. pDirectorySearch->FreeColumn(&searchColumn);
  788. hres = ADsGetObject(objPath, IID_IDirectoryObject, (void **)&pDirectoryObject);
  789. if(FAILED(hres)) return ADSIToWMIErrorCodes(hres);
  790. hres = pf_ADToCIM(&pWbemClassObject, pDirectoryObject, pWbemServices);
  791. if(FAILED(hres)) return ADSIToWMIErrorCodes(hres);
  792. if(pWbemClassObject == NULL) return WBEM_E_FAILED;
  793. hres = pResponseHandler->Indicate(1, &pWbemClassObject);
  794. }
  795. }
  796. catch(long hret)
  797. {
  798. hres = ADSIToWMIErrorCodes(hret);
  799. ERRORTRACE((LOG_ESS, "POLICMAN: Translation of Policy object from AD to WMI generated HRESULT 0x%08X\n", hres));
  800. }
  801. catch(wchar_t *swErrString)
  802. {
  803. ERRORTRACE((LOG_ESS, "POLICMAN: Caught Exception: %S\n", swErrString));
  804. hres = WBEM_E_FAILED;
  805. }
  806. catch(...)
  807. {
  808. ERRORTRACE((LOG_ESS, "POLICMAN: Caught unknown Exception\n"));
  809. hres = WBEM_E_TRANSPORT_FAILURE; // HACK for SP1
  810. }
  811. pDirectorySearch->CloseSearchHandle(searchHandle);
  812. return hres;
  813. }
  814. void LogExtendedADErrorInfo(HRESULT hres)
  815. {
  816. DWORD dwLastError;
  817. WCHAR szErrorBuf[1024], szNameBuf[256];
  818. if(HRESULT_FACILITY(hres) == FACILITY_WIN32)
  819. {
  820. HRESULT hres2;
  821. hres2 = ADsGetLastError(&dwLastError, szErrorBuf, 1023, szNameBuf, 255);
  822. if(SUCCEEDED(hres2))
  823. ERRORTRACE((LOG_ESS, "POLICMAN: Error Code: %d Error Text: %S Provider: %S\n", dwLastError, szErrorBuf, szNameBuf));
  824. else
  825. ERRORTRACE((LOG_ESS, "POLICMAN: Type mismatch on date property\n"));
  826. }
  827. }