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.

294 lines
7.0 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name :
  4. anonymousprovider.cxx
  5. Abstract:
  6. Anonymous authentication provider
  7. Author:
  8. Bilal Alam (balam) 10-Jan-2000
  9. Environment:
  10. Win32 - User Mode
  11. Project:
  12. ULW3.DLL
  13. --*/
  14. #include "precomp.hxx"
  15. #include "anonymousprovider.hxx"
  16. HRESULT
  17. ANONYMOUS_AUTH_PROVIDER::DoesApply(
  18. W3_MAIN_CONTEXT * pMainContext,
  19. BOOL * pfApplies
  20. )
  21. /*++
  22. Routine Description:
  23. Does anonymous apply to this request?
  24. Arguments:
  25. pMainContext - Main context representing request
  26. pfApplies - Set to true if SSPI is applicable
  27. Return Value:
  28. HRESULT
  29. --*/
  30. {
  31. if ( pfApplies == NULL )
  32. {
  33. DBG_ASSERT( FALSE );
  34. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  35. }
  36. //
  37. // Anonymous ALWAYS applies!
  38. //
  39. *pfApplies = TRUE;
  40. return NO_ERROR;
  41. }
  42. HRESULT
  43. ANONYMOUS_AUTH_PROVIDER::DoAuthenticate(
  44. W3_MAIN_CONTEXT * pMainContext
  45. )
  46. /*++
  47. Routine Description:
  48. Do anonymous authentication (trivial)
  49. Arguments:
  50. pMainContext - Main context representing request
  51. Return Value:
  52. HRESULT
  53. --*/
  54. {
  55. W3_METADATA * pMetaData = NULL;
  56. TOKEN_CACHE_ENTRY * pCachedToken = NULL;
  57. HRESULT hr;
  58. ANONYMOUS_USER_CONTEXT* pUserContext = NULL;
  59. // add 1 to strUserDomain for separator "\"
  60. STACK_STRA( strUserDomain, UNLEN + IIS_DNLEN + 1 + 1 );
  61. STACK_STRA( strPassword, PWLEN + 1 );
  62. // add 1 to strUserDomainW for separator "\"
  63. STACK_STRU( strUserDomainW, UNLEN + IIS_DNLEN + 1 + 1 );
  64. STACK_STRU( strPasswordW, PWLEN + 1 );
  65. STACK_STRU( strDomainNameW, IIS_DNLEN + 1 );
  66. STACK_STRU( strUserNameW, UNLEN + 1 );
  67. BOOL fFinished;
  68. BOOL fRet;
  69. DWORD dwLogonError;
  70. BOOL fPossibleUPNLogon = FALSE;
  71. if ( pMainContext == NULL )
  72. {
  73. DBG_ASSERT( FALSE );
  74. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  75. }
  76. pMetaData = pMainContext->QueryUrlContext()->QueryMetaData();
  77. DBG_ASSERT( pMetaData != NULL );
  78. //
  79. // Notify authentication filters
  80. //
  81. if ( pMainContext->IsNotificationNeeded( SF_NOTIFY_AUTHENTICATION ) )
  82. {
  83. HTTP_FILTER_AUTHENT filterAuthent;
  84. DBG_ASSERT( strUserDomain.IsEmpty() );
  85. hr = strUserDomain.Resize( SF_MAX_USERNAME );
  86. if ( FAILED( hr ) )
  87. {
  88. return hr;
  89. }
  90. DBG_ASSERT( strPassword.IsEmpty() );
  91. hr = strPassword.Resize( SF_MAX_PASSWORD );
  92. if ( FAILED( hr ) )
  93. {
  94. return hr;
  95. }
  96. filterAuthent.pszUser = strUserDomain.QueryStr();
  97. filterAuthent.cbUserBuff = SF_MAX_USERNAME;
  98. filterAuthent.pszPassword = strPassword.QueryStr();
  99. filterAuthent.cbPasswordBuff = SF_MAX_PASSWORD;
  100. fRet = pMainContext->NotifyFilters( SF_NOTIFY_AUTHENTICATION,
  101. &filterAuthent,
  102. &fFinished );
  103. if ( !fRet )
  104. {
  105. return HRESULT_FROM_WIN32( GetLastError() );
  106. }
  107. if ( fFinished )
  108. {
  109. pMainContext->SetFinishedResponse();
  110. return NO_ERROR;
  111. }
  112. strUserDomain.SetLen( strlen( strUserDomain.QueryStr() ) );
  113. strPassword.SetLen( strlen( strPassword.QueryStr() ) );
  114. }
  115. //
  116. // If the filter set a user/password, then use it
  117. //
  118. if ( strUserDomain.QueryCCH() > 0 )
  119. {
  120. //
  121. // Convert to unicode
  122. //
  123. hr = strUserDomainW.CopyA( strUserDomain.QueryStr() );
  124. if ( FAILED( hr ) )
  125. {
  126. return hr;
  127. }
  128. hr = strPasswordW.CopyA( strPassword.QueryStr() );
  129. if ( FAILED( hr ) )
  130. {
  131. return hr;
  132. }
  133. //
  134. // Get username/domain out of domain\username
  135. //
  136. hr = W3_STATE_AUTHENTICATION::SplitUserDomain( strUserDomainW,
  137. &strUserNameW,
  138. &strDomainNameW,
  139. pMetaData->QueryDomainName(),
  140. &fPossibleUPNLogon );
  141. if ( FAILED( hr ) )
  142. {
  143. return hr;
  144. }
  145. //
  146. // Try to get the token
  147. //
  148. DBG_ASSERT( g_pW3Server->QueryTokenCache() != NULL );
  149. hr = g_pW3Server->QueryTokenCache()->GetCachedToken(
  150. strUserNameW.QueryStr(),
  151. strDomainNameW.QueryStr(),
  152. strPasswordW.QueryStr(),
  153. pMetaData->QueryLogonMethod(),
  154. fPossibleUPNLogon,
  155. &pCachedToken,
  156. &dwLogonError );
  157. if ( FAILED( hr ) )
  158. {
  159. return hr;
  160. }
  161. }
  162. else
  163. {
  164. //
  165. // Use the IUSR account
  166. //
  167. pCachedToken = pMetaData->QueryAnonymousToken();
  168. if ( pCachedToken != NULL )
  169. {
  170. //
  171. // Reference cached token because the metadata may go away from us
  172. // if AUTH_COMPLETE backed up the state machine
  173. //
  174. pCachedToken->ReferenceCacheEntry();
  175. }
  176. }
  177. if ( pCachedToken == NULL )
  178. {
  179. //
  180. // Bogus anonymous account
  181. //
  182. pMainContext->QueryResponse()->SetStatus( HttpStatusUnauthorized,
  183. Http401BadLogon );
  184. return NO_ERROR;
  185. }
  186. //
  187. // For perf reasons, the anonymous user context is inline
  188. //
  189. pUserContext = new (pMainContext) ANONYMOUS_USER_CONTEXT( this );
  190. DBG_ASSERT( pUserContext != NULL );
  191. hr = pUserContext->Create( pCachedToken,
  192. pMetaData->QueryLogonMethod() );
  193. if ( FAILED( hr ) )
  194. {
  195. return hr;
  196. }
  197. pMainContext->SetUserContext( pUserContext );
  198. return NO_ERROR;
  199. }
  200. HRESULT
  201. ANONYMOUS_USER_CONTEXT::Create(
  202. TOKEN_CACHE_ENTRY * pCachedToken,
  203. DWORD dwLogonMethod
  204. )
  205. /*++
  206. Routine Description:
  207. Initialize anonymous context
  208. Arguments:
  209. pCachedToken - anonymous user token
  210. dwLogonMethod - logon method
  211. Return Value:
  212. HRESULT
  213. --*/
  214. {
  215. if ( pCachedToken == NULL )
  216. {
  217. DBG_ASSERT( FALSE );
  218. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  219. }
  220. if ( dwLogonMethod == LOGON32_LOGON_INTERACTIVE ||
  221. dwLogonMethod == LOGON32_LOGON_BATCH )
  222. {
  223. _fDelegatable = TRUE;
  224. }
  225. _pCachedToken = pCachedToken;
  226. return NO_ERROR;
  227. }