Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

475 lines
9.9 KiB

/*++
Microsoft Windows NT RPC Name Service
Copyright (c) 1995 Microsoft Corporation
Module Name:
master.cxx
Abstract:
This file contains the implementations for non inline member functions
of CMasterLookupHandle and CMasterObjectInqHandle, which are classes used for
interaction with a master locator for looking up binding handles and objects.
Things to improve in future revisions:
1. The structure of the locator-to-locator RPC interface needs a complete redesign.
The query to a master locator should be for a complete entry, not piecemeal
and painfully repetitive as it is now.
2. There is a suspicion that client locators don't release all the lookup handles
they get from a master locator (about 1 in 200 in a random test), probably in
exceptional circumstances. This needs to be fixed if true.
Author:
Satish Thatte (SatishT) 10/1/95 Created all the code below except where
otherwise indicated.
--*/
#include <master.hxx>
#include <api.hxx>
#include <var.hxx>
#include <loctoloc.h>
#if DBG
ULONG CMasterLookupHandle::ulMasterLookupHandleCount = 0;
ULONG CMasterLookupHandle::ulMasterLookupHandleNo = 0;
#endif
NSI_UUID_VECTOR_P_T
getObjectVector(
IN RPC_BINDING_HANDLE hCurrentMaster,
IN UNSIGNED32 EntryNameSyntax,
IN STRING_T EntryName,
OUT ULONG& StatusCode
)
/*++
Routine Description:
Broadcasts for the requested binding handles.
Arguments:
hCurrentMaster - the binding handle for the master locator
EntryNameSyntax - syntax of entry name
EntryName - entry name for object query
StatusCode - status of query returned here
Returns:
A standard UUID vector containing the object UUIDs returned by the
master locator.
--*/
{
STATUS Status;
NSI_UUID_VECTOR_P_T pUuidVector = NULL;
HANDLE hObjectHandle = NULL;
RpcImpersonateClient(0);
RpcTryExcept {
CLIENT_I_nsi_entry_object_inq_begin(
hCurrentMaster,
EntryNameSyntax,
EntryName,
&hObjectHandle,
&Status
);
}
RpcExcept (EXCEPTION_EXECUTE_HANDLER) {
RpcBindingFree(&hCurrentMaster);
hCurrentMaster = NULL;
StatusCode = RpcExceptionCode();
if (StatusCode == RPC_S_ACCESS_DENIED)
StatusCode = NSI_S_NO_NS_PRIVILEGE;
RpcRevertToSelf();
return NULL;
}
RpcEndExcept;
if ((StatusCode = Status) != NSI_S_OK) return NULL;
CLIENT_I_nsi_entry_object_inq_next(
hCurrentMaster,
hObjectHandle,
&pUuidVector,
&Status
);
StatusCode = Status;
CLIENT_I_nsi_entry_object_inq_done(
&hObjectHandle,
&Status
);
StatusCode = Status;
RpcRevertToSelf();
return pUuidVector;
}
void
CMasterLookupHandle::initialize()
/*++
Method Description:
Establishes contact with the master locator and acquires a context handle
for the lookup parameters stored as members in this object.
Remarks:
The reason for separating initialization as a method separate from the
constructor is that "lookupIfNecessary" may force reinitialization if
the information is too stale. This can happen if the user resets the
expiration age for a specific context handle.
--*/
{
DBGOUT(TRACE,"CMasterLookupHandle::initialize called for Handle#" << ulHandleNo << "\n\n");
StatusCode = NSI_S_OK;
RPC_SYNTAX_IDENTIFIER interfaceID;
if (pgvInterface) interfaceID = *pgvInterface;
RPC_SYNTAX_IDENTIFIER xferSyntaxID;
if (pgvTransferSyntax) xferSyntaxID = *pgvTransferSyntax;
NSI_UUID_T objID;
if (pidObject) objID = pidObject->myGUID();
UNSIGNED16 status = 0;
RpcMgmtSetCancelTimeout(CONNECTION_TIMEOUT);
hCurrentMaster = ConnectToMasterLocator(
StatusCode
);
if (!hCurrentMaster || StatusCode) {
StatusCode = NSI_S_NAME_SERVICE_UNAVAILABLE;
myRpcLocator->SetDCsDown();
return;
}
else myRpcLocator->SetDCsUp();
RpcImpersonateClient(0);
lookupHandle = NULL;
/* The following is a work around, because the compiler refuses to accept
penEntryName ? (*penEntryName) : NULL
*/
STRING_T szEntryName = NULL;
if (penEntryName) szEntryName = *penEntryName;
RpcTryExcept {
CLIENT_I_nsi_lookup_begin(
hCurrentMaster,
u32EntryNameSyntax,
szEntryName,
pgvInterface? &interfaceID : NULL,
pgvTransferSyntax? &xferSyntaxID : NULL,
pidObject? &objID : NULL,
ulVS,
ulCacheMax? ulCacheMax: ulCacheMax+CACHE_GRACE, // ensures that it is nonzero
&lookupHandle, // the above is wierd but necessary because ulCacheAge is frequently -1
&status
);
}
RpcExcept (EXCEPTION_EXECUTE_HANDLER) {
RpcBindingFree(&hCurrentMaster);
hCurrentMaster = NULL;
StatusCode = RpcExceptionCode();
if (StatusCode == RPC_S_ACCESS_DENIED)
StatusCode = NSI_S_NO_NS_PRIVILEGE;
// this is a copout to take care of NT vs NSI code conflicts
else if (StatusCode < NSI_S_STATUS_MAX)
StatusCode = NSI_S_NAME_SERVICE_UNAVAILABLE;
RpcRevertToSelf();
return;
}
RpcEndExcept;
RpcRevertToSelf();
StatusCode = status; // hopefully, RPC_S_OK;
fFinished = FALSE;
ulCreationTime = CurrentTime();
fNotInitialized = FALSE;
}
BOOL
CMasterLookupHandle::fetchNext()
/*++
Method Description:
Fetches the next vector of binding handles from the master locator, along
with associated object UUIDs.
Remarks:
The process is inefficient in that each binding handle returned has an
entry name associated with it and we must make a full fledged object query
for every binding handle. This is extremely expensive but the current structure
of the locator-to-locator interface forces it upon us.
--*/
{
DBGOUT(TRACE,"CMasterLookupHandle::fetchNext called for Handle#" << ulHandleNo << "\n\n");
STATUS status;
/* We only want to run down the info acquired in the last fetchNext.
A full-scale rundown of the handle would also give up the context
handle and binding to the master locator, which would ruin us.
The only thing we have to fix is to reset the fNotInitialzed flag,
so that we don't call initialize() again on this handle.
*/
CRemoteLookupHandle::rundown();
fNotInitialized = FALSE;
psslNewCache = new TSSLEntryList;
NSI_BINDING_VECTOR_T * pNextVector = NULL;
RpcImpersonateClient(0);
RpcTryExcept {
CLIENT_I_nsi_lookup_next(
hCurrentMaster,
lookupHandle,
&pNextVector,
&status
);
}
RpcExcept (EXCEPTION_EXECUTE_HANDLER) {
RpcBindingFree(&hCurrentMaster);
hCurrentMaster = NULL;
StatusCode = RpcExceptionCode();
if (StatusCode == RPC_S_ACCESS_DENIED)
StatusCode = NSI_S_NO_NS_PRIVILEGE;
RpcRevertToSelf();
return FALSE;
}
RpcEndExcept;
RpcRevertToSelf();
StatusCode = status;
if (status == NSI_S_NO_MORE_BINDINGS) return FALSE;
else if (status != NSI_S_OK) Raise(status);
else {
NSI_UUID_VECTOR_P_T pUuidVector;
for (unsigned int i = 0; i < pNextVector->count; i++)
{
pUuidVector = getObjectVector(
hCurrentMaster,
pNextVector->binding[i].entry_name_syntax,
pNextVector->binding[i].entry_name,
StatusCode
);
/* first update the central cache and, if there is anything new,
also update the temporary cache in psslNewCache
*/
CGUIDVersion nullGV; // standard initialization to null
myRpcLocator->UpdateCache(
pNextVector->binding[i].entry_name,
pNextVector->binding[i].entry_name_syntax,
pgvInterface ? *pgvInterface : nullGV,
pgvTransferSyntax ? *pgvTransferSyntax : nullGV,
pNextVector->binding[i].string,
pUuidVector,
psslNewCache
);
midl_user_free(pNextVector->binding[i].entry_name);
midl_user_free(pNextVector->binding[i].string);
if (pUuidVector) {
for (unsigned int j = 0; j < pUuidVector->count; j++)
midl_user_free(pUuidVector->uuid[j]);
midl_user_free(pUuidVector);
}
pUuidVector = NULL;
}
midl_user_free(pNextVector);
}
TEntryIterator *pCacheIter = new TSSLEntryListIterator(*psslNewCache);
plhFetched = new CGroupLookupHandle(
pCacheIter,
pgvInterface,
pgvTransferSyntax,
pidObject,
ulVS,
ulCacheMax
);
/* do not delete psslNewCache -- it is done by the constructor above */
return TRUE;
}
void
CMasterLookupHandle::rundown()
/*++
Method Description:
Release the binding to the master and the context handle received from the master.
Remarks:
The reason to separate this from the destructor is similar to the case of
initialize(), i.e., finalization may happen due to reinitialization rather than
destruction.
--*/{
DBGOUT(TRACE,"CMasterLookupHandle::rundown called for Handle#" << ulHandleNo << "\n\n");
STATUS status;
// First do the standard rundown for remote handles
CRemoteLookupHandle::rundown();
// Then try closing lookupHandle in master locator
if (hCurrentMaster) {
RpcImpersonateClient(0);
RpcTryExcept {
CLIENT_I_nsi_lookup_done(
hCurrentMaster,
&lookupHandle,
&status
);
}
RpcExcept (EXCEPTION_EXECUTE_HANDLER) {
DBGOUT(MEM1,"Could not close lookup handle in master\n\n");
}
RpcEndExcept;
RpcBindingFree(&hCurrentMaster);
hCurrentMaster = NULL;
RpcRevertToSelf();
}
}
CMasterObjectInqHandle::CMasterObjectInqHandle(
STRING_T szEntryName,
ULONG ulCacheAge
)
: CRemoteObjectInqHandle(szEntryName,ulCacheAge)
{
}
void
CMasterObjectInqHandle::initialize() {
ulIndex = 0;
StatusCode = NSI_S_OK;
RpcMgmtSetCancelTimeout(CONNECTION_TIMEOUT);
RPC_BINDING_HANDLE hCurrentMaster =
ConnectToMasterLocator(
StatusCode
);
if (!hCurrentMaster || StatusCode) {
myRpcLocator->SetDCsDown();
return;
}
else myRpcLocator->SetDCsUp();
/* The following is a work around, because the compiler refuses to accept
penEntryName ? (*penEntryName) : NULL
*/
STRING_T szEntryName = NULL;
if (penEntryName) szEntryName = *penEntryName;
pUuidVector = getObjectVector(
hCurrentMaster,
RPC_C_NS_SYNTAX_DCE,
szEntryName,
StatusCode
);
ulCreationTime = CurrentTime();
fNotInitialized = FALSE;
}