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.
 
 
 
 
 
 

535 lines
11 KiB

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
rpcstub.c
Abstract:
License Logging Service client stubs.
Author:
Arthur Hanson (arth) 06-Dec-1994
Environment: User mode only.
Revision History:
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <string.h>
#include <zwapi.h>
#include <llsconst.h>
#include <debug.h>
#include "lsapi_c.h"
#include <strsafe.h>
// #define API_TRACE 1
BOOLEAN LLSUp = FALSE;
//swi, code review, why we hard code the length here, where is 72 from? winnt.h has a define already, SECURITY_MAX_SID_SIZE
#define MAX_EXPECTED_SID_LENGTH 72
LPTSTR pszStringBinding = NULL;
RTL_CRITICAL_SECTION LPCInitLock;
static HANDLE LpcPortHandle = NULL;
/////////////////////////////////////////////////////////////////////////
NTSTATUS
LLSReInitLPC( )
/*++
Routine Description:
This service connects to the LLS server and initializes the LPC port.
Arguments:
Return Value:
STATUS_SUCCESS - The call completed successfully.
--*/
{
RPC_STATUS Status = STATUS_SUCCESS;
LPTSTR pszUuid = NULL;
LPTSTR pszProtocolSequence = NULL;
LPTSTR pszNetworkAddress = NULL;
LPTSTR pszEndpoint = NULL;
LPTSTR pszOptions = NULL;
pszProtocolSequence = TEXT("ncalrpc");
pszEndpoint = TEXT(LLS_LPC_ENDPOINT);
pszNetworkAddress = NULL;
if (LLSUp) {
LLSUp = FALSE;
if (pszStringBinding != NULL) {
Status = RpcStringFree(&pszStringBinding);
pszStringBinding = NULL;
}
if (Status == STATUS_SUCCESS) {
if (lsapirpc_handle != NULL) {
Status = RpcBindingFree(&lsapirpc_handle);
}
lsapirpc_handle = NULL;
}
}
try {
// Compose a string binding
Status = RpcStringBindingComposeW(pszUuid,
pszProtocolSequence,
pszNetworkAddress,
pszEndpoint,
pszOptions,
&pszStringBinding);
}
except (TRUE) {
Status = RpcExceptionCode();
}
if(Status) {
#if DBG
dprintf(TEXT("NTLSAPI RpcStringBindingComposeW Failed: 0x%lX\n"), Status);
#endif
if (pszStringBinding != NULL) {
RpcStringFree(&pszStringBinding);
pszStringBinding = NULL;
}
return I_RpcMapWin32Status(Status);
}
// Bind using the created string binding...
try {
Status = RpcBindingFromStringBindingW(pszStringBinding, &lsapirpc_handle);
}
except (TRUE) {
Status = RpcExceptionCode();
}
if(Status) {
#if DBG
dprintf(TEXT("NTLSAPI RpcBindingFromStringBindingW Failed: 0x%lX\n"), Status);
#endif
// lsapirpc_handle = NULL;
if (pszStringBinding != NULL) {
RpcStringFree(&pszStringBinding);
pszStringBinding = NULL;
}
return I_RpcMapWin32Status(Status);
}
LLSUp = TRUE;
return I_RpcMapWin32Status(Status);
} // LLSReInitLPC
/////////////////////////////////////////////////////////////////////////
NTSTATUS
LLSInitLPC( )
/*++
Routine Description:
This service connects to the LLS server and initializes the LPC port.
Arguments:
Return Value:
STATUS_SUCCESS - The call completed successfully.
--*/
{
NTSTATUS status;
status = RtlInitializeCriticalSection(&LPCInitLock);
lsapirpc_handle = NULL;
return status;
} // LLSInitLPC
/////////////////////////////////////////////////////////////////////////
NTSTATUS
LLSCloseLPC( )
/*++
Routine Description:
This closes the LPC port connection to the service.
Arguments:
Return Value:
STATUS_SUCCESS - The call completed successfully.
--*/
{
RPC_STATUS Status = STATUS_SUCCESS, Status2 = STATUS_SUCCESS;
RtlEnterCriticalSection(&LPCInitLock);
LLSUp = FALSE;
if (pszStringBinding != NULL) {
Status = RpcStringFree(&pszStringBinding);
pszStringBinding = NULL;
}
if (lsapirpc_handle != NULL) {
Status2 = RpcBindingFree(&lsapirpc_handle);
}
if (Status == STATUS_SUCCESS)
Status = Status2;
lsapirpc_handle = NULL;
RtlLeaveCriticalSection(&LPCInitLock);
return Status;
} // LLSCloseLPC
/////////////////////////////////////////////////////////////////////////
NTSTATUS
LLSLicenseRequest2 (
IN LPWSTR ProductName,
IN LPWSTR Version,
IN ULONG DataType,
IN BOOLEAN IsAdmin,
IN PVOID Data,
OUT PHANDLE LicenseHandle
)
/*++
Arguments:
ProductName -
Version -
DataType -
IsAdmin -
Data -
LicenseHandle -
Return Status:
STATUS_SUCCESS - Indicates the service completed successfully.
Routine Description:
--*/
{
WCHAR ProductID[MAX_PRODUCT_NAME_LENGTH + MAX_VERSION_LENGTH + 2];
NTSTATUS Status = STATUS_SUCCESS;
BOOL Close = FALSE;
ULONG VersionIndex;
ULONG Size = 0;
ULONG i;
LICENSE_HANDLE RpcLicenseHandle;
BOOL bActuallyConnect = TRUE;
HRESULT hr;
size_t cb;
ZeroMemory(&RpcLicenseHandle, sizeof(RpcLicenseHandle));
//
// Get this out of the way in-case anything goes wrong
//
*LicenseHandle = NULL;
//
// If LicenseService isn't running (no LPC port) then just return
// dummy info - and let the user on.
//
RtlEnterCriticalSection(&LPCInitLock);
if (!LLSUp)
Status = LLSReInitLPC();
RtlLeaveCriticalSection(&LPCInitLock);
if (!NT_SUCCESS(Status))
return STATUS_SUCCESS;
if (((i = lstrlen(ProductName)) > MAX_PRODUCT_NAME_LENGTH) || (lstrlen(Version) > MAX_VERSION_LENGTH))
return STATUS_SUCCESS;
//
// Create productID - product name + version string.
//
cb = sizeof(ProductID);
hr = StringCbCopy(ProductID, cb, ProductName);
ASSERT(SUCCEEDED(hr));
hr = StringCbCat(ProductID, cb, TEXT(" "));
ASSERT(SUCCEEDED(hr));
hr = StringCbCat(ProductID, cb, Version);
ASSERT(SUCCEEDED(hr));
VersionIndex = i;
//
// Based on DataType figure out if we are doing a name or a SID
// and copy the data appropriatly
//
if (DataType == NT_LS_USER_NAME) {
Size = lstrlen((LPWSTR) Data);
//swi, code review, MAX_USER_NAME_LENGTH is defined in inc\llsconst.h as 37 where did 37 come from?
if (Size > MAX_USER_NAME_LENGTH)
return STATUS_SUCCESS;
Size = (Size + 1) * sizeof(TCHAR);
}
if (DataType == NT_LS_USER_SID) {
//
// Friggin SID, so need to copy it manually.
// WARNING: This makes it dependent on the structure of the
// SID!!!
//
Size = RtlLengthSid( (PSID) Data);
if (Size > MAX_EXPECTED_SID_LENGTH)
return STATUS_SUCCESS;
}
//swi, code review, what happen if DataType is not NT_LS_USER_NAME or NT_LS_USER_SID?
//- it at least pass the call with invalid data to rpc. we should block from here.
//- check with the server side code, it doesn't validate DataType either and it actually goes through the loop to check it against all users in cached list. mostly performance hit.
//
// Call the Server.
//
try {
Status = LlsrLicenseRequestW(
&RpcLicenseHandle,
ProductID,
VersionIndex,
IsAdmin,
DataType,
Size,
(PBYTE) Data );
}
except (TRUE) {
#if DBG
Status = I_RpcMapWin32Status(RpcExceptionCode());
if (Status != RPC_NT_SERVER_UNAVAILABLE) {
dprintf(TEXT("ERROR NTLSAPI.DLL: RPC Exception: 0x%lX\n"), Status);
// ASSERT(FALSE);
}
#endif
*LicenseHandle = NULL;
Status = STATUS_SUCCESS;
bActuallyConnect = FALSE;
}
if (Close)
LLSCloseLPC();
// This is really a ULONG, we just treated it as a PVOID so
// RPC would treat is as a context handle
if(bActuallyConnect == TRUE)
*LicenseHandle = RpcLicenseHandle;
return Status;
} // LLSLicenseRequest
/////////////////////////////////////////////////////////////////////////
NTSTATUS
LLSLicenseRequest (
IN LPWSTR ProductName,
IN LPWSTR Version,
IN ULONG DataType,
IN BOOLEAN IsAdmin,
IN PVOID Data,
OUT PULONG LicenseHandle
)
/*++
Arguments:
ProductName -
Version -
DataType -
IsAdmin -
Data -
LicenseHandle -
Return Status:
STATUS_SUCCESS - Indicates the service completed successfully.
Routine Description:
--*/
{
HANDLE RealLicenseHandle;
NTSTATUS status;
#pragma warning (push)
#pragma warning (disable : 4127) //conditional expression is constant
if (sizeof(ULONG) == sizeof(HANDLE))
#pragma warning (pop)
{
// Should still work on Win32
status = LLSLicenseRequest2(ProductName,Version,DataType,IsAdmin,Data,&RealLicenseHandle);
if (NULL != LicenseHandle)
*LicenseHandle = PtrToUlong(RealLicenseHandle);
}
else
{
status = STATUS_NOT_IMPLEMENTED;
if (NULL != LicenseHandle)
*LicenseHandle = (ULONG) 0xFFFFFFFF;
}
return status;
}
/////////////////////////////////////////////////////////////////////////
NTSTATUS
LLSLicenseFree2 (
IN HANDLE LicenseHandle
)
/*++
Arguments:
LicenseHandle -
Return Status:
STATUS_SUCCESS - Indicates the service completed successfully.
--*/
{
BOOL Close = FALSE;
NTSTATUS Status;
LICENSE_HANDLE RpcLicenseHandle = (LICENSE_HANDLE) LicenseHandle;
//
// If LicenseService isn't running (no LPC port) then just return
// dummy info - and let the user on.
//
if (!LLSUp)
{
return STATUS_SUCCESS;
}
//
// Call the Server.
//
try {
Status = LlsrLicenseFree( &RpcLicenseHandle );
}
except (TRUE) {
#if DBG
Status = I_RpcMapWin32Status(RpcExceptionCode());
if (Status != RPC_NT_SERVER_UNAVAILABLE) {
dprintf(TEXT("ERROR NTLSAPI.DLL: RPC Exception: 0x%lX\n"), Status);
// ASSERT(FALSE);
}
#endif
Status = STATUS_SUCCESS;
}
if (Close)
LLSCloseLPC();
return Status;
} // LLSLicenseFree
/////////////////////////////////////////////////////////////////////////
NTSTATUS
LLSLicenseFree (
IN ULONG LicenseHandle
)
/*++
Arguments:
LicenseHandle -
Return Status:
STATUS_SUCCESS - Indicates the service completed successfully.
--*/
{
#pragma warning (push)
#pragma warning (disable : 4127) //conditional expression is constant
if (sizeof(ULONG) == sizeof(HANDLE))
#pragma warning (pop)
{
// Should still work on Win32
return LLSLicenseFree2(ULongToPtr(LicenseHandle));
}
else
{
return STATUS_NOT_IMPLEMENTED;
}
}