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.

3337 lines
88 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1996
  5. //
  6. // File: init.cpp
  7. //
  8. // Contents:
  9. // All hydra license server initialization code.
  10. //
  11. // History:
  12. // Feb. 4, 98 HueiWang Created
  13. // Note:
  14. //---------------------------------------------------------------------------
  15. #include "pch.cpp"
  16. #include "globals.h"
  17. #include "init.h"
  18. #include "misc.h"
  19. #include "tlscert.h"
  20. #include "pid.h"
  21. #include "upgdb.h"
  22. #include "lkplite.h"
  23. #include "gencert.h"
  24. //
  25. // file scope define
  26. //
  27. #define DEFAULT_CSP MS_DEF_PROV
  28. #define PROVIDER_TYPE PROV_RSA_FULL
  29. DWORD
  30. TLSStartupLSDB(
  31. IN BOOL bCheckDBStatus,
  32. IN DWORD dwMaxDbHandles,
  33. IN BOOL bStartEmptyIfError,
  34. IN LPTSTR pszChkPointDirPath,
  35. IN LPTSTR pszTempDirPath,
  36. IN LPTSTR pszLogDirPath,
  37. IN LPTSTR pszDbFile,
  38. IN LPTSTR pszUserName,
  39. IN LPTSTR pszPassword
  40. );
  41. DWORD
  42. TLSLoadRuntimeParameters();
  43. DWORD
  44. TLSStartLSDbWorkspaceEngine(
  45. BOOL,
  46. BOOL,
  47. BOOL,
  48. BOOL
  49. );
  50. ////////////////////////////////////////////////////////////////////////////
  51. //
  52. //
  53. // Global Variables
  54. //
  55. //
  56. ////////////////////////////////////////////////////////////////////////////
  57. static BOOL g_ValidDatabase=FALSE;
  58. #if DBG
  59. void
  60. EnsureExclusiveAccessToDbFile(
  61. LPTSTR szDatabaseFile
  62. )
  63. /*++
  64. --*/
  65. {
  66. HANDLE hFile = NULL;
  67. DWORD dwErrCode;
  68. hFile = CreateFile(
  69. szDatabaseFile,
  70. GENERIC_WRITE | GENERIC_READ,
  71. 0,
  72. NULL,
  73. OPEN_EXISTING,
  74. FILE_ATTRIBUTE_NORMAL,
  75. NULL
  76. );
  77. if( INVALID_HANDLE_VALUE == hFile )
  78. {
  79. dwErrCode = GetLastError();
  80. if( ERROR_FILE_NOT_FOUND != dwErrCode )
  81. {
  82. DBGPrintf(
  83. DBG_INFORMATION,
  84. DBG_FACILITY_INIT,
  85. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  86. _TEXT("EnsureExclusiveAccessToDbFile() failed with %d\n"),
  87. dwErrCode
  88. );
  89. }
  90. else if( ERROR_SHARING_VIOLATION == dwErrCode )
  91. {
  92. // special attention...
  93. TLSASSERT( FALSE );
  94. }
  95. else
  96. {
  97. TLSASSERT( FALSE );
  98. }
  99. }
  100. else
  101. {
  102. CloseHandle( hFile );
  103. }
  104. return;
  105. }
  106. #endif
  107. ////////////////////////////////////////////////////////////////////////////
  108. BOOL
  109. TLSGenerateLSDBBackupFileName(
  110. IN LPCTSTR pszPath,
  111. IN OUT LPTSTR pszTempFile
  112. )
  113. /*++
  114. --*/
  115. {
  116. DWORD dwTempRandom;
  117. if (lstrlen(pszPath)+13 > MAX_PATH)
  118. {
  119. // path too long
  120. return FALSE;
  121. }
  122. //
  123. // Generate a temporary file name.
  124. //
  125. dwTempRandom = GetTempFileName(
  126. pszPath,
  127. _TEXT("TLS"),
  128. 0,
  129. pszTempFile
  130. );
  131. if(dwTempRandom == 0)
  132. {
  133. //
  134. // GetTempFileName failed
  135. // Generate a backup file name based on current time,
  136. // possibility of collision is high
  137. //
  138. SYSTEMTIME LocalTime;
  139. if (lstrlen(pszPath)+25 > MAX_PATH)
  140. {
  141. // path too long
  142. return FALSE;
  143. }
  144. GetLocalTime(&LocalTime);
  145. wsprintf(
  146. pszTempFile,
  147. _TEXT("%s\\LSDBBackup.%02d%02d%02d%02d%02d%02d"),
  148. pszPath,
  149. LocalTime.wYear,
  150. LocalTime.wMonth,
  151. LocalTime.wDay,
  152. LocalTime.wHour,
  153. LocalTime.wMinute,
  154. LocalTime.wSecond
  155. );
  156. }
  157. return TRUE;
  158. }
  159. /////////////////////////////////////////////////////////////////////////////
  160. BOOL
  161. CanIssuePermLicense()
  162. {
  163. #ifndef ENFORCE_LICENSING
  164. return TRUE;
  165. #else
  166. if(g_bHasHydraCert == TRUE || (g_pbServerSPK != NULL && g_cbServerSPK != 0))
  167. {
  168. return TRUE;
  169. }
  170. return FALSE;
  171. #endif
  172. }
  173. /////////////////////////////////////////////////////////////////////////////
  174. void
  175. GetServiceLastShutdownTime(
  176. OUT FILETIME* ft
  177. )
  178. /*++
  179. --*/
  180. {
  181. *ft = g_ftLastShutdownTime;
  182. return;
  183. }
  184. //---------------------------------------------------------------------
  185. void
  186. SetServiceLastShutdownTime()
  187. {
  188. GetSystemTimeAsFileTime(&g_ftLastShutdownTime);
  189. }
  190. //---------------------------------------------------------------------
  191. void
  192. GetJobObjectDefaults(
  193. PDWORD pdwInterval,
  194. PDWORD pdwRetries,
  195. PDWORD pdwRestartTime
  196. )
  197. /*++
  198. --*/
  199. {
  200. *pdwInterval = g_dwTlsJobInterval;
  201. *pdwRetries = g_dwTlsJobRetryTimes;
  202. *pdwRestartTime = g_dwTlsJobRestartTime;
  203. }
  204. /////////////////////////////////////////////////////////////////////////////
  205. DWORD
  206. GetLicenseServerRole()
  207. {
  208. return g_SrvRole;
  209. }
  210. /////////////////////////////////////////////////////////////////////////////
  211. void
  212. FirstTimeSetTotalLicenses()
  213. {
  214. HKEY hBase=NULL;
  215. DWORD dwStatus;
  216. TCHAR szProductId[LSERVER_MAX_STRING_SIZE+1];
  217. DWORD cbProductId;
  218. DWORD index=0;
  219. FILETIME ft;
  220. DWORD dwKeyType;
  221. DWORD dwValue;
  222. DWORD cbValue;
  223. PTLSDbWorkSpace pDbWkSpace=NULL;
  224. //
  225. // verify key exist, if not, not first time startup
  226. dwStatus=RegOpenKeyEx(
  227. HKEY_LOCAL_MACHINE,
  228. FIRSTTIME_STARTUP_REGBASE,
  229. 0,
  230. KEY_ALL_ACCESS,
  231. &hBase
  232. );
  233. if(dwStatus != ERROR_SUCCESS)
  234. return;
  235. pDbWkSpace = AllocateWorkSpace( g_GeneralDbTimeout );
  236. if(pDbWkSpace == FALSE)
  237. {
  238. //
  239. // BUG BUG - should be initialization error but ignore for now
  240. //
  241. return;
  242. }
  243. do {
  244. cbProductId=sizeof(szProductId)/sizeof(szProductId[0]) - 1;
  245. cbValue = sizeof(dwValue);
  246. dwStatus=RegEnumValue(
  247. hBase,
  248. index++,
  249. szProductId,
  250. &cbProductId,
  251. NULL,
  252. &dwKeyType,
  253. (LPBYTE)&dwValue,
  254. &cbValue);
  255. if(dwStatus != ERROR_SUCCESS)
  256. break;
  257. if(dwKeyType == REG_DWORD && dwStatus == ERROR_SUCCESS)
  258. {
  259. DWORD total, numAvail;
  260. if(!_tcsicmp(szProductId, HYDRAPRODUCT_EXISTING_SKU))
  261. {
  262. total = dwValue;
  263. numAvail = 0;
  264. }
  265. else
  266. {
  267. total = dwValue;
  268. numAvail = dwValue;
  269. }
  270. //
  271. // TODO - find the key pack and set the available license
  272. //
  273. assert(FALSE);
  274. }
  275. } while(TRUE);
  276. RegCloseKey(hBase);
  277. RegDeleteKey(
  278. HKEY_LOCAL_MACHINE,
  279. FIRSTTIME_STARTUP_REGBASE
  280. );
  281. if(pDbWkSpace)
  282. {
  283. ReleaseWorkSpace(&pDbWkSpace);
  284. }
  285. return;
  286. }
  287. /////////////////////////////////////////////////////////////////////////////
  288. void
  289. ServerShutdown()
  290. {
  291. #if ENFORCE_LICENSING
  292. if(g_hCaStore)
  293. {
  294. CertCloseStore(
  295. g_hCaStore,
  296. CERT_CLOSE_STORE_FORCE_FLAG
  297. );
  298. }
  299. if(g_hCaRegKey)
  300. {
  301. RegCloseKey(g_hCaRegKey);
  302. }
  303. #endif
  304. if(g_SignKey)
  305. {
  306. CryptDestroyKey(g_SignKey);
  307. }
  308. if(g_ExchKey)
  309. {
  310. CryptDestroyKey(g_ExchKey);
  311. }
  312. TLServerLastRun lastRun;
  313. memset(&lastRun, 0, sizeof(TLServerLastRun));
  314. lastRun.dwVersion = LSERVER_LSA_LASTRUN_VER_CURRENT;
  315. lastRun.ftLastShutdownTime = g_ftLastShutdownTime;
  316. // if unclean shutdown or can't get next ID, set to 0
  317. if( g_ValidDatabase == FALSE ||
  318. TLSDBGetMaxKeyPackId(g_DbWorkSpace, (DWORD *)&g_NextKeyPackId) == FALSE ||
  319. TLSDBGetMaxLicenseId(g_DbWorkSpace, (DWORD *)&g_NextLicenseId) == FALSE )
  320. {
  321. g_NextKeyPackId = 0;
  322. g_NextLicenseId = 0;
  323. }
  324. lastRun.dwMaxKeyPackId = g_NextKeyPackId;
  325. lastRun.dwMaxLicenseId = g_NextLicenseId;
  326. StoreKey(
  327. LSERVER_LSA_LASTRUN,
  328. (PBYTE)&lastRun,
  329. sizeof(TLServerLastRun)
  330. );
  331. LSShutdownCertutilLib();
  332. if( g_SelfSignCertContext != NULL )
  333. {
  334. CertFreeCertificateContext(g_SelfSignCertContext);
  335. }
  336. if(g_LicenseCertContext)
  337. {
  338. CertFreeCertificateContext(g_LicenseCertContext);
  339. }
  340. TLSDestroyCryptContext(g_hCryptProv);
  341. g_hCryptProv=NULL;
  342. //
  343. // shutdown Work manager
  344. //
  345. TLSWorkManagerShutdown();
  346. #ifndef _NO_ODBC_JET
  347. if(g_DbWorkSpace != NULL)
  348. {
  349. ReleaseWorkSpace(&g_DbWorkSpace);
  350. }
  351. #endif
  352. CloseWorkSpacePool();
  353. FreeMemory(g_pbSecretKey);
  354. FreeMemory(g_pbSignatureEncodedCert);
  355. FreeMemory(g_pbExchangeEncodedCert);
  356. //FreeMemory(g_pbDomainSid);
  357. FreeMemory(g_pCertExtensions);
  358. FreeMemory(g_pszServerUniqueId);
  359. FreeMemory(g_pszServerPid);
  360. FreeMemory(g_pbServerSPK);
  361. if(g_szDomainGuid != NULL)
  362. {
  363. RpcStringFree(&g_szDomainGuid);
  364. }
  365. return;
  366. }
  367. /////////////////////////////////////////////////////////////////////////////
  368. DWORD
  369. StartServerInitThread(
  370. void* p
  371. )
  372. /*
  373. */
  374. {
  375. DWORD dwStatus = ERROR_SUCCESS;
  376. BOOL bDebug = (p) ? TRUE : FALSE;
  377. HKEY hKey = NULL;
  378. PTLSLSASERVERID pTlsLsaServerIds=NULL;
  379. DWORD cbTlsLsaServerIds=0;
  380. EXCEPTION_RECORD ExceptionCode;
  381. _set_se_translator( trans_se_func );
  382. __try {
  383. do {
  384. TLSInit();
  385. //
  386. // Load various run time parameters
  387. //
  388. dwStatus = TLSLoadRuntimeParameters();
  389. if(dwStatus != ERROR_SUCCESS)
  390. {
  391. break;
  392. }
  393. //
  394. // Retrive License Server's IDs
  395. //
  396. dwStatus = RetrieveKey(
  397. LSERVER_LSA_LSERVERID,
  398. (PBYTE *)&pTlsLsaServerIds,
  399. &cbTlsLsaServerIds
  400. );
  401. if(dwStatus != ERROR_SUCCESS)
  402. {
  403. //
  404. // First time, generate various license server ID
  405. //
  406. dwStatus = TLSGeneratePid(
  407. &g_pszServerPid,
  408. &g_cbServerPid,
  409. &g_pszServerUniqueId,
  410. &g_cbServerUniqueId
  411. );
  412. if(dwStatus != ERROR_SUCCESS)
  413. {
  414. TLSLogEvent(
  415. EVENTLOG_ERROR_TYPE,
  416. TLS_E_SERVICEINIT,
  417. TLS_E_GENERATE_IDS
  418. );
  419. break;
  420. }
  421. //
  422. // Store this into LSA
  423. //
  424. dwStatus = ServerIdsToLsaServerId(
  425. (PBYTE)g_pszServerUniqueId,
  426. g_cbServerUniqueId,
  427. (PBYTE)g_pszServerPid,
  428. g_cbServerPid,
  429. g_pbServerSPK,
  430. g_cbServerSPK,
  431. NULL,
  432. 0,
  433. &pTlsLsaServerIds,
  434. &cbTlsLsaServerIds
  435. );
  436. if(dwStatus != ERROR_SUCCESS)
  437. {
  438. TLSLogEvent(
  439. EVENTLOG_ERROR_TYPE,
  440. TLS_E_SERVICEINIT,
  441. dwStatus = TLS_E_STORE_IDS
  442. );
  443. break;
  444. }
  445. dwStatus = StoreKey(
  446. LSERVER_LSA_LSERVERID,
  447. (PBYTE)pTlsLsaServerIds,
  448. cbTlsLsaServerIds
  449. );
  450. if(dwStatus != ERROR_SUCCESS)
  451. {
  452. TLSLogEvent(
  453. EVENTLOG_ERROR_TYPE,
  454. TLS_E_SERVICEINIT,
  455. dwStatus = TLS_E_STORE_IDS
  456. );
  457. break;
  458. }
  459. }
  460. else
  461. {
  462. dwStatus = LsaServerIdToServerIds(
  463. pTlsLsaServerIds,
  464. cbTlsLsaServerIds,
  465. (PBYTE *)&g_pszServerUniqueId,
  466. &g_cbServerUniqueId,
  467. (PBYTE *)&g_pszServerPid,
  468. &g_cbServerPid,
  469. &g_pbServerSPK,
  470. &g_cbServerSPK,
  471. &g_pCertExtensions,
  472. &g_cbCertExtensions
  473. );
  474. if(dwStatus != ERROR_SUCCESS)
  475. {
  476. TLSLogEvent(
  477. EVENTLOG_ERROR_TYPE,
  478. TLS_E_SERVICEINIT,
  479. dwStatus = TLS_E_RETRIEVE_IDS
  480. );
  481. break;
  482. }
  483. if( g_pszServerUniqueId == NULL ||
  484. g_cbServerUniqueId == 0 ||
  485. g_pszServerPid == NULL ||
  486. g_cbServerPid == 0 )
  487. {
  488. TLSLogEvent(
  489. EVENTLOG_ERROR_TYPE,
  490. TLS_E_SERVICEINIT,
  491. dwStatus = TLS_E_INTERNAL
  492. );
  493. break;
  494. }
  495. }
  496. //
  497. // License Server common secret key for encoding/decoding
  498. // client HWID
  499. //
  500. LicenseGetSecretKey(&g_cbSecretKey, NULL);
  501. if((g_pbSecretKey = (PBYTE)AllocateMemory(g_cbSecretKey)) == NULL)
  502. {
  503. TLSLogEvent(
  504. EVENTLOG_ERROR_TYPE,
  505. TLS_E_SERVICEINIT,
  506. dwStatus = TLS_E_ALLOCATE_MEMORY
  507. );
  508. break;
  509. }
  510. if(LicenseGetSecretKey( &g_cbSecretKey, g_pbSecretKey ) != LICENSE_STATUS_OK)
  511. {
  512. TLSLogEvent(
  513. EVENTLOG_ERROR_TYPE,
  514. TLS_E_SERVICEINIT,
  515. dwStatus = TLS_E_RETRIEVE_KEY
  516. );
  517. break;
  518. }
  519. //--------------------------------------------------------------
  520. //
  521. // Check if our database file is in import directory
  522. //
  523. //--------------------------------------------------------------
  524. dwStatus = TLSStartLSDbWorkspaceEngine(
  525. bDebug == FALSE,
  526. FALSE, // check DB file on export directory
  527. FALSE, // check file time on DB file
  528. TRUE // log low license count warning.
  529. );
  530. if(dwStatus != ERROR_SUCCESS)
  531. {
  532. break;
  533. }
  534. dwStatus = ERROR_SUCCESS;
  535. g_ValidDatabase = TRUE;
  536. //
  537. // load all policy module, ignore error
  538. //
  539. ServiceLoadAllPolicyModule(
  540. HKEY_LOCAL_MACHINE,
  541. LSERVER_POLICY_REGBASE
  542. );
  543. //
  544. // Upgrade - make two copies of certificate
  545. //
  546. dwStatus = RegOpenKeyEx(
  547. HKEY_LOCAL_MACHINE,
  548. LSERVER_SERVER_CERTIFICATE_REGKEY,
  549. 0,
  550. KEY_ALL_ACCESS,
  551. &hKey
  552. );
  553. if(hKey != NULL)
  554. {
  555. RegCloseKey(hKey);
  556. }
  557. if(dwStatus != ERROR_SUCCESS)
  558. {
  559. dwStatus = ERROR_SUCCESS;
  560. // we are not register yet...
  561. break;
  562. }
  563. //
  564. // Verify first backup copy of certificate exists
  565. //
  566. hKey = NULL;
  567. dwStatus = RegOpenKeyEx(
  568. HKEY_LOCAL_MACHINE,
  569. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1,
  570. 0,
  571. KEY_ALL_ACCESS,
  572. &hKey
  573. );
  574. if(hKey != NULL)
  575. {
  576. RegCloseKey(hKey);
  577. }
  578. if(dwStatus == ERROR_FILE_NOT_FOUND)
  579. {
  580. dwStatus = TLSRestoreLicenseServerCertificate(
  581. LSERVER_SERVER_CERTIFICATE_REGKEY,
  582. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1
  583. );
  584. if(dwStatus != ERROR_SUCCESS)
  585. {
  586. TLSLogWarningEvent(TLS_W_BACKUPCERTIFICATE);
  587. TLSRegDeleteKey(
  588. HKEY_LOCAL_MACHINE,
  589. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1
  590. );
  591. }
  592. }
  593. //
  594. // Verify second backup copy of certificate exists
  595. //
  596. hKey = NULL;
  597. dwStatus = RegOpenKeyEx(
  598. HKEY_LOCAL_MACHINE,
  599. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2,
  600. 0,
  601. KEY_ALL_ACCESS,
  602. &hKey
  603. );
  604. if(hKey != NULL)
  605. {
  606. RegCloseKey(hKey);
  607. }
  608. if(dwStatus == ERROR_FILE_NOT_FOUND)
  609. {
  610. dwStatus = TLSRestoreLicenseServerCertificate(
  611. LSERVER_SERVER_CERTIFICATE_REGKEY,
  612. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2
  613. );
  614. if(dwStatus != ERROR_SUCCESS)
  615. {
  616. TLSLogWarningEvent(TLS_W_BACKUPCERTIFICATE);
  617. TLSRegDeleteKey(
  618. HKEY_LOCAL_MACHINE,
  619. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2
  620. );
  621. }
  622. }
  623. dwStatus = ERROR_SUCCESS;
  624. } while(FALSE);
  625. }
  626. __except(
  627. ExceptionCode = *(GetExceptionInformation())->ExceptionRecord,
  628. EXCEPTION_EXECUTE_HANDLER )
  629. {
  630. dwStatus = ExceptionCode.ExceptionCode;
  631. if(dwStatus == ERROR_OUTOFMEMORY)
  632. {
  633. TLSLogEvent(
  634. EVENTLOG_ERROR_TYPE,
  635. TLS_E_SERVICEINIT,
  636. dwStatus
  637. );
  638. }
  639. }
  640. if(pTlsLsaServerIds != NULL)
  641. {
  642. LocalFree(pTlsLsaServerIds);
  643. }
  644. ExitThread(dwStatus);
  645. return dwStatus;
  646. }
  647. /////////////////////////////////////////////////////////////////////////////
  648. HANDLE
  649. ServerInit(
  650. BOOL bDebug
  651. )
  652. {
  653. HANDLE hThread;
  654. DWORD dump;
  655. hThread=(HANDLE)CreateThread(
  656. NULL,
  657. 0,
  658. StartServerInitThread,
  659. LongToPtr(bDebug),
  660. 0,
  661. &dump
  662. );
  663. return hThread;
  664. }
  665. /////////////////////////////////////////////////////////////////////////////
  666. DWORD
  667. TLSRestoreLicenseServerCertificate(
  668. LPCTSTR pszSourceRegKey,
  669. LPCTSTR pszTargetRegKey
  670. )
  671. /*++
  672. --*/
  673. {
  674. DWORD dwStatus = ERROR_SUCCESS;
  675. // first delete the certificate key, ignore error
  676. TLSRegDeleteKey(
  677. HKEY_LOCAL_MACHINE,
  678. pszTargetRegKey
  679. );
  680. // copy from backup
  681. dwStatus = TLSTreeCopyRegKey(
  682. HKEY_LOCAL_MACHINE,
  683. pszSourceRegKey,
  684. HKEY_LOCAL_MACHINE,
  685. pszTargetRegKey
  686. );
  687. if(dwStatus == ERROR_FILE_NOT_FOUND)
  688. {
  689. // source registry key does not exist
  690. dwStatus = TLS_E_NO_CERTIFICATE;
  691. }
  692. return dwStatus;
  693. }
  694. ////////////////////////////////////////////////////////////////////////////////
  695. DWORD
  696. TLSLoadVerifyLicenseServerCertificates()
  697. /*++
  698. --*/
  699. {
  700. DWORD dwStatus;
  701. #if ENFORCE_LICENSING
  702. // load certificate from normal place
  703. dwStatus = TLSLoadCHEndosedCertificate(
  704. &g_cbSignatureEncodedCert,
  705. &g_pbSignatureEncodedCert,
  706. &g_cbExchangeEncodedCert,
  707. &g_pbExchangeEncodedCert
  708. );
  709. if(dwStatus == ERROR_SUCCESS)
  710. {
  711. if(g_hCaStore != NULL)
  712. {
  713. CertCloseStore(
  714. g_hCaStore,
  715. CERT_CLOSE_STORE_FORCE_FLAG
  716. );
  717. }
  718. if(g_hCaRegKey != NULL)
  719. {
  720. RegCloseKey(g_hCaRegKey);
  721. }
  722. //
  723. // license server is registered, verify certificate
  724. //
  725. g_hCaStore = CertOpenRegistryStore(
  726. HKEY_LOCAL_MACHINE,
  727. LSERVER_CERTIFICATE_REG_CA_SIGNATURE,
  728. g_hCryptProv,
  729. &g_hCaRegKey
  730. );
  731. if(g_hCaStore != NULL)
  732. {
  733. //
  734. // Go thru license server's certficiate to validate
  735. //
  736. dwStatus = TLSValidateServerCertficates(
  737. g_hCryptProv,
  738. g_hCaStore,
  739. g_pbSignatureEncodedCert,
  740. g_cbSignatureEncodedCert,
  741. g_pbExchangeEncodedCert,
  742. g_cbExchangeEncodedCert,
  743. &g_ftCertExpiredTime
  744. );
  745. if(dwStatus != ERROR_SUCCESS)
  746. {
  747. //
  748. // Invalid certificate in registry
  749. //
  750. dwStatus = TLS_E_INVALID_CERTIFICATE;
  751. }
  752. }
  753. else
  754. {
  755. //
  756. // Can't open registry key, startup as non-register
  757. // server.
  758. //
  759. //TLSLogEvent(
  760. // EVENTLOG_ERROR_TYPE,
  761. // TLS_E_SERVICEINIT,
  762. // TLS_E_OPEN_CERTSTORE,
  763. // dwStatus = GetLastError()
  764. // );
  765. dwStatus = TLS_E_NO_CERTIFICATE;
  766. }
  767. }
  768. if(dwStatus == ERROR_SUCCESS)
  769. {
  770. if(g_LicenseCertContext != NULL)
  771. {
  772. CertFreeCertificateContext(g_LicenseCertContext);
  773. }
  774. g_LicenseCertContext = CertCreateCertificateContext(
  775. X509_ASN_ENCODING,
  776. g_pbSignatureEncodedCert,
  777. g_cbSignatureEncodedCert
  778. );
  779. //if(!g_LicenseCertContext)
  780. //{
  781. // TLSLogEvent(
  782. // EVENTLOG_ERROR_TYPE,
  783. // TLS_E_SERVICEINIT,
  784. // TLS_E_CREATE_CERTCONTEXT,
  785. // GetLastError()
  786. // );
  787. //}
  788. }
  789. if(dwStatus != ERROR_SUCCESS)
  790. {
  791. g_bHasHydraCert = FALSE;
  792. }
  793. else
  794. {
  795. g_bHasHydraCert = TRUE;
  796. }
  797. #else
  798. dwStatus = TLS_E_NO_CERTIFICATE;
  799. #endif
  800. return dwStatus;
  801. }
  802. ///////////////////////////////////////////////////////////////////////
  803. BOOL
  804. TLSLoadServerCertificate()
  805. /*++
  806. Abstract:
  807. Load license server certificate
  808. --*/
  809. {
  810. BOOL bSuccess = FALSE;
  811. DWORD dwStatus;
  812. PBYTE pbSelfSignedCert = NULL;
  813. DWORD cbSelfSignedCert = 0;
  814. BOOL bSelfSignedCreated = FALSE;
  815. g_ftCertExpiredTime.dwLowDateTime = 0xFFFFFFFF;
  816. g_ftCertExpiredTime.dwHighDateTime = 0xFFFFFFFF;
  817. #if ENFORCE_LICENSING
  818. dwStatus = TLSLoadVerifyLicenseServerCertificates();
  819. //
  820. // failed to load server certificate, try backup copy,
  821. // if either one success, make sure we have all three copy up
  822. // to date.
  823. //
  824. if(dwStatus == TLS_E_INVALID_CERTIFICATE || dwStatus == TLS_E_NO_CERTIFICATE)
  825. {
  826. dwStatus = TLSRestoreLicenseServerCertificate(
  827. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1,
  828. LSERVER_SERVER_CERTIFICATE_REGKEY
  829. );
  830. if(dwStatus == ERROR_SUCCESS)
  831. {
  832. dwStatus = TLSLoadVerifyLicenseServerCertificates();
  833. if(dwStatus == ERROR_SUCCESS)
  834. {
  835. //
  836. // Log event indicate we are using backup certificate
  837. //
  838. LPCTSTR pString[1];
  839. pString[0]= g_szComputerName;
  840. TLSLogEventString(
  841. EVENTLOG_WARNING_TYPE,
  842. TLS_W_CORRUPTTRYBACKUPCERTIFICATE,
  843. 1,
  844. pString
  845. );
  846. //
  847. // make sure second copy is same as first copy.
  848. //
  849. TLSRestoreLicenseServerCertificate(
  850. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1,
  851. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2
  852. );
  853. }
  854. }
  855. }
  856. if(dwStatus == TLS_E_INVALID_CERTIFICATE || dwStatus == TLS_E_NO_CERTIFICATE)
  857. {
  858. dwStatus = TLSRestoreLicenseServerCertificate(
  859. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2,
  860. LSERVER_SERVER_CERTIFICATE_REGKEY
  861. );
  862. if(dwStatus == ERROR_SUCCESS)
  863. {
  864. dwStatus = TLSLoadVerifyLicenseServerCertificates();
  865. if(dwStatus == ERROR_SUCCESS)
  866. {
  867. //
  868. // Log event indicate we are using backup certificate
  869. //
  870. LPCTSTR pString[1];
  871. pString[0]= g_szComputerName;
  872. TLSLogEventString(
  873. EVENTLOG_WARNING_TYPE,
  874. TLS_W_CORRUPTTRYBACKUPCERTIFICATE,
  875. 1,
  876. pString
  877. );
  878. //
  879. // make sure our first copy is up to date
  880. //
  881. TLSRestoreLicenseServerCertificate(
  882. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2,
  883. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1
  884. );
  885. }
  886. }
  887. }
  888. //
  889. // Everything failed, log an event state that license server
  890. // will startup in un-registered mode
  891. //
  892. if(dwStatus == TLS_E_INVALID_CERTIFICATE)
  893. {
  894. LPCTSTR pString[1];
  895. pString[0] = g_szComputerName;
  896. TLSLogEventString(
  897. EVENTLOG_WARNING_TYPE,
  898. TLS_W_STARTUPCORRUPTEDCERT,
  899. 1,
  900. pString
  901. );
  902. }
  903. else if(CanIssuePermLicense() == FALSE)
  904. {
  905. // we are not registered yet
  906. LPCTSTR pString[1];
  907. pString[0] = g_szComputerName;
  908. TLSLogEventString(
  909. EVENTLOG_WARNING_TYPE,
  910. TLS_W_STARTUPNOCERT,
  911. 1,
  912. pString
  913. );
  914. }
  915. if( dwStatus != ERROR_SUCCESS )
  916. {
  917. //
  918. // if all failed, re-generate and start up as un-register
  919. // license server
  920. //
  921. bSuccess = FALSE;
  922. //
  923. // wipe out all certificates and re-generate everything,
  924. // don't re-generate key if we are not registered yet.
  925. //
  926. if(g_pbServerSPK == NULL || g_cbServerSPK == 0)
  927. {
  928. TLSReGenerateKeys(FALSE);
  929. }
  930. }
  931. else
  932. {
  933. bSuccess = TRUE;
  934. }
  935. #endif
  936. if(bSuccess == FALSE)
  937. {
  938. bSuccess = (TLSLoadSelfSignCertificates(
  939. g_hCryptProv,
  940. #if ENFORCE_LICENSING
  941. g_pbServerSPK,
  942. g_cbServerSPK,
  943. #else
  944. NULL,
  945. 0,
  946. #endif
  947. &g_cbSignatureEncodedCert,
  948. &g_pbSignatureEncodedCert,
  949. &g_cbExchangeEncodedCert,
  950. &g_pbExchangeEncodedCert
  951. ) == ERROR_SUCCESS);
  952. #ifndef ENFORCE_LICENSING
  953. //
  954. // non enforce license version
  955. g_bHasHydraCert = TRUE;
  956. #endif
  957. if(bSuccess == TRUE)
  958. {
  959. if(g_LicenseCertContext != NULL)
  960. {
  961. CertFreeCertificateContext(g_LicenseCertContext);
  962. }
  963. g_LicenseCertContext = CertCreateCertificateContext(
  964. X509_ASN_ENCODING,
  965. g_pbSignatureEncodedCert,
  966. g_cbSignatureEncodedCert
  967. );
  968. if(!g_LicenseCertContext)
  969. {
  970. bSuccess = FALSE;
  971. //
  972. // For self-signed cert, this is critical error, for
  973. // cert. in registry store, it must have been thru validation
  974. // so still critical error.
  975. //
  976. TLSLogEvent(
  977. EVENTLOG_ERROR_TYPE,
  978. TLS_E_SERVICEINIT,
  979. TLS_E_CREATE_CERTCONTEXT,
  980. GetLastError()
  981. );
  982. }
  983. else
  984. {
  985. // we have created a self-signed certificate.
  986. bSelfSignedCreated = TRUE;
  987. }
  988. }
  989. }
  990. //
  991. // Create a self-signed certificate for old client,
  992. //
  993. if( bSuccess == TRUE )
  994. {
  995. if( g_SelfSignCertContext != NULL )
  996. {
  997. CertFreeCertificateContext( g_SelfSignCertContext );
  998. g_SelfSignCertContext = NULL;
  999. }
  1000. if( bSelfSignedCreated == FALSE )
  1001. {
  1002. //
  1003. // Create a self-signed certificate just for old client
  1004. //
  1005. dwStatus = TLSCreateSelfSignCertificate(
  1006. g_hCryptProv,
  1007. AT_SIGNATURE,
  1008. #if ENFORCE_LICENSING
  1009. g_pbServerSPK,
  1010. g_cbServerSPK,
  1011. #else
  1012. NULL,
  1013. 0,
  1014. #endif
  1015. 0,
  1016. NULL,
  1017. &cbSelfSignedCert,
  1018. &pbSelfSignedCert
  1019. );
  1020. if( dwStatus == ERROR_SUCCESS )
  1021. {
  1022. g_SelfSignCertContext = CertCreateCertificateContext(
  1023. X509_ASN_ENCODING,
  1024. pbSelfSignedCert,
  1025. cbSelfSignedCert
  1026. );
  1027. if( g_SelfSignCertContext == NULL )
  1028. {
  1029. bSuccess = FALSE;
  1030. TLSLogEvent(
  1031. EVENTLOG_ERROR_TYPE,
  1032. TLS_E_SERVICEINIT,
  1033. TLS_E_CREATE_CERTCONTEXT,
  1034. GetLastError()
  1035. );
  1036. }
  1037. }
  1038. }
  1039. else
  1040. {
  1041. // we already have self-signed certificate created.
  1042. g_SelfSignCertContext = CertDuplicateCertificateContext( g_LicenseCertContext );
  1043. if( g_SelfSignCertContext == NULL )
  1044. {
  1045. TLSASSERT(FALSE);
  1046. //
  1047. // impossible, CertDuplicateCertificateContext() simply increase
  1048. // reference count
  1049. //
  1050. bSuccess = FALSE;
  1051. TLSLogEvent(
  1052. EVENTLOG_ERROR_TYPE,
  1053. TLS_E_SERVICEINIT,
  1054. TLS_E_CREATE_CERTCONTEXT,
  1055. GetLastError()
  1056. );
  1057. }
  1058. }
  1059. }
  1060. FreeMemory(pbSelfSignedCert);
  1061. return bSuccess;
  1062. }
  1063. //---------------------------------------------------------------------
  1064. DWORD
  1065. ServiceInitCrypto(
  1066. IN BOOL bCreateNewKeys,
  1067. IN LPCTSTR pszKeyContainer,
  1068. OUT HCRYPTPROV* phCryptProv,
  1069. OUT HCRYPTKEY* phSignKey,
  1070. OUT HCRYPTKEY* phExchKey
  1071. )
  1072. /*
  1073. */
  1074. {
  1075. DWORD dwStatus=ERROR_SUCCESS;
  1076. PBYTE pbSignKey=NULL;
  1077. DWORD cbSignKey=0;
  1078. PBYTE pbExchKey=NULL;
  1079. DWORD cbExchKey=0;
  1080. if(bCreateNewKeys == FALSE)
  1081. {
  1082. //
  1083. // Load key from LSA
  1084. //
  1085. dwStatus = TLSLoadSavedCryptKeyFromLsa(
  1086. &pbSignKey,
  1087. &cbSignKey,
  1088. &pbExchKey,
  1089. &cbExchKey
  1090. );
  1091. }
  1092. if(bCreateNewKeys == TRUE || dwStatus == ERROR_FILE_NOT_FOUND)
  1093. {
  1094. dwStatus = TLSCryptGenerateNewKeys(
  1095. &pbSignKey,
  1096. &cbSignKey,
  1097. &pbExchKey,
  1098. &cbExchKey
  1099. );
  1100. if(dwStatus == ERROR_SUCCESS)
  1101. {
  1102. // Save Key to LSA
  1103. dwStatus = TLSSaveCryptKeyToLsa(
  1104. pbSignKey,
  1105. cbSignKey,
  1106. pbExchKey,
  1107. cbExchKey
  1108. );
  1109. }
  1110. }
  1111. if(dwStatus == ERROR_SUCCESS)
  1112. {
  1113. //
  1114. // Initialize a clean crypto.
  1115. //
  1116. dwStatus = TLSInitCryptoProv(
  1117. pszKeyContainer,
  1118. pbSignKey,
  1119. cbSignKey,
  1120. pbExchKey,
  1121. cbExchKey,
  1122. phCryptProv,
  1123. phSignKey,
  1124. phExchKey
  1125. );
  1126. }
  1127. if(pbSignKey)
  1128. {
  1129. LocalFree(pbSignKey);
  1130. }
  1131. if(pbExchKey)
  1132. {
  1133. LocalFree(pbExchKey);
  1134. }
  1135. return dwStatus;
  1136. }
  1137. /////////////////////////////////////////////////////////////////////////////
  1138. DWORD
  1139. InitCryptoAndCertificate()
  1140. {
  1141. DWORD status=ERROR_SUCCESS;
  1142. DWORD dwServiceState;
  1143. DWORD dwCryptoState;
  1144. //
  1145. // Initialize single global Cryptographic Provider
  1146. //
  1147. status = ServiceInitCrypto(
  1148. FALSE,
  1149. NULL,
  1150. &g_hCryptProv,
  1151. &g_SignKey,
  1152. &g_ExchKey
  1153. );
  1154. if(status != ERROR_SUCCESS)
  1155. {
  1156. TLSLogEvent(
  1157. EVENTLOG_ERROR_TYPE,
  1158. TLS_E_SERVICEINIT,
  1159. TLS_E_INIT_CRYPTO,
  1160. status
  1161. );
  1162. status = TLS_E_SERVICE_STARTUP;
  1163. goto cleanup;
  1164. }
  1165. LSInitCertutilLib( NULL );
  1166. if(!TLSLoadServerCertificate())
  1167. {
  1168. status = TLS_E_SERVICE_STARTUP;
  1169. TLSLogErrorEvent(TLS_E_LOAD_CERTIFICATE);
  1170. goto cleanup;
  1171. }
  1172. //
  1173. if(!g_pbExchangeEncodedCert || !g_pbSignatureEncodedCert)
  1174. {
  1175. TLSLogErrorEvent(status = TLS_E_INTERNAL);
  1176. }
  1177. cleanup:
  1178. return status;
  1179. }
  1180. //////////////////////////////////////////////////////////////////
  1181. DWORD
  1182. TLSReGenKeysAndReloadServerCert(
  1183. BOOL bReGenKey
  1184. )
  1185. /*++
  1186. --*/
  1187. {
  1188. DWORD dwStatus;
  1189. dwStatus = TLSReGenerateKeys(bReGenKey);
  1190. //
  1191. // always try reload certificate since TLSReGenerateKeys()
  1192. // will wipe out our keys.
  1193. //
  1194. if(TLSLoadServerCertificate() == TRUE)
  1195. {
  1196. if(!g_pbExchangeEncodedCert || !g_pbSignatureEncodedCert)
  1197. {
  1198. TLSLogErrorEvent(dwStatus = TLS_E_INTERNAL);
  1199. }
  1200. }
  1201. else
  1202. {
  1203. TLSLogErrorEvent(dwStatus = TLS_E_LOAD_CERTIFICATE);
  1204. }
  1205. return dwStatus;
  1206. }
  1207. ////////////////////////////////////////////////////////////////////
  1208. DWORD
  1209. TLSReGenerateKeys(
  1210. BOOL bReGenKey
  1211. )
  1212. /*++
  1213. Always restore state back to clean install, bReGenKeyOnly
  1214. not supported.
  1215. --*/
  1216. {
  1217. HCRYPTPROV hCryptProv = NULL;
  1218. HCRYPTKEY hSignKey = NULL;
  1219. HCRYPTKEY hExchKey = NULL;
  1220. DWORD dwStatus = ERROR_SUCCESS;
  1221. PTLSLSASERVERID pTlsLsaServerIds=NULL;
  1222. DWORD cbTlsLsaServerIds=0;
  1223. //
  1224. // Create a new clean crypto.
  1225. //
  1226. dwStatus = ServiceInitCrypto(
  1227. bReGenKey,
  1228. NULL,
  1229. &hCryptProv,
  1230. &hSignKey,
  1231. &hExchKey
  1232. );
  1233. if(dwStatus != ERROR_SUCCESS)
  1234. {
  1235. return dwStatus;
  1236. }
  1237. //
  1238. // Cleanup our certificate registry.
  1239. //
  1240. TLSUninstallLsCertificate();
  1241. //
  1242. // Cleanup in-memory certificates, keys...
  1243. //
  1244. if(g_SignKey)
  1245. {
  1246. CryptDestroyKey(g_SignKey);
  1247. g_SignKey = NULL;
  1248. }
  1249. if(g_ExchKey)
  1250. {
  1251. CryptDestroyKey(g_ExchKey);
  1252. g_ExchKey = NULL;
  1253. }
  1254. if( g_SelfSignCertContext != NULL )
  1255. {
  1256. CertFreeCertificateContext( g_SelfSignCertContext );
  1257. g_SelfSignCertContext = NULL;
  1258. }
  1259. if( g_LicenseCertContext != NULL )
  1260. {
  1261. CertFreeCertificateContext(g_LicenseCertContext);
  1262. g_LicenseCertContext = NULL;
  1263. }
  1264. if(g_hCryptProv != NULL)
  1265. {
  1266. TLSDestroyCryptContext(g_hCryptProv);
  1267. }
  1268. g_hCryptProv=NULL;
  1269. FreeMemory(g_pbSignatureEncodedCert);
  1270. g_pbSignatureEncodedCert = NULL;
  1271. g_cbSignatureEncodedCert = 0;
  1272. FreeMemory(g_pbExchangeEncodedCert);
  1273. g_pbExchangeEncodedCert = NULL;
  1274. g_cbExchangeEncodedCert = 0;
  1275. //
  1276. // Always back to clean state.
  1277. //
  1278. FreeMemory(g_pCertExtensions);
  1279. g_pCertExtensions = NULL;
  1280. g_cbCertExtensions = 0;
  1281. FreeMemory(g_pbServerSPK);
  1282. g_pbServerSPK = NULL;
  1283. g_cbServerSPK = 0;
  1284. //
  1285. // Store this into LSA
  1286. //
  1287. dwStatus = ServerIdsToLsaServerId(
  1288. (PBYTE)g_pszServerUniqueId,
  1289. g_cbServerUniqueId,
  1290. (PBYTE)g_pszServerPid,
  1291. g_cbServerPid,
  1292. NULL,
  1293. 0,
  1294. NULL,
  1295. 0,
  1296. &pTlsLsaServerIds,
  1297. &cbTlsLsaServerIds
  1298. );
  1299. if(dwStatus != ERROR_SUCCESS)
  1300. {
  1301. assert(FALSE);
  1302. goto cleanup;
  1303. }
  1304. dwStatus = StoreKey(
  1305. LSERVER_LSA_LSERVERID,
  1306. (PBYTE)pTlsLsaServerIds,
  1307. cbTlsLsaServerIds
  1308. );
  1309. if(dwStatus != ERROR_SUCCESS)
  1310. {
  1311. assert(FALSE);
  1312. goto cleanup;
  1313. }
  1314. //
  1315. // Re-generate in-memory certificates...
  1316. //
  1317. g_hCryptProv = hCryptProv;
  1318. g_SignKey = hSignKey;
  1319. g_ExchKey = hExchKey;
  1320. cleanup:
  1321. FreeMemory(pTlsLsaServerIds);
  1322. return dwStatus;
  1323. }
  1324. //////////////////////////////////////////////////////////////////
  1325. DWORD
  1326. TLSReGenSelfSignCert(
  1327. IN HCRYPTPROV hCryptProv,
  1328. IN PBYTE pbSPK,
  1329. IN DWORD cbSPK,
  1330. IN DWORD dwNumExtensions,
  1331. IN PCERT_EXTENSION pCertExtensions
  1332. )
  1333. /*++
  1334. --*/
  1335. {
  1336. DWORD dwStatus;
  1337. PTLSLSASERVERID pbLsaServerId = NULL;
  1338. DWORD cbLsaServerId = 0;
  1339. PBYTE pbSignCert = NULL;
  1340. DWORD cbSignCert = 0;
  1341. PBYTE pbExchCert = NULL;
  1342. DWORD cbExchCert = 0;
  1343. DWORD dwVerifyResult;
  1344. PCCERT_CONTEXT hLicenseCertContext = NULL;
  1345. LPTSTR pszSPK = NULL;
  1346. if(hCryptProv == NULL || pbSPK == NULL || cbSPK == 0)
  1347. {
  1348. dwStatus = ERROR_INVALID_PARAMETER;
  1349. goto cleanup;
  1350. }
  1351. //
  1352. // Verify SPK, current SPK is base 24 encoded string
  1353. //
  1354. pszSPK = (LPTSTR)AllocateMemory(cbSPK + sizeof(TCHAR));
  1355. if(pszSPK == NULL)
  1356. {
  1357. dwStatus = TLS_E_ALLOCATE_MEMORY;
  1358. goto cleanup;
  1359. }
  1360. memcpy(
  1361. pszSPK,
  1362. pbSPK,
  1363. cbSPK
  1364. );
  1365. //
  1366. // Verify SPK
  1367. //
  1368. dwVerifyResult = LKPLITE_SPK_VALID;
  1369. dwStatus = LKPLiteVerifySPK(
  1370. g_pszServerPid,
  1371. pszSPK,
  1372. &dwVerifyResult
  1373. );
  1374. if(dwStatus != ERROR_SUCCESS || dwVerifyResult != LKPLITE_SPK_VALID)
  1375. {
  1376. if(dwVerifyResult == LKPLITE_SPK_INVALID)
  1377. {
  1378. dwStatus = TLS_E_INVALID_SPK;
  1379. }
  1380. else if(dwVerifyResult == LKPLITE_SPK_INVALID_SIGN)
  1381. {
  1382. dwStatus = TLS_E_SPK_INVALID_SIGN;
  1383. }
  1384. goto cleanup;
  1385. }
  1386. //
  1387. // Write SPK to LSA
  1388. //
  1389. dwStatus = ServerIdsToLsaServerId(
  1390. (PBYTE)g_pszServerUniqueId,
  1391. g_cbServerUniqueId,
  1392. (PBYTE)g_pszServerPid,
  1393. g_cbServerPid,
  1394. pbSPK,
  1395. cbSPK,
  1396. pCertExtensions,
  1397. dwNumExtensions,
  1398. &pbLsaServerId,
  1399. &cbLsaServerId
  1400. );
  1401. if(dwStatus != ERROR_SUCCESS)
  1402. {
  1403. goto cleanup;
  1404. }
  1405. //
  1406. // Save data to LSA
  1407. //
  1408. dwStatus = StoreKey(
  1409. LSERVER_LSA_LSERVERID,
  1410. (PBYTE) pbLsaServerId,
  1411. cbLsaServerId
  1412. );
  1413. if(dwStatus != ERROR_SUCCESS)
  1414. {
  1415. goto cleanup;
  1416. }
  1417. //
  1418. // Re-generate our certificatge
  1419. //
  1420. dwStatus = TLSCreateSelfSignCertificate(
  1421. hCryptProv,
  1422. AT_SIGNATURE,
  1423. pbSPK,
  1424. cbSPK,
  1425. dwNumExtensions,
  1426. pCertExtensions,
  1427. &cbSignCert,
  1428. &pbSignCert
  1429. );
  1430. if(dwStatus != ERROR_SUCCESS)
  1431. {
  1432. goto cleanup;
  1433. }
  1434. hLicenseCertContext = CertCreateCertificateContext(
  1435. X509_ASN_ENCODING,
  1436. pbSignCert,
  1437. cbSignCert
  1438. );
  1439. if( hLicenseCertContext == NULL )
  1440. {
  1441. dwStatus = GetLastError();
  1442. goto cleanup;
  1443. }
  1444. dwStatus = TLSCreateSelfSignCertificate(
  1445. hCryptProv,
  1446. AT_KEYEXCHANGE,
  1447. pbSPK,
  1448. cbSPK,
  1449. dwNumExtensions,
  1450. pCertExtensions,
  1451. &cbExchCert,
  1452. &pbExchCert
  1453. );
  1454. if(dwStatus != ERROR_SUCCESS)
  1455. {
  1456. goto cleanup;
  1457. }
  1458. //
  1459. // Certificate generated is Perm. self-signed certificate,
  1460. // don't store in registry.
  1461. //
  1462. //
  1463. // Make a copy of SPK
  1464. //
  1465. g_pbServerSPK = (PBYTE)AllocateMemory(cbSPK);
  1466. if(g_pbServerSPK == NULL)
  1467. {
  1468. dwStatus = GetLastError();
  1469. goto cleanup;
  1470. }
  1471. memcpy(
  1472. g_pbServerSPK,
  1473. pbSPK,
  1474. cbSPK
  1475. );
  1476. g_cbServerSPK = cbSPK;
  1477. if( g_SelfSignCertContext != NULL )
  1478. {
  1479. CertFreeCertificateContext(g_SelfSignCertContext);
  1480. }
  1481. g_SelfSignCertContext = CertDuplicateCertificateContext(hLicenseCertContext);
  1482. if( g_SelfSignCertContext == NULL )
  1483. {
  1484. TLSASSERT( g_SelfSignCertContext != NULL );
  1485. dwStatus = GetLastError();
  1486. goto cleanup;
  1487. }
  1488. //
  1489. // Everything is OK, switch to new certificate
  1490. //
  1491. FreeMemory(g_pbSignatureEncodedCert);
  1492. g_pbSignatureEncodedCert = pbSignCert;
  1493. g_cbSignatureEncodedCert = cbSignCert;
  1494. if(g_LicenseCertContext != NULL)
  1495. {
  1496. CertFreeCertificateContext(g_LicenseCertContext);
  1497. }
  1498. //
  1499. // use duplicate instead of direct assign
  1500. //
  1501. g_LicenseCertContext = CertDuplicateCertificateContext(hLicenseCertContext);
  1502. TLSASSERT(g_LicenseCertContext != NULL);
  1503. FreeMemory(g_pbExchangeEncodedCert);
  1504. g_pbExchangeEncodedCert = pbExchCert;
  1505. g_cbExchangeEncodedCert = cbExchCert;
  1506. pbSignCert = NULL;
  1507. pbExchCert = NULL;
  1508. //
  1509. // Mark we have Perm. self-signed cert.
  1510. //
  1511. g_bHasHydraCert = FALSE;
  1512. cleanup:
  1513. if( hLicenseCertContext != NULL )
  1514. {
  1515. CertFreeCertificateContext( hLicenseCertContext );
  1516. }
  1517. FreeMemory(pszSPK);
  1518. FreeMemory(pbLsaServerId);
  1519. FreeMemory(pbSignCert);
  1520. FreeMemory(pbExchCert);
  1521. return dwStatus;
  1522. }
  1523. //------------------------------------------------
  1524. void
  1525. CleanSetupLicenseServer()
  1526. /*++
  1527. --*/
  1528. {
  1529. DWORD dwStatus;
  1530. //
  1531. // Wipe out SPK in LSA
  1532. //
  1533. dwStatus = StoreKey(
  1534. LSERVER_LSA_LSERVERID,
  1535. (PBYTE) NULL,
  1536. 0
  1537. );
  1538. dwStatus = StoreKey(
  1539. LSERVER_LSA_LASTRUN,
  1540. (PBYTE) NULL,
  1541. 0
  1542. );
  1543. dwStatus = StoreKey(
  1544. LSERVER_LSA_PRIVATEKEY_EXCHANGE,
  1545. (PBYTE) NULL,
  1546. 0
  1547. );
  1548. dwStatus = StoreKey(
  1549. LSERVER_LSA_PRIVATEKEY_SIGNATURE,
  1550. (PBYTE) NULL,
  1551. 0
  1552. );
  1553. dwStatus = TLSUninstallLsCertificate();
  1554. return;
  1555. }
  1556. //-----------------------------------------------
  1557. //
  1558. //
  1559. DWORD
  1560. TLSStartupLSDB(
  1561. IN BOOL bCheckDBStatus,
  1562. IN DWORD dwMaxDbHandles,
  1563. IN BOOL bStartEmptyIfError,
  1564. IN BOOL bLogWarning,
  1565. IN LPTSTR pszChkPointDirPath,
  1566. IN LPTSTR pszTempDirPath,
  1567. IN LPTSTR pszLogDirPath,
  1568. IN LPTSTR pszDbFile,
  1569. IN LPTSTR pszUserName,
  1570. IN LPTSTR pszPassword
  1571. )
  1572. /*++
  1573. Abstract:
  1574. Initialize License Server's DB workspace handle list.
  1575. Parameters:
  1576. pszChkPointDirPath : ESE check point directory.
  1577. pszTempDirPath : ESE temp. directory.
  1578. pszLogDirPath : ESE log file directory.
  1579. pszDbPath : License Server database file path.
  1580. pszDbFile : License Server database file name (no path).
  1581. pszUserName : Database file user name.
  1582. pszPassword : Database file password.
  1583. Returns:
  1584. ERROR_SUCCESS or error code.
  1585. --*/
  1586. {
  1587. BOOL bSuccess = TRUE;
  1588. DWORD status = ERROR_SUCCESS;
  1589. BOOL bEmptyDatabase = FALSE;
  1590. BOOL bRemoveAvailableLicense = FALSE;
  1591. if( __TlsDbWorkSpace::g_JbInstance.IsValid() == FALSE )
  1592. {
  1593. //
  1594. // Initialize Jet Instance
  1595. //
  1596. bSuccess = TLSJbInstanceInit(
  1597. __TlsDbWorkSpace::g_JbInstance,
  1598. pszChkPointDirPath,
  1599. pszTempDirPath,
  1600. pszLogDirPath
  1601. );
  1602. if(bSuccess == FALSE)
  1603. {
  1604. status = GetLastError();
  1605. TLSASSERT(FALSE);
  1606. goto cleanup;
  1607. }
  1608. }
  1609. //
  1610. // Upgrade the database
  1611. //
  1612. status = TLSUpgradeDatabase(
  1613. __TlsDbWorkSpace::g_JbInstance,
  1614. pszDbFile,
  1615. pszUserName,
  1616. pszPassword
  1617. );
  1618. if( status == TLS_E_BETADATABSE ||
  1619. status == TLS_E_INCOMPATIBLEDATABSE ||
  1620. (TLS_ERROR(status) == TRUE && bStartEmptyIfError == TRUE) )
  1621. {
  1622. if(status == TLS_E_BETADATABSE)
  1623. {
  1624. CleanSetupLicenseServer();
  1625. }
  1626. //
  1627. // bad database, try to save a copy of it and
  1628. // restart from scratch
  1629. //
  1630. TLSLogInfoEvent(status);
  1631. TCHAR szTmpFileName[2*MAX_PATH+1];
  1632. bSuccess = TLSGenerateLSDBBackupFileName(
  1633. pszTempDirPath,
  1634. szTmpFileName
  1635. );
  1636. if (bSuccess)
  1637. {
  1638. bSuccess = MoveFileEx(
  1639. pszDbFile,
  1640. szTmpFileName,
  1641. MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED
  1642. );
  1643. }
  1644. if(bSuccess == TRUE)
  1645. {
  1646. LPCTSTR pString[1];
  1647. pString[0] = szTmpFileName;
  1648. TLSLogEventString(
  1649. EVENTLOG_INFORMATION_TYPE,
  1650. TLS_I_RENAME_DBFILE,
  1651. sizeof(pString)/sizeof(pString[0]),
  1652. pString
  1653. );
  1654. status = TLSUpgradeDatabase(
  1655. __TlsDbWorkSpace::g_JbInstance,
  1656. pszDbFile,
  1657. pszUserName,
  1658. pszPassword
  1659. );
  1660. }
  1661. else
  1662. {
  1663. //
  1664. // Can't rename this file, log an error and exit.
  1665. //
  1666. LPCTSTR pString[1];
  1667. pString[0] = pszDbFile;
  1668. TLSLogEventString(
  1669. EVENTLOG_ERROR_TYPE,
  1670. TLS_E_RENAME_DBFILE,
  1671. sizeof(pString)/sizeof(pString[0]),
  1672. pString
  1673. );
  1674. status = TLS_E_RENAME_DBFILE;
  1675. }
  1676. }
  1677. if(TLS_ERROR(status) == TRUE)
  1678. {
  1679. goto cleanup;
  1680. }
  1681. if(status == TLS_I_CREATE_EMPTYDATABASE)
  1682. {
  1683. // we startup from scratch, ignore ID checking
  1684. bEmptyDatabase = TRUE;
  1685. }
  1686. else if(status == TLS_W_NOTOWNER_DATABASE)
  1687. {
  1688. #if ENFORCE_LICENSING
  1689. // not owner of database or database version mismatch, we need to kill all the
  1690. // available licenses
  1691. bRemoveAvailableLicense = TRUE;
  1692. #endif
  1693. }
  1694. status = ERROR_SUCCESS;
  1695. //
  1696. // Allocate one handle to verify database
  1697. //
  1698. bSuccess = InitializeWorkSpacePool(
  1699. 1,
  1700. pszDbFile,
  1701. pszUserName,
  1702. pszPassword,
  1703. pszChkPointDirPath,
  1704. pszTempDirPath,
  1705. pszLogDirPath,
  1706. TRUE
  1707. );
  1708. if(bSuccess == FALSE)
  1709. {
  1710. status = GetLastError();
  1711. TLSASSERT(FALSE);
  1712. goto cleanup;
  1713. }
  1714. if((g_DbWorkSpace = AllocateWorkSpace(g_GeneralDbTimeout)) == NULL)
  1715. {
  1716. TLSLogEvent(
  1717. EVENTLOG_ERROR_TYPE,
  1718. TLS_E_SERVICEINIT,
  1719. status = TLS_E_ALLOCATE_HANDLE
  1720. );
  1721. goto cleanup;
  1722. }
  1723. //
  1724. // Initialize next keypack id and license id
  1725. //
  1726. if(TLSDBGetMaxKeyPackId(g_DbWorkSpace, (DWORD *)&g_NextKeyPackId) == FALSE)
  1727. {
  1728. status=GetLastError();
  1729. if(IS_JB_ERROR(status))
  1730. {
  1731. LPTSTR pString = NULL;
  1732. TLSGetESEError(
  1733. GET_JB_ERROR_CODE(status),
  1734. &pString
  1735. );
  1736. TLSLogEvent(
  1737. EVENTLOG_ERROR_TYPE,
  1738. TLS_E_SERVICEINIT,
  1739. TLS_E_JB_BASE,
  1740. GET_JB_ERROR_CODE(status),
  1741. (pString != NULL) ? pString : _TEXT("")
  1742. );
  1743. if(pString != NULL)
  1744. {
  1745. LocalFree(pString);
  1746. }
  1747. }
  1748. else
  1749. {
  1750. TLSLogEvent(
  1751. EVENTLOG_ERROR_TYPE,
  1752. TLS_E_SERVICEINIT,
  1753. status
  1754. );
  1755. }
  1756. goto cleanup;
  1757. }
  1758. if(!TLSDBGetMaxLicenseId(g_DbWorkSpace, (DWORD *)&g_NextLicenseId))
  1759. {
  1760. status=GetLastError();
  1761. if(IS_JB_ERROR(status))
  1762. {
  1763. LPTSTR pString = NULL;
  1764. TLSGetESEError(
  1765. GET_JB_ERROR_CODE(status),
  1766. &pString
  1767. );
  1768. TLSLogEvent(
  1769. EVENTLOG_ERROR_TYPE,
  1770. TLS_E_SERVICEINIT,
  1771. TLS_E_JB_BASE,
  1772. GET_JB_ERROR_CODE(status),
  1773. (pString != NULL) ? pString : _TEXT("")
  1774. );
  1775. if(pString != NULL)
  1776. {
  1777. LocalFree(pString);
  1778. }
  1779. }
  1780. else
  1781. {
  1782. TLSLogEvent(
  1783. EVENTLOG_ERROR_TYPE,
  1784. TLS_E_SERVICEINIT,
  1785. status
  1786. );
  1787. }
  1788. goto cleanup;
  1789. }
  1790. DBGPrintf(
  1791. DBG_INFORMATION,
  1792. DBG_FACILITY_INIT,
  1793. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1794. _TEXT("Next KeyPack ID - %d, Next License ID - %d\n"),
  1795. g_NextKeyPackId,
  1796. g_NextLicenseId
  1797. );
  1798. //
  1799. // Verify database status with last run status
  1800. //
  1801. {
  1802. LPTLServerLastRun lpLastRun = NULL;
  1803. DWORD cbByte=0;
  1804. PBYTE pbByte=NULL;
  1805. status = RetrieveKey(
  1806. LSERVER_LSA_LASTRUN,
  1807. &pbByte,
  1808. &cbByte
  1809. );
  1810. lpLastRun = (LPTLServerLastRun)pbByte;
  1811. if( status == ERROR_SUCCESS && lpLastRun != NULL )
  1812. {
  1813. DBGPrintf(
  1814. DBG_INFORMATION,
  1815. DBG_FACILITY_INIT,
  1816. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1817. _TEXT("Last run status : Next KeyPack ID - %d, Next License ID - %d\n"),
  1818. lpLastRun->dwMaxKeyPackId,
  1819. lpLastRun->dwMaxLicenseId
  1820. );
  1821. //
  1822. // Verify no 'copy' database
  1823. //
  1824. if( bCheckDBStatus == TRUE &&
  1825. bEmptyDatabase == FALSE &&
  1826. bRemoveAvailableLicense == FALSE &&
  1827. lpLastRun->dwMaxKeyPackId != 0 &&
  1828. lpLastRun->dwMaxLicenseId != 0 )
  1829. {
  1830. // enforce version will remove all available licenses
  1831. #if ENFORCE_LICENSING
  1832. if( lpLastRun->dwMaxKeyPackId != g_NextKeyPackId ||
  1833. lpLastRun->dwMaxLicenseId != g_NextLicenseId)
  1834. {
  1835. TLSLogWarningEvent(TLS_W_INCONSISTENT_STATUS);
  1836. bRemoveAvailableLicense = TRUE;
  1837. }
  1838. #endif
  1839. }
  1840. else
  1841. {
  1842. g_ftLastShutdownTime = lpLastRun->ftLastShutdownTime;
  1843. }
  1844. }
  1845. if(pbByte)
  1846. {
  1847. LocalFree(pbByte);
  1848. }
  1849. //
  1850. // overwrite last run status to 0 so if we crash,
  1851. // check won't get kick it
  1852. //
  1853. TLServerLastRun LastRun;
  1854. memset(&LastRun, 0, sizeof(LastRun));
  1855. LastRun.ftLastShutdownTime = g_ftLastShutdownTime;
  1856. StoreKey(
  1857. LSERVER_LSA_LASTRUN,
  1858. (PBYTE)&LastRun,
  1859. sizeof(TLServerLastRun)
  1860. );
  1861. }
  1862. g_NextKeyPackId++;
  1863. g_NextLicenseId++;
  1864. //
  1865. // remove available licenses
  1866. if(bRemoveAvailableLicense == TRUE)
  1867. {
  1868. status = TLSRemoveLicensesFromInvalidDatabase(
  1869. g_DbWorkSpace
  1870. );
  1871. if(status != ERROR_SUCCESS)
  1872. {
  1873. goto cleanup;
  1874. }
  1875. }
  1876. //
  1877. // Insert a keypack for Terminal Service Certificate.
  1878. //
  1879. status = TLSAddTermServCertificatePack(g_DbWorkSpace, bLogWarning);
  1880. if(status != ERROR_SUCCESS && status != TLS_E_DUPLICATE_RECORD)
  1881. {
  1882. TLSLogEvent(
  1883. EVENTLOG_ERROR_TYPE,
  1884. TLS_E_SERVICEINIT,
  1885. status = TLS_E_UPGRADE_DATABASE
  1886. );
  1887. goto cleanup;
  1888. }
  1889. //
  1890. // Allocate rest of the workspace handle
  1891. //
  1892. bSuccess = InitializeWorkSpacePool(
  1893. dwMaxDbHandles,
  1894. pszDbFile,
  1895. pszUserName,
  1896. pszPassword,
  1897. NULL,
  1898. NULL,
  1899. NULL,
  1900. FALSE
  1901. );
  1902. //
  1903. if(bSuccess == FALSE && GetNumberOfWorkSpaceHandle() < DB_MIN_HANDLE_NEEDED)
  1904. {
  1905. status = GetLastError();
  1906. }
  1907. cleanup:
  1908. return status;
  1909. }
  1910. ///////////////////////////////////////////////////////////////
  1911. DWORD
  1912. TLSStartLSDbWorkspaceEngine(
  1913. BOOL bChkDbStatus,
  1914. BOOL bIgnoreRestoreFile,
  1915. BOOL bIgnoreFileTimeChk,
  1916. BOOL bLogWarning
  1917. )
  1918. /*++
  1919. bChkDbStatus : Match next LKP ID and License ID with LSA
  1920. bIgnoreRestoreFile : FALSE if try to open DB file under EXPORT, TRUE otherwise
  1921. bLogWarning : TRUE if log low license count warning, FALSE otherwise.
  1922. note, this parameter is ignore in enforce build.
  1923. --*/
  1924. {
  1925. TCHAR szDbRestoreFile[MAX_PATH+1];
  1926. WIN32_FIND_DATA RestoreFileAttr;
  1927. WIN32_FIND_DATA LsDbFileAttr;
  1928. BOOL bSuccess = TRUE;
  1929. DWORD dwStatus = ERROR_SUCCESS;
  1930. TCHAR szDbBackupFile[MAX_PATH+1];
  1931. TCHAR szDbRestoreTmpFile[MAX_PATH+1];
  1932. if(bIgnoreRestoreFile == TRUE)
  1933. {
  1934. DBGPrintf(
  1935. DBG_INFORMATION,
  1936. DBG_FACILITY_INIT,
  1937. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1938. _TEXT("Ignore restore file\n")
  1939. );
  1940. goto open_existing;
  1941. }
  1942. //----------------------------------------------------------
  1943. //
  1944. // Check database file in the export directory.
  1945. //
  1946. //----------------------------------------------------------
  1947. _tcscpy(szDbRestoreFile, g_szDatabaseDir);
  1948. _tcscat(szDbRestoreFile, TLSBACKUP_EXPORT_DIR);
  1949. _tcscat(szDbRestoreFile, _TEXT("\\"));
  1950. _tcscat(szDbRestoreFile, g_szDatabaseFname);
  1951. bSuccess = FileExists(
  1952. szDbRestoreFile,
  1953. &RestoreFileAttr
  1954. );
  1955. if(bSuccess == FALSE)
  1956. {
  1957. goto open_existing;
  1958. }
  1959. bSuccess = FileExists(
  1960. g_szDatabaseFile,
  1961. &LsDbFileAttr
  1962. );
  1963. if(bSuccess == FALSE)
  1964. {
  1965. DBGPrintf(
  1966. DBG_INFORMATION,
  1967. DBG_FACILITY_INIT,
  1968. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1969. _TEXT("No existing database file, use restored file...\n")
  1970. );
  1971. //
  1972. // Database file does not exist, move the restored file over and open it.
  1973. //
  1974. bSuccess = MoveFileEx(
  1975. szDbRestoreFile,
  1976. g_szDatabaseFile,
  1977. MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH
  1978. );
  1979. if(bSuccess == FALSE)
  1980. {
  1981. DBGPrintf(
  1982. DBG_INFORMATION,
  1983. DBG_FACILITY_INIT,
  1984. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1985. _TEXT("Failed to move restore to existing db file - %d\n"),
  1986. GetLastError()
  1987. );
  1988. // can't move restore file, don't use the restore file,
  1989. // startup with empty database
  1990. dwStatus = GetLastError();
  1991. LPCTSTR pString[1];
  1992. pString[0] = szDbRestoreFile;
  1993. TLSLogEventString(
  1994. EVENTLOG_WARNING_TYPE,
  1995. TLS_E_DBRESTORE_MOVEFILE,
  1996. 1,
  1997. pString
  1998. );
  1999. }
  2000. else
  2001. {
  2002. TLSLogInfoEvent(TLS_I_USE_DBRESTOREFILE);
  2003. }
  2004. #if DBG
  2005. EnsureExclusiveAccessToDbFile( g_szDatabaseFile );
  2006. #endif
  2007. goto open_existing;
  2008. }
  2009. //
  2010. // Compare file's last modification time, if existing database file is newer
  2011. // than restore one, log event and continue opening existing file
  2012. //
  2013. if( bIgnoreFileTimeChk == FALSE )
  2014. {
  2015. if(CompareFileTime(&(RestoreFileAttr.ftLastWriteTime), &(LsDbFileAttr.ftLastWriteTime)) <= 0 )
  2016. {
  2017. DBGPrintf(
  2018. DBG_INFORMATION,
  2019. DBG_FACILITY_INIT,
  2020. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2021. _TEXT("Restore file is too old...\n"),
  2022. GetLastError()
  2023. );
  2024. //TLSLogInfoEvent(TLS_I_DBRESTORE_OLD);
  2025. goto open_existing;
  2026. }
  2027. }
  2028. //
  2029. // make a backup copy of existing database file.
  2030. //
  2031. bSuccess = TLSGenerateLSDBBackupFileName(
  2032. g_szDatabaseDir,
  2033. szDbBackupFile
  2034. );
  2035. if (bSuccess)
  2036. {
  2037. DBGPrintf(
  2038. DBG_INFORMATION,
  2039. DBG_FACILITY_INIT,
  2040. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2041. _TEXT("Existing database file has been backup to %s\n"),
  2042. szDbBackupFile
  2043. );
  2044. bSuccess = MoveFileEx(
  2045. g_szDatabaseFile,
  2046. szDbBackupFile,
  2047. MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH
  2048. );
  2049. }
  2050. if(bSuccess == FALSE)
  2051. {
  2052. DBGPrintf(
  2053. DBG_INFORMATION,
  2054. DBG_FACILITY_INIT,
  2055. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2056. _TEXT("Failed to backup existing database file - %d\n"),
  2057. GetLastError()
  2058. );
  2059. //
  2060. // Can't save a copy of existing database file
  2061. // Log an error and continue to open using existing database
  2062. //
  2063. LPCTSTR pString[1];
  2064. pString[0] = g_szDatabaseFile;
  2065. TLSLogEventString(
  2066. EVENTLOG_WARNING_TYPE,
  2067. TLS_W_DBRESTORE_SAVEEXISTING,
  2068. 1,
  2069. pString
  2070. );
  2071. goto open_existing;
  2072. }
  2073. //
  2074. // Rename restore file and then try to open the restore file.
  2075. //
  2076. bSuccess = MoveFileEx(
  2077. szDbRestoreFile,
  2078. g_szDatabaseFile,
  2079. MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH
  2080. );
  2081. if(bSuccess == TRUE)
  2082. {
  2083. #if DBG
  2084. EnsureExclusiveAccessToDbFile( g_szDatabaseFile );
  2085. #endif
  2086. //
  2087. // Open the restore database file
  2088. //
  2089. dwStatus = TLSStartupLSDB(
  2090. bChkDbStatus,
  2091. g_dwMaxDbHandles,
  2092. FALSE,
  2093. bLogWarning,
  2094. g_szDatabaseDir,
  2095. g_szDatabaseDir,
  2096. g_szDatabaseDir,
  2097. g_szDatabaseFile,
  2098. g_szDbUser,
  2099. g_szDbPwd
  2100. );
  2101. if(dwStatus == ERROR_SUCCESS)
  2102. {
  2103. //
  2104. // Log event indicating we open the restore file, existing
  2105. // database file has been saved as ...
  2106. //
  2107. LPCTSTR pString[1];
  2108. pString[0] = szDbBackupFile;
  2109. TLSLogEventString(
  2110. EVENTLOG_INFORMATION_TYPE,
  2111. TLS_I_OPENRESTOREDBFILE,
  2112. 1,
  2113. pString
  2114. );
  2115. return dwStatus;
  2116. }
  2117. }
  2118. //
  2119. // Can't open the restore db file or MoveFileEx() failed
  2120. //
  2121. bSuccess = TLSGenerateLSDBBackupFileName(
  2122. g_szDatabaseDir,
  2123. szDbRestoreTmpFile
  2124. );
  2125. if (bSuccess)
  2126. {
  2127. DBGPrintf(
  2128. DBG_INFORMATION,
  2129. DBG_FACILITY_INIT,
  2130. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2131. _TEXT("Backup restore file to %s\n"),
  2132. szDbRestoreTmpFile
  2133. );
  2134. bSuccess = MoveFileEx(
  2135. g_szDatabaseFile,
  2136. szDbRestoreTmpFile,
  2137. MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH
  2138. );
  2139. }
  2140. if(bSuccess == FALSE)
  2141. {
  2142. // failed to backup restore db file, delete it
  2143. bSuccess = DeleteFile(g_szDatabaseFile);
  2144. TLSLogErrorEvent(TLS_E_RESTOREDBFILE_OPENFAIL);
  2145. }
  2146. else
  2147. {
  2148. LPCTSTR pString[1];
  2149. pString[0] = szDbRestoreTmpFile;
  2150. TLSLogEventString(
  2151. EVENTLOG_ERROR_TYPE,
  2152. TLS_E_RESTOREDBFILE_OPENFAIL_SAVED,
  2153. 1,
  2154. pString
  2155. );
  2156. }
  2157. DBGPrintf(
  2158. DBG_INFORMATION,
  2159. DBG_FACILITY_INIT,
  2160. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2161. _TEXT("Restore original database file %s to %s\n"),
  2162. szDbBackupFile,
  2163. g_szDatabaseFile
  2164. );
  2165. //
  2166. // Restore the existing database file
  2167. //
  2168. bSuccess = MoveFileEx(
  2169. szDbBackupFile,
  2170. g_szDatabaseFile,
  2171. MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH
  2172. );
  2173. if(bSuccess == FALSE)
  2174. {
  2175. DBGPrintf(
  2176. DBG_INFORMATION,
  2177. DBG_FACILITY_INIT,
  2178. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2179. _TEXT("failed to restore original DB file - %d\n"),
  2180. GetLastError()
  2181. );
  2182. TLSASSERT(FALSE);
  2183. // this is really bad, continue with empty database file.
  2184. }
  2185. #if DBG
  2186. EnsureExclusiveAccessToDbFile( g_szDatabaseFile );
  2187. #endif
  2188. open_existing:
  2189. return TLSStartupLSDB(
  2190. bChkDbStatus,
  2191. g_dwMaxDbHandles,
  2192. TRUE,
  2193. bLogWarning,
  2194. g_szDatabaseDir,
  2195. g_szDatabaseDir,
  2196. g_szDatabaseDir,
  2197. g_szDatabaseFile,
  2198. g_szDbUser,
  2199. g_szDbPwd
  2200. );
  2201. }
  2202. ///////////////////////////////////////////////////////////////
  2203. DWORD
  2204. TLSLoadRuntimeParameters()
  2205. /*++
  2206. --*/
  2207. {
  2208. HKEY hKey = NULL;
  2209. DWORD dwStatus = ERROR_SUCCESS;
  2210. DWORD dwKeyType;
  2211. TCHAR szDbPath[MAX_PATH+1];;
  2212. TCHAR szDbFileName[MAX_PATH+1];
  2213. DWORD dwBuffer;
  2214. DWORD cbByte = 0;
  2215. PBYTE pbByte = NULL;
  2216. //-------------------------------------------------------------------
  2217. //
  2218. // Open HKLM\system\currentcontrolset\sevices\termservlicensing\parameters
  2219. //
  2220. //-------------------------------------------------------------------
  2221. dwStatus =RegCreateKeyEx(
  2222. HKEY_LOCAL_MACHINE,
  2223. LSERVER_REGISTRY_BASE _TEXT(SZSERVICENAME) _TEXT("\\") LSERVER_PARAMETERS,
  2224. 0,
  2225. NULL,
  2226. REG_OPTION_NON_VOLATILE,
  2227. KEY_ALL_ACCESS,
  2228. NULL,
  2229. &hKey,
  2230. NULL
  2231. );
  2232. if(dwStatus != ERROR_SUCCESS)
  2233. {
  2234. TLSLogEvent(
  2235. EVENTLOG_ERROR_TYPE,
  2236. TLS_E_SERVICEINIT,
  2237. TLS_E_ACCESS_REGISTRY,
  2238. dwStatus
  2239. );
  2240. dwStatus = TLS_E_INIT_GENERAL;
  2241. goto cleanup;
  2242. }
  2243. //-------------------------------------------------------------------
  2244. //
  2245. // Get database file location and file name
  2246. //
  2247. //-------------------------------------------------------------------
  2248. dwBuffer = sizeof(szDbPath) / sizeof(szDbPath[0]);
  2249. dwStatus = RegQueryValueEx(
  2250. hKey,
  2251. LSERVER_PARAMETERS_DBPATH,
  2252. NULL,
  2253. NULL,
  2254. (LPBYTE)szDbPath,
  2255. &dwBuffer
  2256. );
  2257. if(dwStatus != ERROR_SUCCESS)
  2258. {
  2259. //
  2260. // need to startup so use default value,
  2261. //
  2262. _tcscpy(
  2263. szDbPath,
  2264. LSERVER_DEFAULT_DBPATH
  2265. );
  2266. }
  2267. //
  2268. // Get database file name
  2269. //
  2270. dwBuffer = sizeof(szDbFileName) / sizeof(szDbFileName[0]);
  2271. dwStatus = RegQueryValueEx(
  2272. hKey,
  2273. LSERVER_PARAMETERS_DBFILE,
  2274. NULL,
  2275. NULL,
  2276. (LPBYTE)szDbFileName,
  2277. &dwBuffer
  2278. );
  2279. if(dwStatus != ERROR_SUCCESS)
  2280. {
  2281. //
  2282. // Use default value.
  2283. //
  2284. _tcscpy(
  2285. szDbFileName,
  2286. LSERVER_DEFAULT_EDB
  2287. );
  2288. }
  2289. _tcscpy(g_szDatabaseFname, szDbFileName);
  2290. //
  2291. // Always expand DB Path.
  2292. //
  2293. dwStatus = ExpandEnvironmentStrings(
  2294. szDbPath,
  2295. g_szDatabaseDir,
  2296. sizeof(g_szDatabaseDir) / sizeof(g_szDatabaseDir[0])
  2297. );
  2298. if(dwStatus == 0)
  2299. {
  2300. // can't expand environment variable, error out.
  2301. TLSLogEvent(
  2302. EVENTLOG_ERROR_TYPE,
  2303. TLS_E_SERVICEINIT,
  2304. TLS_E_LOCALDATABASEFILE,
  2305. dwStatus = GetLastError()
  2306. );
  2307. goto cleanup;
  2308. }
  2309. if(g_szDatabaseDir[_tcslen(g_szDatabaseDir) - 1] != _TEXT('\\'))
  2310. {
  2311. // JetBlue needs this.
  2312. _tcscat(g_szDatabaseDir, _TEXT("\\"));
  2313. }
  2314. //
  2315. // Full path to database file
  2316. //
  2317. _tcscpy(g_szDatabaseFile, g_szDatabaseDir);
  2318. _tcscat(g_szDatabaseFile, szDbFileName);
  2319. //
  2320. // Database file user and password
  2321. //
  2322. dwBuffer = sizeof(g_szDbUser) / sizeof(g_szDbUser[0]);
  2323. dwStatus = RegQueryValueEx(
  2324. hKey,
  2325. LSERVER_PARAMETERS_USER,
  2326. NULL,
  2327. NULL,
  2328. (LPBYTE)g_szDbUser,
  2329. &dwBuffer
  2330. );
  2331. // password is rendomly generated
  2332. dwStatus = RetrieveKey(
  2333. LSERVER_LSA_PASSWORD_KEYNAME,
  2334. &pbByte,
  2335. &cbByte
  2336. );
  2337. // backward compatibilty
  2338. if(dwStatus != ERROR_SUCCESS)
  2339. {
  2340. //
  2341. // Load password from registry or default to 'default' password
  2342. //
  2343. dwBuffer = sizeof(g_szDbPwd) / sizeof(g_szDbPwd[0]);
  2344. dwStatus = RegQueryValueEx(
  2345. hKey,
  2346. LSERVER_PARAMETERS_PWD,
  2347. NULL,
  2348. NULL,
  2349. (LPBYTE)g_szDbPwd,
  2350. &dwBuffer
  2351. );
  2352. }
  2353. else
  2354. {
  2355. //
  2356. // save info into global variable
  2357. //
  2358. memset(g_szDbPwd, 0, sizeof(g_szDbPwd));
  2359. memcpy((PBYTE)g_szDbPwd, pbByte, min(cbByte, sizeof(g_szDbPwd)));
  2360. }
  2361. if(pbByte != NULL)
  2362. {
  2363. LocalFree(pbByte);
  2364. }
  2365. //--------------------------------------------------------------------
  2366. //
  2367. // Work Object Parameters
  2368. //
  2369. //--------------------------------------------------------------------
  2370. dwBuffer = sizeof(g_dwTlsJobInterval);
  2371. dwStatus = RegQueryValueEx(
  2372. hKey,
  2373. LSERVER_PARAMETERS_WORKINTERVAL,
  2374. NULL,
  2375. NULL,
  2376. (LPBYTE)&g_dwTlsJobInterval,
  2377. &dwBuffer
  2378. );
  2379. if(dwStatus != ERROR_SUCCESS)
  2380. {
  2381. g_dwTlsJobInterval = DEFAULT_JOB_INTERVAL;
  2382. }
  2383. dwBuffer = sizeof(g_dwTlsJobRetryTimes);
  2384. dwStatus = RegQueryValueEx(
  2385. hKey,
  2386. LSERVER_PARAMETERS_RETRYTIMES,
  2387. NULL,
  2388. NULL,
  2389. (LPBYTE)&g_dwTlsJobRetryTimes,
  2390. &dwBuffer
  2391. );
  2392. if(dwStatus != ERROR_SUCCESS)
  2393. {
  2394. g_dwTlsJobRetryTimes = DEFAULT_JOB_RETRYTIMES;
  2395. }
  2396. dwBuffer=sizeof(g_dwTlsJobRestartTime);
  2397. dwStatus = RegQueryValueEx(
  2398. hKey,
  2399. LSERVER_PARAMETERS_WORKRESTART,
  2400. NULL,
  2401. NULL,
  2402. (LPBYTE)&g_dwTlsJobRestartTime,
  2403. &dwBuffer
  2404. );
  2405. if(dwStatus != ERROR_SUCCESS)
  2406. {
  2407. g_dwTlsJobRestartTime = DEFAULT_JOB_INTERVAL;
  2408. }
  2409. //---------------------------------------------------
  2410. //
  2411. // load low license warning count
  2412. //
  2413. //---------------------------------------------------
  2414. dwBuffer = sizeof(g_LowLicenseCountWarning);
  2415. dwStatus = RegQueryValueEx(
  2416. hKey,
  2417. LSERVER_PARAMETERS_LOWLICENSEWARNING,
  2418. NULL,
  2419. &dwKeyType,
  2420. NULL,
  2421. &dwBuffer
  2422. );
  2423. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2424. {
  2425. dwStatus = RegQueryValueEx(
  2426. hKey,
  2427. LSERVER_PARAMETERS_LOWLICENSEWARNING,
  2428. NULL,
  2429. &dwKeyType,
  2430. (LPBYTE)&g_LowLicenseCountWarning,
  2431. &dwBuffer
  2432. );
  2433. }
  2434. //---------------------------------------------------
  2435. //
  2436. // Temp. license grace period
  2437. //
  2438. //---------------------------------------------------
  2439. dwBuffer = sizeof(g_GracePeriod);
  2440. dwStatus = RegQueryValueEx(
  2441. hKey,
  2442. LSERVER_PARAMETERS_GRACEPERIOD,
  2443. NULL,
  2444. &dwKeyType,
  2445. NULL,
  2446. &dwBuffer
  2447. );
  2448. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2449. {
  2450. dwStatus = RegQueryValueEx(
  2451. hKey,
  2452. LSERVER_PARAMETERS_GRACEPERIOD,
  2453. NULL,
  2454. &dwKeyType,
  2455. (LPBYTE)&g_GracePeriod,
  2456. &dwBuffer
  2457. );
  2458. }
  2459. if(g_GracePeriod > GRACE_PERIOD)
  2460. {
  2461. // grace period can be greated than this.
  2462. g_GracePeriod = GRACE_PERIOD;
  2463. }
  2464. //
  2465. // Are we allow to issue temp. license
  2466. //
  2467. dwBuffer = sizeof(g_IssueTemporayLicense);
  2468. dwStatus = RegQueryValueEx(
  2469. hKey,
  2470. LSERVER_PARAMETERS_ISSUETEMPLICENSE,
  2471. NULL,
  2472. &dwKeyType,
  2473. NULL,
  2474. &dwBuffer
  2475. );
  2476. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2477. {
  2478. dwStatus = RegQueryValueEx(
  2479. hKey,
  2480. LSERVER_PARAMETERS_ISSUETEMPLICENSE,
  2481. NULL,
  2482. &dwKeyType,
  2483. (LPBYTE)&g_IssueTemporayLicense,
  2484. &dwBuffer
  2485. );
  2486. }
  2487. //------------------------------------------------------
  2488. //
  2489. // Timeout value if can't allocate a DB handle
  2490. //
  2491. //------------------------------------------------------
  2492. //
  2493. // Timeout for allocating a write handle
  2494. //
  2495. dwBuffer = sizeof(g_GeneralDbTimeout);
  2496. dwStatus = RegQueryValueEx(
  2497. hKey,
  2498. LSERVER_PARAMETERS_DBTIMEOUT,
  2499. NULL,
  2500. &dwKeyType,
  2501. NULL,
  2502. &dwBuffer
  2503. );
  2504. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2505. {
  2506. dwStatus = RegQueryValueEx(
  2507. hKey,
  2508. LSERVER_PARAMETERS_DBTIMEOUT,
  2509. NULL,
  2510. &dwKeyType,
  2511. (LPBYTE)&g_GeneralDbTimeout,
  2512. &dwBuffer
  2513. );
  2514. }
  2515. //
  2516. // Timeout for read handle
  2517. //
  2518. dwBuffer = sizeof(g_EnumDbTimeout);
  2519. dwStatus = RegQueryValueEx(
  2520. hKey,
  2521. LSERVER_PARAMETERS_EDBTIMEOUT,
  2522. NULL,
  2523. &dwKeyType,
  2524. NULL,
  2525. &dwBuffer
  2526. );
  2527. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2528. {
  2529. dwStatus = RegQueryValueEx(
  2530. hKey,
  2531. LSERVER_PARAMETERS_EDBTIMEOUT,
  2532. NULL,
  2533. &dwKeyType,
  2534. (LPBYTE)&g_EnumDbTimeout,
  2535. &dwBuffer
  2536. );
  2537. }
  2538. //------------------------------------------------------
  2539. //
  2540. // Number of database handles
  2541. //
  2542. //------------------------------------------------------
  2543. dwBuffer = sizeof(g_dwMaxDbHandles);
  2544. dwStatus = RegQueryValueEx(
  2545. hKey,
  2546. LSERVER_PARAMETERS_MAXDBHANDLES,
  2547. NULL,
  2548. &dwKeyType,
  2549. NULL,
  2550. &dwBuffer
  2551. );
  2552. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2553. {
  2554. dwStatus = RegQueryValueEx(
  2555. hKey,
  2556. LSERVER_PARAMETERS_MAXDBHANDLES,
  2557. NULL,
  2558. &dwKeyType,
  2559. (LPBYTE)&g_dwMaxDbHandles,
  2560. &dwBuffer
  2561. );
  2562. if(g_dwMaxDbHandles > DB_MAX_CONNECTIONS-1)
  2563. {
  2564. g_dwMaxDbHandles = DEFAULT_DB_CONNECTIONS;
  2565. }
  2566. }
  2567. //------------------------------------------------------
  2568. //
  2569. // Load parameters for ESENT, all parameter must be set
  2570. // and confirm to ESENT document, any error, we just
  2571. // revert back to some value we know it works.
  2572. //
  2573. //------------------------------------------------------
  2574. dwBuffer = sizeof(g_EsentMaxCacheSize);
  2575. dwStatus = RegQueryValueEx(
  2576. hKey,
  2577. LSERVER_PARAMETERS_ESENTMAXCACHESIZE,
  2578. NULL,
  2579. NULL,
  2580. (LPBYTE)&g_EsentMaxCacheSize,
  2581. &dwBuffer
  2582. );
  2583. if(dwStatus == ERROR_SUCCESS)
  2584. {
  2585. dwBuffer = sizeof(g_EsentStartFlushThreshold);
  2586. dwStatus = RegQueryValueEx(
  2587. hKey,
  2588. LSERVER_PARAMETERS_ESENTSTARTFLUSH,
  2589. NULL,
  2590. NULL,
  2591. (LPBYTE)&g_EsentStartFlushThreshold,
  2592. &dwBuffer
  2593. );
  2594. if(dwStatus == ERROR_SUCCESS)
  2595. {
  2596. dwBuffer = sizeof(g_EsentStopFlushThreadhold);
  2597. dwStatus = RegQueryValueEx(
  2598. hKey,
  2599. LSERVER_PARAMETERS_ESENTSTOPFLUSH,
  2600. NULL,
  2601. NULL,
  2602. (LPBYTE)&g_EsentStopFlushThreadhold,
  2603. &dwBuffer
  2604. );
  2605. }
  2606. }
  2607. if( dwStatus != ERROR_SUCCESS ||
  2608. g_EsentStartFlushThreshold > g_EsentStopFlushThreadhold ||
  2609. g_EsentStopFlushThreadhold > g_EsentMaxCacheSize ||
  2610. g_EsentMaxCacheSize < LSERVER_PARAMETERS_ESENTMAXCACHESIZE_MIN ||
  2611. g_EsentStartFlushThreshold < LSERVER_PARAMETERS_ESENTSTARTFLUSH_MIN ||
  2612. g_EsentStopFlushThreadhold < LSERVER_PARAMETERS_ESENTSTOPFLUSH_MIN ||
  2613. g_EsentMaxCacheSize > LSERVER_PARAMETERS_ESENTMAXCACHESIZE_MAX ||
  2614. g_EsentStartFlushThreshold > LSERVER_PARAMETERS_ESENTSTARTFLUSH_MAX ||
  2615. g_EsentStopFlushThreadhold > LSERVER_PARAMETERS_ESENTSTOPFLUSH_MAX )
  2616. {
  2617. // pre-define number to let ESENT picks its number
  2618. if( g_EsentMaxCacheSize != LSERVER_PARAMETERS_USE_ESENTDEFAULT )
  2619. {
  2620. g_EsentMaxCacheSize = LSERVER_PARAMETERS_ESENTMAXCACHESIZE_DEFAULT;
  2621. g_EsentStartFlushThreshold = LSERVER_PARAMETERS_ESENTSTARTFLUSH_DEFAULT;
  2622. g_EsentStopFlushThreadhold = LSERVER_PARAMETERS_ESENTSTOPFLUSH_DEFAULT;
  2623. }
  2624. }
  2625. //------------------------------------------------------
  2626. //
  2627. // Determine role of server in enterprise
  2628. //
  2629. //------------------------------------------------------
  2630. dwBuffer = sizeof(g_SrvRole);
  2631. dwStatus = RegQueryValueEx(
  2632. hKey,
  2633. LSERVER_PARAMETERS_ROLE,
  2634. NULL,
  2635. NULL,
  2636. (LPBYTE)&g_SrvRole,
  2637. &dwBuffer
  2638. );
  2639. if(g_SrvRole & TLSERVER_ENTERPRISE_SERVER)
  2640. {
  2641. dwBuffer = sizeof(g_szScope)/sizeof(g_szScope[0]);
  2642. memset(g_szScope, 0, sizeof(g_szScope));
  2643. dwStatus = RegQueryValueEx(
  2644. hKey,
  2645. LSERVER_PARAMETERS_SCOPE,
  2646. NULL,
  2647. &dwKeyType,
  2648. (LPBYTE)g_szScope,
  2649. &dwBuffer
  2650. );
  2651. if(dwStatus != ERROR_SUCCESS)
  2652. {
  2653. // no scope is set, default to local machine name
  2654. // consider using domain name ???
  2655. LoadResourceString(
  2656. IDS_SCOPE_ENTERPRISE,
  2657. g_szScope,
  2658. sizeof(g_szScope)/sizeof(g_szScope[0])
  2659. );
  2660. }
  2661. g_pszScope = g_szScope;
  2662. }
  2663. else
  2664. {
  2665. //
  2666. // Use the workgroup or domain name as scope
  2667. //
  2668. LPWSTR pszScope;
  2669. if(GetMachineGroup(NULL, &pszScope) == FALSE)
  2670. {
  2671. TLSLogEvent(
  2672. EVENTLOG_ERROR_TYPE,
  2673. TLS_E_SERVICEINIT,
  2674. TLS_E_RETRIEVEGROUPNAME
  2675. );
  2676. goto cleanup;
  2677. }
  2678. g_pszScope = pszScope;
  2679. }
  2680. //------------------------------------------------------
  2681. //
  2682. // Reissuance Parameters
  2683. //
  2684. //------------------------------------------------------
  2685. dwBuffer = sizeof(g_dwReissueLeaseMinimum);
  2686. dwStatus = RegQueryValueEx(
  2687. hKey,
  2688. LSERVER_PARAMETERS_LEASE_MIN,
  2689. NULL,
  2690. NULL,
  2691. (LPBYTE)&g_dwReissueLeaseMinimum,
  2692. &dwBuffer
  2693. );
  2694. if (dwStatus == ERROR_SUCCESS)
  2695. {
  2696. g_dwReissueLeaseMinimum = min(g_dwReissueLeaseMinimum,
  2697. PERMANENT_LICENSE_LEASE_EXPIRE_MIN);
  2698. }
  2699. else
  2700. {
  2701. g_dwReissueLeaseMinimum = PERMANENT_LICENSE_LEASE_EXPIRE_MIN;
  2702. }
  2703. dwBuffer = sizeof(g_dwReissueLeaseRange);
  2704. dwStatus = RegQueryValueEx(
  2705. hKey,
  2706. LSERVER_PARAMETERS_LEASE_RANGE,
  2707. NULL,
  2708. NULL,
  2709. (LPBYTE)&g_dwReissueLeaseRange,
  2710. &dwBuffer
  2711. );
  2712. if (dwStatus == ERROR_SUCCESS)
  2713. {
  2714. g_dwReissueLeaseRange = min(g_dwReissueLeaseRange,
  2715. PERMANENT_LICENSE_LEASE_EXPIRE_RANGE);
  2716. g_dwReissueLeaseRange = max(g_dwReissueLeaseRange, 1);
  2717. }
  2718. else
  2719. {
  2720. g_dwReissueLeaseRange = PERMANENT_LICENSE_LEASE_EXPIRE_RANGE;
  2721. }
  2722. dwBuffer = sizeof(g_dwReissueLeaseLeeway);
  2723. dwStatus = RegQueryValueEx(
  2724. hKey,
  2725. LSERVER_PARAMETERS_LEASE_LEEWAY,
  2726. NULL,
  2727. NULL,
  2728. (LPBYTE)&g_dwReissueLeaseLeeway,
  2729. &dwBuffer
  2730. );
  2731. if (dwStatus == ERROR_SUCCESS)
  2732. {
  2733. g_dwReissueLeaseLeeway = min(g_dwReissueLeaseLeeway,
  2734. PERMANENT_LICENSE_LEASE_EXPIRE_LEEWAY);
  2735. }
  2736. else
  2737. {
  2738. g_dwReissueLeaseLeeway = PERMANENT_LICENSE_LEASE_EXPIRE_LEEWAY;
  2739. }
  2740. dwBuffer = sizeof(g_dwReissueExpireThreadSleep);
  2741. dwStatus = RegQueryValueEx(
  2742. hKey,
  2743. LSERVER_PARAMETERS_EXPIRE_THREAD_SLEEP,
  2744. NULL,
  2745. NULL,
  2746. (LPBYTE)&g_dwReissueExpireThreadSleep,
  2747. &dwBuffer
  2748. );
  2749. if (dwStatus == ERROR_SUCCESS)
  2750. {
  2751. g_dwReissueExpireThreadSleep = min(g_dwReissueExpireThreadSleep,
  2752. EXPIRE_THREAD_SLEEP_TIME);
  2753. }
  2754. else
  2755. {
  2756. g_dwReissueExpireThreadSleep = EXPIRE_THREAD_SLEEP_TIME;
  2757. }
  2758. dwStatus = ERROR_SUCCESS;
  2759. cleanup:
  2760. if(hKey != NULL)
  2761. {
  2762. RegCloseKey(hKey);
  2763. }
  2764. return dwStatus;
  2765. }
  2766. ///////////////////////////////////////////////////////////////
  2767. DWORD
  2768. TLSPrepareForBackupRestore()
  2769. {
  2770. DBGPrintf(
  2771. DBG_INFORMATION,
  2772. DBG_FACILITY_INIT,
  2773. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2774. _TEXT("TLSPrepareForBackupRestore...\n")
  2775. );
  2776. //
  2777. // Pretend we are shutting down.
  2778. //
  2779. // ServiceSignalShutdown();
  2780. //
  2781. // first stop workmanager thread
  2782. //
  2783. TLSWorkManagerShutdown();
  2784. //
  2785. // Close all workspace and DB handle
  2786. //
  2787. #ifndef _NO_ODBC_JET
  2788. if(g_DbWorkSpace != NULL)
  2789. {
  2790. ReleaseWorkSpace(&g_DbWorkSpace);
  2791. }
  2792. #endif
  2793. CloseWorkSpacePool();
  2794. return ERROR_SUCCESS;
  2795. }
  2796. ///////////////////////////////////////////////////////////////
  2797. DWORD
  2798. TLSRestartAfterBackupRestore(
  2799. BOOL bRestartAfterbackup
  2800. )
  2801. /*++
  2802. bRestartAfterbackup : TRUE if restart after backup, FALSE if restart after restore.
  2803. --*/
  2804. {
  2805. DWORD dwStatus;
  2806. BOOL bIgnoreRestoreFile;
  2807. BOOL bIgnoreFileTimeChecking;
  2808. BOOL bLogWarning;
  2809. DBGPrintf(
  2810. DBG_INFORMATION,
  2811. DBG_FACILITY_INIT,
  2812. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2813. _TEXT("TLSRestartAfterBackupRestore...\n")
  2814. );
  2815. //
  2816. // Reset shutdown event
  2817. //
  2818. // ServiceResetShutdownEvent();
  2819. //
  2820. // Startup DB engine.
  2821. //
  2822. bIgnoreRestoreFile = bRestartAfterbackup;
  2823. bIgnoreFileTimeChecking = (bRestartAfterbackup == FALSE); // on restore, we need to ignore file time checking
  2824. bLogWarning = bIgnoreFileTimeChecking; // log warning after restart from restore
  2825. dwStatus = TLSStartLSDbWorkspaceEngine(
  2826. TRUE,
  2827. bIgnoreRestoreFile,
  2828. bIgnoreFileTimeChecking,
  2829. bLogWarning
  2830. );
  2831. if(dwStatus == ERROR_SUCCESS)
  2832. {
  2833. dwStatus = TLSWorkManagerInit();
  2834. }
  2835. // backup/restore always shutdown namedpipe thread
  2836. InitNamedPipeThread();
  2837. TLSASSERT(dwStatus == ERROR_SUCCESS);
  2838. DBGPrintf(
  2839. DBG_INFORMATION,
  2840. DBG_FACILITY_INIT,
  2841. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2842. _TEXT("\tTLSRestartAfterBackupRestore() returns %d\n"),
  2843. dwStatus
  2844. );
  2845. return dwStatus;
  2846. }