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.

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