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.

877 lines
20 KiB

  1. #ifdef SMARTCARD_DOGFOOD
  2. #include "msgina.h"
  3. #include <stdio.h>
  4. #include <Wincrypt.h>
  5. #include "tchar.h"
  6. #include "authmon.h"
  7. #include "sql.h"
  8. #include "sqlext.h"
  9. #include "sqltypes.h"
  10. #include "odbcss.h"
  11. #define SQL_CALL_SUCCESS(status) (status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO)
  12. #if DBG || DEBUG
  13. #define DebugPrint(a) _DebugPrint a
  14. void
  15. __cdecl
  16. _DebugPrint(
  17. LPCTSTR szFormat,
  18. ...
  19. )
  20. {
  21. TCHAR szBuffer[512];
  22. va_list ap;
  23. szBuffer[0] = 0;
  24. va_start(ap, szFormat);
  25. _vsntprintf(szBuffer, ARRAYSIZE(szBuffer), szFormat, ap);
  26. szBuffer[ ARRAYSIZE(szBuffer) - 1 ] = 0;
  27. OutputDebugString(szBuffer);
  28. }
  29. int debugLine = __LINE__;
  30. #define DEBUG_MARKER debugLine = __LINE__
  31. #else
  32. #define DebugPrint(a)
  33. #define DEBUG_MARKER
  34. #endif
  35. typedef struct _AUTH_DATA {
  36. HANDLE hHeap;
  37. BOOL bConsole;
  38. WCHAR szUser[64];
  39. AUTH_OPERATION AuthOperation;
  40. WCHAR szReader[32];
  41. WCHAR szCard[48];
  42. ULONG StopWatch;
  43. NTSTATUS Status;
  44. WCHAR szDomain[32];
  45. WCHAR szDC[32];
  46. BYTE pCertBlob[4096];
  47. ULONG uCertBlob;
  48. SQLWCHAR szSQLServer[64];
  49. SQLWCHAR szSQLUser[64];
  50. SQLWCHAR szSQLPassword[64];
  51. SQLWCHAR szSQLDatabase[64];
  52. } AUTH_DATA, *PAUTH_DATA;
  53. DWORD
  54. WINAPI
  55. WriteLogonData(
  56. PAUTH_DATA pAuthData
  57. )
  58. {
  59. SQLRETURN RetCode = SQL_SUCCESS;
  60. HSTMT hStmt = NULL;
  61. HENV hEnv = NULL, hDbc = NULL;
  62. BOOL bConnected = FALSE;
  63. SQLSMALLINT cbConnect = 0;
  64. static SQLWCHAR szConnect[256], szInConnect[256];
  65. __try {
  66. RetCode = SQLAllocHandle(
  67. SQL_HANDLE_ENV,
  68. SQL_NULL_HANDLE,
  69. &hEnv
  70. );
  71. if(!SQL_CALL_SUCCESS(RetCode)) {
  72. DEBUG_MARKER;
  73. __leave;
  74. }
  75. RetCode = SQLSetEnvAttr(
  76. hEnv,
  77. SQL_ATTR_ODBC_VERSION,
  78. (SQLPOINTER) SQL_OV_ODBC3,
  79. SQL_IS_INTEGER
  80. );
  81. if(!SQL_CALL_SUCCESS(RetCode)) {
  82. DEBUG_MARKER;
  83. __leave;
  84. }
  85. RetCode = SQLAllocHandle(
  86. SQL_HANDLE_DBC,
  87. hEnv,
  88. &hDbc
  89. );
  90. if(!SQL_CALL_SUCCESS(RetCode)) {
  91. DEBUG_MARKER;
  92. __leave;
  93. }
  94. RetCode = SQLSetConnectAttr(
  95. hDbc,
  96. SQL_ATTR_LOGIN_TIMEOUT,
  97. (SQLPOINTER) 120,
  98. SQL_IS_UINTEGER
  99. );
  100. if(!SQL_CALL_SUCCESS(RetCode)) {
  101. DEBUG_MARKER;
  102. __leave;
  103. }
  104. RetCode = SQLSetConnectAttr(
  105. hDbc,
  106. SQL_COPT_SS_INTEGRATED_SECURITY,
  107. (SQLPOINTER) SQL_IS_OFF,
  108. SQL_IS_INTEGER
  109. );
  110. if(!SQL_CALL_SUCCESS(RetCode)) {
  111. DEBUG_MARKER;
  112. __leave;
  113. }
  114. _snwprintf(
  115. szInConnect,
  116. sizeof(szInConnect) / sizeof(SQLWCHAR),
  117. (const wchar_t *) L"DRIVER=SQL Server;Server=%s;UID=%s;PWD=%s;DATABASE=%s",
  118. pAuthData->szSQLServer,
  119. pAuthData->szSQLUser,
  120. pAuthData->szSQLPassword,
  121. pAuthData->szSQLDatabase
  122. );
  123. szInConnect[ sizeof(szInConnect) / sizeof(SQLWCHAR) - 1 ] = 0;
  124. RetCode = SQLDriverConnect(
  125. hDbc,
  126. NULL,
  127. szInConnect,
  128. SQL_NTS,
  129. szConnect,
  130. sizeof(szConnect) / sizeof(szConnect[0]),
  131. &cbConnect,
  132. SQL_DRIVER_NOPROMPT
  133. );
  134. if(!SQL_CALL_SUCCESS(RetCode)) {
  135. DEBUG_MARKER;
  136. __leave;
  137. }
  138. bConnected = TRUE;
  139. RetCode = SQLAllocHandle(
  140. SQL_HANDLE_STMT,
  141. hDbc,
  142. &hStmt
  143. );
  144. if(!SQL_CALL_SUCCESS(RetCode)) {
  145. DEBUG_MARKER;
  146. __leave;
  147. }
  148. static WCHAR szStatement[] =
  149. L"INSERT INTO AuthMonitor ("
  150. L"BUILDLAB,"
  151. L"CARD,"
  152. L"CERTISSUER,"
  153. L"DC,"
  154. L"DOMAIN,"
  155. L"MACHINENAME,"
  156. L"READER,"
  157. L"SESSION,"
  158. L"STATUS,"
  159. L"STOPWATCH,"
  160. L"TIMESTAMP,"
  161. L"UNLOCK,"
  162. L"USERNAME"
  163. L") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)";
  164. RetCode = SQLPrepare(
  165. hStmt,
  166. szStatement,
  167. SQL_NTS
  168. );
  169. if(!SQL_CALL_SUCCESS(RetCode)) {
  170. DEBUG_MARKER;
  171. __leave;
  172. }
  173. SQLUSMALLINT iParamNo = 1;
  174. //
  175. // BUILDLAB
  176. //
  177. HKEY hKey;
  178. DWORD dwStatus = RegOpenKeyEx(
  179. HKEY_LOCAL_MACHINE,
  180. L"Software\\Microsoft\\Windows NT\\CurrentVersion",
  181. 0,
  182. KEY_READ,
  183. &hKey
  184. );
  185. static WCHAR szBuild[MAX_PATH];
  186. DWORD cbBuild = sizeof(szBuild);
  187. wcscpy(szBuild, L"");
  188. if (dwStatus == ERROR_SUCCESS) {
  189. DWORD dwType = REG_SZ;
  190. dwStatus = RegQueryValueEx(
  191. hKey,
  192. L"BuildLab",
  193. 0,
  194. &dwType,
  195. (LPBYTE) szBuild,
  196. &cbBuild
  197. );
  198. if (dwStatus != ERROR_SUCCESS) {
  199. cbBuild = sizeof(szBuild);
  200. dwStatus = RegQueryValueEx(
  201. hKey,
  202. L"CurrentBuildNumber",
  203. 0,
  204. &dwType,
  205. (LPBYTE) szBuild,
  206. &cbBuild
  207. );
  208. }
  209. RegCloseKey(hKey);
  210. }
  211. SQLLEN cbBuildLab = SQL_NTS;
  212. SQLBindParameter(
  213. hStmt,
  214. iParamNo++,
  215. SQL_PARAM_INPUT,
  216. SQL_C_WCHAR,
  217. SQL_WCHAR,
  218. 64,
  219. 0,
  220. szBuild,
  221. 0,
  222. &cbBuildLab
  223. );
  224. //
  225. // CARD
  226. //
  227. SQLLEN cbCard = SQL_NTS;
  228. SQLBindParameter(
  229. hStmt,
  230. iParamNo++,
  231. SQL_PARAM_INPUT,
  232. SQL_C_WCHAR,
  233. SQL_WCHAR,
  234. 48,
  235. 0,
  236. pAuthData->szCard,
  237. 0,
  238. &cbCard
  239. );
  240. //
  241. // CERTISSUER
  242. //
  243. PCERT_CONTEXT pCert = (PCERT_CONTEXT) CertCreateCertificateContext(
  244. X509_ASN_ENCODING,
  245. pAuthData->pCertBlob,
  246. pAuthData->uCertBlob
  247. );
  248. WCHAR szIssuer[64] = L"";
  249. if (pCert) {
  250. // intentionally ignore errors
  251. CertGetNameString(
  252. pCert,
  253. CERT_NAME_FRIENDLY_DISPLAY_TYPE,
  254. CERT_NAME_ISSUER_FLAG,
  255. NULL,
  256. szIssuer,
  257. sizeof(szIssuer) / sizeof(szIssuer[0])
  258. );
  259. CertFreeCertificateContext(pCert);
  260. }
  261. SQLLEN cbIssuer = SQL_NTS;
  262. SQLBindParameter(
  263. hStmt,
  264. iParamNo++,
  265. SQL_PARAM_INPUT,
  266. SQL_C_WCHAR,
  267. SQL_WCHAR,
  268. 64,
  269. 0,
  270. szIssuer,
  271. 0,
  272. &cbIssuer
  273. );
  274. //
  275. // DC
  276. //
  277. PDOMAIN_CONTROLLER_INFO pDCInfo = NULL;
  278. dwStatus = DsGetDcName(
  279. NULL,
  280. pAuthData->szDomain,
  281. NULL,
  282. NULL,
  283. DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME,
  284. &pDCInfo
  285. );
  286. static WCHAR szDC[MAX_PATH];
  287. wcscpy(szDC, L"");
  288. static WCHAR szDomain[ARRAYSIZE(pAuthData->szDomain)];
  289. wcscpy(szDomain, L"");
  290. if (dwStatus == ERROR_SUCCESS) {
  291. lstrcpyn(szDC, pDCInfo->DomainControllerName, ARRAYSIZE(szDC));
  292. lstrcpyn(szDomain, pDCInfo->DomainName, ARRAYSIZE(szDomain));
  293. NetApiBufferFree(pDCInfo);
  294. }
  295. SQLLEN cbDC = SQL_NTS;
  296. SQLBindParameter(
  297. hStmt,
  298. iParamNo++,
  299. SQL_PARAM_INPUT,
  300. SQL_C_WCHAR,
  301. SQL_WCHAR,
  302. 32,
  303. 0,
  304. szDC,
  305. 0,
  306. &cbDC
  307. );
  308. //
  309. // DOMAIN
  310. //
  311. if (pAuthData->szDomain[0] == L'\0') {
  312. PWCHAR pszPos;
  313. if (pszPos = wcschr(pAuthData->szUser, L'@')) {
  314. lstrcpyn(szDomain, pszPos + 1, ARRAYSIZE(szDomain));
  315. if (pszPos = wcschr(szDomain, L'.')) {
  316. *pszPos = L'\0';
  317. }
  318. }
  319. } else {
  320. wcscpy(szDomain, pAuthData->szDomain);
  321. }
  322. SQLLEN cbDomain = SQL_NTS;
  323. SQLBindParameter(
  324. hStmt,
  325. iParamNo++,
  326. SQL_PARAM_INPUT,
  327. SQL_C_WCHAR,
  328. SQL_WCHAR,
  329. 32,
  330. 0,
  331. szDomain,
  332. 0,
  333. &cbDomain
  334. );
  335. //
  336. // MACHINENAME
  337. //
  338. static WCHAR szMachineName[MAX_PATH];
  339. wcscpy(szMachineName, L"");
  340. DWORD dwMachineName = sizeof(szMachineName)/sizeof(szMachineName[0]);
  341. // intentionally ignore any failures
  342. GetComputerNameEx(
  343. ComputerNameDnsHostname,
  344. szMachineName,
  345. &dwMachineName
  346. );
  347. SQLLEN cbMachineName = SQL_NTS;
  348. SQLBindParameter(
  349. hStmt,
  350. iParamNo++,
  351. SQL_PARAM_INPUT,
  352. SQL_C_WCHAR,
  353. SQL_WCHAR,
  354. 64,
  355. 0,
  356. szMachineName,
  357. 0,
  358. &cbMachineName
  359. );
  360. //
  361. // READER
  362. //
  363. SQLLEN cbReader = SQL_NTS;
  364. SQLBindParameter(
  365. hStmt,
  366. iParamNo++,
  367. SQL_PARAM_INPUT,
  368. SQL_C_WCHAR,
  369. SQL_WCHAR,
  370. 32,
  371. 0,
  372. pAuthData->szReader,
  373. 0,
  374. &cbReader
  375. );
  376. //
  377. // SESSION
  378. //
  379. SQLLEN cbSession = 0;
  380. BOOL bSession = !pAuthData->bConsole;
  381. SQLBindParameter(
  382. hStmt,
  383. iParamNo++,
  384. SQL_PARAM_INPUT,
  385. SQL_C_SHORT,
  386. SQL_SMALLINT,
  387. 0,
  388. 0,
  389. &bSession,
  390. 0,
  391. &cbSession
  392. );
  393. //
  394. // STATUS
  395. //
  396. SQLLEN cbStatus = 0;
  397. SQLBindParameter(
  398. hStmt,
  399. iParamNo++,
  400. SQL_PARAM_INPUT,
  401. SQL_C_LONG,
  402. SQL_INTEGER,
  403. 0,
  404. 0,
  405. &pAuthData->Status,
  406. 0,
  407. &cbStatus
  408. );
  409. //
  410. // STOPWATCH
  411. //
  412. SQLLEN cbStopWatch = 0;
  413. SQLBindParameter(
  414. hStmt,
  415. iParamNo++,
  416. SQL_PARAM_INPUT,
  417. SQL_C_ULONG,
  418. SQL_INTEGER,
  419. 0,
  420. 0,
  421. &pAuthData->StopWatch,
  422. 0,
  423. &cbStopWatch
  424. );
  425. //
  426. // TIMESTAMP
  427. //
  428. TIMESTAMP_STRUCT TimeStamp;
  429. SYSTEMTIME SystemTime;
  430. GetLocalTime(&SystemTime);
  431. TimeStamp.day = SystemTime.wDay;
  432. TimeStamp.month = SystemTime.wMonth;
  433. TimeStamp.year = SystemTime.wYear;
  434. TimeStamp.hour = SystemTime.wHour;
  435. TimeStamp.minute = SystemTime.wMinute;
  436. TimeStamp.second = SystemTime.wSecond;
  437. TimeStamp.fraction = 0;
  438. SQLLEN cbTimeStamp = 0;
  439. SQLBindParameter(
  440. hStmt,
  441. iParamNo++,
  442. SQL_PARAM_INPUT,
  443. SQL_C_TIMESTAMP,
  444. SQL_TIMESTAMP,
  445. 19,
  446. 0,
  447. &TimeStamp,
  448. 0,
  449. &cbTimeStamp
  450. );
  451. //
  452. // UNLOCK
  453. //
  454. SQLLEN cbAuthOperation = 0;
  455. SQLBindParameter(
  456. hStmt,
  457. iParamNo++,
  458. SQL_PARAM_INPUT,
  459. SQL_C_SHORT,
  460. SQL_SMALLINT,
  461. 0,
  462. 0,
  463. &pAuthData->AuthOperation,
  464. 0,
  465. &cbAuthOperation
  466. );
  467. //
  468. // USERNAME
  469. //
  470. static WCHAR szUser[ARRAYSIZE(pAuthData->szUser)];
  471. wcscpy(szUser, pAuthData->szUser);
  472. if (PWCHAR pszPos = wcschr(szUser, L'@')) {
  473. *pszPos = L'\0';
  474. }
  475. SQLLEN cbUserName = SQL_NTS;
  476. SQLBindParameter(
  477. hStmt,
  478. iParamNo++,
  479. SQL_PARAM_INPUT,
  480. SQL_C_WCHAR,
  481. SQL_WCHAR,
  482. 64,
  483. 0,
  484. szUser,
  485. 0,
  486. &cbUserName
  487. );
  488. RetCode = SQLExecute(hStmt);
  489. DEBUG_MARKER;
  490. }
  491. __finally {
  492. }
  493. if (!SQL_CALL_SUCCESS(RetCode)) {
  494. SDWORD swError;
  495. static SQLWCHAR szErrorMsg[SQL_MAX_MESSAGE_LENGTH];
  496. SWORD swErrorMsg;
  497. SQLWCHAR szSQLState[50];
  498. SQLError(
  499. hEnv,
  500. hDbc,
  501. hStmt,
  502. szSQLState,
  503. &swError,
  504. szErrorMsg,
  505. SQL_MAX_MESSAGE_LENGTH - 1,
  506. &swErrorMsg
  507. );
  508. DebugPrint(
  509. (L"AuthMonitor: Error WriteLogonData (%d) - %s (%s)\n [%s]",
  510. debugLine,
  511. szErrorMsg,
  512. szSQLState,
  513. szInConnect)
  514. );
  515. }
  516. if (hStmt) {
  517. SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
  518. hStmt = NULL;
  519. }
  520. if (hDbc) {
  521. if (bConnected) {
  522. SQLDisconnect(hDbc);
  523. bConnected = FALSE;
  524. }
  525. SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
  526. hDbc = NULL;
  527. }
  528. if (hEnv) {
  529. SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
  530. hEnv = NULL;
  531. }
  532. HeapFree(pAuthData->hHeap, 0, pAuthData);
  533. DebugPrint(
  534. (L"AuthMonitor: WriteLogonData %s\n",
  535. (SQL_CALL_SUCCESS(RetCode) ? L"succeeded" : L"failed"))
  536. );
  537. return 0;
  538. }
  539. EXTERN_C HANDLE AuthMonitor(
  540. AUTH_OPERATION AuthOper,
  541. BOOL Console,
  542. PUNICODE_STRING User,
  543. PUNICODE_STRING Domain,
  544. PWSTR Card,
  545. PWSTR Reader,
  546. PKERB_SMART_CARD_PROFILE Profile,
  547. DWORD Timer,
  548. NTSTATUS Status
  549. )
  550. {
  551. PAUTH_DATA pAuthData = NULL;
  552. HANDLE hHeap = NULL;
  553. HANDLE hThread = NULL;
  554. HKEY hKey = NULL;
  555. USHORT usLength;
  556. LONG lResult = RegOpenKeyEx(
  557. HKEY_LOCAL_MACHINE,
  558. TEXT("SOFTWARE\\Policies\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"),
  559. 0,
  560. KEY_READ,
  561. &hKey
  562. );
  563. if (lResult != ERROR_SUCCESS) {
  564. return NULL;
  565. }
  566. __try {
  567. DWORD dwSize, dwType, dwEnabled = 0;
  568. dwSize = sizeof(dwEnabled);
  569. lResult = RegQueryValueEx(
  570. hKey,
  571. TEXT("AuthMonEnabled"),
  572. 0,
  573. &dwType,
  574. (PBYTE) &dwEnabled,
  575. &dwSize
  576. );
  577. if (lResult != ERROR_SUCCESS || dwType != REG_DWORD || dwEnabled == 0) {
  578. DEBUG_MARKER;
  579. __leave;
  580. }
  581. hHeap = GetProcessHeap();
  582. if (hHeap == NULL) {
  583. DEBUG_MARKER;
  584. __leave;
  585. }
  586. pAuthData = (PAUTH_DATA) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(AUTH_DATA));
  587. if (pAuthData == NULL) {
  588. DEBUG_MARKER;
  589. __leave;
  590. }
  591. dwSize = sizeof(pAuthData->szSQLServer);
  592. lResult = RegQueryValueEx(
  593. hKey,
  594. TEXT("AuthMonServer"),
  595. 0,
  596. &dwType,
  597. (PBYTE) &pAuthData->szSQLServer,
  598. &dwSize
  599. );
  600. if (lResult != ERROR_SUCCESS || dwType != REG_SZ) {
  601. DEBUG_MARKER;
  602. __leave;
  603. }
  604. dwSize = sizeof(pAuthData->szSQLUser);
  605. lResult = RegQueryValueEx(
  606. hKey,
  607. TEXT("AuthMonUser"),
  608. 0,
  609. &dwType,
  610. (PBYTE) &pAuthData->szSQLUser,
  611. &dwSize
  612. );
  613. if (lResult != ERROR_SUCCESS || dwType != REG_SZ) {
  614. DEBUG_MARKER;
  615. __leave;
  616. }
  617. dwSize = sizeof(pAuthData->szSQLPassword);
  618. lResult = RegQueryValueEx(
  619. hKey,
  620. TEXT("AuthMonPassword"),
  621. 0,
  622. &dwType,
  623. (PBYTE) &pAuthData->szSQLPassword,
  624. &dwSize
  625. );
  626. if (lResult != ERROR_SUCCESS || dwType != REG_SZ) {
  627. DEBUG_MARKER;
  628. __leave;
  629. }
  630. dwSize = sizeof(pAuthData->szSQLDatabase);
  631. lResult = RegQueryValueEx(
  632. hKey,
  633. TEXT("AuthMonDatabase"),
  634. 0,
  635. &dwType,
  636. (PBYTE) &pAuthData->szSQLDatabase,
  637. &dwSize
  638. );
  639. if (lResult != ERROR_SUCCESS || dwType != REG_SZ) {
  640. DEBUG_MARKER;
  641. __leave;
  642. }
  643. pAuthData->hHeap = hHeap;
  644. pAuthData->AuthOperation = AuthOper;
  645. pAuthData->bConsole = Console;
  646. usLength = Domain->Length;
  647. if (usLength + 2 > sizeof(pAuthData->szDomain))
  648. {
  649. usLength = sizeof(pAuthData->szDomain) - 2;
  650. }
  651. memcpy(pAuthData->szDomain, Domain->Buffer, usLength);
  652. usLength = User->Length;
  653. if (usLength + 2 > sizeof(pAuthData->szUser))
  654. {
  655. usLength = sizeof(pAuthData->szUser) - 2;
  656. }
  657. memcpy(pAuthData->szUser, User->Buffer, usLength);
  658. if (Card) {
  659. lstrcpyn(pAuthData->szCard, Card, ARRAYSIZE(pAuthData->szCard));
  660. }
  661. if (Reader) {
  662. lstrcpyn(pAuthData->szReader, Reader, ARRAYSIZE(pAuthData->szReader));
  663. }
  664. if (Profile && Profile->CertificateData && (Profile->CertificateSize < sizeof(pAuthData->pCertBlob))) {
  665. memcpy(
  666. pAuthData->pCertBlob,
  667. Profile->CertificateData,
  668. Profile->CertificateSize
  669. );
  670. pAuthData->uCertBlob = Profile->CertificateSize;
  671. }
  672. pAuthData->StopWatch = Timer;
  673. pAuthData->Status = Status;
  674. hThread = CreateThread(
  675. NULL,
  676. 0,
  677. (LPTHREAD_START_ROUTINE) WriteLogonData,
  678. pAuthData,
  679. 0,
  680. NULL
  681. );
  682. DEBUG_MARKER;
  683. }
  684. __finally {
  685. if (hKey) {
  686. RegCloseKey(hKey);
  687. }
  688. if (hThread == NULL) {
  689. if (pAuthData) {
  690. HeapFree(hHeap, 0, pAuthData);
  691. }
  692. DebugPrint((L"AuthMonitor: Error line %d\n", debugLine));
  693. }
  694. #ifndef TEST
  695. else
  696. {
  697. CloseHandle(hThread);
  698. hThread = NULL;
  699. }
  700. #endif
  701. }
  702. return hThread;
  703. }
  704. #ifdef TEST
  705. _cdecl main()
  706. {
  707. UNICODE_STRING Domain, User;
  708. HANDLE hThread = NULL;
  709. RtlInitUnicodeString(
  710. &Domain,
  711. L""
  712. );
  713. RtlInitUnicodeString(
  714. &User,
  715. L"Klaus"
  716. );
  717. hThread = AuthMonitor(
  718. AuthOperLogon,
  719. 0,
  720. &User,
  721. &Domain,
  722. L"Gemplus",
  723. L"Utimaco",
  724. NULL,
  725. 10,
  726. 0
  727. );
  728. if (hThread) {
  729. WaitForSingleObjectEx(hThread, INFINITE, FALSE);
  730. }
  731. }
  732. #endif
  733. #endif