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.

430 lines
9.5 KiB

  1. /*++
  2. Copyright (c) 2001-2001 Microsoft Corporation
  3. Module Name:
  4. rpc.c
  5. Abstract:
  6. DNS Resolver Service
  7. RPC intialization, shutdown and utility routines.
  8. Author:
  9. Jim Gilroy (jamesg) April 19, 2001
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. #include <rpc.h>
  14. #include "rpcdce.h"
  15. #include "secobj.h"
  16. #undef UNICODE
  17. //
  18. // RPC globals
  19. //
  20. BOOL g_fRpcInitialized = FALSE;
  21. DWORD g_RpcProtocol = RESOLVER_RPC_USE_LPC;
  22. PSECURITY_DESCRIPTOR g_pRpcSecurityDescriptor;
  23. #define AUTO_BIND
  24. DNS_STATUS
  25. Rpc_Initialize(
  26. VOID
  27. )
  28. /*++
  29. Routine Description:
  30. Initialize server side RPC.
  31. Arguments:
  32. None.
  33. Return Value:
  34. ERROR_SUCCESS if successful.
  35. Error status on failure.
  36. --*/
  37. {
  38. RPC_STATUS status;
  39. BOOL fusingTcpip = FALSE;
  40. DNSDBG( RPC, (
  41. "Rpc_Initialize()\n"
  42. "\tIF handle = %p\n"
  43. "\tprotocol = %d\n",
  44. DnsResolver_ServerIfHandle,
  45. g_RpcProtocol
  46. ));
  47. //
  48. // RPC disabled?
  49. //
  50. if ( ! g_RpcProtocol )
  51. {
  52. g_RpcProtocol = RESOLVER_RPC_USE_LPC;
  53. }
  54. #if 0
  55. //
  56. // Create security for RPC API
  57. //
  58. status = NetpCreateWellKnownSids( NULL );
  59. if ( status != ERROR_SUCCESS )
  60. {
  61. DNS_PRINT(( "ERROR: Creating well known SIDs.\n" ));
  62. return( status );
  63. }
  64. status = RpcUtil_CreateSecurityObjects();
  65. if ( status != ERROR_SUCCESS )
  66. {
  67. DNS_PRINT(( "ERROR: Creating DNS security object.\n" ));
  68. return( status );
  69. }
  70. #endif
  71. //
  72. // build security descriptor
  73. //
  74. // NULL security descriptor gives some sort of default security
  75. // on the interface
  76. // - owner is this service (currently "Network Service")
  77. // - read access for everyone
  78. //
  79. // note: if roll your own, remember to avoid NULL DACL, this
  80. // puts NO security on interface including the right to
  81. // change security, so any app can hijack the ACL and
  82. // deny access to folks; the default SD==NULL security
  83. // doesn't give everyone WRITE_DACL
  84. //
  85. g_pRpcSecurityDescriptor = NULL;
  86. //
  87. // RPC over LPC
  88. //
  89. if( g_RpcProtocol & RESOLVER_RPC_USE_LPC )
  90. {
  91. status = RpcServerUseProtseqEpW(
  92. L"ncalrpc", // protocol string.
  93. RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // maximum concurrent calls
  94. RESOLVER_RPC_LPC_ENDPOINT_W, // endpoint
  95. g_pRpcSecurityDescriptor // security
  96. );
  97. // duplicate endpoint is ok
  98. if ( status == RPC_S_DUPLICATE_ENDPOINT )
  99. {
  100. status = RPC_S_OK;
  101. }
  102. if ( status != RPC_S_OK )
  103. {
  104. DNSDBG( INIT, (
  105. "ERROR: RpcServerUseProtseqEp() for LPC failed.]n"
  106. "\tstatus = %d 0x%08lx.\n",
  107. status, status ));
  108. return( status );
  109. }
  110. }
  111. //
  112. // RCP over TCP/IP
  113. //
  114. if( g_RpcProtocol & RESOLVER_RPC_USE_TCPIP )
  115. {
  116. #ifdef AUTO_BIND
  117. RPC_BINDING_VECTOR * bindingVector;
  118. status = RpcServerUseProtseqW(
  119. L"ncacn_ip_tcp", // protocol string.
  120. RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // max concurrent calls
  121. g_pRpcSecurityDescriptor
  122. );
  123. if ( status != RPC_S_OK )
  124. {
  125. DNSDBG( INIT, (
  126. "ERROR: RpcServerUseProtseq() for TCP/IP failed.]n"
  127. "\tstatus = %d 0x%08lx.\n",
  128. status, status ));
  129. return( status );
  130. }
  131. status = RpcServerInqBindings( &bindingVector );
  132. if ( status != RPC_S_OK )
  133. {
  134. DNSDBG( INIT, (
  135. "ERROR: RpcServerInqBindings failed.\n"
  136. "\tstatus = %d 0x%08lx.\n",
  137. status, status ));
  138. return( status );
  139. }
  140. //
  141. // register interface(s)
  142. // since only one DNS server on a host can use
  143. // RpcEpRegister() rather than RpcEpRegisterNoReplace()
  144. //
  145. status = RpcEpRegisterW(
  146. DnsResolver_ServerIfHandle,
  147. bindingVector,
  148. NULL,
  149. L"" );
  150. if ( status != RPC_S_OK )
  151. {
  152. DNSDBG( ANY, (
  153. "ERROR: RpcEpRegisterNoReplace() failed.\n"
  154. "\tstatus = %d %p.\n",
  155. status, status ));
  156. return( status );
  157. }
  158. //
  159. // free binding vector
  160. //
  161. status = RpcBindingVectorFree( &bindingVector );
  162. ASSERT( status == RPC_S_OK );
  163. status = RPC_S_OK;
  164. #else // not AUTO_BIND
  165. status = RpcServerUseProtseqEpW(
  166. L"ncacn_ip_tcp", // protocol string.
  167. RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // maximum concurrent calls
  168. RESOLVER_RPC_SERVER_PORT_W, // endpoint
  169. g_pRpcSecurityDescriptor // security
  170. );
  171. if ( status != RPC_S_OK )
  172. {
  173. DNSDBG( ANY, (
  174. "ERROR: RpcServerUseProtseqEp() for TCP/IP failed.]n"
  175. "\tstatus = %d 0x%08lx.\n",
  176. status, status ));
  177. return( status );
  178. }
  179. #endif // AUTO_BIND
  180. fusingTcpip = TRUE;
  181. }
  182. //
  183. // RPC over named pipes
  184. //
  185. if ( g_RpcProtocol & RESOLVER_RPC_USE_NAMED_PIPE )
  186. {
  187. status = RpcServerUseProtseqEpW(
  188. L"ncacn_np", // protocol string.
  189. RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // maximum concurrent calls
  190. RESOLVER_RPC_PIPE_NAME_W, // endpoint
  191. g_pRpcSecurityDescriptor
  192. );
  193. // duplicate endpoint is ok
  194. if ( status == RPC_S_DUPLICATE_ENDPOINT )
  195. {
  196. status = RPC_S_OK;
  197. }
  198. if ( status != RPC_S_OK )
  199. {
  200. DNSDBG( INIT, (
  201. "ERROR: RpcServerUseProtseqEp() for named pipe failed.]n"
  202. "\tstatus = %d 0x%08lx.\n",
  203. status,
  204. status ));
  205. return( status );
  206. }
  207. }
  208. //
  209. // register DNS RPC interface(s)
  210. //
  211. status = RpcServerRegisterIf(
  212. DnsResolver_ServerIfHandle,
  213. 0,
  214. 0);
  215. if ( status != RPC_S_OK )
  216. {
  217. DNSDBG( INIT, (
  218. "ERROR: RpcServerRegisterIf() failed.]n"
  219. "\tstatus = %d 0x%08lx.\n",
  220. status, status ));
  221. return(status);
  222. }
  223. #if 0
  224. //
  225. // for TCP/IP setup authentication
  226. //
  227. if ( fuseTcpip )
  228. {
  229. status = RpcServerRegisterAuthInfoW(
  230. RESOLVER_RPC_SECURITY_W, // app name to security provider.
  231. RESOLVER_RPC_SECURITY_AUTH_ID, // Auth package ID.
  232. NULL, // Encryption function handle.
  233. NULL ); // argment pointer to Encrypt function.
  234. if ( status != RPC_S_OK )
  235. {
  236. DNSDBG( INIT, (
  237. "ERROR: RpcServerRegisterAuthInfo() failed.]n"
  238. "\tstatus = %d 0x%08lx.\n",
  239. status, status ));
  240. return( status );
  241. }
  242. }
  243. #endif
  244. //
  245. // Listen on RPC
  246. //
  247. status = RpcServerListen(
  248. 1, // min threads
  249. RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // max concurrent calls
  250. TRUE ); // return on completion
  251. if ( status != RPC_S_OK )
  252. {
  253. DNS_PRINT((
  254. "ERROR: RpcServerListen() failed\n"
  255. "\tstatus = %d 0x%p\n",
  256. status, status ));
  257. return( status );
  258. }
  259. g_fRpcInitialized = TRUE;
  260. return( status );
  261. } // Rpc_Initialize
  262. VOID
  263. Rpc_Shutdown(
  264. VOID
  265. )
  266. /*++
  267. Routine Description:
  268. Shutdown RPC on the server.
  269. Arguments:
  270. None.
  271. Return Value:
  272. None.
  273. --*/
  274. {
  275. DWORD status;
  276. RPC_BINDING_VECTOR * bindingVector = NULL;
  277. DNSDBG( RPC, ( "Rpc_Shutdown().\n" ));
  278. if( ! g_fRpcInitialized )
  279. {
  280. DNSDBG( RPC, (
  281. "RPC not active, no shutdown necessary.\n" ));
  282. return;
  283. }
  284. //
  285. // stop server listen
  286. // then wait for all RPC threads to go away
  287. //
  288. status = RpcMgmtStopServerListening(
  289. NULL // this app
  290. );
  291. if ( status == RPC_S_OK )
  292. {
  293. status = RpcMgmtWaitServerListen();
  294. }
  295. //
  296. // unbind / unregister endpoints
  297. //
  298. status = RpcServerInqBindings( &bindingVector );
  299. ASSERT( status == RPC_S_OK );
  300. if ( status == RPC_S_OK )
  301. {
  302. status = RpcEpUnregister(
  303. DnsResolver_ServerIfHandle,
  304. bindingVector,
  305. NULL ); // Uuid vector.
  306. if ( status != RPC_S_OK )
  307. {
  308. DNSDBG( ANY, (
  309. "ERROR: RpcEpUnregister, status = %d.\n", status ));
  310. }
  311. }
  312. //
  313. // free binding vector
  314. //
  315. if ( bindingVector )
  316. {
  317. status = RpcBindingVectorFree( &bindingVector );
  318. ASSERT( status == RPC_S_OK );
  319. }
  320. //
  321. // wait for all calls to complete
  322. //
  323. status = RpcServerUnregisterIf(
  324. DnsResolver_ServerIfHandle,
  325. 0,
  326. TRUE );
  327. ASSERT( status == ERROR_SUCCESS );
  328. g_fRpcInitialized = FALSE;
  329. DNSDBG( RPC, (
  330. "RPC shutdown completed.\n" ));
  331. }
  332. //
  333. // End rpc.c
  334. //