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.

424 lines
9.9 KiB

  1. /*++
  2. Copyright (c) 1995-1996 Microsoft Corporation
  3. Module Name:
  4. Mid.cxx
  5. Abstract:
  6. Implements the CMid class.
  7. Author:
  8. Mario Goertzel [MarioGo]
  9. Revision History:
  10. MarioGo 12-13-95 Bits 'n pieces
  11. MarioGo 02-01-96 Move binding handles out of mid
  12. --*/
  13. #include<or.hxx>
  14. class CObjexPPing : public CParallelPing
  15. {
  16. public:
  17. CObjexPPing(WCHAR *pBindings, CMid *pMid) :
  18. _pBindings(pBindings),
  19. _pMid(pMid)
  20. {}
  21. BOOL NextCall(PROTSEQINFO *pProtseqInfo)
  22. {
  23. if (*_pBindings)
  24. {
  25. pProtseqInfo->pvUserInfo = _pBindings;
  26. pProtseqInfo->hRpc = _pMid->MakeBinding(_pBindings);
  27. _pBindings = OrStringSearch(_pBindings, 0) +1;
  28. return TRUE;
  29. }
  30. else
  31. {
  32. return FALSE;
  33. }
  34. }
  35. void ReleaseCall(PROTSEQINFO *pProtseqInfo)
  36. {
  37. if (pProtseqInfo->hRpc)
  38. {
  39. RpcBindingFree(&pProtseqInfo->hRpc);
  40. }
  41. }
  42. private:
  43. WCHAR * _pBindings;
  44. CMid * _pMid;
  45. };
  46. void dsaProtocolMerge(DUALSTRINGARRAY *pdsaSrc, DUALSTRINGARRAY **ppdsaDest)
  47. /*++
  48. Routine Description:
  49. Gives string bindings intersected with the allowed string bindings
  50. for this machine.
  51. Arguments:
  52. pdsaSrc - string bindings to intersect
  53. ppdsaDest - generated string bindings
  54. Return Value:
  55. none
  56. --*/
  57. {
  58. *ppdsaDest = (DUALSTRINGARRAY *)PrivMemAlloc(pdsaSrc->wNumEntries*sizeof(WCHAR) + sizeof(DUALSTRINGARRAY));
  59. if (!*ppdsaDest)
  60. {
  61. return;
  62. }
  63. LPWSTR pTempDest = (*ppdsaDest)->aStringArray;
  64. // NOTE: Do not change the order of these loops
  65. // It is pertinent to correctly order the final
  66. // string.
  67. for (ULONG i=0; i<cMyProtseqs; i++)
  68. {
  69. for (LPWSTR pTempSrc = pdsaSrc->aStringArray;
  70. *pTempSrc;
  71. pTempSrc = OrStringSearch(pTempSrc, 0) + 1)
  72. {
  73. if (aMyProtseqs[i] == *pTempSrc)
  74. {
  75. // tower ids are the same
  76. wcscpy(pTempDest, pTempSrc);
  77. pTempDest = OrStringSearch(pTempDest, 0) + 1;
  78. }
  79. }
  80. }
  81. ULONG_PTR len = pTempDest - (*ppdsaDest)->aStringArray;
  82. if ( len == 0)
  83. {
  84. *pTempDest = 0;
  85. pTempDest++;
  86. len++;
  87. }
  88. // copy sec bindings
  89. *pTempDest = 0;
  90. pTempDest++;
  91. len++;
  92. (*ppdsaDest)->wSecurityOffset = (USHORT) len;
  93. memcpy(pTempDest, pdsaSrc->aStringArray + pdsaSrc->wSecurityOffset,
  94. (pdsaSrc->wNumEntries - pdsaSrc->wSecurityOffset)*sizeof(WCHAR));
  95. len += pdsaSrc->wNumEntries - pdsaSrc->wSecurityOffset;
  96. (*ppdsaDest)->wNumEntries = (USHORT) len;
  97. }
  98. CMid::CMid( DUALSTRINGARRAY *pdsa, BOOL fLocal, ID OldMid, BOOL* pfInitOkay) :
  99. _fLocal(fLocal),
  100. _fStale(FALSE),
  101. _fDynamic(FALSE),
  102. _fInitialized(FALSE),
  103. _StringBinding(NULL),
  104. _fSecure(FALSE),
  105. _pdsaValidStringBindings(0)
  106. /*++
  107. Routine Description:
  108. Constructs a CMid object.
  109. Arguments:
  110. pdsa - The dual string array of the server rpcss.
  111. fLocal - TRUE if the mid represents this machine.
  112. OldMid - Optional reassigned machine id.
  113. Return Value:
  114. none
  115. --*/
  116. {
  117. DWORD i;
  118. // this must be allocated to include the size of the embedded dsa.
  119. dsaCopy(&_dsa, pdsa);
  120. // Set _fSecure iff we find an authentication service in the
  121. // dual string array that we are willing to use.
  122. _wAuthnSvc = RPC_C_AUTHN_NONE;
  123. _ulMarshaledTargetInfoLength = 0;
  124. _pMarshaledTargetInfo = NULL;
  125. for (i = 0; i < s_cRpcssSvc; i++)
  126. {
  127. if (ValidAuthnSvc( &_dsa, s_aRpcssSvc[i].wId ))
  128. {
  129. _fSecure = TRUE;
  130. break;
  131. }
  132. }
  133. if (OldMid)
  134. {
  135. _id = OldMid;
  136. ASSERT(fLocal);
  137. *pfInitOkay = TRUE;
  138. }
  139. else
  140. {
  141. *pfInitOkay = AllocateId(&_id);
  142. }
  143. }
  144. RPC_BINDING_HANDLE
  145. CMid::MakeBinding(WCHAR *pBinding)
  146. /*++
  147. Routine Description:
  148. Creates a binding handle from a specified string binding or a default
  149. string binding with or without an endpoint.
  150. Arguments:
  151. pBinding - The string binding to use or NULL for the default.
  152. Return Value:
  153. binding handle
  154. --*/
  155. {
  156. if (!pBinding)
  157. {
  158. pBinding = _StringBinding;
  159. }
  160. if (pBinding)
  161. {
  162. if (_fDynamic)
  163. {
  164. // Create binding without an endpoint.
  165. return ::GetBinding(pBinding);
  166. }
  167. else
  168. {
  169. return GetBindingToOr(pBinding);
  170. }
  171. }
  172. return 0;
  173. }
  174. RPC_BINDING_HANDLE
  175. CMid::GetBinding()
  176. /*++
  177. Routine Description:
  178. Gets an RPC binding handle to the remote machine.
  179. Arguments:
  180. None
  181. Return Value:
  182. 0 - when no more binding are available.
  183. non-zero - A binding to the machine.
  184. --*/
  185. {
  186. if (IsLocal())
  187. {
  188. return(0);
  189. }
  190. //
  191. // if the Mid is already initialized, then just
  192. // return the binding.
  193. //
  194. if (_fInitialized)
  195. {
  196. return MakeBinding();
  197. }
  198. //
  199. // merge the strings
  200. //
  201. DUALSTRINGARRAY *pdsaValidStringBindings = 0;
  202. if (!_pdsaValidStringBindings)
  203. {
  204. // merge with valid protocols for this server
  205. gpClientLock->LockExclusive();
  206. if (!_pdsaValidStringBindings)
  207. {
  208. dsaProtocolMerge(&_dsa, &pdsaValidStringBindings);
  209. if (!pdsaValidStringBindings)
  210. {
  211. gpClientLock->UnlockExclusive();
  212. return 0;
  213. }
  214. ASSERT(pdsaValidStringBindings);
  215. _pdsaValidStringBindings = pdsaValidStringBindings;
  216. }
  217. gpClientLock->UnlockExclusive();
  218. }
  219. // Ping the server on all bindings in parallel to get
  220. // the correct binding for this server. This loop executes
  221. // twice to try the bindings w/o the endpoint.
  222. //
  223. ULONG ndx;
  224. BOOL bNoEndpoint = FALSE;
  225. RPC_BINDING_HANDLE hserver = NULL;
  226. RPC_STATUS status;
  227. { // scope the parallel ping object
  228. CObjexPPing ping(_pdsaValidStringBindings->aStringArray, this);
  229. for (;;)
  230. {
  231. status = ping.Ping();
  232. if ( RPC_S_UNKNOWN_IF == status )
  233. {
  234. if ( ! bNoEndpoint )
  235. {
  236. for ( unsigned int ProtseqIndex = 0; ProtseqIndex < ping.HandleCount(); ProtseqIndex++ )
  237. {
  238. RPC_BINDING_HANDLE tmpBinding;
  239. status = RpcBindingCopy( ping.Info(ProtseqIndex)->hRpc, &tmpBinding);
  240. if (status != RPC_S_OK)
  241. break;
  242. status = RpcBindingFree( &(ping.Info(ProtseqIndex)->hRpc));
  243. if (status != RPC_S_OK)
  244. {
  245. RpcBindingFree(&tmpBinding);
  246. break;
  247. }
  248. status = RpcBindingReset(tmpBinding);
  249. if (status != RPC_S_OK)
  250. {
  251. RpcBindingFree(&tmpBinding);
  252. break;
  253. }
  254. ping.Info(ProtseqIndex)->hRpc = tmpBinding;
  255. }
  256. bNoEndpoint = TRUE;
  257. continue;
  258. }
  259. }
  260. if (status == RPC_S_OK && bNoEndpoint)
  261. {
  262. _fDynamic = TRUE;
  263. }
  264. break;
  265. }
  266. if (status == RPC_S_OK)
  267. {
  268. hserver = ping.GetWinner()->hRpc;
  269. ping.GetWinner()->hRpc = NULL;
  270. if (!_StringBinding)
  271. {
  272. gpClientLock->LockExclusive();
  273. if (!_StringBinding)
  274. {
  275. _StringBinding = (WCHAR *) ping.GetWinner()->pvUserInfo;
  276. }
  277. gpClientLock->UnlockExclusive();
  278. }
  279. }
  280. ping.Reset();
  281. } // end scope for ping object
  282. //
  283. // the mid is initialized now
  284. //
  285. if (RPC_S_OK == status)
  286. _fInitialized = TRUE;
  287. return hserver;
  288. }
  289. //keeps a copy of the passed in creds
  290. ORSTATUS CMid::SetMarshaledTargetInfo(unsigned long ulMarshaledTargetInfoLength, unsigned char *pMarshaledTargetInfo)
  291. {
  292. if (_pMarshaledTargetInfo)
  293. {
  294. MIDL_user_free(_pMarshaledTargetInfo);
  295. }
  296. _ulMarshaledTargetInfoLength = 0;
  297. _pMarshaledTargetInfo = NULL;
  298. ORSTATUS status=OR_OK;
  299. if (ulMarshaledTargetInfoLength)
  300. {
  301. _pMarshaledTargetInfo = (unsigned char *) MIDL_user_allocate(ulMarshaledTargetInfoLength * sizeof(char));
  302. if (_pMarshaledTargetInfo)
  303. {
  304. memcpy(_pMarshaledTargetInfo, pMarshaledTargetInfo, ulMarshaledTargetInfoLength);
  305. _ulMarshaledTargetInfoLength = ulMarshaledTargetInfoLength;
  306. }
  307. else
  308. status = ERROR_NOT_ENOUGH_MEMORY;
  309. }
  310. return status;
  311. }
  312. // hands out a copy of my creds
  313. ORSTATUS CMid::GetMarshaledTargetInfo(unsigned long *pulMarshaledTargetInfoLength, unsigned char **pucMarshaledTargetInfo)
  314. {
  315. ORSTATUS status=OR_OK;
  316. *pulMarshaledTargetInfoLength = 0;
  317. *pucMarshaledTargetInfo = NULL;
  318. if (_ulMarshaledTargetInfoLength)
  319. {
  320. *pucMarshaledTargetInfo = (unsigned char *) MIDL_user_allocate(_ulMarshaledTargetInfoLength * sizeof(char));
  321. if (*pucMarshaledTargetInfo)
  322. {
  323. memcpy(*pucMarshaledTargetInfo, _pMarshaledTargetInfo, _ulMarshaledTargetInfoLength);
  324. *pulMarshaledTargetInfoLength = _ulMarshaledTargetInfoLength;
  325. }
  326. else
  327. status = ERROR_NOT_ENOUGH_MEMORY;
  328. }
  329. return status;
  330. }