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.

281 lines
5.6 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name :
  4. certmapprovider.cxx
  5. Abstract:
  6. Active Directory Certificate Mapper 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 "certmapprovider.hxx"
  16. HRESULT
  17. CERTMAP_AUTH_PROVIDER::DoesApply(
  18. W3_MAIN_CONTEXT * pMainContext,
  19. BOOL * pfApplies
  20. )
  21. /*++
  22. Routine Description:
  23. Does certificate map authentication apply?
  24. Arguments:
  25. pMainContext - Main context
  26. pfApplies - Set to TRUE if cert map auth applies
  27. Return Value:
  28. HRESULT
  29. --*/
  30. {
  31. CERTIFICATE_CONTEXT * pCertificateContext;
  32. URL_CONTEXT * pUrlContext = NULL;
  33. W3_METADATA * pMetaData = NULL;
  34. BOOL fApplies = FALSE;
  35. if ( pMainContext == NULL ||
  36. pfApplies == NULL )
  37. {
  38. DBG_ASSERT( FALSE );
  39. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  40. }
  41. //
  42. // If cert mapping is not allowed for this vroot, then ignore client
  43. // cert token and let other authentication mechanisms do their thing
  44. //
  45. pUrlContext = pMainContext->QueryUrlContext();
  46. DBG_ASSERT( pUrlContext != NULL );
  47. pMetaData = pUrlContext->QueryMetaData();
  48. DBG_ASSERT( pMetaData != NULL );
  49. DBG_ASSERT( pMainContext->QuerySite() );
  50. if ( !pMainContext->QuerySite()->QueryUseDSMapper() )
  51. {
  52. fApplies = FALSE;
  53. }
  54. else if ( pMetaData->QuerySslAccessPerms() & VROOT_MASK_MAP_CERT )
  55. {
  56. pCertificateContext = pMainContext->QueryCertificateContext();
  57. if ( pCertificateContext != NULL )
  58. {
  59. if ( pCertificateContext->QueryImpersonationToken() != NULL )
  60. {
  61. fApplies = TRUE;
  62. }
  63. }
  64. }
  65. *pfApplies = fApplies;
  66. return NO_ERROR;
  67. }
  68. HRESULT
  69. CERTMAP_AUTH_PROVIDER::DoAuthenticate(
  70. W3_MAIN_CONTEXT * pMainContext
  71. )
  72. /*++
  73. Routine Description:
  74. Create a user context representing a cert mapped token
  75. Arguments:
  76. pMainContext - Main context
  77. Return Value:
  78. HRESULT
  79. --*/
  80. {
  81. CERTMAP_USER_CONTEXT * pUserContext = NULL;
  82. CERTIFICATE_CONTEXT * pCertificateContext = NULL;
  83. HANDLE hImpersonation;
  84. BOOL fDelegatable = FALSE;
  85. HRESULT hr = NO_ERROR;
  86. if ( pMainContext == NULL )
  87. {
  88. DBG_ASSERT( FALSE );
  89. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  90. }
  91. pCertificateContext = pMainContext->QueryCertificateContext();
  92. DBG_ASSERT( pCertificateContext != NULL );
  93. hImpersonation = pCertificateContext->QueryImpersonationToken();
  94. DBG_ASSERT( hImpersonation != NULL );
  95. //
  96. // Create the user context for this request
  97. //
  98. pUserContext = new CERTMAP_USER_CONTEXT( this );
  99. if ( pUserContext == NULL )
  100. {
  101. return HRESULT_FROM_WIN32( GetLastError() );
  102. }
  103. //
  104. // Is this a delegatable token? Put another way is this token mapped
  105. // using an IIS cert mapper (IIS cert mapper creates delegatable token,
  106. // the DS mapper does not)
  107. //
  108. fDelegatable = FALSE;
  109. hr = pUserContext->Create( hImpersonation, fDelegatable );
  110. if ( FAILED( hr ) )
  111. {
  112. pUserContext->DereferenceUserContext();
  113. pUserContext = NULL;
  114. return hr;
  115. }
  116. pMainContext->SetUserContext( pUserContext );
  117. return NO_ERROR;
  118. }
  119. HRESULT
  120. CERTMAP_AUTH_PROVIDER::OnAccessDenied(
  121. W3_MAIN_CONTEXT * pMainContext
  122. )
  123. /*++
  124. Routine Description:
  125. NOP since we have nothing to do on access denied
  126. Arguments:
  127. pMainContext - Main context
  128. Return Value:
  129. HRESULT
  130. --*/
  131. {
  132. //
  133. // No headers to add
  134. //
  135. return NO_ERROR;
  136. }
  137. HRESULT
  138. CERTMAP_USER_CONTEXT::Create(
  139. HANDLE hImpersonation,
  140. BOOL fDelegatable
  141. )
  142. /*++
  143. Routine Description:
  144. Create a certificate mapped user context
  145. Arguments:
  146. hImpersonation - Impersonation token
  147. fDelegatable - Is this token delegatable?
  148. Return Value:
  149. HRESULT
  150. --*/
  151. {
  152. DWORD cchUserName = sizeof( _achUserName ) / sizeof( WCHAR );
  153. if ( hImpersonation == NULL )
  154. {
  155. DBG_ASSERT( FALSE );
  156. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  157. }
  158. //
  159. // First the easy stuff
  160. //
  161. _fDelegatable = fDelegatable;
  162. _hImpersonationToken = hImpersonation;
  163. //
  164. // Now get the user name
  165. //
  166. if ( !SetThreadToken( NULL, _hImpersonationToken ) )
  167. {
  168. return HRESULT_FROM_WIN32( GetLastError() );
  169. }
  170. if ( !GetUserNameEx( NameSamCompatible,
  171. _achUserName,
  172. &cchUserName ) )
  173. {
  174. RevertToSelf();
  175. return HRESULT_FROM_WIN32( GetLastError() );
  176. }
  177. RevertToSelf();
  178. return NO_ERROR;
  179. }
  180. HANDLE
  181. CERTMAP_USER_CONTEXT::QueryPrimaryToken(
  182. VOID
  183. )
  184. /*++
  185. Routine Description:
  186. Get a primary token
  187. Arguments:
  188. None
  189. Return Value:
  190. HANDLE
  191. --*/
  192. {
  193. if ( _hPrimaryToken == NULL )
  194. {
  195. if ( DuplicateTokenEx( _hImpersonationToken,
  196. TOKEN_ALL_ACCESS,
  197. NULL,
  198. SecurityImpersonation,
  199. TokenPrimary,
  200. &_hPrimaryToken ) )
  201. {
  202. DBG_ASSERT( _hPrimaryToken != NULL );
  203. }
  204. }
  205. return _hPrimaryToken;
  206. }