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.

659 lines
16 KiB

  1. //+-------------------------------------------------------------------------
  2. // Microsoft Windows
  3. //
  4. // Copyright (C) Microsoft Corporation, 1995 - 1999
  5. //
  6. // File: dblog.cpp
  7. //
  8. // Contents: Database Log Event APIs
  9. //
  10. // Functions: I_DBLogCrypt32Event
  11. // I_DBLogAttach
  12. // I_DBLogDetach
  13. //
  14. // History: 11-Oct-00 philh created
  15. //--------------------------------------------------------------------------
  16. #include "global.hxx"
  17. #include <dbgdef.h>
  18. #ifdef ROOT_AUTO_UPDATE_DOGFOOD
  19. #ifdef STATIC
  20. #undef STATIC
  21. #endif
  22. #define STATIC
  23. #include "sql.h"
  24. #include "sqlext.h"
  25. #include "sqltypes.h"
  26. #include "odbcss.h"
  27. #define SQL_CALL_SUCCESS(status) (status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO)
  28. #if DBG || DEBUG
  29. #define DebugPrint(a) _DebugPrintW a
  30. void
  31. __cdecl
  32. _DebugPrintW(
  33. LPCWSTR szFormat,
  34. ...
  35. )
  36. {
  37. WCHAR szBuffer[512];
  38. va_list ap;
  39. va_start(ap, szFormat);
  40. vswprintf(szBuffer, szFormat, ap);
  41. OutputDebugStringW(szBuffer);
  42. }
  43. int debugLine = __LINE__;
  44. #define DEBUG_MARKER debugLine = __LINE__
  45. #else
  46. #define DebugPrint(a)
  47. #define DEBUG_MARKER
  48. #endif
  49. #define SHA1_HASH_LEN 20
  50. #define SHA1_HASH_NAME_LEN (2 * SHA1_HASH_LEN)
  51. typedef struct _DBLOG_EVENT_DATA {
  52. DWORD dwStatus;
  53. DWORD dwCPU64;
  54. TIMESTAMP_STRUCT TimeStamp;
  55. WCHAR wszOperation[16];
  56. WCHAR wszHash[SHA1_HASH_NAME_LEN + 1];
  57. WCHAR wszSubject[64];
  58. WCHAR wszBuildLab[64];
  59. WCHAR wszMachineName[32];
  60. } DBLOG_EVENT_DATA, *PDBLOG_EVENT_DATA;
  61. void
  62. I_DBLogAttach()
  63. {
  64. }
  65. void
  66. I_DBLogDetach()
  67. {
  68. }
  69. DWORD WINAPI I_DBLogCrypt32EventThreadProc(
  70. LPVOID lpThreadParameter
  71. )
  72. {
  73. PDBLOG_EVENT_DATA pEventData = (PDBLOG_EVENT_DATA) lpThreadParameter;
  74. SQLRETURN RetCode = SQL_SUCCESS;
  75. HSTMT hStmt = NULL;
  76. HENV hEnv = NULL, hDbc = NULL;
  77. __try {
  78. __try {
  79. RetCode = SQLAllocHandle(
  80. SQL_HANDLE_ENV,
  81. SQL_NULL_HANDLE,
  82. &hEnv
  83. );
  84. if(!SQL_CALL_SUCCESS(RetCode)) {
  85. DEBUG_MARKER;
  86. __leave;
  87. }
  88. RetCode = SQLSetEnvAttr(
  89. hEnv,
  90. SQL_ATTR_ODBC_VERSION,
  91. (SQLPOINTER) SQL_OV_ODBC3,
  92. SQL_IS_INTEGER
  93. );
  94. if(!SQL_CALL_SUCCESS(RetCode)) {
  95. DEBUG_MARKER;
  96. __leave;
  97. }
  98. RetCode = SQLAllocHandle(
  99. SQL_HANDLE_DBC,
  100. hEnv,
  101. &hDbc
  102. );
  103. if(!SQL_CALL_SUCCESS(RetCode)) {
  104. DEBUG_MARKER;
  105. __leave;
  106. }
  107. RetCode = SQLSetConnectAttr(
  108. hDbc,
  109. SQL_ATTR_LOGIN_TIMEOUT,
  110. (SQLPOINTER) 120,
  111. SQL_IS_UINTEGER
  112. );
  113. if(!SQL_CALL_SUCCESS(RetCode)) {
  114. DEBUG_MARKER;
  115. __leave;
  116. }
  117. RetCode = SQLSetConnectAttr(
  118. hDbc,
  119. SQL_COPT_SS_INTEGRATED_SECURITY,
  120. (SQLPOINTER) SQL_IS_OFF,
  121. SQL_IS_INTEGER
  122. );
  123. if(!SQL_CALL_SUCCESS(RetCode)) {
  124. DEBUG_MARKER;
  125. __leave;
  126. }
  127. {
  128. SQLWCHAR szConnect[1024];
  129. SQLSMALLINT cbConnect = 0;
  130. SQLWCHAR szInConnect[] = L"DRIVER=SQL Server;SERVER=kschutz-team2;UID=crypt32;PWD=crypt32;DATABASE=Crypt32";
  131. RetCode = SQLDriverConnectW(
  132. hDbc,
  133. NULL,
  134. szInConnect,
  135. SQL_NTS,
  136. szConnect,
  137. sizeof(szConnect) / sizeof(szConnect[0]),
  138. &cbConnect,
  139. SQL_DRIVER_NOPROMPT
  140. );
  141. if(!SQL_CALL_SUCCESS(RetCode)) {
  142. DEBUG_MARKER;
  143. __leave;
  144. }
  145. }
  146. RetCode = SQLAllocHandle(
  147. SQL_HANDLE_STMT,
  148. hDbc,
  149. &hStmt
  150. );
  151. if(!SQL_CALL_SUCCESS(RetCode)) {
  152. DEBUG_MARKER;
  153. __leave;
  154. }
  155. WCHAR szStatement[] =
  156. L"INSERT INTO AddRoot2 ("
  157. L"OPERATION,"
  158. L"STATUS,"
  159. L"TIMESTAMP,"
  160. L"HASH,"
  161. L"SUBJECT,"
  162. L"MACHINENAME,"
  163. L"BUILDLAB,"
  164. L"CPU64"
  165. L") VALUES (?,?,?,?,?,?,?,?)";
  166. RetCode = SQLPrepareW(
  167. hStmt,
  168. szStatement,
  169. SQL_NTS
  170. );
  171. if(!SQL_CALL_SUCCESS(RetCode)) {
  172. DEBUG_MARKER;
  173. __leave;
  174. }
  175. SQLUSMALLINT iParamNo = 1;
  176. //
  177. // OPERATION
  178. //
  179. SQLLEN cbOperation = SQL_NTS;
  180. SQLBindParameter(
  181. hStmt,
  182. iParamNo++,
  183. SQL_PARAM_INPUT,
  184. SQL_C_WCHAR,
  185. SQL_WCHAR,
  186. sizeof(pEventData->wszOperation) / sizeof(WCHAR),
  187. 0,
  188. pEventData->wszOperation,
  189. 0,
  190. &cbOperation
  191. );
  192. //
  193. // STATUS
  194. //
  195. SQLLEN cbStatus = 0;
  196. SQLBindParameter(
  197. hStmt,
  198. iParamNo++,
  199. SQL_PARAM_INPUT,
  200. SQL_C_LONG,
  201. SQL_INTEGER,
  202. 0,
  203. 0,
  204. &pEventData->dwStatus,
  205. 0,
  206. &cbStatus
  207. );
  208. //
  209. // TIMESTAMP
  210. //
  211. SQLLEN cbTimeStamp = 0;
  212. SQLBindParameter(
  213. hStmt,
  214. iParamNo++,
  215. SQL_PARAM_INPUT,
  216. SQL_C_TIMESTAMP,
  217. SQL_TIMESTAMP,
  218. 19,
  219. 0,
  220. &pEventData->TimeStamp,
  221. 0,
  222. &cbTimeStamp
  223. );
  224. //
  225. // HASH
  226. //
  227. SQLLEN cbHash = SQL_NTS;
  228. SQLBindParameter(
  229. hStmt,
  230. iParamNo++,
  231. SQL_PARAM_INPUT,
  232. SQL_C_WCHAR,
  233. SQL_WCHAR,
  234. sizeof(pEventData->wszHash) / sizeof(WCHAR),
  235. 0,
  236. pEventData->wszHash,
  237. 0,
  238. &cbHash
  239. );
  240. //
  241. // SUBJECT
  242. //
  243. SQLLEN cbSubject = SQL_NTS;
  244. SQLBindParameter(
  245. hStmt,
  246. iParamNo++,
  247. SQL_PARAM_INPUT,
  248. SQL_C_WCHAR,
  249. SQL_WCHAR,
  250. sizeof(pEventData->wszSubject) / sizeof(WCHAR),
  251. 0,
  252. pEventData->wszSubject,
  253. 0,
  254. &cbSubject
  255. );
  256. //
  257. // MACHINENAME
  258. //
  259. SQLLEN cbMachineName = SQL_NTS;
  260. SQLBindParameter(
  261. hStmt,
  262. iParamNo++,
  263. SQL_PARAM_INPUT,
  264. SQL_C_WCHAR,
  265. SQL_WCHAR,
  266. sizeof(pEventData->wszMachineName) / sizeof(WCHAR),
  267. 0,
  268. pEventData->wszMachineName,
  269. 0,
  270. &cbMachineName
  271. );
  272. //
  273. // BUILDLAB
  274. //
  275. SQLLEN cbBuildLab = SQL_NTS;
  276. SQLBindParameter(
  277. hStmt,
  278. iParamNo++,
  279. SQL_PARAM_INPUT,
  280. SQL_C_WCHAR,
  281. SQL_WCHAR,
  282. sizeof(pEventData->wszBuildLab) / sizeof(WCHAR),
  283. 0,
  284. pEventData->wszBuildLab,
  285. 0,
  286. &cbBuildLab
  287. );
  288. //
  289. // CPU64
  290. //
  291. SQLLEN cbCPU64 = 0;
  292. SQLBindParameter(
  293. hStmt,
  294. iParamNo++,
  295. SQL_PARAM_INPUT,
  296. SQL_C_TINYINT,
  297. SQL_TINYINT,
  298. 0,
  299. 0,
  300. &pEventData->dwCPU64,
  301. 0,
  302. &cbCPU64
  303. );
  304. RetCode = SQLExecute(hStmt);
  305. DEBUG_MARKER;
  306. }
  307. __finally {
  308. }
  309. if (!SQL_CALL_SUCCESS(RetCode)) {
  310. SDWORD swError;
  311. SQLWCHAR szErrorMsg[SQL_MAX_MESSAGE_LENGTH];
  312. SWORD swErrorMsg;
  313. SQLWCHAR szSQLState[50];
  314. SQLErrorW(
  315. hEnv,
  316. hDbc,
  317. hStmt,
  318. szSQLState,
  319. &swError,
  320. szErrorMsg,
  321. SQL_MAX_MESSAGE_LENGTH - 1,
  322. &swErrorMsg
  323. );
  324. DebugPrint(
  325. (L"I_DBLogCrypt32EventThreadProc: Error (%d) - %s (%s)\n",
  326. debugLine,
  327. szErrorMsg,
  328. szSQLState)
  329. );
  330. }
  331. if (hStmt) {
  332. SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
  333. }
  334. if (hDbc) {
  335. SQLDisconnect(hDbc);
  336. SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
  337. }
  338. if (hEnv) {
  339. SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
  340. }
  341. }
  342. __except(EXCEPTION_EXECUTE_HANDLER) {
  343. DebugPrint(
  344. (L"I_DBLogCrypt32EventThreadProc: Exception Error (%d)\n",
  345. GetExceptionCode())
  346. );
  347. RetCode = SQL_ERROR;
  348. }
  349. PkiFree(pEventData);
  350. DebugPrint(
  351. (L"I_DBLogCrypt32EventThreadProc %s\n",
  352. (SQL_CALL_SUCCESS(RetCode) ? L"succeeded" : L"failed"))
  353. );
  354. return 0;
  355. }
  356. void
  357. I_DBLogCrypt32Event(
  358. IN WORD wType,
  359. IN DWORD dwEventID,
  360. IN WORD wNumStrings,
  361. IN LPCWSTR *rgpwszStrings
  362. )
  363. {
  364. PDBLOG_EVENT_DATA pEventData = NULL;
  365. HANDLE hThread = NULL;
  366. if (NULL == (pEventData = (PDBLOG_EVENT_DATA) PkiZeroAlloc(
  367. sizeof(DBLOG_EVENT_DATA))))
  368. goto OutOfMemory;
  369. switch (dwEventID) {
  370. case MSG_ROOT_AUTO_UPDATE_INFORMATIONAL:
  371. case MSG_UNTRUSTED_ROOT_INFORMATIONAL:
  372. case MSG_PARTIAL_CHAIN_INFORMATIONAL:
  373. switch (dwEventID) {
  374. case MSG_ROOT_AUTO_UPDATE_INFORMATIONAL:
  375. // Successful auto update of third-party root certificate::
  376. // Subject: <%1> Sha1 thumbprint: <%2>
  377. wcscpy(pEventData->wszOperation, L"AddCert");
  378. break;
  379. case MSG_UNTRUSTED_ROOT_INFORMATIONAL:
  380. // Untrusted root certificate:: Subject: <%1>
  381. // Sha1 thumbprint: <%2>
  382. wcscpy(pEventData->wszOperation, L"UntrustedRoot");
  383. break;
  384. case MSG_PARTIAL_CHAIN_INFORMATIONAL:
  385. // Partial Chain:: Issuer: <%1>
  386. // Subject Sha1 thumbprint: <%2>
  387. wcscpy(pEventData->wszOperation, L"PartialChain");
  388. break;
  389. }
  390. if (2 <= wNumStrings) {
  391. wcsncpy(pEventData->wszSubject, rgpwszStrings[0],
  392. sizeof(pEventData->wszSubject) / sizeof(WCHAR) - 1);
  393. wcsncpy(pEventData->wszHash, rgpwszStrings[1],
  394. sizeof(pEventData->wszHash) / sizeof(WCHAR) - 1);
  395. }
  396. break;
  397. case MSG_ROOT_LIST_AUTO_UPDATE_URL_RETRIEVAL_INFORMATIONAL:
  398. // Successful auto update of third-party root list cab from: <%1>
  399. case MSG_ROOT_LIST_AUTO_UPDATE_URL_RETRIEVAL_ERROR:
  400. // Failed auto update of third-party root list cab from: <%1>
  401. // with error: %2
  402. wcscpy(pEventData->wszOperation, L"FetchCab");
  403. break;
  404. case MSG_ROOT_LIST_AUTO_UPDATE_EXTRACT_ERROR:
  405. // Failed extract of third-party root list from auto update
  406. // cab at: <%1> with error: %2
  407. wcscpy(pEventData->wszOperation, L"ExtractCtl");
  408. break;
  409. case MSG_ROOT_CERT_AUTO_UPDATE_URL_RETRIEVAL_INFORMATIONAL:
  410. // Successful auto update of third-party root certificate from: <%1>
  411. case MSG_ROOT_CERT_AUTO_UPDATE_URL_RETRIEVAL_ERROR:
  412. // Failed auto update of third-party root certificate from: <%1>
  413. // with error: %2
  414. wcscpy(pEventData->wszOperation, L"FetchCert");
  415. // %1 contains
  416. // "RootDir" "/" "AsciiHexHash" ".cer"
  417. // for example,
  418. // "http://www.xyz.com/roots/216B2A29E62A00CE820146D8244141B92511B279.cer"
  419. {
  420. LPCWSTR pwszHash = rgpwszStrings[0];
  421. DWORD cchHash;
  422. cchHash = wcslen(pwszHash);
  423. if ((SHA1_HASH_NAME_LEN + 4) <= cchHash)
  424. memcpy(pEventData->wszHash,
  425. pwszHash + (cchHash - (SHA1_HASH_NAME_LEN + 4)),
  426. SHA1_HASH_NAME_LEN * sizeof(WCHAR));
  427. }
  428. break;
  429. case MSG_CRYPT32_EVENT_LOG_THRESHOLD_WARNING:
  430. // Reached crypt32 threshold of %1 events and will suspend
  431. // logging for %2 minutes
  432. wcscpy(pEventData->wszOperation, L"EventOverflow");
  433. break;
  434. case MSG_ROOT_SEQUENCE_NUMBER_AUTO_UPDATE_URL_RETRIEVAL_INFORMATIONAL:
  435. // Successful auto update of third-party root list sequence
  436. // number from: <%1>
  437. case MSG_ROOT_SEQUENCE_NUMBER_AUTO_UPDATE_URL_RETRIEVAL_ERROR:
  438. // Failed auto update of third-party root list sequence number
  439. // from: <%1> with error: %2
  440. wcscpy(pEventData->wszOperation, L"FetchSeq");
  441. break;
  442. default:
  443. goto SkipDbLogCrypt32Event;
  444. }
  445. if (MSG_CRYPT32_EVENT_LOG_THRESHOLD_WARNING == dwEventID)
  446. pEventData->dwStatus = (DWORD) ERROR_BUFFER_OVERFLOW;
  447. else if (EVENTLOG_ERROR_TYPE == wType && 2 <= wNumStrings)
  448. // The second string should contain the error code string
  449. pEventData->dwStatus = (DWORD) wcstoul(rgpwszStrings[1], NULL, 0);
  450. {
  451. SYSTEMTIME SystemTime;
  452. GetLocalTime(&SystemTime);
  453. pEventData->TimeStamp.day = SystemTime.wDay;
  454. pEventData->TimeStamp.month = SystemTime.wMonth;
  455. pEventData->TimeStamp.year = SystemTime.wYear;
  456. pEventData->TimeStamp.hour = SystemTime.wHour;
  457. pEventData->TimeStamp.minute = SystemTime.wMinute;
  458. pEventData->TimeStamp.second = SystemTime.wSecond;
  459. // pEventData->TimeStamp.fraction = 0;
  460. }
  461. {
  462. WCHAR wszMachineName[MAX_PATH] = L"";
  463. DWORD cchMachineName = sizeof(wszMachineName) / sizeof(WCHAR);
  464. // intentionally ignore any failures
  465. GetComputerNameExW(
  466. ComputerNameDnsHostname,
  467. wszMachineName,
  468. &cchMachineName
  469. );
  470. wcsncpy(pEventData->wszMachineName, wszMachineName,
  471. sizeof(pEventData->wszMachineName) / sizeof(WCHAR) - 1);
  472. }
  473. {
  474. HKEY hKey;
  475. WCHAR wszBuildLab[MAX_PATH];
  476. DWORD dwStatus;
  477. wcscpy(wszBuildLab, L"<BuildLab Unknown>");
  478. dwStatus = RegOpenKeyExW(
  479. HKEY_LOCAL_MACHINE,
  480. L"Software\\Microsoft\\Windows NT\\CurrentVersion",
  481. 0,
  482. KEY_READ,
  483. &hKey
  484. );
  485. if (dwStatus == ERROR_SUCCESS) {
  486. DWORD dwType = REG_SZ;
  487. DWORD cbBuildLab = sizeof(wszBuildLab);
  488. dwStatus = RegQueryValueExW(
  489. hKey,
  490. L"BuildLab",
  491. 0,
  492. &dwType,
  493. (LPBYTE) wszBuildLab,
  494. &cbBuildLab
  495. );
  496. if (dwStatus != ERROR_SUCCESS) {
  497. dwType = REG_SZ;
  498. cbBuildLab = sizeof(wszBuildLab);
  499. dwStatus = RegQueryValueExW(
  500. hKey,
  501. L"CurrentBuildNumber",
  502. 0,
  503. &dwType,
  504. (LPBYTE) wszBuildLab,
  505. &cbBuildLab
  506. );
  507. }
  508. RegCloseKey(hKey);
  509. }
  510. wcsncpy(pEventData->wszBuildLab, wszBuildLab,
  511. sizeof(pEventData->wszBuildLab) / sizeof(WCHAR) - 1);
  512. }
  513. #if defined(M_IA64) || defined(IA64) || defined(_IA64_)
  514. pEventData->dwCPU64 = 1;
  515. #endif
  516. // Create the thread to do the logging to the database
  517. if (NULL == (hThread = CreateThread(
  518. NULL, // lpThreadAttributes
  519. 0, // dwStackSize
  520. I_DBLogCrypt32EventThreadProc,
  521. pEventData,
  522. 0, // dwCreationFlags
  523. NULL // pdwThreadId
  524. )))
  525. goto CreateThreadError;
  526. CloseHandle(hThread);
  527. CommonReturn:
  528. return;
  529. ErrorReturn:
  530. PkiFree(pEventData);
  531. goto CommonReturn;
  532. TRACE_ERROR(OutOfMemory)
  533. TRACE_ERROR(SkipDbLogCrypt32Event)
  534. TRACE_ERROR(CreateThreadError)
  535. }
  536. #else
  537. void
  538. I_DBLogAttach()
  539. {
  540. }
  541. void
  542. I_DBLogDetach()
  543. {
  544. }
  545. void
  546. I_DBLogCrypt32Event(
  547. IN WORD wType,
  548. IN DWORD dwEventID,
  549. IN WORD wNumStrings,
  550. IN LPCWSTR *rgpwszStrings
  551. )
  552. {
  553. }
  554. #endif