00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
#include "lpcp.h"
00024 
00025 
#ifdef ALLOC_PRAGMA
00026 
#pragma alloc_text(PAGE,LpcpFreePortClientSecurity)
00027 
#pragma alloc_text(PAGE,NtImpersonateClientOfPort)
00028 
#endif
00029 
00030 
00031 
NTSTATUS
00032 NtImpersonateClientOfPort (
00033     IN HANDLE PortHandle,
00034     IN PPORT_MESSAGE Message
00035     )
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
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     
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     
00118     
00119     
00120 
00121     
Status = 
LpcpReferencePortObject( 
PortHandle, 0,
00122                                       PreviousMode, &PortObject );
00123     
if (!
NT_SUCCESS( 
Status )) {
00124 
00125         
return( 
Status );
00126     }
00127 
00128     
00129     
00130     
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     
00142     
00143     
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     
00159     
00160     
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     
00181     
00182     
00183     
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     
00200     
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             
00215             
00216 
00217             
if ( ThreadWaitingForReply ==  
ClientThread) {
00218 
00219                 
break;
00220             }
00221 
00222             Next = Next->Flink;
00223         }
00224 
00225         
00226         
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     
00246     
00247     
00248     
00249 
00250     
if (ConnectedPort->
Flags & 
PORT_DYNAMIC_SECURITY) {
00251 
00252         
00253         
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         
00277         
00278 
00279         
Status = 
SeImpersonateClientEx( &ConnectedPort->
StaticSecurity, 
NULL );
00280 
00281     }
00282 
00283     
ObDereferenceObject( PortObject );
00284     
ObDereferenceObject( 
ClientThread );
00285     
ObDereferenceObject( ConnectedPort );
00286 
00287     
00288     
00289     
00290 
00291     
return Status;
00292 }
00293 
00294 
00295 
VOID
00296 LpcpFreePortClientSecurity (
00297     IN 
PLPCP_PORT_OBJECT Port
00298     )
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 {
00318     
00319     
00320     
00321 
00322     
if ((Port->Flags & 
PORT_TYPE) == 
CLIENT_COMMUNICATION_PORT) {
00323 
00324         
00325         
00326         
00327         
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     
00341     
00342 
00343     
return;
00344 }