test: lpcpriv.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# lpcpriv.c File Reference

`#include "lpcp.h"`

Go to the source code of this file.

## Functions

NTSTATUS | NtImpersonateClientOfPort (IN HANDLE PortHandle, IN PPORT_MESSAGE Message)
VOID | LpcpFreePortClientSecurity (IN PLPCP_PORT_OBJECT Port)

## Function Documentation

VOID LpcpFreePortClientSecurity | ( | IN PLPCP_PORT_OBJECT | Port | ) |

Definition at line 296 of file lpcpriv.c.

References CLIENT_COMMUNICATION_PORT, PORT_DYNAMIC_SECURITY, PORT_TYPE, and SeDeleteClientSecurity.

Referenced by LpcpDeletePort().

    00302                    :
    00303
    00304     This routine cleans up the captured security context for a client port.
    00305     The cleanup is typically done when we are deleting a port
    00306
    00307 Arguments:
    00308
    00309     Port - Supplies the client port being deleted
    00310
    00311 Return Value:
    00312
    00313     None.
    00314
    00315 --*/
    00316
    00317 {
    00318     //
    00319     //  We only do this action if supplied with a client communication port
    00320     //
    00321
    00322     if ((Port->Flags & PORT_TYPE) == CLIENT_COMMUNICATION_PORT) {
    00323
    00324         //
    00325         //  We only do this action if the port has static security tracking,
    00326         //  and we have a captured client token.  The action is to simply
    00327         //  delete the client token.
    00328         //
    00329
    00330         if (!(Port->Flags & PORT_DYNAMIC_SECURITY)) {
    00331
    00332             if ( Port->StaticSecurity.ClientToken ) {
    00333
    00334                 SeDeleteClientSecurity( &(Port)->StaticSecurity );
    00335             }
    00336         }
    00337     }
    00338
    00339     //
    00340     //  And return to our caller
    00341     //
    00342
    00343     return;
    00344 }
    }

NTSTATUS NtImpersonateClientOfPort | ( | IN HANDLE | PortHandle,
|  | IN PPORT_MESSAGE | Message
| ) |

Definition at line 32 of file lpcpriv.c.

References ClientThread(), _LPCP_PORT_OBJECT::ConnectedPort, EXCEPTION_EXECUTE_HANDLER, _LPCP_PORT_OBJECT::Flags, KernelMode, KPROCESSOR_MODE, LpcpAcquireLpcpLock, LpcpFreeDynamicClientSecurity, LpcpGetDynamicClientSecurity, LpcpReferencePortObject, LpcpReleaseLpcpLock, _LPCP_PORT_OBJECT::LpcReplyChainHead, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObject, PAGED_CODE, PORT_DELETED, PORT_DYNAMIC_SECURITY, PORT_TYPE, PortHandle, ProbeForRead, PsLookupProcessThreadByCid(), SeImpersonateClientEx(), SERVER_COMMUNICATION_PORT, _LPCP_PORT_OBJECT::StaticSecurity, and Status.

Referenced by RtlImpersonateLpcClient(), and SepServerImpersonateClient().

    00039                    :
    00040
    00041     This procedure is used by the server thread to temporarily acquire the
    00042     identifier set of a client thread.
    00043
    00044     This service establishes an impersonation token for the calling thread.
    00045     The impersonation token corresponds to the context provided by the port
    00046     client.  The client must currently be waiting for a reply to the
    00047     specified message.
    00048
    00049     This service returns an error status code if the client thread is not
    00050     waiting for a reply to the message.  The security quality of service
    00051     parameters specified by the client upon connection dictate what use the
    00052     server will have of the client's security context.
    00053
    00054     For complicated or extended impersonation needs, the server may open a
    00055     copy of the client's token (using NtOpenThreadToken()).  This must be
    00056     done while impersonating the client.
    00057
    00058 Arguments:
    00059
    00060     PortHandle - Specifies the handle of the communication port that the
    00061         message was received from.
    00062
    00063     Message - Specifies an address of a message that was received from the
    00064         client that is to be impersonated.  The ClientId field of the message
    00065         identifies the client thread that is to be impersonated.  The client
    00066         thread must be waiting for a reply to the message in order to
    00067         impersonate the client.
    00068
    00069 Return Value:
    00070
    00071     NTSTATUS - Status code that indicates whether or not the operation was
    00072     successful.
    00073
    00074 --*/
    00075
    00076 {
    00077     PLPCP_PORT_OBJECT PortObject;
    00078     PLPCP_PORT_OBJECT ConnectedPort;
    00079     KPROCESSOR_MODE PreviousMode;
    00080     NTSTATUS Status;
    00081     PETHREAD ClientThread;
    00082     CLIENT_ID CapturedClientId;
    00083     ULONG CapturedMessageId;
    00084     SECURITY_CLIENT_CONTEXT DynamicSecurity;
    00085     PLIST_ENTRY Next, Head;
    00086     PETHREAD ThreadWaitingForReply;
    00087
    00088     PAGED_CODE();
    00089
    00090     //
    00091     //  Get previous processor mode and probe output arguments if necessary.
    00092     //
    00093
    00094     PreviousMode = KeGetPreviousMode();
    00095
    00096     if (PreviousMode != KernelMode) {
    00097
    00098         try {
    00099
    00100             ProbeForRead( Message, sizeof( PORT_MESSAGE ), sizeof( ULONG ));
    00101
    00102             CapturedClientId = Message->ClientId;
    00103             CapturedMessageId = Message->MessageId;
    00104
    00105         } except( EXCEPTION_EXECUTE_HANDLER ) {
    00106
    00107             return( GetExceptionCode() );
    00108         }
    00109
    00110     } else {
    00111
    00112         CapturedClientId = Message->ClientId;
    00113         CapturedMessageId = Message->MessageId;
    00114     }
    00115
    00116     //
    00117     //  Reference the communication port object by handle.  Return status if
    00118     //  unsuccessful.
    00119     //
    00120
    00121     Status = LpcpReferencePortObject( PortHandle, 0,
    00122                                       PreviousMode, &PortObject );
    00123     if (!NT_SUCCESS( Status )) {
    00124
    00125         return( Status );
    00126     }
    00127
    00128     //
    00129     //  It is an error to try this on any port other than a server
    00130     //  communication port
    00131     //
    00132
    00133     if ((PortObject->Flags & PORT_TYPE) != SERVER_COMMUNICATION_PORT) {
    00134
    00135         ObDereferenceObject( PortObject );
    00136
    00137         return( STATUS_INVALID_PORT_HANDLE );
    00138     }
    00139
    00140     //
    00141     //  Translate the ClientId from the connection request into a
    00142     //  thread pointer.  This is a referenced pointer to keep the thread
    00143     //  from evaporating out from under us.
    00144     //
    00145
    00146     Status = PsLookupProcessThreadByCid( &CapturedClientId,
    00147                                          NULL,
    00148                                          &ClientThread );
    00149
    00150     if (!NT_SUCCESS( Status )) {
    00151
    00152         ObDereferenceObject( PortObject );
    00153
    00154         return( Status );
    00155     }
    00156
    00157     //
    00158     //  Acquire the mutex that guards the LpcReplyMessage field of
    00159     //  the thread and get the pointer to the message that the thread
    00160     //  is waiting for a reply to.
    00161     //
    00162
    00163     LpcpAcquireLpcpLock();
    00164
    00165     if ( ( PortObject->ConnectedPort == NULL ) ||
    00166          ( PortObject->ConnectedPort->Flags & PORT_DELETED )) {
    00167
    00168         LpcpReleaseLpcpLock();
    00169
    00170         ObDereferenceObject( PortObject );
    00171         ObDereferenceObject( ClientThread );
    00172
    00173         return( STATUS_PORT_DISCONNECTED );
    00174     }
    00175
    00176     ConnectedPort = PortObject->ConnectedPort;
    00177     ObReferenceObject( ConnectedPort );
    00178
    00179     //
    00180     //  See if the thread is waiting for a reply to the message
    00181     //  specified on this call, if the user gave us a bad
    00182     //  message id.  If not then a bogus message
    00183     //  has been specified, so return failure.
    00184     //
    00185
    00186     if ((ClientThread->LpcReplyMessageId != CapturedMessageId) ||
    00187         (CapturedMessageId == 0)) {
    00188
    00189         LpcpReleaseLpcpLock();
    00190
    00191         ObDereferenceObject( PortObject );
    00192         ObDereferenceObject( ClientThread );
    00193         ObDereferenceObject( ConnectedPort );
    00194
    00195         return (STATUS_REPLY_MESSAGE_MISMATCH);
    00196     }
    00197
    00198     //
    00199     //  Search in the LpcReplyChain if the ClientThread exists
    00200     //  Perform this search only if the client thread is queued to the port object
    00201     //
    00202
    00203     if ( !IsListEmpty( &ClientThread->LpcReplyChain ) ) {
    00204
    00205         ThreadWaitingForReply = NULL;
    00206         Head = &PortObject->LpcReplyChainHead;
    00207         Next = Head->Flink;
    00208
    00209         while ((Next != NULL) && (Next != Head)) {
    00210
    00211             ThreadWaitingForReply = CONTAINING_RECORD( Next, ETHREAD, LpcReplyChain );
    00212
    00213             //
    00214             //  If found the Client thread, quit from the loop
    00215             //
    00216
    00217             if ( ThreadWaitingForReply ==  ClientThread) {
    00218
    00219                 break;
    00220             }
    00221
    00222             Next = Next->Flink;
    00223         }
    00224
    00225         //
    00226         //  If not found, return an error
    00227         //
    00228
    00229         if (ThreadWaitingForReply !=  ClientThread) {
    00230
    00231             LpcpReleaseLpcpLock();
    00232
    00233             ObDereferenceObject( PortObject );
    00234             ObDereferenceObject( ClientThread );
    00235             ObDereferenceObject( ConnectedPort );
    00236
    00237             return (STATUS_REPLY_MESSAGE_MISMATCH);
    00238         }
    00239     }
    00240
    00241
    00242     LpcpReleaseLpcpLock();
    00243
    00244     //
    00245     //  If the client requested dynamic security tracking, then the client
    00246     //  security needs to be referenced.  Otherwise, (static case)
    00247     //  it is already in the client's port.
    00248     //
    00249
    00250     if (ConnectedPort->Flags & PORT_DYNAMIC_SECURITY) {
    00251
    00252         //
    00253         //  Impersonate the client with information from the queued message
    00254         //
    00255
    00256         Status = LpcpGetDynamicClientSecurity( ClientThread,
    00257                                                PortObject->ConnectedPort,
    00258                                                &DynamicSecurity );
    00259
    00260         if (!NT_SUCCESS( Status )) {
    00261
    00262             ObDereferenceObject( PortObject );
    00263             ObDereferenceObject( ClientThread );
    00264             ObDereferenceObject( ConnectedPort );
    00265
    00266             return( Status );
    00267         }
    00268
    00269         Status = SeImpersonateClientEx( &DynamicSecurity, NULL );
    00270
    00271         LpcpFreeDynamicClientSecurity( &DynamicSecurity );
    00272
    00273     } else {
    00274
    00275         //
    00276         //  Impersonate the client with information from the client's port
    00277         //
    00278
    00279         Status = SeImpersonateClientEx( &ConnectedPort->StaticSecurity, NULL );
    00280
    00281     }
    00282
    00283     ObDereferenceObject( PortObject );
    00284     ObDereferenceObject( ClientThread );
    00285     ObDereferenceObject( ConnectedPort );
    00286
    00287     //
    00288     //  And return to our caller
    00289     //
    00290
    00291     return Status;
    00292 }