123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721 |
- /*##############################################################################
- HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ############################################################################## */
- #include "caching.hpp"
- #include "jtime.hpp"
- #include "digisign.hpp"
- using namespace cryptohelper;
- //define a container for multiple instances of a security manager cache
- typedef map<string, CPermissionsCache*> MapCache;
- static CriticalSection mapCacheCS;//guards modifications to the cache map
- static MapCache g_mapCache;
- /**********************************************************
- * CResPermissionsCache *
- * (used by CPermissionsCache defined below) *
- **********************************************************/
- time_t getThreadCreateTime()
- {
- time_t t;
- void* tslval = getThreadLocalVal();
- if(tslval == NULL)
- return 0;
- memcpy(&t, tslval, sizeof(t));
- return t;
- }
- CResPermissionsCache::~CResPermissionsCache()
- {
- MapResAccess::const_iterator i;
- MapResAccess::const_iterator iEnd = m_resAccessMap.end();
- for (i = m_resAccessMap.begin(); i != iEnd; i++)
- {
- ISecResource* ptr = ((*i).second).second;
- if(ptr)
- {
- ptr->Release();
- }
- }
- }
- //called from within a ReadLockBlock
- int CResPermissionsCache::lookup( IArrayOf<ISecResource>& resources, bool* pFound )
- {
- time_t tstamp;
- time(&tstamp);
- int nresources = resources.ordinality();
- int nFound = 0;
- for (int i = 0; i < nresources; i++)
- {
- ISecResource& secResource = resources.item(i);
- const char* resource = secResource.getName();
- if(resource == NULL)
- {
- *pFound++ = false;
- continue;
- }
- #ifdef _DEBUG
- DBGLOG("CACHE: CResPermissionsCache Looking up resource(%d of %d) %s:%s", i, nresources, m_user.c_str(), resource);
- #endif
- MapResAccess::iterator it = m_resAccessMap.find(SecCacheKeyEntry(resource, secResource.getResourceType()));
- if (it != m_resAccessMap.end())//exists in cache
- {
- ResPermCacheEntry& resParamCacheEntry = (*it).second;
- const time_t timeExpiry = resParamCacheEntry.first + m_pParentCache->getCacheTimeout();
- if (timeExpiry < tstamp)//entry was not stale during last cleanup but is stale now
- *pFound++ = false;
- else if(!m_pParentCache->isCacheEnabled() && m_pParentCache->isTransactionalEnabled())//m_pParentCache->getOriginalTimeout() == 0)
- {
- time_t tctime = getThreadCreateTime();
- if(tctime <= 0 || timeExpiry < tctime)
- {
- *pFound++ = false;
- }
- else
- {
- secResource.copy(resParamCacheEntry.second);
- #ifdef _DEBUG
- DBGLOG("CACHE: CResPermissionsCache FoundA %s:%s=>%d", m_user.c_str(), resource, ((ISecResource*)resParamCacheEntry.second)->getAccessFlags());
- #endif
- *pFound++ = true;
- nFound++;
- }
- }
- else
- {
- secResource.copy(resParamCacheEntry.second);
- #ifdef _DEBUG
- DBGLOG("CACHE: CResPermissionsCache FoundB %s:%s=>%d", m_user.c_str(), resource, ((ISecResource*)resParamCacheEntry.second)->getAccessFlags());
- #endif
- *pFound++ = true;
- nFound++;
- }
- }
- else
- *pFound++ = false;
- }
- return nFound;
- }
- //called from within a WriteLockBlock
- void CResPermissionsCache::add( IArrayOf<ISecResource>& resources )
- {
- time_t tstamp;
- time(&tstamp);
- int nresources = resources.ordinality();
- for (int i = 0; i < nresources; i++)
- {
- ISecResource* secResource = &resources.item(i);
- if(!secResource)
- continue;
- const char* resource = secResource->getName();
- SecResourceType resourcetype = secResource->getResourceType();
- if(resource == NULL)
- continue;
- int permissions = secResource->getAccessFlags();
- if(permissions == SecAccess_Unavailable)
- continue;
- MapResAccess::iterator it = m_resAccessMap.find(SecCacheKeyEntry(resource, resourcetype));
- if (it != m_resAccessMap.end())//already exists so overwrite it but first remove existing timestamp info
- {
- ResPermCacheEntry& resParamCacheEntry = (*it).second;
- time_t oldtstamp = resParamCacheEntry.first;
- //there may be multiple resources associated with the same timestamp
- //in the multimap so find this entry
- //
- MapTimeStamp::iterator itL = m_timestampMap.lower_bound( oldtstamp );
- MapTimeStamp::iterator itU = m_timestampMap.upper_bound( oldtstamp );
- MapTimeStamp::iterator its;
- for ( its = itL; its != itU; its++)
- {
- SecCacheKeyEntry& cachekey = (*its).second;
- if (cachekey.first == resource && cachekey.second == resourcetype)
- {
- m_timestampMap.erase(its);
- break;
- }
- }
- resParamCacheEntry.second->Release();
- m_resAccessMap.erase(SecCacheKeyEntry(resource, resourcetype));
- }
- #ifdef _DEBUG
- DBGLOG("CACHE: CResPermissionsCache Adding %s:%s(%d)", m_user.c_str(), resource, permissions);
- #endif
- m_resAccessMap.insert( pair<SecCacheKeyEntry, ResPermCacheEntry>(SecCacheKeyEntry(resource, resourcetype), ResPermCacheEntry(tstamp, secResource->clone())));
- m_timestampMap.insert( pair<time_t, SecCacheKeyEntry>(tstamp, SecCacheKeyEntry(resource, resourcetype)));
- }
- }
- //called from within a WriteLockBlock
- void CResPermissionsCache::removeStaleEntries(time_t tstamp)
- {
- if (needsCleanup(tstamp, m_pParentCache->getCacheTimeout()))
- {
- MapTimeStamp::iterator i;
- MapTimeStamp::iterator itL = m_timestampMap.lower_bound(tstamp);
- MapTimeStamp::iterator iBegin = m_timestampMap.begin();
- for (i = iBegin; i != itL; i++)
- {
- SecCacheKeyEntry& cachekey = (*i).second;
- MapResAccess::iterator it = m_resAccessMap.find(cachekey);
- if (it != m_resAccessMap.end())//exists in cache
- {
- ResPermCacheEntry& entry = (*it).second;
- if(entry.second)
- entry.second->Release();
- }
- m_resAccessMap.erase(cachekey);
- }
- m_timestampMap.erase(iBegin, itL);
- m_tLastCleanup = tstamp;
- }
- }
- //called from within a WriteLockBlock
- void CResPermissionsCache::remove(SecResourceType rtype, const char* resourcename)
- {
- SecCacheKeyEntry key(resourcename, rtype);
- MapResAccess::iterator it = m_resAccessMap.find(key);
- if (it != m_resAccessMap.end())//exists in cache
- {
- ResPermCacheEntry& entry = (*it).second;
- if(entry.second)
- entry.second->Release();
- }
- m_resAccessMap.erase(key);
- }
- /**********************************************************
- * CPermissionsCache *
- **********************************************************/
- CPermissionsCache::~CPermissionsCache()
- {
- if (!m_secMgrClass.isEmpty())
- {
- CriticalBlock block(mapCacheCS);
- g_mapCache.erase(m_secMgrClass.str());
- }
- flush();
- }
- int CPermissionsCache::lookup( ISecUser& sec_user, IArrayOf<ISecResource>& resources, bool* pFound)
- {
- time_t tstamp;
- time(&tstamp);
- const char* userId = sec_user.getName();
- //First check if matching cache entry is stale
- bool needsCleanup = false;
- {
- ReadLockBlock readLock(m_resPermCacheRWLock);
- MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( userId );
- if (i != m_resPermissionsMap.end())
- {
- CResPermissionsCache* pResPermissionsCache = (*i).second;
- needsCleanup = pResPermissionsCache->needsCleanup(tstamp, getCacheTimeout());
- }
- }
- //clear stale cache entries for this CResPermissionsCache entry
- if (needsCleanup)
- {
- WriteLockBlock writeLock(m_resPermCacheRWLock);
- MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( userId );
- if (i != m_resPermissionsMap.end())//Entry could have been deleted by another thread
- {
- CResPermissionsCache* pResPermissionsCache = (*i).second;
- pResPermissionsCache->removeStaleEntries(tstamp);
- }
- }
- //Lookup all user/resources
- int nFound;
- ReadLockBlock readLock(m_resPermCacheRWLock);
- MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( userId );
- if (i != m_resPermissionsMap.end())
- {
- CResPermissionsCache* pResPermissionsCache = (*i).second;
- nFound = pResPermissionsCache->lookup( resources, pFound );
- }
- else
- {
- nFound = 0;
- memset(pFound, 0, sizeof(bool)*resources.ordinality());
- }
- #ifdef _DEBUG
- DBGLOG("CACHE: CPermissionsCache Looked up resources for %s:*, found %d of %d matches", userId, nFound, resources.ordinality());
- #endif
- return nFound;
- }
- void CPermissionsCache::add( ISecUser& sec_user, IArrayOf<ISecResource>& resources )
- {
- const char* user = sec_user.getName();
- WriteLockBlock writeLock(m_resPermCacheRWLock);
- MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( user );
- CResPermissionsCache* pResPermissionsCache;
- if (i == m_resPermissionsMap.end())
- {
- #ifdef _DEBUG
- DBGLOG("CACHE: CPermissionsCache Adding resources to cache for new user %s", user);
- #endif
- pResPermissionsCache = new CResPermissionsCache(this, user);
- m_resPermissionsMap.insert(pair<string, CResPermissionsCache*>(user, pResPermissionsCache));
- }
- else
- {
- #ifdef _DEBUG
- DBGLOG("CACHE: CPermissionsCache Adding resources to cache for existing user %s", user);
- #endif
- pResPermissionsCache = (*i).second;
- }
- pResPermissionsCache->add( resources );
- }
- void CPermissionsCache::removePermissions( ISecUser& sec_user)
- {
- const char* user = sec_user.getName();
- if(user != NULL && *user != '\0')
- {
- #ifdef _DEBUG
- DBGLOG("CACHE: CPermissionsCache Removing permissions for user %s", user);
- #endif
- WriteLockBlock writeLock(m_resPermCacheRWLock);
- m_resPermissionsMap.erase(user);
- }
- }
- void CPermissionsCache::remove(SecResourceType rtype, const char* resourcename)
- {
- MapResPermissionsCache::const_iterator i;
- WriteLockBlock writeLock(m_resPermCacheRWLock);
- MapResPermissionsCache::const_iterator iEnd = m_resPermissionsMap.end();
- for (i = m_resPermissionsMap.begin(); i != iEnd; i++)
- {
- i->second->remove(rtype, resourcename);
- }
- }
- bool CPermissionsCache::lookup(ISecUser& sec_user)
- {
- if(!isCacheEnabled())
- return false;
- const char* username = sec_user.getName();
- if(!username || !*username)
- return false;
- bool deleteEntry = false;
- {
- ReadLockBlock readLock(m_userCacheRWLock );
- MapUserCache::iterator it = m_userCache.find(username);
- if (it == m_userCache.end())
- return false;
- CachedUser* user = (CachedUser*)(it->second);
- time_t now;
- time(&now);
- if(user->getTimestamp() < (now - m_cacheTimeout) && 0==sec_user.credentials().getSessionToken())//don't delete session based users
- {
- deleteEntry = true;
- }
- else
- {
- const char* cachedpw = user->queryUser()->credentials().getPassword();
- const char * pw = sec_user.credentials().getPassword();
- if ((sec_user.credentials().getSessionToken() != 0) || !isEmptyString(sec_user.credentials().getSignature()) || !isEmptyString(user->queryUser()->credentials().getSignature()) )
- {//presence of session token or signature means user is authenticated
- #ifdef _DEBUG
- DBGLOG("CACHE: CPermissionsCache Found validated user %s", username);
- #endif
- user->queryUser()->copyTo(sec_user);
- return true;
- }
- else if(cachedpw && pw && *pw != '\0')
- {
- if(strcmp(cachedpw, pw) == 0)
- {
- #ifdef _DEBUG
- DBGLOG("CACHE: CPermissionsCache Found validated user %s", username);
- #endif
- user->queryUser()->copyTo(sec_user);
- return true;
- }
- else
- {
- deleteEntry = true;
- }
- }
- }
- }
- if (deleteEntry)
- {
- WriteLockBlock writeLock(m_userCacheRWLock);
- MapUserCache::iterator it = m_userCache.find(username);
- if (it != m_userCache.end())
- {
- CachedUser* user = (CachedUser*)(it->second);
- m_userCache.erase(username);
- delete user;
- }
- }
- return false;
- }
- ISecUser* CPermissionsCache::getCachedUser( ISecUser& sec_user)
- {
- if(!isCacheEnabled())
- return NULL;
- const char* username = sec_user.getName();
- if(!username || !*username)
- return NULL;
- ReadLockBlock readLock(m_userCacheRWLock );
- MapUserCache::iterator it = m_userCache.find(username);
- if (it == m_userCache.end())
- return NULL;
- CachedUser* user = (CachedUser*)(it->second);
- return LINK(user->queryUser());
- }
- void CPermissionsCache::add(ISecUser& sec_user)
- {
- if(!isCacheEnabled())
- return;
-
- const char* username = sec_user.getName();
- if(!username || !*username)
- return;
-
- WriteLockBlock writeLock(m_userCacheRWLock );
- MapUserCache::iterator it = m_userCache.find(username);
- CachedUser* user = NULL;
- if (it != m_userCache.end())
- {
- user = (CachedUser*)(it->second);
- m_userCache.erase(username);
- delete user;
- }
- #ifdef _DEBUG
- DBGLOG("CACHE: CPermissionsCache Adding cached user %s", username);
- #endif
- if (isEmptyString(sec_user.credentials().getPassword()) && (0 == sec_user.credentials().getSessionToken()) && isEmptyString(sec_user.credentials().getSignature()))
- {
- //No need to sign if password or authenticated session based user
- IDigitalSignatureManager * pDSM = queryDigitalSignatureManagerInstanceFromEnv();
- if (pDSM && pDSM->isDigiSignerConfigured())
- {
- //Set user digital signature
- StringBuffer b64Signature;
- pDSM->digiSign(b64Signature, sec_user.getName());
- sec_user.credentials().setSignature(b64Signature);//callers sec_user will now contain signature
- }
- }
- m_userCache[username] = new CachedUser(LINK(&sec_user));
- }
- void CPermissionsCache::removeFromUserCache(ISecUser& sec_user)
- {
- const char* username = sec_user.getName();
- if(username && *username)
- {
- WriteLockBlock writeLock(m_userCacheRWLock );
- MapUserCache::iterator it = m_userCache.find(username);
- if (it != m_userCache.end())
- {
- CachedUser* user = (CachedUser*)(it->second);
- m_userCache.erase(username);
- delete user;
- #ifdef _DEBUG
- DBGLOG("CACHE: CPermissionsCache Removing cached user %s", username);
- #endif
- }
- }
- }
- bool CPermissionsCache::addManagedFileScopes(IArrayOf<ISecResource>& scopes)
- {
- WriteLockBlock writeLock(m_scopesRWLock);
- ForEachItemIn(x, scopes)
- {
- ISecResource* scope = &scopes.item(x);
- if(!scope)
- continue;
- const char* cachekey = scope->getName();
- if(cachekey == NULL)
- continue;
- map<string, ISecResource*>::iterator it = m_managedFileScopesMap.find(cachekey);
- if (it != m_managedFileScopesMap.end())
- {
- ISecResource *res = (*it).second;
- res->Release();
- m_managedFileScopesMap.erase(it);
- }
- #ifdef _DEBUG
- DBGLOG("Caching Managed File Scope %s",cachekey);
- #endif
- m_managedFileScopesMap.insert( pair<string, ISecResource*>(cachekey, LINK(scope)));
- }
- return true;
- }
- inline void CPermissionsCache::removeManagedFileScopes(IArrayOf<ISecResource>& scopes)
- {
- WriteLockBlock writeLock(m_scopesRWLock);
- ForEachItemIn(x, scopes)
- {
- ISecResource* scope = &scopes.item(x);
- if(!scope)
- continue;
- const char* cachekey = scope->getName();
- if(cachekey == NULL)
- continue;
- map<string, ISecResource*>::iterator it = m_managedFileScopesMap.find(cachekey);
- if (it != m_managedFileScopesMap.end())
- {
- ISecResource *res = (*it).second;
- res->Release();
- m_managedFileScopesMap.erase(it);
- }
- }
- }
- inline void CPermissionsCache::removeAllManagedFileScopes()
- {
- WriteLockBlock writeLock(m_scopesRWLock);
- map<string, ISecResource*>::const_iterator cit;
- map<string, ISecResource*>::const_iterator iEnd = m_managedFileScopesMap.end();
- for (cit = m_managedFileScopesMap.begin(); cit != iEnd; cit++)
- {
- ISecResource *res = (*cit).second;
- res->Release();
- }
- m_managedFileScopesMap.clear();
- }
- /*
- if perms set on 'scopeA::scopeB' only and lookup of 'scopeA::scopeB::scopeC::scopeD'
- need to lookup:
- 'scopeA'
- no match=>continue
- match=>continue if read permissions (if no read, implies can't "see" child scopes)
- 'scopeA::scopeB'
- no match=>continue
- match=>continue if read permissions (if no read, implies can't "see" child scopes)
- etc. Until full scope path checked, or no read permissions hit on ancestor scope.
- */
- static CriticalSection msCacheSyncCS;//for managed scopes cache syncronization
- bool CPermissionsCache::queryPermsManagedFileScope(ISecUser& sec_user, const char * fullScope, StringBuffer& managedScope, SecAccessFlags * accessFlags)
- {
- unsigned start = msTick();
- if (!fullScope || !*fullScope)
- {
- *accessFlags = queryDefaultPermission(sec_user);
- return true;
- }
- if (m_secMgr)
- {
- CriticalBlock block(msCacheSyncCS);
- time_t now;
- time(&now);
- if (0 == m_lastManagedFileScopesRefresh || ((now - m_lastManagedFileScopesRefresh) > m_cacheTimeout))
- {
- removeAllManagedFileScopes();
- IArrayOf<ISecResource> scopes;
- aindex_t count = m_secMgr->getManagedFileScopes(scopes);
- if (count)
- addManagedFileScopes(scopes);
- m_defaultPermission = SecAccess_Unknown;//trigger refresh
- time(&m_lastManagedFileScopesRefresh);
- }
- }
- if (m_managedFileScopesMap.empty())
- {
- *accessFlags = queryDefaultPermission(sec_user);
- return true;
- }
- StringArray scopes;
- {
- StringBuffer scope;
- const char * p = fullScope;
- while (*p)
- {
- if (*p == ':')
- {
- if (*(p+1) != ':')
- return false;//Malformed scope string, let LDAP figure it out
- scopes.append(scope.str());
- scope.append(*(p++));
- }
- scope.append(*(p++));
- }
- scopes.append(scope.str());
- }
- ISecResource *matchedRes = NULL;
- ISecResource *res = NULL;
- bool isManaged = false;
- ReadLockBlock readLock(m_scopesRWLock);
- for(unsigned i = 0; i < scopes.length(); i++)
- {
- const char* scope = scopes.item(i);
- map<string, ISecResource*>::const_iterator it = m_managedFileScopesMap.find(scope);
- if (it != m_managedFileScopesMap.end())
- {
- isManaged = true;
- res = (*it).second;
- res->setResourceType(RT_FILE_SCOPE);
- LINK(res);
- IArrayOf<ISecResource> secResArr;
- secResArr.append(*res);
- bool found;
- int nFound = lookup(sec_user, secResArr, &found);
- if (nFound && found)
- {
- if (0 == (res->getAccessFlags() & SecAccess_Read))
- {
- *accessFlags = res->getAccessFlags();
- managedScope.append(const_cast<char *>(res->getName()));
- DBGLOG("FileScope %s for %s(%s) access denied %d at scope %s, took %dms",fullScope, sec_user.getName(), res->getName(), *accessFlags, scope, msTick()-start);
- return true;
- }
- else
- matchedRes = res;//allowed at this scope, but must also look at child scopes
- }
- }
- }
- bool rc;
- if (isManaged)
- {
- if (matchedRes)
- {
- *accessFlags = matchedRes->getAccessFlags();
- managedScope.append(const_cast<char *>(matchedRes->getName()));
- #ifdef _DEBUG
- DBGLOG("FileScope %s for %s(%s) access granted %d, took %dms", fullScope, sec_user.getName(), matchedRes->getName(), *accessFlags, msTick()-start);
- #endif
- rc = true;
- }
- else
- {
- managedScope.append(const_cast<char *>(res->getName()));
- #ifdef _DEBUG
- DBGLOG("FileScope %s for %s(%s) managed but not cached, took %dms", fullScope, sec_user.getName(), res->getName(), msTick()-start);
- #endif
- rc = false;//need to go to LDAP to check
- }
- }
- else
- {
- *accessFlags = queryDefaultPermission(sec_user);
- #ifdef _DEBUG
- DBGLOG("FileScope %s for %s not managed, using default %d, took %dms", fullScope, sec_user.getName(),*accessFlags, msTick()-start);
- #endif
- rc = true;
- }
- return rc;
- }
- SecAccessFlags CPermissionsCache::queryDefaultPermission(ISecUser& user)
- {
- if (m_defaultPermission == SecAccess_Unknown)
- {
- if (m_secMgr)
- m_defaultPermission = m_secMgr->queryDefaultPermission(user);
- else
- m_defaultPermission = SecAccess_None;
- }
- return m_defaultPermission;
- }
- void CPermissionsCache::flush()
- {
- // MORE - is this safe? m_defaultPermossion and m_lastManagedFileScopesRefresh are unprotected,
- // and entries could be added to the first cache while the second is being cleared - does that matter?
- {
- WriteLockBlock writeLock(m_resPermCacheRWLock);
- MapResPermissionsCache::const_iterator i;
- MapResPermissionsCache::const_iterator iEnd = m_resPermissionsMap.end();
- for (i = m_resPermissionsMap.begin(); i != iEnd; i++)
- delete (*i).second;
- m_resPermissionsMap.clear();
- }
- {
- WriteLockBlock writeLock(m_userCacheRWLock );
- MapUserCache::const_iterator ui;
- MapUserCache::const_iterator uiEnd = m_userCache.end();
- for (ui = m_userCache.begin(); ui != uiEnd; ui++)
- delete (*ui).second;
- m_userCache.clear();
- }
- m_lastManagedFileScopesRefresh = 0;
- m_defaultPermission = SecAccess_Unknown;//trigger refresh
- }
- CPermissionsCache* CPermissionsCache::getInstance(const char * _secMgrClass)
- {
- const char * secMgrClass = (_secMgrClass != nullptr && *_secMgrClass) ? _secMgrClass : "genericSecMgrClass";
- CriticalBlock block(mapCacheCS);
- MapCache::iterator it = g_mapCache.find(secMgrClass);
- if (it != g_mapCache.end())//exists in cache
- {
- LINK((*it).second);
- return (*it).second;
- }
- else
- {
- CPermissionsCache * instance = new CPermissionsCache(_secMgrClass);
- g_mapCache.insert(pair<string, CPermissionsCache*>(secMgrClass, instance));
- return instance;
- }
- }
|