/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

  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. #pragma warning (disable : 4786)
  14. #include <stdlib.h>
  15. #include "ws_accessService.hpp"
  16. #include "exception_util.hpp"
  17. #include "dasess.hpp"
  18. #include "dautils.hpp"
  19. #include <set>
  20. #define MSG_SEC_MANAGER_IS_NULL "Security manager is not found. Please check if the system authentication is set up correctly"
  21. #define MSG_SEC_MANAGER_ISNT_LDAP "LDAP Security manager is required for this feature. Please enable LDAP in the system configuration"
  22. #define FILE_SCOPE_URL "FileScopeAccess"
  23. #define FILE_SCOPE_RTYPE "file"
  24. #define FILE_SCOPE_RTITLE "FileScope"
  25. #define MAX_USERS_DISPLAY 400
  26. #define MAX_RESOURCES_DISPLAY 3000
  27. static const long MAXXLSTRANSFER = 5000000;
  28. void checkUser(IEspContext& context, const char* rtype = NULL, const char* rtitle = NULL, unsigned int SecAccessFlags = SecAccess_Full)
  29. {
  30. CLdapSecManager* secmgr = dynamic_cast<CLdapSecManager*>(context.querySecManager());
  31. if(secmgr == NULL)
  32. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  33. if (rtype && rtitle && strieq(rtype, FILE_SCOPE_RTYPE) && strieq(rtitle, FILE_SCOPE_RTITLE))
  34. {
  35. if (!context.validateFeatureAccess(FILE_SCOPE_URL, SecAccessFlags, false))
  36. {
  37. context.setAuthStatus(AUTH_STATUS_NOACCESS);
  38. throw MakeStringException(ECLWATCH_DFU_WU_ACCESS_DENIED, "Access to File Scope is denied.");
  39. }
  40. return;
  41. }
  42. if(!secmgr->isSuperUser(context.queryUser()))
  43. {
  44. context.setAuthStatus(AUTH_STATUS_NOACCESS);
  45. throw MakeStringException(ECLWATCH_ADMIN_ACCESS_DENIED, "Access denied, administrators only.");
  46. }
  47. }
  48. void Cws_accessEx::init(IPropertyTree *cfg, const char *process, const char *service)
  49. {
  50. if(cfg == NULL)
  51. throw MakeStringException(-1, "can't initialize Cws_accessEx, cfg is NULL");
  52. StringBuffer xpath;
  53. xpath.appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]", process, service);
  54. IPropertyTree* servicecfg = cfg->getPropTree(xpath.str());
  55. if(servicecfg == NULL)
  56. {
  57. OWARNLOG("Config not found for service %s/%s",process, service);
  58. return;
  59. }
  60. m_servicecfg.setown(servicecfg);
  61. /* Config is like -
  62. <Modules basedn="ou=le,ou=ecl,dc=le">
  63. <Eclserver name="eclserver" basedn="ou=le,ou=ecl,dc=le" templateName="repository.newmoduletemplate"/>
  64. </Modules>
  65. <Files basedn="ou=Files,ou=ecl"/>
  66. <Resources>
  67. <Binding name="EspBinding" service="espsmc" port="8010" basedn="ou=SMC,ou=EspServices,ou=ecl" workunitsBasedn="ou=workunits,ou=ecl"/>
  68. </Resources>
  69. */
  70. Owned<IPropertyTreeIterator> eclservers = m_servicecfg->getElements("Modules/Eclserver");
  71. for (eclservers->first(); eclservers->isValid(); eclservers->next())
  72. {
  73. const char *templatename = eclservers->query().queryProp("@templateName");
  74. const char* basedn = eclservers->query().queryProp("@basedn");
  75. if(basedn && *basedn)
  76. {
  77. StringBuffer name, head;
  78. const char* eclservername = eclservers->query().queryProp("@name");
  79. name.append("Repository Modules for ").append(eclservername);
  80. Owned<IEspDnStruct> onedn = createDnStruct();
  81. onedn->setBasedn(basedn);
  82. onedn->setName(name.str());
  83. onedn->setRtype("module");
  84. onedn->setRtitle("Module");
  85. if(templatename != NULL)
  86. {
  87. onedn->setTemplatename(templatename);
  88. }
  89. m_rawbasedns.append(*onedn.getLink());
  90. }
  91. }
  92. const char* modules_basedn = m_servicecfg->queryProp("Modules/@basedn");
  93. if(modules_basedn && *modules_basedn)
  94. {
  95. Owned<IEspDnStruct> onedn = createDnStruct();
  96. onedn->setBasedn(modules_basedn);
  97. onedn->setName("Repository Modules");
  98. onedn->setRtype("module");
  99. onedn->setRtitle("Module");
  100. m_rawbasedns.append(*onedn.getLink());
  101. }
  102. const char* files_basedn = m_servicecfg->queryProp("Files/@basedn");
  103. if(files_basedn && *files_basedn)
  104. {
  105. Owned<IEspDnStruct> onedn = createDnStruct();
  106. onedn->setBasedn(files_basedn);
  107. onedn->setName("File Scopes");
  108. onedn->setRtype(FILE_SCOPE_RTYPE);
  109. m_rawbasedns.append(*onedn.getLink());
  110. onedn->setRtitle(FILE_SCOPE_RTITLE);
  111. }
  112. StringBuffer workunits_basedn;
  113. Owned<IPropertyTreeIterator> bindings = m_servicecfg->getElements("Resources/Binding");
  114. for (bindings->first(); bindings->isValid(); bindings->next())
  115. {
  116. const char *service = bindings->query().queryProp("@service");
  117. const char* basedn = bindings->query().queryProp("@basedn");
  118. if(workunits_basedn.length() == 0)
  119. {
  120. const char* wubasedn = bindings->query().queryProp("@workunitsBasedn");
  121. if(wubasedn != NULL)
  122. workunits_basedn.append(wubasedn);
  123. }
  124. if(basedn && *basedn)
  125. {
  126. StringBuffer name, head;
  127. name.append("Esp Features for ");
  128. const char* bptr = basedn;
  129. while(*bptr != '\0' && *bptr != '=')
  130. bptr++;
  131. if(*bptr != '\0')
  132. bptr++;
  133. const char* colon = strstr(bptr, ",");
  134. if(colon == NULL)
  135. head.append(bptr);
  136. else
  137. head.append(colon - bptr, bptr);
  138. if(stricmp(head.str(), "WsAttributesAccess") == 0)
  139. continue;
  140. Owned<IEspDnStruct> onedn = createDnStruct();
  141. onedn->setBasedn(basedn);
  142. name.append(head.str());
  143. onedn->setName(name.str());
  144. onedn->setRtype("service");
  145. head.append(" Feature");
  146. onedn->setRtitle(head.str());
  147. m_rawbasedns.append(*onedn.getLink());
  148. }
  149. }
  150. if(workunits_basedn.length() > 0)
  151. {
  152. Owned<IEspDnStruct> onedn = createDnStruct();
  153. onedn->setBasedn(workunits_basedn.str());
  154. onedn->setName("Workunit Scopes");
  155. onedn->setRtype("workunit");
  156. onedn->setRtitle("WorkunitScope");
  157. m_rawbasedns.append(*onedn.getLink());
  158. }
  159. xpath.setf("Software/EspProcess[@name=\"%s\"]/@PageCacheTimeoutSeconds", process);
  160. if (cfg->hasProp(xpath.str()))
  161. setPageCacheTimeoutMilliSeconds(cfg->getPropInt(xpath.str()));
  162. xpath.setf("Software/EspProcess[@name=\"%s\"]/@MaxPageCacheItems", process);
  163. if (cfg->hasProp(xpath.str()))
  164. setMaxPageCacheItems(cfg->getPropInt(xpath.str()));
  165. }
  166. CLdapSecManager* Cws_accessEx::queryLDAPSecurityManager(IEspContext &context)
  167. {
  168. ISecManager* secMgr = context.querySecManager();
  169. if(secMgr && secMgr->querySecMgrType() != SMT_LDAP)
  170. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_ISNT_LDAP);
  171. return dynamic_cast<CLdapSecManager*>(secMgr);
  172. }
  173. void Cws_accessEx::getBasednReq(IEspContext &context, const char* name, const char* basedn,
  174. const char* rType, const char* rTitle, IEspDnStruct* dn)
  175. {
  176. double version = context.getClientVersion();
  177. if (version >= 1.14)
  178. {
  179. if (isEmptyString(name))
  180. throw MakeStringException(ECLWATCH_INVALID_INPUT, "BaseDN not specified");
  181. if(m_basedns.length() == 0)
  182. setBasedns(context);
  183. ForEachItemIn(i, m_basedns)
  184. {
  185. IEspDnStruct& cur = m_basedns.item(i);
  186. if(strieq(cur.getName(), name))
  187. {
  188. dn->setBasedn(cur.getBasedn());
  189. dn->setRtype(cur.getRtype());
  190. dn->setRtitle(cur.getRtitle());
  191. return;
  192. }
  193. }
  194. throw MakeStringException(ECLWATCH_INVALID_INPUT, "BaseDN %s not found", name);
  195. }
  196. //before version 1.14
  197. if (isEmptyString(basedn))
  198. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Basedn not specified");
  199. if (isEmptyString(rType))
  200. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Rtype not specified");
  201. if (isEmptyString(rTitle))
  202. throw MakeStringException(ECLWATCH_INVALID_INPUT, "Rtitle not specified");
  203. dn->setBasedn(basedn);
  204. dn->setRtype(rType);
  205. dn->setRtitle(rTitle);
  206. }
  207. void Cws_accessEx::setBasedns(IEspContext &context)
  208. {
  209. CLdapSecManager* secmgr = (CLdapSecManager*)(context.querySecManager());
  210. if(secmgr == NULL)
  211. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  212. set<string> alreadythere;
  213. ForEachItemInRev(x, m_rawbasedns)
  214. {
  215. IEspDnStruct* basedn = &(m_rawbasedns.popGet());
  216. const char* tname = basedn->getTemplatename();
  217. StringBuffer nbasedn;
  218. secmgr->normalizeDn(basedn->getBasedn(), nbasedn);
  219. if(alreadythere.find(nbasedn.str()) == alreadythere.end())
  220. {
  221. alreadythere.insert(nbasedn.str());
  222. Owned<IEspDnStruct> onedn = createDnStruct();
  223. onedn->setBasedn(nbasedn.str());
  224. onedn->setName(basedn->getName());
  225. onedn->setRtype(basedn->getRtype());
  226. onedn->setRtitle(basedn->getRtitle());
  227. if(tname != NULL && *tname != '\0')
  228. onedn->setTemplatename(tname);
  229. m_basedns.append(*onedn.getLink());
  230. }
  231. else
  232. {
  233. ForEachItemIn(y, m_basedns)
  234. {
  235. IEspDnStruct* curbasedn = &(m_basedns.item(y));
  236. if(stricmp(curbasedn->getBasedn(), nbasedn.str()) == 0)
  237. {
  238. const char* curtname = curbasedn->getTemplatename();
  239. if((curtname == NULL || *curtname == '\0') && (tname != NULL && *tname != '\0'))
  240. curbasedn->setTemplatename(tname);
  241. break;
  242. }
  243. }
  244. }
  245. }
  246. return;
  247. }
  248. bool Cws_accessEx::getNewFileScopePermissions(ISecManager* secmgr, const char* name, IEspDnStruct* basednReq, StringBuffer& existingResource, StringArray& newResources)
  249. {
  250. if (!secmgr)
  251. return false;
  252. if (isEmptyString(name))
  253. return false;
  254. char* pStr0 = (char*) name;
  255. while (pStr0[0] == ':') //in case of some ':' by mistake
  256. pStr0++;
  257. if (pStr0[0] == 0)
  258. return false;
  259. StringBuffer lastFileScope;
  260. char* pStr = strstr(pStr0, "::");
  261. while (pStr)
  262. {
  263. char fileScope[10240];
  264. strncpy(fileScope, pStr0, pStr-pStr0);
  265. fileScope[pStr-pStr0] = 0;
  266. if (lastFileScope.length() < 1)
  267. lastFileScope.append(fileScope);
  268. else
  269. lastFileScope.appendf("::%s", fileScope);
  270. newResources.append(lastFileScope.str());
  271. pStr0 = pStr+2;
  272. while (pStr0[0] == ':') //in case of more than two ':' by mistake
  273. pStr0++;
  274. if (pStr0[0] == 0)
  275. break;
  276. pStr = strstr(pStr0, "::");
  277. }
  278. if (pStr0[0] != 0)
  279. {
  280. if (lastFileScope.length() < 1)
  281. lastFileScope.append(pStr0);
  282. else
  283. lastFileScope.appendf("::%s", pStr0);
  284. newResources.append(lastFileScope.str());
  285. }
  286. CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
  287. while (newResources.ordinality())
  288. {
  289. StringBuffer namebuf(newResources.item(0));
  290. try
  291. {
  292. IArrayOf<CPermission> permissions;
  293. ldapsecmgr->getPermissionsArray(basednReq->getBasedn(), str2type(basednReq->getRtype()), namebuf.str(), permissions);
  294. if (!permissions.ordinality())
  295. {
  296. break;
  297. }
  298. }
  299. catch(IException* e) //exception may be thrown when no permission for the resource
  300. {
  301. e->Release();
  302. break;
  303. }
  304. existingResource.clear().append(namebuf);
  305. newResources.remove(0);
  306. }
  307. return true;
  308. }
  309. bool Cws_accessEx::setNewFileScopePermissions(ISecManager* secmgr, IEspDnStruct* basednReq, StringBuffer& existingResource, StringArray& newResources)
  310. {
  311. if (!secmgr || !newResources.ordinality())
  312. {
  313. return false;
  314. }
  315. const char* basedn = basednReq->getBasedn();
  316. if (!basedn || !*basedn)
  317. {
  318. return false;
  319. }
  320. StringBuffer basednBuf;
  321. basednBuf.append(basedn);
  322. if (existingResource.length() < 1)
  323. {
  324. existingResource.append("files");
  325. const char* comma = strchr(basedn, ',');
  326. const char* eqsign = strchr(basedn, '=');
  327. if(eqsign && comma && (strlen(comma) > 1))
  328. {
  329. basednBuf.clear().append(comma + 1);
  330. }
  331. }
  332. IArrayOf<CPermission> requiredPermissions;
  333. CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
  334. ldapsecmgr->getPermissionsArray(basednBuf, str2type(basednReq->getRtype()), existingResource.str(), requiredPermissions);
  335. if (!requiredPermissions.ordinality())
  336. {
  337. return false;
  338. }
  339. ForEachItemIn(x, requiredPermissions)
  340. {
  341. CPermission& perm = requiredPermissions.item(x);
  342. int accType = perm.getAccount_type(); //0-individual, 1 - group
  343. const char* actname = perm.getAccount_name();
  344. if (!actname || !*actname)
  345. continue;
  346. CPermissionAction paction;
  347. paction.m_basedn.append(basednReq->getBasedn());
  348. paction.m_rtype = str2type(basednReq->getRtype());
  349. paction.m_account_type = (ACT_TYPE)accType;
  350. paction.m_account_name.append(actname);
  351. paction.m_allows = perm.getAllows();
  352. paction.m_denies = perm.getDenies();
  353. if ((accType != GROUP_ACT) || ((stricmp(actname, "Administrators") != 0) && (stricmp(actname, "Authenticated Users") != 0)))
  354. {
  355. paction.m_action.append("add");
  356. }
  357. else
  358. {
  359. paction.m_action.append("update");
  360. }
  361. ForEachItemIn(y, newResources)
  362. {
  363. StringBuffer namebuf(newResources.item(y));
  364. paction.m_rname.clear().append(namebuf.str());
  365. ldapsecmgr->changePermission(paction);
  366. }
  367. }
  368. return true;
  369. }
  370. bool Cws_accessEx::onUsers(IEspContext &context, IEspUserRequest &req, IEspUserResponse &resp)
  371. {
  372. try
  373. {
  374. CLdapSecManager* secmgr = queryLDAPSecurityManager(context);
  375. double version = context.getClientVersion();
  376. if (version > 1.03)
  377. {
  378. if(secmgr == NULL)
  379. {
  380. resp.setNoSecMngr(true);
  381. return true;
  382. }
  383. }
  384. else
  385. {
  386. if(secmgr == NULL)
  387. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  388. }
  389. checkUser(context);
  390. const char* searchstr = req.getSearchinput();
  391. int numusers = secmgr->countUsers(searchstr, MAX_USERS_DISPLAY);
  392. if(numusers == -1)
  393. {
  394. resp.setToomany(true);
  395. return true;
  396. }
  397. resp.setToomany(false);
  398. /*
  399. LdapServerType servertype = secmgr->getLdapServerType();
  400. if(servertype != ACTIVE_DIRECTORY)
  401. resp.setPosixok(true);
  402. else
  403. resp.setPosixok(false);
  404. */
  405. resp.setPosixok(false);
  406. IArrayOf<IEspUserInfo> espusers;
  407. IUserArray users;
  408. secmgr->searchUsers(searchstr, users);
  409. ForEachItemIn(x, users)
  410. {
  411. ISecUser* usr = &users.item(x);
  412. if(usr)
  413. {
  414. Owned<IEspUserInfo> oneusr = createUserInfo();
  415. oneusr->setUsername(usr->getName());
  416. oneusr->setFullname(usr->getFullName());
  417. double version = context.getClientVersion();
  418. if (version >= 1.10)
  419. {
  420. oneusr->setEmployeeID(usr->getEmployeeID());
  421. }
  422. if (version >= 1.07)
  423. {
  424. StringBuffer sb;
  425. oneusr->setPasswordexpiration(getPasswordExpiration(usr, sb));
  426. }
  427. if (version >= 1.16)
  428. {
  429. oneusr->setEmployeeNumber(usr->getEmployeeNumber());
  430. }
  431. espusers.append(*oneusr.getLink());
  432. }
  433. }
  434. resp.setUsers(espusers);
  435. }
  436. catch(IException* e)
  437. {
  438. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  439. }
  440. return true;
  441. }
  442. const char *Cws_accessEx::getPasswordExpiration(ISecUser *usr, StringBuffer &passwordExpiration)
  443. {
  444. switch (usr->getPasswordDaysRemaining())//-1 if expired, -2 if never expires
  445. {
  446. case scPasswordExpired:
  447. passwordExpiration.set("Expired");
  448. break;
  449. case scPasswordNeverExpires:
  450. passwordExpiration.set("Never");
  451. break;
  452. default:
  453. {
  454. CDateTime dt;
  455. usr->getPasswordExpiration(dt);
  456. dt.getDateString(passwordExpiration);
  457. break;
  458. }
  459. }
  460. return passwordExpiration.str();
  461. }
  462. bool Cws_accessEx::onUserQuery(IEspContext &context, IEspUserQueryRequest &req, IEspUserQueryResponse &resp)
  463. {
  464. try
  465. {
  466. CLdapSecManager* secmgr = queryLDAPSecurityManager(context);
  467. if(!secmgr)
  468. {
  469. resp.setNoSecMngr(true);
  470. return true;
  471. }
  472. checkUser(context);
  473. __int64 pageStartFrom = 0;
  474. unsigned pageSize = 100;
  475. if (!req.getPageSize_isNull())
  476. pageSize = req.getPageSize();
  477. if (!req.getPageStartFrom_isNull())
  478. pageStartFrom = req.getPageStartFrom();
  479. UserField sortOrder[2] = {UFName, UFterm};
  480. CUserSortBy sortBy = req.getSortBy();
  481. switch (sortBy)
  482. {
  483. case CUserSortBy_FullName:
  484. sortOrder[0] = UFFullName;
  485. break;
  486. case CUserSortBy_PasswordExpiration:
  487. sortOrder[0] = UFPasswordExpiration;
  488. break;
  489. case CUserSortBy_EmployeeID:
  490. sortOrder[0] = UFEmployeeID;
  491. break;
  492. case CUserSortBy_EmployeeNumber:
  493. sortOrder[0] = UFEmployeeNumber;
  494. break;
  495. default:
  496. break;
  497. }
  498. sortOrder[0] = (UserField) (sortOrder[0] | UFnocase);
  499. bool descending = req.getDescending();
  500. if (descending)
  501. sortOrder[0] = (UserField) (sortOrder[0] | UFreverse);
  502. unsigned total;
  503. __int64 cacheHint;
  504. IArrayOf<IEspUserInfo> espUsers;
  505. Owned<ISecItemIterator> it = secmgr->getUsersSorted(req.getName(), sortOrder, (const __int64) pageStartFrom, (const unsigned) pageSize, &total, &cacheHint);
  506. ForEach(*it)
  507. {
  508. IPropertyTree& usr = it->query();
  509. const char* userName = usr.queryProp(getUserFieldNames(UFName));
  510. if (!userName || !*userName)
  511. continue;
  512. Owned<IEspUserInfo> userInfo = createUserInfo();
  513. userInfo->setUsername(userName);
  514. const char* fullName = usr.queryProp(getUserFieldNames(UFFullName));
  515. if (fullName && *fullName)
  516. userInfo->setFullname(fullName);
  517. const char* passwordExpiration = usr.queryProp(getUserFieldNames(UFPasswordExpiration));
  518. if (passwordExpiration && *passwordExpiration)
  519. userInfo->setPasswordexpiration(passwordExpiration);
  520. const char* employeeID = usr.queryProp(getUserFieldNames(UFEmployeeID));
  521. if (employeeID && *employeeID)
  522. userInfo->setEmployeeID(employeeID);
  523. const char* employeeNumber = usr.queryProp(getUserFieldNames(UFEmployeeNumber));
  524. if (employeeNumber && *employeeNumber)
  525. userInfo->setEmployeeNumber(employeeNumber);
  526. espUsers.append(*userInfo.getClear());
  527. }
  528. resp.setUsers(espUsers);
  529. resp.setTotalUsers(total);
  530. resp.setCacheHint(cacheHint);
  531. }
  532. catch(IException* e)
  533. {
  534. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  535. }
  536. return true;
  537. }
  538. bool Cws_accessEx::onUserEdit(IEspContext &context, IEspUserEditRequest &req, IEspUserEditResponse &resp)
  539. {
  540. try
  541. {
  542. checkUser(context);
  543. ISecManager* secmgr = context.querySecManager();
  544. if(secmgr == NULL)
  545. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  546. CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
  547. resp.setUsername(req.getUsername());
  548. double version = context.getClientVersion();
  549. if (version >= 1.13)
  550. resp.setIsLDAPAdmin(ldapsecmgr->isSuperUser(context.queryUser()));
  551. StringArray groupnames;
  552. ldapsecmgr->getGroups(req.getUsername(), groupnames);
  553. IArrayOf<IEspGroupInfo> groups;
  554. for(unsigned i = 0; i < groupnames.length(); i++)
  555. {
  556. const char* grpname = groupnames.item(i);
  557. if(grpname == NULL || grpname[0] == '\0')
  558. continue;
  559. Owned<IEspGroupInfo> onegrp = createGroupInfo();
  560. onegrp->setName(grpname);
  561. groups.append(*onegrp.getLink());
  562. }
  563. resp.setGroups(groups);
  564. }
  565. catch(IException* e)
  566. {
  567. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  568. }
  569. return true;
  570. }
  571. bool Cws_accessEx::onUserGroupEditInput(IEspContext &context, IEspUserGroupEditInputRequest &req, IEspUserGroupEditInputResponse &resp)
  572. {
  573. try
  574. {
  575. checkUser(context);
  576. ISecManager* secmgr = context.querySecManager();
  577. if(secmgr == NULL)
  578. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  579. CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
  580. resp.setUsername(req.getUsername());
  581. set<string> ogrps;
  582. ogrps.insert("Authenticated Users");
  583. StringArray grps;
  584. ldapsecmgr->getGroups(req.getUsername(), grps);
  585. unsigned i = 0;
  586. for(i = 0; i < grps.length(); i++)
  587. {
  588. const char* grp = grps.item(i);
  589. if(grp != NULL && *grp != '\0')
  590. {
  591. ogrps.insert(grp);
  592. }
  593. }
  594. StringArray groupnames;
  595. StringArray managedBy;
  596. StringArray descriptions;
  597. ldapsecmgr->getAllGroups(groupnames, managedBy, descriptions);
  598. IArrayOf<IEspGroupInfo> groups;
  599. for(i = 0; i < groupnames.length(); i++)
  600. {
  601. const char* grpname = groupnames.item(i);
  602. if(grpname == NULL || grpname[0] == '\0')
  603. continue;
  604. if(ogrps.find(grpname) == ogrps.end())
  605. {
  606. Owned<IEspGroupInfo> onegrp = createGroupInfo();
  607. onegrp->setName(grpname);
  608. onegrp->setGroupDesc(descriptions.item(i));
  609. onegrp->setGroupOwner(managedBy.item(i));
  610. groups.append(*onegrp.getLink());
  611. }
  612. }
  613. resp.setGroups(groups);
  614. }
  615. catch(IException* e)
  616. {
  617. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  618. }
  619. return true;
  620. }
  621. bool Cws_accessEx::onUserGroupEdit(IEspContext &context, IEspUserGroupEditRequest &req, IEspUserGroupEditResponse &resp)
  622. {
  623. try
  624. {
  625. checkUser(context);
  626. CLdapSecManager* secmgr = (CLdapSecManager*)(context.querySecManager());
  627. if(secmgr == NULL)
  628. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  629. const char* username = req.getUsername();
  630. if(username == NULL || *username == '\0')
  631. {
  632. resp.setRetcode(-1);
  633. resp.setRetmsg("username can't be empty");
  634. return false;
  635. }
  636. StringArray& groupnames = req.getGroupnames();
  637. try
  638. {
  639. for(unsigned i = 0; i < groupnames.length(); i++)
  640. {
  641. const char* grpname = groupnames.item(i);
  642. if(grpname == NULL || *grpname == '\0')
  643. continue;
  644. secmgr->changeUserGroup(req.getAction(), username, grpname);
  645. }
  646. }
  647. catch(IException* e)
  648. {
  649. StringBuffer errmsg;
  650. e->errorMessage(errmsg);
  651. OERRLOG("error changing user's group membership: %s", errmsg.str());
  652. resp.setRetcode(e->errorCode());
  653. resp.setRetmsg(errmsg.str());
  654. return false;
  655. }
  656. resp.setRetcode(0);
  657. resp.setUsername(username);
  658. resp.setAction(req.getAction());
  659. if(stricmp(req.getAction(), "add") == 0)
  660. resp.setRetmsg("user successfully added to groups");
  661. else
  662. resp.setRetmsg("user successfully deleted from groups");
  663. }
  664. catch(IException* e)
  665. {
  666. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  667. }
  668. return true;
  669. }
  670. bool Cws_accessEx::onGroups(IEspContext &context, IEspGroupRequest &req, IEspGroupResponse &resp)
  671. {
  672. try
  673. {
  674. CLdapSecManager* secmgr0 = queryLDAPSecurityManager(context);
  675. double version = context.getClientVersion();
  676. if (version > 1.03)
  677. {
  678. if(secmgr0 == NULL)
  679. {
  680. //throw MakeStringException(-1, "SecManager is NULL, please check if the binding's authentication is set up correctly");
  681. resp.setNoSecMngr(true);
  682. return true;
  683. }
  684. }
  685. checkUser(context);
  686. StringArray groupnames;
  687. StringArray groupManagedBy;
  688. StringArray groupDescriptions;
  689. ISecManager* secmgr = context.querySecManager();
  690. if(secmgr == NULL)
  691. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  692. secmgr->getAllGroups(groupnames, groupManagedBy, groupDescriptions);
  693. ///groupnames.append("Administrators");
  694. ///groupnames.append("Full_Access_TestingOnly");
  695. //groupnames.kill();
  696. if (groupnames.length() > 0)
  697. {
  698. IArrayOf<IEspGroupInfo> groups;
  699. for(unsigned i = 0; i < groupnames.length(); i++)
  700. {
  701. const char* grpname = groupnames.item(i);
  702. //if(grpname == NULL || grpname[0] == '\0' || stricmp(grpname, "Authenticated Users") == 0)
  703. if(grpname == NULL || grpname[0] == '\0')
  704. continue;
  705. Owned<IEspGroupInfo> onegrp = createGroupInfo();
  706. onegrp->setName(grpname);
  707. onegrp->setGroupDesc(groupDescriptions.item(i));
  708. onegrp->setGroupOwner(groupManagedBy.item(i));
  709. groups.append(*onegrp.getLink());
  710. }
  711. resp.setGroups(groups);
  712. }
  713. /*
  714. IArrayOf<IEspGroupInfo> groups;
  715. Owned<IEspGroupInfo> onegrp = createGroupInfo();
  716. onegrp->setName("grpname");
  717. groups.append(*onegrp.getLink());
  718. resp.setGroups(groups);
  719. */
  720. }
  721. catch(IException* e)
  722. {
  723. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  724. }
  725. return true;
  726. }
  727. bool Cws_accessEx::onGroupQuery(IEspContext &context, IEspGroupQueryRequest &req, IEspGroupQueryResponse &resp)
  728. {
  729. try
  730. {
  731. CLdapSecManager* secmgr = queryLDAPSecurityManager(context);
  732. if(!secmgr)
  733. {
  734. resp.setNoSecMngr(true);
  735. return true;
  736. }
  737. checkUser(context);
  738. __int64 pageStartFrom = 0;
  739. unsigned pageSize = 100;
  740. if (!req.getPageSize_isNull())
  741. pageSize = req.getPageSize();
  742. if (!req.getPageStartFrom_isNull())
  743. pageStartFrom = req.getPageStartFrom();
  744. GroupField sortOrder[2] = {GFName, GFterm};
  745. CGroupSortBy sortBy = req.getSortBy();
  746. switch (sortBy)
  747. {
  748. case CGroupSortBy_ManagedBy:
  749. sortOrder[0] = GFManagedBy;
  750. break;
  751. default:
  752. break;
  753. }
  754. sortOrder[0] = (GroupField) (sortOrder[0] | GFnocase);
  755. bool descending = req.getDescending();
  756. if (descending)
  757. sortOrder[0] = (GroupField) (sortOrder[0] | GFreverse);
  758. unsigned total;
  759. __int64 cacheHint;
  760. IArrayOf<IEspGroupInfo> groups;
  761. Owned<ISecItemIterator> it = secmgr->getGroupsSorted(sortOrder, (const __int64) pageStartFrom, (const unsigned) pageSize, &total, &cacheHint);
  762. ForEach(*it)
  763. {
  764. IPropertyTree& g = it->query();
  765. const char* groupName = g.queryProp(getGroupFieldNames(GFName));
  766. if (!groupName || !*groupName)
  767. continue;
  768. Owned<IEspGroupInfo> groupInfo = createGroupInfo();
  769. groupInfo->setName(groupName);
  770. const char* managedBy = g.queryProp(getGroupFieldNames(GFManagedBy));
  771. if (managedBy && *managedBy)
  772. groupInfo->setGroupOwner(managedBy);
  773. const char* desc = g.queryProp(getGroupFieldNames(GFDesc));
  774. if (desc && *desc)
  775. groupInfo->setGroupDesc(desc);
  776. groups.append(*groupInfo.getClear());
  777. }
  778. resp.setGroups(groups);
  779. resp.setTotalGroups(total);
  780. resp.setCacheHint(cacheHint);
  781. }
  782. catch(IException* e)
  783. {
  784. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  785. }
  786. return true;
  787. }
  788. bool Cws_accessEx::onAddUser(IEspContext &context, IEspAddUserRequest &req, IEspAddUserResponse &resp)
  789. {
  790. try
  791. {
  792. checkUser(context);
  793. ISecManager* secmgr = context.querySecManager();
  794. if(secmgr == NULL)
  795. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  796. const char* username = req.getUsername();
  797. if(username == NULL || *username == '\0')
  798. {
  799. resp.setRetcode(-1);
  800. resp.setRetmsg("username can't be empty");
  801. return false;
  802. }
  803. if(strchr(username, ' '))
  804. {
  805. resp.setRetcode(-1);
  806. resp.setRetmsg("Username can't contain spaces");
  807. return false;
  808. }
  809. CLdapSecManager* secmgr0 = (CLdapSecManager*)secmgr;
  810. if((secmgr0->getLdapServerType() == ACTIVE_DIRECTORY) && (strlen(username) > 20))
  811. {
  812. resp.setRetcode(-1);
  813. resp.setRetmsg("Username can't be more than 20 characters.");
  814. return false;
  815. }
  816. const char* pass1 = req.getPassword1();
  817. const char* pass2 = req.getPassword2();
  818. if(pass1 == NULL || pass2 == NULL || *pass1 == '\0' || *pass2 == '\0' || strcmp(pass1, pass2) != 0)
  819. {
  820. resp.setRetcode(-1);
  821. resp.setRetmsg("password and retype can't be empty and must match.");
  822. return false;
  823. }
  824. const char * employeeID = NULL;
  825. if (context.getClientVersion() >= 1.10)
  826. {
  827. employeeID = req.getEmployeeID();
  828. }
  829. const char * employeeNumber = nullptr;
  830. if (context.getClientVersion() >= 1.16)
  831. {
  832. employeeNumber = req.getEmployeeNumber();
  833. }
  834. Owned<ISecUser> user = secmgr->createUser(username);
  835. ISecCredentials& cred = user->credentials();
  836. const char* firstname = req.getFirstname();
  837. const char* lastname = req.getLastname();
  838. if(firstname != NULL)
  839. user->setFirstName(firstname);
  840. if(lastname != NULL)
  841. user->setLastName(lastname);
  842. if(employeeID != NULL)
  843. user->setEmployeeID(employeeID);
  844. if(employeeNumber != nullptr)
  845. user->setEmployeeNumber(employeeNumber);
  846. if(pass1 != NULL)
  847. cred.setPassword(pass1);
  848. try
  849. {
  850. if (user.get())
  851. secmgr->addUser(*user.get());
  852. }
  853. catch(IException* e)
  854. {
  855. resp.setRetcode(-1);
  856. StringBuffer errmsg;
  857. resp.setRetmsg(e->errorMessage(errmsg).str());
  858. return false;
  859. }
  860. resp.setRetcode(0);
  861. resp.setRetmsg("User successfully added");
  862. }
  863. catch(IException* e)
  864. {
  865. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  866. }
  867. return true;
  868. }
  869. bool Cws_accessEx::onUserAction(IEspContext &context, IEspUserActionRequest &req, IEspUserActionResponse &resp)
  870. {
  871. try
  872. {
  873. checkUser(context);
  874. CLdapSecManager* secmgr = (CLdapSecManager*)(context.querySecManager());
  875. if(secmgr == NULL)
  876. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  877. const char* action = req.getActionType();
  878. if (!action || !*action)
  879. throw MakeStringException(ECLWATCH_INVALID_ACTION, "Action not specified.");
  880. if (!stricmp(action, "delete"))
  881. {
  882. StringArray& usernames = req.getUsernames();
  883. for(unsigned i = 0; i < usernames.length(); i++)
  884. {
  885. const char* username = usernames.item(i);
  886. Owned<ISecUser> user = secmgr->createUser(username);
  887. secmgr->deleteUser(user.get());
  888. }
  889. }
  890. else if (!stricmp(action, "export"))
  891. {
  892. StringBuffer users;
  893. StringArray& usernames = req.getUsernames();
  894. for(unsigned i = 0; i < usernames.length(); i++)
  895. {
  896. const char* username = usernames.item(i);
  897. if (i > 0)
  898. users.appendf("&usernames_i%d=%s", i+1, username);
  899. else
  900. users.append(username);
  901. }
  902. resp.setRedirectUrl(StringBuffer("/ws_access/UserAccountExport?usernames_i1=").append(users).str());
  903. }
  904. resp.setAction(action);
  905. }
  906. catch(IException* e)
  907. {
  908. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  909. }
  910. return true;
  911. }
  912. bool Cws_accessEx::onGroupAdd(IEspContext &context, IEspGroupAddRequest &req, IEspGroupAddResponse &resp)
  913. {
  914. try
  915. {
  916. checkUser(context);
  917. CLdapSecManager* secmgr = (CLdapSecManager*)(context.querySecManager());
  918. if(secmgr == NULL)
  919. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  920. const char* groupname = req.getGroupname();
  921. if(groupname == NULL || *groupname == '\0')
  922. {
  923. resp.setRetcode(-1);
  924. resp.setRetmsg("Group name can't be empty");
  925. return false;
  926. }
  927. resp.setGroupname(groupname);
  928. double version = context.getClientVersion();
  929. const char * groupDesc = NULL;
  930. const char * groupOwner = NULL;
  931. if (version >= 1.09)
  932. {
  933. groupDesc = req.getGroupDesc();
  934. groupOwner = req.getGroupOwner();
  935. }
  936. try
  937. {
  938. secmgr->addGroup(groupname, groupOwner, groupDesc);
  939. }
  940. catch(IException* e)
  941. {
  942. StringBuffer emsg;
  943. e->errorMessage(emsg);
  944. resp.setRetcode(e->errorCode());
  945. resp.setRetmsg(emsg.str());
  946. return false;
  947. }
  948. catch(...)
  949. {
  950. resp.setRetcode(-1);
  951. resp.setRetmsg("Unknown error");
  952. return false;
  953. }
  954. resp.setRetcode(0);
  955. }
  956. catch(IException* e)
  957. {
  958. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  959. }
  960. return true;
  961. }
  962. bool Cws_accessEx::onGroupAction(IEspContext &context, IEspGroupActionRequest &req, IEspGroupActionResponse &resp)
  963. {
  964. try
  965. {
  966. checkUser(context);
  967. CLdapSecManager* secmgr = queryLDAPSecurityManager(context);
  968. if(secmgr == NULL)
  969. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  970. const char* action = req.getActionType();
  971. if (!action || !*action)
  972. throw MakeStringException(ECLWATCH_INVALID_ACTION, "Action not specified.");
  973. if (!stricmp(action, "export"))
  974. {
  975. StringBuffer groups;
  976. StringArray& groupnames = req.getGroupnames();
  977. for(unsigned i = 0; i < groupnames.length(); i++)
  978. {
  979. const char* group = groupnames.item(i);
  980. if (i > 0)
  981. groups.appendf("&groupnames_i%d=%s", i+1, group);
  982. else
  983. groups.append(group);
  984. }
  985. resp.setRedirectUrl(StringBuffer("/ws_access/UserAccountExport?groupnames_i1=").append(groups).str());
  986. }
  987. else if (!stricmp(action, "delete"))
  988. {
  989. CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
  990. StringArray& groupnames = req.getGroupnames();
  991. IArrayOf<IEspAccountPermission> accountPermissions;
  992. double version = context.getClientVersion();
  993. if (version > 1.01)
  994. {
  995. bool bDeletePermission = false;
  996. if(!req.getDeletePermission_isNull())
  997. bDeletePermission = req.getDeletePermission();
  998. if(m_basedns.length() == 0)
  999. {
  1000. setBasedns(context);
  1001. }
  1002. ForEachItemIn(y, m_basedns)
  1003. {
  1004. IEspDnStruct* curbasedn = &(m_basedns.item(y));
  1005. const char *basednName = curbasedn->getName();
  1006. const char *aBasedn = curbasedn->getBasedn();
  1007. const char *aRtype = curbasedn->getRtype();
  1008. if (!aBasedn || !*aBasedn ||!aRtype || !*aRtype)
  1009. continue;
  1010. SecResourceType rtype = str2type(aRtype);
  1011. IArrayOf<IEspResource> ResourceArray;
  1012. if(rtype == RT_WORKUNIT_SCOPE)
  1013. {
  1014. StringBuffer deft_basedn, deft_name;
  1015. const char* comma = strchr(aBasedn, ',');
  1016. const char* eqsign = strchr(aBasedn, '=');
  1017. if(eqsign != NULL)
  1018. {
  1019. if(comma == NULL)
  1020. deft_name.append(eqsign+1);
  1021. else
  1022. {
  1023. deft_name.append(comma - eqsign - 1, eqsign+1);
  1024. deft_basedn.append(comma + 1);
  1025. }
  1026. }
  1027. if (deft_name.length() > 0)
  1028. {
  1029. Owned<IEspResource> oneresource = createResource();
  1030. oneresource->setName(deft_name);
  1031. oneresource->setDescription(deft_basedn);
  1032. ResourceArray.append(*oneresource.getLink());
  1033. }
  1034. }
  1035. IArrayOf<ISecResource> resources;
  1036. if(secmgr->getResources(rtype, aBasedn, resources))
  1037. {
  1038. ForEachItemIn(y1, resources)
  1039. {
  1040. ISecResource& r = resources.item(y1);
  1041. const char* rname = r.getName();
  1042. if(rname == NULL || *rname == '\0')
  1043. continue;
  1044. Owned<IEspResource> oneresource = createResource();
  1045. oneresource->setName(rname);
  1046. oneresource->setDescription(aBasedn);
  1047. ResourceArray.append(*oneresource.getLink());
  1048. }
  1049. }
  1050. ForEachItemIn(y2, ResourceArray)
  1051. {
  1052. IEspResource& r = ResourceArray.item(y2);
  1053. const char* resourceName = r.getName();
  1054. const char* bnname = r.getDescription();
  1055. if (isEmptyString(resourceName))
  1056. continue;
  1057. try
  1058. {
  1059. IArrayOf<CPermission> permissions;
  1060. ldapsecmgr->getPermissionsArray(bnname, rtype, resourceName, permissions);
  1061. ForEachItemIn(x, permissions)
  1062. {
  1063. CPermission& perm = permissions.item(x);
  1064. const char* actname = perm.getAccount_name();
  1065. int accountType = perm.getAccount_type(); //0-individual, 1 - group
  1066. //if ((bGroupAccount && accountType < 1) || (!bGroupAccount && accountType > 0))
  1067. if (accountType < 1 || !actname || !*actname) //Support Group only
  1068. continue;
  1069. ForEachItemIn(x1, groupnames)
  1070. {
  1071. const char* groupname = groupnames.item(x1);
  1072. if (groupname && !strcmp(actname, groupname))
  1073. {
  1074. ///bDeletePermission = true;
  1075. if (!bDeletePermission)
  1076. {
  1077. Owned<IEspAccountPermission> onepermission = createAccountPermission();
  1078. if (version < 1.15)
  1079. {
  1080. onepermission->setBasedn(bnname);
  1081. onepermission->setRType(aRtype);
  1082. }
  1083. else
  1084. {
  1085. onepermission->setBasednName(basednName);
  1086. }
  1087. onepermission->setResourceName(resourceName);
  1088. onepermission->setPermissionName(groupname);
  1089. accountPermissions.append(*onepermission.getLink());
  1090. }
  1091. else
  1092. {
  1093. CPermissionAction paction;
  1094. paction.m_basedn.append(bnname);
  1095. paction.m_rtype = rtype;
  1096. paction.m_rname.append(resourceName);
  1097. paction.m_account_name.append(actname);
  1098. paction.m_account_type = (ACT_TYPE) accountType;
  1099. paction.m_allows = perm.getAllows();
  1100. paction.m_denies = perm.getDenies();
  1101. paction.m_action.append("delete");
  1102. if(!ldapsecmgr->changePermission(paction))
  1103. {
  1104. resp.setRetcode(-1);
  1105. resp.setRetmsg("Unknown error");
  1106. return false;
  1107. }
  1108. }
  1109. break;
  1110. }
  1111. }
  1112. }
  1113. }
  1114. catch(IException* e)
  1115. {
  1116. e->Release();
  1117. }
  1118. }
  1119. }
  1120. }
  1121. try
  1122. {
  1123. if (accountPermissions.length() < 1)
  1124. {
  1125. ForEachItemIn(x1, groupnames)
  1126. {
  1127. const char* groupname = groupnames.item(x1);
  1128. secmgr->deleteGroup(groupname);
  1129. }
  1130. }
  1131. else
  1132. {
  1133. StringBuffer groupnamestr;
  1134. groupnamestr.append("DeletePermission=1");
  1135. ForEachItemIn(x1, groupnames)
  1136. {
  1137. const char* groupname = groupnames.item(x1);
  1138. groupnamestr.appendf("&groupnames_i%d=%s", x1+1, groupname);
  1139. }
  1140. resp.setPermissions(accountPermissions);
  1141. resp.setGroupnames(groupnamestr.str());
  1142. resp.setRetcode(0);
  1143. }
  1144. }
  1145. catch(IException* e)
  1146. {
  1147. StringBuffer emsg;
  1148. e->errorMessage(emsg);
  1149. resp.setRetcode(e->errorCode());
  1150. resp.setRetmsg(emsg.str());
  1151. return false;
  1152. }
  1153. catch(...)
  1154. {
  1155. resp.setRetcode(-1);
  1156. resp.setRetmsg("Unknown error");
  1157. return false;
  1158. }
  1159. }
  1160. resp.setRetcode(0);
  1161. }
  1162. catch(IException* e)
  1163. {
  1164. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1165. }
  1166. return true;
  1167. }
  1168. bool Cws_accessEx::onGroupEdit(IEspContext &context, IEspGroupEditRequest &req, IEspGroupEditResponse &resp)
  1169. {
  1170. try
  1171. {
  1172. checkUser(context);
  1173. ISecManager* secmgr = context.querySecManager();
  1174. if(secmgr == NULL)
  1175. throw MakeStringException(ECLWATCH_INVALID_SEC_MANAGER, MSG_SEC_MANAGER_IS_NULL);
  1176. CLdapSecManager* ldapsecmgr = (CLdapSecManager*)secmgr;
  1177. resp.setGroupname(req.getGroupname());
  1178. StringArray usernames;
  1179. ldapsecmgr->getGroupMembers(req.getGroupname(), usernames);
  1180. IArrayOf<IEspUserInfo> users;
  1181. unsigned i = 0;
  1182. for(i = 0; i < usernames.length(); i++)
  1183. {
  1184. const char* usrname = usernames.item(i);
  1185. if(usrname == NULL || usrname[0] == '\0')
  1186. continue;
  1187. ///////////////////////////////////////BUG#41536///////////////
  1188. bool bFound = false;
  1189. IUserArray usersInBaseDN;
  1190. ldapsecmgr->searchUsers(usrname, usersInBaseDN);
  1191. ForEachItemIn(x, usersInBaseDN)
  1192. {
  1193. ISecUser* usr = &usersInBaseDN.item(x);
  1194. if(usr)
  1195. {
  1196. const char* usrname = usr->getName();
  1197. if(usrname == NULL || usrname[0] == '\0')
  1198. continue;
  1199. bFound = true;
  1200. break;
  1201. }
  1202. }
  1203. if (!bFound)
  1204. continue;
  1205. //////////////////////////////////////////////////////////////
  1206. Owned<IEspUserInfo> oneusr = createUserInfo();
  1207. oneusr->setUsername(usrname);
  1208. users.append(*oneusr.getLink());
  1209. }
  1210. resp.setUsers(users);
  1211. }
  1212. catch(IException* e)
  1213. {
  1214. FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
  1215. }
  1216. return true;
  1217. }
  1218. bool Cws_accessEx::onGroupMemberQuery(IEspContext &context, IEspGroupMemberQueryRequest &req, IEspGroupMemberQueryResponse &resp)
  1219. {
  1220. try
  1221. {
  1222. CLdapSecManager* secmgr = queryLDAPSecurityManager(context);
  1223. if(!secmgr)
  1224. {
  1225. resp.setNoSecMngr(true);
  1226. return true;
  1227. }
  1228. checkUser(context);
  1229. __int64 pageStartFrom = 0;
  1230. unsigned pageSize = 100;
  1231. if (!req.getPageSize_isNull())
  1232. pageSize = req.getPageSize();
  1233. if (!req.getPageStartFrom_isNull())
  1234. pageStartFrom = req.getPageStartFrom();
  1235. UserField sortOrder[2] = {UFName, UFterm};
  1236. CUserSortBy sortBy = req.getSortBy();
  1237. switch (sortBy)
  1238. {
  1239. case CUserSortBy_FullName:
  1240. sortOrder[0] = UFFullName;
  1241. break;
  1242. case CUserSortBy_PasswordExpiration:
  1243. sortOrder[0] = UFPasswordExpiration;
  1244. break;
  1245. case CUserSortBy_EmployeeID:
  1246. sortOrder[0] = UFEmployeeID;
  1247. break;
  1248. case CUserSortBy_EmployeeNumber:
  1249. sortOrder[0] = UFEmployeeNumber;
  1250. break;
  1251. default:
  1252. break;
  1253. }
  1254. sortOrder[0] = (UserField) (sortOrder[0] | UFnocase);
  1255. bool descending = req.getDescending();
  1256. if (descending)
  1257. sortOrder[0] = (UserField) (sortOrder[0] | UFreverse);
  1258. unsigned total;
  1259. __int64 cacheHint;
  1260. IArrayOf<IEspUserInfo> users;
  1261. Owned<ISecItemIterator> it = secmgr->getGroupMembersSorted(req.getGroupName(), sortOrder, (const __int64) pageStartFrom, (const unsigned) pageSize, &total, &cacheHint);
  1262. ForEach(*it)
  1263. {
  1264. IPropertyTree& usr = it->query();
  1265. const char* userName = usr.queryProp(getUserFieldNames(UFName));
  1266. if (!userName || !*userName)
  1267. continue;
  1268. Owned<IEspUserInfo> userInfo = createUserInfo();
  1269. userInfo->setUsername(userName);
  1270. const char* fullName = usr.queryProp(getUserFieldNames(UFFullName));
  1271. if (fullName && *fullName)
  1272. userInfo->setFullname(fullName);
  1273. const char* passwordExpiration = usr.queryProp(getUserFieldNames(UFPasswordExpiration));
  1274. if (passwordExpiration && *passwordExpiration)
  1275. us