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.

322 lines
8.1 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: U H C O M M O N . C P P
  7. //
  8. // Contents: Common UPnP Device Host code
  9. //
  10. // Notes:
  11. //
  12. // Author: mbend 21 Sep 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "ncbase.h"
  18. #include "uhcommon.h"
  19. static PSID g_pNetworkSid;
  20. HRESULT HrUDNStringToGUID(const wchar_t * szUUID, UUID & uuid)
  21. {
  22. HRESULT hr = S_OK;
  23. // Size of uuid:UUID
  24. const long nUDNStringLength = 41;
  25. // Size of uuid: prefix
  26. const long nUDNPrefix = 5;
  27. if(nUDNStringLength != lstrlen(szUUID))
  28. {
  29. TraceTag(ttidError, "GUIDFromString: Invalid GUID string");
  30. hr = E_INVALIDARG;
  31. }
  32. if(SUCCEEDED(hr))
  33. {
  34. // Skip past "uuid:"
  35. RPC_STATUS status;
  36. status = UuidFromString((unsigned short *)(const_cast<wchar_t*>(&szUUID[nUDNPrefix])), &uuid);
  37. if(RPC_S_INVALID_STRING_UUID == status)
  38. {
  39. TraceTag(ttidError, "GUIDFromString: Invalid GUID string");
  40. hr = E_INVALIDARG;
  41. }
  42. }
  43. TraceHr(ttidError, FAL, hr, FALSE, "HrUDNStringToGUID");
  44. return hr;
  45. }
  46. HRESULT HrContentURLToGUID(const wchar_t * szURL, GUID & guid)
  47. {
  48. HRESULT hr = S_OK;
  49. const wchar_t * sz = szURL;
  50. while (*sz && *sz != '=')
  51. {
  52. sz++;
  53. }
  54. if (*sz == '=')
  55. {
  56. sz++;
  57. hr = HrUDNStringToGUID(sz, guid);
  58. }
  59. TraceHr(ttidError, FAL, hr, FALSE, "HrContentURLToGUID");
  60. return hr;
  61. }
  62. //+---------------------------------------------------------------------------
  63. //
  64. // Function: HrSysAllocString
  65. //
  66. // Purpose: Simple HR wrapper for HrSysAllocString
  67. //
  68. // Arguments:
  69. // pszSource [in] Source string (WCHAR)
  70. // pbstrDest [out] Output param -- pointer to BSTR
  71. //
  72. // Returns: S_OK on success, E_OUTOFMEMORY if the alloc failed.
  73. //
  74. // Author: jeffspr 16 Sep 1999
  75. //
  76. // Notes:
  77. //
  78. HRESULT HrSysAllocString(LPCWSTR pszSource, BSTR *pbstrDest)
  79. {
  80. HRESULT hr = S_OK;
  81. Assert(pszSource);
  82. Assert(pbstrDest);
  83. *pbstrDest = SysAllocString(pszSource);
  84. if (!*pbstrDest)
  85. {
  86. TraceTag(ttidError, "HrSysAllocString failed on %S", pszSource);
  87. hr = E_OUTOFMEMORY;
  88. }
  89. TraceHr(ttidError, FAL, hr, FALSE, "HrSysAllocString");
  90. return hr;
  91. }
  92. //+---------------------------------------------------------------------------
  93. //
  94. // Function: HrIsAllowedCOMCallLocality
  95. //
  96. // Purpose: Used to check whether the caller of a method on a COM interface
  97. // should be allowed to call that method, based on whether it's
  98. // a call from the local machine or across the network
  99. //
  100. // Arguments:
  101. // clAllowedCallLocality - bitmask of allowed COM call localities
  102. //
  103. // Returns :
  104. // E_ACCESSDENIED if access is denied, S_OK if access is granted, error HRESULT otherwise.
  105. //
  106. // Author: AMallet 15 Mar 2002
  107. //
  108. HRESULT HrIsAllowedCOMCallLocality( IN CALL_LOCALITY clAllowedCallLocality )
  109. {
  110. HRESULT hr = S_OK;
  111. CALL_LOCALITY clCurrentCallLocality;
  112. //
  113. // Retrieve the current call locality
  114. //
  115. if ( FAILED( hr = HrGetCurrentCallLocality( &clCurrentCallLocality ) ))
  116. {
  117. TraceHr(ttidRegistrar,FAL, hr, FALSE,"HrGetCurrentCallLocality");
  118. }
  119. else
  120. {
  121. //
  122. // If current call locality isn't one of the allowed ones, deny access
  123. //
  124. if ( ( clCurrentCallLocality & clAllowedCallLocality ) == 0 )
  125. {
  126. TraceTag(ttidRegistrar, "Caller locality %d, granted locality %d, access denied.",
  127. clCurrentCallLocality, clAllowedCallLocality);
  128. hr = E_ACCESSDENIED;
  129. }
  130. }
  131. return hr;
  132. }
  133. //+---------------------------------------------------------------------------
  134. //
  135. // Function: HrGetCurrentCallLocality
  136. //
  137. // Purpose: Checks locality (in-proc, on same machine, on different machine) of
  138. // caller of a COM method
  139. //
  140. // Arguments:
  141. // pclCurrentCallLocality [out] - set to
  142. //
  143. // Author: radus 7 Mar 2002
  144. //
  145. // Notes: Currently implemented by checking the existence of the NETWORK
  146. // SID in the impersonation token of the calling thread
  147. HRESULT HrGetCurrentCallLocality( OUT CALL_LOCALITY *pclCurrentCallLocality )
  148. {
  149. HRESULT hr = S_OK;
  150. HANDLE hToken = NULL;
  151. BOOL fImpersonated = FALSE;
  152. if ( !pclCurrentCallLocality || !g_pNetworkSid )
  153. {
  154. return E_INVALIDARG;
  155. }
  156. //
  157. // Impersonate client
  158. //
  159. hr = CoImpersonateClient();
  160. if(SUCCEEDED(hr))
  161. {
  162. fImpersonated = TRUE;
  163. //
  164. // open impersonation token
  165. //
  166. if( OpenThreadToken(
  167. GetCurrentThread(),
  168. TOKEN_QUERY,
  169. TRUE,
  170. &hToken))
  171. {
  172. //
  173. // Check whether the token has the NETWORK SID in it; if it does,
  174. // assume the caller is on a different machine. Else, the caller
  175. // is on the local machine.
  176. //
  177. // Note : This isn't entirely foolproof in that it's possible for a local
  178. // user's token to also have the NETWORK SID eg if they called LsaLogonUser
  179. // with the Network LogonType, but it's the best we can do for XP SP1.
  180. // COM may have a way to get more accurate information for .NET Server.
  181. //
  182. BOOL fIsMember;
  183. if( CheckTokenMembership(
  184. hToken,
  185. g_pNetworkSid,
  186. &fIsMember))
  187. {
  188. if ( fIsMember )
  189. {
  190. *pclCurrentCallLocality = CALL_LOCALITY_DIFFERENTMACHINE;
  191. }
  192. else
  193. {
  194. *pclCurrentCallLocality = (CALL_LOCALITY)
  195. ( CALL_LOCALITY_LOCAL | CALL_LOCALITY_INPROC );
  196. }
  197. }
  198. else
  199. {
  200. hr = HrFromLastWin32Error();
  201. TraceHr(ttidRegistrar, FAL, hr, FALSE, "CheckTokenMembership");
  202. }
  203. }
  204. else
  205. {
  206. hr = HrFromLastWin32Error();
  207. TraceHr(ttidRegistrar, FAL, hr, FALSE, "OpenThreadToken");
  208. }
  209. }
  210. else
  211. {
  212. //
  213. // If the COM call is a direct in-proc v-tbl call, with no proxy, the call to
  214. // CoImpersonateClient will return RPC_E_CALL_COMPLETE; in this case,
  215. // we know the caller is in-proc to us
  216. //
  217. if ( hr == RPC_E_CALL_COMPLETE )
  218. {
  219. *pclCurrentCallLocality = CALL_LOCALITY_INPROC;
  220. hr = S_OK;
  221. }
  222. else
  223. {
  224. TraceHr(ttidRegistrar,FAL, hr, FALSE, "CoImpersonateClient");
  225. }
  226. }
  227. if ( hToken )
  228. {
  229. CloseHandle( hToken );
  230. }
  231. if ( fImpersonated )
  232. {
  233. CoRevertToSelf();
  234. }
  235. TraceHr(ttidRegistrar, FAL, hr, FALSE, "HrCheckAccessRights");
  236. return hr;
  237. }
  238. //+---------------------------------------------------------------------------
  239. //
  240. // Function: HrCreateNetworkSID
  241. //
  242. // Purpose: Allocates and initializes a SID structure with the NETWORK SID
  243. //
  244. // Arguments:
  245. // None
  246. //
  247. // Author: AMallet 16 Mar 2002
  248. //
  249. HRESULT HrCreateNetworkSID()
  250. {
  251. HRESULT hr = S_OK;
  252. SID_IDENTIFIER_AUTHORITY id = SECURITY_NT_AUTHORITY;
  253. //
  254. // Allocate the NETWORK SID
  255. //
  256. if( !AllocateAndInitializeSid(
  257. &id,
  258. 1,
  259. SECURITY_NETWORK_RID,
  260. 0,0,0,0,0,0,0,
  261. &g_pNetworkSid ) ) // S-1-5-2
  262. {
  263. hr = HrFromLastWin32Error();
  264. TraceHr(ttidError, FAL, hr, FALSE, "AllocateAndInitializeSid");
  265. }
  266. return hr;
  267. }
  268. //+---------------------------------------------------------------------------
  269. //
  270. // Function: CleanupNetworkSID
  271. //
  272. // Purpose: Cleans up the NETWORK SID allocated via call to HrCreateNetworkSID
  273. //
  274. // Arguments:
  275. // None
  276. //
  277. // Author: AMallet 16 Mar 2002
  278. //
  279. VOID CleanupNetworkSID()
  280. {
  281. if ( g_pNetworkSid )
  282. {
  283. FreeSid( g_pNetworkSid );
  284. }
  285. }