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.

491 lines
11 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: si.cpp
  8. //
  9. // This file contains the implementation of the CSecurityInformation
  10. // base class.
  11. //
  12. //--------------------------------------------------------------------------
  13. #include "si.h"
  14. #include <wmistr.h>
  15. CSecurityInformation::CSecurityInformation()
  16. : m_cRef(1), m_pszObjectName(NULL)
  17. {
  18. }
  19. CSecurityInformation::~CSecurityInformation()
  20. {
  21. }
  22. STDMETHODIMP
  23. CSecurityInformation::Initialize(LPTSTR pszObject,
  24. LPGUID Guid)
  25. {
  26. m_pszObjectName = pszObject;
  27. m_guid = *Guid;
  28. return(S_OK);
  29. }
  30. ///////////////////////////////////////////////////////////
  31. //
  32. // IUnknown methods
  33. //
  34. ///////////////////////////////////////////////////////////
  35. STDMETHODIMP_(ULONG)
  36. CSecurityInformation::AddRef()
  37. {
  38. return ++m_cRef;
  39. }
  40. STDMETHODIMP_(ULONG)
  41. CSecurityInformation::Release()
  42. {
  43. if (--m_cRef == 0)
  44. {
  45. delete this;
  46. return 0;
  47. }
  48. return m_cRef;
  49. }
  50. STDMETHODIMP
  51. CSecurityInformation::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  52. {
  53. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ISecurityInformation))
  54. {
  55. *ppv = (LPSECURITYINFO)this;
  56. m_cRef++;
  57. return S_OK;
  58. }
  59. else
  60. {
  61. *ppv = NULL;
  62. return E_NOINTERFACE;
  63. }
  64. }
  65. ///////////////////////////////////////////////////////////
  66. //
  67. // ISecurityInformation methods
  68. //
  69. ///////////////////////////////////////////////////////////
  70. ULONG DiscpAnsiToUnicodeSize(
  71. IN LPCSTR AnsiString,
  72. OUT ULONG *UnicodeSizeInChar
  73. )
  74. /*++
  75. Routine Description:
  76. This routine will return the length needed to represent the ANSI
  77. string as unicode
  78. Arguments:
  79. AnsiString is the ansi string whose unicode length is returned
  80. *UnicodeSizeInChar is number of chars needed to represent ansi
  81. string as unicode
  82. Return Value:
  83. ERROR_SUCCESS or error code
  84. --*/
  85. {
  86. *UnicodeSizeInChar = MultiByteToWideChar(CP_ACP,
  87. 0,
  88. AnsiString,
  89. -1,
  90. NULL,
  91. 0);
  92. return((*UnicodeSizeInChar == 0) ? GetLastError() : ERROR_SUCCESS);
  93. }
  94. ULONG DiscpAnsiToUnicode(
  95. IN LPSTR pszA,
  96. OUT LPWSTR *ppszW,
  97. IN ULONG MaxLen
  98. )
  99. /*++
  100. Routine Description:
  101. Convert Ansi string into its Unicode equivalent
  102. Arguments:
  103. pszA is ansi string to convert
  104. *ppszW on entry has pointer to buffer to write converted string or
  105. NULL is converted string is to be dynamically allocated
  106. Return Value:
  107. Error code
  108. --*/
  109. {
  110. ULONG cCharacters;
  111. ULONG cbUnicodeUsed;
  112. ULONG Status;
  113. BOOLEAN AllocMemory;
  114. PWCHAR u;
  115. //
  116. // If input is null then just return the same.
  117. //
  118. if (pszA == NULL)
  119. {
  120. *ppszW = NULL;
  121. Status = ERROR_SUCCESS;
  122. } else {
  123. if (*ppszW == NULL)
  124. {
  125. Status = DiscpAnsiToUnicodeSize(pszA, &MaxLen);
  126. if (Status == ERROR_SUCCESS)
  127. {
  128. *ppszW = (PWCHAR)LocalAlloc(LPTR, MaxLen * sizeof(WCHAR));
  129. if (*ppszW == NULL)
  130. {
  131. Status = ERROR_NOT_ENOUGH_MEMORY;
  132. } else {
  133. AllocMemory = TRUE;
  134. }
  135. }
  136. } else {
  137. Status = ERROR_SUCCESS;
  138. AllocMemory = FALSE;
  139. }
  140. if (Status == ERROR_SUCCESS)
  141. {
  142. //
  143. // Convert to Unicode
  144. //
  145. cbUnicodeUsed = MultiByteToWideChar(CP_ACP,
  146. 0,
  147. pszA,
  148. -1,
  149. *ppszW,
  150. MaxLen);
  151. if (0 == cbUnicodeUsed)
  152. {
  153. Status = GetLastError();
  154. if (AllocMemory)
  155. {
  156. LocalFree(*ppszW);
  157. }
  158. }
  159. }
  160. }
  161. return(Status);
  162. }
  163. STDMETHODIMP
  164. CSecurityInformation::GetObjectInformation(PSI_OBJECT_INFO pObjectInfo)
  165. {
  166. PWCHAR u;
  167. pObjectInfo->dwFlags = SI_EDIT_PERMS | SI_ADVANCED | SI_EDIT_AUDITS;
  168. pObjectInfo->hInstance = NULL;
  169. pObjectInfo->pszServerName = NULL;
  170. u = NULL;
  171. DiscpAnsiToUnicode(m_pszObjectName,
  172. &u,
  173. 0);
  174. pObjectInfo->pszObjectName = u;
  175. return(S_OK);
  176. }
  177. STDMETHODIMP
  178. CSecurityInformation::GetSecurity(SECURITY_INFORMATION si,
  179. PSECURITY_DESCRIPTOR *ppSD,
  180. BOOL fDefault)
  181. {
  182. HRESULT hr = S_OK;
  183. *ppSD = NULL;
  184. hr = ReadObjectSecurity(m_pszObjectName, si, ppSD);
  185. return(hr);
  186. }
  187. STDMETHODIMP
  188. CSecurityInformation::SetSecurity(SECURITY_INFORMATION si,
  189. PSECURITY_DESCRIPTOR pSD)
  190. {
  191. HRESULT hr = S_OK;
  192. hr = WriteObjectSecurity(m_pszObjectName, si, pSD);
  193. return(hr);
  194. }
  195. STDMETHODIMP
  196. CSecurityInformation::PropertySheetPageCallback(HWND hwnd,
  197. UINT uMsg,
  198. SI_PAGE_TYPE uPage)
  199. {
  200. return S_OK;
  201. }
  202. STDMETHODIMP
  203. CSecurityInformation::ReadObjectSecurity(LPCTSTR pszObject,
  204. SECURITY_INFORMATION si,
  205. PSECURITY_DESCRIPTOR *ppSD)
  206. {
  207. DWORD dwErr;
  208. dwErr = GetWmiGuidSecurityInfo(&m_guid,
  209. si,
  210. NULL,
  211. NULL,
  212. NULL,
  213. NULL,
  214. ppSD);
  215. return(HRESULT_FROM_WIN32(dwErr));
  216. }
  217. STDMETHODIMP
  218. CSecurityInformation::WriteObjectSecurity(LPCTSTR pszObject,
  219. SECURITY_INFORMATION si,
  220. PSECURITY_DESCRIPTOR pSD)
  221. {
  222. DWORD dwErr;
  223. SECURITY_DESCRIPTOR_CONTROL wSDControl = 0;
  224. DWORD dwRevision;
  225. PSID psidOwner = NULL;
  226. PSID psidGroup = NULL;
  227. PACL pDacl = NULL;
  228. PACL pSacl = NULL;
  229. BOOL bDefaulted;
  230. BOOL bPresent;
  231. //
  232. // Get pointers to various security descriptor parts for
  233. // calling SetNamedSecurityInfo
  234. //
  235. GetSecurityDescriptorControl(pSD, &wSDControl, &dwRevision);
  236. GetSecurityDescriptorOwner(pSD, &psidOwner, &bDefaulted);
  237. GetSecurityDescriptorGroup(pSD, &psidGroup, &bDefaulted);
  238. GetSecurityDescriptorDacl(pSD, &bPresent, &pDacl, &bDefaulted);
  239. GetSecurityDescriptorSacl(pSD, &bPresent, &pSacl, &bDefaulted);
  240. if (si & DACL_SECURITY_INFORMATION)
  241. {
  242. if (wSDControl & SE_DACL_PROTECTED)
  243. si |= PROTECTED_DACL_SECURITY_INFORMATION;
  244. else
  245. si |= UNPROTECTED_DACL_SECURITY_INFORMATION;
  246. }
  247. if (si & SACL_SECURITY_INFORMATION)
  248. {
  249. if (wSDControl & SE_SACL_PROTECTED)
  250. si |= PROTECTED_SACL_SECURITY_INFORMATION;
  251. else
  252. si |= UNPROTECTED_SACL_SECURITY_INFORMATION;
  253. }
  254. dwErr = SetWmiGuidSecurityInfo(&m_guid,
  255. si,
  256. psidOwner,
  257. psidGroup,
  258. pDacl,
  259. pSacl);
  260. return(HRESULT_FROM_WIN32(dwErr));
  261. }
  262. GUID GuidNull = {0, 0, 0, 0, 0, 0x0, 0, 0, 0, 0, 0};
  263. SI_ACCESS SIAccess[] =
  264. {
  265. {
  266. &GuidNull,
  267. WMIGUID_QUERY,
  268. L"Query",
  269. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  270. },
  271. {
  272. &GuidNull,
  273. WMIGUID_SET,
  274. L"Set",
  275. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  276. },
  277. {
  278. &GuidNull,
  279. WMIGUID_EXECUTE,
  280. L"Execute Method",
  281. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  282. },
  283. {
  284. &GuidNull,
  285. WMIGUID_NOTIFICATION,
  286. L"Receive Notification",
  287. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  288. },
  289. {
  290. &GuidNull,
  291. SYNCHRONIZE,
  292. L"Synchronize",
  293. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  294. },
  295. {
  296. &GuidNull,
  297. TRACELOG_CREATE_REALTIME,
  298. L"TRACELOG_CREATE_REALTIME",
  299. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  300. },
  301. {
  302. &GuidNull,
  303. TRACELOG_CREATE_ONDISK,
  304. L"TRACELOG_CREATE_ONDISK",
  305. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  306. },
  307. {
  308. &GuidNull,
  309. TRACELOG_GUID_ENABLE,
  310. L"TRACELOG_GUID_ENABLE",
  311. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  312. },
  313. {
  314. &GuidNull,
  315. TRACELOG_ACCESS_KERNEL_LOGGER,
  316. L"TRACELOG_ACCESS_KERNEL_LOGGER",
  317. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  318. },
  319. {
  320. &GuidNull,
  321. TRACELOG_CREATE_INPROC,
  322. L"TRACELOG_CREATE_INPROC",
  323. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  324. },
  325. {
  326. &GuidNull,
  327. TRACELOG_ACCESS_REALTIME,
  328. L"TRACELOG_ACCESS_REALTIME",
  329. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  330. },
  331. {
  332. &GuidNull,
  333. TRACELOG_REGISTER_GUIDS,
  334. L"TRACELOG_REGISTER_GUIDS",
  335. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  336. },
  337. {
  338. &GuidNull,
  339. WRITE_DAC,
  340. L"WRITE_DAC",
  341. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  342. },
  343. {
  344. &GuidNull,
  345. DELETE,
  346. L"DELETE",
  347. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  348. },
  349. };
  350. #define SIAccessCount ( sizeof(SIAccess) / sizeof(SI_ACCESS) )
  351. STDMETHODIMP
  352. CSecurityInformation::GetAccessRights(const GUID* pguidObjectType,
  353. DWORD dwFlags,
  354. PSI_ACCESS *ppAccess,
  355. ULONG *pcAccesses,
  356. ULONG *piDefaultAccess)
  357. {
  358. *ppAccess = SIAccess;
  359. *pcAccesses = SIAccessCount;
  360. *piDefaultAccess = 0;
  361. return(S_OK);
  362. }
  363. GENERIC_MAPPING GenericMapping =
  364. {
  365. // GENERIC_READ <--> WMIGUID_QUERY
  366. WMIGUID_QUERY,
  367. // GENERIC_WRUTE <--> WMIGUID_SET
  368. WMIGUID_SET,
  369. // GENERIC_EXECUTE <--> WMIGUID_EXECUTE
  370. WMIGUID_EXECUTE,
  371. // GENERIC_ALL <--> WMIGUID_ALL_ACCESS
  372. WMIGUID_ALL_ACCESS
  373. };
  374. STDMETHODIMP
  375. CSecurityInformation::MapGeneric(const GUID *pguidObjectType,
  376. UCHAR *pAceFlags,
  377. ACCESS_MASK *pmask)
  378. {
  379. MapGenericMask(pmask, &GenericMapping);
  380. return(S_OK);
  381. }
  382. STDMETHODIMP
  383. CSecurityInformation::GetInheritTypes(PSI_INHERIT_TYPE *ppInheritTypes,
  384. ULONG *pcInheritTypes)
  385. {
  386. *ppInheritTypes = NULL;
  387. *pcInheritTypes = 0;
  388. return(S_OK);
  389. }
  390. void EditGuidSecurity(
  391. LPTSTR GuidString,
  392. LPGUID Guid
  393. )
  394. {
  395. CSecurityInformation *pSec;
  396. pSec = new CSecurityInformation();
  397. pSec->Initialize(GuidString,
  398. Guid);
  399. EditSecurity(NULL,
  400. pSec);
  401. }