893 lines
25 KiB
C++
893 lines
25 KiB
C++
//+--------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996-1998
|
|
//
|
|
// File: permlic.cpp
|
|
//
|
|
// Contents:
|
|
// Issue perm. license to client
|
|
//
|
|
// History:
|
|
// Feb 4, 98 HueiWang Created
|
|
//---------------------------------------------------------------------------
|
|
#include "pch.cpp"
|
|
#include "globals.h"
|
|
#include "permlic.h"
|
|
#include "misc.h"
|
|
#include "db.h"
|
|
#include "clilic.h"
|
|
#include "findlost.h"
|
|
#include <winsta.h>
|
|
|
|
DWORD
|
|
GenerateRandomNumber(
|
|
IN DWORD Seed
|
|
);
|
|
|
|
void
|
|
LicensedProductToDbLicensedProduct(
|
|
PLICENSEDPRODUCT pSrc,
|
|
PTLSDBLICENSEDPRODUCT pDest
|
|
);
|
|
|
|
void
|
|
CopyDbLicensedProduct(
|
|
PTLSDBLICENSEDPRODUCT pSrc,
|
|
PTLSDBLICENSEDPRODUCT pDest
|
|
);
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
//
|
|
// Memory leak at service shutdown time
|
|
//
|
|
typedef struct __LoggedLowLicenseProduct {
|
|
LPTSTR pszCompanyName;
|
|
LPTSTR pszProductId;
|
|
DWORD dwProductVersion;
|
|
|
|
__LoggedLowLicenseProduct() : pszProductId(NULL), pszCompanyName(NULL) {};
|
|
|
|
friend bool
|
|
operator<(
|
|
const __LoggedLowLicenseProduct&,
|
|
const __LoggedLowLicenseProduct&
|
|
);
|
|
|
|
} LoggedLowLicenseProduct;
|
|
|
|
//-------------------------------------------------------------------------
|
|
inline bool
|
|
operator<(
|
|
const __LoggedLowLicenseProduct& a,
|
|
const __LoggedLowLicenseProduct& b
|
|
)
|
|
/*++
|
|
|
|
--*/
|
|
{
|
|
bool bStatus;
|
|
|
|
TLSASSERT(a.pszCompanyName != NULL && b.pszCompanyName != NULL);
|
|
TLSASSERT(a.pszProductId != NULL && b.pszProductId != NULL);
|
|
|
|
// in case we mess up...
|
|
if(a.pszProductId == NULL || a.pszCompanyName == NULL)
|
|
{
|
|
bStatus = TRUE;
|
|
}
|
|
else if(b.pszProductId == NULL || b.pszCompanyName == NULL)
|
|
{
|
|
bStatus = FALSE;
|
|
}
|
|
else
|
|
{
|
|
bStatus = (_tcsicmp(a.pszCompanyName, b.pszCompanyName) < 0);
|
|
|
|
if(bStatus == TRUE)
|
|
{
|
|
bStatus = (_tcsicmp(a.pszProductId, b.pszProductId) < 0);
|
|
}
|
|
|
|
if(bStatus == TRUE)
|
|
{
|
|
bStatus = (CompareTLSVersions(a.dwProductVersion, b.dwProductVersion) < 0);
|
|
}
|
|
}
|
|
|
|
return bStatus;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
typedef map<
|
|
LoggedLowLicenseProduct,
|
|
BOOL,
|
|
less<LoggedLowLicenseProduct>
|
|
> LOGLOWLICENSEMAP;
|
|
|
|
static CCriticalSection LogLock;
|
|
static LOGLOWLICENSEMAP LowLicenseLog;
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
void
|
|
TLSResetLogLowLicenseWarning(
|
|
IN LPTSTR pszCompanyName,
|
|
IN LPTSTR pszProductId,
|
|
IN DWORD dwProductVersion,
|
|
IN BOOL bLogged
|
|
)
|
|
/*++
|
|
|
|
--*/
|
|
{
|
|
LOGLOWLICENSEMAP::iterator it;
|
|
LoggedLowLicenseProduct product;
|
|
|
|
product.pszCompanyName = pszCompanyName;
|
|
product.pszProductId = pszProductId;
|
|
product.dwProductVersion = dwProductVersion;
|
|
|
|
LogLock.Lock();
|
|
|
|
try {
|
|
it = LowLicenseLog.find(product);
|
|
if(it != LowLicenseLog.end())
|
|
{
|
|
// reset to not logged warning yet.
|
|
(*it).second = bLogged;
|
|
}
|
|
else if(bLogged == TRUE)
|
|
{
|
|
memset(&product, 0, sizeof(product));
|
|
|
|
// memory leak here at service stop.
|
|
product.pszProductId = _tcsdup(pszProductId);
|
|
product.pszCompanyName = _tcsdup(pszCompanyName);
|
|
product.dwProductVersion = dwProductVersion;
|
|
|
|
if(product.pszProductId != NULL && product.pszCompanyName != NULL)
|
|
{
|
|
LowLicenseLog[product] = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// if unable to allocate any more memory, log message every time
|
|
if(product.pszProductId != NULL)
|
|
{
|
|
free(product.pszProductId);
|
|
}
|
|
|
|
if(product.pszCompanyName != NULL)
|
|
{
|
|
free(product.pszCompanyName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch(...) {
|
|
}
|
|
|
|
LogLock.UnLock();
|
|
|
|
return;
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
|
|
void
|
|
TLSLogLowLicenseWarning(
|
|
IN PTLSDbWorkSpace pDbWkSpace,
|
|
IN PTLSDBLICENSEREQUEST pRequest,
|
|
IN BOOL bNoLicense
|
|
)
|
|
/*++
|
|
|
|
Abstract:
|
|
|
|
Log an low license count warning.
|
|
|
|
Parameter:
|
|
|
|
pDbWkSpace - Workspace handle.
|
|
pRequest - License Request.
|
|
Workspace - No license available.
|
|
LicensePack - License pack that is out of license
|
|
|
|
return:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
LOGLOWLICENSEMAP::iterator it;
|
|
BOOL bWarningLogged = FALSE;
|
|
DWORD dwStatus;
|
|
|
|
|
|
if( pRequest == NULL || pRequest->pClientLicenseRequest == NULL ||
|
|
pRequest->pClientLicenseRequest->pszProductId == NULL )
|
|
{
|
|
TLSASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
LoggedLowLicenseProduct product;
|
|
|
|
product.pszProductId = pRequest->pClientLicenseRequest->pszProductId;
|
|
product.pszCompanyName = pRequest->pClientLicenseRequest->pszCompanyName;
|
|
product.dwProductVersion = pRequest->pClientLicenseRequest->dwProductVersion;
|
|
|
|
LogLock.Lock();
|
|
|
|
try {
|
|
// see if we already log this warning message
|
|
it = LowLicenseLog.find(product);
|
|
if(it == LowLicenseLog.end())
|
|
{
|
|
memset(&product, 0, sizeof(product));
|
|
|
|
// memory leak here at service stop.
|
|
product.pszProductId = _tcsdup(pRequest->pClientLicenseRequest->pszProductId);
|
|
product.pszCompanyName = _tcsdup(pRequest->pClientLicenseRequest->pszCompanyName);
|
|
product.dwProductVersion = pRequest->pClientLicenseRequest->dwProductVersion;
|
|
|
|
if(product.pszProductId != NULL && product.pszCompanyName != NULL)
|
|
{
|
|
LowLicenseLog[product] = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// if unable to allocate any more memory, log message every time
|
|
if(product.pszProductId != NULL)
|
|
{
|
|
free(product.pszProductId);
|
|
}
|
|
|
|
if(product.pszCompanyName != NULL)
|
|
{
|
|
free(product.pszCompanyName);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bWarningLogged = (*it).second;
|
|
(*it).second = TRUE;
|
|
}
|
|
}
|
|
catch(...) {
|
|
// assuming no message has been logged.
|
|
bWarningLogged = FALSE;
|
|
}
|
|
|
|
LogLock.UnLock();
|
|
|
|
if(bWarningLogged == TRUE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// ask policy module if they have description
|
|
//
|
|
PMKEYPACKDESCREQ kpDescReq;
|
|
PPMKEYPACKDESC pKpDesc;
|
|
|
|
//
|
|
// Ask for default system language ID
|
|
//
|
|
kpDescReq.pszProductId = pRequest->pszProductId;
|
|
kpDescReq.dwLangId = GetSystemDefaultLangID();
|
|
kpDescReq.dwVersion = pRequest->dwProductVersion;
|
|
pKpDesc = NULL;
|
|
|
|
dwStatus = pRequest->pPolicy->PMLicenseRequest(
|
|
pRequest->hClient,
|
|
REQUEST_KEYPACKDESC,
|
|
(PVOID)&kpDescReq,
|
|
(PVOID *)&pKpDesc
|
|
);
|
|
|
|
if(dwStatus != ERROR_SUCCESS || pKpDesc == NULL)
|
|
{
|
|
if(GetSystemDefaultLangID() != MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US))
|
|
{
|
|
// see if we have any US desc.
|
|
kpDescReq.dwLangId = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
|
|
pKpDesc = NULL;
|
|
|
|
dwStatus = pRequest->pPolicy->PMLicenseRequest(
|
|
pRequest->hClient,
|
|
REQUEST_KEYPACKDESC,
|
|
(PVOID)&kpDescReq,
|
|
(PVOID *)&pKpDesc
|
|
);
|
|
}
|
|
}
|
|
|
|
LPCTSTR pString[2];
|
|
|
|
pString[0] = g_szComputerName;
|
|
pString[1] = (dwStatus == ERROR_SUCCESS && pKpDesc != NULL) ? pKpDesc->szProductDesc :
|
|
pRequest->pClientLicenseRequest->pszProductId;
|
|
|
|
TLSLogEventString(
|
|
EVENTLOG_WARNING_TYPE,
|
|
(bNoLicense == TRUE) ? TLS_W_NOPERMLICENSE : TLS_W_PRODUCTNOTINSTALL,
|
|
sizeof(pString)/sizeof(pString[0]),
|
|
pString
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------
|
|
DWORD
|
|
TLSDBIssuePermanentLicense(
|
|
IN PTLSDbWorkSpace pDbWkSpace,
|
|
IN PTLSDBLICENSEREQUEST pRequest,
|
|
IN BOOL bLatestVersion,
|
|
IN BOOL bAcceptFewerLicenses,
|
|
IN OUT DWORD *pdwQuantity,
|
|
IN OUT PTLSDBLICENSEDPRODUCT pLicensedProduct,
|
|
IN DWORD dwSupportFlags
|
|
)
|
|
/*
|
|
Abstract:
|
|
|
|
Routine to allocate a perm. license.
|
|
|
|
Parameters:
|
|
|
|
pDbWkSpace - Workspace handle.
|
|
pRequest - license request.
|
|
bLatestVersion - Request latest version (unused)
|
|
bAcceptFewerLicenses - TRUE if succeeding with fewer licenses than
|
|
requested is acceptable
|
|
pdwQuantity - on input, number of licenses to allocate. on output,
|
|
number of licenses actually allocated
|
|
IN OUT pLicensedProduct - licensed product
|
|
dwSupportFlags - abilities supported by TS and LS.
|
|
|
|
Returns:
|
|
|
|
*/
|
|
{
|
|
DWORD status=ERROR_SUCCESS;
|
|
ULARGE_INTEGER ulSerialNumber;
|
|
DWORD dwLicenseId;
|
|
TLSLICENSEPACK LicensePack;
|
|
UCHAR ucKeyPackStatus;
|
|
LICENSEDCLIENT issuedLicense;
|
|
DWORD CertSerialNumber;
|
|
|
|
PMGENERATELICENSE PolModGenLicense;
|
|
PPMCERTEXTENSION pPolModCertExtension=NULL;
|
|
|
|
FILETIME notBefore, notAfter;
|
|
UCHAR ucAgreementType;
|
|
|
|
memset(&ulSerialNumber, 0, sizeof(ulSerialNumber));
|
|
|
|
//----------------------------------------------------------------------
|
|
//
|
|
// this step require reduce available license by dwQuantity
|
|
//
|
|
status=TLSDBGetPermanentLicense(
|
|
pDbWkSpace,
|
|
pRequest,
|
|
bAcceptFewerLicenses,
|
|
pdwQuantity,
|
|
bLatestVersion,
|
|
&LicensePack
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
if(status == TLS_E_NO_LICENSE || status == TLS_E_PRODUCT_NOTINSTALL)
|
|
{
|
|
TLSLogLowLicenseWarning(
|
|
pDbWkSpace,
|
|
pRequest,
|
|
(status == TLS_E_NO_LICENSE)
|
|
);
|
|
}
|
|
|
|
goto cleanup;
|
|
}
|
|
|
|
ucKeyPackStatus = (LicensePack.ucKeyPackStatus & ~LSKEYPACKSTATUS_RESERVED);
|
|
|
|
if( ucKeyPackStatus != LSKEYPACKSTATUS_PENDING &&
|
|
ucKeyPackStatus != LSKEYPACKSTATUS_ACTIVE )
|
|
{
|
|
SetLastError(status = TLS_E_INTERNAL);
|
|
goto cleanup;
|
|
}
|
|
|
|
ucAgreementType = (LicensePack.ucAgreementType & ~ LSKEYPACK_RESERVED_TYPE);
|
|
|
|
if( ucAgreementType != LSKEYPACKTYPE_SELECT &&
|
|
ucAgreementType != LSKEYPACKTYPE_RETAIL &&
|
|
ucAgreementType != LSKEYPACKTYPE_FREE &&
|
|
ucAgreementType != LSKEYPACKTYPE_OPEN )
|
|
{
|
|
SetLastError(status = TLS_E_INTERNAL);
|
|
goto cleanup;
|
|
}
|
|
|
|
|
|
//
|
|
// for pending activation keypack, we still
|
|
// issue permanent license and rely
|
|
// on revoke key pack list to invalidate licenses.
|
|
//
|
|
dwLicenseId=TLSDBGetNextLicenseId();
|
|
|
|
//
|
|
// Reset status
|
|
//
|
|
status = ERROR_SUCCESS;
|
|
|
|
//
|
|
// Formuate license serial number
|
|
//
|
|
ulSerialNumber.LowPart = dwLicenseId;
|
|
ulSerialNumber.HighPart = LicensePack.dwKeyPackId;
|
|
|
|
// Update License Table Here
|
|
memset(&issuedLicense, 0, sizeof(LICENSEDCLIENT));
|
|
issuedLicense.dwLicenseId = dwLicenseId;
|
|
issuedLicense.dwKeyPackId = LicensePack.dwKeyPackId;
|
|
issuedLicense.dwKeyPackLicenseId = LicensePack.dwNextSerialNumber;
|
|
issuedLicense.dwSystemBiosChkSum = pRequest->hWid.dwPlatformID;
|
|
issuedLicense.dwVideoBiosChkSum = pRequest->hWid.Data1;
|
|
issuedLicense.dwFloppyBiosChkSum = pRequest->hWid.Data2;
|
|
issuedLicense.dwHardDiskSize = pRequest->hWid.Data3;
|
|
issuedLicense.dwRamSize = pRequest->hWid.Data4;
|
|
issuedLicense.dwNumLicenses = *pdwQuantity;
|
|
issuedLicense.ftIssueDate = time(NULL);
|
|
|
|
_tcscpy(issuedLicense.szMachineName, pRequest->szMachineName);
|
|
_tcscpy(issuedLicense.szUserName, pRequest->szUserName);
|
|
|
|
if ((dwSupportFlags & SUPPORT_PER_SEAT_REISSUANCE) &&
|
|
((_tcsnicmp(LicensePack.szProductId, TERMSERV_PRODUCTID_SKU,
|
|
_tcslen(TERMSERV_PRODUCTID_SKU)) == 0) ||
|
|
(_tcsnicmp(LicensePack.szProductId, TERMSERV_PRODUCTID_CONCURRENT_SKU,
|
|
_tcslen(TERMSERV_PRODUCTID_CONCURRENT_SKU)) == 0)) &&
|
|
((LicensePack.ucAgreementType == LSKEYPACKTYPE_SELECT) ||
|
|
(LicensePack.ucAgreementType == LSKEYPACKTYPE_RETAIL) ||
|
|
(LicensePack.ucAgreementType == LSKEYPACKTYPE_OPEN)))
|
|
{
|
|
DWORD dwRange;
|
|
|
|
dwRange = GenerateRandomNumber(GetCurrentThreadId()) %
|
|
g_dwReissueLeaseRange;
|
|
|
|
issuedLicense.ftExpireDate = ((DWORD)time(NULL)) +
|
|
g_dwReissueLeaseMinimum + dwRange;
|
|
}
|
|
else
|
|
{
|
|
issuedLicense.ftExpireDate = PERMANENT_LICENSE_EXPIRE_DATE;
|
|
}
|
|
|
|
issuedLicense.ucLicenseStatus =
|
|
(LicensePack.ucKeyPackStatus == LSKEYPACKSTATUS_PENDING) ?
|
|
LSLICENSE_STATUS_PENDING : LSLICENSE_STATUS_ACTIVE;
|
|
|
|
UnixTimeToFileTime(LicensePack.dwActivateDate, ¬Before);
|
|
UnixTimeToFileTime(issuedLicense.ftExpireDate, ¬After);
|
|
|
|
//
|
|
// Inform Policy Module of license issued.
|
|
//
|
|
if(pRequest->pPolicy)
|
|
{
|
|
PolModGenLicense.dwKeyPackType = LicensePack.ucAgreementType;
|
|
PolModGenLicense.pLicenseRequest = pRequest->pPolicyLicenseRequest;
|
|
PolModGenLicense.dwKeyPackId = LicensePack.dwKeyPackId;;
|
|
PolModGenLicense.dwKeyPackLicenseId = LicensePack.dwNextSerialNumber;
|
|
PolModGenLicense.ClientLicenseSerialNumber = ulSerialNumber;
|
|
PolModGenLicense.ftNotBefore = notBefore;
|
|
PolModGenLicense.ftNotAfter = notAfter;
|
|
|
|
status = pRequest->pPolicy->PMLicenseRequest(
|
|
pRequest->hClient,
|
|
REQUEST_GENLICENSE,
|
|
(PVOID)&PolModGenLicense,
|
|
(PVOID *)&pPolModCertExtension
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
//
|
|
// Error in policy module
|
|
//
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check error return from policy module
|
|
//
|
|
if(pPolModCertExtension != NULL)
|
|
{
|
|
if(pPolModCertExtension->pbData != NULL &&
|
|
pPolModCertExtension->cbData == 0 ||
|
|
pPolModCertExtension->pbData == NULL &&
|
|
pPolModCertExtension->cbData != 0 )
|
|
{
|
|
// assuming no extension data
|
|
pPolModCertExtension->cbData = 0;
|
|
pPolModCertExtension->pbData = NULL;
|
|
}
|
|
|
|
if(CompareFileTime( &(pPolModCertExtension->ftNotBefore),
|
|
&(pPolModCertExtension->ftNotAfter)) > 0)
|
|
{
|
|
//
|
|
// invalid data return from policy module
|
|
//
|
|
TLSLogEvent(
|
|
EVENTLOG_ERROR_TYPE,
|
|
TLS_E_GENERATECLIENTELICENSE,
|
|
status = TLS_E_POLICYMODULEERROR,
|
|
pRequest->pPolicy->GetCompanyName(),
|
|
pRequest->pPolicy->GetProductId()
|
|
);
|
|
|
|
goto cleanup;
|
|
}
|
|
|
|
|
|
if( FileTimeToLicenseDate(&(pPolModCertExtension->ftNotBefore), &issuedLicense.ftIssueDate) == FALSE ||
|
|
FileTimeToLicenseDate(&(pPolModCertExtension->ftNotAfter), &issuedLicense.ftExpireDate) == FALSE )
|
|
{
|
|
//
|
|
// Invalid data return from policy module
|
|
//
|
|
TLSLogEvent(
|
|
EVENTLOG_ERROR_TYPE,
|
|
TLS_E_GENERATECLIENTELICENSE,
|
|
status = TLS_E_POLICYMODULEERROR,
|
|
pRequest->pPolicy->GetCompanyName(),
|
|
pRequest->pPolicy->GetProductId()
|
|
);
|
|
|
|
goto cleanup;
|
|
}
|
|
|
|
notBefore = pPolModCertExtension->ftNotBefore;
|
|
notAfter = pPolModCertExtension->ftNotAfter;
|
|
}
|
|
|
|
//
|
|
// Add license into license table
|
|
//
|
|
status=TLSDBLicenseAdd(
|
|
pDbWkSpace,
|
|
&issuedLicense,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Return licensed product
|
|
//
|
|
pLicensedProduct->pSubjectPublicKeyInfo = NULL;
|
|
pLicensedProduct->dwQuantity = *pdwQuantity;
|
|
pLicensedProduct->ulSerialNumber = ulSerialNumber;
|
|
|
|
pLicensedProduct->dwKeyPackId = LicensePack.dwKeyPackId;
|
|
pLicensedProduct->dwLicenseId = dwLicenseId;
|
|
pLicensedProduct->dwKeyPackLicenseId = LicensePack.dwNextSerialNumber;
|
|
pLicensedProduct->dwNumLicenseLeft = LicensePack.dwNumberOfLicenses;
|
|
pLicensedProduct->ClientHwid = pRequest->hWid;
|
|
pLicensedProduct->bTemp = FALSE;
|
|
|
|
pLicensedProduct->NotBefore = notBefore;
|
|
pLicensedProduct->NotAfter = notAfter;
|
|
|
|
pLicensedProduct->dwProductVersion = MAKELONG(LicensePack.wMinorVersion, LicensePack.wMajorVersion);
|
|
|
|
_tcscpy(pLicensedProduct->szUserName, pRequest->szUserName);
|
|
_tcscpy(pLicensedProduct->szMachineName, pRequest->szMachineName);
|
|
|
|
_tcscpy(pLicensedProduct->szCompanyName, LicensePack.szCompanyName);
|
|
_tcscpy(pLicensedProduct->szLicensedProductId, LicensePack.szProductId);
|
|
_tcscpy(pLicensedProduct->szRequestProductId, pRequest->pClientLicenseRequest->pszProductId);
|
|
|
|
pLicensedProduct->dwLanguageID = pRequest->dwLanguageID;
|
|
pLicensedProduct->dwPlatformID = pRequest->dwPlatformID;
|
|
pLicensedProduct->pbPolicyData = (pPolModCertExtension) ? pPolModCertExtension->pbData : NULL;
|
|
pLicensedProduct->cbPolicyData = (pPolModCertExtension) ? pPolModCertExtension->cbData : 0;
|
|
|
|
cleanup:
|
|
|
|
return status;
|
|
}
|
|
|
|
DWORD
|
|
TLSDBReissuePermanentLicense(
|
|
IN PTLSDbWorkSpace pDbWkSpace,
|
|
IN PLICENSEDPRODUCT pExpiredLicense,
|
|
IN OUT PTLSDBLICENSEDPRODUCT pReissuedLicense
|
|
)
|
|
/*++
|
|
Abstract:
|
|
|
|
Searches for the expired license in the database and, if found, resets
|
|
the expiration and returns the modified license.
|
|
|
|
Parameters:
|
|
|
|
Returns:
|
|
|
|
--*/
|
|
{
|
|
TLSDBLICENSEDPRODUCT LicensedProduct;
|
|
|
|
LicensedProductToDbLicensedProduct(pExpiredLicense,&LicensedProduct);
|
|
|
|
return TLSDBReissueFoundPermanentLicense(pDbWkSpace,
|
|
&LicensedProduct,
|
|
pReissuedLicense);
|
|
}
|
|
|
|
DWORD
|
|
TLSDBReissueFoundPermanentLicense(
|
|
IN PTLSDbWorkSpace pDbWkSpace,
|
|
IN PTLSDBLICENSEDPRODUCT pExpiredLicense,
|
|
IN OUT PTLSDBLICENSEDPRODUCT pReissuedLicense
|
|
)
|
|
/*++
|
|
Abstract:
|
|
|
|
Searches for the expired license in the database and, if found, resets
|
|
the expiration and returns the modified license.
|
|
|
|
Parameters:
|
|
|
|
Returns:
|
|
|
|
--*/
|
|
{
|
|
DWORD dwStatus;
|
|
LICENSEDCLIENT License;
|
|
|
|
ASSERT(pDbWkSpace != NULL);
|
|
ASSERT(pExpiredLicense != NULL);
|
|
ASSERT(pReissuedLicense != NULL);
|
|
|
|
dwStatus = TLSFindDbLicensedProduct(pExpiredLicense, &License);
|
|
|
|
if (dwStatus == ERROR_SUCCESS)
|
|
{
|
|
DWORD dwRange;
|
|
|
|
dwRange = GenerateRandomNumber(GetCurrentThreadId()) %
|
|
g_dwReissueLeaseRange;
|
|
|
|
License.ftExpireDate = ((DWORD)time(NULL)) +
|
|
g_dwReissueLeaseMinimum + dwRange;
|
|
|
|
TLSDBLockLicenseTable();
|
|
|
|
try
|
|
{
|
|
dwStatus = TLSDBLicenseUpdateEntry(
|
|
USEHANDLE(pDbWkSpace),
|
|
LSLICENSE_SEARCH_EXPIREDATE,
|
|
&License,
|
|
FALSE
|
|
);
|
|
}
|
|
catch(...)
|
|
{
|
|
dwStatus = TLS_E_INTERNAL;
|
|
}
|
|
|
|
TLSDBUnlockLicenseTable();
|
|
}
|
|
|
|
if (dwStatus == ERROR_SUCCESS)
|
|
{
|
|
CopyDbLicensedProduct(pExpiredLicense, pReissuedLicense);
|
|
UnixTimeToFileTime(License.ftExpireDate, &(pReissuedLicense->NotAfter));
|
|
pReissuedLicense->pSubjectPublicKeyInfo = NULL;
|
|
}
|
|
|
|
return(dwStatus);
|
|
}
|
|
|
|
//+------------------------------------------------------------------------
|
|
DWORD
|
|
TLSDBGetPermanentLicense(
|
|
IN PTLSDbWorkSpace pDbWkSpace,
|
|
IN PTLSDBLICENSEREQUEST pRequest,
|
|
IN BOOL bAcceptFewerLicenses,
|
|
IN OUT DWORD *pdwQuantity,
|
|
IN BOOL bLatestVersion,
|
|
IN OUT PTLSLICENSEPACK pLicensePack
|
|
)
|
|
/*++
|
|
Abstract:
|
|
|
|
Allocate a permanent license from database.
|
|
|
|
Parameters:
|
|
|
|
pDbWkSpace : workspace handle.
|
|
pRequest : product to be request.
|
|
bAcceptFewerLicenses - TRUE if succeeding with fewer licenses than
|
|
requested is acceptable
|
|
pdwQuantity - on input, number of licenses to allocate. on output,
|
|
number of licenses actually allocated
|
|
bLatestversion : latest version (unused).
|
|
pLicensePack : license pack where license is allocated.
|
|
|
|
Returns:
|
|
|
|
|
|
++*/
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
TLSDBLicenseAllocation allocated;
|
|
TLSDBAllocateRequest AllocateRequest;
|
|
TLSLICENSEPACK LicenseKeyPack;
|
|
DWORD dwTotalAllocated = 0;
|
|
|
|
|
|
DWORD dwSearchedType = 0;
|
|
DWORD dwSuggestType;
|
|
DWORD dwPMAdjustedType = LSKEYPACKTYPE_UNKNOWN;
|
|
DWORD dwLocalType = LSKEYPACKTYPE_UNKNOWN;
|
|
|
|
POLICY_TS_MACHINE groupPolicy;
|
|
RegGetMachinePolicy(&groupPolicy);
|
|
|
|
#define NUM_KEYPACKS 5
|
|
|
|
DWORD dwAllocation[NUM_KEYPACKS];
|
|
TLSLICENSEPACK keypack[NUM_KEYPACKS];
|
|
|
|
for (int i=0; i < NUM_KEYPACKS; i++)
|
|
{
|
|
keypack[i].pbDomainSid = NULL;
|
|
}
|
|
|
|
AllocateRequest.szCompanyName = (LPTSTR)pRequest->pszCompanyName;
|
|
AllocateRequest.szProductId = (LPTSTR)pRequest->pszProductId;
|
|
AllocateRequest.dwVersion = pRequest->dwProductVersion;
|
|
AllocateRequest.dwPlatformId = pRequest->dwPlatformID;
|
|
AllocateRequest.dwLangId = pRequest->dwLanguageID;
|
|
AllocateRequest.dwNumLicenses = *pdwQuantity;
|
|
if( groupPolicy.fPolicyPreventLicenseUpgrade == 1 && groupPolicy.fPreventLicenseUpgrade == 1)
|
|
{
|
|
AllocateRequest.dwScheme = ALLOCATE_EXACT_VERSION;
|
|
}
|
|
else
|
|
{
|
|
AllocateRequest.dwScheme = ALLOCATE_ANY_GREATER_VERSION;
|
|
}
|
|
memset(&allocated, 0, sizeof(allocated));
|
|
|
|
|
|
do {
|
|
|
|
allocated.dwBufSize = NUM_KEYPACKS;
|
|
allocated.pdwAllocationVector = dwAllocation;
|
|
allocated.lpAllocateKeyPack = keypack;
|
|
|
|
dwSuggestType = dwLocalType;
|
|
|
|
dwStatus = pRequest->pPolicy->PMLicenseRequest(
|
|
pRequest->hClient,
|
|
REQUEST_KEYPACKTYPE,
|
|
UlongToPtr(dwSuggestType),
|
|
(PVOID *)&dwPMAdjustedType
|
|
);
|
|
|
|
if(dwStatus != ERROR_SUCCESS)
|
|
break;
|
|
|
|
dwLocalType = (dwPMAdjustedType & ~LSKEYPACK_RESERVED_TYPE);
|
|
if(dwLocalType > LSKEYPACKTYPE_LAST)
|
|
{
|
|
TLSLogEvent(
|
|
EVENTLOG_ERROR_TYPE,
|
|
TLS_E_GENERATECLIENTELICENSE,
|
|
dwStatus = TLS_E_POLICYMODULEERROR,
|
|
pRequest->pPolicy->GetCompanyName(),
|
|
pRequest->pPolicy->GetProductId()
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
if(dwSearchedType & (0x1 << dwLocalType))
|
|
{
|
|
//
|
|
// we already went thru this license pack, policy module error
|
|
//
|
|
TLSLogEvent(
|
|
EVENTLOG_ERROR_TYPE,
|
|
TLS_E_GENERATECLIENTELICENSE,
|
|
dwStatus = TLS_E_POLICYMODULERECURSIVE,
|
|
pRequest->pPolicy->GetCompanyName(),
|
|
pRequest->pPolicy->GetProductId()
|
|
);
|
|
break;
|
|
}
|
|
|
|
dwSearchedType |= (0x1 << dwLocalType);
|
|
AllocateRequest.ucAgreementType = dwPMAdjustedType;
|
|
|
|
dwStatus = AllocateLicensesFromDB(
|
|
pDbWkSpace,
|
|
&AllocateRequest,
|
|
TRUE, // fCheckAgreementType
|
|
&allocated
|
|
);
|
|
|
|
if(dwStatus == ERROR_SUCCESS)
|
|
{
|
|
//
|
|
// successfully allocate a license
|
|
//
|
|
dwTotalAllocated += allocated.dwTotalAllocated;
|
|
|
|
if (dwTotalAllocated >= *pdwQuantity)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
AllocateRequest.dwNumLicenses -= allocated.dwTotalAllocated;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if(dwStatus != TLS_I_NO_MORE_DATA && dwStatus != TLS_E_PRODUCT_NOTINSTALL)
|
|
{
|
|
//
|
|
// error occurred in AllocateLicenseFromDB()
|
|
//
|
|
break;
|
|
}
|
|
} while(dwLocalType != LSKEYPACKTYPE_UNKNOWN);
|
|
|
|
if ((dwTotalAllocated == 0)
|
|
|| (!bAcceptFewerLicenses &&
|
|
((dwTotalAllocated < *pdwQuantity))))
|
|
{
|
|
// Failing to commit will return all licenses allocated so far
|
|
|
|
SetLastError(dwStatus = TLS_E_NO_LICENSE);
|
|
}
|
|
else if ((dwTotalAllocated != 0) && bAcceptFewerLicenses)
|
|
{
|
|
dwStatus = ERROR_SUCCESS;
|
|
}
|
|
|
|
if(dwStatus == ERROR_SUCCESS)
|
|
{
|
|
//
|
|
// LicenseKeyPack return via TLSDBLicenseAllocation structure
|
|
//
|
|
*pLicensePack = keypack[0];
|
|
*pdwQuantity = dwTotalAllocated;
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|