/*++ Copyright (c) 2001-2001 Microsoft Corporation Module Name: rpc.c Abstract: DNS Resolver Service RPC intialization, shutdown and utility routines. Author: Jim Gilroy (jamesg) April 19, 2001 Revision History: --*/ #include "local.h" #include #include "rpcdce.h" #include "secobj.h" #undef UNICODE // // RPC globals // BOOL g_fRpcInitialized = FALSE; DWORD g_RpcProtocol = RESOLVER_RPC_USE_LPC; PSECURITY_DESCRIPTOR g_pRpcSecurityDescriptor; #define AUTO_BIND DNS_STATUS Rpc_Initialize( VOID ) /*++ Routine Description: Initialize server side RPC. Arguments: None. Return Value: ERROR_SUCCESS if successful. Error status on failure. --*/ { RPC_STATUS status; BOOL fusingTcpip = FALSE; DNSDBG( RPC, ( "Rpc_Initialize()\n" "\tIF handle = %p\n" "\tprotocol = %d\n", DnsResolver_ServerIfHandle, g_RpcProtocol )); // // RPC disabled? // if ( ! g_RpcProtocol ) { g_RpcProtocol = RESOLVER_RPC_USE_LPC; } #if 0 // // Create security for RPC API // status = NetpCreateWellKnownSids( NULL ); if ( status != ERROR_SUCCESS ) { DNS_PRINT(( "ERROR: Creating well known SIDs.\n" )); return( status ); } status = RpcUtil_CreateSecurityObjects(); if ( status != ERROR_SUCCESS ) { DNS_PRINT(( "ERROR: Creating DNS security object.\n" )); return( status ); } #endif // // build security descriptor // // NULL security descriptor gives some sort of default security // on the interface // - owner is this service (currently "Network Service") // - read access for everyone // // note: if roll your own, remember to avoid NULL DACL, this // puts NO security on interface including the right to // change security, so any app can hijack the ACL and // deny access to folks; the default SD==NULL security // doesn't give everyone WRITE_DACL // g_pRpcSecurityDescriptor = NULL; // // RPC over LPC // if( g_RpcProtocol & RESOLVER_RPC_USE_LPC ) { status = RpcServerUseProtseqEpW( L"ncalrpc", // protocol string. RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // maximum concurrent calls RESOLVER_RPC_LPC_ENDPOINT_W, // endpoint g_pRpcSecurityDescriptor // security ); // duplicate endpoint is ok if ( status == RPC_S_DUPLICATE_ENDPOINT ) { status = RPC_S_OK; } if ( status != RPC_S_OK ) { DNSDBG( INIT, ( "ERROR: RpcServerUseProtseqEp() for LPC failed.]n" "\tstatus = %d 0x%08lx.\n", status, status )); return( status ); } } // // RCP over TCP/IP // if( g_RpcProtocol & RESOLVER_RPC_USE_TCPIP ) { #ifdef AUTO_BIND RPC_BINDING_VECTOR * bindingVector; status = RpcServerUseProtseqW( L"ncacn_ip_tcp", // protocol string. RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // max concurrent calls g_pRpcSecurityDescriptor ); if ( status != RPC_S_OK ) { DNSDBG( INIT, ( "ERROR: RpcServerUseProtseq() for TCP/IP failed.]n" "\tstatus = %d 0x%08lx.\n", status, status )); return( status ); } status = RpcServerInqBindings( &bindingVector ); if ( status != RPC_S_OK ) { DNSDBG( INIT, ( "ERROR: RpcServerInqBindings failed.\n" "\tstatus = %d 0x%08lx.\n", status, status )); return( status ); } // // register interface(s) // since only one DNS server on a host can use // RpcEpRegister() rather than RpcEpRegisterNoReplace() // status = RpcEpRegisterW( DnsResolver_ServerIfHandle, bindingVector, NULL, L"" ); if ( status != RPC_S_OK ) { DNSDBG( ANY, ( "ERROR: RpcEpRegisterNoReplace() failed.\n" "\tstatus = %d %p.\n", status, status )); return( status ); } // // free binding vector // status = RpcBindingVectorFree( &bindingVector ); ASSERT( status == RPC_S_OK ); status = RPC_S_OK; #else // not AUTO_BIND status = RpcServerUseProtseqEpW( L"ncacn_ip_tcp", // protocol string. RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // maximum concurrent calls RESOLVER_RPC_SERVER_PORT_W, // endpoint g_pRpcSecurityDescriptor // security ); if ( status != RPC_S_OK ) { DNSDBG( ANY, ( "ERROR: RpcServerUseProtseqEp() for TCP/IP failed.]n" "\tstatus = %d 0x%08lx.\n", status, status )); return( status ); } #endif // AUTO_BIND fusingTcpip = TRUE; } // // RPC over named pipes // if ( g_RpcProtocol & RESOLVER_RPC_USE_NAMED_PIPE ) { status = RpcServerUseProtseqEpW( L"ncacn_np", // protocol string. RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // maximum concurrent calls RESOLVER_RPC_PIPE_NAME_W, // endpoint g_pRpcSecurityDescriptor ); // duplicate endpoint is ok if ( status == RPC_S_DUPLICATE_ENDPOINT ) { status = RPC_S_OK; } if ( status != RPC_S_OK ) { DNSDBG( INIT, ( "ERROR: RpcServerUseProtseqEp() for named pipe failed.]n" "\tstatus = %d 0x%08lx.\n", status, status )); return( status ); } } // // register DNS RPC interface(s) // status = RpcServerRegisterIf( DnsResolver_ServerIfHandle, 0, 0); if ( status != RPC_S_OK ) { DNSDBG( INIT, ( "ERROR: RpcServerRegisterIf() failed.]n" "\tstatus = %d 0x%08lx.\n", status, status )); return(status); } #if 0 // // for TCP/IP setup authentication // if ( fuseTcpip ) { status = RpcServerRegisterAuthInfoW( RESOLVER_RPC_SECURITY_W, // app name to security provider. RESOLVER_RPC_SECURITY_AUTH_ID, // Auth package ID. NULL, // Encryption function handle. NULL ); // argment pointer to Encrypt function. if ( status != RPC_S_OK ) { DNSDBG( INIT, ( "ERROR: RpcServerRegisterAuthInfo() failed.]n" "\tstatus = %d 0x%08lx.\n", status, status )); return( status ); } } #endif // // Listen on RPC // status = RpcServerListen( 1, // min threads RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // max concurrent calls TRUE ); // return on completion if ( status != RPC_S_OK ) { DNS_PRINT(( "ERROR: RpcServerListen() failed\n" "\tstatus = %d 0x%p\n", status, status )); return( status ); } g_fRpcInitialized = TRUE; return( status ); } // Rpc_Initialize VOID Rpc_Shutdown( VOID ) /*++ Routine Description: Shutdown RPC on the server. Arguments: None. Return Value: None. --*/ { DWORD status; RPC_BINDING_VECTOR * bindingVector = NULL; DNSDBG( RPC, ( "Rpc_Shutdown().\n" )); if( ! g_fRpcInitialized ) { DNSDBG( RPC, ( "RPC not active, no shutdown necessary.\n" )); return; } // // stop server listen // then wait for all RPC threads to go away // status = RpcMgmtStopServerListening( NULL // this app ); if ( status == RPC_S_OK ) { status = RpcMgmtWaitServerListen(); } // // unbind / unregister endpoints // status = RpcServerInqBindings( &bindingVector ); ASSERT( status == RPC_S_OK ); if ( status == RPC_S_OK ) { status = RpcEpUnregister( DnsResolver_ServerIfHandle, bindingVector, NULL ); // Uuid vector. if ( status != RPC_S_OK ) { DNSDBG( ANY, ( "ERROR: RpcEpUnregister, status = %d.\n", status )); } } // // free binding vector // if ( bindingVector ) { status = RpcBindingVectorFree( &bindingVector ); ASSERT( status == RPC_S_OK ); } // // wait for all calls to complete // status = RpcServerUnregisterIf( DnsResolver_ServerIfHandle, 0, TRUE ); ASSERT( status == ERROR_SUCCESS ); g_fRpcInitialized = FALSE; DNSDBG( RPC, ( "RPC shutdown completed.\n" )); } // // End rpc.c //