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.

862 lines
25 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1998.
  5. //
  6. // File: imprsnat.hxx
  7. //
  8. // Contents: Classes used to control the security context.
  9. // When called from the "WWW service", the thread is
  10. // impersonated as the authenticated client, often the
  11. // "Internet Anonymous User". This user has few privileges
  12. // and cannot access the content index data needed to
  13. // resolve the queries. However, for enumerated queries, we
  14. // need to stay in the context of the client so that normal
  15. // access controls will work correctly.
  16. //
  17. // To assume the system context, we use the fact that before
  18. // impersonating as the client, the thread was in fact had
  19. // "local system" privileges.
  20. // We save the TOKEN of the current thread, revert to the system
  21. // privileges and on the way out, we restore the TOKEN of the
  22. // anonymous user.
  23. //
  24. // Impersonating a client involves just calling
  25. // ImpersonateLoggedOnUser with the supplied client token,
  26. // then calling RevertToSelf when done.
  27. //
  28. // Classes: CImpersonateSystem - Become the "system" context
  29. // CImpersonateClient - Impersonate to a client
  30. //
  31. // History: 2-16-96 srikants Created
  32. //
  33. //----------------------------------------------------------------------------
  34. #pragma once
  35. #include <smatch.hxx>
  36. #include <filterr.h>
  37. //+---------------------------------------------------------------------------
  38. //
  39. // Class: CImpersonateSystem
  40. //
  41. // Purpose: An unwindable class to impersonate system and revert back
  42. // to what it was before.
  43. //
  44. // History: 4-01-96 srikants Added header
  45. //
  46. //----------------------------------------------------------------------------
  47. class CImpersonateSystem
  48. {
  49. public:
  50. CImpersonateSystem( BOOL fShouldImpersonate = IsRunningAsSystem() ) :
  51. _fRevertedToSystem( FALSE ),
  52. _hClientToken( INVALID_HANDLE_VALUE )
  53. {
  54. if ( fShouldImpersonate )
  55. MakePrivileged();
  56. }
  57. ~CImpersonateSystem();
  58. // in SYSTEM context
  59. static BOOL IsImpersonated();
  60. static BOOL IsRunningAsSystem();
  61. static void SetRunningAsSystem();
  62. private:
  63. void MakePrivileged();
  64. static BOOL _fIsRunningAsSystem; // TRUE if query.dll came up initially
  65. BOOL _fRevertedToSystem; // Set to TRUE if we are running in
  66. // "SYSTEM" context.
  67. HANDLE _hClientToken; // Handle of the client token
  68. };
  69. //+---------------------------------------------------------------------------
  70. //
  71. // Class: CImpersonateClient
  72. //
  73. // Purpose: An unwindable class to impersonate a user whose token is given
  74. // and to revert back to system later.
  75. //
  76. // History: 4-01-96 srikants Added Header
  77. //
  78. //----------------------------------------------------------------------------
  79. class CImpersonateClient
  80. {
  81. public:
  82. CImpersonateClient( HANDLE hToken ) :
  83. _hClientToken( hToken )
  84. {
  85. if ( INVALID_HANDLE_VALUE != hToken )
  86. Impersonate();
  87. }
  88. ~CImpersonateClient();
  89. private:
  90. void Impersonate();
  91. HANDLE _hClientToken; // Handle of the client token
  92. };
  93. //+---------------------------------------------------------------------------
  94. //
  95. // Class: CLogonInfo
  96. //
  97. // Purpose: A linked list element that keeps logon information for a
  98. // user.
  99. //
  100. // History: 4-05-96 srikants Created
  101. //
  102. // Notes:
  103. //
  104. //----------------------------------------------------------------------------
  105. class CLogonInfo : public CDoubleLink
  106. {
  107. public:
  108. CLogonInfo()
  109. {
  110. CDoubleLink::Close();
  111. _pwszUser = _pwszDomain = 0;
  112. _ccUser = _ccDomain = 0;
  113. _cRef = 0; _fZombie = FALSE;
  114. _hToken = INVALID_HANDLE_VALUE;
  115. }
  116. ~CLogonInfo();
  117. DWORD Logon( WCHAR const * pwszUser, WCHAR const * pwszDomain,
  118. WCHAR const * pwszPassword );
  119. BOOL IsSameUser( WCHAR const * pwszUser, WCHAR const * pwszDomain ) const;
  120. BOOL IsSamePassword( WCHAR const * pwszPassword ) const;
  121. void Addref() { _cRef++; }
  122. void Release()
  123. {
  124. Win4Assert( _cRef > 0 );
  125. _cRef--;
  126. }
  127. BOOL IsInUse() const { return _cRef > 0; }
  128. void Zombify() { _fZombie = TRUE; }
  129. BOOL IsZombie() const { return _fZombie; }
  130. HANDLE GetHandle() const { return _hToken; }
  131. static WCHAR * AllocAndCopy( WCHAR const * pwszSrc, ULONG & cc );
  132. WCHAR * GetUser() { return _pwszUser; }
  133. WCHAR * GetDomain() { return _pwszDomain; }
  134. private:
  135. WCHAR * _pwszUser; // User Name
  136. ULONG _ccUser; // Length of user name
  137. WCHAR * _pwszDomain; // Domain Name
  138. ULONG _ccDomain;
  139. XArray<BYTE> _xEncryptedPassword;
  140. LONG _cRef; // Refcount
  141. BOOL _fZombie; // Set to TRUE if this has been
  142. // zombified
  143. HANDLE _hToken; // "Logged on" token for the account
  144. };
  145. class CLogonInfoList : public TDoubleList<CLogonInfo>
  146. {
  147. public:
  148. CLogonInfoList() {}
  149. void Empty();
  150. ~CLogonInfoList() { Empty(); }
  151. };
  152. typedef class TFwdListIter<CLogonInfo, CLogonInfoList> CFwdLogonInfoIter;
  153. //+---------------------------------------------------------------------------
  154. //
  155. // Class: CImprsObjInfo
  156. //
  157. // Purpose: A class that encapsulates the object that a user is trying
  158. // to access.
  159. //
  160. // History: 7-12-96 srikants Created
  161. //
  162. // Notes:
  163. //
  164. //----------------------------------------------------------------------------
  165. class CImprsObjInfo
  166. {
  167. public:
  168. CImprsObjInfo( WCHAR const * const pwszPath,
  169. WCHAR const * const pwszVPath )
  170. : _pwszPath( pwszPath ),
  171. _pwszVPath( pwszVPath )
  172. {
  173. }
  174. WCHAR const * GetPhysicalPath() const { return _pwszPath; }
  175. WCHAR const * GetVPath() const { return _pwszVPath; }
  176. private:
  177. WCHAR const * const _pwszPath; // physical path
  178. WCHAR const * const _pwszVPath; // Virtual path, can be 0
  179. };
  180. //+---------------------------------------------------------------------------
  181. //
  182. // Class: CPhyDirLogonInfo
  183. //
  184. // Purpose: Logon information for a physical directory
  185. //
  186. // History: 4-01-96 srikants Created
  187. //
  188. // Notes:
  189. //
  190. //----------------------------------------------------------------------------
  191. class CPhyDirLogonInfo : public CDoubleLink
  192. {
  193. friend class CImpersonationTokenCache;
  194. public:
  195. CPhyDirLogonInfo( CImpersonationTokenCache & cache,
  196. CImprsObjInfo const & obj,
  197. CLogonInfo * pLogonInfo
  198. );
  199. BOOL IsInScope( WCHAR const * pwszPath, ULONG len ) const
  200. {
  201. return _phyScope.IsInScope( pwszPath, len );
  202. }
  203. BOOL IsInScope( WCHAR const * pwszPath ) const
  204. {
  205. return _phyScope.IsInScope( pwszPath, wcslen(pwszPath) );
  206. }
  207. BOOL IsInVirtualScope( WCHAR const * pwszVPath ) const
  208. {
  209. return pwszVPath ?
  210. _virtualScope.IsInScope( pwszVPath, wcslen(pwszVPath) ) : TRUE;
  211. }
  212. BOOL IsMatch( CImprsObjInfo const & info ) const;
  213. int Compare( CPhyDirLogonInfo const & rhs ) const;
  214. HANDLE GetHandle() const
  215. {
  216. return _pLogonInfo ? _pLogonInfo->GetHandle()
  217. : INVALID_HANDLE_VALUE;
  218. }
  219. BOOL IsZombie() const { return _fIsZombie; }
  220. BOOL IsInUse() const { return _cRef > 0; }
  221. ULONG GetVirtualRootLen() const { return _ccVirtual; }
  222. BOOL IsSame( CImprsObjInfo const & info ) const;
  223. BOOL IsSameVPath( WCHAR const * pwszVPath ) const
  224. {
  225. Win4Assert( (0 == _pwszVirtualRoot && 0 == _ccVirtual) ||
  226. (0 != _pwszVirtualRoot && 0 != _ccVirtual) );
  227. ULONG ccVirtual = pwszVPath ? wcslen( pwszVPath ) : 0;
  228. if ( 0 == _ccVirtual && 0 == ccVirtual )
  229. return TRUE;
  230. else if ( ccVirtual != _ccVirtual )
  231. return FALSE;
  232. return RtlEqualMemory( pwszVPath, _pwszVirtualRoot, ccVirtual * sizeof(WCHAR) );
  233. }
  234. BOOL IsSamePhysicalPath( WCHAR const * pwszPath ) const
  235. {
  236. ULONG cc = pwszPath ? wcslen( pwszPath ) : 0;
  237. if ( cc != _cc )
  238. return FALSE;
  239. Win4Assert( 0 != _cc );
  240. return RtlEqualMemory( pwszPath, _pwszDirName, cc * sizeof(WCHAR) );
  241. }
  242. ~CPhyDirLogonInfo();
  243. CLogonInfo * GetLogonInfo()
  244. {
  245. return _pLogonInfo;
  246. }
  247. private:
  248. WCHAR const * GetDirName() const { return _pwszDirName; }
  249. ULONG GetNameLen() const { return _cc; }
  250. void AddRef() { _cRef++; }
  251. void Release()
  252. {
  253. Win4Assert( _cRef > 0 );
  254. _cRef--;
  255. }
  256. void Zombify() { _fIsZombie = TRUE; }
  257. CImpersonationTokenCache & _cache; // token cache
  258. WCHAR * _pwszDirName; // Physical directory
  259. ULONG _cc; // Length of the physical dir
  260. WCHAR * _pwszVirtualRoot; // Virtual root.
  261. ULONG _ccVirtual; // Length of the virtual root
  262. CLogonInfo * _pLogonInfo; // LogonInformation for this share
  263. // The impersonation token to use
  264. BOOL _fIsZombie; // Set to TRUE if this is a zombie
  265. long _cRef; // Refcount
  266. CScopeMatch _phyScope; // For physical scope testing
  267. CScopeMatch _virtualScope; // For virtula scope testing
  268. };
  269. //+---------------------------------------------------------------------------
  270. //
  271. // Member: CPhyDirLogonInfo::IsMatch
  272. //
  273. // Synopsis: Tests if the given path and the vroot are valid
  274. // for access using this logon info.
  275. //
  276. // Arguments: [info] -- object to be compared
  277. //
  278. // Returns: TRUE if the logon info is valid for this vroot.
  279. //
  280. // History: 7-12-96 srikants Created
  281. //
  282. // Notes: It is assumed that the default server entries are at the end
  283. // in the list. For the default server, there will be no check
  284. // done on the ip-address for match.
  285. //
  286. //----------------------------------------------------------------------------
  287. inline
  288. BOOL CPhyDirLogonInfo::IsMatch( CImprsObjInfo const & info ) const
  289. {
  290. return IsInVirtualScope(info.GetVPath() ) &&
  291. IsInScope( info.GetPhysicalPath() );
  292. }
  293. //+---------------------------------------------------------------------------
  294. //
  295. // Member: CPhyDirLogonInfo::IsSame
  296. //
  297. // Synopsis: Tests if the information contained for a path here is exactly
  298. // the same as the given info.
  299. //
  300. // Arguments: [info] -
  301. //
  302. // History: 7-12-96 srikants Created
  303. //
  304. //----------------------------------------------------------------------------
  305. inline
  306. BOOL CPhyDirLogonInfo::IsSame( CImprsObjInfo const & info ) const
  307. {
  308. return IsSameVPath( info.GetVPath() ) &&
  309. IsSamePhysicalPath( info.GetPhysicalPath() );
  310. }
  311. //+---------------------------------------------------------------------------
  312. //
  313. // Member: CPhyDirLogonInfo::Compare
  314. //
  315. // Synopsis: Compares this logon information for precedence calculation with
  316. // the given rhs.
  317. //
  318. // Arguments: [rhs] -
  319. //
  320. // Returns: 0 if they are equal
  321. // -1 if this is < than rhs
  322. // +1 if this is > rhs
  323. //
  324. // History: 7-12-96 srikants Created
  325. //
  326. // Notes: The nodes in the list are ordered by .
  327. //
  328. // Increasing order of ip addresses,
  329. // Decreasing order of vpath lengths,
  330. // Decreasing order of phy.path lengths
  331. //
  332. // This causes the default ip address nodes to be at the end
  333. // of the list.
  334. //
  335. //----------------------------------------------------------------------------
  336. inline
  337. int CPhyDirLogonInfo::Compare( CPhyDirLogonInfo const & rhs ) const
  338. {
  339. if ( _ccVirtual == rhs._ccVirtual )
  340. {
  341. if ( _cc == rhs._cc )
  342. {
  343. return 0;
  344. }
  345. else
  346. {
  347. return _cc < rhs._cc ? -1 : 1;
  348. }
  349. }
  350. else
  351. {
  352. return _ccVirtual < rhs._ccVirtual ? -1 : 1;
  353. }
  354. }
  355. typedef class TDoubleList<CPhyDirLogonInfo> CPhyDirLogonList;
  356. typedef class TFwdListIter<CPhyDirLogonInfo, CPhyDirLogonList> CFwdPhyDirLogonIter;
  357. //+---------------------------------------------------------------------------
  358. //
  359. // Class: CImpersonationTokenCache
  360. //
  361. // Purpose: A cache of impersonation tokens for use in accessing remote
  362. // shares.
  363. //
  364. // History: 4-01-96 srikants Created
  365. //
  366. // Notes:
  367. //
  368. //----------------------------------------------------------------------------
  369. typedef struct _INET_INFO_VIRTUAL_ROOT_LIST INET_INFO_VIRTUAL_ROOT_LIST;
  370. typedef struct _INET_INFO_VIRTUAL_ROOT_ENTRY INET_INFO_VIRTUAL_ROOT_ENTRY;
  371. class CIISVirtualDirectories;
  372. class CImpersonationTokenCache
  373. {
  374. friend class CRegistryScopesCallBackImp;
  375. friend class CIISCallBackImp;
  376. enum { CI_MAX_DRIVES = 26 };
  377. enum EDriveType { eUnknown, eLocal, eRemote };
  378. public:
  379. CImpersonationTokenCache( WCHAR const * pwcCatName );
  380. ~CImpersonationTokenCache();
  381. CPhyDirLogonInfo * Find( CImprsObjInfo & info, ULONG cSkip );
  382. CPhyDirLogonInfo * Find( WCHAR const * pwszPath, ULONG cc );
  383. void Release( CPhyDirLogonInfo * pInfo )
  384. {
  385. CLock lock(_mutex);
  386. pInfo->Release();
  387. if ( pInfo->IsZombie() && !pInfo->IsInUse() )
  388. {
  389. Win4Assert( pInfo->IsSingle() );
  390. delete pInfo;
  391. }
  392. }
  393. void Release( CLogonInfo * pInfo )
  394. {
  395. CLock lock(_mutex);
  396. pInfo->Release();
  397. if ( pInfo->IsZombie() && !pInfo->IsInUse() )
  398. {
  399. Win4Assert( pInfo->IsSingle() );
  400. delete pInfo;
  401. }
  402. }
  403. BOOL IsNetworkDrive( WCHAR const * pwszPath );
  404. BOOL IsIndexingW3Roots() const { return _fIndexW3Roots; }
  405. BOOL IsIndexingNNTPRoots() const { return _fIndexNNTPRoots; }
  406. BOOL IsIndexingIMAPRoots() const { return _fIndexIMAPRoots; }
  407. ULONG GetW3Instance() const { return _W3SvcInstance; }
  408. ULONG GetNNTPInstance() const { return _NNTPSvcInstance; }
  409. ULONG GetIMAPInstance() const { return _IMAPSvcInstance; }
  410. BOOL AreRemoteSharesPresent() const { return _fRemoteSharesPresent; }
  411. void Initialize( WCHAR const * pwszComponent,
  412. BOOL fIndexW3Roots,
  413. BOOL fIndexNNTPRoots,
  414. BOOL fIndexIMAPRoots,
  415. ULONG W3SvcInstance,
  416. ULONG NNTPSvcInstance,
  417. ULONG IMAPSvcInstance );
  418. void ReInitializeIISScopes();
  419. void ReInitializeIISScopes( CIISVirtualDirectories * pW3Dirs,
  420. CIISVirtualDirectories * pNNTPDirs,
  421. CIISVirtualDirectories * pIMAPDirs );
  422. void ReInitializeScopes();
  423. WCHAR const * GetCatalog() { return _awcCatalogName; }
  424. private:
  425. CPhyDirLogonInfo * _FindExact( CImprsObjInfo const & info );
  426. CLogonInfo * _LokFindLogonEntry( WCHAR const * pwszUser,
  427. WCHAR const * pwszDomain );
  428. DWORD _LokValidateOrAddLogonEntry( WCHAR const * pwszUser,
  429. WCHAR const * pwszDomain,
  430. WCHAR const * pwszPassword );
  431. void _LokAddLogonEntry( WCHAR const * pwszUser, WCHAR const * pwszDomain,
  432. WCHAR const * pwszPassword );
  433. void _LokValidateOrAddDirEntry( CImprsObjInfo const & info,
  434. WCHAR const * pwszAccount );
  435. void _LokAddDirEntry( CImprsObjInfo const & info,
  436. WCHAR const * pwszAccountName );
  437. void _LokSyncUp( INET_INFO_VIRTUAL_ROOT_ENTRY * aEntries,
  438. ULONG cEntries );
  439. unsigned _GetDriveIndex( WCHAR wcDriveLetter )
  440. {
  441. return towlower(wcDriveLetter) - L'a';
  442. }
  443. void _WriteLogonFailure( WCHAR const * pwszUser, DWORD dwError );
  444. BOOL _fIndexW3Roots; // Set to TRUE if indexing w3svc roots
  445. BOOL _fIndexNNTPRoots; // Set to TRUE if NNTP is enabled
  446. BOOL _fIndexIMAPRoots; // Set to TRUE if IMAP is enabled
  447. ULONG _W3SvcInstance; // server instance #
  448. ULONG _NNTPSvcInstance; // server instance #
  449. ULONG _IMAPSvcInstance; // server instance #
  450. BOOL _fRemoteSharesPresent;
  451. // Optimization - don't do any
  452. // checks if there are no remote
  453. // shares.
  454. WCHAR * _pwszComponentName; // Name of the component for event log
  455. // messages
  456. CMutexSem _mutex; // Serialization Mutex
  457. EDriveType _aDriveInfo[CI_MAX_DRIVES];
  458. // Array of information on drive
  459. // letters.
  460. CPhyDirLogonList _phyDirList; // list of remote directories
  461. WCHAR _awcCatalogName[MAX_PATH]; // name of the catalog
  462. };
  463. extern CLogonInfoList g_LogonList; // List of logon information
  464. #define CI_DAEMON_NAME L"CiDaemon"
  465. #define CI_ACTIVEX_NAME L"Indexing Service"
  466. //+---------------------------------------------------------------------------
  467. //
  468. // Class: CImpersonateRemoteAccess
  469. //
  470. // Purpose: An unwindable object to impersonate for access to remote
  471. // shares.
  472. //
  473. // History: 4-01-96 srikants Created
  474. //
  475. // Notes:
  476. //
  477. //----------------------------------------------------------------------------
  478. class CImpersonateRemoteAccess
  479. {
  480. public:
  481. CImpersonateRemoteAccess( CImpersonationTokenCache * pCache );
  482. ~CImpersonateRemoteAccess()
  483. {
  484. Release();
  485. }
  486. void SetTokenCache( CImpersonationTokenCache * pCache )
  487. {
  488. _pCache = pCache;
  489. }
  490. static BOOL IsNetPath( WCHAR const * pwszPath )
  491. {
  492. //
  493. // WWW server and CI don't allow remote drive letters.
  494. // This allows us to do the check significantly cheaper.
  495. //
  496. return L'\\' == pwszPath[0] &&
  497. L'\\' == pwszPath[1] &&
  498. L'.' != pwszPath[2];
  499. }
  500. BOOL ImpersonateIfNoThrow( WCHAR const * pwszPath,
  501. WCHAR const * pwszVirtualPath )
  502. {
  503. Win4Assert( 0 != pwszPath );
  504. if ( IsNetPath( pwszPath ) )
  505. {
  506. if ( !_ImpersonateIf( pwszPath, pwszVirtualPath ) )
  507. return FALSE;
  508. }
  509. else if ( IsImpersonated() )
  510. {
  511. //
  512. // This thread was impersonated for some network access. Revert back to
  513. // what it was before impersonation.
  514. //
  515. Release();
  516. }
  517. return TRUE;
  518. }
  519. void ImpersonateIf( WCHAR const * pwszPath,
  520. WCHAR const * pwszVirtualPath )
  521. {
  522. if ( !ImpersonateIfNoThrow( pwszPath, pwszVirtualPath ) )
  523. {
  524. THROW( CException(STATUS_LOGON_FAILURE) );
  525. }
  526. }
  527. BOOL ImpersonateIf( WCHAR const * pwszPath,
  528. ULONG cSkip,
  529. BOOL fDummy
  530. )
  531. {
  532. Win4Assert( 0 != pwszPath );
  533. if ( IsNetPath( pwszPath ) )
  534. {
  535. return _ImpersonateIf( pwszPath, 0, cSkip );
  536. }
  537. else if ( IsImpersonated() )
  538. {
  539. //
  540. // This thread was impersonated for some network access. Revert back to
  541. // what it was before impersonation.
  542. //
  543. Release();
  544. }
  545. return TRUE;
  546. }
  547. void Release();
  548. BOOL IsImpersonated() const { return _fMustRevert; }
  549. BOOL IsTokenFound() const { return 0 != _pTokenInfo; }
  550. private:
  551. BOOL _ImpersonateIf( WCHAR const * pwszPath,
  552. WCHAR const * pwszVirtualPath,
  553. ULONG cSkip = 0 );
  554. CImpersonationTokenCache * _pCache;
  555. CPhyDirLogonInfo * _pTokenInfo; // Impersonation information
  556. HANDLE _hTokenPrev; // If valid, the token of the
  557. // thread before impersonation
  558. BOOL _fMustRevert; // Set to TRUE if we have to
  559. // revert to previous state
  560. };
  561. //+---------------------------------------------------------------------------
  562. //
  563. // Class: PImpersonatedWorkItem
  564. //
  565. // Purpose: Abstract base class that allows the caller to impersonate
  566. // until success or no more options.
  567. //
  568. // History: 7-15-96 srikants Created
  569. //
  570. // Notes: This class defines the framework by which threads that need
  571. // maximum impersonation level allowed by the user to do a
  572. // particular work. For example, if /vroot1 and /vroot2 point to
  573. // the same physical remote root, but have different user-id and
  574. // levels of permission, we have to use whatever id allows the
  575. // required level of access.
  576. //
  577. //----------------------------------------------------------------------------
  578. class PImpersonatedWorkItem
  579. {
  580. public:
  581. PImpersonatedWorkItem( WCHAR const * pwszPath )
  582. : _pwszPath(pwszPath),
  583. _fDontUseDefault(FALSE)
  584. {
  585. _fNetPath = CImpersonateRemoteAccess::IsNetPath( _pwszPath );
  586. }
  587. virtual BOOL DoIt() = 0;
  588. static BOOL IsRetryableError( NTSTATUS status )
  589. {
  590. return STATUS_ACCESS_DENIED == status ||
  591. ERROR_ACCESS_DENIED == status ||
  592. FILTER_E_ACCESS == status ||
  593. HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == status;
  594. }
  595. protected:
  596. void ImpersonateAndDoWork( CImpersonateRemoteAccess & remoteAccess );
  597. WCHAR const * const _pwszPath; // Phy. Path to impersonate for
  598. BOOL _fNetPath; // Set to TRUE if this is a network path
  599. private:
  600. BOOL _fDontUseDefault; // Set to TRUE if default vroot must not
  601. // be used for impersonation
  602. };
  603. //+---------------------------------------------------------------------------
  604. //
  605. // Class: CImpersonatedGetAttr
  606. //
  607. // Purpose: A class that is capable of repeatedly trying to do
  608. // GetAttributesEx() until there is a success or there are no
  609. // more impersonation contexts to try.
  610. //
  611. // History: 7-18-96 srikants Created
  612. //
  613. //----------------------------------------------------------------------------
  614. class CImpersonatedGetAttr: public PImpersonatedWorkItem
  615. {
  616. public:
  617. CImpersonatedGetAttr( const CFunnyPath & funnyPath ) :
  618. PImpersonatedWorkItem( funnyPath.GetActualPath() ),
  619. _funnyPath( funnyPath )
  620. {
  621. }
  622. // THROWS if it cannot get attributes in any context
  623. void DoWork( CImpersonateRemoteAccess & remoteAccess )
  624. {
  625. ImpersonateAndDoWork( remoteAccess );
  626. }
  627. BOOL DoIt(); // virtual
  628. WIN32_FIND_DATA const & GetAttrEx() const { return _ffData; }
  629. private:
  630. WIN32_FIND_DATA _ffData;
  631. const CFunnyPath & _funnyPath;
  632. };
  633. //+---------------------------------------------------------------------------
  634. //
  635. // Class: CImpersonatedGetFileAttr
  636. //
  637. // Purpose: A class that is capable of repeatedly trying to do
  638. // GetAttributesEx() until there is a success or there are no
  639. // more impersonation contexts to try.
  640. //
  641. // History: 7-18-96 srikants Created
  642. //
  643. //----------------------------------------------------------------------------
  644. class CImpersonatedGetFileAttr: public PImpersonatedWorkItem
  645. {
  646. public:
  647. CImpersonatedGetFileAttr( const CFunnyPath & funnyPath ) :
  648. PImpersonatedWorkItem( funnyPath.GetActualPath() ),
  649. _ulAttr( INVALID_FILE_ATTRIBUTES ),
  650. _funnyPath( funnyPath )
  651. {
  652. }
  653. // THROWS if it cannot get attributes in any context
  654. void DoWork( CImpersonateRemoteAccess & remoteAccess )
  655. {
  656. ImpersonateAndDoWork( remoteAccess );
  657. }
  658. BOOL DoIt(); // virtual
  659. ULONG GetAttr() const { return _ulAttr; }
  660. private:
  661. ULONG _ulAttr;
  662. const CFunnyPath & _funnyPath;
  663. };
  664. //
  665. // This function throws if the caller doesn't have admin priv
  666. //
  667. void VerifyThreadHasAdminPrivilege( void );