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.

568 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: rpc.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 10-Nov-95 MarkBl Created.
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "..\pch\headers.hxx"
  18. #pragma hdrstop
  19. #include "debug.hxx"
  20. #include "atsvc.h"
  21. #include "SASecRPC.h"
  22. typedef HRESULT (* BindFunction)(LPWSTR, RPC_BINDING_HANDLE *);
  23. RPC_STATUS BindNetBIOSOverNetBEUI(LPWSTR, RPC_BINDING_HANDLE *);
  24. RPC_STATUS BindNetBIOSOverTCP(LPWSTR, RPC_BINDING_HANDLE *);
  25. RPC_STATUS BindNetBIOSOverIPX(LPWSTR, RPC_BINDING_HANDLE *);
  26. RPC_STATUS BindNamedPipe(LPWSTR, RPC_BINDING_HANDLE *);
  27. RPC_STATUS BindSPX(LPWSTR, RPC_BINDING_HANDLE *);
  28. RPC_STATUS BindTCPIP(LPWSTR, RPC_BINDING_HANDLE *);
  29. RPC_STATUS BindViaProtocol(LPTSTR , LPWSTR , RPC_BINDING_HANDLE * );
  30. extern "C" handle_t GenericBind(LPCWSTR, RPC_IF_HANDLE);
  31. extern "C" void GenericUnbind(LPCWSTR, RPC_BINDING_HANDLE);
  32. BindFunction grgProtocolBindFuncs[] = {
  33. BindNamedPipe,
  34. BindTCPIP,
  35. BindSPX,
  36. NULL
  37. };
  38. RPC_BINDING_HANDLE gRpcHandle = NULL;
  39. //+---------------------------------------------------------------------------
  40. //
  41. // Function: ATSVC_HANDLE_bind
  42. //
  43. // Synopsis: Called from RPC on auto bind.
  44. //
  45. // Arguments: [ServerName] -- Server to bind to.
  46. //
  47. // Returns: RPC_STATUS code
  48. //
  49. // Notes: None.
  50. //
  51. //----------------------------------------------------------------------------
  52. extern "C" handle_t
  53. ATSVC_HANDLE_bind(ATSVC_HANDLE ServerName)
  54. {
  55. return(GenericBind(ServerName, atsvc_ClientIfHandle));
  56. }
  57. //+---------------------------------------------------------------------------
  58. //
  59. // Function: ATSVC_HANDLE_unbind
  60. //
  61. // Synopsis: Unbind. Free the handle.
  62. //
  63. // Arguments: [ServerName] -- Unused.
  64. // [BindingHandle] -- Binding handle to free.
  65. //
  66. // Returns: RPC_STATUS code
  67. //
  68. // Notes: None.
  69. //
  70. //----------------------------------------------------------------------------
  71. extern "C" void
  72. ATSVC_HANDLE_unbind(ATSVC_HANDLE ServerName, RPC_BINDING_HANDLE BindingHandle)
  73. {
  74. GenericUnbind(ServerName, BindingHandle);
  75. }
  76. //+---------------------------------------------------------------------------
  77. //
  78. // Function: SASEC_HANDLE_bind
  79. //
  80. // Synopsis: Called from RPC on auto bind.
  81. //
  82. // Arguments: [ServerName] -- Server to bind to.
  83. //
  84. // Returns: RPC_STATUS code
  85. //
  86. // Notes: None.
  87. //
  88. //----------------------------------------------------------------------------
  89. extern "C" handle_t
  90. SASEC_HANDLE_bind(SASEC_HANDLE ServerName)
  91. {
  92. RPC_BINDING_HANDLE BindingHandle;
  93. RPC_STATUS RpcStatus;
  94. if ((BindingHandle = GenericBind(ServerName,
  95. sasec_ClientIfHandle)) != NULL)
  96. {
  97. //
  98. // Set the connection to be authenticated and all arguments encrypted.
  99. //
  100. RPC_SECURITY_QOS qos;
  101. ZeroMemory(&qos, sizeof(RPC_SECURITY_QOS));
  102. qos.Version = RPC_C_SECURITY_QOS_VERSION;
  103. qos.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
  104. qos.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC;
  105. qos.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
  106. RpcStatus = RpcBindingSetAuthInfoEx(BindingHandle,
  107. NULL,
  108. RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
  109. RPC_C_AUTHN_WINNT,
  110. NULL,
  111. RPC_C_AUTHZ_NONE,
  112. &qos);
  113. //
  114. // Refuse the bind, if the requested authentication failed.
  115. //
  116. if (RpcStatus != RPC_S_OK)
  117. {
  118. GenericUnbind(ServerName, BindingHandle);
  119. CHECK_HRESULT(HRESULT_FROM_WIN32(RpcStatus));
  120. return(NULL);
  121. }
  122. }
  123. return(BindingHandle);
  124. }
  125. //+---------------------------------------------------------------------------
  126. //
  127. // Function: SASEC_HANDLE_unbind
  128. //
  129. // Synopsis: Unbind. Free the handle.
  130. //
  131. // Arguments: [ServerName] -- Unused.
  132. // [BindingHandle] -- Binding handle to free.
  133. //
  134. // Returns: RPC_STATUS code
  135. //
  136. // Notes: None.
  137. //
  138. //----------------------------------------------------------------------------
  139. extern "C" void
  140. SASEC_HANDLE_unbind(SASEC_HANDLE ServerName, RPC_BINDING_HANDLE BindingHandle)
  141. {
  142. GenericUnbind(ServerName, BindingHandle);
  143. }
  144. //+---------------------------------------------------------------------------
  145. //
  146. // Function: GenericBind
  147. //
  148. // Synopsis:
  149. //
  150. // Arguments: [ServerName] -- Server to bind to.
  151. // [ClientIfHandle] -- Specific interface.
  152. // Returns:
  153. //
  154. // Notes: None.
  155. //
  156. //----------------------------------------------------------------------------
  157. extern "C" handle_t
  158. GenericBind(LPCWSTR ServerName, RPC_IF_HANDLE ClientIfHandle)
  159. {
  160. RPC_BINDING_HANDLE BindingHandle = NULL;
  161. RPC_STATUS RpcStatus;
  162. //
  163. // If local, use LRPC. Otherwise, try multiple protocols.
  164. //
  165. if (ServerName == NULL)
  166. {
  167. RpcStatus = BindViaProtocol(TEXT("ncalrpc"), NULL, &BindingHandle);
  168. CHECK_HRESULT(HRESULT_FROM_WIN32(RpcStatus));
  169. if (RpcStatus == RPC_S_OK)
  170. {
  171. RpcStatus = RpcEpResolveBinding(BindingHandle, ClientIfHandle);
  172. CHECK_HRESULT(HRESULT_FROM_WIN32(RpcStatus));
  173. }
  174. }
  175. else
  176. {
  177. BindFunction pBindFunc;
  178. pBindFunc = grgProtocolBindFuncs[0];
  179. int i = 0;
  180. //
  181. // Iterate through the protocols until we find one that can connect.
  182. //
  183. do
  184. {
  185. RpcStatus = pBindFunc((LPWSTR)ServerName, &BindingHandle);
  186. if (RpcStatus == RPC_S_OK)
  187. {
  188. //
  189. // For the named pipes protocol, we use a static endpoint,
  190. // so the call to RpcEpResolveBinding is not needed.
  191. //
  192. // BUGBUG : review the above. Also, should we be specifying
  193. // authentication info?
  194. //
  195. if (pBindFunc != BindNamedPipe)
  196. {
  197. RpcStatus = RpcEpResolveBinding(BindingHandle,
  198. ClientIfHandle);
  199. CHECK_HRESULT(HRESULT_FROM_WIN32(RpcStatus));
  200. }
  201. }
  202. else if (RpcStatus == RPC_S_PROTSEQ_NOT_SUPPORTED)
  203. {
  204. //
  205. // If the protocol is not on this computer, then rearrange
  206. // the list so it is not tried anymore.
  207. //
  208. CopyMemory(&grgProtocolBindFuncs[i],
  209. &grgProtocolBindFuncs[i + 1],
  210. sizeof(grgProtocolBindFuncs) -
  211. (&grgProtocolBindFuncs[i + 1] - &grgProtocolBindFuncs[0]));
  212. i--;
  213. }
  214. //
  215. // Try the next protocol's connection function.
  216. //
  217. if (RpcStatus != RPC_S_OK)
  218. {
  219. i++;
  220. pBindFunc = grgProtocolBindFuncs[i];
  221. }
  222. } while (!((RpcStatus == RPC_S_OK) || (pBindFunc == NULL)));
  223. }
  224. return(BindingHandle);
  225. }
  226. //+---------------------------------------------------------------------------
  227. //
  228. // Function: GenericUnbind
  229. //
  230. // Synopsis:
  231. //
  232. // Arguments: [ServerName] -- Server to bind to.
  233. //
  234. // Returns:
  235. //
  236. // Notes: None.
  237. //
  238. //----------------------------------------------------------------------------
  239. extern "C" void
  240. GenericUnbind(LPCWSTR ServerName, RPC_BINDING_HANDLE BindingHandle)
  241. {
  242. UNREFERENCED_PARAMETER(ServerName);
  243. if (BindingHandle != NULL) {
  244. RPC_STATUS RpcStatus = RpcBindingFree(&BindingHandle);
  245. schAssert(RpcStatus == RPC_S_OK);
  246. }
  247. }
  248. //+---------------------------------------------------------------------------
  249. //
  250. // Function: BindingFromStringBinding
  251. //
  252. // Synopsis: Bind then free the string binding passed.
  253. //
  254. // Arguments: [StringBinding] -- Target string binding.
  255. // [pBindingHandle] -- Returned binding handle.
  256. //
  257. // Returns: RPC_STATUS code
  258. //
  259. // Notes: None.
  260. //
  261. //----------------------------------------------------------------------------
  262. RPC_STATUS
  263. BindingFromStringBinding(
  264. LPTSTR * StringBinding,
  265. RPC_BINDING_HANDLE * pBindingHandle)
  266. {
  267. RPC_STATUS RpcStatus;
  268. RpcStatus = RpcBindingFromStringBinding(*StringBinding, pBindingHandle);
  269. RpcStringFree(StringBinding);
  270. if (RpcStatus != RPC_S_OK)
  271. {
  272. *pBindingHandle = NULL;
  273. }
  274. return(RpcStatus);
  275. }
  276. //+---------------------------------------------------------------------------
  277. //
  278. // Function: BindViaProtocol
  279. //
  280. // Synopsis: Bind via the specified protocol.
  281. //
  282. // Arguments: [ServerName] -- Server name to bind to.
  283. // [pBindingHandle] -- Returned binding handle.
  284. //
  285. // Returns: RPC_STATUS code
  286. //
  287. // Notes: None.
  288. //
  289. //----------------------------------------------------------------------------
  290. RPC_STATUS
  291. BindViaProtocol(
  292. LPTSTR rpc_protocol,
  293. LPWSTR ServerName,
  294. RPC_BINDING_HANDLE * pBindingHandle)
  295. {
  296. TCHAR tszServerName[SA_MAX_COMPUTERNAME_LENGTH + 3]; // plus 3 for "\\" and NULL
  297. RPC_STATUS RpcStatus;
  298. LPTSTR StringBinding;
  299. LPTSTR PlainServerName;
  300. *pBindingHandle = NULL;
  301. schDebugOut((DEB_ITRACE,
  302. "Attempting RPC bind via protocol \"%ws\"\n",
  303. rpc_protocol));
  304. if (ServerName != NULL)
  305. {
  306. if (FAILED(StringCchCopy(tszServerName, SA_MAX_COMPUTERNAME_LENGTH + 3, ServerName)))
  307. {
  308. return ERROR_INVALID_COMPUTERNAME;
  309. }
  310. }
  311. //
  312. // Ignore leading "\\"
  313. //
  314. if (ServerName != NULL && ServerName[0] == L'\\' &&
  315. ServerName[1] == L'\\')
  316. {
  317. PlainServerName = &tszServerName[2];
  318. }
  319. else
  320. {
  321. PlainServerName = ServerName != NULL ? tszServerName : NULL;
  322. }
  323. RpcStatus = RpcStringBindingCompose(NULL,
  324. rpc_protocol,
  325. PlainServerName,
  326. NULL, // endpoint
  327. NULL,
  328. &StringBinding);
  329. if (RpcStatus != RPC_S_OK)
  330. {
  331. CHECK_HRESULT(HRESULT_FROM_WIN32(RpcStatus));
  332. return(RpcStatus);
  333. }
  334. return(BindingFromStringBinding(&StringBinding, pBindingHandle));
  335. }
  336. //+---------------------------------------------------------------------------
  337. //
  338. // Function: BindNetBIOSOverNetBEUI
  339. //
  340. // Synopsis: Attempt to bind via netbeui.
  341. //
  342. // Arguments: [ServerName] -- Server name to bind to.
  343. // [pBindingHandle] -- Returned binding handle.
  344. //
  345. // Returns: RPC_STATUS code
  346. //
  347. // Notes: None.
  348. //
  349. //----------------------------------------------------------------------------
  350. RPC_STATUS
  351. BindNetBIOSOverNetBEUI(LPWSTR ServerName, RPC_BINDING_HANDLE * pBindingHandle)
  352. {
  353. return(BindViaProtocol(TEXT("ncacn_nb_nb"),
  354. ServerName,
  355. pBindingHandle));
  356. }
  357. //+---------------------------------------------------------------------------
  358. //
  359. // Function: BindNetBIOSOverTCP
  360. //
  361. // Synopsis: Attempt to bind via tcp over netbios.
  362. //
  363. // Arguments: [ServerName] -- Server name to bind to.
  364. // [pBindingHandle] -- Returned binding handle.
  365. //
  366. // Returns: RPC_STATUS code
  367. //
  368. // Notes: None.
  369. //
  370. //----------------------------------------------------------------------------
  371. RPC_STATUS
  372. BindNetBIOSOverTCP(LPWSTR ServerName, RPC_BINDING_HANDLE * pBindingHandle)
  373. {
  374. return(BindViaProtocol(TEXT("ncacn_nb_tcp"),
  375. ServerName,
  376. pBindingHandle));
  377. }
  378. //+---------------------------------------------------------------------------
  379. //
  380. // Function: BindNetBIOSOverIPX
  381. //
  382. // Synopsis: Attempt to bind via ipx over netbios.
  383. //
  384. // Arguments: [ServerName] -- Server name to bind to.
  385. // [pBindingHandle] -- Returned binding handle.
  386. //
  387. // Returns: RPC_STATUS code
  388. //
  389. // Notes: None.
  390. //
  391. //----------------------------------------------------------------------------
  392. RPC_STATUS
  393. BindNetBIOSOverIPX(LPWSTR ServerName, RPC_BINDING_HANDLE * pBindingHandle)
  394. {
  395. return(BindViaProtocol(TEXT("ncacn_nb_ipx"),
  396. ServerName,
  397. pBindingHandle));
  398. }
  399. //+---------------------------------------------------------------------------
  400. //
  401. // Function: BindNamedPipe
  402. //
  403. // Synopsis: Attempt to bind via named pipes.
  404. //
  405. // Arguments: [ServerName] -- Server name to bind to.
  406. // [pBindingHandle] -- Returned binding handle.
  407. //
  408. // Returns: ERROR_INVALID_COMPUTERNAME
  409. // RPC_STATUS code
  410. //
  411. // Notes: Server side *not* supported in Win95.
  412. //
  413. //----------------------------------------------------------------------------
  414. RPC_STATUS
  415. BindNamedPipe(LPWSTR ServerName, RPC_BINDING_HANDLE * pBindingHandle)
  416. {
  417. RPC_STATUS RpcStatus;
  418. LPTSTR StringBinding;
  419. LPWSTR SlashServerName;
  420. WCHAR Buffer[SA_MAX_COMPUTERNAME_LENGTH + 3]; // plus 3 for '\\' and NULL
  421. int have_slashes;
  422. ULONG NameLen;
  423. *pBindingHandle = NULL;
  424. if (ServerName[1] == L'\\')
  425. {
  426. have_slashes = 1;
  427. }
  428. else
  429. {
  430. have_slashes = 0;
  431. }
  432. //
  433. // Be nice and prepend slashes if not supplied.
  434. //
  435. NameLen = wcslen(ServerName);
  436. if ((!have_slashes) && (NameLen > 0))
  437. {
  438. if ((NameLen + 2) >= sizeof(Buffer))
  439. {
  440. return(ERROR_INVALID_COMPUTERNAME);
  441. }
  442. Buffer[0] = L'\\';
  443. Buffer[1] = L'\\';
  444. if (FAILED(StringCchCopy(&Buffer[2], SA_MAX_COMPUTERNAME_LENGTH + 1, ServerName))) // this is really SA_MAX_COMPUTERNAME_LENGTH + 3 - 2
  445. {
  446. return ERROR_INVALID_COMPUTERNAME;
  447. }
  448. SlashServerName = Buffer;
  449. }
  450. else
  451. {
  452. SlashServerName = ServerName;
  453. }
  454. RpcStatus = RpcStringBindingCompose(0,
  455. TEXT("ncacn_np"),
  456. SlashServerName,
  457. TEXT("\\PIPE\\atsvc"),
  458. NULL,
  459. &StringBinding);
  460. if (RpcStatus != RPC_S_OK)
  461. {
  462. CHECK_HRESULT(HRESULT_FROM_WIN32(RpcStatus));
  463. return(RpcStatus);
  464. }
  465. return(BindingFromStringBinding(&StringBinding, pBindingHandle));
  466. }
  467. //+---------------------------------------------------------------------------
  468. //
  469. // Function: BindSPX
  470. //
  471. // Synopsis: Attempt to bind over SPX.
  472. //
  473. // Arguments: [ServerName] -- Server name to bind to.
  474. // [pBindingHandle] -- Returned binding handle.
  475. //
  476. // Returns: RPC_STATUS code
  477. //
  478. // Notes: None.
  479. //
  480. //----------------------------------------------------------------------------
  481. RPC_STATUS
  482. BindSPX(LPWSTR ServerName, RPC_BINDING_HANDLE * pBindingHandle)
  483. {
  484. return(BindViaProtocol(TEXT("ncacn_spx"),
  485. ServerName,
  486. pBindingHandle));
  487. }
  488. //+---------------------------------------------------------------------------
  489. //
  490. // Function: BindTCPIP
  491. //
  492. // Synopsis: Attempt to bind over TCP/IP.
  493. //
  494. // Arguments: [ServerName] -- Server name to bind to.
  495. // [pBindingHandle] -- Returned binding handle.
  496. //
  497. // Returns: RPC_STATUS code
  498. //
  499. // Notes: None.
  500. //
  501. //----------------------------------------------------------------------------
  502. RPC_STATUS
  503. BindTCPIP(LPWSTR ServerName, RPC_BINDING_HANDLE * pBindingHandle)
  504. {
  505. return(BindViaProtocol(TEXT("ncacn_ip_tcp"),
  506. ServerName,
  507. pBindingHandle));
  508. }