/esp/services/ws_access/ws_accessService.cpp
http://github.com/hpcc-systems/HPCC-Platform · C++ · 4715 lines · 4004 code · 632 blank · 79 comment · 1079 complexity · fb4b80db762fa919f43758032576b2b8 MD5 · raw file
Large files are truncated click here to view the full file
- /*##############################################################################
- 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.
- ############################################################################## */
- #pragma warning (disable : 4786)
- #include <stdlib.h>
- #include "ws_accessService.hpp"
- #include "exception_util.hpp"
- #include "dasess.hpp"
- #include "dautils.hpp"
- #include <set>
- #define MSG_SEC_MANAGER_IS_NULL "Security manager is not found. Please check if the system authentication is set up correctly"
- #define MSG_SEC_MANAGER_ISNT_LDAP "LDAP Security manager is required for this feature. Please enable LDAP in the system configuration"
- #define FILE_SCOPE_URL "FileScopeAccess"
- #define FILE_SCOPE_RTYPE "file"
- #define FILE_SCOPE_RTITLE "FileScope"
- #define MAX_USERS_DISPLAY 400
- #define MAX_RESOURCES_DISPLAY 3000
- static const long MAXXLSTRANSFER = 5000000;
- void checkUser(IEspContext& context, const char* rtype = NULL, const char* rtitle = NULL, unsigned int SecAccessFlags = SecAccess_Full)
- {
- CLdapSecManager* secmgr = dynamic_cast<CLdapSecManager*>(context.querySecManager());
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- if (rtype && rtitle && strieq(rtype, FILE_SCOPE_RTYPE) && strieq(rtitle, FILE_SCOPE_RTITLE))
- {
- if (!context.validateFeatureAccess(FILE_SCOPE_URL, SecAccessFlags, false))
- {
- context.setAuthStatus(AUTH_STATUS_NOACCESS);
- throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Access to File Scope is denied.");
- }
- return;
- }
- if(!secmgr->isSuperUser(context.queryUser()))
- {
- context.setAuthStatus(AUTH_STATUS_NOACCESS);
- throw MakeStringException(ECLWATCH_ADMIN_ACCESS_DENIED, "Access denied, administrators only.");
- }
- }
- void Cws_accessEx::init(IPropertyTree *cfg, const char *process, const char *service)
- {
- if(cfg == NULL)
- throw MakeStringException(-1, "can't initialize Cws_accessEx, cfg is NULL");
- StringBuffer xpath;
- xpath.appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]", process, service);
- IPropertyTree* servicecfg = cfg->getPropTree(xpath.str());
- if(servicecfg == NULL)
- {
- OWARNLOG("Config not found for service %s/%s",process, service);
- return;
- }
- m_servicecfg.setown(servicecfg);
- /* Config is like -
- <Modules basedn="ou=le,ou=ecl,dc=le">
- <Eclserver name="eclserver" basedn="ou=le,ou=ecl,dc=le" templateName="repository.newmoduletemplate"/>
- </Modules>
- <Files basedn="ou=Files,ou=ecl"/>
- <Resources>
- <Binding name="EspBinding" service="espsmc" port="8010" basedn="ou=SMC,ou=EspServices,ou=ecl" workunitsBasedn="ou=workunits,ou=ecl"/>
- </Resources>
- */
- Owned<IPropertyTreeIterator> eclservers = m_servicecfg->getElements("Modules/Eclserver");
- for (eclservers->first(); eclservers->isValid(); eclservers->next())
- {
- const char *templatename = eclservers->query().queryProp("@templateName");
- const char* basedn = eclservers->query().queryProp("@basedn");
- if(basedn && *basedn)
- {
- StringBuffer name, head;
- const char* eclservername = eclservers->query().queryProp("@name");
- name.append("Repository Modules for ").append(eclservername);
- Owned<IEspDnStruct> onedn = createDnStruct();
- onedn->setBasedn(basedn);
- onedn->setName(name.str());
- onedn->setRtype("module");
- onedn->setRtitle("Module");
- if(templatename != NULL)
- {
- onedn->setTemplatename(templatename);
- }
- m_rawbasedns.append(*onedn.getLink());
- }
- }
- const char* modules_basedn = m_servicecfg->queryProp("Modules/@basedn");
- if(modules_basedn && *modules_basedn)
- {
- Owned<IEspDnStruct> onedn = createDnStruct();
- onedn->setBasedn(modules_basedn);
- onedn->setName("Repository Modules");
- onedn->setRtype("module");
- onedn->setRtitle("Module");
- m_rawbasedns.append(*onedn.getLink());
- }
- const char* files_basedn = m_servicecfg->queryProp("Files/@basedn");
- if(files_basedn && *files_basedn)
- {
- Owned<IEspDnStruct> onedn = createDnStruct();
- onedn->setBasedn(files_basedn);
- onedn->setName("File Scopes");
- onedn->setRtype(FILE_SCOPE_RTYPE);
- m_rawbasedns.append(*onedn.getLink());
- onedn->setRtitle(FILE_SCOPE_RTITLE);
- }
- StringBuffer workunits_basedn;
- Owned<IPropertyTreeIterator> bindings = m_servicecfg->getElements("Resources/Binding");
- for (bindings->first(); bindings->isValid(); bindings->next())
- {
- const char *service = bindings->query().queryProp("@service");
- const char* basedn = bindings->query().queryProp("@basedn");
- if(workunits_basedn.length() == 0)
- {
- const char* wubasedn = bindings->query().queryProp("@workunitsBasedn");
- if(wubasedn != NULL)
- workunits_basedn.append(wubasedn);
- }
- if(basedn && *basedn)
- {
- StringBuffer name, head;
- name.append("Esp Features for ");
- const char* bptr = basedn;
- while(*bptr != '\0' && *bptr != '=')
- bptr++;
- if(*bptr != '\0')
- bptr++;
- const char* colon = strstr(bptr, ",");
- if(colon == NULL)
- head.append(bptr);
- else
- head.append(colon - bptr, bptr);
- if(stricmp(head.str(), "WsAttributesAccess") == 0)
- continue;
- Owned<IEspDnStruct> onedn = createDnStruct();
- onedn->setBasedn(basedn);
- name.append(head.str());
- onedn->setName(name.str());
- onedn->setRtype("service");
- head.append(" Feature");
- onedn->setRtitle(head.str());
- m_rawbasedns.append(*onedn.getLink());
- }
- }
- if(workunits_basedn.length() > 0)
- {
- Owned<IEspDnStruct> onedn = createDnStruct();
- onedn->setBasedn(workunits_basedn.str());
- onedn->setName("Workunit Scopes");
- onedn->setRtype("workunit");
- onedn->setRtitle("WorkunitScope");
- m_rawbasedns.append(*onedn.getLink());
- }
- xpath.setf("Software/EspProcess[@name=\"%s\"]/@PageCacheTimeoutSeconds", process);
- if (cfg->hasProp(xpath.str()))
- setPageCacheTimeoutMilliSeconds(cfg->getPropInt(xpath.str()));
- xpath.setf("Software/EspProcess[@name=\"%s\"]/@MaxPageCacheItems", process);
- if (cfg->hasProp(xpath.str()))
- setMaxPageCacheItems(cfg->getPropInt(xpath.str()));
- }
- CLdapSecManager* Cws_accessEx::queryLDAPSecurityManager(IEspContext &context)
- {
- ISecManager* secMgr = context.querySecManager();
- if(secMgr && secMgr->querySecMgrType() != SMT_LDAP)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_ISNT_LDAP);
- return dynamic_cast<CLdapSecManager*>(secMgr);
- }
- void Cws_accessEx::getBasednReq(IEspContext &context, const char* name, const char* basedn,
- const char* rType, const char* rTitle, IEspDnStruct* dn)
- {
- double version = context.getClientVersion();
- if (version >= 1.14)
- {
- if (isEmptyString(name))
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "BaseDN not specified");
- if(m_basedns.length() == 0)
- setBasedns(context);
- ForEachItemIn(i, m_basedns)
- {
- IEspDnStruct& cur = m_basedns.item(i);
- if(strieq(cur.getName(), name))
- {
- dn->setBasedn(cur.getBasedn());
- dn->setRtype(cur.getRtype());
- dn->setRtitle(cur.getRtitle());
- return;
- }
- }
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "BaseDN %s not found", name);
- }
- //before version 1.14
- if (isEmptyString(basedn))
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "Basedn not specified");
- if (isEmptyString(rType))
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "Rtype not specified");
- if (isEmptyString(rTitle))
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "Rtitle not specified");
- dn->setBasedn(basedn);
- dn->setRtype(rType);
- dn->setRtitle(rTitle);
- }
- void Cws_accessEx::setBasedns(IEspContext &context)
- {
- CLdapSecManager* secmgr = (CLdapSecManager*)(context.querySecManager());
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- set<string> alreadythere;
- ForEachItemInRev(x, m_rawbasedns)
- {
- IEspDnStruct* basedn = &(m_rawbasedns.popGet());
- const char* tname = basedn->getTemplatename();
- StringBuffer nbasedn;
- secmgr->normalizeDn(basedn->getBasedn(), nbasedn);
- if(alreadythere.find(nbasedn.str()) == alreadythere.end())
- {
- alreadythere.insert(nbasedn.str());
- Owned<IEspDnStruct> onedn = createDnStruct();
- onedn->setBasedn(nbasedn.str());
- onedn->setName(basedn->getName());
- onedn->setRtype(basedn->getRtype());
- onedn->setRtitle(basedn->getRtitle());
- if(tname != NULL && *tname != '\0')
- onedn->setTemplatename(tname);
- m_basedns.append(*onedn.getLink());
- }
- else
- {
- ForEachItemIn(y, m_basedns)
- {
- IEspDnStruct* curbasedn = &(m_basedns.item(y));
- if(stricmp(curbasedn->getBasedn(), nbasedn.str()) == 0)
- {
- const char* curtname = curbasedn->getTemplatename();
- if((curtname == NULL || *curtname == '\0') && (tname != NULL && *tname != '\0'))
- curbasedn->setTemplatename(tname);
- break;
- }
- }
- }
- }
- return;
- }
- bool Cws_accessEx::getNewFileScopePermissions(ISecManager* secmgr, const char* name, IEspDnStruct* basednReq, StringBuffer& existingResource, StringArray& newResources)
- {
- if (!secmgr)
- return false;
- if (isEmptyString(name))
- return false;
- char* pStr0 = (char*) name;
- while (pStr0[0] == ':') //in case of some ':' by mistake
- pStr0++;
- if (pStr0[0] == 0)
- return false;
- StringBuffer lastFileScope;
- char* pStr = strstr(pStr0, "::");
- while (pStr)
- {
- char fileScope[10240];
- strncpy(fileScope, pStr0, pStr-pStr0);
- fileScope[pStr-pStr0] = 0;
- if (lastFileScope.length() < 1)
- lastFileScope.append(fileScope);
- else
- lastFileScope.appendf("::%s", fileScope);
- newResources.append(lastFileScope.str());
- pStr0 = pStr+2;
- while (pStr0[0] == ':') //in case of more than two ':' by mistake
- pStr0++;
- if (pStr0[0] == 0)
- break;
- pStr = strstr(pStr0, "::");
- }
- if (pStr0[0] != 0)
- {
- if (lastFileScope.length() < 1)
- lastFileScope.append(pStr0);
- else
- lastFileScope.appendf("::%s", pStr0);
- newResources.append(lastFileScope.str());
- }
- CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
- while (newResources.ordinality())
- {
- StringBuffer namebuf(newResources.item(0));
- try
- {
- IArrayOf<CPermission> permissions;
- ldapsecmgr->getPermissionsArray(basednReq->getBasedn(), str2type(basednReq->getRtype()), namebuf.str(), permissions);
- if (!permissions.ordinality())
- {
- break;
- }
- }
- catch(IException* e) //exception may be thrown when no permission for the resource
- {
- e->Release();
- break;
- }
- existingResource.clear().append(namebuf);
- newResources.remove(0);
- }
- return true;
- }
- bool Cws_accessEx::setNewFileScopePermissions(ISecManager* secmgr, IEspDnStruct* basednReq, StringBuffer& existingResource, StringArray& newResources)
- {
- if (!secmgr || !newResources.ordinality())
- {
- return false;
- }
- const char* basedn = basednReq->getBasedn();
- if (!basedn || !*basedn)
- {
- return false;
- }
- StringBuffer basednBuf;
- basednBuf.append(basedn);
- if (existingResource.length() < 1)
- {
- existingResource.append("files");
- const char* comma = strchr(basedn, ',');
- const char* eqsign = strchr(basedn, '=');
- if(eqsign && comma && (strlen(comma) > 1))
- {
- basednBuf.clear().append(comma + 1);
- }
- }
- IArrayOf<CPermission> requiredPermissions;
- CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
- ldapsecmgr->getPermissionsArray(basednBuf, str2type(basednReq->getRtype()), existingResource.str(), requiredPermissions);
- if (!requiredPermissions.ordinality())
- {
- return false;
- }
- ForEachItemIn(x, requiredPermissions)
- {
- CPermission& perm = requiredPermissions.item(x);
- int accType = perm.getAccount_type(); //0-individual, 1 - group
- const char* actname = perm.getAccount_name();
- if (!actname || !*actname)
- continue;
- CPermissionAction paction;
- paction.m_basedn.append(basednReq->getBasedn());
- paction.m_rtype = str2type(basednReq->getRtype());
- paction.m_account_type = (ACT_TYPE)accType;
- paction.m_account_name.append(actname);
- paction.m_allows = perm.getAllows();
- paction.m_denies = perm.getDenies();
- if ((accType != GROUP_ACT) || ((stricmp(actname, "Administrators") != 0) && (stricmp(actname, "Authenticated Users") != 0)))
- {
- paction.m_action.append("add");
- }
- else
- {
- paction.m_action.append("update");
- }
- ForEachItemIn(y, newResources)
- {
- StringBuffer namebuf(newResources.item(y));
- paction.m_rname.clear().append(namebuf.str());
- ldapsecmgr->changePermission(paction);
- }
- }
- return true;
- }
- bool Cws_accessEx::onUsers(IEspContext &context, IEspUserRequest &req, IEspUserResponse &resp)
- {
- try
- {
- CLdapSecManager* secmgr = queryLDAPSecurityManager(context);
- double version = context.getClientVersion();
- if (version > 1.03)
- {
- if(secmgr == NULL)
- {
- resp.setNoSecMngr(true);
- return true;
- }
- }
- else
- {
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- }
- checkUser(context);
- const char* searchstr = req.getSearchinput();
- int numusers = secmgr->countUsers(searchstr, MAX_USERS_DISPLAY);
- if(numusers == -1)
- {
- resp.setToomany(true);
- return true;
- }
- resp.setToomany(false);
- /*
- LdapServerType servertype = secmgr->getLdapServerType();
- if(servertype != ACTIVE_DIRECTORY)
- resp.setPosixok(true);
- else
- resp.setPosixok(false);
- */
- resp.setPosixok(false);
- IArrayOf<IEspUserInfo> espusers;
- IUserArray users;
- secmgr->searchUsers(searchstr, users);
- ForEachItemIn(x, users)
- {
- ISecUser* usr = &users.item(x);
- if(usr)
- {
- Owned<IEspUserInfo> oneusr = createUserInfo();
- oneusr->setUsername(usr->getName());
- oneusr->setFullname(usr->getFullName());
- double version = context.getClientVersion();
- if (version >= 1.10)
- {
- oneusr->setEmployeeID(usr->getEmployeeID());
- }
- if (version >= 1.07)
- {
- StringBuffer sb;
- oneusr->setPasswordexpiration(getPasswordExpiration(usr, sb));
- }
- if (version >= 1.16)
- {
- oneusr->setEmployeeNumber(usr->getEmployeeNumber());
- }
- espusers.append(*oneusr.getLink());
- }
- }
- resp.setUsers(espusers);
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- const char *Cws_accessEx::getPasswordExpiration(ISecUser *usr, StringBuffer &passwordExpiration)
- {
- switch (usr->getPasswordDaysRemaining())//-1 if expired, -2 if never expires
- {
- case scPasswordExpired:
- passwordExpiration.set("Expired");
- break;
- case scPasswordNeverExpires:
- passwordExpiration.set("Never");
- break;
- default:
- {
- CDateTime dt;
- usr->getPasswordExpiration(dt);
- dt.getDateString(passwordExpiration);
- break;
- }
- }
- return passwordExpiration.str();
- }
- bool Cws_accessEx::onUserQuery(IEspContext &context, IEspUserQueryRequest &req, IEspUserQueryResponse &resp)
- {
- try
- {
- CLdapSecManager* secmgr = queryLDAPSecurityManager(context);
- if(!secmgr)
- {
- resp.setNoSecMngr(true);
- return true;
- }
- checkUser(context);
- __int64 pageStartFrom = 0;
- unsigned pageSize = 100;
- if (!req.getPageSize_isNull())
- pageSize = req.getPageSize();
- if (!req.getPageStartFrom_isNull())
- pageStartFrom = req.getPageStartFrom();
- UserField sortOrder[2] = {UFName, UFterm};
- CUserSortBy sortBy = req.getSortBy();
- switch (sortBy)
- {
- case CUserSortBy_FullName:
- sortOrder[0] = UFFullName;
- break;
- case CUserSortBy_PasswordExpiration:
- sortOrder[0] = UFPasswordExpiration;
- break;
- case CUserSortBy_EmployeeID:
- sortOrder[0] = UFEmployeeID;
- break;
- case CUserSortBy_EmployeeNumber:
- sortOrder[0] = UFEmployeeNumber;
- break;
- default:
- break;
- }
- sortOrder[0] = (UserField) (sortOrder[0] | UFnocase);
- bool descending = req.getDescending();
- if (descending)
- sortOrder[0] = (UserField) (sortOrder[0] | UFreverse);
- unsigned total;
- __int64 cacheHint;
- IArrayOf<IEspUserInfo> espUsers;
- Owned<ISecItemIterator> it = secmgr->getUsersSorted(req.getName(), sortOrder, (const __int64) pageStartFrom, (const unsigned) pageSize, &total, &cacheHint);
- ForEach(*it)
- {
- IPropertyTree& usr = it->query();
- const char* userName = usr.queryProp(getUserFieldNames(UFName));
- if (!userName || !*userName)
- continue;
- Owned<IEspUserInfo> userInfo = createUserInfo();
- userInfo->setUsername(userName);
- const char* fullName = usr.queryProp(getUserFieldNames(UFFullName));
- if (fullName && *fullName)
- userInfo->setFullname(fullName);
- const char* passwordExpiration = usr.queryProp(getUserFieldNames(UFPasswordExpiration));
- if (passwordExpiration && *passwordExpiration)
- userInfo->setPasswordexpiration(passwordExpiration);
- const char* employeeID = usr.queryProp(getUserFieldNames(UFEmployeeID));
- if (employeeID && *employeeID)
- userInfo->setEmployeeID(employeeID);
- const char* employeeNumber = usr.queryProp(getUserFieldNames(UFEmployeeNumber));
- if (employeeNumber && *employeeNumber)
- userInfo->setEmployeeNumber(employeeNumber);
- espUsers.append(*userInfo.getClear());
- }
- resp.setUsers(espUsers);
- resp.setTotalUsers(total);
- resp.setCacheHint(cacheHint);
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool Cws_accessEx::onUserEdit(IEspContext &context, IEspUserEditRequest &req, IEspUserEditResponse &resp)
- {
- try
- {
- checkUser(context);
- ISecManager* secmgr = context.querySecManager();
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
- resp.setUsername(req.getUsername());
- double version = context.getClientVersion();
- if (version >= 1.13)
- resp.setIsLDAPAdmin(ldapsecmgr->isSuperUser(context.queryUser()));
- StringArray groupnames;
- ldapsecmgr->getGroups(req.getUsername(), groupnames);
- IArrayOf<IEspGroupInfo> groups;
- for(unsigned i = 0; i < groupnames.length(); i++)
- {
- const char* grpname = groupnames.item(i);
- if(grpname == NULL || grpname[0] == '\0')
- continue;
- Owned<IEspGroupInfo> onegrp = createGroupInfo();
- onegrp->setName(grpname);
- groups.append(*onegrp.getLink());
- }
- resp.setGroups(groups);
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool Cws_accessEx::onUserGroupEditInput(IEspContext &context, IEspUserGroupEditInputRequest &req, IEspUserGroupEditInputResponse &resp)
- {
- try
- {
- checkUser(context);
- ISecManager* secmgr = context.querySecManager();
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
- resp.setUsername(req.getUsername());
- set<string> ogrps;
- ogrps.insert("Authenticated Users");
- StringArray grps;
- ldapsecmgr->getGroups(req.getUsername(), grps);
- unsigned i = 0;
- for(i = 0; i < grps.length(); i++)
- {
- const char* grp = grps.item(i);
- if(grp != NULL && *grp != '\0')
- {
- ogrps.insert(grp);
- }
- }
- StringArray groupnames;
- StringArray managedBy;
- StringArray descriptions;
- ldapsecmgr->getAllGroups(groupnames, managedBy, descriptions);
- IArrayOf<IEspGroupInfo> groups;
- for(i = 0; i < groupnames.length(); i++)
- {
- const char* grpname = groupnames.item(i);
- if(grpname == NULL || grpname[0] == '\0')
- continue;
- if(ogrps.find(grpname) == ogrps.end())
- {
- Owned<IEspGroupInfo> onegrp = createGroupInfo();
- onegrp->setName(grpname);
- onegrp->setGroupDesc(descriptions.item(i));
- onegrp->setGroupOwner(managedBy.item(i));
- groups.append(*onegrp.getLink());
- }
- }
- resp.setGroups(groups);
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool Cws_accessEx::onUserGroupEdit(IEspContext &context, IEspUserGroupEditRequest &req, IEspUserGroupEditResponse &resp)
- {
- try
- {
- checkUser(context);
- CLdapSecManager* secmgr = (CLdapSecManager*)(context.querySecManager());
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- const char* username = req.getUsername();
- if(username == NULL || *username == '\0')
- {
- resp.setRetcode(-1);
- resp.setRetmsg("username can't be empty");
- return false;
- }
- StringArray& groupnames = req.getGroupnames();
- try
- {
- for(unsigned i = 0; i < groupnames.length(); i++)
- {
- const char* grpname = groupnames.item(i);
- if(grpname == NULL || *grpname == '\0')
- continue;
- secmgr->changeUserGroup(req.getAction(), username, grpname);
- }
- }
- catch(IException* e)
- {
- StringBuffer errmsg;
- e->errorMessage(errmsg);
- OERRLOG("error changing user's group membership: %s", errmsg.str());
- resp.setRetcode(e->errorCode());
- resp.setRetmsg(errmsg.str());
- return false;
- }
- resp.setRetcode(0);
- resp.setUsername(username);
- resp.setAction(req.getAction());
- if(stricmp(req.getAction(), "add") == 0)
- resp.setRetmsg("user successfully added to groups");
- else
- resp.setRetmsg("user successfully deleted from groups");
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool Cws_accessEx::onGroups(IEspContext &context, IEspGroupRequest &req, IEspGroupResponse &resp)
- {
- try
- {
- CLdapSecManager* secmgr0 = queryLDAPSecurityManager(context);
- double version = context.getClientVersion();
- if (version > 1.03)
- {
- if(secmgr0 == NULL)
- {
- //throw MakeStringException(-1, "SecManager is NULL, please check if the binding's authentication is set up correctly");
- resp.setNoSecMngr(true);
- return true;
- }
- }
- checkUser(context);
- StringArray groupnames;
- StringArray groupManagedBy;
- StringArray groupDescriptions;
- ISecManager* secmgr = context.querySecManager();
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- secmgr->getAllGroups(groupnames, groupManagedBy, groupDescriptions);
- ///groupnames.append("Administrators");
- ///groupnames.append("Full_Access_TestingOnly");
- //groupnames.kill();
- if (groupnames.length() > 0)
- {
- IArrayOf<IEspGroupInfo> groups;
- for(unsigned i = 0; i < groupnames.length(); i++)
- {
- const char* grpname = groupnames.item(i);
- //if(grpname == NULL || grpname[0] == '\0' || stricmp(grpname, "Authenticated Users") == 0)
- if(grpname == NULL || grpname[0] == '\0')
- continue;
- Owned<IEspGroupInfo> onegrp = createGroupInfo();
- onegrp->setName(grpname);
- onegrp->setGroupDesc(groupDescriptions.item(i));
- onegrp->setGroupOwner(groupManagedBy.item(i));
- groups.append(*onegrp.getLink());
- }
- resp.setGroups(groups);
- }
- /*
- IArrayOf<IEspGroupInfo> groups;
- Owned<IEspGroupInfo> onegrp = createGroupInfo();
- onegrp->setName("grpname");
- groups.append(*onegrp.getLink());
- resp.setGroups(groups);
- */
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool Cws_accessEx::onGroupQuery(IEspContext &context, IEspGroupQueryRequest &req, IEspGroupQueryResponse &resp)
- {
- try
- {
- CLdapSecManager* secmgr = queryLDAPSecurityManager(context);
- if(!secmgr)
- {
- resp.setNoSecMngr(true);
- return true;
- }
- checkUser(context);
- __int64 pageStartFrom = 0;
- unsigned pageSize = 100;
- if (!req.getPageSize_isNull())
- pageSize = req.getPageSize();
- if (!req.getPageStartFrom_isNull())
- pageStartFrom = req.getPageStartFrom();
- GroupField sortOrder[2] = {GFName, GFterm};
- CGroupSortBy sortBy = req.getSortBy();
- switch (sortBy)
- {
- case CGroupSortBy_ManagedBy:
- sortOrder[0] = GFManagedBy;
- break;
- default:
- break;
- }
- sortOrder[0] = (GroupField) (sortOrder[0] | GFnocase);
- bool descending = req.getDescending();
- if (descending)
- sortOrder[0] = (GroupField) (sortOrder[0] | GFreverse);
- unsigned total;
- __int64 cacheHint;
- IArrayOf<IEspGroupInfo> groups;
- Owned<ISecItemIterator> it = secmgr->getGroupsSorted(sortOrder, (const __int64) pageStartFrom, (const unsigned) pageSize, &total, &cacheHint);
- ForEach(*it)
- {
- IPropertyTree& g = it->query();
- const char* groupName = g.queryProp(getGroupFieldNames(GFName));
- if (!groupName || !*groupName)
- continue;
- Owned<IEspGroupInfo> groupInfo = createGroupInfo();
- groupInfo->setName(groupName);
- const char* managedBy = g.queryProp(getGroupFieldNames(GFManagedBy));
- if (managedBy && *managedBy)
- groupInfo->setGroupOwner(managedBy);
- const char* desc = g.queryProp(getGroupFieldNames(GFDesc));
- if (desc && *desc)
- groupInfo->setGroupDesc(desc);
- groups.append(*groupInfo.getClear());
- }
- resp.setGroups(groups);
- resp.setTotalGroups(total);
- resp.setCacheHint(cacheHint);
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool Cws_accessEx::onAddUser(IEspContext &context, IEspAddUserRequest &req, IEspAddUserResponse &resp)
- {
- try
- {
- checkUser(context);
- ISecManager* secmgr = context.querySecManager();
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- const char* username = req.getUsername();
- if(username == NULL || *username == '\0')
- {
- resp.setRetcode(-1);
- resp.setRetmsg("username can't be empty");
- return false;
- }
- if(strchr(username, ' '))
- {
- resp.setRetcode(-1);
- resp.setRetmsg("Username can't contain spaces");
- return false;
- }
- CLdapSecManager* secmgr0 = (CLdapSecManager*)secmgr;
- if((secmgr0->getLdapServerType() == ACTIVE_DIRECTORY) && (strlen(username) > 20))
- {
- resp.setRetcode(-1);
- resp.setRetmsg("Username can't be more than 20 characters.");
- return false;
- }
- const char* pass1 = req.getPassword1();
- const char* pass2 = req.getPassword2();
- if(pass1 == NULL || pass2 == NULL || *pass1 == '\0' || *pass2 == '\0' || strcmp(pass1, pass2) != 0)
- {
- resp.setRetcode(-1);
- resp.setRetmsg("password and retype can't be empty and must match.");
- return false;
- }
- const char * employeeID = NULL;
- if (context.getClientVersion() >= 1.10)
- {
- employeeID = req.getEmployeeID();
- }
- const char * employeeNumber = nullptr;
- if (context.getClientVersion() >= 1.16)
- {
- employeeNumber = req.getEmployeeNumber();
- }
- Owned<ISecUser> user = secmgr->createUser(username);
- ISecCredentials& cred = user->credentials();
- const char* firstname = req.getFirstname();
- const char* lastname = req.getLastname();
- if(firstname != NULL)
- user->setFirstName(firstname);
- if(lastname != NULL)
- user->setLastName(lastname);
- if(employeeID != NULL)
- user->setEmployeeID(employeeID);
- if(employeeNumber != nullptr)
- user->setEmployeeNumber(employeeNumber);
- if(pass1 != NULL)
- cred.setPassword(pass1);
- try
- {
- if (user.get())
- secmgr->addUser(*user.get());
- }
- catch(IException* e)
- {
- resp.setRetcode(-1);
- StringBuffer errmsg;
- resp.setRetmsg(e->errorMessage(errmsg).str());
- return false;
- }
- resp.setRetcode(0);
- resp.setRetmsg("User successfully added");
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool Cws_accessEx::onUserAction(IEspContext &context, IEspUserActionRequest &req, IEspUserActionResponse &resp)
- {
- try
- {
- checkUser(context);
- CLdapSecManager* secmgr = (CLdapSecManager*)(context.querySecManager());
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- const char* action = req.getActionType();
- if (!action || !*action)
- throw MakeStringException(ECLWATCH_INVALID_ACTION, "Action not specified.");
- if (!stricmp(action, "delete"))
- {
- StringArray& usernames = req.getUsernames();
- for(unsigned i = 0; i < usernames.length(); i++)
- {
- const char* username = usernames.item(i);
- Owned<ISecUser> user = secmgr->createUser(username);
- secmgr->deleteUser(user.get());
- }
- }
- else if (!stricmp(action, "export"))
- {
- StringBuffer users;
- StringArray& usernames = req.getUsernames();
- for(unsigned i = 0; i < usernames.length(); i++)
- {
- const char* username = usernames.item(i);
- if (i > 0)
- users.appendf("&usernames_i%d=%s", i+1, username);
- else
- users.append(username);
- }
- resp.setRedirectUrl(StringBuffer("/ws_access/UserAccountExport?usernames_i1=").append(users).str());
- }
- resp.setAction(action);
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool Cws_accessEx::onGroupAdd(IEspContext &context, IEspGroupAddRequest &req, IEspGroupAddResponse &resp)
- {
- try
- {
- checkUser(context);
- CLdapSecManager* secmgr = (CLdapSecManager*)(context.querySecManager());
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- const char* groupname = req.getGroupname();
- if(groupname == NULL || *groupname == '\0')
- {
- resp.setRetcode(-1);
- resp.setRetmsg("Group name can't be empty");
- return false;
- }
- resp.setGroupname(groupname);
- double version = context.getClientVersion();
- const char * groupDesc = NULL;
- const char * groupOwner = NULL;
- if (version >= 1.09)
- {
- groupDesc = req.getGroupDesc();
- groupOwner = req.getGroupOwner();
- }
- try
- {
- secmgr->addGroup(groupname, groupOwner, groupDesc);
- }
- catch(IException* e)
- {
- StringBuffer emsg;
- e->errorMessage(emsg);
- resp.setRetcode(e->errorCode());
- resp.setRetmsg(emsg.str());
- return false;
- }
- catch(...)
- {
- resp.setRetcode(-1);
- resp.setRetmsg("Unknown error");
- return false;
- }
- resp.setRetcode(0);
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool Cws_accessEx::onGroupAction(IEspContext &context, IEspGroupActionRequest &req, IEspGroupActionResponse &resp)
- {
- try
- {
- checkUser(context);
- CLdapSecManager* secmgr = queryLDAPSecurityManager(context);
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- const char* action = req.getActionType();
- if (!action || !*action)
- throw MakeStringException(ECLWATCH_INVALID_ACTION, "Action not specified.");
- if (!stricmp(action, "export"))
- {
- StringBuffer groups;
- StringArray& groupnames = req.getGroupnames();
- for(unsigned i = 0; i < groupnames.length(); i++)
- {
- const char* group = groupnames.item(i);
- if (i > 0)
- groups.appendf("&groupnames_i%d=%s", i+1, group);
- else
- groups.append(group);
- }
- resp.setRedirectUrl(StringBuffer("/ws_access/UserAccountExport?groupnames_i1=").append(groups).str());
- }
- else if (!stricmp(action, "delete"))
- {
- CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
- StringArray& groupnames = req.getGroupnames();
- IArrayOf<IEspAccountPermission> accountPermissions;
- double version = context.getClientVersion();
- if (version > 1.01)
- {
- bool bDeletePermission = false;
- if(!req.getDeletePermission_isNull())
- bDeletePermission = req.getDeletePermission();
- if(m_basedns.length() == 0)
- {
- setBasedns(context);
- }
- ForEachItemIn(y, m_basedns)
- {
- IEspDnStruct* curbasedn = &(m_basedns.item(y));
- const char *basednName = curbasedn->getName();
- const char *aBasedn = curbasedn->getBasedn();
- const char *aRtype = curbasedn->getRtype();
- if (!aBasedn || !*aBasedn ||!aRtype || !*aRtype)
- continue;
- SecResourceType rtype = str2type(aRtype);
- IArrayOf<IEspResource> ResourceArray;
- if(rtype == RT_WORKUNIT_SCOPE)
- {
- StringBuffer deft_basedn, deft_name;
- const char* comma = strchr(aBasedn, ',');
- const char* eqsign = strchr(aBasedn, '=');
- if(eqsign != NULL)
- {
- if(comma == NULL)
- deft_name.append(eqsign+1);
- else
- {
- deft_name.append(comma - eqsign - 1, eqsign+1);
- deft_basedn.append(comma + 1);
- }
- }
- if (deft_name.length() > 0)
- {
- Owned<IEspResource> oneresource = createResource();
- oneresource->setName(deft_name);
- oneresource->setDescription(deft_basedn);
- ResourceArray.append(*oneresource.getLink());
- }
- }
- IArrayOf<ISecResource> resources;
- if(secmgr->getResources(rtype, aBasedn, resources))
- {
- ForEachItemIn(y1, resources)
- {
- ISecResource& r = resources.item(y1);
- const char* rname = r.getName();
- if(rname == NULL || *rname == '\0')
- continue;
- Owned<IEspResource> oneresource = createResource();
- oneresource->setName(rname);
- oneresource->setDescription(aBasedn);
- ResourceArray.append(*oneresource.getLink());
- }
- }
- ForEachItemIn(y2, ResourceArray)
- {
- IEspResource& r = ResourceArray.item(y2);
- const char* resourceName = r.getName();
- const char* bnname = r.getDescription();
- if (isEmptyString(resourceName))
- continue;
- try
- {
- IArrayOf<CPermission> permissions;
- ldapsecmgr->getPermissionsArray(bnname, rtype, resourceName, permissions);
- ForEachItemIn(x, permissions)
- {
- CPermission& perm = permissions.item(x);
- const char* actname = perm.getAccount_name();
- int accountType = perm.getAccount_type(); //0-individual, 1 - group
- //if ((bGroupAccount && accountType < 1) || (!bGroupAccount && accountType > 0))
- if (accountType < 1 || !actname || !*actname) //Support Group only
- continue;
- ForEachItemIn(x1, groupnames)
- {
- const char* groupname = groupnames.item(x1);
- if (groupname && !strcmp(actname, groupname))
- {
- ///bDeletePermission = true;
- if (!bDeletePermission)
- {
- Owned<IEspAccountPermission> onepermission = createAccountPermission();
- if (version < 1.15)
- {
- onepermission->setBasedn(bnname);
- onepermission->setRType(aRtype);
- }
- else
- {
- onepermission->setBasednName(basednName);
- }
- onepermission->setResourceName(resourceName);
- onepermission->setPermissionName(groupname);
- accountPermissions.append(*onepermission.getLink());
- }
- else
- {
- CPermissionAction paction;
- paction.m_basedn.append(bnname);
- paction.m_rtype = rtype;
- paction.m_rname.append(resourceName);
- paction.m_account_name.append(actname);
- paction.m_account_type = (ACT_TYPE) accountType;
- paction.m_allows = perm.getAllows();
- paction.m_denies = perm.getDenies();
- paction.m_action.append("delete");
- if(!ldapsecmgr->changePermission(paction))
- {
- resp.setRetcode(-1);
- resp.setRetmsg("Unknown error");
- return false;
- }
- }
- break;
- }
- }
- }
- }
- catch(IException* e)
- {
- e->Release();
- }
- }
- }
- }
- try
- {
- if (accountPermissions.length() < 1)
- {
- ForEachItemIn(x1, groupnames)
- {
- const char* groupname = groupnames.item(x1);
- secmgr->deleteGroup(groupname);
- }
- }
- else
- {
- StringBuffer groupnamestr;
- groupnamestr.append("DeletePermission=1");
- ForEachItemIn(x1, groupnames)
- {
- const char* groupname = groupnames.item(x1);
- groupnamestr.appendf("&groupnames_i%d=%s", x1+1, groupname);
- }
- resp.setPermissions(accountPermissions);
- resp.setGroupnames(groupnamestr.str());
- resp.setRetcode(0);
- }
- }
- catch(IException* e)
- {
- StringBuffer emsg;
- e->errorMessage(emsg);
- resp.setRetcode(e->errorCode());
- resp.setRetmsg(emsg.str());
- return false;
- }
- catch(...)
- {
- resp.setRetcode(-1);
- resp.setRetmsg("Unknown error");
- return false;
- }
- }
- resp.setRetcode(0);
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool Cws_accessEx::onGroupEdit(IEspContext &context, IEspGroupEditRequest &req, IEspGroupEditResponse &resp)
- {
- try
- {
- checkUser(context);
- ISecManager* secmgr = context.querySecManager();
- if(secmgr == NULL)
- throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
- CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
- resp.setGroupname(req.getGroupname());
- StringArray usernames;
- ldapsecmgr->getGroupMembers(req.getGroupname(), usernames);
- IArrayOf<IEspUserInfo> users;
- unsigned i = 0;
- for(i = 0; i < usernames.length(); i++)
- {
- const char* usrname = usernames.item(i);
- if(usrname == NULL || usrname[0] == '\0')
- continue;
- ///////////////////////////////////////BUG#41536///////////////
- bool bFound = false;
- IUserArray usersInBaseDN;
- ldapsecmgr->searchUsers(usrname, usersInBaseDN);
- ForEachItemIn(x, usersInBaseDN)
- {
- ISecUser* usr = &usersInBaseDN.item(x);
- if(usr)
- {
- const char* usrname = usr->getName();
- if(usrname == NULL || usrname[0] == '\0')
- continue;
- bFound = true;
- break;
- }
- }
- if (!bFound)
- continue;
- //////////////////////////////////////////////////////////////
- Owned<IEspUserInfo> oneusr = createUserInfo();
- oneusr->setUsername(usrname);
- users.append(*oneusr.getLink());
- }
- resp.setUsers(users);
- }
- catch(IException* e)
- {
- FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
- }
- return true;
- }
- bool Cws_accessEx::onGroupMemberQuery(IEspContext &context, IEspGroupMemberQueryRequest &req, IEspGroupMemberQueryResponse &resp)
- {
- try
- {
- CLdapSecManager* secmgr = queryLDAPSecurityManager(context);
- if(!secmgr)
- {
- resp.setNoSecMngr(true);
- return true;
- }
- checkUser(context);
- __int64 pageStartFrom = 0;
- unsigned pageSize = 100;
- if (!req.getPageSize_isNull())
- pageSize = req.getPageSize();
- if (!req.getPageStartFrom_isNull())
- pageStartFrom = req.getPageStartFrom();
- UserField sortOrder[2] = {UFName, UFterm};
- CUserSortBy sortBy = req.getSortBy();
- switch (sortBy)
- {
- case CUserSortBy_FullName:
- sortOrder[0] = UFFullName;
- break;
- case CUserSortBy_PasswordExpiration:
- sortOrder[0] = UFPasswordExpiration;
- break;
- case CUserSortBy_EmployeeID:
- sortOrder[0] = UFEmployeeID;
- break;
- case CUserSortBy_EmployeeNumber:
- sortOrder[0] = UFEmployeeNumber;
- break;
- default:
- break;
- }
- sortOrder[0] = (UserField) (sortOrder[0] | UFnocase);
- bool descending = req.getDescending();
- if (descending)
- sortOrder[0] = (UserField) (sortOrder[0] | UFreverse);
- unsigned total;
- __int64 cacheHint;
- IArrayOf<IEspUserInfo> users;
- Owned<ISecItemIterator> it = secmgr->getGroupMembersSorted(req.getGroupName(), sortOrder, (const __int64) pageStartFrom, (const unsigned) pageSize, &total, &cacheHint);
- ForEach(*it)
- {
- IPropertyTree& usr = it->query();
- const char* userName = usr.queryProp(getUserFieldNames(UFName));
- if (!userName || !*userName)
- continue;
- Owned<IEspUserInfo> userInfo = createUserInfo();
- userInfo->setUsername(userName);
- const char* fullName = usr.queryProp(getUserFieldNames(UFFullName));
- if (fullName && *fullName)
- userInfo->setFullname(fullName);
- const char* passwordExpiration = usr.queryProp(getUserFieldNames(UFPasswordExpiration));
- if (passwordExpiration && *passwordExpiration)
- us…