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.
 
 
 
 
 
 

941 lines
22 KiB

/* --------------------------------------------------------------------
File : osfsvr.hxx
Title : Classes for the OSF RPC protocol module (server classes).
Description :
History :
mikemon ??-??-?? Beginning of recorded history.
mikemon 10-15-90 Changed the shutdown functionality to PauseExecution
rather than suspending and resuming a thread.
mikemon 10-16-90 Added ListenThreadCompleted to OSF_ADDRESS.
-------------------------------------------------------------------- */
#ifndef __OSFSVR_HXX__
#define __OSFSVR_HXX__
class OSF_SCONNECTION;
NEW_SDICT(OSF_ASSOCIATION);
class OSF_ADDRESS : public RPC_ADDRESS
{
private:
OSF_ASSOCIATION_DICT Associations;
int CallThreadCount;
int MinimumCallThreads;
int ServerListeningFlag;
int ReceiveDirectCount;
protected:
OSF_ADDRESS (
IN OUT RPC_STATUS PAPI * RpcStatus
);
public:
virtual
TransMarkReceiveAny ( // Indicate that the specified server
// connection should be waited on when a receive
// operation is performed on the address.
IN OSF_SCONNECTION * Connection
) = 0;
virtual RPC_STATUS
TransReceive ( // Receive from one of the connections marked as receive
// any for this address.
OUT OSF_SCONNECTION * * Connection, // The connection for which the
// receive occured.
IN OUT void * * Buffer, // Buffer of data received from the
// connection.
IN OUT unsigned int * BufferLength
) = 0;
virtual unsigned int // Returns the length of the secondary address.
TransSecondarySize ( // The length will be used to allocate a buffer.
);
virtual RPC_STATUS
TransSecondary ( // Places the secondary address in the specified buffer.
IN unsigned char * Address, // Buffer for the address.
IN unsigned int AddressLength // Length of the buffer.
);
RPC_STATUS
FireUpManager (
IN unsigned int MinimumConcurrentCalls
);
RPC_STATUS
ServerStartingToListen (
IN unsigned int MinimumCallThreads,
IN unsigned int MaximumConcurrentCalls,
IN int ServerThreadsStarted
);
void
ServerStoppedListening (
);
unsigned int
InqNumberOfActiveCalls (
);
OSF_ASSOCIATION * // Returns the association deleted or 0.
RemoveAssociation ( // Remove the association specified by Key from this
// address.
IN int Key
);
int // Indicates success (0), or an error (-1).
AddAssociation ( // Add the specified association to this address.
IN OSF_ASSOCIATION * TheAssociation
);
OSF_ASSOCIATION *
FindAssociation (
IN unsigned long AssociationGroupId,
IN RPC_CLIENT_PROCESS_IDENTIFIER * ClientProcess
);
void
MaybeMakeReceiveDirect (
IN OSF_SCONNECTION * SConnection,
OUT unsigned int PAPI * ReceiveDirectFlag
);
void
ReceiveLotsaCalls (
);
void
NotifyReceiveDirectClosed (
);
virtual RPC_STATUS
SetupAddressWithEndpoint (
IN RPC_CHAR PAPI * Endpoint,
OUT RPC_CHAR PAPI * PAPI * lNetworkAddress,
OUT unsigned int PAPI * NumNetworkAddress,
IN void PAPI * SecurityDescriptor, OPTIONAL
IN unsigned int PendingQueueSize,
IN RPC_CHAR PAPI * RpcProtocolSequence,
IN unsigned long EndpointFlags,
IN unsigned long NICFlags
) = 0;
virtual RPC_STATUS
SetupAddressUnknownEndpoint (
OUT RPC_CHAR PAPI * PAPI * Endpoint,
OUT RPC_CHAR PAPI * PAPI * lNetworkAddress,
OUT unsigned int PAPI * NumNetworkAddress,
IN void PAPI * SecurityDescriptor, OPTIONAL
IN unsigned int PendingQueueSize,
IN RPC_CHAR PAPI * RpcProtocolSequence,
IN unsigned long EndpointFlags,
IN unsigned long NICFlags
) = 0;
#if defined(NTENV) || defined(WIN96)
virtual RPC_STATUS
StartListening (
) = 0;
#endif
int
IsServerListening (
) ;
};
inline int
OSF_ADDRESS::IsServerListening (
)
{
return ServerListeningFlag ;
}
void
ReceiveLotsaCallsWrapper(
IN OSF_ADDRESS PAPI * Address
);
inline void
OSF_ADDRESS::NotifyReceiveDirectClosed (
)
/*++
Routine Description:
This routine will get called to notify an address that a receive direct
connection has closed.
--*/
{
AddressMutex.Request();
ReceiveDirectCount -= 1;
AddressMutex.Clear();
}
#define RPCSTATUS_GET_CREATETHREAD(x) Server->CreateThread( \
(THREAD_PROC)&ReceiveLotsaCallsWrapper,x);
class OSF_SBINDING
{
private:
RPC_SYNTAX_IDENTIFIER InterfaceID;
RPC_SYNTAX_IDENTIFIER TransferSyntaxID;
RPC_INTERFACE * Interface;
unsigned int PresentContext;
unsigned long CurrentSecId;
unsigned long CallbackAccepted;
public:
unsigned long SequenceNumber ;
OSF_SBINDING ( // Constructor.
IN RPC_INTERFACE * TheInterface,
IN RPC_SYNTAX_IDENTIFIER * InterfaceSyntax,
IN RPC_SYNTAX_IDENTIFIER * TransferSyntax,
IN int PContext
) {
InterfaceID = *InterfaceSyntax;
TransferSyntaxID = *TransferSyntax;
PresentContext = PContext;
Interface = TheInterface;
CallbackAccepted = 0;
SequenceNumber = 0;
}
RPC_INTERFACE *
GetInterface (
) {return(Interface);}
unsigned int
GetPresentationContext (
) {return(PresentContext);}
void
CopyTransferSyntax (
OUT RPC_SYNTAX_IDENTIFIER * TransferSyntax
) {
*TransferSyntax = TransferSyntaxID;
}
RPC_SYNTAX_IDENTIFIER *
TransferSyntax (
) {
return(&TransferSyntaxID);
}
inline RPC_STATUS
CheckSecurity (
SCONNECTION * Connetion,
unsigned long AuthId
);
};
inline RPC_STATUS
OSF_SBINDING::CheckSecurity(
SCONNECTION * Connection,
unsigned long AuthId
)
{
if ( (Interface->IsSecurityCallbackReqd() == 0) ||
((SequenceNumber == Interface->SequenceNumber)
&& (AuthId == CurrentSecId)) )
{
return (RPC_S_OK);
}
if (Interface->CheckSecurityIfNecessary(Connection) == RPC_S_OK)
{
SequenceNumber = Interface->SequenceNumber ;
CallbackAccepted = 1;
CurrentSecId = AuthId;
return (RPC_S_OK);
}
else
{
SequenceNumber = 0;
}
return (RPC_S_ACCESS_DENIED);
}
NEW_SDICT(OSF_SBINDING);
NEW_SDICT(SSECURITY_CONTEXT);
class OSF_SCONNECTION : public SCONNECTION
/*++
Class Description:
Fields:
ObjectUuid - Contains the object UUID specified for the remote
procedure call by the client.
ObjectUuidSpecified - Contains a flag which indicates whether
or not the remote procedure call specified an object UUID.
This field will be zero if an object UUID was not specified
in the call, and non-zero if one was specified.
Association - Contains the association to which this connection
belongs. This field will be zero until after the initial client
bind request has been accepted.
ServerSecurityContext - Contains the security context for this connection
if security is being performed at the rpc protocol level.
AuthenticationLevel - Contains a value indicating what authentication
is being performed at the rpc protocol level. A value of
RPC_C_AUTHN_LEVEL_NONE indicates that no authentication is being
performed at the rpc protocol level.
AuthenticationService - Contains which authentication service is being
used at the rpc protocol level.
AuthorizationService - Contains which authorization service is being
used at the rpc protocol level.
AdditionalSpaceForSecurity - Contains the amount of space to save for
security in each buffer we allocate.
FirstCachedBuffer - Contains the first cached buffer.
SecondCachedBuffer - Contains the second cached buffer.
ThirdCachedBuffer - Contains the third cached buffer.
BufferCacheFlags - Contains three flags which control the buffer cache:
a bit indicating whether or not each of the buffers (there are two)
in the cache are available. And a bit indicating whether or not the
cached buffers were allocated.
CachedBufferLength - Contains the length of each cached buffer.
ImpersonatedClientFlag - Contains a flag indicating whether or not this
connection has been used to impersonate the client; a non-zero value
indicates that impersonation has occured.
ReceiveDirectReady - Contains a flag indicating that the connection is
ready to receive remote procedure calls; a non-zero value indicates
this is the case.
DceSecurityInfo - Contains the security information necessary for
DCE security to work correctly.
SavedPac - While a call is being dispatched to manager, the manager
could query for a PAC. However, manager is not explicitly going
to free the PAC. Runtime is supposed to do that. This feild
takes care of that.
AuthzSvc - Authorization service
SavedHeader - Unbyte swapped header + - do that check sums work
--*/
{
private:
OSF_SBINDING_DICT Bindings;
OSF_SBINDING * CurrentBinding;
unsigned short MaxFrag;
unsigned long CallId;
int CallStack;
unsigned long DataRep;
RPC_UUID ObjectUuid;
unsigned int ObjectUuidSpecified;
OSF_ASSOCIATION * Association;
unsigned AuthContextId;
SSECURITY_CONTEXT * CurrentSecurityContext;
SSECURITY_CONTEXT_DICT SecurityContextDict;
unsigned int AdditionalSpaceForSecurity;
unsigned long RpcSecurityBeingUsed;
unsigned long SecurityContextAltered;
void PAPI * FirstCachedBuffer;
void PAPI * SecondCachedBuffer;
void PAPI * ThirdCachedBuffer;
unsigned int BufferCacheFlags;
unsigned int CachedBufferLength;
unsigned int ImpersonatedClientFlag;
unsigned int ReceiveDirectReady;
unsigned long SavedHeaderSize;
void PAPI * SavedHeader;
unsigned int FragmentLength ;
unsigned int CurrentBufferLength ;
int FirstFrag ;
protected:
THREAD * Thread;
int AlertCount;
int CallOrphaned;
LONG CancelPending;
DCE_SECURITY_INFO DceSecurityInfo;
// Count of the number of buffers allocated for this connection, but
// not yet freed. Note, this member should actually be protected.
int OutstandingBuffers;
// Time of the last call.
long LastCall;
MUTEX CachedBufferMutex;
long ExtendedError;
OSF_SCONNECTION (
IN OUT RPC_STATUS PAPI * RpcStatus
);
public:
OSF_ADDRESS * ReceiveDirectAddress;
virtual ~OSF_SCONNECTION ( // Destructor.
);
// --------------------------------------------------------------------
virtual RPC_STATUS
SendReceive (
IN OUT PRPC_MESSAGE Message
);
virtual RPC_STATUS
GetBuffer (
IN OUT PRPC_MESSAGE Message
);
RPC_STATUS
GetBufferDo (
IN PRPC_MESSAGE Message,
IN unsigned int culRequiredLength,
OUT void ** ppBuffer,
IN unsigned long Extra
);
virtual void
FreeBuffer (
IN PRPC_MESSAGE Message
);
virtual void
FreePipeBuffer (
IN PRPC_MESSAGE Message
) ;
virtual RPC_STATUS
ReallocPipeBuffer (
IN PRPC_MESSAGE Message,
IN unsigned int NewSize
) ;
virtual RPC_STATUS
Receive (
IN OUT PRPC_MESSAGE Message,
IN unsigned int Size
) ;
RPC_STATUS
ReceiveFirstFrag(
IN OUT PRPC_MESSAGE Message,
IN int Callback
) ;
RPC_STATUS
MonitorAssociation (
IN PRPC_RUNDOWN RundownRoutine,
IN void * pContext
);
RPC_STATUS // Value to be returned by the RpcMonitorAssociation
// API.
StopMonitorAssociation ( // Monitor the association for this connection.
);
RPC_STATUS // Value to be returned by the RpcGetAssociationContext API.
GetAssociationContext (
OUT void ** AssociationContext
);
RPC_STATUS // set the association context field
SetAssociationContext (
IN void * pContext
);
RPC_STATUS
ImpersonateClient (
);
RPC_STATUS
RevertToSelf (
);
RPC_STATUS
IsClientLocal (
OUT unsigned int PAPI * ClientLocalFlag
);
RPC_STATUS
ConvertToServerBinding (
OUT RPC_BINDING_HANDLE __RPC_FAR * ServerBinding
);
// --------------------------------------------------------------------
virtual RPC_STATUS
TransReceive ( // Receive a buffer of data from the transport.
IN OUT void * * Buffer,
IN OUT unsigned int * BufferLength,
IN unsigned int CanMigrate
) = 0;
virtual RPC_STATUS
TransSend ( // Send a buffer of data on the transport.
IN void * Buffer,
IN unsigned int BufferLength
) = 0;
virtual RPC_STATUS
TransSendReceive ( // Send a buffer of data on the transport, and then
// receive a buffer of data from the transport. Note: some
// transports allow this to be performed as one operation.
IN void * SendBuffer,
IN unsigned int SendBufferLength,
IN OUT void * * ReceiveBuffer,
IN OUT unsigned int * ReceiveBufferLength
) = 0;
virtual RPC_STATUS
TransGetBuffer ( // Allocate a buffer of the specified size.
OUT void * * Buffer,
IN unsigned int BufferLength
);
virtual void
TransFreeBuffer ( // Free a buffer.
IN void PAPI * Buffer
);
virtual unsigned int // Returns the maximum size of a send.
TransMaximumSend ( // Returns the maximum size allowed for a send.
) = 0;
virtual RPC_STATUS // Value to be returned by RpcImpersonateClient.
TransImpersonateClient ( // Attempts to impersonate the client in a
// transport specific fashion.
) = 0;
virtual void
TransRevertToSelf ( // Stops impersonating a client.
) = 0;
virtual void
TransQueryClientProcess (
OUT RPC_CLIENT_PROCESS_IDENTIFIER * ClientProcess
) = 0;
virtual RPC_STATUS
TransQueryClientNetworkAddress (
OUT RPC_CHAR ** NetworkAddress
) = 0;
#if defined(NTENV) || defined(WIN96)
virtual unsigned int
TransGetReceiveDirectFlag (
) = 0;
virtual void
SetReceiveAnyFlag (
IN unsigned int
) = 0;
virtual void
SetReceiveDirectFlag(
IN unsigned int ReceiveAnyFlag
) = 0;
#endif
// --------------------------------------------------------------------
int
AssociationRequested (
IN OSF_ADDRESS * Address,
IN rpcconn_bind * BindPacket,
IN unsigned int BindPacketLength
);
int // Indicates if the connection canbe removed by returning 1
fCanDiscard(
);
int // Indicates success (0), or an internal error code.
AlterContextRequested ( // Process the alter context request. Send
// a reply.
IN rpcconn_alter_context * pAlterContext,
IN unsigned int culAlterContextLength,
IN OSF_ADDRESS * Address
);
int // Indicates success (0), or an internal error code.
SendBindNak ( // Construct and send the bind nak packet using the
// specified reject reason.
IN p_reject_reason_t reject_reason
);
unsigned int
InqMaximumFragmentLength (
);
void
SetCallId(
unsigned long CallId
);
private:
int
ProcessPContextList (
IN OSF_ADDRESS * Address,
IN p_cont_list_t * PContextList,
IN OUT unsigned int * PContextListLength,
OUT p_result_list_t * ResultList
);
public:
unsigned int
GuessBufferSize (
);
int
DispatchPacket (
IN rpcconn_common * Packet,
IN unsigned int PacketLength,
IN OSF_ADDRESS * Address
);
int
ReceiveOriginalCall (
IN rpcconn_common * Packet,
IN unsigned int PacketLength
);
void
SendFault (
IN RPC_STATUS Status,
IN int DidNotExecute
);
RPC_STATUS
ReceiveMessage (
IN OUT PRPC_MESSAGE Message,
OUT unsigned int PAPI * RemoteFaultOccured
);
#define MAX_ALLOC_Hint 16*1024
RPC_STATUS
EatAuthInfoFromPacket (
IN rpcconn_request PAPI * Request,
IN OUT unsigned int PAPI * RequestLength
);
RPC_STATUS
ReceiveRequestOrResponse (
IN PRPC_MESSAGE Message
);
RPC_STATUS
ReceiveNextChunk (
IN PRPC_MESSAGE Message,
IN unsigned int Size,
IN int FirstReceive = 0,
IN int SecurityFailureOccured = 0
);
RPC_STATUS
Send(
IN OUT PRPC_MESSAGE Message
) ;
RPC_STATUS
SendRequestOrResponse (
IN OUT PRPC_MESSAGE Message,
IN unsigned char PacketType,
IN int IsPartial = 0
);
RPC_STATUS
SendFragment(
IN OUT rpcconn_common PAPI *pFragment,
IN unsigned int LastFragmentFlag,
IN unsigned int HeaderSize,
IN unsigned int MaxSecuritySize,
IN unsigned int DataLength,
IN unsigned int MaximumFragmentLength,
IN unsigned char PAPI *ReservedForSecurity,
OUT void PAPI * PAPI *ReceiveBuffer,
OUT unsigned int *ReceiveBufferLength
) ;
OSF_ASSOCIATION *
TheAssociation (
) {return(Association);}
void
ReceiveLotsaCalls (
);
void
InquireObjectUuid (
OUT RPC_UUID PAPI * ObjectUuid
);
RPC_STATUS
ToStringBinding (
OUT RPC_CHAR PAPI * PAPI * StringBinding
);
RPC_STATUS
InquireAuthClient (
OUT RPC_AUTHZ_HANDLE PAPI * Privileges,
OUT RPC_CHAR PAPI * PAPI * ServerPrincipalName, OPTIONAL
OUT unsigned long PAPI * AuthenticationLevel,
OUT unsigned long PAPI * AuthenticationService,
OUT unsigned long PAPI * AuthorizationService
);
virtual void
Delete (
);
void
ReceiveDirect (
);
void
NotifyReceiveDirectReady (
);
#if defined(NTENV) || defined(WIN96)
void
NotifyReceiveDirectCancelled(
) ;
#endif
void
RemoveFromAssociation (
);
inline
SSECURITY_CONTEXT *
FindSecurityContext(
unsigned long Id,
unsigned long Level,
unsigned long Svc
);
virtual RPC_STATUS
InqTransportType(
OUT unsigned int __RPC_FAR * Type
) ;
RPC_STATUS
Cancel(
void * ThreadHandle
);
unsigned
TestCancel(
);
};
inline RPC_STATUS
OSF_SCONNECTION::InqTransportType(
OUT unsigned int __RPC_FAR * Type
)
{
*Type = TRANSPORT_TYPE_CN ;
return (RPC_S_OK) ;
}
inline unsigned int
OSF_SCONNECTION::InqMaximumFragmentLength (
)
/*++
Return Value:
The maximum fragment length negotiated for this connection will be
returned.
--*/
{
return(MaxFrag);
}
inline
void OSF_SCONNECTION::SetCallId(
unsigned long Call
)
{
CallId = Call;
}
inline
SSECURITY_CONTEXT *
OSF_SCONNECTION::FindSecurityContext(
unsigned long Id,
unsigned long Level,
unsigned long Svc
)
{
SSECURITY_CONTEXT *Sec;
SecurityContextDict.Reset();
while ( (Sec = SecurityContextDict.Next()) != 0 )
{
if ( (Sec->AuthContextId == Id)
&&(Sec->AuthenticationLevel == Level)
&&(Sec->AuthenticationService == Svc) )
{
break;
}
}
return (Sec);
}
class OSF_ASSOCIATION : public ASSOCIATION_HANDLE
{
private:
int ConnectionCount;
unsigned long AssociationGroupId;
int AssociationDictKey;
OSF_ADDRESS * Address;
RPC_CLIENT_PROCESS_IDENTIFIER ClientProcess;
public:
OSF_ASSOCIATION (
IN OSF_ADDRESS * TheAddress,
IN RPC_CLIENT_PROCESS_IDENTIFIER * ClientProcess,
OUT RPC_STATUS * Status
);
~OSF_ASSOCIATION ( // Destructor.
);
void
AddConnection ( // Add a connection to the association.
);
int // Indicates success (0), or an internal error.
RemoveConnection ( // Remove a connection from the association.
);
int // Returns the association group id for this association.
AssocGroupId (
) {return(AssociationGroupId);}
OSF_ADDRESS *
TheAddress (
) {return(Address);}
int
TheConnectionCount (
) {return(ConnectionCount);}
int
IsMyAssocGroupId (
IN unsigned long PossibleAssocGroupId,
IN RPC_CLIENT_PROCESS_IDENTIFIER * ClientProcess
);
};
inline int
OSF_ASSOCIATION::IsMyAssocGroupId (
IN unsigned long PossibleAssocGroupId,
IN RPC_CLIENT_PROCESS_IDENTIFIER * ClientProcess
)
/*++
Routine Description:
We compare the supplied possible association group id against my
association group id in this routine.
Arguments:
PossibleAssocGroupId - Supplies a possible association group id to
compare against mine.
ClientProcess - Supplies the identifier for the client process at the
other end of the connection requesting this association.
Return Value:
Non-zero will be returned if the possible association group id is the
same as my association group id.
--*/
{
return( ( PossibleAssocGroupId == AssociationGroupId )
&& ( this->ClientProcess.FirstPart == ClientProcess->FirstPart )
&& ( this->ClientProcess.SecondPart == ClientProcess->SecondPart ) );
}
inline void
OSF_SCONNECTION::RemoveFromAssociation (
)
/*++
Routine Description:
This connection will be removed from the association. We need to do
this so that context rundown will occur, even though the connection
has not been deleted yet.
--*/
{
if ( Association != 0 )
{
Association->RemoveConnection();
Association = 0;
}
}
#endif // __OSFSVR_HXX__