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.

2288 lines
60 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. //
  5. // File: tlsjob.cpp
  6. //
  7. // Contents: Various license server job.
  8. //
  9. // History:
  10. //
  11. //---------------------------------------------------------------------------
  12. #include "pch.cpp"
  13. #include "tlsjob.h"
  14. #include "jobmgr.h"
  15. #include "wkstore.h"
  16. #include "srvlist.h"
  17. #include "kp.h"
  18. #include "clilic.h"
  19. #include "keypack.h"
  20. #include "init.h"
  21. #include <winsta.h>
  22. #include <globals.h>
  23. #define STRSAFE_NO_DEPRECATE
  24. #include "strsafe.h"
  25. /////////////////////////////////////////////////////////////
  26. //
  27. //
  28. //
  29. //
  30. /////////////////////////////////////////////////////////////
  31. //////////////////////////////////////////////////////////////
  32. // Various interface into global work manager
  33. //////////////////////////////////////////////////////////////
  34. CWorkManager g_WorkManager;
  35. CPersistentWorkStorage g_WorkStorage;
  36. #define MAX_ERROR_MSG_SIZE 1024
  37. DWORD
  38. TLSWorkManagerInit()
  39. /*++
  40. Abstract:
  41. Initialize work manager.
  42. Parameter:
  43. None.
  44. returns:
  45. ERROR_SUCCESS or error code.
  46. --*/
  47. {
  48. DWORD dwStatus;
  49. WorkItemTable* pWkStorageTable = NULL;
  50. //
  51. // Initialize Work Storage table
  52. //
  53. pWkStorageTable = GetWorkItemStorageTable();
  54. if(pWkStorageTable == NULL)
  55. {
  56. dwStatus = GetLastError();
  57. goto cleanup;
  58. }
  59. //
  60. // Init Persistent work storage table
  61. //
  62. if(g_WorkStorage.AttachTable(pWkStorageTable) == FALSE)
  63. {
  64. dwStatus = GetLastError();
  65. goto cleanup;
  66. }
  67. //
  68. // Initialize Work Manager
  69. //
  70. dwStatus = g_WorkManager.Startup(&g_WorkStorage);
  71. cleanup:
  72. return dwStatus;
  73. }
  74. //-----------------------------------------------------------
  75. void
  76. TLSWorkManagerShutdown()
  77. /*++
  78. Abstract:
  79. Shutdown work manager.
  80. Parameter:
  81. None:
  82. Return:
  83. None.
  84. --*/
  85. {
  86. g_WorkManager.Shutdown();
  87. }
  88. //-----------------------------------------------------------
  89. DWORD
  90. TLSWorkManagerSchedule(
  91. IN DWORD dwTime,
  92. IN CWorkObject* pJob
  93. )
  94. /*++
  95. Abstract:
  96. Schedule a job to work manager.
  97. Parameter:
  98. dwTime : Suggested time for work manager to process this job.
  99. pJob : Job to be processed/scheduled.
  100. Returns:
  101. ERROR_SUCCESS or error code.
  102. --*/
  103. {
  104. return g_WorkManager.ScheduleJob(dwTime, pJob);
  105. }
  106. //-----------------------------------------------------------
  107. BOOL
  108. TLSWorkManagerSetJobDefaults(
  109. CWorkObject* pJob
  110. )
  111. /*++
  112. Abstract:
  113. Set job's interval and retry time.
  114. Parameter:
  115. pJob : Job to be set.
  116. Returns:
  117. TRUE/FALSE.
  118. --*/
  119. {
  120. DWORD dwInterval, dwRetries, dwRestart;
  121. DWORD dwStatus = ERROR_SUCCESS;
  122. if(pJob != NULL)
  123. {
  124. GetJobObjectDefaults(&dwInterval, &dwRetries, &dwRestart);
  125. pJob->SetJobInterval(dwInterval);
  126. pJob->SetJobRetryTimes(dwRetries);
  127. pJob->SetJobRestartTime(dwRestart);
  128. }
  129. else
  130. {
  131. SetLastError(ERROR_INVALID_PARAMETER);
  132. }
  133. return dwStatus == ERROR_SUCCESS;
  134. }
  135. //-----------------------------------------------------------
  136. BOOL
  137. CopyBinaryData(
  138. IN OUT PBYTE* ppbDestData,
  139. IN OUT DWORD* pcbDestData,
  140. IN PBYTE pbSrcData,
  141. IN DWORD cbSrcData
  142. )
  143. /*++
  144. Abstract:
  145. Internal routine to copy a binary data from one buffer
  146. to another.
  147. Parameters:
  148. ppbDestData: Pointer to pointer...
  149. pcbDestData:
  150. pbSrcData:
  151. cbSrcData:
  152. Return:
  153. TRUE if successful, FALSE otherwise.
  154. ++*/
  155. {
  156. PBYTE pbTarget = NULL;
  157. if( ppbDestData == NULL || pcbDestData == NULL ||
  158. pbSrcData == NULL || cbSrcData == 0 )
  159. {
  160. SetLastError(ERROR_INVALID_PARAMETER);
  161. return FALSE;
  162. }
  163. pbTarget = *ppbDestData;
  164. //
  165. // would be nice to get the actual size of memory allocated
  166. //
  167. if( *ppbDestData == NULL || LocalSize(*ppbDestData) < cbSrcData )
  168. {
  169. if(*ppbDestData == NULL)
  170. {
  171. pbTarget = (PBYTE)AllocateMemory(cbSrcData);
  172. }
  173. else
  174. {
  175. pbTarget = (PBYTE)ReallocateMemory(*ppbDestData, cbSrcData);
  176. }
  177. }
  178. if(pbTarget != NULL)
  179. {
  180. memcpy(
  181. pbTarget,
  182. pbSrcData,
  183. cbSrcData
  184. );
  185. *pcbDestData = cbSrcData;
  186. *ppbDestData = pbTarget;
  187. }
  188. return pbTarget != NULL;
  189. }
  190. //////////////////////////////////////////////////////////////////////////
  191. //
  192. // CAnnounceLsServer
  193. //
  194. //////////////////////////////////////////////////////////////////////////
  195. BOOL
  196. CAnnounceLserver::VerifyWorkObjectData(
  197. IN BOOL bCallByIsValid, // invoke by IsValid() function.
  198. IN PANNOUNCESERVERWO pbData,
  199. IN DWORD cbData
  200. )
  201. /*++
  202. Verify Announce License Server work object Data.
  203. --*/
  204. {
  205. BOOL bSuccess = FALSE;
  206. DWORD dwLen;
  207. if(pbData == NULL || cbData == 0 || cbData != pbData->dwStructSize)
  208. {
  209. TLSASSERT(FALSE);
  210. SetLastError(ERROR_INVALID_DATA);
  211. return FALSE;
  212. }
  213. //
  214. // NULL terminate string...
  215. //
  216. pbData->m_szServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  217. pbData->m_szServerName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  218. dwLen = _tcslen(pbData->m_szServerId);
  219. if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
  220. {
  221. dwLen = _tcslen(pbData->m_szServerName);
  222. if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
  223. {
  224. bSuccess = TRUE;
  225. }
  226. }
  227. if(bSuccess == FALSE)
  228. {
  229. SetLastError(ERROR_INVALID_DATA);
  230. }
  231. return bSuccess;
  232. }
  233. //------------------------------------------------------------------------
  234. BOOL
  235. CAnnounceLserver::CopyWorkObjectData(
  236. OUT PANNOUNCESERVERWO* ppbDest,
  237. OUT PDWORD pcbDest,
  238. IN PANNOUNCESERVERWO pbSrc,
  239. IN DWORD cbSrc
  240. )
  241. /*++
  242. Copy Announce license server work object's data
  243. --*/
  244. {
  245. DWORD dwStatus = ERROR_SUCCESS;
  246. if(ppbDest == NULL || pcbDest == NULL)
  247. {
  248. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  249. TLSASSERT(FALSE);
  250. goto cleanup;
  251. }
  252. if(CopyBinaryData(
  253. (PBYTE *)ppbDest,
  254. pcbDest,
  255. (PBYTE) pbSrc,
  256. cbSrc
  257. ) == FALSE)
  258. {
  259. dwStatus = GetLastError();
  260. }
  261. cleanup:
  262. return dwStatus == ERROR_SUCCESS;
  263. }
  264. //---------------------------------------------------------------------------
  265. BOOL
  266. CAnnounceLserver::CleanupWorkObjectData(
  267. IN OUT PANNOUNCESERVERWO* ppbData,
  268. IN OUT PDWORD pcbData
  269. )
  270. /*++
  271. Cleanup Announce license server's work object data.
  272. --*/
  273. {
  274. if(ppbData != NULL && pcbData != NULL)
  275. {
  276. FreeMemory(*ppbData);
  277. *ppbData = NULL;
  278. *pcbData = 0;
  279. }
  280. return TRUE;
  281. }
  282. //---------------------------------------------------------------------------
  283. BOOL
  284. CAnnounceLserver::IsJobCompleted(
  285. IN PANNOUNCESERVERWO pbData,
  286. IN DWORD cbData
  287. )
  288. /*++
  289. Determine if Announce License Server Job has completed.
  290. --*/
  291. {
  292. return (pbData == NULL) ? TRUE : (pbData->dwRetryTimes > GetJobRetryTimes());
  293. }
  294. //---------------------------------------------------------------------------
  295. BOOL
  296. ServerEnumCallBack(
  297. TLS_HANDLE hHandle,
  298. LPCTSTR pszServerName,
  299. HANDLE dwUserData
  300. )
  301. /*++
  302. See TLSAPI on license server enumeration.
  303. ++*/
  304. {
  305. CAnnounceLserver* pWkObject = (CAnnounceLserver *)dwUserData;
  306. DWORD dwStatus = ERROR_SUCCESS;
  307. DWORD dwErrCode;
  308. TCHAR szRemoteServerId[LSERVER_MAX_STRING_SIZE+2];
  309. TCHAR szRemoteServerName[LSERVER_MAX_STRING_SIZE+2];
  310. if(pWkObject == NULL)
  311. {
  312. SetLastError(ERROR_INVALID_DATA);
  313. TLSASSERT(dwUserData != NULL);
  314. return FALSE;
  315. }
  316. BOOL bCancel;
  317. if(pWkObject->IsWorkManagerShuttingDown() == TRUE)
  318. {
  319. return TRUE;
  320. }
  321. //
  322. // Enumeration call ServerEnumCallBack() twice, once before actual connection
  323. // and once after it successfully connect to remote server
  324. //
  325. if( lstrcmpi(pszServerName, pWkObject->GetWorkData()->m_szServerName) != 0 && hHandle != NULL)
  326. {
  327. //
  328. // throw exception if fail to allocate memory
  329. //
  330. TLServerInfo ServerInfo;
  331. TLServerInfo ExistingServerInfo;
  332. TLS_HANDLE hTrustHandle;
  333. hTrustHandle = TLSConnectAndEstablishTrust(
  334. NULL,
  335. hHandle
  336. );
  337. if(hTrustHandle != NULL)
  338. {
  339. dwStatus = TLSRetrieveServerInfo(
  340. hTrustHandle,
  341. &ServerInfo
  342. );
  343. if( dwStatus == ERROR_SUCCESS &&
  344. lstrcmpi(ServerInfo.GetServerId(), pWkObject->GetWorkData()->m_szServerId) != 0 )
  345. // lstrcmpi(ServerInfo.GetServerName(), pWkObject->GetWorkData()->m_szServerName) != 0
  346. {
  347. // check to see if this server is already exists
  348. dwStatus = TLSLookupRegisteredServer(
  349. ServerInfo.GetServerId(),
  350. ServerInfo.GetServerDomain(),
  351. ServerInfo.GetServerName(),
  352. &ExistingServerInfo
  353. );
  354. if(dwStatus == ERROR_SUCCESS)
  355. {
  356. ServerInfo = ExistingServerInfo;
  357. }
  358. else
  359. {
  360. // register every server.
  361. dwStatus = TLSRegisterServerWithServerInfo(&ServerInfo);
  362. if(dwStatus == TLS_E_DUPLICATE_RECORD)
  363. {
  364. dwStatus = ERROR_SUCCESS;
  365. }
  366. }
  367. // let enforce talk to non-enforce, replication will be block later
  368. if( ServerInfo.IsAnnounced() == FALSE && dwStatus == ERROR_SUCCESS )
  369. {
  370. DBGPrintf(
  371. DBG_INFORMATION,
  372. DBG_FACILITY_JOB,
  373. DBGLEVEL_FUNCTION_TRACE,
  374. _TEXT("%s - Announce to %s\n"),
  375. pWkObject->GetJobDescription(),
  376. ServerInfo.GetServerName()
  377. );
  378. dwStatus = TLSAnnounceServerToRemoteServer(
  379. TLSANNOUNCE_TYPE_STARTUP,
  380. ServerInfo.GetServerId(),
  381. ServerInfo.GetServerDomain(),
  382. ServerInfo.GetServerName(),
  383. pWkObject->GetWorkData()->m_szServerId,
  384. pWkObject->GetWorkData()->m_szScope,
  385. pWkObject->GetWorkData()->m_szServerName,
  386. &(pWkObject->GetWorkData()->m_ftLastShutdownTime)
  387. );
  388. }
  389. }
  390. }
  391. }
  392. return (dwStatus == ERROR_SUCCESS) ? pWkObject->IsWorkManagerShuttingDown() : TRUE;
  393. }
  394. //---------------------------------------------------------------------------
  395. DWORD
  396. CAnnounceLserver::ExecuteJob(
  397. IN PANNOUNCESERVERWO pbData,
  398. IN DWORD cbData
  399. )
  400. /*++
  401. Execute a announce license server job.
  402. --*/
  403. {
  404. DWORD dwStatus = ERROR_SUCCESS;
  405. DBGPrintf(
  406. DBG_INFORMATION,
  407. DBG_FACILITY_JOB,
  408. DBGLEVEL_FUNCTION_TRACE,
  409. _TEXT("%s ...\n"),
  410. GetJobDescription()
  411. );
  412. if(IsWorkManagerShuttingDown() == TRUE)
  413. {
  414. return TLS_I_WORKMANAGER_SHUTDOWN;
  415. }
  416. //
  417. // Enumerate all license server
  418. //
  419. dwStatus = EnumerateTlsServer(
  420. ServerEnumCallBack,
  421. this,
  422. TLSERVER_ENUM_TIMEOUT,
  423. FALSE
  424. );
  425. //
  426. // Discovery run twice so that if more than one server
  427. // start up at the same time, second loop will catch it.
  428. //
  429. pbData->dwRetryTimes++;
  430. DBGPrintf(
  431. DBG_INFORMATION,
  432. DBG_FACILITY_JOB,
  433. DBGLEVEL_FUNCTION_TRACE,
  434. _TEXT("%s ended...\n"),
  435. GetJobDescription()
  436. );
  437. return dwStatus;
  438. }
  439. //----------------------------------------------------------------------------------------------
  440. LPCTSTR
  441. CAnnounceLserver::GetJobDescription()
  442. /*++
  443. Get announce license server job description, this is used
  444. only at debug tracing.
  445. --*/
  446. {
  447. memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
  448. _tcsncpy(
  449. m_szJobDescription,
  450. ANNOUNCESERVER_DESCRIPTION,
  451. sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1
  452. );
  453. return m_szJobDescription;
  454. }
  455. ////////////////////////////////////////////////////////////
  456. //////////////////////////////////////////////////////////////////////////
  457. //
  458. // CAnnounceTOEServer
  459. //
  460. //////////////////////////////////////////////////////////////////////////
  461. BOOL
  462. CAnnounceToEServer::VerifyWorkObjectData(
  463. IN BOOL bCallByIsValid, // invoke by IsValid() function.
  464. IN PANNOUNCETOESERVERWO pbData,
  465. IN DWORD cbData
  466. )
  467. /*++
  468. Verify Announce license server to enterprise server work object
  469. data.
  470. --*/
  471. {
  472. BOOL bSuccess = FALSE;
  473. DWORD dwLen;
  474. if(pbData == NULL || cbData != pbData->dwStructSize)
  475. {
  476. TLSASSERT(FALSE);
  477. SetLastError(ERROR_INVALID_PARAMETER);
  478. return FALSE;
  479. }
  480. //
  481. // NULL terminate string...
  482. //
  483. pbData->m_szServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  484. pbData->m_szServerName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  485. dwLen = _tcslen(pbData->m_szServerId);
  486. if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
  487. {
  488. dwLen = _tcslen(pbData->m_szServerName);
  489. if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
  490. {
  491. bSuccess = TRUE;
  492. }
  493. }
  494. if(bSuccess == FALSE)
  495. {
  496. SetLastError(ERROR_INVALID_DATA);
  497. }
  498. return bSuccess;
  499. }
  500. //------------------------------------------------------------------------
  501. BOOL
  502. CAnnounceToEServer::CopyWorkObjectData(
  503. OUT PANNOUNCETOESERVERWO* ppbDest,
  504. OUT PDWORD pcbDest,
  505. IN PANNOUNCETOESERVERWO pbSrc,
  506. IN DWORD cbSrc
  507. )
  508. /*++
  509. Copy announce license server to enterprise server work
  510. object data.
  511. --*/
  512. {
  513. DWORD dwStatus = ERROR_SUCCESS;
  514. if(ppbDest == NULL || pcbDest == NULL)
  515. {
  516. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  517. TLSASSERT(FALSE);
  518. goto cleanup;
  519. }
  520. if(CopyBinaryData(
  521. (PBYTE *)ppbDest,
  522. pcbDest,
  523. (PBYTE) pbSrc,
  524. cbSrc
  525. ) == FALSE)
  526. {
  527. dwStatus = GetLastError();
  528. }
  529. cleanup:
  530. return dwStatus == ERROR_SUCCESS;
  531. }
  532. //---------------------------------------------------------------------------
  533. BOOL
  534. CAnnounceToEServer::CleanupWorkObjectData(
  535. IN OUT PANNOUNCETOESERVERWO* ppbData,
  536. IN OUT PDWORD pcbData
  537. )
  538. /*++
  539. Cleanup announce license server to enterprise server work
  540. object data.
  541. --*/
  542. {
  543. if(ppbData != NULL && pcbData != NULL)
  544. {
  545. FreeMemory(*ppbData);
  546. *ppbData = NULL;
  547. *pcbData = 0;
  548. }
  549. return TRUE;
  550. }
  551. //---------------------------------------------------------------------------
  552. BOOL
  553. CAnnounceToEServer::IsJobCompleted(
  554. IN PANNOUNCETOESERVERWO pbData,
  555. IN DWORD cbData
  556. )
  557. /*++
  558. Detemine if announce license server to enterprise server
  559. is completed.
  560. --*/
  561. {
  562. return (pbData == NULL) ? TRUE : GetWorkData()->bCompleted;
  563. }
  564. //---------------------------------------------------------------------------
  565. DWORD
  566. CAnnounceToEServer::ExecuteJob(
  567. IN PANNOUNCETOESERVERWO pbData,
  568. IN DWORD cbData
  569. )
  570. /*++
  571. Execute an announce license server to enterprise server work object.
  572. --*/
  573. {
  574. DWORD dwStatus = ERROR_SUCCESS;
  575. LPWSTR* pszEServerList = NULL;
  576. DWORD dwCount = 0;
  577. DWORD dwErrCode;
  578. BOOL bSkipServer;
  579. TCHAR szRemoteServerId[LSERVER_MAX_STRING_SIZE+2];
  580. TCHAR szRemoteServerName[LSERVER_MAX_STRING_SIZE+2];
  581. DBGPrintf(
  582. DBG_INFORMATION,
  583. DBG_FACILITY_JOB,
  584. DBGLEVEL_FUNCTION_TRACE,
  585. _TEXT("%s ...\n"),
  586. GetJobDescription()
  587. );
  588. TLSASSERT(pbData != NULL && cbData != 0);
  589. dwStatus = GetAllEnterpriseServers(
  590. &pszEServerList,
  591. &dwCount
  592. );
  593. if(dwStatus == ERROR_SUCCESS && dwCount > 0 && pszEServerList != NULL)
  594. {
  595. for(DWORD index = 0;
  596. index < dwCount && IsWorkManagerShuttingDown() == FALSE;
  597. index++)
  598. {
  599. bSkipServer = TRUE;
  600. if(pszEServerList[index] == NULL)
  601. {
  602. continue;
  603. }
  604. //
  605. // check if we already have this server in our list
  606. //
  607. TLServerInfo ServerInfo;
  608. dwStatus = TLSLookupRegisteredServer(
  609. NULL,
  610. NULL,
  611. pszEServerList[index],
  612. &ServerInfo
  613. );
  614. if(dwStatus != ERROR_SUCCESS)
  615. {
  616. //
  617. // Get the actual server name.
  618. //
  619. TLS_HANDLE hTrustHandle = NULL;
  620. hTrustHandle = TLSConnectAndEstablishTrust(
  621. pszEServerList[index],
  622. NULL
  623. );
  624. if(hTrustHandle != NULL)
  625. {
  626. if(IsWorkManagerShuttingDown() == TRUE)
  627. {
  628. // handle leak but we are shutting down
  629. break;
  630. }
  631. dwStatus = TLSRetrieveServerInfo(
  632. hTrustHandle,
  633. &ServerInfo
  634. );
  635. if(dwStatus == ERROR_SUCCESS)
  636. {
  637. if( lstrcmpi(ServerInfo.GetServerName(), pbData->m_szServerName) != 0 )
  638. {
  639. if(IsWorkManagerShuttingDown() == TRUE)
  640. {
  641. // handle leak but we are shutting down
  642. break;
  643. }
  644. dwStatus = TLSRegisterServerWithServerInfo(&ServerInfo);
  645. if(dwStatus == ERROR_SUCCESS)
  646. {
  647. // at this point, if we gets duplicate record, that mean
  648. // server is registered via announce and we already
  649. // sync. local license pack so skip it.
  650. bSkipServer = FALSE;
  651. }
  652. }
  653. }
  654. }
  655. if( hTrustHandle != NULL)
  656. {
  657. TLSDisconnectFromServer(hTrustHandle);
  658. }
  659. dwStatus = ERROR_SUCCESS;
  660. if(bSkipServer == TRUE)
  661. {
  662. continue;
  663. }
  664. }
  665. else if(GetLicenseServerRole() & TLSERVER_ENTERPRISE_SERVER)
  666. {
  667. // for enterprise server, other server will announce itself,
  668. // for domain server, we need to announce once a while
  669. // so that after enterprise restart, it still have our
  670. // server
  671. if(dwStatus == ERROR_SUCCESS && ServerInfo.GetServerVersion() != 0)
  672. {
  673. //
  674. // we already 'push' sync. with this server
  675. //
  676. continue;
  677. }
  678. }
  679. DBGPrintf(
  680. DBG_INFORMATION,
  681. DBG_FACILITY_JOB,
  682. DBGLEVEL_FUNCTION_TRACE,
  683. _TEXT("%s - Announce to %s\n"),
  684. GetJobDescription(),
  685. pszEServerList[index]
  686. );
  687. if(IsWorkManagerShuttingDown() == TRUE)
  688. {
  689. // handle leak but we are shutting down
  690. break;
  691. }
  692. dwStatus = TLSAnnounceServerToRemoteServer(
  693. TLSANNOUNCE_TYPE_STARTUP,
  694. ServerInfo.GetServerId(),
  695. ServerInfo.GetServerDomain(),
  696. ServerInfo.GetServerName(),
  697. GetWorkData()->m_szServerId,
  698. GetWorkData()->m_szScope,
  699. GetWorkData()->m_szServerName,
  700. &(GetWorkData()->m_ftLastShutdownTime)
  701. );
  702. }
  703. //
  704. // Free memory
  705. //
  706. if(pszEServerList != NULL)
  707. {
  708. for( index = 0; index < dwCount; index ++)
  709. {
  710. if(pszEServerList[index] != NULL)
  711. {
  712. LocalFree(pszEServerList[index]);
  713. }
  714. }
  715. LocalFree(pszEServerList);
  716. }
  717. }
  718. //
  719. // Continue running in case user install a NT5 PDC
  720. //
  721. if(IsWorkManagerShuttingDown() == TRUE)
  722. {
  723. GetWorkData()->bCompleted = TRUE;
  724. }
  725. return dwStatus;
  726. }
  727. //--------------------------------------------------------------------
  728. LPCTSTR
  729. CAnnounceToEServer::GetJobDescription()
  730. /*++
  731. Get announce license server to enterprise server
  732. job description, used only at debug tracing.
  733. --*/
  734. {
  735. memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
  736. _tcsncpy(
  737. m_szJobDescription,
  738. ANNOUNCETOESERVER_DESCRIPTION,
  739. sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1
  740. );
  741. return m_szJobDescription;
  742. }
  743. ////////////////////////////////////////////////////////////
  744. //////////////////////////////////////////////////////////////////////////
  745. //
  746. // CReturnLicense
  747. //
  748. //////////////////////////////////////////////////////////////////////////
  749. CWorkObject* WINAPI
  750. InitializeCReturnWorkObject(
  751. IN CWorkManager* pWkMgr,
  752. IN PBYTE pbWorkData,
  753. IN DWORD cbWorkData
  754. )
  755. /*++
  756. Abstract:
  757. Create/initialize a Return License work object.
  758. Parameters:
  759. pWkMgr : Pointer work manager.
  760. pbWorkData : Object's work data used to initialize return license.
  761. cbWorkData : size of work data.
  762. Return:
  763. A pointer to CWorkObject or NULL if error.
  764. --*/
  765. {
  766. CReturnLicense* pRetLicense = NULL;
  767. DWORD dwStatus;
  768. DBGPrintf(
  769. DBG_INFORMATION,
  770. DBG_FACILITY_WORKMGR,
  771. DBGLEVEL_FUNCTION_TRACE,
  772. _TEXT("InitializeCReturnWorkObject() - initializing return license...\n")
  773. );
  774. pRetLicense = new CReturnLicense(
  775. TRUE,
  776. (PRETURNLICENSEWO)pbWorkData,
  777. cbWorkData
  778. );
  779. //
  780. // TODO - fix this, bad design
  781. //
  782. pRetLicense->SetProcessingWorkManager(pWkMgr);
  783. TLSASSERT(pRetLicense->IsValid() == TRUE);
  784. return pRetLicense;
  785. }
  786. //--------------------------------------------------------
  787. BOOL
  788. CReturnLicense::VerifyWorkObjectData(
  789. IN BOOL bCallByIsValid,
  790. IN PRETURNLICENSEWO pbData,
  791. IN DWORD cbData
  792. )
  793. /*++
  794. Verify a return license work object data.
  795. --*/
  796. {
  797. DWORD dwStatus = ERROR_SUCCESS;
  798. DWORD dwLen;
  799. DWORD dwNumLicensedProduct;
  800. if(pbData == NULL || cbData == 0 || pbData->cbEncryptedHwid == 0)
  801. {
  802. TLSASSERT(FALSE);
  803. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  804. }
  805. if(dwStatus == ERROR_SUCCESS)
  806. {
  807. if( pbData->dwStructVersion < CURRENT_RETURNLICENSEWO_STRUCT_VER ||
  808. pbData->dwStructSize != cbData )
  809. {
  810. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  811. TLSASSERT(FALSE);
  812. }
  813. }
  814. if(dwStatus == ERROR_SUCCESS)
  815. {
  816. //
  817. // NULL Terminate Target Server ID
  818. //
  819. pbData->szTargetServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  820. dwLen = _tcslen(pbData->szTargetServerId);
  821. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
  822. {
  823. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  824. }
  825. }
  826. if(dwStatus == ERROR_SUCCESS)
  827. {
  828. pbData->szTargetServerName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  829. dwLen = _tcslen(pbData->szTargetServerName);
  830. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
  831. {
  832. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  833. }
  834. }
  835. if(dwStatus == ERROR_SUCCESS)
  836. {
  837. pbData->szOrgProductID[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  838. dwLen = _tcslen(pbData->szOrgProductID);
  839. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
  840. {
  841. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  842. }
  843. }
  844. if(dwStatus == ERROR_SUCCESS)
  845. {
  846. pbData->szCompanyName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  847. dwLen = _tcslen(pbData->szCompanyName);
  848. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
  849. {
  850. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  851. }
  852. }
  853. if(dwStatus == ERROR_SUCCESS)
  854. {
  855. pbData->szProductId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  856. dwLen = _tcslen(pbData->szProductId);
  857. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
  858. {
  859. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  860. }
  861. }
  862. if(dwStatus == ERROR_SUCCESS)
  863. {
  864. pbData->szUserName[MAXCOMPUTERNAMELENGTH+1] = _TEXT('\0');
  865. dwLen = _tcslen(pbData->szUserName);
  866. if(dwLen == 0 || dwLen >= MAXCOMPUTERNAMELENGTH+1)
  867. {
  868. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  869. }
  870. }
  871. if(dwStatus == ERROR_SUCCESS)
  872. {
  873. pbData->szMachineName[MAXUSERNAMELENGTH+1] = _TEXT('\0');
  874. dwLen = _tcslen(pbData->szMachineName);
  875. if(dwLen == 0 || dwLen >= MAXUSERNAMELENGTH+1)
  876. {
  877. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  878. }
  879. }
  880. return dwStatus == ERROR_SUCCESS;
  881. }
  882. //----------------------------------------------------------------------------------------------
  883. BOOL
  884. CReturnLicense::CopyWorkObjectData(
  885. IN OUT PRETURNLICENSEWO* ppbDest,
  886. IN OUT PDWORD pcbDest,
  887. IN PRETURNLICENSEWO pbSrc,
  888. IN DWORD cbSrc
  889. )
  890. /*++
  891. Copy return license work object data.
  892. --*/
  893. {
  894. DWORD dwStatus = ERROR_SUCCESS;
  895. if(ppbDest == NULL || pcbDest == NULL)
  896. {
  897. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  898. TLSASSERT(FALSE);
  899. goto cleanup;
  900. }
  901. if(CopyBinaryData(
  902. (PBYTE *)ppbDest,
  903. pcbDest,
  904. (PBYTE) pbSrc,
  905. cbSrc
  906. ) == FALSE)
  907. {
  908. dwStatus = GetLastError();
  909. }
  910. cleanup:
  911. return dwStatus == ERROR_SUCCESS;
  912. }
  913. //-------------------------------------------------------------------------
  914. BOOL
  915. CReturnLicense::CleanupWorkObjectData(
  916. IN OUT PRETURNLICENSEWO* ppbData,
  917. IN OUT PDWORD pcbData
  918. )
  919. /*++
  920. Cleanup return license work object data.
  921. --*/
  922. {
  923. if(ppbData != NULL && pcbData != NULL)
  924. {
  925. FreeMemory(*ppbData);
  926. *ppbData = NULL;
  927. *pcbData = 0;
  928. }
  929. return TRUE;
  930. }
  931. //---------------------------------------------------------------------------
  932. BOOL
  933. CReturnLicense::IsJobCompleted(
  934. IN PRETURNLICENSEWO pbData,
  935. IN DWORD cbData
  936. )
  937. /*++
  938. Determine if return license job is completed.
  939. --*/
  940. {
  941. return (pbData != NULL) ? (pbData->dwNumRetry >= m_dwRetryTimes) : TRUE;
  942. }
  943. RPC_STATUS
  944. TryGetLastError(PCONTEXT_HANDLE hBinding,
  945. LPTSTR *pszBuffer,
  946. DWORD *pdwErrCode)
  947. {
  948. RPC_STATUS status;
  949. status = TLSGetLastErrorFixed(hBinding,pszBuffer,pdwErrCode);
  950. if(status != RPC_S_OK)
  951. {
  952. LPTSTR lpszError = NULL;
  953. status = ERROR_NOACCESS;
  954. size_t cbError;
  955. try
  956. {
  957. if ( !MyVirtualAlloc( (LSERVER_MAX_STRING_SIZE+1) * sizeof( TCHAR ),
  958. (PVOID*) &lpszError ) )
  959. {
  960. return RPC_S_OUT_OF_MEMORY;
  961. }
  962. DWORD uSize = LSERVER_MAX_STRING_SIZE +1 ;
  963. memset(lpszError, 0, ( LSERVER_MAX_STRING_SIZE +1 ) * sizeof( TCHAR ));
  964. status = TLSGetLastError(hBinding,uSize,lpszError,pdwErrCode);
  965. if((status == RPC_S_OK) && (pdwErrCode != NULL) && (*pdwErrCode == ERROR_SUCCESS))
  966. {
  967. if (SUCCEEDED(StringCbLength(lpszError,uSize,&cbError)))
  968. {
  969. *pszBuffer = (LPTSTR)MIDL_user_allocate(cbError+sizeof(TCHAR));
  970. if (NULL != *pszBuffer)
  971. {
  972. _tcscpy(*pszBuffer,lpszError);
  973. }
  974. else
  975. {
  976. status = RPC_S_OUT_OF_MEMORY;
  977. }
  978. }
  979. else
  980. {
  981. status = RPC_S_INVALID_ARG;
  982. }
  983. }
  984. }
  985. catch (...)
  986. {
  987. status = ERROR_NOACCESS;
  988. }
  989. if(lpszError)
  990. MyVirtualFree(lpszError);
  991. }
  992. return status;
  993. }
  994. //--------------------------------------------------------------------------------
  995. DWORD
  996. CReturnLicense::ExecuteJob(
  997. IN PRETURNLICENSEWO pbData,
  998. IN DWORD cbData
  999. )
  1000. /*++
  1001. Execute a return license work object.
  1002. --*/
  1003. {
  1004. DWORD dwStatus = ERROR_SUCCESS;
  1005. TLServerInfo ServerInfo;
  1006. TCHAR szServer[LSERVER_MAX_STRING_SIZE+2];
  1007. TLSLicenseToBeReturn ToBeReturn;
  1008. TLS_HANDLE hHandle = NULL;
  1009. DWORD dwErrCode = ERROR_SUCCESS;
  1010. // log an error
  1011. TCHAR *szErrMsg = NULL;
  1012. DBGPrintf(
  1013. DBG_INFORMATION,
  1014. DBG_FACILITY_JOB,
  1015. DBGLEVEL_FUNCTION_TRACE,
  1016. _TEXT("%s ...\n"),
  1017. GetJobDescription()
  1018. );
  1019. //-------------------------------------------------------
  1020. if(VerifyWorkObjectData(TRUE, pbData, cbData) == FALSE)
  1021. {
  1022. TLSASSERT(FALSE);
  1023. //
  1024. // this is invalid data, quitely abort operation
  1025. //
  1026. pbData->dwNumRetry = m_dwRetryTimes;
  1027. SetLastError(dwStatus = ERROR_INVALID_DATA);
  1028. goto cleanup;
  1029. }
  1030. if(IsWorkManagerShuttingDown() == TRUE)
  1031. {
  1032. SetLastError(dwStatus = TLS_I_WORKMANAGER_SHUTDOWN);
  1033. goto cleanup;
  1034. }
  1035. dwStatus = TLSResolveServerIdToServer(
  1036. pbData->szTargetServerId,
  1037. sizeof(szServer),
  1038. szServer
  1039. );
  1040. if(dwStatus != ERROR_SUCCESS)
  1041. {
  1042. // Server not register with this server, try using
  1043. // whatever name we have
  1044. lstrcpy(szServer, pbData->szTargetServerName);
  1045. dwStatus = ERROR_SUCCESS;
  1046. }
  1047. ToBeReturn.dwQuantity = pbData->dwQuantity;
  1048. ToBeReturn.dwKeyPackId = pbData->dwKeyPackId;
  1049. ToBeReturn.dwLicenseId = pbData->dwLicenseId;
  1050. ToBeReturn.cbEncryptedHwid = pbData->cbEncryptedHwid;
  1051. ToBeReturn.pbEncryptedHwid = pbData->pbEncryptedHwid;
  1052. ToBeReturn.dwProductVersion = pbData->dwProductVersion;
  1053. ToBeReturn.pszOrgProductId = pbData->szOrgProductID;
  1054. ToBeReturn.pszCompanyName = pbData->szCompanyName;
  1055. ToBeReturn.pszProductId = pbData->szProductId;
  1056. ToBeReturn.pszUserName = pbData->szUserName;
  1057. ToBeReturn.pszMachineName = pbData->szMachineName;
  1058. ToBeReturn.dwPlatformID = pbData->dwPlatformId;
  1059. if(IsWorkManagerShuttingDown() == TRUE)
  1060. {
  1061. SetLastError(dwStatus = TLS_I_WORKMANAGER_SHUTDOWN);
  1062. goto cleanup;
  1063. }
  1064. hHandle = TLSConnectAndEstablishTrust(szServer, NULL);
  1065. if(hHandle == NULL)
  1066. {
  1067. dwStatus = GetLastError();
  1068. // TLSLogEvent(
  1069. // EVENTLOG_WARNING_TYPE,
  1070. // TLS_W_RETURNLICENSE,
  1071. // TLS_I_CONTACTSERVER,
  1072. // szServer
  1073. // );
  1074. }
  1075. else
  1076. {
  1077. if(IsWorkManagerShuttingDown() == TRUE)
  1078. {
  1079. SetLastError(dwStatus = TLS_I_WORKMANAGER_SHUTDOWN);
  1080. goto cleanup;
  1081. }
  1082. // make a RPC call to return client license
  1083. dwStatus = TLSReturnLicensedProduct(
  1084. hHandle,
  1085. &ToBeReturn,
  1086. &dwErrCode
  1087. );
  1088. if(dwStatus != ERROR_SUCCESS)
  1089. {
  1090. // retry again
  1091. // TLSLogEvent(
  1092. // EVENTLOG_WARNING_TYPE,
  1093. // TLS_W_RETURNLICENSE,
  1094. // TLS_I_CONTACTSERVER,
  1095. // szServer
  1096. // );
  1097. }
  1098. else if(dwErrCode >= LSERVER_ERROR_BASE)
  1099. {
  1100. if(dwErrCode != LSERVER_E_DATANOTFOUND && dwErrCode != LSERVER_E_INVALID_DATA)
  1101. {
  1102. DWORD status;
  1103. DWORD errCode;
  1104. status = TryGetLastError(
  1105. hHandle,
  1106. &szErrMsg,
  1107. &errCode
  1108. );
  1109. if(status == ERROR_SUCCESS)
  1110. {
  1111. TLSLogEvent(
  1112. EVENTLOG_WARNING_TYPE,
  1113. TLS_W_RETURNLICENSE,
  1114. TLS_E_RETURNLICENSE,
  1115. ToBeReturn.pszMachineName,
  1116. ToBeReturn.pszUserName,
  1117. szErrMsg,
  1118. szServer
  1119. );
  1120. MIDL_user_free(szErrMsg);
  1121. }
  1122. else
  1123. {
  1124. // server might be done at this instance,
  1125. // log an error with error code
  1126. TLSLogEvent(
  1127. EVENTLOG_WARNING_TYPE,
  1128. TLS_W_RETURNLICENSE,
  1129. TLS_E_RETURNLICENSECODE,
  1130. ToBeReturn.pszMachineName,
  1131. ToBeReturn.pszUserName,
  1132. dwErrCode,
  1133. szServer
  1134. );
  1135. }
  1136. }
  1137. }
  1138. }
  1139. if(dwStatus == ERROR_SUCCESS && dwErrCode == ERROR_SUCCESS)
  1140. {
  1141. // successfully return license.
  1142. pbData->dwNumRetry = m_dwRetryTimes;
  1143. }
  1144. else if(dwErrCode == LSERVER_E_INVALID_DATA || dwErrCode == LSERVER_E_DATANOTFOUND)
  1145. {
  1146. // server might be re-installed so all database entry is gone
  1147. // delete this return license job
  1148. pbData->dwNumRetry = m_dwRetryTimes;
  1149. }
  1150. else
  1151. {
  1152. pbData->dwNumRetry++;
  1153. if(pbData->dwNumRetry >= m_dwRetryTimes)
  1154. {
  1155. TLSLogEvent(
  1156. EVENTLOG_WARNING_TYPE,
  1157. TLS_W_RETURNLICENSE,
  1158. TLS_E_RETURNLICENSETOOMANY,
  1159. ToBeReturn.pszMachineName,
  1160. ToBeReturn.pszUserName,
  1161. pbData->dwNumRetry
  1162. );
  1163. }
  1164. }
  1165. cleanup:
  1166. if(hHandle != NULL)
  1167. {
  1168. TLSDisconnectFromServer(hHandle);
  1169. hHandle = NULL;
  1170. }
  1171. return dwStatus;
  1172. }
  1173. //----------------------------------------------------------------------------------------------
  1174. LPCTSTR
  1175. CReturnLicense::GetJobDescription()
  1176. /*++
  1177. Get job description, use only at debug tracing.
  1178. --*/
  1179. {
  1180. PRETURNLICENSEWO pbData = GetWorkData();
  1181. memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
  1182. if(pbData)
  1183. {
  1184. _sntprintf(
  1185. m_szJobDescription,
  1186. sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1,
  1187. RETURNLICENSE_DESCRIPTION,
  1188. pbData->dwNumRetry,
  1189. pbData->dwKeyPackId,
  1190. pbData->dwLicenseId,
  1191. pbData->szTargetServerName
  1192. );
  1193. }
  1194. return m_szJobDescription;
  1195. }
  1196. //////////////////////////////////////////////////////////////////////////
  1197. //
  1198. // CSsyncLicensePack
  1199. //
  1200. //////////////////////////////////////////////////////////////////////////
  1201. BOOL
  1202. CSsyncLicensePack::VerifyWorkObjectData(
  1203. IN BOOL bCallByIsValid, // invoke by IsValid() function.
  1204. IN PSSYNCLICENSEPACK pbData,
  1205. IN DWORD cbData
  1206. )
  1207. /*++
  1208. Verify a sync. license pack work object data.
  1209. --*/
  1210. {
  1211. BOOL bSuccess = TRUE;
  1212. DWORD dwLen;
  1213. if( pbData == NULL || cbData == 0 || cbData != pbData->dwStructSize ||
  1214. (pbData->dwSyncType != SSYNC_ALL_LKP && pbData->dwSyncType != SSYNC_ONE_LKP) )
  1215. {
  1216. TLSASSERT(FALSE);
  1217. SetLastError(ERROR_INVALID_DATA);
  1218. bSuccess = FALSE;
  1219. }
  1220. else if(bCallByIsValid == FALSE)
  1221. {
  1222. for(DWORD index =0;
  1223. index < pbData->dwNumServer && bSuccess == TRUE;
  1224. index++)
  1225. {
  1226. //
  1227. // NULL terminate string...
  1228. //
  1229. pbData->m_szTargetServer[index][MAX_COMPUTERNAME_LENGTH+1] = _TEXT('\0');
  1230. dwLen = _tcslen(pbData->m_szTargetServer[index]);
  1231. if(dwLen == 0 || dwLen >= MAX_COMPUTERNAME_LENGTH + 1)
  1232. {
  1233. SetLastError(ERROR_INVALID_DATA);
  1234. bSuccess = FALSE;
  1235. }
  1236. }
  1237. }
  1238. return bSuccess;
  1239. }
  1240. //------------------------------------------------------------------------
  1241. BOOL
  1242. CSsyncLicensePack::CopyWorkObjectData(
  1243. OUT PSSYNCLICENSEPACK* ppbDest,
  1244. OUT PDWORD pcbDest,
  1245. IN PSSYNCLICENSEPACK pbSrc,
  1246. IN DWORD cbSrc
  1247. )
  1248. /*++
  1249. Copy a sync. license pack work object data.
  1250. --*/
  1251. {
  1252. DWORD dwStatus = ERROR_SUCCESS;
  1253. if(ppbDest == NULL || pcbDest == NULL)
  1254. {
  1255. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  1256. TLSASSERT(FALSE);
  1257. goto cleanup;
  1258. }
  1259. if(CopyBinaryData(
  1260. (PBYTE *)ppbDest,
  1261. pcbDest,
  1262. (PBYTE) pbSrc,
  1263. cbSrc
  1264. ) == FALSE)
  1265. {
  1266. dwStatus = GetLastError();
  1267. }
  1268. cleanup:
  1269. return dwStatus == ERROR_SUCCESS;
  1270. }
  1271. //---------------------------------------------------------------------------
  1272. BOOL
  1273. CSsyncLicensePack::CleanupWorkObjectData(
  1274. IN OUT PSSYNCLICENSEPACK* ppbData,
  1275. IN OUT PDWORD pcbData
  1276. )
  1277. /*++
  1278. Cleanup a sync. license pack work object data.
  1279. --*/
  1280. {
  1281. if(ppbData != NULL && pcbData != NULL)
  1282. {
  1283. FreeMemory(*ppbData);
  1284. *ppbData = NULL;
  1285. *pcbData = 0;
  1286. }
  1287. return TRUE;
  1288. }
  1289. //---------------------------------------------------------------------------
  1290. BOOL
  1291. CSsyncLicensePack::IsJobCompleted(
  1292. IN PSSYNCLICENSEPACK pbData,
  1293. IN DWORD cbData
  1294. )
  1295. /*++
  1296. Detemine if Job is completed.
  1297. --*/
  1298. {
  1299. return (pbData == NULL) ? TRUE : pbData->bCompleted;
  1300. }
  1301. //---------------------------------------------------------------------------
  1302. void
  1303. _AnnounceLicensePackToServers(
  1304. IN CWorkObject* ptr,
  1305. IN PTLSLICENSEPACK pLicensePack,
  1306. IN PDWORD pdwCount,
  1307. IN TCHAR pszServerList[][MAX_COMPUTERNAME_LENGTH+2],
  1308. IN BOOL* pbSsyncStatus
  1309. )
  1310. /*++
  1311. Abstract:
  1312. Sync. a license pack to list of remote server.
  1313. Parameter:
  1314. ptr : pointer to work object that started this call.
  1315. pLicensePack : Pointer to license keypack to sync. with
  1316. list of remote server.
  1317. pdwCount : On input, number of license server to push sync,
  1318. on output, number of license server successfully sync.
  1319. pszServerList : Pointer to list of remote server.
  1320. pbSsyncStatus : Pointer to an array to receive push sync status.
  1321. Returns:
  1322. None, all error are ignored.
  1323. --*/
  1324. {
  1325. DWORD dwStatus = ERROR_SUCCESS;
  1326. TLSReplRecord record;
  1327. DWORD dwNumServer = *pdwCount;
  1328. DWORD dwIndex;
  1329. TLS_HANDLE hHandle;
  1330. RPC_STATUS rpcStatus;
  1331. BOOL fActAsEarlierVersion = FALSE;
  1332. WORD wMinorVersion, wMajorVersion;
  1333. TCHAR pszProductId[LSERVER_MAX_STRING_SIZE + 1];
  1334. *pdwCount = 0;
  1335. //
  1336. // Setup replication record
  1337. //
  1338. record.dwReplCode = REPLICATIONCODE_SYNC;
  1339. record.dwUnionType = UNION_TYPE_LICENSEPACK;
  1340. record.w.ReplLicPack = *pLicensePack;
  1341. //
  1342. // Announce to all server in the list
  1343. //
  1344. for( dwIndex = 0;
  1345. dwIndex < dwNumServer && ptr->IsWorkManagerShuttingDown() == FALSE;
  1346. dwIndex++ )
  1347. {
  1348. if(pbSsyncStatus[dwIndex] == FALSE)
  1349. {
  1350. hHandle = TLSConnectAndEstablishTrust(
  1351. pszServerList[dwIndex],
  1352. NULL
  1353. );
  1354. if(hHandle != NULL)
  1355. {
  1356. DWORD dwSupportFlags = 0;
  1357. dwStatus = TLSGetSupportFlags(
  1358. hHandle,
  1359. &dwSupportFlags
  1360. );
  1361. // License Keypack is not replicated if License server version < license Keypack version
  1362. if (((dwStatus == RPC_S_OK) && !(dwSupportFlags & SUPPORT_WHISTLER_CAL))
  1363. || (dwStatus != RPC_S_OK))
  1364. {
  1365. // This LS doesn't support Whistler CALs
  1366. if (CompareTLSVersions(MAKELONG(pLicensePack->wMinorVersion,pLicensePack->wMajorVersion),MAKELONG(1,5)) >= 0)
  1367. {
  1368. POLICY_TS_MACHINE groupPolicy;
  1369. RegGetMachinePolicy(&groupPolicy);
  1370. //
  1371. // This is a Whistler or later CAL
  1372. //
  1373. if (groupPolicy.fPolicyPreventLicenseUpgrade
  1374. && groupPolicy.fPreventLicenseUpgrade)
  1375. {
  1376. //
  1377. // We'll never want to issue a CAL to this LS
  1378. //
  1379. continue;
  1380. }
  1381. else
  1382. {
  1383. if( _tcsnicmp(pLicensePack->szProductId,
  1384. TERMSERV_PRODUCTID_SKU,
  1385. _tcslen(TERMSERV_PRODUCTID_SKU)) == 0 )
  1386. {
  1387. //
  1388. // Per Seat
  1389. //
  1390. fActAsEarlierVersion = TRUE;
  1391. wMinorVersion = pLicensePack->wMinorVersion;
  1392. wMajorVersion = pLicensePack->wMajorVersion;
  1393. _tcscpy(pszProductId,pLicensePack->szProductId);
  1394. pLicensePack->wMajorVersion = 5;
  1395. pLicensePack->wMinorVersion = 0;
  1396. _tcscpy(pLicensePack->szProductId,_T("A02-5.00-S"));
  1397. }
  1398. else
  1399. {
  1400. //
  1401. // never replicate if it isn't per-seat
  1402. //
  1403. continue;
  1404. }
  1405. }
  1406. }
  1407. }
  1408. rpcStatus = TLSAnnounceLicensePack(
  1409. hHandle,
  1410. &record,
  1411. &dwStatus
  1412. );
  1413. if (fActAsEarlierVersion)
  1414. {
  1415. // Put it back to the original values
  1416. pLicensePack->wMajorVersion = wMajorVersion;
  1417. pLicensePack->wMinorVersion = wMinorVersion;
  1418. _tcscpy(pLicensePack->szProductId,pszProductId);
  1419. }
  1420. if(rpcStatus != RPC_S_OK)
  1421. {
  1422. // this server might be down, mark it so that
  1423. // we don't retry again
  1424. pbSsyncStatus[dwIndex] = TRUE;
  1425. }
  1426. else if(dwStatus == LSERVER_E_SERVER_BUSY)
  1427. {
  1428. // retry only when server return busy status
  1429. pbSsyncStatus[dwIndex] = FALSE;
  1430. }
  1431. else
  1432. {
  1433. // any error, just don't bother trying again
  1434. pbSsyncStatus[dwIndex] = TRUE;
  1435. }
  1436. }
  1437. else
  1438. {
  1439. // server is not available, don't ssync again
  1440. pbSsyncStatus[dwIndex] = TRUE;
  1441. }
  1442. if(hHandle != NULL)
  1443. {
  1444. TLSDisconnectFromServer(hHandle);
  1445. hHandle = NULL;
  1446. }
  1447. }
  1448. if(pbSsyncStatus[dwIndex] == TRUE)
  1449. {
  1450. (*pdwCount)++;
  1451. }
  1452. }
  1453. return;
  1454. }
  1455. //---------------------------------------------------------------------------
  1456. DWORD
  1457. _SsyncOneLocalLicensePack(
  1458. IN CSsyncLicensePack* ptr,
  1459. IN PSSYNCLICENSEPACK pSsyncLkp
  1460. )
  1461. /*++
  1462. Abstract:
  1463. Sync. one license pack to one remote server.
  1464. Parameter:
  1465. Ptr : Pointer to CSsyncLicensePack work object.
  1466. pSsyncLkp : Pinter to PSSYNCLICENSEPACK.
  1467. Returns:
  1468. ERROR_SUCCESS or error code.
  1469. --*/
  1470. {
  1471. DWORD dwStatus = ERROR_SUCCESS;
  1472. PTLSDbWorkSpace pDbWkSpace = NULL;
  1473. TLSLICENSEPACK LicensePackSearch;
  1474. TLSLICENSEPACK LicensePack;
  1475. DWORD dwSuccessCount = 0;
  1476. //
  1477. // Allocate DB Work Space.
  1478. //
  1479. pDbWkSpace = AllocateWorkSpace(SSYNC_DBWORKSPACE_TIMEOUT);
  1480. if(pDbWkSpace == NULL)
  1481. {
  1482. SetLastError(dwStatus = TLS_I_SSYNCLKP_SERVER_BUSY);
  1483. TLSLogInfoEvent(TLS_I_SSYNCLKP_SERVER_BUSY);
  1484. goto cleanup;
  1485. }
  1486. LicensePackSearch.dwKeyPackId = pSsyncLkp->dwKeyPackId;
  1487. //
  1488. // retrieve license pack
  1489. //
  1490. dwStatus = TLSDBKeyPackFind(
  1491. pDbWkSpace,
  1492. TRUE,
  1493. LICENSEDPACK_PROCESS_DWINTERNAL,
  1494. &LicensePackSearch,
  1495. &LicensePack
  1496. );
  1497. if(dwStatus != ERROR_SUCCESS)
  1498. {
  1499. if(dwStatus != TLS_E_RECORD_NOTFOUND)
  1500. {
  1501. TLSLogEvent(
  1502. EVENTLOG_INFORMATION_TYPE,
  1503. TLS_W_SSYNCLKP,
  1504. dwStatus
  1505. );
  1506. }
  1507. goto cleanup;
  1508. }
  1509. if(IsLicensePackRepl(&LicensePack) == FALSE)
  1510. {
  1511. goto cleanup;
  1512. }
  1513. if(ptr->IsWorkManagerShuttingDown() == TRUE)
  1514. {
  1515. SetLastError(dwStatus = TLS_I_SERVICE_STOP);
  1516. goto cleanup;
  1517. }
  1518. //
  1519. // Make sure local Server ID and Server Name is correct
  1520. //
  1521. SAFESTRCPY(LicensePack.szInstallId, pSsyncLkp->m_szServerId);
  1522. SAFESTRCPY(LicensePack.szTlsServerName, pSsyncLkp->m_szServerName);
  1523. dwSuccessCount = pSsyncLkp->dwNumServer;
  1524. _AnnounceLicensePackToServers(
  1525. ptr,
  1526. &LicensePack,
  1527. &dwSuccessCount,
  1528. pSsyncLkp->m_szTargetServer,
  1529. pSsyncLkp->m_bSsync
  1530. );
  1531. if(dwSuccessCount != pSsyncLkp->dwNumServer)
  1532. {
  1533. TLSLogInfoEvent(TLS_I_SSYNCLKP_FAILED);
  1534. }
  1535. cleanup:
  1536. if(pDbWkSpace != NULL)
  1537. {
  1538. ReleaseWorkSpace(&pDbWkSpace);
  1539. }
  1540. return dwStatus;
  1541. }
  1542. //----------------------------------------------------------------------------
  1543. DWORD
  1544. _SsyncAllLocalLicensePack(
  1545. IN CSsyncLicensePack* ptr,
  1546. IN PSSYNCLICENSEPACK pSsyncLkp
  1547. )
  1548. /*++
  1549. Sync. all local license pack to a remote server.
  1550. --*/
  1551. {
  1552. DWORD dwStatus = ERROR_SUCCESS;
  1553. PTLSDbWorkSpace pDbWkSpace = NULL;
  1554. TLSLICENSEPACK LicensePackSearch;
  1555. TLSLICENSEPACK LicensePack;
  1556. DWORD dwSuccessCount = 0;
  1557. BOOL SyncStatus[SSYNCLKP_MAX_TARGET];
  1558. //
  1559. // Allocate DB Work Space.
  1560. //
  1561. pDbWkSpace = AllocateWorkSpace(SSYNC_DBWORKSPACE_TIMEOUT);
  1562. if(pDbWkSpace == NULL)
  1563. {
  1564. SetLastError(dwStatus = TLS_I_SSYNCLKP_SERVER_BUSY);
  1565. TLSLogInfoEvent(TLS_I_SSYNCLKP_SERVER_BUSY);
  1566. goto cleanup;
  1567. }
  1568. dwStatus = TLSDBKeyPackEnumBegin(
  1569. pDbWkSpace,
  1570. FALSE,
  1571. 0,
  1572. NULL
  1573. );
  1574. if(dwStatus == ERROR_SUCCESS)
  1575. {
  1576. while((dwStatus = TLSDBKeyPackEnumNext(pDbWkSpace, &LicensePack)) == ERROR_SUCCESS)
  1577. {
  1578. // unreliable, system time between two machine might not work,
  1579. // force sync and let remote server update its data.
  1580. if(CompareFileTime(
  1581. &LicensePack.ftLastModifyTime,
  1582. &ptr->GetWorkData()->m_ftStartSyncTime
  1583. ) < 0)
  1584. {
  1585. continue;
  1586. }
  1587. if(ptr->IsWorkManagerShuttingDown() == TRUE)
  1588. {
  1589. break;
  1590. }
  1591. if(IsLicensePackRepl(&LicensePack) == FALSE)
  1592. {
  1593. continue;
  1594. }
  1595. //
  1596. // Make sure local Server ID and Server Name is correct
  1597. //
  1598. SAFESTRCPY(LicensePack.szInstallId, pSsyncLkp->m_szServerId);
  1599. SAFESTRCPY(LicensePack.szTlsServerName, pSsyncLkp->m_szServerName);
  1600. memset(SyncStatus, 0, sizeof(SyncStatus));
  1601. dwSuccessCount = pSsyncLkp->dwNumServer;
  1602. _AnnounceLicensePackToServers(
  1603. ptr,
  1604. &LicensePack,
  1605. &dwSuccessCount,
  1606. pSsyncLkp->m_szTargetServer,
  1607. SyncStatus
  1608. );
  1609. }
  1610. TLSDBKeyPackEnumEnd(pDbWkSpace);
  1611. }
  1612. //
  1613. // ignore all error
  1614. //
  1615. dwStatus = ERROR_SUCCESS;
  1616. cleanup:
  1617. if(pDbWkSpace != NULL)
  1618. {
  1619. ReleaseWorkSpace(&pDbWkSpace);
  1620. }
  1621. return dwStatus;
  1622. }
  1623. //----------------------------------------------------------------------------
  1624. DWORD
  1625. CSsyncLicensePack::ExecuteJob(
  1626. IN PSSYNCLICENSEPACK pSsyncLkp,
  1627. IN DWORD cbSsyncLkp
  1628. )
  1629. /*++
  1630. Execute a CSsyncLicensePack work object.
  1631. --*/
  1632. {
  1633. DWORD dwStatus = ERROR_SUCCESS;
  1634. DBGPrintf(
  1635. DBG_INFORMATION,
  1636. DBG_FACILITY_JOB,
  1637. DBGLEVEL_FUNCTION_TRACE,
  1638. _TEXT("%s ...\n"),
  1639. GetJobDescription()
  1640. );
  1641. TLSASSERT(pSsyncLkp != NULL && cbSsyncLkp != 0);
  1642. if(VerifyWorkObjectData(FALSE, pSsyncLkp, cbSsyncLkp) == FALSE)
  1643. {
  1644. TLSASSERT(FALSE);
  1645. SetLastError(ERROR_INVALID_DATA);
  1646. pSsyncLkp->bCompleted = TRUE;
  1647. return ERROR_INVALID_DATA;
  1648. }
  1649. if(pSsyncLkp->dwSyncType == SSYNC_ONE_LKP)
  1650. {
  1651. dwStatus = _SsyncOneLocalLicensePack(this, pSsyncLkp);
  1652. }
  1653. else
  1654. {
  1655. dwStatus = _SsyncAllLocalLicensePack(this, pSsyncLkp);
  1656. }
  1657. if(dwStatus == TLS_I_SSYNCLKP_SERVER_BUSY || dwStatus == TLS_I_SSYNCLKP_FAILED)
  1658. {
  1659. // retry operation
  1660. pSsyncLkp->bCompleted = FALSE;
  1661. }
  1662. else
  1663. {
  1664. pSsyncLkp->bCompleted = TRUE;
  1665. }
  1666. DBGPrintf(
  1667. DBG_INFORMATION,
  1668. DBG_FACILITY_JOB,
  1669. DBGLEVEL_FUNCTION_TRACE,
  1670. _TEXT("%s ended...\n"),
  1671. GetJobDescription()
  1672. );
  1673. return dwStatus;
  1674. }
  1675. //--------------------------------------------------------------------------------------
  1676. LPCTSTR
  1677. CSsyncLicensePack::GetJobDescription()
  1678. /*++
  1679. Get CSsyncLicensePack job description, use only
  1680. by debug tracing.
  1681. --*/
  1682. {
  1683. PSSYNCLICENSEPACK pbData = GetWorkData();
  1684. memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
  1685. if(pbData != NULL)
  1686. {
  1687. _sntprintf(
  1688. m_szJobDescription,
  1689. sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1,
  1690. SSYNCLICENSEKEYPACK_DESCRIPTION,
  1691. (pbData->dwSyncType == SSYNC_ALL_LKP) ? _TEXT("ALL") : _TEXT("One"),
  1692. pbData->m_szTargetServer
  1693. );
  1694. }
  1695. return m_szJobDescription;
  1696. }
  1697. //////////////////////////////////////////////////////////////////////////
  1698. //
  1699. // CAnnounceResponse
  1700. //
  1701. //////////////////////////////////////////////////////////////////////////
  1702. BOOL
  1703. CAnnounceResponse::VerifyWorkObjectData(
  1704. IN BOOL bCallByIsValid, // invoke by IsValid() function.
  1705. IN PANNOUNCERESPONSEWO pbData,
  1706. IN DWORD cbData
  1707. )
  1708. /*++
  1709. Verify CAnnounceResponse work object data.
  1710. --*/
  1711. {
  1712. BOOL bSuccess = TRUE;
  1713. DWORD dwLen;
  1714. if(pbData == NULL || cbData == 0 || cbData != pbData->dwStructSize)
  1715. {
  1716. bSuccess = FALSE;
  1717. }
  1718. if(bSuccess == TRUE)
  1719. {
  1720. pbData->m_szTargetServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  1721. dwLen = _tcslen(pbData->m_szTargetServerId);
  1722. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE + 1)
  1723. {
  1724. bSuccess = FALSE;
  1725. }
  1726. }
  1727. if(bSuccess == FALSE)
  1728. {
  1729. TLSASSERT(FALSE);
  1730. SetLastError(ERROR_INVALID_DATA);
  1731. }
  1732. return bSuccess;
  1733. }
  1734. //------------------------------------------------------------------------
  1735. BOOL
  1736. CAnnounceResponse::CopyWorkObjectData(
  1737. OUT PANNOUNCERESPONSEWO* ppbDest,
  1738. OUT PDWORD pcbDest,
  1739. IN PANNOUNCERESPONSEWO pbSrc,
  1740. IN DWORD cbSrc
  1741. )
  1742. /*++
  1743. Copy CAnnounceResponse work object data.
  1744. --*/
  1745. {
  1746. DWORD dwStatus = ERROR_SUCCESS;
  1747. if(ppbDest == NULL || pcbDest == NULL)
  1748. {
  1749. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  1750. TLSASSERT(FALSE);
  1751. goto cleanup;
  1752. }
  1753. if(CopyBinaryData(
  1754. (PBYTE *)ppbDest,
  1755. pcbDest,
  1756. (PBYTE) pbSrc,
  1757. cbSrc
  1758. ) == FALSE)
  1759. {
  1760. dwStatus = GetLastError();
  1761. }
  1762. cleanup:
  1763. return dwStatus == ERROR_SUCCESS;
  1764. }
  1765. //---------------------------------------------------------------------------
  1766. BOOL
  1767. CAnnounceResponse::CleanupWorkObjectData(
  1768. IN OUT PANNOUNCERESPONSEWO* ppbData,
  1769. IN OUT PDWORD pcbData
  1770. )
  1771. /*++
  1772. cleanup CAnnounceResponse work object data.
  1773. --*/
  1774. {
  1775. if(ppbData != NULL && pcbData != NULL)
  1776. {
  1777. FreeMemory(*ppbData);
  1778. *ppbData = NULL;
  1779. *pcbData = 0;
  1780. }
  1781. return TRUE;
  1782. }
  1783. //---------------------------------------------------------------------------
  1784. BOOL
  1785. CAnnounceResponse::IsJobCompleted(
  1786. IN PANNOUNCERESPONSEWO pbData,
  1787. IN DWORD cbData
  1788. )
  1789. /*++
  1790. Detemine if job completed.
  1791. --*/
  1792. {
  1793. return (pbData == NULL) ? TRUE : pbData->bCompleted;
  1794. }
  1795. //---------------------------------------------------------------------------
  1796. DWORD
  1797. CAnnounceResponse::ExecuteJob(
  1798. IN PANNOUNCERESPONSEWO pbData,
  1799. IN DWORD cbData
  1800. )
  1801. /*++
  1802. Execute a CAnnounceResponse work object.
  1803. --*/
  1804. {
  1805. DWORD dwStatus = ERROR_SUCCESS;
  1806. TLS_HANDLE hHandle = NULL;
  1807. DBGPrintf(
  1808. DBG_INFORMATION,
  1809. DBG_FACILITY_JOB,
  1810. DBGLEVEL_FUNCTION_TRACE,
  1811. _TEXT("%s ...\n"),
  1812. GetJobDescription()
  1813. );
  1814. TLServerInfo ServerInfo;
  1815. dwStatus = TLSLookupRegisteredServer(
  1816. pbData->m_szTargetServerId,
  1817. NULL,
  1818. NULL,
  1819. &ServerInfo
  1820. );
  1821. if(dwStatus == ERROR_SUCCESS)
  1822. {
  1823. DBGPrintf(
  1824. DBG_INFORMATION,
  1825. DBG_FACILITY_JOB,
  1826. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1827. _TEXT("Announcing server to %s...\n"),
  1828. ServerInfo.GetServerName()
  1829. );
  1830. if(IsWorkManagerShuttingDown() == FALSE)
  1831. {
  1832. dwStatus = TLSAnnounceServerToRemoteServer(
  1833. TLSANNOUNCE_TYPE_RESPONSE,
  1834. ServerInfo.GetServerId(),
  1835. ServerInfo.GetServerDomain(),
  1836. ServerInfo.GetServerName(),
  1837. pbData->m_szLocalServerId,
  1838. pbData->m_szLocalScope,
  1839. pbData->m_szLocalServerName,
  1840. &(pbData->m_ftLastShutdownTime)
  1841. );
  1842. }
  1843. }
  1844. else
  1845. {
  1846. TLSASSERT(FALSE);
  1847. }
  1848. //
  1849. // Discovery run once
  1850. //
  1851. pbData->bCompleted = TRUE;
  1852. DBGPrintf(
  1853. DBG_INFORMATION,
  1854. DBG_FACILITY_JOB,
  1855. DBGLEVEL_FUNCTION_TRACE,
  1856. _TEXT("%s ended...\n"),
  1857. GetJobDescription()
  1858. );
  1859. return dwStatus;
  1860. }
  1861. //----------------------------------------------------------------------------------------------
  1862. LPCTSTR
  1863. CAnnounceResponse::GetJobDescription()
  1864. /*++
  1865. Retrieve CAnnounceResponse job description.
  1866. --*/
  1867. {
  1868. memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
  1869. PANNOUNCERESPONSEWO pbData = GetWorkData();
  1870. if(pbData != NULL)
  1871. {
  1872. _sntprintf(
  1873. m_szJobDescription,
  1874. sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1,
  1875. ANNOUNCERESPONSE_DESCRIPTION,
  1876. pbData->m_szTargetServerId
  1877. );
  1878. }
  1879. return m_szJobDescription;
  1880. }