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.

442 lines
9.0 KiB

  1. #ifndef _TOKENCACHE_HXX_
  2. #define _TOKENCACHE_HXX_
  3. #include <wincrypt.h>
  4. #include <winsock2.h>
  5. #include <ws2tcpip.h>
  6. #include "usercache.hxx"
  7. #include "stringa.hxx"
  8. //
  9. // Special logon types to indicate local system and passport
  10. //
  11. #define IIS_LOGON_METHOD_LOCAL_SYSTEM (-2)
  12. #define IIS_LOGON_METHOD_PASSPORT (-3)
  13. #define DEFAULT_MD5_HASH_SIZE 16
  14. class TOKEN_CACHE_KEY : public CACHE_KEY
  15. {
  16. public:
  17. TOKEN_CACHE_KEY()
  18. : m_strHashKey( m_achHashKey, sizeof( m_achHashKey ) )
  19. {
  20. }
  21. BOOL
  22. QueryIsEqual(
  23. const CACHE_KEY * pCompareKey
  24. ) const
  25. {
  26. TOKEN_CACHE_KEY * pTokenKey = (TOKEN_CACHE_KEY*) pCompareKey;
  27. DBG_ASSERT( pTokenKey != NULL );
  28. //
  29. // If lengths are not equal, this is easy
  30. //
  31. if ( m_strHashKey.QueryCB() != pTokenKey->m_strHashKey.QueryCB() )
  32. {
  33. return FALSE;
  34. }
  35. //
  36. // Do memcmp
  37. //
  38. return memcmp( m_strHashKey.QueryStr(),
  39. pTokenKey->m_strHashKey.QueryStr(),
  40. m_strHashKey.QueryCB() ) == 0;
  41. }
  42. DWORD
  43. QueryKeyHash(
  44. VOID
  45. ) const
  46. {
  47. return HashString( m_strHashKey.QueryStr() );
  48. }
  49. HRESULT
  50. SetKey(
  51. TOKEN_CACHE_KEY * pCacheKey
  52. )
  53. {
  54. return m_strHashKey.Copy( pCacheKey->m_strHashKey.QueryStr() );
  55. }
  56. HRESULT
  57. CreateCacheKey(
  58. WCHAR * pszUserName,
  59. WCHAR * pszDomainName,
  60. DWORD dwLogonMethod
  61. );
  62. private:
  63. WCHAR m_achHashKey[ 64 ];
  64. STRU m_strHashKey;
  65. };
  66. //
  67. // The check period for how long a token can be in the cache.
  68. // Tokens can be in the cache for up to two times this value
  69. // (in seconds)
  70. //
  71. #define DEFAULT_CACHED_TOKEN_TTL ( 15 * 60 )
  72. #define SID_DEFAULT_SIZE 64
  73. #define TOKEN_CACHE_ENTRY_SIGNATURE 'TC3W'
  74. #define TOKEN_CACHE_ENTRY_FREE_SIGNATURE 'fC3W'
  75. class TOKEN_CACHE_ENTRY : public CACHE_ENTRY
  76. {
  77. public:
  78. TOKEN_CACHE_ENTRY( OBJECT_CACHE * pObjectCache )
  79. : CACHE_ENTRY( pObjectCache ),
  80. m_strMD5Password( m_achMD5Password, sizeof( m_achMD5Password ) ),
  81. m_lOOPToken( 0 ),
  82. m_lDisBackupPriToken( 0 ),
  83. m_hImpersonationToken( NULL ),
  84. m_hPrimaryToken( NULL ),
  85. m_pSid( NULL )
  86. {
  87. m_liPwdExpiry.HighPart = 0x7fffffff;
  88. m_liPwdExpiry.LowPart = 0xffffffff;
  89. m_dwSignature = TOKEN_CACHE_ENTRY_SIGNATURE;
  90. }
  91. virtual ~TOKEN_CACHE_ENTRY()
  92. {
  93. DBG_ASSERT( CheckSignature() );
  94. m_dwSignature = TOKEN_CACHE_ENTRY_FREE_SIGNATURE;
  95. if ( m_hImpersonationToken != NULL )
  96. {
  97. CloseHandle( m_hImpersonationToken );
  98. m_hImpersonationToken = NULL;
  99. }
  100. if ( m_hPrimaryToken != NULL )
  101. {
  102. CloseHandle( m_hPrimaryToken );
  103. m_hPrimaryToken = NULL;
  104. }
  105. }
  106. CACHE_KEY *
  107. QueryCacheKey(
  108. VOID
  109. ) const
  110. {
  111. return (CACHE_KEY*) &m_cacheKey;
  112. }
  113. HRESULT
  114. SetCacheKey(
  115. TOKEN_CACHE_KEY * pCacheKey
  116. )
  117. {
  118. return m_cacheKey.SetKey( pCacheKey );
  119. }
  120. BOOL
  121. CheckSignature(
  122. VOID
  123. ) const
  124. {
  125. return m_dwSignature == TOKEN_CACHE_ENTRY_SIGNATURE;
  126. }
  127. VOID *
  128. operator new(
  129. #if DBG
  130. size_t size
  131. #else
  132. size_t
  133. #endif
  134. )
  135. {
  136. DBG_ASSERT( size == sizeof( TOKEN_CACHE_ENTRY ) );
  137. DBG_ASSERT( sm_pachTokenCacheEntry != NULL );
  138. return sm_pachTokenCacheEntry->Alloc();
  139. }
  140. VOID
  141. operator delete(
  142. VOID * pTokenCacheEntry
  143. )
  144. {
  145. DBG_ASSERT( pTokenCacheEntry != NULL );
  146. DBG_ASSERT( sm_pachTokenCacheEntry != NULL );
  147. DBG_REQUIRE( sm_pachTokenCacheEntry->Free( pTokenCacheEntry ) );
  148. }
  149. HANDLE
  150. QueryImpersonationToken(
  151. VOID
  152. );
  153. HANDLE
  154. QueryPrimaryToken(
  155. VOID
  156. );
  157. PSID
  158. QuerySid(
  159. VOID
  160. );
  161. LARGE_INTEGER *
  162. QueryExpiry(
  163. VOID
  164. )
  165. {
  166. return &m_liPwdExpiry;
  167. }
  168. LONG
  169. QueryOOPToken(
  170. VOID
  171. )
  172. {
  173. if( m_lOOPToken )
  174. {
  175. return m_lOOPToken;
  176. }
  177. return InterlockedExchange( &m_lOOPToken, 1 );
  178. }
  179. LONG
  180. QueryDisBackupPriToken(
  181. VOID
  182. )
  183. {
  184. if( m_lDisBackupPriToken )
  185. {
  186. return m_lDisBackupPriToken;
  187. }
  188. return InterlockedExchange( &m_lDisBackupPriToken, 1 );
  189. }
  190. HRESULT
  191. GenMD5Password(
  192. IN WCHAR * pszPassword,
  193. OUT STRA * pstrMD5Password
  194. );
  195. HRESULT
  196. EqualMD5Password(
  197. IN WCHAR * pszPassword,
  198. OUT BOOL * fEqual
  199. );
  200. HRESULT
  201. Create(
  202. IN HANDLE hToken,
  203. IN WCHAR * pszPassword,
  204. IN LARGE_INTEGER * pliPwdExpiry,
  205. IN BOOL fImpersonation
  206. );
  207. static
  208. HRESULT
  209. Initialize(
  210. VOID
  211. );
  212. static
  213. VOID
  214. Terminate(
  215. VOID
  216. );
  217. private:
  218. TOKEN_CACHE_ENTRY(const TOKEN_CACHE_ENTRY &);
  219. void operator=(const TOKEN_CACHE_ENTRY &);
  220. DWORD m_dwSignature;
  221. //
  222. // Cache key
  223. //
  224. TOKEN_CACHE_KEY m_cacheKey;
  225. //
  226. // Hashed password. The hashed binary data will be converted to
  227. // ASCII hex representation, so the size would be twice as big
  228. // as the original one
  229. //
  230. CHAR m_achMD5Password[ 2 * DEFAULT_MD5_HASH_SIZE + 1 ];
  231. STRA m_strMD5Password;
  232. //
  233. // The actual tokens
  234. //
  235. HANDLE m_hImpersonationToken;
  236. HANDLE m_hPrimaryToken;
  237. //
  238. // Have we modified the token for OOP isapi
  239. //
  240. LONG m_lOOPToken;
  241. //
  242. // Have we disabled the backup privilege for the token
  243. //
  244. LONG m_lDisBackupPriToken;
  245. //
  246. // Time to expire for the token
  247. //
  248. LARGE_INTEGER m_liPwdExpiry;
  249. //
  250. // Keep the sid for file cache purposes
  251. //
  252. PSID m_pSid;
  253. BYTE m_abSid[ SID_DEFAULT_SIZE ];
  254. //
  255. // Allocation cache for TOKEN_CACHE_ENTRY's
  256. //
  257. static ALLOC_CACHE_HANDLER * sm_pachTokenCacheEntry;
  258. //
  259. // Handle of a cryptographic service provider
  260. //
  261. static HCRYPTPROV sm_hCryptProv;
  262. };
  263. class TOKEN_CACHE : public OBJECT_CACHE
  264. {
  265. public:
  266. TOKEN_CACHE()
  267. : m_dwLastPriorityUPNLogon ( 0 ),
  268. m_hKey ( NULL ),
  269. m_hEvent ( NULL ),
  270. m_hWaitObject ( NULL ),
  271. m_fInitializedThreadPool ( FALSE )
  272. {}
  273. ~TOKEN_CACHE()
  274. {}
  275. HRESULT
  276. GetCachedToken(
  277. IN LPWSTR pszUserName,
  278. IN LPWSTR pszDomain,
  279. IN LPWSTR pszPassword,
  280. IN DWORD dwLogonMethod,
  281. IN BOOL fUseSubAuth,
  282. IN BOOL fPossibleUPNLogon,
  283. IN PSOCKADDR pSockAddr,
  284. OUT TOKEN_CACHE_ENTRY ** ppCachedToken,
  285. OUT DWORD * pdwLogonError
  286. );
  287. WCHAR *
  288. QueryName(
  289. VOID
  290. ) const
  291. {
  292. return L"TOKEN_CACHE";
  293. }
  294. HKEY
  295. QueryRegKey(
  296. VOID
  297. ) const
  298. {
  299. return m_hKey;
  300. }
  301. HANDLE
  302. QueryEventHandle(
  303. VOID
  304. ) const
  305. {
  306. return m_hEvent;
  307. }
  308. HRESULT
  309. Initialize(
  310. VOID
  311. );
  312. VOID
  313. Terminate(
  314. VOID
  315. );
  316. static
  317. VOID
  318. WINAPI
  319. FlushTokenCacheWaitCallback(
  320. PVOID pParam,
  321. BOOL fWaitFired
  322. );
  323. private:
  324. TOKEN_CACHE(const TOKEN_CACHE &);
  325. void operator=(const TOKEN_CACHE &);
  326. DWORD m_dwLastPriorityUPNLogon;
  327. //
  328. // Handle to the "UserTokenTTL" registry key
  329. //
  330. HKEY m_hKey;
  331. //
  332. // Handle to the event waiting for the notification
  333. //
  334. HANDLE m_hEvent;
  335. //
  336. // Wait handle
  337. //
  338. HANDLE m_hWaitObject;
  339. //
  340. // Has the threadpool been successfully initialized
  341. //
  342. BOOL m_fInitializedThreadPool;
  343. };
  344. HRESULT
  345. ToHex(
  346. IN BUFFER & buffSrc,
  347. OUT STRA & strDst
  348. );
  349. #endif