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.

386 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. regbind.c
  5. Abstract:
  6. This module contains routines for binding and unbinding to the Win32
  7. Registry server.
  8. Author:
  9. David J. Gilman (davegi) 06-Feb-1992
  10. Revision History:
  11. Dragos C. Sambotin (dragoss) 21-May-1999
  12. Moved this code from ..\client\bind.c
  13. Added EndpointConn_np (pipe connecting)
  14. Added BaseBindToMachineShutdownInterface to bind to the new winlogon
  15. ShutDown interface
  16. --*/
  17. #include <ntrpcp.h>
  18. #include <rpc.h>
  19. #include "shutinit.h"
  20. #include "regconn.h"
  21. //
  22. // wRegConn_bind - common function to bind to a transport and free the
  23. // string binding.
  24. //
  25. wRegConn_bind(
  26. LPWSTR * StringBinding,
  27. RPC_BINDING_HANDLE * pBindingHandle
  28. )
  29. {
  30. DWORD RpcStatus;
  31. RpcStatus = RpcBindingFromStringBindingW(*StringBinding,pBindingHandle);
  32. RpcStringFreeW(StringBinding);
  33. if ( RpcStatus != RPC_S_OK ) {
  34. *pBindingHandle = NULL;
  35. return RpcStatus;
  36. }
  37. return(ERROR_SUCCESS);
  38. }
  39. /*++
  40. Routine Description for the RegConn_* functions:
  41. Bind to the RPC server over the specified transport
  42. Arguments:
  43. ServerName - Name of server to bind with (or netaddress).
  44. pBindingHandle - Location where binding handle is to be placed
  45. Return Value:
  46. ERROR_SUCCESS - The binding has been successfully completed.
  47. ERROR_INVALID_COMPUTER_NAME - The ServerName syntax is invalid.
  48. ERROR_NO_MEMORY - There is not sufficient memory available to the
  49. caller to perform the binding.
  50. --*/
  51. //
  52. // wRegConn_Netbios - Worker function to get a binding handle for any of the
  53. // netbios protocols
  54. //
  55. DWORD wRegConn_Netbios(
  56. IN LPWSTR rpc_protocol,
  57. IN LPCWSTR ServerName,
  58. OUT RPC_BINDING_HANDLE * pBindingHandle
  59. )
  60. {
  61. RPC_STATUS RpcStatus;
  62. LPWSTR StringBinding;
  63. LPCWSTR PlainServerName;
  64. *pBindingHandle = NULL;
  65. //
  66. // Ignore leading "\\"
  67. //
  68. if ((ServerName[0] == '\\') && (ServerName[1] == '\\')) {
  69. PlainServerName = &ServerName[2];
  70. } else {
  71. PlainServerName = ServerName;
  72. }
  73. RpcStatus = RpcStringBindingComposeW(0,
  74. rpc_protocol,
  75. (LPWSTR)PlainServerName,
  76. NULL, // endpoint
  77. NULL,
  78. &StringBinding);
  79. if ( RpcStatus != RPC_S_OK ) {
  80. return( ERROR_BAD_NETPATH );
  81. }
  82. return(wRegConn_bind(&StringBinding, pBindingHandle));
  83. }
  84. DWORD
  85. RegConn_nb_nb(
  86. IN LPCWSTR ServerName,
  87. OUT RPC_BINDING_HANDLE * pBindingHandle
  88. )
  89. {
  90. return(wRegConn_Netbios(L"ncacn_nb_nb",
  91. ServerName,
  92. pBindingHandle));
  93. }
  94. DWORD
  95. RegConn_nb_tcp(
  96. IN LPCWSTR ServerName,
  97. OUT RPC_BINDING_HANDLE * pBindingHandle
  98. )
  99. {
  100. return(wRegConn_Netbios(L"ncacn_nb_tcp",
  101. ServerName,
  102. pBindingHandle));
  103. }
  104. DWORD
  105. RegConn_nb_ipx(
  106. IN LPCWSTR ServerName,
  107. OUT RPC_BINDING_HANDLE * pBindingHandle
  108. )
  109. {
  110. return(wRegConn_Netbios(L"ncacn_nb_ipx",
  111. ServerName,
  112. pBindingHandle));
  113. }
  114. //
  115. // EndpointConn_np - connects to a specific pipe on the remote machine
  116. // (Win95 does not support server-side named pipes)
  117. //
  118. DWORD
  119. EndpointConn_np(
  120. IN LPCWSTR ServerName,
  121. IN unsigned short * Endpoint,
  122. OUT RPC_BINDING_HANDLE * pBindingHandle
  123. )
  124. {
  125. RPC_STATUS RpcStatus;
  126. LPWSTR StringBinding;
  127. LPWSTR SlashServerName;
  128. int have_slashes;
  129. ULONG NameLen;
  130. *pBindingHandle = NULL;
  131. if (ServerName[1] == L'\\') {
  132. have_slashes = 1;
  133. } else {
  134. have_slashes = 0;
  135. }
  136. //
  137. // Be nice and prepend slashes if not supplied.
  138. //
  139. NameLen = lstrlenW(ServerName);
  140. if ((!have_slashes) &&
  141. (NameLen > 0)) {
  142. //
  143. // Allocate new buffer large enough for two forward slashes and a
  144. // NULL terminator.
  145. //
  146. SlashServerName = LocalAlloc(LMEM_FIXED, (NameLen + 3) * sizeof(WCHAR));
  147. if (SlashServerName == NULL) {
  148. return(ERROR_NOT_ENOUGH_MEMORY);
  149. }
  150. SlashServerName[0] = L'\\';
  151. SlashServerName[1] = L'\\';
  152. lstrcpyW(&SlashServerName[2], ServerName);
  153. } else {
  154. SlashServerName = (LPWSTR)ServerName;
  155. }
  156. RpcStatus = RpcStringBindingComposeW(0,
  157. L"ncacn_np",
  158. SlashServerName,
  159. Endpoint,
  160. NULL,
  161. &StringBinding);
  162. if (SlashServerName != ServerName) {
  163. LocalFree(SlashServerName);
  164. }
  165. if ( RpcStatus != RPC_S_OK ) {
  166. return( ERROR_BAD_NETPATH );
  167. }
  168. return(wRegConn_bind(&StringBinding, pBindingHandle));
  169. }
  170. //
  171. // RegConn_np - get a remote registry RPC binding handle for an NT server
  172. // (Win95 does not support server-side named pipes)
  173. //
  174. DWORD
  175. RegConn_np(
  176. IN LPCWSTR ServerName,
  177. OUT RPC_BINDING_HANDLE * pBindingHandle
  178. )
  179. {
  180. return EndpointConn_np(ServerName,L"\\PIPE\\winreg",pBindingHandle);
  181. }
  182. //
  183. // RegConn_spx - Use the Netbios connection function, RPC will resolve the name
  184. // via winsock.
  185. //
  186. DWORD
  187. RegConn_spx(
  188. IN LPCWSTR ServerName,
  189. OUT RPC_BINDING_HANDLE * pBindingHandle
  190. )
  191. {
  192. return(wRegConn_Netbios(L"ncacn_spx",
  193. ServerName,
  194. pBindingHandle));
  195. }
  196. DWORD RegConn_ip_tcp(
  197. IN LPCWSTR ServerName,
  198. OUT RPC_BINDING_HANDLE * pBindingHandle
  199. )
  200. {
  201. return(wRegConn_Netbios(L"ncacn_ip_tcp",
  202. ServerName,
  203. pBindingHandle));
  204. }
  205. RPC_BINDING_HANDLE
  206. PREGISTRY_SERVER_NAME_bind(
  207. PREGISTRY_SERVER_NAME ServerName
  208. )
  209. /*++
  210. Routine Description:
  211. To make the remote registry multi-protocol aware, PREGISTRY_SERVER_NAME
  212. parameter actually points to an already bound binding handle.
  213. PREGISTRY_SERVER_NAME is declared a PWSTR only to help maintain
  214. compatibility with NT.
  215. --*/
  216. {
  217. return(*(RPC_BINDING_HANDLE *)ServerName);
  218. }
  219. void
  220. PREGISTRY_SERVER_NAME_unbind(
  221. PREGISTRY_SERVER_NAME ServerName,
  222. RPC_BINDING_HANDLE BindingHandle
  223. )
  224. /*++
  225. Routine Description:
  226. This routine unbinds the RPC client from the server. It is called
  227. directly from the RPC stub that references the handle.
  228. Arguments:
  229. ServerName - Not used.
  230. BindingHandle - Supplies the handle to unbind.
  231. Return Value:
  232. None.
  233. --*/
  234. {
  235. DWORD Status;
  236. UNREFERENCED_PARAMETER( ServerName );
  237. return;
  238. }
  239. LONG
  240. BaseBindToMachineShutdownInterface(
  241. IN LPCWSTR lpMachineName,
  242. IN PBIND_CALLBACK BindCallback,
  243. IN PVOID Context1,
  244. IN PVOID Context2
  245. )
  246. /*++
  247. Routine Description:
  248. This is a helper routine used to create an RPC binding from
  249. a given machine name to the shutdown interface (now residing in winlogon)
  250. Arguments:
  251. lpMachineName - Supplies a pointer to a machine name. Must not
  252. be NULL.
  253. BindCallback - Supplies the function that should be called once
  254. a binding has been created to initiate the connection.
  255. Context1 - Supplies the first parameter to pass to the callback routine.
  256. Context2 - Supplies the second parameter to pass to the callback routine.
  257. Return Value:
  258. Returns ERROR_SUCCESS (0) for success; error-code for failure.
  259. --*/
  260. {
  261. LONG Error;
  262. RPC_BINDING_HANDLE binding;
  263. Error = EndpointConn_np(lpMachineName,L"\\PIPE\\InitShutdown",&binding);
  264. if (Error == ERROR_SUCCESS) {
  265. //
  266. // For the named pipes protocol, we use a static endpoint, so the
  267. // call to RpcEpResolveBinding is not needed.
  268. // Also, the server checks the user's credentials on opening
  269. // the named pipe, so RpcBindingSetAuthInfo is not needed.
  270. //
  271. Error = (BindCallback)(&binding,
  272. Context1,
  273. Context2);
  274. RpcBindingFree(&binding);
  275. if (Error != RPC_S_SERVER_UNAVAILABLE) {
  276. return Error;
  277. }
  278. }
  279. if (Error != ERROR_SUCCESS) {
  280. if ((Error == RPC_S_INVALID_ENDPOINT_FORMAT) ||
  281. (Error == RPC_S_INVALID_NET_ADDR) ) {
  282. Error = ERROR_INVALID_COMPUTERNAME;
  283. } else {
  284. Error = ERROR_BAD_NETPATH;
  285. }
  286. }
  287. return(Error);
  288. }