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.

929 lines
25 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 <kerb.hxx>
  18. #include <kerbp.h>
  19. #include "krbevent.h"
  20. #include "kerbevt.h"
  21. #include <limits.h>
  22. #ifdef DEBUG_SUPPORT
  23. static TCHAR THIS_FILE[]=TEXT(__FILE__);
  24. #endif
  25. HANDLE KerbEventLogHandle = NULL;
  26. WCHAR KerbEventSourceName[] = L"Kerberos";
  27. //+-------------------------------------------------------------------------
  28. //
  29. // Function: KerbErrorToString
  30. //
  31. // Synopsis: returns a string from the data segment pointing to the name
  32. // of an error
  33. //
  34. // Effects:
  35. //
  36. // Arguments:
  37. //
  38. // Requires:
  39. //
  40. // Returns:
  41. //
  42. // Notes:
  43. //
  44. //
  45. //--------------------------------------------------------------------------
  46. LPWSTR
  47. KerbErrorToString(
  48. IN KERBERR KerbErr
  49. )
  50. {
  51. LPWSTR String;
  52. switch (KerbErr)
  53. {
  54. case KDC_ERR_NONE : String = L"KDC_ERR_NONE"; break;
  55. case KDC_ERR_NAME_EXP : String = L"KDC_ERR_NAME_EXP"; break;
  56. case KDC_ERR_SERVICE_EXP : String = L"KDC_ERR_SERVICE_EXP"; break;
  57. case KDC_ERR_BAD_PVNO : String = L"KDC_ERR_BAD_PVNO"; break;
  58. case KDC_ERR_C_OLD_MAST_KVNO : String = L"KDC_ERR_C_OLD_MAST_KVNO"; break;
  59. case KDC_ERR_S_OLD_MAST_KVNO : String = L"KDC_ERR_S_OLD_MAST_KVNO"; break;
  60. case KDC_ERR_C_PRINCIPAL_UNKNOWN : String = L"KDC_ERR_C_PRINCIPAL_UNKNOWN"; break;
  61. case KDC_ERR_S_PRINCIPAL_UNKNOWN : String = L" KDC_ERR_S_PRINCIPAL_UNKNOWN"; break;
  62. case KDC_ERR_PRINCIPAL_NOT_UNIQUE : String = L"KDC_ERR_PRINCIPAL_NOT_UNIQUE"; break;
  63. case KDC_ERR_NULL_KEY : String = L"KDC_ERR_NULL_KEY"; break;
  64. case KDC_ERR_CANNOT_POSTDATE : String = L"KDC_ERR_CANNOT_POSTDATE"; break;
  65. case KDC_ERR_NEVER_VALID : String = L"KDC_ERR_NEVER_VALID"; break;
  66. case KDC_ERR_POLICY : String = L"KDC_ERR_POLICY"; break;
  67. case KDC_ERR_BADOPTION : String = L"KDC_ERR_BADOPTION"; break;
  68. case KDC_ERR_ETYPE_NOTSUPP : String = L"KDC_ERR_ETYPE_NOTSUPP"; break;
  69. case KDC_ERR_SUMTYPE_NOSUPP : String = L"KDC_ERR_SUMTYPE_NOSUPP"; break;
  70. case KDC_ERR_PADATA_TYPE_NOSUPP : String = L"KDC_ERR_PADATA_TYPE_NOSUPP"; break;
  71. case KDC_ERR_TRTYPE_NO_SUPP : String = L"KDC_ERR_TRTYPE_NO_SUPP"; break;
  72. case KDC_ERR_CLIENT_REVOKED : String = L"KDC_ERR_CLIENT_REVOKED"; break;
  73. case KDC_ERR_SERVICE_REVOKED : String = L"KDC_ERR_SERVICE_REVOKED"; break;
  74. case KDC_ERR_TGT_REVOKED : String = L"KDC_ERR_TGT_REVOKED"; break;
  75. case KDC_ERR_CLIENT_NOTYET : String = L"KDC_ERR_CLIENT_NOTYET"; break;
  76. case KDC_ERR_SERVICE_NOTYET : String = L"KDC_ERR_SERVICE_NOTYET"; break;
  77. case KDC_ERR_KEY_EXPIRED : String = L"KDC_ERR_KEY_EXPIRED"; break;
  78. case KDC_ERR_PREAUTH_FAILED : String = L"KDC_ERR_PREAUTH_FAILED"; break;
  79. case KDC_ERR_PREAUTH_REQUIRED : String = L"KDC_ERR_PREAUTH_REQUIRED"; break;
  80. case KDC_ERR_SERVER_NOMATCH : String = L"KDC_ERR_SERVER_NOMATCH"; break;
  81. case KDC_ERR_SVC_UNAVAILABLE : String = L"KDC_ERR_SVC_UNAVAILABLE"; break;
  82. case KRB_AP_ERR_BAD_INTEGRITY : String = L"KRB_AP_ERR_BAD_INTEGRITY"; break;
  83. case KRB_AP_ERR_TKT_EXPIRED : String = L"KRB_AP_ERR_TKT_EXPIRED"; break;
  84. case KRB_AP_ERR_TKT_NYV : String = L"KRB_AP_ERR_TKT_NYV"; break;
  85. case KRB_AP_ERR_REPEAT : String = L"KRB_AP_ERR_REPEAT"; break;
  86. case KRB_AP_ERR_NOT_US : String = L"KRB_AP_ERR_NOT_US"; break;
  87. case KRB_AP_ERR_BADMATCH : String = L"KRB_AP_ERR_BADMATCH"; break;
  88. case KRB_AP_ERR_SKEW : String = L"KRB_AP_ERR_SKEW"; break;
  89. case KRB_AP_ERR_BADADDR : String = L"KRB_AP_ERR_BADADDR"; break;
  90. case KRB_AP_ERR_BADVERSION : String = L"KRB_AP_ERR_BADVERSION"; break;
  91. case KRB_AP_ERR_MSG_TYPE : String = L"KRB_AP_ERR_MSG_TYPE"; break;
  92. case KRB_AP_ERR_MODIFIED : String = L"KRB_AP_ERR_MODIFIED"; break;
  93. case KRB_AP_ERR_BADORDER : String = L"KRB_AP_ERR_BADORDER"; break;
  94. case KRB_AP_ERR_BADKEYVER : String = L"KRB_AP_ERR_BADKEYVER"; break;
  95. case KRB_AP_ERR_NOKEY : String = L"KRB_AP_ERR_NOKEY"; break;
  96. case KRB_AP_ERR_MUT_FAIL : String = L"KRB_AP_ERR_MUT_FAIL"; break;
  97. case KRB_AP_ERR_BADDIRECTION : String = L"KRB_AP_ERR_BADDIRECTION"; break;
  98. case KRB_AP_ERR_METHOD : String = L"KRB_AP_ERR_METHOD"; break;
  99. case KRB_AP_ERR_BADSEQ : String = L"KRB_AP_ERR_BADSEQ"; break;
  100. case KRB_AP_ERR_INAPP_CKSUM : String = L"KRB_AP_ERR_INAPP_CKSUM"; break;
  101. case KRB_AP_PATH_NOT_ACCEPTED : String = L"KRB_AP_PATH_NOT_ACCEPTED"; break;
  102. case KRB_ERR_RESPONSE_TOO_BIG : String = L"KRB_ERR_RESPONSE_TOO_BIG"; break;
  103. case KRB_ERR_GENERIC : String = L"KRB_ERR_GENERIC"; break;
  104. case KRB_ERR_FIELD_TOOLONG : String = L"KRB_ERR_FIELD_TOOLONG"; break;
  105. case KDC_ERR_CLIENT_NOT_TRUSTED : String = L"KDC_ERR_CLIENT_NOT_TRUSTED"; break;
  106. case KDC_ERR_KDC_NOT_TRUSTED : String = L"KDC_ERR_KDC_NOT_TRUSTED"; break;
  107. case KDC_ERR_INVALID_SIG : String = L"KDC_ERR_INVALID_SIG"; break;
  108. case KDC_ERR_KEY_TOO_WEAK : String = L"KDC_ERR_KEY_TOO_WEAK"; break;
  109. case KRB_AP_ERR_USER_TO_USER_REQUIRED : String = L"KRB_AP_ERR_USER_TO_USER_REQUIRED"; break;
  110. case KRB_AP_ERR_NO_TGT : String = L"KRB_AP_ERR_NO_TGT"; break;
  111. case KDC_ERR_WRONG_REALM : String = L"KDC_ERR_WRONG_REALM"; break;
  112. default : String = L"Unknown Error"; break;
  113. }
  114. return(String);
  115. }
  116. //+---------------------------------------------------------------------------
  117. //
  118. // Function: InitializeEvents
  119. //
  120. // Synopsis: Connects to event log service
  121. //
  122. // Arguments: (none)
  123. //
  124. // History: 1-03-95 RichardW Created
  125. //
  126. // Notes:
  127. //
  128. //----------------------------------------------------------------------------
  129. NTSTATUS
  130. KerbInitializeEvents(
  131. VOID
  132. )
  133. {
  134. return STATUS_SUCCESS;
  135. }
  136. //+-------------------------------------------------------------------------
  137. //
  138. // Function: KerbInitEventLogHandle
  139. //
  140. // Synopsis:
  141. //
  142. // Effects:
  143. //
  144. // Arguments:
  145. //
  146. // Requires:
  147. //
  148. // Returns:
  149. //
  150. // Notes:
  151. //
  152. //
  153. //--------------------------------------------------------------------------
  154. NTSTATUS
  155. KerbInitEventLogHandle()
  156. {
  157. NTSTATUS Status = STATUS_SUCCESS;
  158. if (KerbEventLogHandle == NULL)
  159. {
  160. HANDLE EventLogHandle;
  161. //
  162. // open an instance of kerb event sources, that discards duplicate
  163. // events in a one hour window.
  164. //
  165. EventLogHandle = NetpEventlogOpen( KerbEventSourceName, 60000*60 );
  166. if (EventLogHandle != NULL)
  167. {
  168. //
  169. // atomically store the new handle value. If there was a race,
  170. // free the one we just created.
  171. //
  172. if(InterlockedCompareExchangePointer(
  173. &KerbEventLogHandle,
  174. EventLogHandle,
  175. NULL
  176. ) != NULL)
  177. {
  178. NetpEventlogClose( EventLogHandle );
  179. }
  180. }
  181. if (KerbEventLogHandle == NULL)
  182. {
  183. D_DebugLog((DEB_ERROR, "Could not open event log, error %d. %ws, line %d - %x\n", GetLastError(), THIS_FILE, __LINE__, Status));
  184. return STATUS_EVENTLOG_CANT_START;
  185. }
  186. }
  187. return Status;
  188. }
  189. //+-------------------------------------------------------------------------
  190. //
  191. // Function: KerbReportNtstatus
  192. //
  193. // Synopsis:
  194. //
  195. // Effects:
  196. //
  197. // Arguments:
  198. //
  199. // Requires:
  200. //
  201. // Returns:
  202. //
  203. // Notes:
  204. //
  205. //
  206. //--------------------------------------------------------------------------
  207. #define MAX_NTSTATUS_STRINGS 10
  208. #define MAX_ULONG_STRING 20
  209. VOID
  210. KerbReportNtstatus(
  211. IN ULONG ErrorClass,
  212. IN NTSTATUS Status,
  213. IN LPWSTR* ErrorStrings,
  214. IN ULONG NumberOfStrings,
  215. IN PULONG Data,
  216. IN ULONG NumberOfUlong
  217. )
  218. {
  219. ULONG StringCount, i, j, allocstart = 0;
  220. LPWSTR Strings[MAX_NTSTATUS_STRINGS];
  221. StringCount = NumberOfUlong + NumberOfStrings;
  222. if (StringCount > MAX_NTSTATUS_STRINGS)
  223. {
  224. return;
  225. }
  226. //
  227. // Validate params
  228. //
  229. switch (ErrorClass)
  230. {
  231. case KERBEVT_INSUFFICIENT_TOKEN_SIZE:
  232. if ((NumberOfStrings != 0) || (NumberOfUlong > 3))
  233. {
  234. DsysAssert(FALSE);
  235. return;
  236. }
  237. break;
  238. default:
  239. return;
  240. }
  241. if (KerbEventLogHandle == NULL)
  242. {
  243. NTSTATUS TmpStatus;
  244. TmpStatus = KerbInitEventLogHandle();
  245. if (TmpStatus != STATUS_SUCCESS)
  246. {
  247. return;
  248. }
  249. }
  250. ZeroMemory( Strings, (StringCount * sizeof(Strings[0])) );
  251. for (i = 0; i < NumberOfStrings; i++)
  252. {
  253. Strings[i] = ErrorStrings[i];
  254. }
  255. allocstart = i; // save for cleanup
  256. for (j = 0; j < NumberOfUlong; j++)
  257. {
  258. UNICODE_STRING DummyString = { MAX_ULONG_STRING, MAX_ULONG_STRING, NULL};
  259. DummyString.Buffer = (LPWSTR) LsaFunctions->AllocatePrivateHeap(MAX_ULONG_STRING);
  260. if ( DummyString.Buffer == NULL )
  261. {
  262. goto Cleanup;
  263. }
  264. //
  265. // Use this since they don't export
  266. // RtlIntegerToUnicode(), and we don't want to
  267. // bring in _itow.
  268. //
  269. RtlIntegerToUnicodeString(
  270. Data[j],
  271. 16,
  272. &DummyString
  273. );
  274. Strings[i] = DummyString.Buffer;
  275. i++;
  276. }
  277. if (ERROR_SUCCESS != NetpEventlogWriteEx(
  278. KerbEventLogHandle,
  279. EVENTLOG_WARNING_TYPE,
  280. 0,
  281. ErrorClass,
  282. (WORD) StringCount,
  283. sizeof(NTSTATUS),
  284. Strings,
  285. &Status
  286. ))
  287. {
  288. D_DebugLog((DEB_ERROR,"Failed to report event: %d. %ws, line %d\n",GetLastError(), THIS_FILE, __LINE__));
  289. }
  290. Cleanup:
  291. for (i = allocstart ; i < (allocstart+NumberOfUlong) ; i++)
  292. {
  293. if (Strings[i] != NULL)
  294. {
  295. LsaFunctions->FreePrivateHeap(Strings[i]);
  296. }
  297. }
  298. return;
  299. }
  300. //+-------------------------------------------------------------------------
  301. //
  302. // Function: KerbReportKerbError
  303. //
  304. // Synopsis:
  305. //
  306. // Effects:
  307. //
  308. // Arguments:
  309. //
  310. // Requires:
  311. //
  312. // Returns:
  313. //
  314. // Notes:
  315. //
  316. //
  317. //--------------------------------------------------------------------------
  318. VOID
  319. KerbReportKerbError(
  320. IN OPTIONAL PKERB_INTERNAL_NAME PrincipalName,
  321. IN OPTIONAL PUNICODE_STRING PrincipalRealm,
  322. IN OPTIONAL PKERB_LOGON_SESSION LogonSession,
  323. IN OPTIONAL PKERB_CREDENTIAL Credential,
  324. IN ULONG KlinInfo,
  325. IN OPTIONAL PKERB_ERROR ErrorMsg,
  326. IN ULONG KerbError,
  327. IN OPTIONAL PKERB_EXT_ERROR pExtendedError,
  328. IN BOOLEAN RequiredEvent
  329. )
  330. {
  331. #ifdef WIN32_CHICAGO
  332. return;
  333. #else
  334. UNICODE_STRING ClientRealm = {0};
  335. UNICODE_STRING ClientName = {0};
  336. UNICODE_STRING ServerRealm = {0};
  337. UNICODE_STRING ServerName = {0};
  338. UNICODE_STRING ErrorText = {0};
  339. UNICODE_STRING LogonSessionName = {0};
  340. UNICODE_STRING TargetFullName = {0};
  341. WCHAR ClientTime[50] = {0};
  342. WCHAR ServerTime[50] = {0};
  343. WCHAR LineString[12] = {0};
  344. WCHAR ErrorCode[12] = {0};
  345. WCHAR ExtendedError[128] = {0};
  346. KERBERR KerbErr;
  347. ULONG NameType;
  348. NTSTATUS Status = STATUS_SUCCESS;
  349. STRING KerbString = {0};
  350. #define KERB_ERROR_STRING_COUNT 13
  351. LPWSTR Strings[KERB_ERROR_STRING_COUNT];
  352. ULONG RawDataSize = 0;
  353. PVOID RawData = NULL;
  354. ULONG Index;
  355. if (!RequiredEvent || KerbGlobalLoggingLevel == 0)
  356. {
  357. return;
  358. }
  359. if (KerbEventLogHandle == NULL)
  360. {
  361. Status = KerbInitEventLogHandle();
  362. if (Status != STATUS_SUCCESS)
  363. {
  364. return;
  365. }
  366. }
  367. //
  368. // Get the user name from the logon session
  369. //
  370. if (ARGUMENT_PRESENT(LogonSession))
  371. {
  372. KerbReadLockLogonSessions( LogonSession );
  373. KerbErr = KerbBuildFullServiceName(
  374. &LogonSession->PrimaryCredentials.DomainName,
  375. &LogonSession->PrimaryCredentials.UserName,
  376. &LogonSessionName
  377. );
  378. KerbUnlockLogonSessions( LogonSession );
  379. if (!KERB_SUCCESS(KerbErr))
  380. {
  381. goto Cleanup;
  382. }
  383. }
  384. if (ARGUMENT_PRESENT(pExtendedError))
  385. {
  386. swprintf(ExtendedError, L"0x%x KLIN(%x)", pExtendedError->status, pExtendedError->klininfo);
  387. }
  388. if (ARGUMENT_PRESENT(PrincipalName) && ARGUMENT_PRESENT(PrincipalRealm))
  389. {
  390. KerbConvertKdcNameToString(
  391. &TargetFullName,
  392. PrincipalName,
  393. PrincipalRealm
  394. );
  395. }
  396. swprintf(LineString, L"%x", KlinInfo);
  397. if (ARGUMENT_PRESENT(ErrorMsg))
  398. {
  399. swprintf(ErrorCode, L"0x%x", ErrorMsg->error_code);
  400. //
  401. // Get the client and server realms
  402. //
  403. if ((ErrorMsg->bit_mask & client_realm_present) != 0)
  404. {
  405. KerbErr = KerbConvertRealmToUnicodeString(
  406. &ClientRealm,
  407. &ErrorMsg->client_realm
  408. );
  409. if (!KERB_SUCCESS(KerbErr))
  410. {
  411. goto Cleanup;
  412. }
  413. }
  414. if (ErrorMsg->realm != NULL)
  415. {
  416. KerbErr = KerbConvertRealmToUnicodeString(
  417. &ServerRealm,
  418. &ErrorMsg->realm
  419. );
  420. if (!KERB_SUCCESS(KerbErr))
  421. {
  422. goto Cleanup;
  423. }
  424. }
  425. if ((ErrorMsg->bit_mask & KERB_ERROR_client_name_present) != 0)
  426. {
  427. KerbErr = KerbConvertPrincipalNameToString(
  428. &ClientName,
  429. &NameType,
  430. &ErrorMsg->KERB_ERROR_client_name
  431. );
  432. if (!KERB_SUCCESS(KerbErr))
  433. {
  434. goto Cleanup;
  435. }
  436. }
  437. KerbErr = KerbConvertPrincipalNameToString(
  438. &ServerName,
  439. &NameType,
  440. &ErrorMsg->server_name
  441. );
  442. if (!KERB_SUCCESS(KerbErr))
  443. {
  444. goto Cleanup;
  445. }
  446. if ((ErrorMsg->bit_mask & client_time_present) != 0)
  447. {
  448. swprintf(ClientTime,L"%d:%d:%d.%04d %d/%d/%d %ws",
  449. ErrorMsg->client_time.hour,
  450. ErrorMsg->client_time.minute,
  451. ErrorMsg->client_time.second,
  452. ErrorMsg->client_time.millisecond,
  453. ErrorMsg->client_time.month,
  454. ErrorMsg->client_time.day,
  455. ErrorMsg->client_time.year,
  456. (ErrorMsg->client_time.universal) ? L"Z" : L""
  457. );
  458. }
  459. swprintf(ServerTime,L"%d:%d:%d.%04d %d/%d/%d %ws",
  460. ErrorMsg->server_time.hour,
  461. ErrorMsg->server_time.minute,
  462. ErrorMsg->server_time.second,
  463. ErrorMsg->server_time.millisecond,
  464. ErrorMsg->server_time.month,
  465. ErrorMsg->server_time.day,
  466. ErrorMsg->server_time.year,
  467. (ErrorMsg->server_time.universal) ? L"Z" : L""
  468. );
  469. if (((ErrorMsg->bit_mask & error_text_present) != 0) &&
  470. (ErrorMsg->error_text.length < SHRT_MAX))
  471. {
  472. KerbString.Buffer = ErrorMsg->error_text.value;
  473. KerbString.Length = (USHORT) ErrorMsg->error_text.length;
  474. KerbErr = KerbStringToUnicodeString(
  475. &ErrorText,
  476. &KerbString
  477. );
  478. if (!KERB_SUCCESS(KerbErr))
  479. {
  480. goto Cleanup;
  481. }
  482. }
  483. if ((ErrorMsg->bit_mask & error_data_present) != 0)
  484. {
  485. RawDataSize = ErrorMsg->error_data.length;
  486. RawData = ErrorMsg->error_data.value;
  487. }
  488. }
  489. else
  490. {
  491. swprintf(ErrorCode, L"0x%x", KerbError);
  492. }
  493. //
  494. // Build the array of strings
  495. //
  496. Strings[0] = LineString;
  497. Strings[1] = LogonSessionName.Buffer;
  498. Strings[2] = ClientTime;
  499. Strings[3] = ServerTime;
  500. Strings[4] = ErrorCode;
  501. Strings[5] = (ARGUMENT_PRESENT(ErrorMsg)
  502. ? KerbErrorToString(ErrorMsg->error_code) :
  503. KerbErrorToString(KerbError));
  504. Strings[6] = ExtendedError;
  505. Strings[7] = ClientRealm.Buffer;
  506. Strings[8] = ClientName.Buffer;
  507. Strings[9] = ServerRealm.Buffer;
  508. Strings[10] = ServerName.Buffer;
  509. Strings[11] = TargetFullName.Buffer;
  510. Strings[12] = ErrorText.Buffer;
  511. //
  512. // Replace NULLs with an empty string.
  513. //
  514. for (Index = 0; Index < KERB_ERROR_STRING_COUNT ; Index++ )
  515. {
  516. if (Strings[Index] == NULL)
  517. {
  518. Strings[Index] = L"";
  519. }
  520. }
  521. if (ERROR_SUCCESS != NetpEventlogWriteEx(
  522. KerbEventLogHandle,
  523. EVENTLOG_ERROR_TYPE,
  524. 0,
  525. KERBEVT_KERB_ERROR_MSG,
  526. KERB_ERROR_STRING_COUNT,
  527. RawDataSize,
  528. Strings,
  529. RawData
  530. ))
  531. {
  532. D_DebugLog((DEB_ERROR,"Failed to report event: %d. %ws, line %d\n",GetLastError(), THIS_FILE, __LINE__));
  533. }
  534. Cleanup:
  535. KerbFreeString( &LogonSessionName );
  536. KerbFreeString( &ClientRealm );
  537. KerbFreeString( &ClientName );
  538. KerbFreeString( &ServerRealm );
  539. KerbFreeString( &ServerName );
  540. KerbFreeString( &ErrorText );
  541. KerbFreeString( &TargetFullName );
  542. }
  543. //+-------------------------------------------------------------------------
  544. //
  545. // Function: KerbReportApModifiedError
  546. //
  547. // Synopsis: Reports error of type KRB_AP_ERR_MODIFIED
  548. //
  549. // Effects:
  550. //
  551. // Arguments:
  552. //
  553. // Requires:
  554. //
  555. // Returns:
  556. //
  557. // Notes:
  558. //
  559. //
  560. //--------------------------------------------------------------------------
  561. #define MAX_STRINGS 2
  562. VOID
  563. KerbReportApError(
  564. PKERB_ERROR ErrorMsg
  565. )
  566. {
  567. KERBERR KerbErr;
  568. LPWSTR Strings[MAX_STRINGS] = {NULL, NULL};
  569. DWORD EventId = 0, dwDataSize = 0;
  570. WORD StringCount = MAX_STRINGS;
  571. LPVOID lpRawData = NULL;
  572. UNICODE_STRING ServerName = {0};
  573. UNICODE_STRING ServerRealm = {0};
  574. ULONG NameType;
  575. NTSTATUS Status;
  576. if (KerbEventLogHandle == NULL)
  577. {
  578. Status = KerbInitEventLogHandle();
  579. if (Status != STATUS_SUCCESS)
  580. {
  581. return;
  582. }
  583. }
  584. KerbErr = KerbConvertPrincipalNameToString(
  585. &ServerName,
  586. &NameType,
  587. &ErrorMsg->server_name
  588. );
  589. if (!KERB_SUCCESS(KerbErr))
  590. {
  591. goto Cleanup;
  592. }
  593. if (ErrorMsg->realm != NULL)
  594. {
  595. KerbErr = KerbConvertRealmToUnicodeString(
  596. &ServerRealm,
  597. &ErrorMsg->realm
  598. );
  599. if (!KERB_SUCCESS(KerbErr))
  600. {
  601. goto Cleanup;
  602. }
  603. }
  604. Strings[0] = ServerName.Buffer;
  605. Strings[1] = ServerRealm.Buffer;
  606. switch (ErrorMsg->error_code)
  607. {
  608. case KRB_AP_ERR_MODIFIED:
  609. EventId = KERBEVT_KRB_AP_ERR_MODIFIED;
  610. break;
  611. case KRB_AP_ERR_TKT_NYV:
  612. EventId = KERBEVT_KRB_AP_ERR_TKT_NYV;
  613. break;
  614. default:
  615. D_DebugLog((DEB_ERROR, "Unknown error to KerbReportApError %x\n", ErrorMsg->error_code));
  616. goto Cleanup;
  617. }
  618. if (ERROR_SUCCESS != NetpEventlogWriteEx(
  619. KerbEventLogHandle,
  620. EVENTLOG_ERROR_TYPE,
  621. 0,
  622. EventId,
  623. StringCount,
  624. dwDataSize,
  625. Strings,
  626. lpRawData
  627. ))
  628. {
  629. D_DebugLog((DEB_ERROR,"Failed to report event: %d. %ws, line %d\n",GetLastError(), THIS_FILE, __LINE__));
  630. }
  631. Cleanup:
  632. KerbFreeString( &ServerRealm );
  633. KerbFreeString( &ServerName );
  634. }
  635. #endif // WIN32_CHICAGO
  636. //+-------------------------------------------------------------------------
  637. //
  638. // Function: KerbShutdownEvents
  639. //
  640. // Synopsis: Shutsdown event log reporting
  641. //
  642. // Effects:
  643. //
  644. // Arguments:
  645. //
  646. // Requires:
  647. //
  648. // Returns:
  649. //
  650. // Notes:
  651. //
  652. //
  653. //--------------------------------------------------------------------------
  654. VOID
  655. KerbShutdownEvents(
  656. VOID
  657. )
  658. {
  659. HANDLE EventLogHandle;
  660. EventLogHandle = InterlockedExchangePointer( &KerbEventLogHandle, NULL );
  661. if( EventLogHandle )
  662. {
  663. NetpEventlogClose( EventLogHandle );
  664. }
  665. }
  666. //+-------------------------------------------------------------------------
  667. //
  668. // Function: KerbReportPACError
  669. //
  670. // Synopsis: Reports error of type KERBEVT_KRB_PAC_VERIFICATION_FAILURE
  671. //
  672. // Effects:
  673. //
  674. // Arguments:
  675. //
  676. // Requires:
  677. //
  678. // Returns:
  679. //
  680. // Notes:
  681. //
  682. //
  683. //--------------------------------------------------------------------------
  684. VOID
  685. KerbReportPACError(
  686. PUNICODE_STRING ClientName,
  687. PUNICODE_STRING ClientDomain,
  688. NTSTATUS FailureStatus
  689. )
  690. {
  691. KERBERR KerbErr;
  692. LPWSTR Strings[MAX_STRINGS] = {NULL, NULL};
  693. NTSTATUS Status;
  694. if (KerbEventLogHandle == NULL)
  695. {
  696. Status = KerbInitEventLogHandle();
  697. if (Status != STATUS_SUCCESS)
  698. {
  699. return;
  700. }
  701. }
  702. Strings[0] = ClientName->Buffer; // this is null terminated in this case
  703. Strings[1] = ClientDomain->Buffer; // this is null terminated in this case
  704. if (ERROR_SUCCESS != NetpEventlogWriteEx(
  705. KerbEventLogHandle,
  706. EVENTLOG_ERROR_TYPE,
  707. 0,
  708. KERBEVT_KRB_PAC_VERIFICATION_FAILURE,
  709. 2,
  710. sizeof(NTSTATUS),
  711. Strings,
  712. &FailureStatus
  713. ))
  714. {
  715. D_DebugLog((DEB_ERROR,"Failed to report event: %d. %ws, line %d\n",GetLastError(), THIS_FILE, __LINE__));
  716. }
  717. }
  718. //+-------------------------------------------------------------------------
  719. //
  720. // Function: KerbReportPkinit
  721. //
  722. // Synopsis: Reports errors generated by invalid client certificates
  723. //
  724. // Effects:
  725. //
  726. // Arguments:
  727. //
  728. // Requires:
  729. //
  730. // Returns:
  731. //
  732. // Notes:
  733. //
  734. //
  735. //--------------------------------------------------------------------------
  736. VOID
  737. KerbReportPkinitError(
  738. IN ULONG PolicyStatus,
  739. IN OPTIONAL PCCERT_CONTEXT KdcCert
  740. )
  741. {
  742. KERBERR KerbErr;
  743. LPWSTR Strings[MAX_STRINGS] = {NULL, NULL};
  744. WCHAR SubjectName[DNS_MAX_NAME_LENGTH + 1];
  745. DWORD NameMaxLength = DNS_MAX_NAME_LENGTH + 1;
  746. DWORD SubjectLength;
  747. NTSTATUS Status;
  748. ULONG StringCount = 0;
  749. if (KerbEventLogHandle == NULL)
  750. {
  751. Status = KerbInitEventLogHandle();
  752. if (Status != STATUS_SUCCESS)
  753. {
  754. return;
  755. }
  756. }
  757. if (ARGUMENT_PRESENT(KdcCert))
  758. {
  759. RtlZeroMemory(
  760. &SubjectName,
  761. NameMaxLength
  762. );
  763. SubjectLength = CertNameToStr(
  764. X509_ASN_ENCODING,
  765. &KdcCert->pCertInfo->Subject,
  766. CERT_NAME_DNS_TYPE,
  767. SubjectName,
  768. NameMaxLength
  769. );
  770. if (SubjectLength != 0)
  771. {
  772. Strings[0] = SubjectName;
  773. StringCount++;
  774. }
  775. }
  776. if (ERROR_SUCCESS != NetpEventlogWriteEx(
  777. KerbEventLogHandle,
  778. EVENTLOG_ERROR_TYPE,
  779. 0,
  780. (ARGUMENT_PRESENT(KdcCert) ?
  781. KERBEVT_BAD_KDC_CERTIFICATE :
  782. KERBEVT_BAD_CLIENT_CERTIFICATE),
  783. StringCount,
  784. sizeof(ULONG),
  785. Strings,
  786. &PolicyStatus
  787. ))
  788. {
  789. D_DebugLog((DEB_ERROR,"Failed to report event: %d. %ws, line %d\n",GetLastError(), THIS_FILE, __LINE__));
  790. }
  791. }