caching.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "caching.hpp"
  14. #include "jtime.hpp"
  15. //define a container for multiple instances of a security manager cache
  16. typedef map<string, CPermissionsCache*> MapCache;
  17. static CriticalSection mapCacheCS;//guards modifications to the cache map
  18. static MapCache g_mapCache;
  19. /**********************************************************
  20. * CResPermissionsCache *
  21. * (used by CPermissionsCache defined below) *
  22. **********************************************************/
  23. time_t getThreadCreateTime()
  24. {
  25. time_t t;
  26. void* tslval = getThreadLocalVal();
  27. if(tslval == NULL)
  28. return 0;
  29. memcpy(&t, tslval, sizeof(t));
  30. return t;
  31. }
  32. CResPermissionsCache::~CResPermissionsCache()
  33. {
  34. MapResAccess::const_iterator i;
  35. MapResAccess::const_iterator iEnd = m_resAccessMap.end();
  36. for (i = m_resAccessMap.begin(); i != iEnd; i++)
  37. {
  38. ISecResource* ptr = ((*i).second).second;
  39. if(ptr)
  40. {
  41. ptr->Release();
  42. }
  43. }
  44. }
  45. //called from within a ReadLockBlock
  46. int CResPermissionsCache::lookup( IArrayOf<ISecResource>& resources, bool* pFound )
  47. {
  48. time_t tstamp;
  49. time(&tstamp);
  50. int nresources = resources.ordinality();
  51. int nFound = 0;
  52. for (int i = 0; i < nresources; i++)
  53. {
  54. ISecResource& secResource = resources.item(i);
  55. const char* resource = secResource.getName();
  56. if(resource == NULL)
  57. {
  58. *pFound++ = false;
  59. continue;
  60. }
  61. #ifdef _DEBUG
  62. DBGLOG("CACHE: CResPermissionsCache Looking up resource(%d of %d) %s:%s", i, nresources, m_user.c_str(), resource);
  63. #endif
  64. MapResAccess::iterator it = m_resAccessMap.find(SecCacheKeyEntry(resource, secResource.getResourceType()));
  65. if (it != m_resAccessMap.end())//exists in cache
  66. {
  67. ResPermCacheEntry& resParamCacheEntry = (*it).second;
  68. const time_t timestamp = resParamCacheEntry.first;
  69. if (timestamp < tstamp)//entry was not stale during last cleanup but is stale now
  70. *pFound++ = false;
  71. else if(!m_pParentCache->isCacheEnabled() && m_pParentCache->isTransactionalEnabled())//m_pParentCache->getOriginalTimeout() == 0)
  72. {
  73. time_t tctime = getThreadCreateTime();
  74. if(tctime <= 0 || timestamp < tctime)
  75. {
  76. *pFound++ = false;
  77. }
  78. else
  79. {
  80. secResource.copy(resParamCacheEntry.second);
  81. #ifdef _DEBUG
  82. DBGLOG("CACHE: CResPermissionsCache FoundA %s:%s=>%d", m_user.c_str(), resource, ((ISecResource*)resParamCacheEntry.second)->getAccessFlags());
  83. #endif
  84. *pFound++ = true;
  85. nFound++;
  86. }
  87. }
  88. else
  89. {
  90. secResource.copy(resParamCacheEntry.second);
  91. #ifdef _DEBUG
  92. DBGLOG("CACHE: CResPermissionsCache FoundB %s:%s=>%d", m_user.c_str(), resource, ((ISecResource*)resParamCacheEntry.second)->getAccessFlags());
  93. #endif
  94. *pFound++ = true;
  95. nFound++;
  96. }
  97. }
  98. else
  99. *pFound++ = false;
  100. }
  101. return nFound;
  102. }
  103. //called from within a WriteLockBlock
  104. void CResPermissionsCache::add( IArrayOf<ISecResource>& resources )
  105. {
  106. time_t tstamp;
  107. time(&tstamp);
  108. int nresources = resources.ordinality();
  109. for (int i = 0; i < nresources; i++)
  110. {
  111. ISecResource* secResource = &resources.item(i);
  112. if(!secResource)
  113. continue;
  114. const char* resource = secResource->getName();
  115. SecResourceType resourcetype = secResource->getResourceType();
  116. if(resource == NULL)
  117. continue;
  118. int permissions = secResource->getAccessFlags();
  119. if(permissions == SecAccess_Unavailable)
  120. continue;
  121. MapResAccess::iterator it = m_resAccessMap.find(SecCacheKeyEntry(resource, resourcetype));
  122. if (it != m_resAccessMap.end())//already exists so overwrite it but first remove existing timestamp info
  123. {
  124. ResPermCacheEntry& resParamCacheEntry = (*it).second;
  125. time_t oldtstamp = resParamCacheEntry.first;
  126. //there may be multiple resources associated with the same timestamp
  127. //in the multimap so find this entry
  128. //
  129. MapTimeStamp::iterator itL = m_timestampMap.lower_bound( oldtstamp );
  130. MapTimeStamp::iterator itU = m_timestampMap.upper_bound( oldtstamp );
  131. MapTimeStamp::iterator its;
  132. for ( its = itL; its != itU; its++)
  133. {
  134. SecCacheKeyEntry& cachekey = (*its).second;
  135. if (cachekey.first == resource && cachekey.second == resourcetype)
  136. {
  137. m_timestampMap.erase(its);
  138. break;
  139. }
  140. }
  141. m_resAccessMap.erase(SecCacheKeyEntry(resource, resourcetype));
  142. }
  143. #ifdef _DEBUG
  144. DBGLOG("CACHE: CResPermissionsCache Adding %s:%s(%d)", m_user.c_str(), resource, permissions);
  145. #endif
  146. m_resAccessMap.insert( pair<SecCacheKeyEntry, ResPermCacheEntry>(SecCacheKeyEntry(resource, resourcetype), ResPermCacheEntry(tstamp, secResource->clone())));
  147. m_timestampMap.insert( pair<time_t, SecCacheKeyEntry>(tstamp, SecCacheKeyEntry(resource, resourcetype)));
  148. }
  149. }
  150. //called from within a WriteLockBlock
  151. void CResPermissionsCache::removeStaleEntries(time_t tstamp)
  152. {
  153. if (needsCleanup(tstamp, m_pParentCache->getCacheTimeout()))
  154. {
  155. MapTimeStamp::iterator i;
  156. MapTimeStamp::iterator itL = m_timestampMap.lower_bound(tstamp);
  157. MapTimeStamp::iterator iBegin = m_timestampMap.begin();
  158. for (i = iBegin; i != itL; i++)
  159. {
  160. SecCacheKeyEntry& cachekey = (*i).second;
  161. MapResAccess::iterator it = m_resAccessMap.find(cachekey);
  162. if (it != m_resAccessMap.end())//exists in cache
  163. {
  164. ResPermCacheEntry& entry = (*it).second;
  165. if(entry.second)
  166. entry.second->Release();
  167. }
  168. m_resAccessMap.erase(cachekey);
  169. }
  170. m_timestampMap.erase(iBegin, itL);
  171. m_tLastCleanup = tstamp;
  172. }
  173. }
  174. //called from within a WriteLockBlock
  175. void CResPermissionsCache::remove(SecResourceType rtype, const char* resourcename)
  176. {
  177. SecCacheKeyEntry key(resourcename, rtype);
  178. MapResAccess::iterator it = m_resAccessMap.find(key);
  179. if (it != m_resAccessMap.end())//exists in cache
  180. {
  181. ResPermCacheEntry& entry = (*it).second;
  182. if(entry.second)
  183. entry.second->Release();
  184. }
  185. m_resAccessMap.erase(key);
  186. }
  187. /**********************************************************
  188. * CPermissionsCache *
  189. **********************************************************/
  190. CPermissionsCache::~CPermissionsCache()
  191. {
  192. if (!m_secMgrClass.isEmpty())
  193. {
  194. CriticalBlock block(mapCacheCS);
  195. g_mapCache.erase(m_secMgrClass.str());
  196. }
  197. flush();
  198. }
  199. int CPermissionsCache::lookup( ISecUser& sec_user, IArrayOf<ISecResource>& resources, bool* pFound)
  200. {
  201. time_t tstamp;
  202. time(&tstamp);
  203. const char* userId = sec_user.getName();
  204. //First check if matching cache entry is stale
  205. bool needsCleanup = false;
  206. {
  207. ReadLockBlock readLock(m_resPermCacheRWLock);
  208. MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( userId );
  209. if (i != m_resPermissionsMap.end())
  210. {
  211. CResPermissionsCache* pResPermissionsCache = (*i).second;
  212. needsCleanup = pResPermissionsCache->needsCleanup(tstamp, getCacheTimeout());
  213. }
  214. }
  215. //clear stale cache entries for this CResPermissionsCache entry
  216. if (needsCleanup)
  217. {
  218. WriteLockBlock writeLock(m_resPermCacheRWLock);
  219. MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( userId );
  220. if (i != m_resPermissionsMap.end())//Entry could have been deleted by another thread
  221. {
  222. CResPermissionsCache* pResPermissionsCache = (*i).second;
  223. pResPermissionsCache->removeStaleEntries(tstamp);
  224. }
  225. }
  226. //Lookup all user/resources
  227. int nFound;
  228. ReadLockBlock readLock(m_resPermCacheRWLock);
  229. MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( userId );
  230. if (i != m_resPermissionsMap.end())
  231. {
  232. CResPermissionsCache* pResPermissionsCache = (*i).second;
  233. nFound = pResPermissionsCache->lookup( resources, pFound );
  234. }
  235. else
  236. {
  237. nFound = 0;
  238. memset(pFound, 0, sizeof(bool)*resources.ordinality());
  239. }
  240. #ifdef _DEBUG
  241. DBGLOG("CACHE: CPermissionsCache Looked up resources for %s:*, found %d of %d matches", userId, nFound, resources.ordinality());
  242. #endif
  243. return nFound;
  244. }
  245. void CPermissionsCache::add( ISecUser& sec_user, IArrayOf<ISecResource>& resources )
  246. {
  247. const char* user = sec_user.getName();
  248. WriteLockBlock writeLock(m_resPermCacheRWLock);
  249. MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( user );
  250. CResPermissionsCache* pResPermissionsCache;
  251. if (i == m_resPermissionsMap.end())
  252. {
  253. #ifdef _DEBUG
  254. DBGLOG("CACHE: CPermissionsCache Adding resources to cache for new user %s", user);
  255. #endif
  256. pResPermissionsCache = new CResPermissionsCache(this, user);
  257. m_resPermissionsMap.insert(pair<string, CResPermissionsCache*>(user, pResPermissionsCache));
  258. }
  259. else
  260. {
  261. #ifdef _DEBUG
  262. DBGLOG("CACHE: CPermissionsCache Adding resources to cache for existing user %s", user);
  263. #endif
  264. pResPermissionsCache = (*i).second;
  265. }
  266. pResPermissionsCache->add( resources );
  267. }
  268. void CPermissionsCache::removePermissions( ISecUser& sec_user)
  269. {
  270. const char* user = sec_user.getName();
  271. if(user != NULL && *user != '\0')
  272. {
  273. #ifdef _DEBUG
  274. DBGLOG("CACHE: CPermissionsCache Removing permissions for user %s", user);
  275. #endif
  276. WriteLockBlock writeLock(m_resPermCacheRWLock);
  277. m_resPermissionsMap.erase(user);
  278. }
  279. }
  280. void CPermissionsCache::remove(SecResourceType rtype, const char* resourcename)
  281. {
  282. MapResPermissionsCache::const_iterator i;
  283. WriteLockBlock writeLock(m_resPermCacheRWLock);
  284. MapResPermissionsCache::const_iterator iEnd = m_resPermissionsMap.end();
  285. for (i = m_resPermissionsMap.begin(); i != iEnd; i++)
  286. {
  287. i->second->remove(rtype, resourcename);
  288. }
  289. }
  290. bool CPermissionsCache::lookup(ISecUser& sec_user)
  291. {
  292. if(!isCacheEnabled())
  293. return false;
  294. const char* username = sec_user.getName();
  295. if(!username || !*username)
  296. return false;
  297. bool deleteEntry = false;
  298. {
  299. ReadLockBlock readLock(m_userCacheRWLock );
  300. MapUserCache::iterator it = m_userCache.find(username);
  301. if (it == m_userCache.end())
  302. return false;
  303. CachedUser* user = (CachedUser*)(it->second);
  304. time_t now;
  305. time(&now);
  306. if(user->getTimestamp() < (now - m_cacheTimeout))
  307. {
  308. deleteEntry = true;
  309. }
  310. else
  311. {
  312. const char* cachedpw = user->queryUser()->credentials().getPassword();
  313. const char * pw = sec_user.credentials().getPassword();
  314. if(cachedpw && pw && *pw != '\0')
  315. {
  316. StringBuffer md5pbuf;
  317. md5_string2(pw, md5pbuf);
  318. if(strcmp(cachedpw, md5pbuf.str()) == 0)
  319. {
  320. #ifdef _DEBUG
  321. DBGLOG("CACHE: CPermissionsCache Found validated user %s", username);
  322. #endif
  323. // Copy cached user to the sec_user structure, but still keep the original clear text password.
  324. user->queryUser()->copyTo(sec_user);
  325. sec_user.credentials().setPassword(pw);
  326. return true;
  327. }
  328. else
  329. {
  330. deleteEntry = true;
  331. }
  332. }
  333. }
  334. }
  335. if (deleteEntry)
  336. {
  337. WriteLockBlock writeLock(m_userCacheRWLock);
  338. MapUserCache::iterator it = m_userCache.find(username);
  339. if (it != m_userCache.end())
  340. {
  341. CachedUser* user = (CachedUser*)(it->second);
  342. m_userCache.erase(username);
  343. delete user;
  344. }
  345. }
  346. return false;
  347. }
  348. ISecUser* CPermissionsCache::getCachedUser( ISecUser& sec_user)
  349. {
  350. if(!isCacheEnabled())
  351. return NULL;
  352. const char* username = sec_user.getName();
  353. if(!username || !*username)
  354. return NULL;
  355. ReadLockBlock readLock(m_userCacheRWLock );
  356. MapUserCache::iterator it = m_userCache.find(username);
  357. if (it == m_userCache.end())
  358. return NULL;
  359. CachedUser* user = (CachedUser*)(it->second);
  360. return LINK(user->queryUser());
  361. }
  362. void CPermissionsCache::add(ISecUser& sec_user)
  363. {
  364. if(!isCacheEnabled())
  365. return;
  366. const char* username = sec_user.getName();
  367. if(!username || !*username)
  368. return;
  369. WriteLockBlock writeLock(m_userCacheRWLock );
  370. MapUserCache::iterator it = m_userCache.find(username);
  371. CachedUser* user = NULL;
  372. if (it != m_userCache.end())
  373. {
  374. user = (CachedUser*)(it->second);
  375. m_userCache.erase(username);
  376. delete user;
  377. }
  378. #ifdef _DEBUG
  379. DBGLOG("CACHE: CPermissionsCache Adding cached user %s", username);
  380. #endif
  381. m_userCache[username] = new CachedUser(LINK(&sec_user));
  382. }
  383. void CPermissionsCache::removeFromUserCache(ISecUser& sec_user)
  384. {
  385. const char* username = sec_user.getName();
  386. if(username && *username)
  387. {
  388. WriteLockBlock writeLock(m_userCacheRWLock );
  389. MapUserCache::iterator it = m_userCache.find(username);
  390. if (it != m_userCache.end())
  391. {
  392. CachedUser* user = (CachedUser*)(it->second);
  393. m_userCache.erase(username);
  394. delete user;
  395. #ifdef _DEBUG
  396. DBGLOG("CACHE: CPermissionsCache Removing cached user %s", username);
  397. #endif
  398. }
  399. }
  400. }
  401. bool CPermissionsCache::addManagedFileScopes(IArrayOf<ISecResource>& scopes)
  402. {
  403. WriteLockBlock writeLock(m_scopesRWLock);
  404. ForEachItemIn(x, scopes)
  405. {
  406. ISecResource* scope = &scopes.item(x);
  407. if(!scope)
  408. continue;
  409. const char* cachekey = scope->getName();
  410. if(cachekey == NULL)
  411. continue;
  412. map<string, ISecResource*>::iterator it = m_managedFileScopesMap.find(cachekey);
  413. if (it != m_managedFileScopesMap.end())
  414. {
  415. ISecResource *res = (*it).second;
  416. res->Release();
  417. m_managedFileScopesMap.erase(it);
  418. }
  419. #ifdef _DEBUG
  420. DBGLOG("Caching Managed File Scope %s",cachekey);
  421. #endif
  422. m_managedFileScopesMap.insert( pair<string, ISecResource*>(cachekey, LINK(scope)));
  423. }
  424. return true;
  425. }
  426. inline void CPermissionsCache::removeManagedFileScopes(IArrayOf<ISecResource>& scopes)
  427. {
  428. WriteLockBlock writeLock(m_scopesRWLock);
  429. ForEachItemIn(x, scopes)
  430. {
  431. ISecResource* scope = &scopes.item(x);
  432. if(!scope)
  433. continue;
  434. const char* cachekey = scope->getName();
  435. if(cachekey == NULL)
  436. continue;
  437. map<string, ISecResource*>::iterator it = m_managedFileScopesMap.find(cachekey);
  438. if (it != m_managedFileScopesMap.end())
  439. {
  440. ISecResource *res = (*it).second;
  441. res->Release();
  442. m_managedFileScopesMap.erase(it);
  443. }
  444. }
  445. }
  446. inline void CPermissionsCache::removeAllManagedFileScopes()
  447. {
  448. WriteLockBlock writeLock(m_scopesRWLock);
  449. map<string, ISecResource*>::const_iterator cit;
  450. map<string, ISecResource*>::const_iterator iEnd = m_managedFileScopesMap.end();
  451. for (cit = m_managedFileScopesMap.begin(); cit != iEnd; cit++)
  452. {
  453. ISecResource *res = (*cit).second;
  454. res->Release();
  455. }
  456. m_managedFileScopesMap.clear();
  457. }
  458. /*
  459. if perms set on 'scopeA::scopeB' only and lookup of 'scopeA::scopeB::scopeC::scopeD'
  460. need to lookup:
  461. 'scopeA'
  462. no match=>continue
  463. match=>continue if read permissions (if no read, implies can't "see" child scopes)
  464. 'scopeA::scopeB'
  465. no match=>continue
  466. match=>continue if read permissions (if no read, implies can't "see" child scopes)
  467. etc. Until full scope path checked, or no read permissions hit on ancestor scope.
  468. */
  469. bool CPermissionsCache::queryPermsManagedFileScope(ISecUser& sec_user, const char * fullScope, StringBuffer& managedScope, SecAccessFlags * accessFlags)
  470. {
  471. if (!fullScope || !*fullScope)
  472. {
  473. *accessFlags = queryDefaultPermission(sec_user);
  474. return true;
  475. }
  476. time_t now;
  477. time(&now);
  478. if (m_secMgr && (0 == m_lastManagedFileScopesRefresh || m_lastManagedFileScopesRefresh < (now - m_cacheTimeout)))
  479. {
  480. removeAllManagedFileScopes();
  481. IArrayOf<ISecResource> scopes;
  482. aindex_t count = m_secMgr->getManagedFileScopes(scopes);
  483. if (count)
  484. addManagedFileScopes(scopes);
  485. m_defaultPermission = SecAccess_Unknown;//trigger refresh
  486. m_lastManagedFileScopesRefresh = now;
  487. }
  488. if (m_managedFileScopesMap.empty())
  489. {
  490. *accessFlags = queryDefaultPermission(sec_user);
  491. return true;
  492. }
  493. StringArray scopes;
  494. {
  495. StringBuffer scope;
  496. const char * p = fullScope;
  497. while (*p)
  498. {
  499. if (*p == ':')
  500. {
  501. if (*(p+1) != ':')
  502. return false;//Malformed scope string, let LDAP figure it out
  503. scopes.append(scope.str());
  504. scope.append(*(p++));
  505. }
  506. scope.append(*(p++));
  507. }
  508. scopes.append(scope.str());
  509. }
  510. ISecResource *matchedRes = NULL;
  511. ISecResource *res = NULL;
  512. bool isManaged = false;
  513. ReadLockBlock readLock(m_scopesRWLock);
  514. for(unsigned i = 0; i < scopes.length(); i++)
  515. {
  516. const char* scope = scopes.item(i);
  517. map<string, ISecResource*>::const_iterator it = m_managedFileScopesMap.find(scope);
  518. if (it != m_managedFileScopesMap.end())
  519. {
  520. isManaged = true;
  521. res = (*it).second;
  522. res->setResourceType(RT_FILE_SCOPE);
  523. LINK(res);
  524. IArrayOf<ISecResource> secResArr;
  525. secResArr.append(*res);
  526. bool found;
  527. int nFound = lookup(sec_user, secResArr, &found);
  528. if (nFound && found)
  529. {
  530. if (0 == (res->getAccessFlags() & SecAccess_Read))
  531. {
  532. *accessFlags = res->getAccessFlags();
  533. managedScope.append(const_cast<char *>(res->getName()));
  534. #ifdef _DEBUG
  535. DBGLOG("FileScope %s for %s(%s) access denied %d",fullScope, sec_user.getName(), res->getName(), *accessFlags);
  536. #endif
  537. return true;
  538. }
  539. else
  540. matchedRes = res;//allowed at this scope, but must also look at child scopes
  541. }
  542. }
  543. }
  544. bool rc;
  545. if (isManaged)
  546. {
  547. if (matchedRes)
  548. {
  549. *accessFlags = matchedRes->getAccessFlags();
  550. managedScope.append(const_cast<char *>(matchedRes->getName()));
  551. #ifdef _DEBUG
  552. DBGLOG("FileScope %s for %s(%s) access granted %d", fullScope, sec_user.getName(), matchedRes->getName(), *accessFlags);
  553. #endif
  554. rc = true;
  555. }
  556. else
  557. {
  558. managedScope.append(const_cast<char *>(res->getName()));
  559. #ifdef _DEBUG
  560. DBGLOG("FileScope %s for %s(%s) managed but not cached", fullScope, sec_user.getName(), res->getName());
  561. #endif
  562. rc = false;//need to go to LDAP to check
  563. }
  564. }
  565. else
  566. {
  567. *accessFlags = queryDefaultPermission(sec_user);
  568. #ifdef _DEBUG
  569. DBGLOG("FileScope %s for %s not managed, using default %d", fullScope, sec_user.getName(),*accessFlags);
  570. #endif
  571. rc = true;
  572. }
  573. return rc;
  574. }
  575. SecAccessFlags CPermissionsCache::queryDefaultPermission(ISecUser& user)
  576. {
  577. if (m_defaultPermission == SecAccess_Unknown)
  578. {
  579. if (m_secMgr)
  580. m_defaultPermission = m_secMgr->queryDefaultPermission(user);
  581. else
  582. m_defaultPermission = SecAccess_None;
  583. }
  584. return m_defaultPermission;
  585. }
  586. void CPermissionsCache::flush()
  587. {
  588. // MORE - is this safe? m_defaultPermossion and m_lastManagedFileScopesRefresh are unprotected,
  589. // and entries could be added to the first cache while the second is being cleared - does that matter?
  590. {
  591. WriteLockBlock writeLock(m_resPermCacheRWLock);
  592. MapResPermissionsCache::const_iterator i;
  593. MapResPermissionsCache::const_iterator iEnd = m_resPermissionsMap.end();
  594. for (i = m_resPermissionsMap.begin(); i != iEnd; i++)
  595. delete (*i).second;
  596. m_resPermissionsMap.clear();
  597. }
  598. {
  599. WriteLockBlock writeLock(m_userCacheRWLock );
  600. MapUserCache::const_iterator ui;
  601. MapUserCache::const_iterator uiEnd = m_userCache.end();
  602. for (ui = m_userCache.begin(); ui != uiEnd; ui++)
  603. delete (*ui).second;
  604. m_userCache.clear();
  605. }
  606. m_lastManagedFileScopesRefresh = 0;
  607. m_defaultPermission = SecAccess_Unknown;//trigger refresh
  608. }
  609. CPermissionsCache* CPermissionsCache::getInstance(const char * _secMgrClass)
  610. {
  611. const char * secMgrClass = (_secMgrClass != nullptr && *_secMgrClass) ? _secMgrClass : "genericSecMgrClass";
  612. CriticalBlock block(mapCacheCS);
  613. MapCache::iterator it = g_mapCache.find(secMgrClass);
  614. if (it != g_mapCache.end())//exists in cache
  615. {
  616. LINK((*it).second);
  617. return (*it).second;
  618. }
  619. else
  620. {
  621. CPermissionsCache * instance = new CPermissionsCache(_secMgrClass);
  622. g_mapCache.insert(pair<string, CPermissionsCache*>(secMgrClass, instance));
  623. return instance;
  624. }
  625. }