|
|
/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
dhcbind.c
Abstract:
Routines which use RPC to bind and unbind the client to the DHCP server service.
Author:
Madan Appiah (madana) 10-Sep-1993
Environment:
User Mode - Win32
Revision History:
--*/
#include "dhcpcli.h"
static WCHAR LocalMachineName[MAX_COMPUTERNAME_LENGTH + 1] = L"";
//
// Bind should timeout in a max of 15 sec
//
const int DHCP_RPC_BIND_TIMEOUT_VALUE = ( 1000 * 15 );
BOOL fShortTimeOut = FALSE;
DWORD FindProtocolToUse( LPWSTR ServerIpAddress ) /*++
Routine Description:
This function returns the protocol binding to be used. It examines the ServerIpAddress string, if it is :
1. NULL or local IPAddress or Local Name - use "ncalrpc" 2. IpAddress - (of the form "ppp.qqq.rrr.sss") - use "ncacn_ip_tcp" 3. otherwise use "ncacn_np" protocol.
Arguments:
ServerIpAddress - The IP address of the server to bind to.
Return Value:
One of the following values :
DHCP_SERVER_USE_RPC_OVER_TCPIP 0x1 DHCP_SERVER_USE_RPC_OVER_NP 0x2 DHCP_SERVER_USE_RPC_OVER_LPC 0x4
--*/ { DWORD DotCount = 0; LPWSTR String = ServerIpAddress; DWORD ComputerNameLength;
if( (ServerIpAddress == NULL) || (*ServerIpAddress == L'\0') ) {
return( DHCP_SERVER_USE_RPC_OVER_LPC ); }
while ( (String = wcschr( String, L'.' )) != NULL ) {
//
// found another DOT.
//
DotCount++; String++; // skip this dot.
}
//
// if the string has 3 DOTs exactly then this string must represent
// an IpAddress.
//
if( DotCount == 3) {
//
// if this is local IP Address, use LPC
//
if( _wcsicmp(L"127.0.0.1" , ServerIpAddress) == 0 ) { return( DHCP_SERVER_USE_RPC_OVER_LPC ); }
//
// ?? determine whether this address is local IPAddress.
//
return(DHCP_SERVER_USE_RPC_OVER_TCPIP); }
//
// It is a computer name string. Check to see this is local
// computer name. If so use LPC, otherwise use NP.
//
if( *LocalMachineName == L'\0' ) {
ComputerNameLength = MAX_COMPUTERNAME_LENGTH;
if( !GetComputerName( LocalMachineName, &ComputerNameLength ) ) {
*LocalMachineName = L'\0'; } }
//
// if know machine ..
//
if( (*LocalMachineName != L'\0') ) {
BOOL LocalMachine;
//
// if the machine has "\\" skip it for name compare.
//
if( *ServerIpAddress == L'\\' ) { LocalMachine = !_wcsicmp( LocalMachineName, ServerIpAddress + 2); } else { LocalMachine = !_wcsicmp( LocalMachineName, ServerIpAddress); }
if( LocalMachine ) { return( DHCP_SERVER_USE_RPC_OVER_LPC ); }
}
return( DHCP_SERVER_USE_RPC_OVER_NP ); }
handle_t DHCP_SRV_HANDLE_bind( DHCP_SRV_HANDLE ServerIpAddress )
/*++
Routine Description:
This routine is called from the DHCP server service client stubs when it is necessary create an RPC binding to the server end.
Arguments:
ServerIpAddress - The IP address of the server to bind to.
Return Value:
The binding handle is returned to the stub routine. If the bind is unsuccessful, a NULL will be returned.
--*/ { RPC_STATUS rpcStatus; LPWSTR binding = NULL; handle_t bindingHandle; DWORD RpcProtocol;
//
// examine the ServerIpAddress string, if it is :
//
// 1. NULL or local IPAddress or Local Name - use "ncalrpc"
// 2. IpAddress - (of the form "ppp.qqq.rrr.sss") - use "ncacn_ip_tcp"
// 3. otherwise use "ncacn_np" protocol.
//
RpcProtocol = FindProtocolToUse( ServerIpAddress );
if( RpcProtocol == DHCP_SERVER_USE_RPC_OVER_LPC ) {
rpcStatus = RpcStringBindingComposeW( 0, L"ncalrpc", NULL, DHCP_LPC_EP, // L"Security=Impersonation Dynamic False",
L"Security=Impersonation Static True", &binding); } else if( RpcProtocol == DHCP_SERVER_USE_RPC_OVER_NP ) {
rpcStatus = RpcStringBindingComposeW( 0, L"ncacn_np", ServerIpAddress, DHCP_NAMED_PIPE, L"Security=Impersonation Static True", &binding); } else {
rpcStatus = RpcStringBindingComposeW( 0, L"ncacn_ip_tcp", ServerIpAddress, DHCP_SERVER_BIND_PORT, NULL, &binding); }
if ( rpcStatus != RPC_S_OK ) { goto Cleanup; }
rpcStatus = RpcBindingFromStringBindingW( binding, &bindingHandle );
if ( rpcStatus != RPC_S_OK ) { goto Cleanup; }
if( RpcProtocol == DHCP_SERVER_USE_RPC_OVER_TCPIP ) { //
// Tell RPC to do the security thing.
//
if( DhcpGlobalTryDownlevel ) { rpcStatus = RpcBindingSetAuthInfo( bindingHandle, // binding handle
DHCP_SERVER_SECURITY, // app name to security provider
RPC_C_AUTHN_LEVEL_CONNECT, // auth level
DHCP_SERVER_SECURITY_AUTH_ID, // Auth package ID
NULL, // client auth info, NULL specified logon info.
RPC_C_AUTHZ_NAME ); } else { rpcStatus = RpcBindingSetAuthInfo( bindingHandle, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN_GSS_NEGOTIATE, NULL, RPC_C_AUTHZ_NAME ); } } // if
rpcStatus = RpcBindingSetOption( bindingHandle, RPC_C_OPT_CALL_TIMEOUT, fShortTimeOut ? DHCP_RPC_BIND_TIMEOUT_VALUE : 0);
Cleanup:
if ( NULL != binding ) { RpcStringFreeW(&binding); }
if ( rpcStatus != RPC_S_OK ) { SetLastError( rpcStatus ); return( NULL ); }
return bindingHandle; }
void DHCP_SRV_HANDLE_unbind( DHCP_SRV_HANDLE ServerIpAddress, handle_t BindHandle )
/*++
Routine Description:
This routine is called from the DHCP server service client stubs when it is necessary to unbind from the server end.
Arguments:
ServerIpAddress - This is the IP address of the server from which to unbind.
BindingHandle - This is the binding handle that is to be closed.
Return Value:
None.
--*/ { fShortTimeOut = FALSE; (VOID)RpcBindingFree(&BindHandle); }
|