InitTermSrv函数中的WinStationInitLPC和WinStationInitRPC函数
InitTermSrv函数中的WinStationInitLPC和WinStationInitRPC函数
04:05:41.953 8981FF7C.E13E5450 TERMSRV: WinStation LPC Service Thread got a message
04:05:41.953 8981FF7C.E13E5450 TERMSRV: WinStation LPC Service Thread got connection message
04:05:41.953 8981FF7C.E13E5450 TERMSRV: WinStationLpcHandleConnectionRequest called
04:05:41.953 8981FF7C.E13E5450 TERMSRV: WSTAPI: Creating View memory
04:05:41.953 8981FF7C.E13E5450 TERMSRV: WSTAPI: Calling AcceptConnectPort, Accept 1
04:05:41.953 8981FF7C.E13E5450 TERMSRV: pContext 000F0670, ConnectionRequest 027FFEAC, info 027FFEC4
04:05:41.953 8981FF7C.E13E5450 TERMSRV: ViewBase 024B0000, ViewSize 0x2000, ViewRemoteBase 00640000
04:05:41.953 8981FF7C.E13E5450 TERMSRV: WSTAPI: Calling CompleteConnect port 00000334
04:05:41.953 8981FF7C.E13E5450 TERMSRV: WinStation LPC Connection Accepted, Logonid 9 pContext 000F0670 Status 0x0
04:05:41.953 8984492C.E12576D8 TERMSRV: WinStation LPC Service Thread got a message
04:05:41.953 8984492C.E12576D8 TERMSRV: WinStation LPC Service Thread got WinStationGetSMCommand message
04:05:41.953 8984492C.E12576D8 TERMSRV: WinStationGetSMCommand, LogonId=9
04:05:41.953 8984492C.E12576D8 TERMSRV: WinStationGetSMCommand queue empty port 00000334
04:05:41.968 89756464.E1A75740 TERMSRV: -|--------------------------------------------|-
04:05:41.968 89756464.E1A75740 TERMSRV: Client SPN: NT AUTHORITY\SYSTEM
04:05:41.968 89756464.E1A75740 TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_PKT_PRIVACY
04:05:41.968 89756464.E1A75740 TERMSRV: Authentication service: RPC_C_AUTHN_WINNT
04:05:41.968 89756464.E1A75740 TERMSRV: -|--------------------------------------------|-
04:05:41.968 898908EC.E1887F38 TERMSRV: -|--------------------------------------------|-
04:05:41.968 898908EC.E1887F38 TERMSRV: Client SPN: NT AUTHORITY\SYSTEM
04:05:41.968 898908EC.E1887F38 TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_PKT_PRIVACY
04:05:41.968 898908EC.E1887F38 TERMSRV: Authentication service: RPC_C_AUTHN_WINNT
04:05:41.968 898908EC.E1887F38 TERMSRV: -|--------------------------------------------|-
04:05:41.968 898908EC.E1887F38 TERMSRV: WinStationWaitForConnect, LogonId=9
04:05:41.968 898908EC.E1887F38 TERMSRV: WaitForConnectWorker, LogonId=9
TERMSRV: WaitForConnectWorker, LogonId=9
第一部分:
/****************************************************************************/
// ServiceMain
//
// TermSrv service entry point.
/****************************************************************************/
VOID ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
Status = InitTermSrv(hKeyTermSrv);
if (!NT_SUCCESS(Status))
goto ShutdownService;
/*
* Initialize WinStationAPI's
*/
Status = WinStationInitRPC();
ASSERT( NT_SUCCESS( Status ) );
if (!NT_SUCCESS(Status)) {
goto done;
}
第二部分:
/****************************************************************************/
// InitTermSrv
//
// Service-load-time initialization.
/****************************************************************************/
NTSTATUS InitTermSrv(HKEY hKeyTermSrv)
{
NTSTATUS Status;
DWORD dwLen;
DWORD dwType;
ULONG szBuffer[MAX_PATH/sizeof(ULONG)];
FILETIME policyTime;
WSADATA wsaData;
Status = WinStationInitLPC();
ASSERT( NT_SUCCESS( Status ) );
if (!NT_SUCCESS(Status)) {
goto badInitLPC;
}
第三部分:
/*****************************************************************************
*
* WinStationInitLPC
*
* Create the Session manager WinStation API LPC port and Thread
*
* ENTRY:
* No Parameters
*
* EXIT:
* STATUS_SUCCESS - no error
*
****************************************************************************/
NTSTATUS
WinStationInitLPC()
{
ULONG i;
NTSTATUS st;
ANSI_STRING Name;
UNICODE_STRING UnicodeName;
OBJECT_ATTRIBUTES ObjA;
ULONG Length;
SYSTEM_BASIC_INFORMATION SysInfo;
PSECURITY_DESCRIPTOR SecurityDescriptor;
TRACE((hTrace,TC_ICASRV,TT_API1,"TERMSRV: WinSta: Init WinStation LPC Channels\n"));
/*
* Initialize PC context LIst
*/
InitializeListHead(&gTermsrvLpcListHead);
/*
* create a security descriptor that allows only SYSTEM access
*/
SecurityDescriptor = BuildSystemOnlySecurityDescriptor();
if (!SecurityDescriptor)
{
return STATUS_NO_MEMORY;
}
/*
* Create the port for the WIN32 CSRSS's to connect to.
*/
RtlInitAnsiString( &Name, "\\SmSsWinStationApiPort" );
st = RtlAnsiStringToUnicodeString( &UnicodeName, &Name, TRUE);
if (!NT_SUCCESS(st))
{
MemFree( SecurityDescriptor );
return st;
}
InitializeObjectAttributes( &ObjA, &UnicodeName, 0, NULL,
SecurityDescriptor );
TRACE((hTrace,TC_ICASRV,TT_API1,"TERMSRV: Creating SsApiPort\n"));
ASSERT( sizeof(WINSTATION_APIMSG) <= PORT_MAXIMUM_MESSAGE_LENGTH );
st = NtCreatePort( &SsWinStationLpcPort,
&ObjA,
sizeof(WINSTATIONAPI_CONNECT_INFO),
sizeof(WINSTATION_APIMSG),
sizeof(WINSTATION_APIMSG) * 32 );
RtlFreeUnicodeString(&UnicodeName);
/*
* Clean up security stuff
*/
MemFree( SecurityDescriptor );
if (!NT_SUCCESS(st))
{
return st;
}
/*
* Determine min/max number of API threads we will support
*/
if (g_bPersonalTS) {
MinApiThreads = 1;
MaxApiThreads = 100;
}
else {
MinApiThreads = 3;
st = NtQuerySystemInformation( SystemBasicInformation,
&SysInfo, sizeof(SysInfo), &Length );
if ( NT_SUCCESS( st ) )
MaxApiThreads = 100; // (3 + SysInfo.NumberOfProcessors * 2);
else {
DBGPRINT(( "TERMSRV: NtQuerySystemInfo failed, rc=0x%x\n", st ));
MaxApiThreads = 100;
}
}
NumApiThreads = 0;
WaitingApiThreads = 0;
st = RtlInitializeCriticalSection( &ApiThreadLock );
if(!(NT_SUCCESS(st))) {
return(st);
}
/*
* Create Initial Set of Server Threads
*/
TRACE((hTrace,TC_ICASRV,TT_API1,"TERMSRV: Creating WinStation LPC Server Threads\n"));
for ( i = 0; i < MinApiThreads; i++ ) {
DWORD ThreadId;
HANDLE Handle;
Handle = CreateThread( NULL,
0,
(LPTHREAD_START_ROUTINE)WinStationLpcThread,
NULL,
THREAD_SET_INFORMATION,
&ThreadId );
if ( !Handle ) {
return( STATUS_TOO_MANY_THREADS );
} else {
NtClose( Handle );
}
}
RtlEnterCriticalSection( &ApiThreadLock );
NumApiThreads += MinApiThreads;
第四部分:
/****************************************************************************/
// ServiceMain
//
// TermSrv service entry point.
/****************************************************************************/
VOID ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
/*
* Initialize WinStationAPI's
*/
Status = WinStationInitRPC();
ASSERT( NT_SUCCESS( Status ) );
if (!NT_SUCCESS(Status)) {
goto done;
}
./winsta/server/winsta.c:179:NTSTATUS WinStationInitRPC( VOID );
第五部分:
/*****************************************************************************
* WinStationInitRPC
*
* Setup the RPC bindings, and listen for incoming requests.
****************************************************************************/
RPC_STATUS
WinStationInitRPC( VOID
)
{
RPC_STATUS Status;
DWORD Result;
RPC_BINDING_VECTOR *pBindingVector;
TRACE((hTrace,TC_ICASRV,TT_API2,"RPC WinStationInitRPC\n"));
//
// Initialize the Critical Sections that are
// necessary for RpcWinStationGetAllProcesses
//
gbRpcGetAllProcessesOK =
((NT_SUCCESS(RtlInitializeCriticalSection(&gRpcGetAllProcessesLock))
&& (NT_SUCCESS(RtlInitializeCriticalSection(&gRpcPointersDatabaseLock)))
)? TRUE : FALSE);
gbRpcSidCacheOK =
NT_SUCCESS(RtlInitializeCriticalSection(&gRpcSidCacheLock)) ? TRUE :
FALSE;
InitializeListHead(&gSidCacheHead);
// register the LPC (local only) interface
Status = RpcServerUseProtseqEp(
L"ncalrpc", // Protocol Sequence (LPC)
MAX_WINSTATION_RPC_THREADS, // Maximum calls at one time
L"IcaApi", // Endpoint
NULL // Pass NULL for Security - RPC will take care of the correct Security based on Protocol Sequence used
);
if( Status != RPC_S_OK ) {
TRACE((hTrace,TC_ICASRV,TT_ERROR,"IcaServ: Error %d RpcUseProtseqEp on ncalrpc\n",Status));
return( Status );
}
//
// register the Named pipes interface
// (remote with NT domain authentication)
//
Status = RpcServerUseProtseqEp(
L"ncacn_np", // Protocol Sequence
MAX_WINSTATION_RPC_THREADS, // Maximum calls at one time
L"\\pipe\\Ctx_WinStation_API_service", // Endpoint
NULL // Security
);
if( Status != RPC_S_OK ) {
TRACE((hTrace,TC_ICASRV,TT_ERROR,"TERMSRV: Error %d RpcUseProtseqEp on ncacn_np\n",Status));
return( Status );
}
// Register our interface handle
Status = RegisterRPCInterface( FALSE );
第六部分:
RPC_STATUS
RegisterRPCInterface(
BOOL bReregister)
{
RPC_STATUS Status;
static BOOL bRunSecure = FALSE;
WCHAR *szDefaultSPN = NULL;
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: IN RegisterRPCInterface Reregister=%d OldSecure= %d Secure=%d\n",bReregister, bRunSecure, g_MachinePolicy.fEncryptRPCTraffic));
if(bReregister)
{
if( bRunSecure == g_MachinePolicy.fEncryptRPCTraffic )
{
return RPC_S_OK;
}
}
else
{
Status = RpcServerInqDefaultPrincName(RPC_C_AUTHN_GSS_NEGOTIATE, &szDefaultSPN);
if( Status != RPC_S_OK )
{
TRACE((hTrace,TC_ICASRV,TT_ERROR,"TERMSRV: Error %d RpcServerInqDefaultPrincName\n",Status));
return( Status );
}
Status = RpcServerRegisterAuthInfo(
szDefaultSPN, // service SPN,
RPC_C_AUTHN_GSS_NEGOTIATE,
NULL,
NULL );
if (szDefaultSPN) {
RpcStringFree(&szDefaultSPN);
}
if( Status != RPC_S_OK )
{
TRACE((hTrace,TC_ICASRV,TT_ERROR,"TERMSRV: Error %d RpcServerRegisterAuthInfo\n",Status));
return( Status );
}
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: RpcServerRegisterAuthInfo OK!\n"));
}
bRunSecure = g_MachinePolicy.fEncryptRPCTraffic;
// Register our interface handle
Status = RpcServerRegisterIfEx(
IcaApi_ServerIfHandle,
NULL,
NULL,
bRunSecure ? RPC_IF_ALLOW_SECURE_ONLY : RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH,
RPC_C_LISTEN_MAX_CALLS_DEFAULT,
&RpcSecurityCallback);
if( Status != RPC_S_OK )
{
TRACE((hTrace,TC_ICASRV,TT_ERROR,"TERMSRV: Error %d RpcServerRegisterIf\n",Status));
return( Status );
}
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: RpcServerRegisterIfEx OK!\n"));
return( Status );
}
第七部分:
RPC_STATUS __stdcall
RpcSecurityCallback(
IN RPC_IF_HANDLE Interface,
IN void *Context)
{
RPC_STATUS status;
WCHAR *szStringBinding = NULL;
WCHAR *szProtSeq = NULL;
RPC_CALL_ATTRIBUTES CallAttributes; // this maps to RPC_CALL_ATTRIBUTES_V1
BOOL bUsingLPC;
BOOL bUsingNP;
#ifdef DBG
//To enable tracing, set these registry values:
//HKLM\System\CurrentControlSet\Control\TerminalServer:
//TraceEnable=(dword)0x8
//TraceClass=(dword)0x1
//TraceDebugger=(dword)0x1
PrintClientInfo();
#endif //DBG
status = RpcBindingToStringBinding(Context, &szStringBinding);
if(status != RPC_S_OK)
{
TRACE((hTrace,TC_ICASRV,TT_ERROR,"TERMSRV: RpcBindingToStringBinding failed - %d\n", status));
return ERROR_ACCESS_DENIED;
}
第八部分:
#ifdef DBG
void PrintClientInfo()
{
RPC_STATUS status;
RPC_CALL_ATTRIBUTES CallAttributes;
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: -|--------------------------------------------|-\n"));
memset(&CallAttributes, 0, sizeof(CallAttributes));
CallAttributes.Version = RPC_CALL_ATTRIBUTES_VERSION;
CallAttributes.Flags = RPC_QUERY_SERVER_PRINCIPAL_NAME | RPC_QUERY_CLIENT_PRINCIPAL_NAME;
RpcServerInqCallAttributes(NULL, &CallAttributes);
if(CallAttributes.ServerPrincipalNameBufferLength)
{
CallAttributes.ServerPrincipalName = (WCHAR*)LocalAlloc(LPTR,
CallAttributes.ServerPrincipalNameBufferLength);
if(!CallAttributes.ServerPrincipalName)
{
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: PrintClientInfo failed - no memory\n"));
goto done;
}
}
if(CallAttributes.ClientPrincipalNameBufferLength)
{
CallAttributes.ClientPrincipalName = (WCHAR*)LocalAlloc(LPTR,
CallAttributes.ClientPrincipalNameBufferLength);
if(!CallAttributes.ClientPrincipalName)
{
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: PrintClientInfo failed - no memory\n"));
goto done;
}
}
status = RpcServerInqCallAttributes(NULL, &CallAttributes);
if(status != RPC_S_OK)
{
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: RpcServerInqCallAttributes failed - %d\n", status));
return ;
}
if(CallAttributes.ServerPrincipalName)
{
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Server SPN: %ws\n", CallAttributes.ServerPrincipalName));
}
if(CallAttributes.ClientPrincipalName)
{
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Client SPN: %ws\n", CallAttributes.ClientPrincipalName));
}
switch(CallAttributes.AuthenticationLevel)
{
case RPC_C_AUTHN_LEVEL_DEFAULT:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_DEFAULT\n"));
break;
case RPC_C_AUTHN_LEVEL_NONE:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_NONE\n"));
break;
case RPC_C_AUTHN_LEVEL_CONNECT:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_CONNECT\n"));
break;
case RPC_C_AUTHN_LEVEL_CALL:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_CALL\n"));
break;
case RPC_C_AUTHN_LEVEL_PKT:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_PKT\n"));
break;
case RPC_C_AUTHN_LEVEL_PKT_INTEGRITY:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_PKT_INTEGRITY\n"));
break;
case RPC_C_AUTHN_LEVEL_PKT_PRIVACY:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_PKT_PRIVACY\n"));
break;
default:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication level: UNKNOWN!!!\n"));
break;
}
switch(CallAttributes.AuthenticationService)
{
case RPC_C_AUTHN_NONE:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_NONE\n"));
break;
case RPC_C_AUTHN_DCE_PRIVATE:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_DCE_PRIVATE\n"));
break;
case RPC_C_AUTHN_DCE_PUBLIC:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_DCE_PUBLIC\n"));
break;
case RPC_C_AUTHN_DEC_PUBLIC:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_DEC_PUBLIC\n"));
break;
case RPC_C_AUTHN_GSS_NEGOTIATE:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_GSS_NEGOTIATE\n"));
break;
case RPC_C_AUTHN_WINNT:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_WINNT\n"));
break;
case RPC_C_AUTHN_GSS_SCHANNEL:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_GSS_SCHANNEL\n"));
break;
case RPC_C_AUTHN_GSS_KERBEROS:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_GSS_KERBEROS\n"));
break;
case RPC_C_AUTHN_DPA:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_DPA\n"));
break;
case RPC_C_AUTHN_MSN:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_MSN\n"));
break;
case RPC_C_AUTHN_DIGEST:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_DIGEST\n"));
break;
case RPC_C_AUTHN_MQ:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_MQ\n"));
break;
case RPC_C_AUTHN_DEFAULT:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: RPC_C_AUTHN_DEFAULT\n"));
break;
default:
TRACE((hTrace,TC_ICASRV,TT_API4,"TERMSRV: Authentication service: UNKNOWN!!!\n"));
break;
}
done:
if(CallAttributes.ServerPrincipalName)
{
LocalFree(CallAttributes.ServerPrincipalName);
}
if(CallAttributes.ClientPrincipalName)
{
LocalFree(CallAttributes.ClientPrincipalName);
}
