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.

415 lines
9.2 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: events.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 1-03-95 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "kdcsvr.hxx"
  18. #include <netlib.h>
  19. extern "C" {
  20. #include <lmserver.h>
  21. #include <srvann.h>
  22. }
  23. HANDLE hEventLog = (HANDLE)NULL;
  24. DWORD LoggingLevel = (1 << EVENTLOG_ERROR_TYPE) | (1 << EVENTLOG_WARNING_TYPE);
  25. WCHAR EventSourceName[] = TEXT("KDC");
  26. #define MAX_EVENT_STRINGS 8
  27. #define MAX_ETYPE_LONG 999
  28. #define MIN_ETYPE_LONG -999
  29. #define MAX_ETYPE_STRING 16 // 4wchar + , + 2 space
  30. #define WSZ_NO_KEYS L"< >"
  31. //+---------------------------------------------------------------------------
  32. //
  33. // Function: InitializeEvents
  34. //
  35. // Synopsis: Connects to event log service
  36. //
  37. // Arguments: (none)
  38. //
  39. // History: 1-03-95 RichardW Created
  40. //
  41. // Notes:
  42. //
  43. //----------------------------------------------------------------------------
  44. BOOL
  45. InitializeEvents(void)
  46. {
  47. TRACE(KDC, InitializeEvents, DEB_FUNCTION);
  48. //
  49. // Interval with which we'll log the same event twice
  50. //
  51. #define KDC_EVENT_LIFETIME (60*60*1000)
  52. hEventLog = NetpEventlogOpen(EventSourceName, KDC_EVENT_LIFETIME);
  53. if (hEventLog)
  54. {
  55. return(TRUE);
  56. }
  57. DebugLog((DEB_ERROR, "Could not open event log, error %d\n", GetLastError()));
  58. return(FALSE);
  59. }
  60. //+---------------------------------------------------------------------------
  61. //
  62. // Function: ReportServiceEvent
  63. //
  64. // Synopsis: Reports an event to the event log
  65. //
  66. // Arguments: [EventType] -- EventType (ERROR, WARNING, etc.)
  67. // [EventId] -- Event ID
  68. // [SizeOfRawData] -- Size of raw data
  69. // [RawData] -- Raw data
  70. // [NumberOfStrings] -- number of strings
  71. // ... -- PWSTRs to string data
  72. //
  73. // History: 1-03-95 RichardW Created
  74. //
  75. // Notes:
  76. //
  77. //----------------------------------------------------------------------------
  78. DWORD
  79. ReportServiceEvent(
  80. IN WORD EventType,
  81. IN DWORD EventId,
  82. IN DWORD SizeOfRawData,
  83. IN PVOID RawData,
  84. IN DWORD NumberOfStrings,
  85. ...
  86. )
  87. {
  88. TRACE(KDC, ReportServiceEvent, DEB_FUNCTION);
  89. va_list arglist;
  90. ULONG i;
  91. PWSTR Strings[ MAX_EVENT_STRINGS ];
  92. DWORD rv;
  93. if (!hEventLog)
  94. {
  95. DebugLog((DEB_ERROR, "Cannot log event, no handle!\n"));
  96. return((DWORD)-1);
  97. }
  98. #ifdef notdef
  99. //
  100. // We're not supposed to be logging this, so nuke it
  101. //
  102. if ((LoggingLevel & (1 << EventType)) == 0)
  103. {
  104. return(0);
  105. }
  106. #endif
  107. //
  108. // Look at the strings, if they were provided
  109. //
  110. va_start( arglist, NumberOfStrings );
  111. if (NumberOfStrings > MAX_EVENT_STRINGS) {
  112. NumberOfStrings = MAX_EVENT_STRINGS;
  113. }
  114. for (i=0; i<NumberOfStrings; i++) {
  115. Strings[ i ] = va_arg( arglist, PWSTR );
  116. }
  117. //
  118. // Report the event to the eventlog service
  119. //
  120. if ((rv = NetpEventlogWrite(
  121. hEventLog,
  122. EventId,
  123. EventType,
  124. (PBYTE) RawData,
  125. SizeOfRawData,
  126. (LPWSTR *) Strings,
  127. NumberOfStrings
  128. )) != ERROR_SUCCESS)
  129. {
  130. DebugLog((DEB_ERROR, "NetpEventlogWrite( 0x%x ) failed - %u\n", EventId, rv ));
  131. }
  132. return rv;
  133. }
  134. BOOL
  135. ShutdownEvents(void)
  136. {
  137. TRACE(KDC, ShutdownEvents, DEB_FUNCTION);
  138. NetpEventlogClose(hEventLog);
  139. return TRUE;
  140. }
  141. NTSTATUS
  142. KdcBuildEtypeStringFromStoredCredential(
  143. IN PKERB_STORED_CREDENTIAL Cred,
  144. IN OUT PWSTR * EtypeString
  145. )
  146. {
  147. ULONG BuffSize;
  148. PWSTR Ret = NULL;
  149. WCHAR Buff[12];
  150. *EtypeString = NULL;
  151. if (Cred == NULL
  152. || ((Cred->CredentialCount + Cred->OldCredentialCount) == 0) )
  153. {
  154. BuffSize = sizeof(WCHAR) * (wcslen(WSZ_NO_KEYS)+1);
  155. *EtypeString = (LPWSTR)MIDL_user_allocate(BuffSize);
  156. if (NULL == *EtypeString)
  157. {
  158. return STATUS_INSUFFICIENT_RESOURCES;
  159. }
  160. wcscpy(*EtypeString, WSZ_NO_KEYS);
  161. return STATUS_SUCCESS;
  162. }
  163. // Guess maximum buffer... Etypes are 4 chars at most
  164. BuffSize = ((Cred->CredentialCount + Cred->OldCredentialCount )* MAX_ETYPE_STRING);
  165. Ret = (LPWSTR)MIDL_user_allocate(BuffSize);
  166. if (NULL == Ret)
  167. {
  168. return STATUS_INSUFFICIENT_RESOURCES;
  169. }
  170. for (LONG Index = 0;Index < (Cred->CredentialCount + Cred->OldCredentialCount ); Index++ )
  171. {
  172. if (Cred->Credentials[Index].Key.keytype > MAX_ETYPE_LONG ||
  173. Cred->Credentials[Index].Key.keytype < MIN_ETYPE_LONG)
  174. {
  175. DebugLog((DEB_ERROR, "Keytype too large for string conversion\n"));
  176. DsysAssert(FALSE);
  177. }
  178. else
  179. {
  180. _itow(Cred->Credentials[Index].Key.keytype, Buff, 10);
  181. wcscat(Ret, Buff);
  182. wcscat(Ret, L" ");
  183. }
  184. }
  185. *EtypeString = Ret;
  186. return STATUS_SUCCESS;
  187. }
  188. NTSTATUS
  189. KdcBuildEtypeStringFromCryptList(
  190. IN PKERB_CRYPT_LIST CryptList,
  191. IN OUT LPWSTR * EtypeString
  192. )
  193. {
  194. ULONG BuffSize = 0, CryptCount = 0;
  195. PWSTR Ret = NULL;
  196. WCHAR Buff[30];
  197. PKERB_CRYPT_LIST ListPointer = CryptList;
  198. *EtypeString = NULL;
  199. if (CryptList == NULL)
  200. {
  201. BuffSize = sizeof(WCHAR) * (wcslen(WSZ_NO_KEYS)+1);
  202. *EtypeString = (LPWSTR)MIDL_user_allocate(BuffSize);
  203. if (NULL == *EtypeString)
  204. {
  205. return STATUS_INSUFFICIENT_RESOURCES;
  206. }
  207. wcscpy(*EtypeString, WSZ_NO_KEYS);
  208. return STATUS_SUCCESS;
  209. }
  210. while (TRUE)
  211. {
  212. if (ListPointer->value > MAX_ETYPE_LONG || ListPointer->value < MIN_ETYPE_LONG)
  213. {
  214. DebugLog((DEB_ERROR, "Maximum etype exceeded\n"));
  215. return STATUS_INVALID_PARAMETER;
  216. }
  217. BuffSize += MAX_ETYPE_STRING;
  218. if (NULL == ListPointer->next)
  219. {
  220. break;
  221. }
  222. ListPointer = ListPointer->next;
  223. }
  224. Ret = (LPWSTR) MIDL_user_allocate(BuffSize);
  225. if (NULL == Ret)
  226. {
  227. return STATUS_INSUFFICIENT_RESOURCES;
  228. }
  229. while (TRUE)
  230. {
  231. _itow(CryptList->value, Buff, 10);
  232. wcscat(Ret,Buff);
  233. wcscat(Ret, L" ");
  234. if (NULL == CryptList->next)
  235. {
  236. break;
  237. }
  238. CryptList = CryptList->next;
  239. }
  240. *EtypeString = Ret;
  241. return STATUS_SUCCESS;
  242. }
  243. void
  244. KdcReportKeyError(
  245. IN PUNICODE_STRING AccountName,
  246. IN OPTIONAL PUNICODE_STRING ServerName,
  247. IN ULONG EventId,
  248. IN OPTIONAL PKERB_CRYPT_LIST RequestEtypes,
  249. IN OPTIONAL PKERB_STORED_CREDENTIAL StoredCredential
  250. )
  251. {
  252. ULONG NumberOfStrings;
  253. NTSTATUS Status;
  254. PWSTR Strings[ MAX_EVENT_STRINGS ];
  255. PWSTR RequestEtypeString = NULL;
  256. PWSTR AccountNameEtypeString = NULL;
  257. DWORD rv;
  258. if (!hEventLog)
  259. {
  260. DebugLog((DEB_ERROR, "Cannot log event, no handle!\n"));
  261. return;
  262. }
  263. Status = KdcBuildEtypeStringFromCryptList(
  264. RequestEtypes,
  265. &RequestEtypeString
  266. );
  267. if (!NT_SUCCESS(Status))
  268. {
  269. DebugLog((DEB_ERROR, "KdcBuildEtypeFromCryptList failed\n"));
  270. goto cleanup;
  271. }
  272. Status = KdcBuildEtypeStringFromStoredCredential(
  273. StoredCredential,
  274. &AccountNameEtypeString
  275. );
  276. if (!NT_SUCCESS(Status))
  277. {
  278. DebugLog((DEB_ERROR, "KdcBuildEtypeFromStoredCredential failed\n"));
  279. goto cleanup;
  280. }
  281. if (EventId == KDCEVENT_NO_KEY_UNION_AS )
  282. {
  283. Strings[0] = AccountName->Buffer;
  284. Strings[1] = RequestEtypeString;
  285. Strings[2] = AccountNameEtypeString;
  286. NumberOfStrings = 3;
  287. }
  288. else if (EventId == KDCEVENT_NO_KEY_UNION_TGS )
  289. {
  290. if (!ARGUMENT_PRESENT(ServerName))
  291. {
  292. DebugLog((DEB_ERROR, "Invalid arg to KdcReportKeyError!\n"));
  293. DsysAssert(FALSE);
  294. goto cleanup;
  295. }
  296. Strings[0] = ServerName->Buffer;
  297. Strings[1] = AccountName->Buffer;
  298. Strings[2] = RequestEtypeString;
  299. Strings[3] = AccountNameEtypeString;
  300. NumberOfStrings = 4;
  301. }
  302. else
  303. {
  304. goto cleanup;
  305. }
  306. if ((rv = NetpEventlogWrite(
  307. hEventLog,
  308. EventId,
  309. EVENTLOG_ERROR_TYPE,
  310. NULL,
  311. 0, // no raw data
  312. (LPWSTR *) Strings,
  313. NumberOfStrings
  314. )) != ERROR_SUCCESS)
  315. {
  316. DebugLog((DEB_ERROR, "NetpEventlogWrite( 0x%x ) failed - %u\n", EventId, rv ));
  317. }
  318. cleanup:
  319. if (NULL != RequestEtypeString )
  320. {
  321. MIDL_user_free(RequestEtypeString);
  322. }
  323. if (NULL != AccountNameEtypeString )
  324. {
  325. MIDL_user_free(AccountNameEtypeString);
  326. }
  327. return;
  328. }
  329. \