298 lines
6.4 KiB
C
298 lines
6.4 KiB
C
|
/*++
|
|||
|
|
|||
|
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"";
|
|||
|
|
|||
|
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' ) {
|
|||
|
|
|||
|
DWORD ComputerNameLength;
|
|||
|
|
|||
|
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;
|
|||
|
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 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Cleanup:
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
(VOID)RpcBindingFree(&BindHandle);
|
|||
|
}
|
|||
|
|
|||
|
|