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.

916 lines
18 KiB

  1. #ifndef _W3CONTEXT_HXX_
  2. #define _W3CONTEXT_HXX_
  3. #define W3_PARAMETERS_KEY \
  4. L"System\\CurrentControlSet\\Services\\w3svc\\Parameters"
  5. // Is it a UNC Path?
  6. #define ISUNC(a) ((a)[0]==L'\\' && (a)[1]==L'\\')
  7. #define W3_FLAG_ASYNC 0x00000001
  8. #define W3_FLAG_SYNC 0x00000002
  9. #define W3_FLAG_NO_CUSTOM_ERROR 0x00000004
  10. #define W3_FLAG_MORE_DATA 0x00000008
  11. #define W3_FLAG_PAST_END_OF_REQ 0x00000010
  12. #define W3_FLAG_NO_HEADERS 0x00000020
  13. #define W3_FLAG_NO_CONTENT_LENGTH 0x00000040
  14. #define W3_FLAG_NO_ERROR_BODY 0x00000080
  15. #define W3_FLAG_VALID ( W3_FLAG_ASYNC | \
  16. W3_FLAG_SYNC | \
  17. W3_FLAG_NO_CUSTOM_ERROR | \
  18. W3_FLAG_MORE_DATA | \
  19. W3_FLAG_PAST_END_OF_REQ | \
  20. W3_FLAG_NO_HEADERS | \
  21. W3_FLAG_NO_ERROR_BODY | \
  22. W3_FLAG_NO_CONTENT_LENGTH )
  23. #define VALID_W3_FLAGS(x) ( (x) == ((x) & (W3_FLAG_VALID)) )
  24. class URL_CONTEXT;
  25. class W3_HANDLER;
  26. class COMPRESSION_CONTEXT;
  27. //
  28. // Access check state
  29. //
  30. // We potentially do two asynchronous operations in determining whether
  31. // a given request is valid
  32. // 1) Do an RDNS lookup if restrictions are configured in metabase
  33. // 2) Request a client certificate if configured in metabase
  34. //
  35. enum W3_CONTEXT_ACCESS_STATE
  36. {
  37. ACCESS_STATE_START,
  38. ACCESS_STATE_RDNS,
  39. ACCESS_STATE_CLIENT_CERT_PRELOAD_ENTITY,
  40. ACCESS_STATE_CLIENT_CERT,
  41. ACCESS_STATE_AUTHENTICATION,
  42. ACCESS_STATE_SENDING_ERROR,
  43. ACCESS_STATE_DONE
  44. };
  45. //
  46. // W3_CONTEXT - Object representing an execution of the state machine to
  47. // handle a given request from UL
  48. //
  49. #define W3_CONTEXT_LIST_SPINS 200
  50. //
  51. // maximum number of nested child execute calls that are supported
  52. //
  53. #define W3_CONTEXT_MAX_RECURSION_LEVEL 100
  54. #define W3_CONTEXT_SIGNATURE ((DWORD) 'XC3W')
  55. #define W3_CONTEXT_SIGNATURE_FREE ((DWORD) 'xc3w')
  56. class W3_CONTEXT
  57. {
  58. private:
  59. DWORD _dwSignature;
  60. //
  61. // Handler for this context
  62. //
  63. W3_HANDLER * _pHandler;
  64. //
  65. // Error Status for request
  66. //
  67. HRESULT _errorStatus;
  68. //
  69. // Completion indication (for synchronous execution of handlers)
  70. //
  71. HANDLE _hCompletion;
  72. //
  73. // Custom error file to cleanup
  74. //
  75. W3_FILE_INFO * _pCustomErrorFile;
  76. //
  77. // Maintain list of contexts
  78. //
  79. LIST_ENTRY _listEntry;
  80. //
  81. // Where are we with checking access rights for this request
  82. //
  83. W3_CONTEXT_ACCESS_STATE _accessState;
  84. BOOL _fDNSRequiredForAccess; // argh
  85. //
  86. // The status of last child request executed by this context
  87. //
  88. USHORT _childStatusCode;
  89. USHORT _childSubErrorCode;
  90. HRESULT _childError;
  91. //
  92. // Is authentication access check required or not
  93. //
  94. BOOL _fAuthAccessCheckRequired;
  95. //
  96. // Are we suppressing the response entity (normally if it is a HEAD
  97. // request to something other than an ISAPI)
  98. //
  99. BOOL _fSuppressEntity;
  100. //
  101. // Recursion level for the ExecuteUrl() used to prevent infinite recursion
  102. // If recursion level reaches W3_CONTEXT_MAX_RECURSION_LEVEL value
  103. // then no more IsapiExecuteUrl() or ExecuteChildRequest() calls are allowed
  104. //
  105. DWORD _dwRecursionLevel;
  106. //
  107. // Keep a reference to the VrToken so it won't get deleted somewhere else
  108. //
  109. TOKEN_CACHE_ENTRY * _pctVrToken;
  110. //
  111. // Chunk buffer
  112. //
  113. CHUNK_BUFFER _ChunkBuffer;
  114. CONTEXT_STATUS
  115. ExecuteCurrentHandler(
  116. VOID
  117. );
  118. protected:
  119. //
  120. // The flags determining how to execute this request
  121. // (we let child contexts alter these flags if needed)
  122. //
  123. DWORD _dwExecFlags;
  124. public:
  125. static CHAR sm_achRedirectMessage[ 512 ];
  126. static DWORD sm_cbRedirectMessage;
  127. static CHAR * sm_pszAccessDeniedMessage;
  128. W3_CONTEXT(
  129. DWORD dwExecFlags,
  130. DWORD dwRecursionLevel
  131. );
  132. virtual ~W3_CONTEXT();
  133. virtual
  134. BOOL
  135. QueryResponseSent(
  136. VOID
  137. ) = 0;
  138. virtual
  139. BOOL
  140. QuerySendLocation(
  141. VOID
  142. )
  143. {
  144. return FALSE;
  145. }
  146. virtual
  147. BOOL
  148. QueryNeedFinalDone(
  149. VOID
  150. ) = 0;
  151. virtual
  152. VOID
  153. SetNeedFinalDone(
  154. VOID
  155. ) = 0;
  156. virtual
  157. W3_REQUEST *
  158. QueryRequest(
  159. VOID
  160. ) = 0;
  161. virtual
  162. W3_RESPONSE *
  163. QueryResponse(
  164. VOID
  165. ) = 0;
  166. virtual
  167. W3_SITE *
  168. QuerySite(
  169. VOID
  170. ) = 0;
  171. virtual
  172. W3_CONTEXT *
  173. QueryParentContext(
  174. VOID
  175. ) = 0;
  176. virtual
  177. W3_MAIN_CONTEXT *
  178. QueryMainContext(
  179. VOID
  180. ) = 0;
  181. virtual
  182. URL_CONTEXT *
  183. QueryUrlContext(
  184. VOID
  185. ) = 0;
  186. virtual
  187. W3_USER_CONTEXT *
  188. QueryUserContext(
  189. VOID
  190. ) = 0;
  191. virtual
  192. W3_FILTER_CONTEXT *
  193. QueryFilterContext(
  194. BOOL fCreateIfNotFound = TRUE
  195. ) = 0;
  196. virtual
  197. ULATQ_CONTEXT
  198. QueryUlatqContext(
  199. VOID
  200. ) = 0;
  201. virtual
  202. BOOL
  203. QueryProviderHandled(
  204. VOID
  205. ) = 0;
  206. virtual
  207. BOOL
  208. NotifyFilters(
  209. DWORD dwNotification,
  210. VOID * pvFilterInfo,
  211. BOOL * pfFinished
  212. ) = 0;
  213. virtual
  214. BOOL
  215. IsNotificationNeeded(
  216. DWORD dwNotification
  217. ) = 0;
  218. virtual
  219. VOID
  220. SetDisconnect(
  221. BOOL fDisconnect
  222. ) = 0;
  223. virtual
  224. BOOL
  225. QueryDisconnect(
  226. VOID
  227. ) = 0;
  228. virtual
  229. VOID
  230. SetDoneWithCompression(
  231. VOID
  232. ) = 0;
  233. virtual
  234. BOOL
  235. QueryDoneWithCompression(
  236. VOID
  237. ) = 0;
  238. virtual
  239. VOID
  240. SetCompressionContext(
  241. COMPRESSION_CONTEXT * pCompressionContext
  242. ) = 0;
  243. virtual
  244. COMPRESSION_CONTEXT *
  245. QueryCompressionContext(
  246. VOID
  247. ) = 0;
  248. virtual
  249. HTTP_LOG_FIELDS_DATA *
  250. QueryUlLogData(
  251. VOID
  252. ) = 0;
  253. virtual
  254. VOID
  255. SetLastIOPending(
  256. LAST_IO_PENDING ioPending
  257. ) = 0;
  258. virtual
  259. VOID
  260. IncrementBytesRecvd(
  261. DWORD dwRead
  262. ) = 0;
  263. virtual
  264. VOID
  265. IncrementBytesSent(
  266. DWORD dwSent
  267. ) = 0;
  268. virtual
  269. BOOL
  270. QueryIsUlCacheable(
  271. VOID
  272. ) = 0;
  273. virtual
  274. VOID
  275. DisableUlCache(
  276. VOID
  277. ) = 0;
  278. //
  279. // Other fixed W3_CONTEXT methods
  280. //
  281. VOID *
  282. ContextAlloc(
  283. DWORD cbSize
  284. );
  285. W3_HANDLER *
  286. QueryHandler(
  287. VOID
  288. ) const
  289. {
  290. return _pHandler;
  291. }
  292. VOID
  293. SetChildStatusAndError(
  294. USHORT ChildStatusCode,
  295. USHORT ChildSubError,
  296. HRESULT ChildError
  297. )
  298. {
  299. _childStatusCode = ChildStatusCode;
  300. _childSubErrorCode = ChildSubError;
  301. _childError = ChildError;
  302. }
  303. VOID
  304. QueryChildStatusAndError(
  305. USHORT * pChildStatusCode,
  306. USHORT * pChildSubError,
  307. DWORD * pChildError
  308. ) const
  309. {
  310. DBG_ASSERT( pChildStatusCode != NULL );
  311. DBG_ASSERT( pChildSubError != NULL );
  312. DBG_ASSERT( pChildError != NULL );
  313. *pChildStatusCode = _childStatusCode;
  314. *pChildSubError = _childSubErrorCode;
  315. if ( FAILED( _childError ) )
  316. {
  317. *pChildError = WIN32_FROM_HRESULT( _childError );
  318. }
  319. else
  320. {
  321. *pChildError = ERROR_SUCCESS;
  322. }
  323. }
  324. BOOL
  325. QuerySendCustomError(
  326. VOID
  327. ) const
  328. {
  329. if ( _dwExecFlags & W3_FLAG_NO_CUSTOM_ERROR )
  330. {
  331. return FALSE;
  332. }
  333. else
  334. {
  335. return TRUE;
  336. }
  337. }
  338. BOOL
  339. QuerySendErrorBody(
  340. VOID
  341. ) const
  342. {
  343. if ( _dwExecFlags & W3_FLAG_NO_ERROR_BODY )
  344. {
  345. return FALSE;
  346. }
  347. else
  348. {
  349. return TRUE;
  350. }
  351. }
  352. BOOL
  353. QuerySendHeaders(
  354. VOID
  355. ) const
  356. {
  357. if ( _dwExecFlags & W3_FLAG_NO_HEADERS )
  358. {
  359. return FALSE;
  360. }
  361. else
  362. {
  363. return TRUE;
  364. }
  365. }
  366. VOID
  367. SetAuthAccessCheckRequired(
  368. BOOL fAuthAccessCheckRequired
  369. )
  370. {
  371. _fAuthAccessCheckRequired = fAuthAccessCheckRequired;
  372. }
  373. BOOL
  374. QueryAuthAccessCheckRequired(
  375. VOID
  376. ) const
  377. {
  378. return _fAuthAccessCheckRequired;
  379. }
  380. VOID
  381. SetSSICommandHandler(
  382. W3_HANDLER * pHandler
  383. );
  384. BOOL
  385. QueryDoUlLogging(
  386. VOID
  387. );
  388. BOOL
  389. QueryDoCustomLogging(
  390. VOID
  391. );
  392. HRESULT
  393. SetupCustomErrorFileResponse(
  394. STRU & strErrorFile
  395. );
  396. HRESULT
  397. SendResponse(
  398. DWORD dwFlags
  399. );
  400. HRESULT
  401. GetCertificateInfoEx(
  402. IN DWORD cbAllocated,
  403. OUT DWORD * pdwCertEncodingType,
  404. OUT unsigned char * pbCertEncoded,
  405. OUT DWORD * pcbCertEncoded,
  406. OUT DWORD * pdwCertificateFlags
  407. );
  408. HANDLE
  409. QueryImpersonationToken(
  410. BOOL * pfIsVrToken = NULL
  411. );
  412. HANDLE
  413. QueryPrimaryToken(
  414. VOID
  415. );
  416. TOKEN_CACHE_ENTRY *
  417. QueryVrToken(
  418. VOID
  419. )
  420. {
  421. return _pctVrToken;
  422. }
  423. VOID
  424. QueryFileCacheUser(
  425. CACHE_USER * pFileUser
  426. );
  427. CONTEXT_STATUS
  428. CheckAccess(
  429. BOOL fCompletion,
  430. DWORD cbCompletion,
  431. DWORD dwCompletionStatus,
  432. BOOL * pfAccessAllowed
  433. );
  434. CERTIFICATE_CONTEXT *
  435. QueryCertificateContext(
  436. VOID
  437. );
  438. CHUNK_BUFFER *
  439. QueryHeaderBuffer(
  440. VOID
  441. )
  442. {
  443. return &_ChunkBuffer;
  444. }
  445. BOOL
  446. CheckClientCertificateAccess(
  447. VOID
  448. );
  449. HRESULT
  450. SendEntity(
  451. DWORD dwFlags
  452. );
  453. HRESULT
  454. ReceiveEntity(
  455. DWORD dwFlags,
  456. VOID * pBuffer,
  457. DWORD cbBuffer,
  458. DWORD * pBytesReceived
  459. );
  460. DWORD
  461. QueryRemainingEntityFromUl(
  462. VOID
  463. );
  464. VOID SetRemainingEntityFromUl(
  465. DWORD cbRemaining
  466. );
  467. VOID
  468. QueryAlreadyAvailableEntity(
  469. VOID ** ppvBuffer,
  470. DWORD * pcbBuffer
  471. );
  472. HRESULT
  473. QueryErrorStatus(
  474. VOID
  475. ) const
  476. {
  477. return _errorStatus;
  478. }
  479. VOID
  480. SetErrorStatus(
  481. HRESULT errorStatus
  482. )
  483. {
  484. _errorStatus = errorStatus;
  485. }
  486. HRESULT
  487. CheckUrlRedirection(
  488. BOOL *pfRedirected,
  489. STRU *pstrDestination,
  490. HTTP_STATUS *pStatusCode
  491. );
  492. HRESULT
  493. SetupHttpRedirect(
  494. STRA & strPath,
  495. BOOL fIncludeParameters,
  496. HTTP_STATUS & httpStatus
  497. );
  498. HRESULT
  499. SetupHttpRedirect(
  500. STRU & strPath,
  501. BOOL fIncludeParameters,
  502. HTTP_STATUS & httpStatus
  503. );
  504. HRESULT
  505. SetupAllowHeader(
  506. VOID
  507. );
  508. BOOL
  509. CheckSignature(
  510. VOID
  511. ) const
  512. {
  513. return _dwSignature == W3_CONTEXT_SIGNATURE;
  514. }
  515. BOOL
  516. QueryAccessChecked(
  517. VOID
  518. ) const
  519. {
  520. return _accessState == ACCESS_STATE_DONE;
  521. }
  522. VOID
  523. ResetAccessCheck(
  524. VOID
  525. )
  526. {
  527. _accessState = ACCESS_STATE_START;
  528. }
  529. HRESULT
  530. SetupCompletionEvent(
  531. VOID
  532. )
  533. {
  534. _hCompletion = IIS_CREATE_EVENT( "W3_CONTEXT::_hCompletion",
  535. this,
  536. FALSE,
  537. FALSE );
  538. if ( _hCompletion == NULL )
  539. {
  540. return HRESULT_FROM_WIN32( GetLastError() );
  541. }
  542. else
  543. {
  544. return NO_ERROR;
  545. }
  546. }
  547. VOID
  548. WaitForCompletion(
  549. VOID
  550. )
  551. {
  552. if ( _hCompletion )
  553. {
  554. WaitForSingleObject( _hCompletion, INFINITE );
  555. }
  556. }
  557. VOID
  558. IndicateCompletion(
  559. VOID
  560. )
  561. {
  562. if ( _hCompletion )
  563. {
  564. SetEvent( _hCompletion );
  565. }
  566. }
  567. BOOL
  568. QueryIsSynchronous(
  569. VOID
  570. ) const
  571. {
  572. return _hCompletion != NULL;
  573. }
  574. HRESULT
  575. IsapiExecuteUrl(
  576. EXEC_URL_INFO * pExecUrlInfo
  577. );
  578. HRESULT
  579. CleanIsapiExecuteUrl(
  580. EXEC_URL_INFO * pExecUrlInfo
  581. );
  582. HRESULT
  583. IsapiSendCustomError(
  584. HSE_CUSTOM_ERROR_INFO * pCustomErrorInfo
  585. );
  586. HRESULT
  587. CleanIsapiSendCustomError(
  588. HSE_CUSTOM_ERROR_INFO * pCustomErrorInfo
  589. );
  590. HRESULT
  591. ExecuteChildRequest(
  592. W3_REQUEST * pNewRequest,
  593. BOOL fOwnRequest,
  594. DWORD dwFlags
  595. );
  596. HRESULT
  597. ExecuteHandler(
  598. DWORD dwFlags,
  599. BOOL * pfDidImmediateFinish = NULL
  600. );
  601. CONTEXT_STATUS
  602. ExecuteHandlerCompletion(
  603. DWORD cbCompletion,
  604. DWORD dwCompletionStatus
  605. );
  606. HRESULT
  607. CheckPathInfoExists(
  608. W3_HANDLER ** ppHandler
  609. );
  610. HRESULT
  611. InternalDetermineHandler(
  612. W3_HANDLER ** ppHandler,
  613. BOOL fDoExistenceCheck
  614. );
  615. HRESULT
  616. DetermineHandler(
  617. VOID
  618. )
  619. {
  620. return InternalDetermineHandler( &_pHandler, TRUE );
  621. }
  622. HRESULT
  623. ValidateAppPool(
  624. BOOL * pfAppPoolValid
  625. );
  626. virtual
  627. DWORD
  628. QueryCurrentStarScriptMapIndex(
  629. VOID
  630. ) = 0;
  631. static HRESULT
  632. Initialize(
  633. VOID
  634. );
  635. static VOID
  636. Terminate(
  637. VOID
  638. );
  639. static
  640. VOID
  641. OnCleanIsapiExecuteUrl(
  642. DWORD dwCompletionStatus,
  643. DWORD cbWritten,
  644. LPOVERLAPPED lpo
  645. );
  646. static
  647. VOID
  648. OnCleanIsapiSendCustomError(
  649. DWORD dwCompletionStatus,
  650. DWORD cbWritten,
  651. LPOVERLAPPED lpo
  652. );
  653. };
  654. //
  655. // EXECUTE_CONTEXT Used to marshall an IsapiExecuteUrl() or
  656. // IsapiSendCustomError() on a clean (non-coinited) thread
  657. //
  658. #define EXECUTE_CONTEXT_SIGNATURE ((DWORD) 'TCXE')
  659. #define EXECUTE_CONTEXT_SIGNATURE_FREE ((DWORD) 'xcxe')
  660. class EXECUTE_CONTEXT
  661. {
  662. public:
  663. EXECUTE_CONTEXT( W3_CONTEXT * pW3Context )
  664. {
  665. DBG_ASSERT( pW3Context != NULL );
  666. _hEvent = NULL;
  667. _pW3Context = pW3Context;
  668. ZeroMemory( &_ExecUrlInfo, sizeof( _ExecUrlInfo ) );
  669. ZeroMemory( &_UserInfo, sizeof( _UserInfo ) );
  670. ZeroMemory( &_EntityInfo, sizeof( _EntityInfo ) );
  671. _dwSignature = EXECUTE_CONTEXT_SIGNATURE;
  672. }
  673. virtual ~EXECUTE_CONTEXT()
  674. {
  675. _dwSignature = EXECUTE_CONTEXT_SIGNATURE_FREE;
  676. if ( _hEvent != NULL )
  677. {
  678. SetEvent( _hEvent );
  679. }
  680. }
  681. HRESULT
  682. InitializeFromExecUrlInfo(
  683. EXEC_URL_INFO * pExecUrlInfo
  684. );
  685. EXEC_URL_INFO *
  686. QueryExecUrlInfo(
  687. VOID
  688. )
  689. {
  690. return &_ExecUrlInfo;
  691. }
  692. VOID
  693. SetCompleteEvent(
  694. HANDLE hEvent
  695. )
  696. {
  697. _hEvent = hEvent;
  698. }
  699. BOOL
  700. CheckSignature(
  701. VOID
  702. ) const
  703. {
  704. return _dwSignature == EXECUTE_CONTEXT_SIGNATURE;
  705. }
  706. HANDLE
  707. QueryCompleteEvent(
  708. VOID
  709. ) const
  710. {
  711. return _hEvent;
  712. }
  713. W3_CONTEXT *
  714. QueryW3Context(
  715. VOID
  716. ) const
  717. {
  718. return _pW3Context;
  719. }
  720. VOID *
  721. operator new(
  722. #if DBG
  723. size_t size
  724. #else
  725. size_t
  726. #endif
  727. )
  728. {
  729. DBG_ASSERT( size == sizeof( EXECUTE_CONTEXT ) );
  730. DBG_ASSERT( sm_pachExecuteContexts != NULL );
  731. return sm_pachExecuteContexts->Alloc();
  732. }
  733. VOID
  734. operator delete(
  735. VOID * pExecuteContext
  736. )
  737. {
  738. DBG_ASSERT( pExecuteContext != NULL );
  739. DBG_ASSERT( sm_pachExecuteContexts != NULL );
  740. DBG_REQUIRE( sm_pachExecuteContexts->Free( pExecuteContext ) );
  741. }
  742. static
  743. HRESULT
  744. Initialize(
  745. VOID
  746. );
  747. static
  748. VOID
  749. Terminate(
  750. VOID
  751. );
  752. private:
  753. DWORD _dwSignature;
  754. W3_CONTEXT * _pW3Context;
  755. EXEC_URL_INFO _ExecUrlInfo;
  756. EXEC_URL_USER_INFO _UserInfo;
  757. EXEC_URL_ENTITY_INFO _EntityInfo;
  758. CHUNK_BUFFER _HeaderBuffer;
  759. HANDLE _hEvent;
  760. static ALLOC_CACHE_HANDLER * sm_pachExecuteContexts;
  761. };
  762. #endif