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.

311 lines
9.3 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. safelog.c (SAFER Event Logging)
  5. Abstract:
  6. This module implements the internal WinSAFER APIs to write eventlog
  7. messages. All of our message strings are defined in ntstatus.mc
  8. and are physically located within ntdll.dll file.
  9. Currently we are just reusing the previously existing event source
  10. called "Application Popup", which already happens to use ntdll.dll
  11. as its message resource library. Events of this source always go
  12. into the "System Log".
  13. Author:
  14. Jeffrey Lawson (JLawson) - Apr 1999
  15. Environment:
  16. User mode only.
  17. Exported Functions:
  18. SaferRecordEventLogEntry
  19. Revision History:
  20. Created - Nov 2000
  21. --*/
  22. #include "pch.h"
  23. #pragma hdrstop
  24. #include <winsafer.h>
  25. #include <winsaferp.h>
  26. #include "saferp.h"
  27. const static GUID guidTrustedCert = SAFER_GUID_RESULT_TRUSTED_CERT;
  28. const static GUID guidDefaultRule = SAFER_GUID_RESULT_DEFAULT_LEVEL;
  29. BOOL WINAPI
  30. SaferpRecordEventLogEntryHelper(
  31. IN NTSTATUS LogStatusCode,
  32. IN LPCWSTR szTargetPath,
  33. IN REFGUID refRuleGuid,
  34. IN LPCWSTR szRulePath
  35. )
  36. {
  37. NTSTATUS Status = STATUS_UNSUCCESSFUL;
  38. WORD wNumStrings = 0;
  39. LPWSTR lpszStrings[5];
  40. HANDLE hEventSource;
  41. UNICODE_STRING UnicodeGuid;
  42. BYTE LocalBuffer[SECURITY_MAX_SID_SIZE + sizeof(TOKEN_USER)];
  43. PSID pSid = NULL;
  44. HANDLE hToken = NULL;
  45. DWORD Ignore = 0;
  46. //
  47. // Open the effective token on the thead and get the token user. On any
  48. // intermediate failure in this operation, we still dump the event to the
  49. // event log, without the user sid information.
  50. //
  51. //
  52. // Get the effective token on the thread.
  53. //
  54. Status = NtOpenThreadToken(
  55. NtCurrentThread(),
  56. TOKEN_QUERY,
  57. TRUE,
  58. &hToken);
  59. //
  60. // If the thread is not impersonating, get the process token.
  61. //
  62. if (Status == STATUS_NO_TOKEN) {
  63. Status = NtOpenProcessToken(
  64. NtCurrentProcess(),
  65. TOKEN_QUERY,
  66. &hToken);
  67. }
  68. if (NT_SUCCESS(Status)) {
  69. //
  70. // Get the User Sid.
  71. //
  72. Status = NtQueryInformationToken (
  73. hToken,
  74. TokenUser,
  75. LocalBuffer,
  76. sizeof(LocalBuffer),
  77. &Ignore);
  78. NtClose(hToken);
  79. if (NT_SUCCESS(Status)) {
  80. //
  81. // We have successfully computed who the user is. This is good.
  82. //
  83. pSid = (PSID) (((PTOKEN_USER) LocalBuffer)->User.Sid);
  84. }
  85. }
  86. hEventSource = RegisterEventSourceW(NULL, L"Software Restriction Policy");
  87. if (hEventSource != NULL) {
  88. Status = STATUS_SUCCESS;
  89. RtlInitEmptyUnicodeString(&UnicodeGuid, NULL, 0);
  90. switch (LogStatusCode)
  91. {
  92. case STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT:
  93. if (!ARGUMENT_PRESENT(szTargetPath)) {
  94. Status = STATUS_INVALID_PARAMETER;
  95. break;
  96. }
  97. lpszStrings[0] = (LPWSTR) szTargetPath;
  98. wNumStrings = 1;
  99. break;
  100. case STATUS_ACCESS_DISABLED_BY_POLICY_OTHER:
  101. if (!ARGUMENT_PRESENT(szTargetPath) ||
  102. !ARGUMENT_PRESENT(refRuleGuid)) {
  103. Status = STATUS_INVALID_PARAMETER;
  104. break;
  105. }
  106. Status = RtlStringFromGUID(refRuleGuid, &UnicodeGuid);
  107. if (NT_SUCCESS(Status)) {
  108. ASSERT(UnicodeGuid.Buffer != NULL);
  109. lpszStrings[0] = (LPWSTR) szTargetPath;
  110. lpszStrings[1] = UnicodeGuid.Buffer;
  111. wNumStrings = 2;
  112. }
  113. break;
  114. case STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER:
  115. if (!ARGUMENT_PRESENT(szTargetPath)) {
  116. Status = STATUS_INVALID_PARAMETER;
  117. break;
  118. }
  119. lpszStrings[0] = (LPWSTR) szTargetPath;
  120. wNumStrings = 1;
  121. break;
  122. case STATUS_ACCESS_DISABLED_BY_POLICY_PATH:
  123. if (!ARGUMENT_PRESENT(szTargetPath) ||
  124. !ARGUMENT_PRESENT(refRuleGuid) ||
  125. !ARGUMENT_PRESENT(szRulePath)) {
  126. Status = STATUS_INVALID_PARAMETER;
  127. break;
  128. }
  129. Status = RtlStringFromGUID(refRuleGuid, &UnicodeGuid);
  130. if (NT_SUCCESS(Status)) {
  131. ASSERT(UnicodeGuid.Buffer != NULL);
  132. lpszStrings[0] = (LPWSTR) szTargetPath;
  133. lpszStrings[1] = UnicodeGuid.Buffer;
  134. lpszStrings[2] = (LPWSTR) szRulePath;
  135. wNumStrings = 3;
  136. }
  137. break;
  138. default:
  139. Status = STATUS_INVALID_PARAMETER;
  140. }
  141. if (NT_SUCCESS(Status)) {
  142. ReportEventW(
  143. hEventSource, // handle to event log
  144. EVENTLOG_WARNING_TYPE, // event type
  145. 0, // event category
  146. LogStatusCode, // event ID
  147. pSid, // current user's SID
  148. wNumStrings, // strings in lpszStrings
  149. 0, // no bytes of raw data
  150. lpszStrings, // array of error strings
  151. NULL); // no raw data
  152. }
  153. DeregisterEventSource(hEventSource);
  154. if (UnicodeGuid.Buffer != NULL) {
  155. RtlFreeUnicodeString(&UnicodeGuid);
  156. }
  157. }
  158. if (NT_SUCCESS(Status)) {
  159. return TRUE;
  160. } else {
  161. return FALSE;
  162. }
  163. }
  164. BOOL WINAPI
  165. SaferRecordEventLogEntry(
  166. IN SAFER_LEVEL_HANDLE hAuthzLevel,
  167. IN LPCWSTR szTargetPath,
  168. IN LPVOID lpReserved
  169. )
  170. {
  171. PSAFER_IDENTIFICATION_HEADER pIdentCommon;
  172. DWORD dwIdentBufferSize;
  173. BOOL bResult;
  174. //
  175. // Allocate enough memory for the largest structure we can expect
  176. // and then query the information about the identifier that matched.
  177. //
  178. dwIdentBufferSize = max(sizeof(SAFER_HASH_IDENTIFICATION),
  179. sizeof(SAFER_PATHNAME_IDENTIFICATION));
  180. pIdentCommon = (PSAFER_IDENTIFICATION_HEADER)
  181. HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwIdentBufferSize);
  182. if (!pIdentCommon) {
  183. return FALSE;
  184. }
  185. pIdentCommon->cbStructSize = sizeof(SAFER_IDENTIFICATION_HEADER);
  186. if (!SaferGetLevelInformation(
  187. hAuthzLevel,
  188. SaferObjectSingleIdentification,
  189. pIdentCommon,
  190. dwIdentBufferSize,
  191. &dwIdentBufferSize)) {
  192. if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY) {
  193. HeapFree(GetProcessHeap(), 0, pIdentCommon);
  194. pIdentCommon = (PSAFER_IDENTIFICATION_HEADER)
  195. HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwIdentBufferSize);
  196. if (!pIdentCommon) {
  197. return FALSE;
  198. }
  199. pIdentCommon->cbStructSize = sizeof(SAFER_IDENTIFICATION_HEADER);
  200. if (!SaferGetLevelInformation(
  201. hAuthzLevel,
  202. SaferObjectSingleIdentification,
  203. pIdentCommon,
  204. dwIdentBufferSize,
  205. &dwIdentBufferSize)) {
  206. bResult = FALSE;
  207. goto Cleanup;
  208. }
  209. }
  210. else
  211. {
  212. bResult = FALSE;
  213. goto Cleanup;
  214. }
  215. }
  216. //
  217. // Look at the resulting information about the identifier.
  218. //
  219. if (IsEqualGUID(&pIdentCommon->IdentificationGuid, &guidTrustedCert))
  220. {
  221. bResult = SaferpRecordEventLogEntryHelper(
  222. STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER,
  223. szTargetPath, NULL, NULL);
  224. }
  225. else if (IsEqualGUID(&pIdentCommon->IdentificationGuid, &guidDefaultRule))
  226. {
  227. bResult = SaferpRecordEventLogEntryHelper(
  228. STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT,
  229. szTargetPath, NULL, NULL);
  230. }
  231. else if (pIdentCommon->dwIdentificationType == SaferIdentityTypeImageName)
  232. {
  233. PSAFER_PATHNAME_IDENTIFICATION pIdentPath =
  234. (PSAFER_PATHNAME_IDENTIFICATION) pIdentCommon;
  235. bResult = SaferpRecordEventLogEntryHelper(
  236. STATUS_ACCESS_DISABLED_BY_POLICY_PATH,
  237. szTargetPath, &pIdentCommon->IdentificationGuid,
  238. pIdentPath->ImageName);
  239. }
  240. else
  241. {
  242. bResult = SaferpRecordEventLogEntryHelper(
  243. STATUS_ACCESS_DISABLED_BY_POLICY_OTHER,
  244. szTargetPath, &pIdentCommon->IdentificationGuid,
  245. NULL);
  246. }
  247. Cleanup:
  248. HeapFree(GetProcessHeap(), 0, pIdentCommon);
  249. return bResult;
  250. }