123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- /*##############################################################################
- HPCC SYSTEMS software Copyright (C) 2015 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.
- ############################################################################## */
- #ifdef _USE_OPENLDAP
- #include "ldapsecurity.ipp"
- #endif
- #include "ws_espcontrolservice.hpp"
- #include "jlib.hpp"
- #include "exception_util.hpp"
- #include "dasds.hpp"
- #define SDS_LOCK_TIMEOUT (5*60*1000) // 5 mins
- const char* CWSESPControlEx::readSessionTimeStamp(int t, StringBuffer& str)
- {
- CDateTime time;
- time.set(t);
- return time.getString(str).str();
- }
- IEspSession* CWSESPControlEx::setSessionInfo(IPropertyTree* espSessionTree, unsigned port, IEspSession* session)
- {
- if (espSessionTree == nullptr)
- return nullptr;
- StringBuffer createTimeStr, lastAccessedStr, TimeoutAtStr;
- int lastAccessed = espSessionTree->getPropInt(PropSessionLastAccessed, 0);
- session->setPort(port);
- session->setID(espSessionTree->queryProp(PropSessionExternalID));
- session->setUserID(espSessionTree->queryProp(PropSessionUserID));
- session->setNetworkAddress(espSessionTree->queryProp(PropSessionNetworkAddress));
- session->setCreateTime(readSessionTimeStamp(espSessionTree->getPropInt(PropSessionCreateTime, 0), createTimeStr));
- session->setLastAccessed(readSessionTimeStamp(espSessionTree->getPropInt(PropSessionLastAccessed, 0), lastAccessedStr));
- session->setTimeoutAt(readSessionTimeStamp(espSessionTree->getPropInt(PropSessionTimeoutAt, 0), TimeoutAtStr));
- session->setTimeoutByAdmin(espSessionTree->getPropBool(PropSessionTimeoutByAdmin, false));
- return session;
- }
- void CWSESPControlEx::init(IPropertyTree *cfg, const char *process, const char *service)
- {
- if(cfg == NULL)
- throw MakeStringException(-1, "Can't initialize CWSESPControlEx, cfg is NULL");
- espProcess.set(process);
- VStringBuffer xpath("Software/EspProcess[@name=\"%s\"]", process);
- IPropertyTree* espCFG = cfg->queryPropTree(xpath.str());
- if (!espCFG)
- throw MakeStringException(-1, "Can't find EspBinding for %s", process);
- Owned<IPropertyTreeIterator> it = espCFG->getElements("AuthDomains/AuthDomain");
- ForEach(*it)
- {
- IPropertyTree& authDomain = it->query();
- StringBuffer name = authDomain.queryProp("@domainName");
- if (name.isEmpty())
- name.set("default");
- sessionTimeoutMinutesMap.setValue(name.str(), authDomain.getPropInt("@sessionTimeoutMinutes", 0));
- }
- }
- bool CWSESPControlEx::onSetLogging(IEspContext& context, IEspSetLoggingRequest& req, IEspSetLoggingResponse& resp)
- {
- try
- {
- #ifdef _USE_OPENLDAP
- CLdapSecManager* secmgr = dynamic_cast<CLdapSecManager*>(context.querySecManager());
- if(secmgr && !secmgr->isSuperUser(context.queryUser()))
- throw MakeStringException(ECLWATCH_SUPER_USER_ACCESS_DENIED, "Failed to change log settings. Permission denied.");
- #endif
- if (!m_container)
- throw MakeStringException(ECLWATCH_INTERNAL_ERROR, "Failed to access container.");
- if (!req.getLoggingLevel_isNull())
- m_container->setLogLevel(req.getLoggingLevel());
- if (!req.getLogRequests_isNull())
- m_container->setLogRequests(req.getLogRequests());
- if (!req.getLogResponses_isNull())
- m_container->setLogResponses(req.getLogResponses());
- resp.setStatus(0);
- resp.setMessage("Logging settings are updated.");
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- IRemoteConnection* CWSESPControlEx::querySDSConnection(const char* xpath, unsigned mode, unsigned timeout)
- {
- Owned<IRemoteConnection> globalLock = querySDS().connect(xpath, myProcessSession(), mode, timeout);
- if (!globalLock)
- throw MakeStringException(ECLWATCH_INTERNAL_ERROR, "Unable to connect to ESP Session information in dali %s", xpath);
- return globalLock.getClear();
- }
- IRemoteConnection* CWSESPControlEx::querySDSConnectionForESPSession(unsigned mode, unsigned timeout)
- {
- VStringBuffer xpath("/%s/%s[@name='%s']", PathSessionRoot, PathSessionProcess, espProcess.get());
- return querySDSConnection(xpath.str(), mode, timeout);
- }
- bool CWSESPControlEx::onSessionQuery(IEspContext& context, IEspSessionQueryRequest& req, IEspSessionQueryResponse& resp)
- {
- try
- {
- #ifdef _USE_OPENLDAP
- CLdapSecManager* secmgr = dynamic_cast<CLdapSecManager*>(context.querySecManager());
- if(secmgr && !secmgr->isSuperUser(context.queryUser()))
- throw MakeStringException(ECLWATCH_SUPER_USER_ACCESS_DENIED, "Failed to query session. Permission denied.");
- #endif
- StringBuffer xpath;
- setSessionXPath(false, nullptr, req.getUserID(), req.getFromIP(), xpath);
- IArrayOf<IEspSession> sessions;
- Owned<IRemoteConnection> globalLock = querySDSConnectionForESPSession(RTM_LOCK_READ, SESSION_SDS_LOCK_TIMEOUT);
- Owned<IPropertyTreeIterator> iter = globalLock->queryRoot()->getElements("*");
- ForEach(*iter)
- {
- IPropertyTree& appSessionTree = iter->query();
- unsigned port = appSessionTree.getPropInt("@port");
- Owned<IPropertyTreeIterator> iter1 = appSessionTree.getElements(xpath.str());
- ForEach(*iter1)
- {
- IPropertyTree& sessionTree = iter1->query();
- Owned<IEspSession> s = createSession();
- setSessionInfo(&sessionTree, port, s);
- sessions.append(*s.getLink());
- }
- }
- resp.setSessions(sessions);
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool CWSESPControlEx::onSessionInfo(IEspContext& context, IEspSessionInfoRequest& req, IEspSessionInfoResponse& resp)
- {
- try
- {
- #ifdef _USE_OPENLDAP
- CLdapSecManager* secmgr = dynamic_cast<CLdapSecManager*>(context.querySecManager());
- if(secmgr && !secmgr->isSuperUser(context.queryUser()))
- throw MakeStringException(ECLWATCH_SUPER_USER_ACCESS_DENIED, "Failed to get session information. Permission denied.");
- #endif
- StringBuffer id = req.getID();
- if (id.trim().isEmpty())
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "ID not specified.");
- unsigned port = 8010;
- if (!req.getPort_isNull())
- port = req.getPort();
- Owned<IRemoteConnection> globalLock;
- VStringBuffer xpath("/%s/%s[@name='%s']/%s[@port='%d']/%s[%s='%s']", PathSessionRoot, PathSessionProcess, espProcess.get(),
- PathSessionApplication, port, PathSessionSession, PropSessionExternalID, id.str());
- try
- {
- globalLock.setown(querySDSConnection(xpath.str(), RTM_LOCK_READ, SESSION_SDS_LOCK_TIMEOUT));
- }
- catch(IException* e)
- {
- VStringBuffer msg("Failed to get session info for id %s on port %u: ", id.str(), port);
- e->errorMessage(msg);
- e->Release();
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "%s", msg.str());
- }
- setSessionInfo(globalLock->queryRoot(), port, &resp.updateSession());
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool CWSESPControlEx::onCleanSession(IEspContext& context, IEspCleanSessionRequest& req, IEspCleanSessionResponse& resp)
- {
- try
- {
- #ifdef _USE_OPENLDAP
- CLdapSecManager* secmgr = dynamic_cast<CLdapSecManager*>(context.querySecManager());
- if(secmgr && !secmgr->isSuperUser(context.queryUser()))
- throw MakeStringException(ECLWATCH_SUPER_USER_ACCESS_DENIED, "Failed to clean session. Permission denied.");
- #endif
- StringBuffer id, userID, fromIP;
- bool allSessions = req.getAllSessions();
- if (!allSessions)
- {
- id.set(req.getID());
- userID.set(req.getUserID());
- fromIP.set(req.getFromIP());
- if ((id.trim().isEmpty()) && (userID.trim().isEmpty()) && (fromIP.trim().isEmpty()))
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "ID, userID or FromIP has to be specified.");
- }
- cleanSessions(allSessions, id.str(), userID.str(), fromIP.str());
- resp.setStatus(0);
- resp.setMessage("Session is cleaned.");
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool CWSESPControlEx::onSetSessionTimeout(IEspContext& context, IEspSetSessionTimeoutRequest& req, IEspSetSessionTimeoutResponse& resp)
- {
- try
- {
- #ifdef _USE_OPENLDAP
- CLdapSecManager* secmgr = dynamic_cast<CLdapSecManager*>(context.querySecManager());
- if(secmgr && !secmgr->isSuperUser(context.queryUser()))
- throw MakeStringException(ECLWATCH_SUPER_USER_ACCESS_DENIED, "Failed to set session timeout. Permission denied.");
- #endif
- StringBuffer id, userID, fromIP;
- bool allSessions = req.getAllSessions();
- if (!allSessions)
- {
- id.set(req.getID());
- userID.set(req.getUserID());
- fromIP.set(req.getFromIP());
- if ((id.trim().isEmpty()) && (userID.trim().isEmpty()) && (fromIP.trim().isEmpty()))
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "ID, userID or FromIP has to be specified.");
- }
- int timeoutMinutes = req.getTimeoutMinutes_isNull() ? 0 : req.getTimeoutMinutes();
- if (timeoutMinutes <= 0)
- cleanSessions(allSessions, id.str(), userID.str(), fromIP.str());
- else
- {
- StringBuffer searchPath;
- setSessionXPath(allSessions, id.str(), userID.str(), fromIP.str(), searchPath);
- Owned<IRemoteConnection> globalLock = querySDSConnectionForESPSession(RTM_LOCK_WRITE, SESSION_SDS_LOCK_TIMEOUT);
- Owned<IPropertyTreeIterator> iter = globalLock->queryRoot()->getElements("*");
- ForEach(*iter)
- {
- Owned<IPropertyTreeIterator> iter1 = iter->query().getElements(searchPath.str());
- ForEach(*iter1)
- setSessionTimeout(timeoutMinutes, iter1->query());
- }
- }
- resp.setStatus(0);
- resp.setMessage("Session timeout is updated.");
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- const char* CWSESPControlEx::setSessionXPath(bool allSessions, const char* id, const char* userID, const char* fromIP, StringBuffer& xPath)
- {
- if (allSessions)
- {
- xPath.set("*");
- return xPath.str();
- }
- if (!isEmptyString(userID))
- xPath.setf("%s[%s='%s']", PathSessionSession, PropSessionUserID, userID);
- else if (!isEmptyString(fromIP))
- xPath.setf("%s[%s='%s']", PathSessionSession, PropSessionNetworkAddress, fromIP);
- else if (!isEmptyString(id))
- xPath.setf("%s[%s='%s']", PathSessionSession, PropSessionExternalID, id);
- else
- xPath.set("*");
- return xPath.str();
- }
- void CWSESPControlEx::cleanSessions(bool allSessions, const char* _id, const char* _userID, const char* _fromIP)
- {
- StringBuffer searchPath;
- setSessionXPath(allSessions, _id, _userID, _fromIP, searchPath);
- Owned<IRemoteConnection> globalLock = querySDSConnectionForESPSession(RTM_LOCK_WRITE, SESSION_SDS_LOCK_TIMEOUT);
- Owned<IPropertyTreeIterator> iter = globalLock->queryRoot()->getElements("*");
- ForEach(*iter)
- {
- IArrayOf<IPropertyTree> toRemove;
- Owned<IPropertyTreeIterator> iter1 = iter->query().getElements(searchPath.str());
- ForEach(*iter1)
- toRemove.append(*LINK(&iter1->query()));
- ForEachItemIn(i, toRemove)
- iter->query().removeTree(&toRemove.item(i));
- }
- }
- void CWSESPControlEx::setSessionTimeout(int timeoutMinutes, IPropertyTree& session)
- {
- CDateTime timeNow;
- timeNow.setNow();
- time_t simple = timeNow.getSimple() + timeoutMinutes*60;
- session.setPropInt64(PropSessionTimeoutAt, simple);
- session.setPropBool(PropSessionTimeoutByAdmin, true);
- }
|