Source code of Windows XP (NT5)
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.

297 lines
6.4 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. dhcbind.c
  5. Abstract:
  6. Routines which use RPC to bind and unbind the client to the
  7. DHCP server service.
  8. Author:
  9. Madan Appiah (madana) 10-Sep-1993
  10. Environment:
  11. User Mode - Win32
  12. Revision History:
  13. --*/
  14. #include "dhcpcli.h"
  15. static WCHAR LocalMachineName[MAX_COMPUTERNAME_LENGTH + 1] = L"";
  16. DWORD
  17. FindProtocolToUse(
  18. LPWSTR ServerIpAddress
  19. )
  20. /*++
  21. Routine Description:
  22. This function returns the protocol binding to be used. It examines
  23. the ServerIpAddress string, if it is :
  24. 1. NULL or local IPAddress or Local Name - use "ncalrpc"
  25. 2. IpAddress - (of the form "ppp.qqq.rrr.sss") - use "ncacn_ip_tcp"
  26. 3. otherwise use "ncacn_np" protocol.
  27. Arguments:
  28. ServerIpAddress - The IP address of the server to bind to.
  29. Return Value:
  30. One of the following values :
  31. DHCP_SERVER_USE_RPC_OVER_TCPIP 0x1
  32. DHCP_SERVER_USE_RPC_OVER_NP 0x2
  33. DHCP_SERVER_USE_RPC_OVER_LPC 0x4
  34. --*/
  35. {
  36. DWORD DotCount = 0;
  37. LPWSTR String = ServerIpAddress;
  38. DWORD ComputerNameLength;
  39. if( (ServerIpAddress == NULL) ||
  40. (*ServerIpAddress == L'\0') ) {
  41. return( DHCP_SERVER_USE_RPC_OVER_LPC );
  42. }
  43. while ( (String = wcschr( String, L'.' )) != NULL ) {
  44. //
  45. // found another DOT.
  46. //
  47. DotCount++;
  48. String++; // skip this dot.
  49. }
  50. //
  51. // if the string has 3 DOTs exactly then this string must represent
  52. // an IpAddress.
  53. //
  54. if( DotCount == 3) {
  55. //
  56. // if this is local IP Address, use LPC
  57. //
  58. if( _wcsicmp(L"127.0.0.1" , ServerIpAddress) == 0 ) {
  59. return( DHCP_SERVER_USE_RPC_OVER_LPC );
  60. }
  61. //
  62. // ?? determine whether this address is local IPAddress.
  63. //
  64. return(DHCP_SERVER_USE_RPC_OVER_TCPIP);
  65. }
  66. //
  67. // It is a computer name string. Check to see this is local
  68. // computer name. If so use LPC, otherwise use NP.
  69. //
  70. if( *LocalMachineName == L'\0' ) {
  71. DWORD ComputerNameLength;
  72. ComputerNameLength = MAX_COMPUTERNAME_LENGTH;
  73. if( !GetComputerName(
  74. LocalMachineName,
  75. &ComputerNameLength ) ) {
  76. *LocalMachineName = L'\0';
  77. }
  78. }
  79. //
  80. // if know machine ..
  81. //
  82. if( (*LocalMachineName != L'\0') ) {
  83. BOOL LocalMachine;
  84. //
  85. // if the machine has "\\" skip it for name compare.
  86. //
  87. if( *ServerIpAddress == L'\\' ) {
  88. LocalMachine = !_wcsicmp( LocalMachineName, ServerIpAddress + 2);
  89. }
  90. else {
  91. LocalMachine = !_wcsicmp( LocalMachineName, ServerIpAddress);
  92. }
  93. if( LocalMachine ) {
  94. return( DHCP_SERVER_USE_RPC_OVER_LPC );
  95. }
  96. }
  97. return( DHCP_SERVER_USE_RPC_OVER_NP );
  98. }
  99. handle_t
  100. DHCP_SRV_HANDLE_bind(
  101. DHCP_SRV_HANDLE ServerIpAddress
  102. )
  103. /*++
  104. Routine Description:
  105. This routine is called from the DHCP server service client stubs when
  106. it is necessary create an RPC binding to the server end.
  107. Arguments:
  108. ServerIpAddress - The IP address of the server to bind to.
  109. Return Value:
  110. The binding handle is returned to the stub routine. If the bind is
  111. unsuccessful, a NULL will be returned.
  112. --*/
  113. {
  114. RPC_STATUS rpcStatus;
  115. LPWSTR binding;
  116. handle_t bindingHandle;
  117. DWORD RpcProtocol;
  118. //
  119. // examine the ServerIpAddress string, if it is :
  120. //
  121. // 1. NULL or local IPAddress or Local Name - use "ncalrpc"
  122. // 2. IpAddress - (of the form "ppp.qqq.rrr.sss") - use "ncacn_ip_tcp"
  123. // 3. otherwise use "ncacn_np" protocol.
  124. //
  125. RpcProtocol = FindProtocolToUse( ServerIpAddress );
  126. if( RpcProtocol == DHCP_SERVER_USE_RPC_OVER_LPC ) {
  127. rpcStatus = RpcStringBindingComposeW(
  128. 0,
  129. L"ncalrpc",
  130. NULL,
  131. DHCP_LPC_EP,
  132. // L"Security=Impersonation Dynamic False",
  133. L"Security=Impersonation Static True",
  134. &binding);
  135. }
  136. else if( RpcProtocol == DHCP_SERVER_USE_RPC_OVER_NP ) {
  137. rpcStatus = RpcStringBindingComposeW(
  138. 0,
  139. L"ncacn_np",
  140. ServerIpAddress,
  141. DHCP_NAMED_PIPE,
  142. L"Security=Impersonation Static True",
  143. &binding);
  144. }
  145. else {
  146. rpcStatus = RpcStringBindingComposeW(
  147. 0,
  148. L"ncacn_ip_tcp",
  149. ServerIpAddress,
  150. DHCP_SERVER_BIND_PORT,
  151. NULL,
  152. &binding);
  153. }
  154. if ( rpcStatus != RPC_S_OK ) {
  155. goto Cleanup;
  156. }
  157. rpcStatus = RpcBindingFromStringBindingW( binding, &bindingHandle );
  158. if ( rpcStatus != RPC_S_OK ) {
  159. goto Cleanup;
  160. }
  161. if( RpcProtocol == DHCP_SERVER_USE_RPC_OVER_TCPIP ) {
  162. //
  163. // Tell RPC to do the security thing.
  164. //
  165. if( DhcpGlobalTryDownlevel ) {
  166. rpcStatus = RpcBindingSetAuthInfo(
  167. bindingHandle, // binding handle
  168. DHCP_SERVER_SECURITY, // app name to security provider
  169. RPC_C_AUTHN_LEVEL_CONNECT, // auth level
  170. DHCP_SERVER_SECURITY_AUTH_ID, // Auth package ID
  171. NULL, // client auth info, NULL specified logon info.
  172. RPC_C_AUTHZ_NAME );
  173. } else {
  174. rpcStatus = RpcBindingSetAuthInfo(
  175. bindingHandle, NULL,
  176. RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
  177. RPC_C_AUTHN_GSS_NEGOTIATE, NULL, RPC_C_AUTHZ_NAME );
  178. }
  179. }
  180. Cleanup:
  181. RpcStringFreeW(&binding);
  182. if ( rpcStatus != RPC_S_OK ) {
  183. SetLastError( rpcStatus );
  184. return( NULL );
  185. }
  186. return bindingHandle;
  187. }
  188. void
  189. DHCP_SRV_HANDLE_unbind(
  190. DHCP_SRV_HANDLE ServerIpAddress,
  191. handle_t BindHandle
  192. )
  193. /*++
  194. Routine Description:
  195. This routine is called from the DHCP server service client stubs
  196. when it is necessary to unbind from the server end.
  197. Arguments:
  198. ServerIpAddress - This is the IP address of the server from which to unbind.
  199. BindingHandle - This is the binding handle that is to be closed.
  200. Return Value:
  201. None.
  202. --*/
  203. {
  204. (VOID)RpcBindingFree(&BindHandle);
  205. }