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
16 KiB

  1. /*******************************************************************************
  2. * AUDIT.C
  3. *
  4. * This module contains the routines for logging audit events
  5. *
  6. * Copyright Citrix Systems Inc. 1995
  7. * Copyright (C) 1997-1999 Microsoft Corp.
  8. *
  9. * Author: Thanh Luu
  10. *******************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include <msaudite.h>
  14. HANDLE AuditLogHandle = NULL;
  15. //Authz Changes
  16. AUTHZ_RESOURCE_MANAGER_HANDLE hRM = NULL;
  17. //END Authz Changes
  18. NTSTATUS
  19. AdtBuildLuidString(
  20. IN PLUID Value,
  21. OUT PUNICODE_STRING ResultantString
  22. );
  23. VOID
  24. AuditEvent( PGLOBALS pGlobals, ULONG EventId );
  25. BOOL
  26. AuditingEnabled ();
  27. NTSTATUS
  28. AuthzReportEventW( IN PAUTHZ_AUDIT_EVENT_TYPE_HANDLE pHAET,
  29. IN DWORD Flags,
  30. IN ULONG EventId,
  31. IN PSID pUserID,
  32. IN USHORT NumStrings,
  33. IN ULONG DataSize OPTIONAL, //Future - DO NOT USE
  34. IN PWSTR* Strings,
  35. IN PVOID Data OPTIONAL //Future - DO NOT USE
  36. );
  37. BOOL AuthzInit( IN DWORD Flags,
  38. IN USHORT CategoryID,
  39. IN USHORT AuditID,
  40. IN USHORT ParameterCount,
  41. OUT PAUTHZ_AUDIT_EVENT_TYPE_HANDLE phAuditEventType
  42. );
  43. NTSTATUS
  44. AdtBuildLuidString(
  45. IN PLUID Value,
  46. OUT PUNICODE_STRING ResultantString
  47. )
  48. /*++
  49. Routine Description:
  50. This function builds a unicode string representing the passed LUID.
  51. The resultant string will be formatted as follows:
  52. (0x00005678,0x12340000)
  53. Arguments:
  54. Value - The value to be transformed to printable format (Unicode string).
  55. ResultantString - Points to the unicode string header. The body of this
  56. unicode string will be set to point to the resultant output value
  57. if successful. Otherwise, the Buffer field of this parameter
  58. will be set to NULL.
  59. FreeWhenDone - If TRUE, indicates that the body of the ResultantString
  60. must be freed to process heap when no longer needed.
  61. Return Values:
  62. STATUS_NO_MEMORY - indicates memory could not be allocated
  63. for the string body.
  64. All other Result Codes are generated by called routines.
  65. --*/
  66. {
  67. NTSTATUS Status;
  68. UNICODE_STRING IntegerString;
  69. ULONG Buffer[(16*sizeof(WCHAR))/sizeof(ULONG)];
  70. IntegerString.Buffer = (PWCHAR)&Buffer[0];
  71. IntegerString.MaximumLength = 16*sizeof(WCHAR);
  72. //
  73. // Length (in WCHARS) is 3 for (0x
  74. // 10 for 1st hex number
  75. // 3 for ,0x
  76. // 10 for 2nd hex number
  77. // 1 for )
  78. // 1 for null termination
  79. //
  80. ResultantString->Length = 0;
  81. ResultantString->MaximumLength = 28 * sizeof(WCHAR);
  82. ResultantString->Buffer = RtlAllocateHeap( RtlProcessHeap(), 0,
  83. ResultantString->MaximumLength);
  84. if (ResultantString->Buffer == NULL) {
  85. return(STATUS_NO_MEMORY);
  86. }
  87. Status = RtlAppendUnicodeToString( ResultantString, L"(0x" );
  88. Status = RtlIntegerToUnicodeString( Value->HighPart, 16, &IntegerString );
  89. Status = RtlAppendUnicodeToString( ResultantString, IntegerString.Buffer );
  90. Status = RtlAppendUnicodeToString( ResultantString, L",0x" );
  91. Status = RtlIntegerToUnicodeString( Value->LowPart, 16, &IntegerString );
  92. Status = RtlAppendUnicodeToString( ResultantString, IntegerString.Buffer );
  93. Status = RtlAppendUnicodeToString( ResultantString, L")" );
  94. return(STATUS_SUCCESS);
  95. }
  96. VOID
  97. AuditEvent( PGLOBALS pGlobals, ULONG EventId )
  98. {
  99. NTSTATUS Status;
  100. WINSTATIONNAME WinStationName;
  101. USHORT StringIndex = 0;
  102. WINSTATIONCLIENT ClientData;
  103. ULONG Length;
  104. BOOL bResult = FALSE;
  105. UNICODE_STRING LuidString;
  106. PWSTR StringPointerArray[6];
  107. TOKEN_STATISTICS TokenInformation;
  108. ULONG ReturnLength;
  109. BOOLEAN WasEnabled;
  110. LUID LogonId = {0,0};
  111. AUTHZ_AUDIT_EVENT_TYPE_HANDLE hAET = NULL;
  112. if (!AuditingEnabled() || pGlobals->AuditLogFull)
  113. return;
  114. //
  115. //AUTHZ Changes
  116. //
  117. if( !AuthzInit( 0, SE_CATEGID_LOGON, (USHORT)EventId, 6, &hAET ))
  118. goto badAuthzInit;
  119. StringPointerArray[StringIndex] = pGlobals->UserName ;
  120. StringIndex++;
  121. StringPointerArray[StringIndex] = pGlobals->Domain;
  122. StringIndex++;
  123. Status = AdtBuildLuidString( &pGlobals->LogonId, &LuidString );
  124. StringPointerArray[StringIndex] = LuidString.Buffer;
  125. StringIndex++;
  126. WinStationNameFromLogonId( SERVERNAME_CURRENT, LOGONID_CURRENT, WinStationName );
  127. StringPointerArray[StringIndex] = WinStationName;
  128. StringIndex++;
  129. bResult = WinStationQueryInformation( SERVERNAME_CURRENT,
  130. LOGONID_CURRENT,
  131. WinStationClient,
  132. &ClientData,
  133. sizeof(ClientData),
  134. &Length );
  135. if ( bResult )
  136. StringPointerArray[StringIndex] = ClientData.ClientName;
  137. else
  138. StringPointerArray[StringIndex = L"Unknown";
  139. StringIndex++;
  140. if ( bResult )
  141. StringPointerArray[StringIndex] = ClientData.ClientAddress;
  142. else
  143. StringPointerArray[StringIndex] = L"Unknown";
  144. StringIndex++;
  145. //Authz Changes
  146. Status = AuthzReportEventW( &hAET,
  147. APF_AuditSuccess,
  148. EventId,
  149. NULL,
  150. StringIndex,
  151. 0,
  152. StringPointerArray,
  153. NULL
  154. );
  155. //end authz changes
  156. if ( !NT_SUCCESS(Status))
  157. DBGPRINT(("Termsrv - failed to report event \n" ));
  158. badAuthzInit:
  159. if( hAET != NULL )
  160. AuthziFreeAuditEventType( hAET );
  161. }
  162. /***************************************************************************\
  163. * AuditingEnabled
  164. *
  165. * Purpose : Check auditing via LSA.
  166. *
  167. * Returns: TRUE on success, FALSE on failure
  168. *
  169. * History:
  170. * 5-6-92 DaveHart Created.
  171. \***************************************************************************/
  172. BOOL
  173. AuditingEnabled()
  174. {
  175. NTSTATUS Status, IgnoreStatus;
  176. PPOLICY_AUDIT_EVENTS_INFO AuditInfo;
  177. OBJECT_ATTRIBUTES ObjectAttributes;
  178. SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
  179. LSA_HANDLE PolicyHandle;
  180. //
  181. // Set up the Security Quality Of Service for connecting to the
  182. // LSA policy object.
  183. //
  184. SecurityQualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
  185. SecurityQualityOfService.ImpersonationLevel = SecurityImpersonation;
  186. SecurityQualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  187. SecurityQualityOfService.EffectiveOnly = FALSE;
  188. //
  189. // Set up the object attributes to open the Lsa policy object
  190. //
  191. InitializeObjectAttributes(
  192. &ObjectAttributes,
  193. NULL,
  194. 0L,
  195. NULL,
  196. NULL
  197. );
  198. ObjectAttributes.SecurityQualityOfService = &SecurityQualityOfService;
  199. //
  200. // Open the local LSA policy object
  201. //
  202. Status = LsaOpenPolicy(
  203. NULL,
  204. &ObjectAttributes,
  205. POLICY_VIEW_AUDIT_INFORMATION | POLICY_SET_AUDIT_REQUIREMENTS,
  206. &PolicyHandle
  207. );
  208. if (!NT_SUCCESS(Status)) {
  209. DebugLog((DEB_ERROR, "Failed to open LsaPolicyObject Status = 0x%lx", Status));
  210. return FALSE;
  211. }
  212. Status = LsaQueryInformationPolicy(
  213. PolicyHandle,
  214. PolicyAuditEventsInformation,
  215. (PVOID *)&AuditInfo
  216. );
  217. IgnoreStatus = LsaClose(PolicyHandle);
  218. ASSERT(NT_SUCCESS(IgnoreStatus));
  219. if (!NT_SUCCESS(Status)) {
  220. DebugLog((DEB_ERROR, "Failed to query audit event info Status = 0x%lx", Status));
  221. return FALSE;
  222. }
  223. return (AuditInfo->AuditingMode &&
  224. ((AuditInfo->EventAuditingOptions)[AuditCategoryLogon] &
  225. POLICY_AUDIT_EVENT_SUCCESS));
  226. }
  227. /*************************************************************
  228. * AuthzInit Purpose : Initialize authz for logging an event to the security log
  229. *Flags - unused
  230. *Category Id - Security Category to which this event belongs
  231. *Audit Id - An id for the event
  232. *PArameter count - Number of parameters that will be passed to the logging function later
  233. ****************************************************************/
  234. BOOL AuthzInit( IN DWORD Flags,
  235. IN USHORT CategoryID,
  236. IN USHORT AuditID,
  237. IN USHORT ParameterCount,
  238. OUT PAUTHZ_AUDIT_EVENT_TYPE_HANDLE phAuditEventType
  239. )
  240. {
  241. BOOL fAuthzInit = TRUE;
  242. if( NULL == phAuditEventType )
  243. goto badAuthzInit;
  244. if( NULL == hRM )
  245. {
  246. fAuthzInit = AuthzInitializeResourceManager( 0,
  247. NULL,
  248. NULL,
  249. NULL,
  250. L"Terminal Server",
  251. &hRM
  252. );
  253. if ( !fAuthzInit )
  254. {
  255. DBGPRINT(("TERMSRV: AuditEvent: AuthzInitializeResourceManager failed with %d\n", GetLastError()));
  256. goto badAuthzInit;
  257. }
  258. }
  259. fAuthzInit = AuthziInitializeAuditEventType( Flags,
  260. CategoryID,
  261. AuditID,
  262. ParameterCount,
  263. phAuditEventType
  264. );
  265. if ( !fAuthzInit )
  266. {
  267. DBGPRINT(("TERMSRV: AuditEvent: AuthziInitializeAuditEventType failed with %d\n", GetLastError()));
  268. goto badAuthzInit;
  269. }
  270. badAuthzInit:
  271. if( !fAuthzInit )
  272. {
  273. if( NULL != hRM )
  274. {
  275. if( !AuthzFreeResourceManager( hRM ))
  276. DBGPRINT(("TERMSRV: AuditEvent: AuthzFreeResourceManager failed with %d\n", GetLastError()));
  277. hRM = NULL;
  278. }
  279. if( NULL != *phAuditEventType )
  280. {
  281. if( !AuthziFreeAuditEventType( *phAuditEventType ))
  282. DBGPRINT(("TERMSRV: AuditEvent: AuthziFreeAuditEventType failed with %d\n", GetLastError()));
  283. *phAuditEventType = NULL;
  284. }
  285. }
  286. // if( fAuthzInit )
  287. // DBGPRINT(("TERMSRV: Successfully initialized authz = %d\n", AuditID));
  288. return fAuthzInit;
  289. }
  290. /*********************************************************
  291. * Purpose : Log an Event to the security log
  292. * In pHAET
  293. * Audit Event type obtained from a call to AuthzInit() above
  294. * In Flags
  295. * APF_AuditSuccess or others as listed in the header file
  296. * pUserSID - Unused
  297. * NumStrings - Number of strings contained within "Strings"
  298. * DataSize - unused
  299. * Strings- Pointer to a sequence of unicode strings
  300. * Data - unused
  301. *
  302. **********************************************************/
  303. NTSTATUS
  304. AuthzReportEventW( IN PAUTHZ_AUDIT_EVENT_TYPE_HANDLE pHAET,
  305. IN DWORD Flags,
  306. IN ULONG EventId,
  307. IN PSID pUserSID,
  308. IN USHORT NumStrings,
  309. IN ULONG DataSize OPTIONAL, //Future - DO NOT USE
  310. IN PWSTR* Strings,
  311. IN PVOID Data OPTIONAL //Future - DO NOT USE
  312. )
  313. {
  314. NTSTATUS status = STATUS_ACCESS_DENIED;
  315. AUTHZ_AUDIT_EVENT_HANDLE hAE = NULL;
  316. BOOL fSuccess = FALSE;
  317. PAUDIT_PARAMS pParams = NULL;
  318. if( NULL == hRM || NULL == pHAET || *pHAET == NULL )
  319. return status;
  320. fSuccess = AuthziAllocateAuditParams( &pParams, NumStrings );
  321. if ( !fSuccess )
  322. {
  323. DBGPRINT(("TERMSRV: AuditEvent: AuthzAllocateAuditParams failed with %d\n", GetLastError()));
  324. goto BadAuditEvent;
  325. }
  326. if( 6 == NumStrings )
  327. {
  328. fSuccess = AuthziInitializeAuditParamsWithRM( Flags,
  329. hRM,
  330. NumStrings,
  331. pParams,
  332. APT_String, Strings[0],
  333. APT_String, Strings[1],
  334. APT_String, Strings[2],
  335. APT_String, Strings[3],
  336. APT_String, Strings[4],
  337. APT_String, Strings[5]
  338. );
  339. }
  340. else if( 0 == NumStrings )
  341. {
  342. fSuccess = AuthziInitializeAuditParamsWithRM( Flags,
  343. hRM,
  344. NumStrings,
  345. pParams
  346. );
  347. }
  348. else
  349. {
  350. //we don't support anything else
  351. fSuccess = FALSE;
  352. DBGPRINT(("TERMSRV: AuditEvent: unsupported audit type \n"));
  353. goto BadAuditEvent;
  354. }
  355. if ( !fSuccess )
  356. {
  357. DBGPRINT(("TERMSRV: AuditEvent: AuthziInitializeAuditParamsWithRM failed with %d\n", GetLastError()));
  358. goto BadAuditEvent;
  359. }
  360. fSuccess = AuthziInitializeAuditEvent( 0,
  361. hRM,
  362. *pHAET,
  363. pParams,
  364. NULL,
  365. INFINITE,
  366. L"",
  367. L"",
  368. L"",
  369. L"",
  370. &hAE
  371. );
  372. if ( !fSuccess )
  373. {
  374. DBGPRINT(("TERMSRV: AuditEvent: AuthziInitializeAuditEvent failed with %d\n", GetLastError()));
  375. goto BadAuditEvent;
  376. }
  377. fSuccess = AuthziLogAuditEvent( 0,
  378. hAE,
  379. NULL
  380. );
  381. if ( !fSuccess )
  382. {
  383. DBGPRINT(("TERMSRV: AuditEvent: AuthziLogAuditEvent failed with %d\n", GetLastError()));
  384. goto BadAuditEvent;
  385. }
  386. BadAuditEvent:
  387. if( hAE )
  388. AuthzFreeAuditEvent( hAE );
  389. if( pParams )
  390. AuthziFreeAuditParams( pParams );
  391. if( fSuccess )
  392. status = STATUS_SUCCESS;
  393. //if( fSuccess )
  394. // DBGPRINT(("TERMSRV: Successfully audited event with authz= %d\n", EventId));
  395. return status;
  396. }