Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

305 lines
7.0 KiB

/*++
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);
}