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.

898 lines
27 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File: permlic.cpp
  7. //
  8. // Contents:
  9. // Issue perm. license to client
  10. //
  11. // History:
  12. // Feb 4, 98 HueiWang Created
  13. //---------------------------------------------------------------------------
  14. #include "pch.cpp"
  15. #include "globals.h"
  16. #include "permlic.h"
  17. #include "misc.h"
  18. #include "db.h"
  19. #include "clilic.h"
  20. #include "findlost.h"
  21. #include <winsta.h>
  22. #define STRSAFE_NO_DEPRECATE
  23. #include <strsafe.h>
  24. DWORD
  25. GenerateRandomNumber(
  26. IN DWORD Seed
  27. );
  28. void
  29. LicensedProductToDbLicensedProduct(
  30. PLICENSEDPRODUCT pSrc,
  31. PTLSDBLICENSEDPRODUCT pDest
  32. );
  33. void
  34. CopyDbLicensedProduct(
  35. PTLSDBLICENSEDPRODUCT pSrc,
  36. PTLSDBLICENSEDPRODUCT pDest
  37. );
  38. //-------------------------------------------------------------------------
  39. //
  40. // Memory leak at service shutdown time
  41. //
  42. typedef struct __LoggedLowLicenseProduct {
  43. LPTSTR pszCompanyName;
  44. LPTSTR pszProductId;
  45. DWORD dwProductVersion;
  46. __LoggedLowLicenseProduct() : pszProductId(NULL), pszCompanyName(NULL) {};
  47. friend bool
  48. operator<(
  49. const __LoggedLowLicenseProduct&,
  50. const __LoggedLowLicenseProduct&
  51. );
  52. } LoggedLowLicenseProduct;
  53. //-------------------------------------------------------------------------
  54. inline bool
  55. operator<(
  56. const __LoggedLowLicenseProduct& a,
  57. const __LoggedLowLicenseProduct& b
  58. )
  59. /*++
  60. --*/
  61. {
  62. bool bStatus;
  63. TLSASSERT(a.pszCompanyName != NULL && b.pszCompanyName != NULL);
  64. TLSASSERT(a.pszProductId != NULL && b.pszProductId != NULL);
  65. // in case we mess up...
  66. if(a.pszProductId == NULL || a.pszCompanyName == NULL)
  67. {
  68. bStatus = TRUE;
  69. }
  70. else if(b.pszProductId == NULL || b.pszCompanyName == NULL)
  71. {
  72. bStatus = FALSE;
  73. }
  74. else
  75. {
  76. bStatus = (_tcsicmp(a.pszCompanyName, b.pszCompanyName) < 0);
  77. if(bStatus == TRUE)
  78. {
  79. bStatus = (_tcsicmp(a.pszProductId, b.pszProductId) < 0);
  80. }
  81. if(bStatus == TRUE)
  82. {
  83. bStatus = (CompareTLSVersions(a.dwProductVersion, b.dwProductVersion) < 0);
  84. }
  85. }
  86. return bStatus;
  87. }
  88. //-------------------------------------------------------------------------
  89. typedef map<
  90. LoggedLowLicenseProduct,
  91. BOOL,
  92. less<LoggedLowLicenseProduct>
  93. > LOGLOWLICENSEMAP;
  94. static CCriticalSection LogLock;
  95. static LOGLOWLICENSEMAP LowLicenseLog;
  96. //---------------------------------------------------------------
  97. void
  98. TLSResetLogLowLicenseWarning(
  99. IN LPTSTR pszCompanyName,
  100. IN LPTSTR pszProductId,
  101. IN DWORD dwProductVersion,
  102. IN BOOL bLogged
  103. )
  104. /*++
  105. --*/
  106. {
  107. LOGLOWLICENSEMAP::iterator it;
  108. LoggedLowLicenseProduct product;
  109. product.pszCompanyName = pszCompanyName;
  110. product.pszProductId = pszProductId;
  111. product.dwProductVersion = dwProductVersion;
  112. LogLock.Lock();
  113. it = LowLicenseLog.find(product);
  114. if(it != LowLicenseLog.end())
  115. {
  116. // reset to not logged warning yet.
  117. (*it).second = bLogged;
  118. }
  119. else if(bLogged == TRUE)
  120. {
  121. memset(&product, 0, sizeof(product));
  122. // memory leak here at service stop.
  123. product.pszProductId = _tcsdup(pszProductId);
  124. product.pszCompanyName = _tcsdup(pszCompanyName);
  125. product.dwProductVersion = dwProductVersion;
  126. if(product.pszProductId != NULL && product.pszCompanyName != NULL)
  127. {
  128. LowLicenseLog[product] = TRUE;
  129. }
  130. else
  131. {
  132. // if unable to allocate any more memory, log message every time
  133. if(product.pszProductId != NULL)
  134. {
  135. free(product.pszProductId);
  136. }
  137. if(product.pszCompanyName != NULL)
  138. {
  139. free(product.pszCompanyName);
  140. }
  141. }
  142. }
  143. LogLock.UnLock();
  144. return;
  145. }
  146. //---------------------------------------------------------------
  147. void
  148. TLSLogLowLicenseWarning(
  149. IN PTLSDbWorkSpace pDbWkSpace,
  150. IN PTLSDBLICENSEREQUEST pRequest,
  151. IN BOOL bNoLicense
  152. )
  153. /*++
  154. Abstract:
  155. Log an low license count warning.
  156. Parameter:
  157. pDbWkSpace - Workspace handle.
  158. pRequest - License Request.
  159. Workspace - No license available.
  160. LicensePack - License pack that is out of license
  161. return:
  162. None
  163. --*/
  164. {
  165. LOGLOWLICENSEMAP::iterator it;
  166. BOOL bWarningLogged = FALSE;
  167. DWORD dwStatus;
  168. if( pRequest == NULL || pRequest->pClientLicenseRequest == NULL ||
  169. pRequest->pClientLicenseRequest->pszProductId == NULL )
  170. {
  171. TLSASSERT(FALSE);
  172. return;
  173. }
  174. LoggedLowLicenseProduct product;
  175. product.pszProductId = pRequest->pClientLicenseRequest->pszProductId;
  176. product.pszCompanyName = pRequest->pClientLicenseRequest->pszCompanyName;
  177. product.dwProductVersion = pRequest->pClientLicenseRequest->dwProductVersion;
  178. LogLock.Lock();
  179. // see if we already log this warning message
  180. it = LowLicenseLog.find(product);
  181. if(it == LowLicenseLog.end())
  182. {
  183. memset(&product, 0, sizeof(product));
  184. // memory leak here at service stop.
  185. product.pszProductId = _tcsdup(pRequest->pClientLicenseRequest->pszProductId);
  186. product.pszCompanyName = _tcsdup(pRequest->pClientLicenseRequest->pszCompanyName);
  187. product.dwProductVersion = pRequest->pClientLicenseRequest->dwProductVersion;
  188. if(product.pszProductId != NULL && product.pszCompanyName != NULL)
  189. {
  190. LowLicenseLog[product] = TRUE;
  191. }
  192. else
  193. {
  194. // if unable to allocate any more memory, log message every time
  195. if(product.pszProductId != NULL)
  196. {
  197. free(product.pszProductId);
  198. }
  199. if(product.pszCompanyName != NULL)
  200. {
  201. free(product.pszCompanyName);
  202. }
  203. }
  204. }
  205. else
  206. {
  207. bWarningLogged = (*it).second;
  208. (*it).second = TRUE;
  209. }
  210. LogLock.UnLock();
  211. if(bWarningLogged == TRUE)
  212. {
  213. return;
  214. }
  215. //
  216. // ask policy module if they have description
  217. //
  218. PMKEYPACKDESCREQ kpDescReq;
  219. PPMKEYPACKDESC pKpDesc;
  220. //
  221. // Ask for default system language ID
  222. //
  223. kpDescReq.pszProductId = pRequest->pszProductId;
  224. kpDescReq.dwLangId = GetSystemDefaultLangID();
  225. kpDescReq.dwVersion = pRequest->dwProductVersion;
  226. pKpDesc = NULL;
  227. dwStatus = pRequest->pPolicy->PMLicenseRequest(
  228. pRequest->hClient,
  229. REQUEST_KEYPACKDESC,
  230. (PVOID)&kpDescReq,
  231. (PVOID *)&pKpDesc
  232. );
  233. if(dwStatus != ERROR_SUCCESS || pKpDesc == NULL)
  234. {
  235. if(GetSystemDefaultLangID() != MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US))
  236. {
  237. // see if we have any US desc.
  238. kpDescReq.dwLangId = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
  239. pKpDesc = NULL;
  240. dwStatus = pRequest->pPolicy->PMLicenseRequest(
  241. pRequest->hClient,
  242. REQUEST_KEYPACKDESC,
  243. (PVOID)&kpDescReq,
  244. (PVOID *)&pKpDesc
  245. );
  246. }
  247. }
  248. LPCTSTR pString[2];
  249. pString[0] = g_szComputerName;
  250. pString[1] = (dwStatus == ERROR_SUCCESS && pKpDesc != NULL) ? pKpDesc->szProductDesc :
  251. pRequest->pClientLicenseRequest->pszProductId;
  252. TLSLogEventString(
  253. EVENTLOG_WARNING_TYPE,
  254. (bNoLicense == TRUE) ? TLS_W_NOPERMLICENSE : TLS_W_PRODUCTNOTINSTALL,
  255. sizeof(pString)/sizeof(pString[0]),
  256. pString
  257. );
  258. return;
  259. }
  260. //--------------------------------------------------------------------------------
  261. DWORD
  262. TLSDBIssuePermanentLicense(
  263. IN PTLSDbWorkSpace pDbWkSpace,
  264. IN PTLSDBLICENSEREQUEST pRequest,
  265. IN BOOL bLatestVersion,
  266. IN BOOL bAcceptFewerLicenses,
  267. IN OUT DWORD *pdwQuantity,
  268. IN OUT PTLSDBLICENSEDPRODUCT pLicensedProduct,
  269. IN DWORD dwSupportFlags
  270. )
  271. /*
  272. Abstract:
  273. Routine to allocate a perm. license.
  274. Parameters:
  275. pDbWkSpace - Workspace handle.
  276. pRequest - license request.
  277. bLatestVersion - Request latest version (unused)
  278. bAcceptFewerLicenses - TRUE if succeeding with fewer licenses than
  279. requested is acceptable
  280. pdwQuantity - on input, number of licenses to allocate. on output,
  281. number of licenses actually allocated
  282. IN OUT pLicensedProduct - licensed product
  283. dwSupportFlags - abilities supported by TS and LS.
  284. Returns:
  285. */
  286. {
  287. DWORD status=ERROR_SUCCESS;
  288. ULARGE_INTEGER ulSerialNumber;
  289. DWORD dwLicenseId;
  290. TLSLICENSEPACK LicensePack;
  291. UCHAR ucKeyPackStatus;
  292. LICENSEDCLIENT issuedLicense;
  293. DWORD CertSerialNumber;
  294. PMGENERATELICENSE PolModGenLicense;
  295. PPMCERTEXTENSION pPolModCertExtension=NULL;
  296. FILETIME notBefore, notAfter;
  297. UCHAR ucAgreementType;
  298. memset(&ulSerialNumber, 0, sizeof(ulSerialNumber));
  299. //----------------------------------------------------------------------
  300. //
  301. // this step require reduce available license by dwQuantity
  302. //
  303. status=TLSDBGetPermanentLicense(
  304. pDbWkSpace,
  305. pRequest,
  306. bAcceptFewerLicenses,
  307. pdwQuantity,
  308. bLatestVersion,
  309. &LicensePack
  310. );
  311. if(status != ERROR_SUCCESS)
  312. {
  313. if(status == TLS_E_NO_LICENSE || status == TLS_E_PRODUCT_NOTINSTALL)
  314. {
  315. TLSLogLowLicenseWarning(
  316. pDbWkSpace,
  317. pRequest,
  318. (status == TLS_E_NO_LICENSE)
  319. );
  320. }
  321. goto cleanup;
  322. }
  323. ucKeyPackStatus = (LicensePack.ucKeyPackStatus & ~LSKEYPACKSTATUS_RESERVED);
  324. if( ucKeyPackStatus != LSKEYPACKSTATUS_PENDING &&
  325. ucKeyPackStatus != LSKEYPACKSTATUS_ACTIVE )
  326. {
  327. SetLastError(status = TLS_E_INTERNAL);
  328. goto cleanup;
  329. }
  330. ucAgreementType = (LicensePack.ucAgreementType & ~ LSKEYPACK_RESERVED_TYPE);
  331. if( ucAgreementType != LSKEYPACKTYPE_SELECT &&
  332. ucAgreementType != LSKEYPACKTYPE_RETAIL &&
  333. ucAgreementType != LSKEYPACKTYPE_FREE &&
  334. ucAgreementType != LSKEYPACKTYPE_OPEN )
  335. {
  336. SetLastError(status = TLS_E_INTERNAL);
  337. goto cleanup;
  338. }
  339. //
  340. // for pending activation keypack, we still
  341. // issue permanent license and rely
  342. // on revoke key pack list to invalidate licenses.
  343. //
  344. dwLicenseId=TLSDBGetNextLicenseId();
  345. //
  346. // Reset status
  347. //
  348. status = ERROR_SUCCESS;
  349. //
  350. // Formuate license serial number
  351. //
  352. ulSerialNumber.LowPart = dwLicenseId;
  353. ulSerialNumber.HighPart = LicensePack.dwKeyPackId;
  354. // Update License Table Here
  355. memset(&issuedLicense, 0, sizeof(LICENSEDCLIENT));
  356. issuedLicense.dwLicenseId = dwLicenseId;
  357. issuedLicense.dwKeyPackId = LicensePack.dwKeyPackId;
  358. issuedLicense.dwKeyPackLicenseId = LicensePack.dwNextSerialNumber;
  359. issuedLicense.dwSystemBiosChkSum = pRequest->hWid.dwPlatformID;
  360. issuedLicense.dwVideoBiosChkSum = pRequest->hWid.Data1;
  361. issuedLicense.dwFloppyBiosChkSum = pRequest->hWid.Data2;
  362. issuedLicense.dwHardDiskSize = pRequest->hWid.Data3;
  363. issuedLicense.dwRamSize = pRequest->hWid.Data4;
  364. issuedLicense.dwNumLicenses = *pdwQuantity;
  365. issuedLicense.ftIssueDate = time(NULL);
  366. StringCbCopy(issuedLicense.szMachineName, sizeof(issuedLicense.szMachineName), pRequest->szMachineName);
  367. StringCbCopy(issuedLicense.szUserName, sizeof(issuedLicense.szUserName), pRequest->szUserName);
  368. if ((dwSupportFlags & SUPPORT_PER_SEAT_REISSUANCE) &&
  369. ((_tcsnicmp(LicensePack.szProductId, TERMSERV_PRODUCTID_SKU,
  370. _tcslen(TERMSERV_PRODUCTID_SKU)) == 0) ||
  371. (_tcsnicmp(LicensePack.szProductId, TERMSERV_PRODUCTID_CONCURRENT_SKU,
  372. _tcslen(TERMSERV_PRODUCTID_CONCURRENT_SKU)) == 0)) &&
  373. ((LicensePack.ucAgreementType == LSKEYPACKTYPE_SELECT) ||
  374. (LicensePack.ucAgreementType == LSKEYPACKTYPE_RETAIL) ||
  375. (LicensePack.ucAgreementType == LSKEYPACKTYPE_OPEN)))
  376. {
  377. DWORD dwRange;
  378. dwRange = GenerateRandomNumber(GetCurrentThreadId()) %
  379. g_dwReissueLeaseRange;
  380. issuedLicense.ftExpireDate = ((DWORD)time(NULL)) +
  381. g_dwReissueLeaseMinimum + dwRange;
  382. }
  383. else
  384. {
  385. issuedLicense.ftExpireDate = PERMANENT_LICENSE_EXPIRE_DATE;
  386. }
  387. issuedLicense.ucLicenseStatus =
  388. (LicensePack.ucKeyPackStatus == LSKEYPACKSTATUS_PENDING) ?
  389. LSLICENSE_STATUS_PENDING : LSLICENSE_STATUS_ACTIVE;
  390. UnixTimeToFileTime(LicensePack.dwActivateDate, &notBefore);
  391. UnixTimeToFileTime(issuedLicense.ftExpireDate, &notAfter);
  392. //
  393. // Inform Policy Module of license issued.
  394. //
  395. if(pRequest->pPolicy)
  396. {
  397. PolModGenLicense.dwKeyPackType = LicensePack.ucAgreementType;
  398. PolModGenLicense.pLicenseRequest = pRequest->pPolicyLicenseRequest;
  399. PolModGenLicense.dwKeyPackId = LicensePack.dwKeyPackId;;
  400. PolModGenLicense.dwKeyPackLicenseId = LicensePack.dwNextSerialNumber;
  401. PolModGenLicense.ClientLicenseSerialNumber = ulSerialNumber;
  402. PolModGenLicense.ftNotBefore = notBefore;
  403. PolModGenLicense.ftNotAfter = notAfter;
  404. status = pRequest->pPolicy->PMLicenseRequest(
  405. pRequest->hClient,
  406. REQUEST_GENLICENSE,
  407. (PVOID)&PolModGenLicense,
  408. (PVOID *)&pPolModCertExtension
  409. );
  410. if(status != ERROR_SUCCESS)
  411. {
  412. //
  413. // Error in policy module
  414. //
  415. goto cleanup;
  416. }
  417. }
  418. //
  419. // Check error return from policy module
  420. //
  421. if(pPolModCertExtension != NULL)
  422. {
  423. if(pPolModCertExtension->pbData != NULL &&
  424. pPolModCertExtension->cbData == 0 ||
  425. pPolModCertExtension->pbData == NULL &&
  426. pPolModCertExtension->cbData != 0 )
  427. {
  428. // assuming no extension data
  429. pPolModCertExtension->cbData = 0;
  430. pPolModCertExtension->pbData = NULL;
  431. }
  432. if(CompareFileTime( &(pPolModCertExtension->ftNotBefore),
  433. &(pPolModCertExtension->ftNotAfter)) > 0)
  434. {
  435. //
  436. // invalid data return from policy module
  437. //
  438. TLSLogEvent(
  439. EVENTLOG_ERROR_TYPE,
  440. TLS_E_GENERATECLIENTELICENSE,
  441. status = TLS_E_POLICYMODULEERROR,
  442. pRequest->pPolicy->GetCompanyName(),
  443. pRequest->pPolicy->GetProductId()
  444. );
  445. goto cleanup;
  446. }
  447. if( FileTimeToLicenseDate(&(pPolModCertExtension->ftNotBefore), &issuedLicense.ftIssueDate) == FALSE ||
  448. FileTimeToLicenseDate(&(pPolModCertExtension->ftNotAfter), &issuedLicense.ftExpireDate) == FALSE )
  449. {
  450. //
  451. // Invalid data return from policy module
  452. //
  453. TLSLogEvent(
  454. EVENTLOG_ERROR_TYPE,
  455. TLS_E_GENERATECLIENTELICENSE,
  456. status = TLS_E_POLICYMODULEERROR,
  457. pRequest->pPolicy->GetCompanyName(),
  458. pRequest->pPolicy->GetProductId()
  459. );
  460. goto cleanup;
  461. }
  462. notBefore = pPolModCertExtension->ftNotBefore;
  463. notAfter = pPolModCertExtension->ftNotAfter;
  464. }
  465. //
  466. // Add license into license table
  467. //
  468. status=TLSDBLicenseAdd(
  469. pDbWkSpace,
  470. &issuedLicense,
  471. 0,
  472. NULL
  473. );
  474. if(status != ERROR_SUCCESS)
  475. {
  476. goto cleanup;
  477. }
  478. //
  479. // Return licensed product
  480. //
  481. pLicensedProduct->pSubjectPublicKeyInfo = NULL;
  482. pLicensedProduct->dwQuantity = *pdwQuantity;
  483. pLicensedProduct->ulSerialNumber = ulSerialNumber;
  484. pLicensedProduct->dwKeyPackId = LicensePack.dwKeyPackId;
  485. pLicensedProduct->dwLicenseId = dwLicenseId;
  486. pLicensedProduct->dwKeyPackLicenseId = LicensePack.dwNextSerialNumber;
  487. pLicensedProduct->dwNumLicenseLeft = LicensePack.dwNumberOfLicenses;
  488. pLicensedProduct->ClientHwid = pRequest->hWid;
  489. pLicensedProduct->bTemp = FALSE;
  490. pLicensedProduct->NotBefore = notBefore;
  491. pLicensedProduct->NotAfter = notAfter;
  492. pLicensedProduct->dwProductVersion = MAKELONG(LicensePack.wMinorVersion, LicensePack.wMajorVersion);
  493. StringCbCopy(pLicensedProduct->szUserName, sizeof(pLicensedProduct->szUserName), pRequest->szUserName);
  494. StringCbCopy(pLicensedProduct->szMachineName, sizeof(pLicensedProduct->szMachineName), pRequest->szMachineName);
  495. StringCbCopy(pLicensedProduct->szCompanyName, sizeof(pLicensedProduct->szCompanyName), LicensePack.szCompanyName);
  496. StringCbCopy(pLicensedProduct->szLicensedProductId, sizeof(pLicensedProduct->szLicensedProductId), LicensePack.szProductId);
  497. StringCbCopy(pLicensedProduct->szRequestProductId, sizeof(pLicensedProduct->szRequestProductId), pRequest->pClientLicenseRequest->pszProductId);
  498. pLicensedProduct->dwLanguageID = pRequest->dwLanguageID;
  499. pLicensedProduct->dwPlatformID = pRequest->dwPlatformID;
  500. pLicensedProduct->pbPolicyData = (pPolModCertExtension) ? pPolModCertExtension->pbData : NULL;
  501. pLicensedProduct->cbPolicyData = (pPolModCertExtension) ? pPolModCertExtension->cbData : 0;
  502. cleanup:
  503. return status;
  504. }
  505. DWORD
  506. TLSDBReissuePermanentLicense(
  507. IN PTLSDbWorkSpace pDbWkSpace,
  508. IN PLICENSEDPRODUCT pExpiredLicense,
  509. IN OUT PTLSDBLICENSEDPRODUCT pReissuedLicense
  510. )
  511. /*++
  512. Abstract:
  513. Searches for the expired license in the database and, if found, resets
  514. the expiration and returns the modified license.
  515. Parameters:
  516. Returns:
  517. --*/
  518. {
  519. TLSDBLICENSEDPRODUCT LicensedProduct;
  520. LicensedProductToDbLicensedProduct(pExpiredLicense,&LicensedProduct);
  521. return TLSDBReissueFoundPermanentLicense(pDbWkSpace,
  522. &LicensedProduct,
  523. pReissuedLicense);
  524. }
  525. DWORD
  526. TLSDBReissueFoundPermanentLicense(
  527. IN PTLSDbWorkSpace pDbWkSpace,
  528. IN PTLSDBLICENSEDPRODUCT pExpiredLicense,
  529. IN OUT PTLSDBLICENSEDPRODUCT pReissuedLicense
  530. )
  531. /*++
  532. Abstract:
  533. Searches for the expired license in the database and, if found, resets
  534. the expiration and returns the modified license.
  535. Parameters:
  536. Returns:
  537. --*/
  538. {
  539. DWORD dwStatus;
  540. LICENSEDCLIENT License;
  541. ASSERT(pDbWkSpace != NULL);
  542. ASSERT(pExpiredLicense != NULL);
  543. ASSERT(pReissuedLicense != NULL);
  544. dwStatus = TLSFindDbLicensedProduct(pExpiredLicense, &License);
  545. if (dwStatus == ERROR_SUCCESS)
  546. {
  547. DWORD dwRange;
  548. dwRange = GenerateRandomNumber(GetCurrentThreadId()) %
  549. g_dwReissueLeaseRange;
  550. License.ftExpireDate = ((DWORD)time(NULL)) +
  551. g_dwReissueLeaseMinimum + dwRange;
  552. TLSDBLockLicenseTable();
  553. dwStatus = TLSDBLicenseUpdateEntry(
  554. USEHANDLE(pDbWkSpace),
  555. LSLICENSE_SEARCH_EXPIREDATE,
  556. &License,
  557. FALSE
  558. );
  559. TLSDBUnlockLicenseTable();
  560. }
  561. if (dwStatus == ERROR_SUCCESS)
  562. {
  563. CopyDbLicensedProduct(pExpiredLicense, pReissuedLicense);
  564. UnixTimeToFileTime(License.ftExpireDate, &(pReissuedLicense->NotAfter));
  565. pReissuedLicense->pSubjectPublicKeyInfo = NULL;
  566. }
  567. return(dwStatus);
  568. }
  569. //+------------------------------------------------------------------------
  570. DWORD
  571. TLSDBGetPermanentLicense(
  572. IN PTLSDbWorkSpace pDbWkSpace,
  573. IN PTLSDBLICENSEREQUEST pRequest,
  574. IN BOOL bAcceptFewerLicenses,
  575. IN OUT DWORD *pdwQuantity,
  576. IN BOOL bLatestVersion,
  577. IN OUT PTLSLICENSEPACK pLicensePack
  578. )
  579. /*++
  580. Abstract:
  581. Allocate a permanent license from database.
  582. Parameters:
  583. pDbWkSpace : workspace handle.
  584. pRequest : product to be request.
  585. bAcceptFewerLicenses - TRUE if succeeding with fewer licenses than
  586. requested is acceptable
  587. pdwQuantity - on input, number of licenses to allocate. on output,
  588. number of licenses actually allocated
  589. bLatestversion : latest version (unused).
  590. pLicensePack : license pack where license is allocated.
  591. Returns:
  592. ++*/
  593. {
  594. DWORD dwStatus = ERROR_SUCCESS;
  595. TLSDBLicenseAllocation allocated;
  596. TLSDBAllocateRequest AllocateRequest;
  597. TLSLICENSEPACK LicenseKeyPack;
  598. DWORD dwTotalAllocated = 0;
  599. BOOL fRetried = FALSE;
  600. DWORD dwSearchedType = 0;
  601. DWORD dwSuggestType;
  602. DWORD dwPMAdjustedType = LSKEYPACKTYPE_UNKNOWN;
  603. DWORD dwLocalType = LSKEYPACKTYPE_UNKNOWN;
  604. POLICY_TS_MACHINE groupPolicy;
  605. RegGetMachinePolicy(&groupPolicy);
  606. #define NUM_KEYPACKS 5
  607. DWORD dwAllocation[NUM_KEYPACKS];
  608. TLSLICENSEPACK keypack[NUM_KEYPACKS];
  609. for (int i=0; i < NUM_KEYPACKS; i++)
  610. {
  611. keypack[i].pbDomainSid = NULL;
  612. }
  613. AllocateRequest.szCompanyName = (LPTSTR)pRequest->pszCompanyName;
  614. AllocateRequest.szProductId = (LPTSTR)pRequest->pszProductId;
  615. AllocateRequest.dwVersion = pRequest->dwProductVersion;
  616. AllocateRequest.dwPlatformId = pRequest->dwPlatformID;
  617. AllocateRequest.dwLangId = pRequest->dwLanguageID;
  618. AllocateRequest.dwNumLicenses = *pdwQuantity;
  619. if( groupPolicy.fPolicyPreventLicenseUpgrade == 1 && groupPolicy.fPreventLicenseUpgrade == 1)
  620. {
  621. AllocateRequest.dwScheme = ALLOCATE_EXACT_VERSION;
  622. }
  623. else
  624. {
  625. AllocateRequest.dwScheme = ALLOCATE_ANY_GREATER_VERSION;
  626. }
  627. memset(&allocated, 0, sizeof(allocated));
  628. retry_search:
  629. do {
  630. allocated.dwBufSize = NUM_KEYPACKS;
  631. allocated.pdwAllocationVector = dwAllocation;
  632. allocated.lpAllocateKeyPack = keypack;
  633. dwSuggestType = dwLocalType;
  634. dwStatus = pRequest->pPolicy->PMLicenseRequest(
  635. pRequest->hClient,
  636. REQUEST_KEYPACKTYPE,
  637. UlongToPtr(dwSuggestType),
  638. (PVOID *)&dwPMAdjustedType
  639. );
  640. if(dwStatus != ERROR_SUCCESS)
  641. break;
  642. dwLocalType = (dwPMAdjustedType & ~LSKEYPACK_RESERVED_TYPE);
  643. if(dwLocalType > LSKEYPACKTYPE_LAST)
  644. {
  645. TLSLogEvent(
  646. EVENTLOG_ERROR_TYPE,
  647. TLS_E_GENERATECLIENTELICENSE,
  648. dwStatus = TLS_E_POLICYMODULEERROR,
  649. pRequest->pPolicy->GetCompanyName(),
  650. pRequest->pPolicy->GetProductId()
  651. );
  652. break;
  653. }
  654. if(dwSearchedType & (0x1 << dwLocalType))
  655. {
  656. //
  657. // we already went thru this license pack, policy module error
  658. //
  659. TLSLogEvent(
  660. EVENTLOG_ERROR_TYPE,
  661. TLS_E_GENERATECLIENTELICENSE,
  662. dwStatus = TLS_E_POLICYMODULERECURSIVE,
  663. pRequest->pPolicy->GetCompanyName(),
  664. pRequest->pPolicy->GetProductId()
  665. );
  666. break;
  667. }
  668. dwSearchedType |= (0x1 << dwLocalType);
  669. AllocateRequest.ucAgreementType = dwPMAdjustedType;
  670. dwStatus = AllocateLicensesFromDB(
  671. pDbWkSpace,
  672. &AllocateRequest,
  673. TRUE, // fCheckAgreementType
  674. &allocated
  675. );
  676. if(dwStatus == ERROR_SUCCESS)
  677. {
  678. //
  679. // successfully allocate a license
  680. //
  681. dwTotalAllocated += allocated.dwTotalAllocated;
  682. if (dwTotalAllocated >= *pdwQuantity)
  683. {
  684. break;
  685. }
  686. else
  687. {
  688. AllocateRequest.dwNumLicenses -= allocated.dwTotalAllocated;
  689. continue;
  690. }
  691. }
  692. if(dwStatus != TLS_I_NO_MORE_DATA && dwStatus != TLS_E_PRODUCT_NOTINSTALL)
  693. {
  694. //
  695. // error occurred in AllocateLicenseFromDB()
  696. //
  697. break;
  698. }
  699. } while(dwLocalType != LSKEYPACKTYPE_UNKNOWN);
  700. if ((!fRetried)
  701. && (dwTotalAllocated < *pdwQuantity)
  702. && (AllocateRequest.dwScheme == ALLOCATE_ANY_GREATER_VERSION)
  703. && (LOWORD(AllocateRequest.dwVersion) == 0))
  704. {
  705. //
  706. // Not enough 5.0 licenses found. Try again with 5.1 licenses.
  707. //
  708. fRetried = TRUE;
  709. dwLocalType = LSKEYPACKTYPE_UNKNOWN;
  710. dwPMAdjustedType = LSKEYPACKTYPE_UNKNOWN;
  711. dwSearchedType = 0;
  712. AllocateRequest.dwVersion |= 1;
  713. AllocateRequest.szProductId[7] = L'1';
  714. goto retry_search;
  715. }
  716. if ((dwTotalAllocated == 0)
  717. || (!bAcceptFewerLicenses &&
  718. ((dwTotalAllocated < *pdwQuantity))))
  719. {
  720. // Failing to commit will return all licenses allocated so far
  721. SetLastError(dwStatus = TLS_E_NO_LICENSE);
  722. }
  723. else if ((dwTotalAllocated != 0) && bAcceptFewerLicenses)
  724. {
  725. dwStatus = ERROR_SUCCESS;
  726. }
  727. if(dwStatus == ERROR_SUCCESS)
  728. {
  729. //
  730. // LicenseKeyPack return via TLSDBLicenseAllocation structure
  731. //
  732. *pLicensePack = keypack[0];
  733. *pdwQuantity = dwTotalAllocated;
  734. }
  735. return dwStatus;
  736. }