ldapsecurity.cpp 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #ifdef _WIN32
  15. #define AXA_API __declspec(dllexport)
  16. #endif
  17. #include "ldapsecurity.ipp"
  18. #include "ldapsecurity.hpp"
  19. #include "authmap.ipp"
  20. #include "defaultsecuritymanager.hpp"
  21. /**********************************************************
  22. * CLdapSecUser *
  23. **********************************************************/
  24. CLdapSecUser::CLdapSecUser(const char *name, const char *pw) :
  25. m_pw(pw), m_authenticateStatus(AS_UNKNOWN)
  26. {
  27. setName(name);
  28. }
  29. CLdapSecUser::~CLdapSecUser()
  30. {
  31. }
  32. //non-interfaced functions
  33. void CLdapSecUser::setUserID(unsigned userid)
  34. {
  35. m_userid = userid;
  36. }
  37. void CLdapSecUser::setUserSid(int sidlen, const char* sid)
  38. {
  39. m_usersid.clear();
  40. m_usersid.append(sidlen, sid);
  41. }
  42. MemoryBuffer& CLdapSecUser::getUserSid()
  43. {
  44. return m_usersid;
  45. }
  46. //interface ISecUser
  47. const char * CLdapSecUser::getName()
  48. {
  49. return m_name.get();
  50. }
  51. bool CLdapSecUser::setName(const char * name)
  52. {
  53. if(name != NULL)
  54. {
  55. const char* atsign = strchr(name, '@');
  56. if(atsign != NULL)
  57. {
  58. m_name.set(name, atsign - name);
  59. m_realm.set(atsign + 1);
  60. }
  61. else
  62. {
  63. m_name.set(name);
  64. }
  65. }
  66. return TRUE;
  67. }
  68. const char * CLdapSecUser::getFullName()
  69. {
  70. return m_fullname.get();
  71. }
  72. bool CLdapSecUser::setFullName(const char * name)
  73. {
  74. if(name != NULL)
  75. {
  76. m_fullname.set(name);
  77. }
  78. return true;
  79. }
  80. const char * CLdapSecUser::getFirstName()
  81. {
  82. return m_firstname.get();
  83. }
  84. bool CLdapSecUser::setFirstName(const char * fname)
  85. {
  86. if(fname != NULL)
  87. {
  88. m_firstname.set(fname);
  89. }
  90. return true;
  91. }
  92. const char * CLdapSecUser::getLastName()
  93. {
  94. return m_lastname.get();
  95. }
  96. bool CLdapSecUser::setLastName(const char * lname)
  97. {
  98. if(lname != NULL)
  99. {
  100. m_lastname.set(lname);
  101. }
  102. return true;
  103. }
  104. const char * CLdapSecUser::getRealm()
  105. {
  106. return m_realm.get();
  107. }
  108. bool CLdapSecUser::setRealm(const char * name)
  109. {
  110. m_realm.set(name);
  111. return TRUE;
  112. }
  113. const char * CLdapSecUser::getFqdn()
  114. {
  115. return m_Fqdn.get();
  116. }
  117. bool CLdapSecUser::setFqdn(const char * Fqdn)
  118. {
  119. m_Fqdn.set(Fqdn);
  120. return true;
  121. }
  122. const char *CLdapSecUser::getPeer()
  123. {
  124. return m_Peer.get();
  125. }
  126. bool CLdapSecUser::setPeer(const char *Peer)
  127. {
  128. m_Peer.set(Peer);
  129. return true;
  130. }
  131. ISecCredentials & CLdapSecUser::credentials()
  132. {
  133. return *this;
  134. }
  135. unsigned CLdapSecUser::getUserID()
  136. {
  137. return m_userid;
  138. }
  139. //interface ISecCredentials
  140. bool CLdapSecUser::setPassword(const char * pw)
  141. {
  142. m_pw.set(pw);
  143. return TRUE;
  144. }
  145. const char* CLdapSecUser::getPassword()
  146. {
  147. return m_pw;
  148. }
  149. bool CLdapSecUser::setEncodedPassword(SecPasswordEncoding enc, void * pw, unsigned length, void * salt, unsigned saltlen)
  150. {
  151. return FALSE; //not supported yet
  152. }
  153. bool CLdapSecUser::addToken(unsigned type, void * data, unsigned length)
  154. {
  155. return FALSE; //not supported yet
  156. }
  157. void CLdapSecUser::copyTo(ISecUser& destination)
  158. {
  159. CLdapSecUser* dest = dynamic_cast<CLdapSecUser*>(&destination);
  160. if(!dest)
  161. return;
  162. dest->setAuthenticateStatus(getAuthenticateStatus());
  163. dest->setName(getName());
  164. dest->setFullName(getFullName());
  165. dest->setFirstName(getFirstName());
  166. dest->setLastName(getLastName());
  167. dest->setRealm(getRealm());
  168. dest->credentials().setPassword(credentials().getPassword());
  169. dest->setUserSid(m_usersid.length(), m_usersid.toByteArray());
  170. dest->setUserID(m_userid);
  171. dest->setPasswordExpiration(m_passwordExpiration);
  172. }
  173. ISecUser * CLdapSecUser::clone()
  174. {
  175. CLdapSecUser* newuser = new CLdapSecUser(m_name.get(), m_pw.get());
  176. if(newuser)
  177. copyTo(*newuser);
  178. return newuser;
  179. }
  180. /**********************************************************
  181. * CLdapSecResource *
  182. **********************************************************/
  183. CLdapSecResource::CLdapSecResource(const char *name) : m_name(name), m_access(0), m_required_access(0)
  184. {
  185. m_resourcetype = RT_DEFAULT;
  186. }
  187. void CLdapSecResource::addAccess(int flags)
  188. {
  189. m_access |= flags;
  190. }
  191. void CLdapSecResource::setAccessFlags(int flags)
  192. {
  193. m_access = flags;
  194. }
  195. void CLdapSecResource::setRequiredAccessFlags(int flags)
  196. {
  197. m_required_access = flags;
  198. }
  199. int CLdapSecResource::getRequiredAccessFlags()
  200. {
  201. return m_required_access;
  202. }
  203. //interface ISecResource : extends IInterface
  204. const char * CLdapSecResource::getName()
  205. {
  206. return m_name.get();
  207. }
  208. int CLdapSecResource::getAccessFlags()
  209. {
  210. return m_access;
  211. }
  212. int CLdapSecResource::addParameter(const char* name, const char* value)
  213. {
  214. if (!m_parameters)
  215. m_parameters.setown(createProperties(false));
  216. m_parameters->setProp(name, value);
  217. return 0;
  218. }
  219. const char * CLdapSecResource::getParameter(const char * name)
  220. {
  221. if (m_parameters)
  222. {
  223. const char *value = m_parameters->queryProp(name);
  224. return value;
  225. }
  226. return NULL;
  227. }
  228. void CLdapSecResource::setDescription(const char* description)
  229. {
  230. m_description.clear().append(description);
  231. }
  232. const char* CLdapSecResource::getDescription()
  233. {
  234. return m_description.str();
  235. }
  236. void CLdapSecResource::setValue(const char* value)
  237. {
  238. m_value.clear();
  239. m_value.append(value);
  240. }
  241. const char* CLdapSecResource::getValue()
  242. {
  243. return m_value.str();
  244. }
  245. ISecResource * CLdapSecResource::clone()
  246. {
  247. CLdapSecResource* _res = new CLdapSecResource(m_name.get());
  248. if(!_res)
  249. return NULL;
  250. _res->setResourceType(m_resourcetype);
  251. _res->setValue(m_value.str());
  252. _res->m_access = m_access;
  253. _res->m_required_access = m_required_access;
  254. _res->setDescription(m_description.str());
  255. if(!m_parameters)
  256. return _res;
  257. Owned<IPropertyIterator> Itr = m_parameters->getIterator();
  258. Itr->first();
  259. while(Itr->isValid())
  260. {
  261. _res->addParameter(Itr->getPropKey(),m_parameters->queryProp(Itr->getPropKey()));
  262. Itr->next();
  263. }
  264. return _res;
  265. }
  266. void CLdapSecResource::copy(ISecResource* from)
  267. {
  268. if(!from)
  269. return;
  270. CLdapSecResource* ldapfrom = dynamic_cast<CLdapSecResource*>(from);
  271. if(!ldapfrom)
  272. return;
  273. m_access = ldapfrom->m_access;
  274. setDescription(ldapfrom->m_description.str());
  275. if(m_parameters.get())
  276. {
  277. m_parameters.clear();
  278. }
  279. if(!ldapfrom->m_parameters.get())
  280. return;
  281. Owned<IPropertyIterator> Itr = ldapfrom->m_parameters->getIterator();
  282. Itr->first();
  283. while(Itr->isValid())
  284. {
  285. addParameter(Itr->getPropKey(), ldapfrom->m_parameters->queryProp(Itr->getPropKey()));
  286. Itr->next();
  287. }
  288. return;
  289. }
  290. SecResourceType CLdapSecResource::getResourceType()
  291. {
  292. return m_resourcetype;
  293. }
  294. void CLdapSecResource::setResourceType(SecResourceType resourcetype)
  295. {
  296. m_resourcetype = resourcetype;
  297. }
  298. /**********************************************************
  299. * CLdapSecResourceList *
  300. **********************************************************/
  301. CLdapSecResourceList::CLdapSecResourceList(const char *name) : m_complete(0)
  302. {
  303. m_name.set(name);
  304. }
  305. void CLdapSecResourceList::setAuthorizationComplete(bool value)
  306. {
  307. m_complete=value;
  308. }
  309. IArrayOf<ISecResource>& CLdapSecResourceList::getResourceList()
  310. {
  311. return m_rlist;
  312. }
  313. //interface ISecResourceList : extends IInterface
  314. bool CLdapSecResourceList::isAuthorizationComplete()
  315. {
  316. return m_complete;
  317. }
  318. ISecResourceList * CLdapSecResourceList::clone()
  319. {
  320. CLdapSecResourceList* _newList = new CLdapSecResourceList(m_name.get());
  321. if(!_newList)
  322. return NULL;
  323. copyTo(*_newList);
  324. return _newList;
  325. }
  326. bool CLdapSecResourceList::copyTo(ISecResourceList& destination)
  327. {
  328. ForEachItemIn(x, m_rlist)
  329. {
  330. CLdapSecResource* res = (CLdapSecResource*)(&(m_rlist.item(x)));
  331. if(res)
  332. destination.addResource(res->clone());
  333. }
  334. return false;
  335. }
  336. ISecResource* CLdapSecResourceList::addResource(const char * name)
  337. {
  338. if(!name || !*name)
  339. return NULL;
  340. ISecResource* resource = m_rmap[name];
  341. if(resource == NULL)
  342. {
  343. resource = new CLdapSecResource(name);
  344. m_rlist.append(*resource);
  345. m_rmap[name] = resource;
  346. }
  347. return resource;
  348. }
  349. void CLdapSecResourceList::addResource(ISecResource * resource)
  350. {
  351. if(resource == NULL)
  352. return;
  353. const char* name = resource->getName();
  354. if(!name || !*name)
  355. return;
  356. ISecResource* r = m_rmap[name];
  357. if(r == NULL)
  358. {
  359. m_rlist.append(*resource);
  360. m_rmap[name] = resource;
  361. }
  362. }
  363. bool CLdapSecResourceList::addCustomResource(const char * name, const char * config)
  364. {
  365. return false;
  366. }
  367. ISecResource * CLdapSecResourceList::getResource(const char * Resource)
  368. {
  369. if(!Resource || !*Resource)
  370. return NULL;
  371. ISecResource* r = m_rmap[Resource];
  372. if(r)
  373. return LINK(r);
  374. else
  375. return NULL;
  376. }
  377. void CLdapSecResourceList::clear()
  378. {
  379. m_rlist.kill();
  380. }
  381. int CLdapSecResourceList::count()
  382. {
  383. return m_rlist.length();
  384. }
  385. const char* CLdapSecResourceList::getName()
  386. {
  387. return m_name.get();
  388. }
  389. ISecResource * CLdapSecResourceList::queryResource(unsigned seq)
  390. {
  391. if(seq < m_rlist.length())
  392. return &(m_rlist.item(seq));
  393. else
  394. return NULL;
  395. }
  396. ISecPropertyIterator * CLdapSecResourceList::getPropertyItr()
  397. {
  398. return new ArrayIIteratorOf<IArrayOf<struct ISecResource>, ISecProperty, ISecPropertyIterator>(m_rlist);
  399. }
  400. ISecProperty* CLdapSecResourceList::findProperty(const char* name)
  401. {
  402. if(!name || !*name)
  403. return NULL;
  404. return m_rmap[name];
  405. }
  406. /**********************************************************
  407. * CLdapSecManager *
  408. **********************************************************/
  409. CLdapSecManager::CLdapSecManager(const char *serviceName, const char *config)
  410. {
  411. IPropertyTree* cfg = createPTreeFromXMLString(config, ipt_caseInsensitive);
  412. if(cfg == NULL)
  413. {
  414. throw MakeStringException(-1, "createPTreeFromXMLString() failed for %s", config);
  415. }
  416. init(serviceName, cfg);
  417. }
  418. void CLdapSecManager::init(const char *serviceName, IPropertyTree* cfg)
  419. {
  420. for(int i = 0; i < RT_SCOPE_MAX; i++)
  421. m_cache_off[i] = false;
  422. m_usercache_off = false;
  423. m_cfg.setown(cfg);
  424. cfg->getProp(".//@ldapAddress", m_server);
  425. cfg->getProp(".//@description", m_description);
  426. ILdapClient* ldap_client = createLdapClient(cfg);
  427. IPermissionProcessor* pp;
  428. if(ldap_client->getServerType() == ACTIVE_DIRECTORY)
  429. pp = new PermissionProcessor(cfg);
  430. else if(ldap_client->getServerType() == IPLANET)
  431. pp = new CIPlanetAciProcessor(cfg);
  432. else if(ldap_client->getServerType() == OPEN_LDAP)
  433. pp = new COpenLdapAciProcessor(cfg);
  434. ldap_client->init(pp);
  435. pp->setLdapClient(ldap_client);
  436. m_ldap_client.setown(ldap_client);
  437. m_pp.setown(pp);
  438. int cachetimeout = cfg->getPropInt("@cacheTimeout", 5);
  439. m_permissionsCache.setCacheTimeout( 60 * cachetimeout);
  440. m_permissionsCache.setTransactionalEnabled(true);
  441. m_passwordExpirationWarningDays = cfg->getPropInt(".//@passwordExpirationWarningDays", 10); //Default to 10 days
  442. };
  443. CLdapSecManager::CLdapSecManager(const char *serviceName, IPropertyTree &config)
  444. {
  445. init(serviceName, &config);
  446. }
  447. CLdapSecManager::~CLdapSecManager()
  448. {
  449. }
  450. //interface ISecManager : extends IInterface
  451. ISecUser * CLdapSecManager::createUser(const char * user_name)
  452. {
  453. return (new CLdapSecUser(user_name, NULL));
  454. }
  455. ISecResourceList * CLdapSecManager::createResourceList(const char * rlname)
  456. {
  457. return (new CLdapSecResourceList(rlname));
  458. }
  459. bool CLdapSecManager::subscribe(ISecAuthenticEvents & events)
  460. {
  461. m_subscriber.set(&events);
  462. return true;
  463. }
  464. bool CLdapSecManager::unsubscribe(ISecAuthenticEvents & events)
  465. {
  466. if (&events == m_subscriber.get())
  467. {
  468. m_subscriber.set(NULL);
  469. }
  470. return true;
  471. }
  472. bool CLdapSecManager::authenticate(ISecUser* user)
  473. {
  474. if(!user)
  475. return false;
  476. if(user->getAuthenticateStatus() == AS_AUTHENTICATED)
  477. return true;
  478. if(m_permissionsCache.isCacheEnabled() && !m_usercache_off && m_permissionsCache.lookup(*user))
  479. {
  480. user->setAuthenticateStatus(AS_AUTHENTICATED);
  481. return true;
  482. }
  483. bool ok = m_ldap_client->authenticate(*user);
  484. if(ok)
  485. {
  486. if(m_permissionsCache.isCacheEnabled() && !m_usercache_off)
  487. m_permissionsCache.add(*user);
  488. user->setAuthenticateStatus(AS_AUTHENTICATED);
  489. }
  490. return ok;
  491. }
  492. bool CLdapSecManager::authorizeEx(SecResourceType rtype, ISecUser& sec_user, ISecResourceList * Resources)
  493. {
  494. if(!authenticate(&sec_user))
  495. {
  496. return false;
  497. }
  498. CLdapSecResourceList * reslist = (CLdapSecResourceList*)Resources;
  499. if(!reslist)
  500. return true;
  501. IArrayOf<ISecResource>& rlist = reslist->getResourceList();
  502. int nResources = rlist.length();
  503. int ri;
  504. for(ri = 0; ri < nResources; ri++)
  505. {
  506. ISecResource* res = &rlist.item(ri);
  507. if(res != NULL)
  508. res->setResourceType(rtype);
  509. }
  510. if (nResources <= 0)
  511. return true;
  512. bool rc;
  513. time_t tctime = getThreadCreateTime();
  514. if ((m_permissionsCache.isCacheEnabled() || (m_permissionsCache.isTransactionalEnabled() && tctime > 0)) && (!m_cache_off[rtype]))
  515. {
  516. bool* cached_found = (bool*)alloca(nResources*sizeof(bool));
  517. int nFound = m_permissionsCache.lookup(sec_user, rlist, cached_found);
  518. if (nFound < nResources)
  519. {
  520. IArrayOf<ISecResource> rlist2;
  521. int i;
  522. for (i=0; i < nResources; i++)
  523. {
  524. if (*(cached_found+i) == false)
  525. {
  526. ISecResource& secRes = rlist.item(i);
  527. secRes.Link();
  528. rlist2.append(secRes);
  529. //DBGLOG("CACHE: Fetching permissions for %s:%s", sec_user.getName(), secRes.getName());
  530. }
  531. }
  532. rc = m_ldap_client->authorize(rtype, sec_user, rlist2);
  533. if (rc)
  534. m_permissionsCache.add(sec_user, rlist2);
  535. }
  536. else
  537. rc = true;
  538. }
  539. else
  540. {
  541. rc = m_ldap_client->authorize(rtype, sec_user, rlist);
  542. }
  543. return rc;
  544. }
  545. int CLdapSecManager::authorizeEx(SecResourceType rtype, ISecUser & user, const char * resourcename)
  546. {
  547. if(!resourcename || !*resourcename)
  548. return SecAccess_Full;
  549. Owned<ISecResourceList> rlist;
  550. rlist.setown(createResourceList("resources"));
  551. rlist->addResource(resourcename);
  552. bool ok = authorizeEx(rtype, user, rlist.get());
  553. if(ok)
  554. return rlist->queryResource(0)->getAccessFlags();
  555. else
  556. return -1;
  557. }
  558. bool CLdapSecManager::authorizeEx(SecResourceType rtype, ISecUser& sec_user, ISecResourceList * Resources, bool doAuthentication)
  559. {
  560. if(doAuthentication && !authenticate(&sec_user))
  561. {
  562. return false;
  563. }
  564. CLdapSecResourceList * reslist = (CLdapSecResourceList*)Resources;
  565. if(!reslist)
  566. return true;
  567. IArrayOf<ISecResource>& rlist = reslist->getResourceList();
  568. int nResources = rlist.length();
  569. int ri;
  570. for(ri = 0; ri < nResources; ri++)
  571. {
  572. ISecResource* res = &rlist.item(ri);
  573. if(res != NULL)
  574. res->setResourceType(rtype);
  575. }
  576. if (nResources <= 0)
  577. return true;
  578. bool rc;
  579. time_t tctime = getThreadCreateTime();
  580. if ((m_permissionsCache.isCacheEnabled() || (m_permissionsCache.isTransactionalEnabled() && tctime > 0)) && (!m_cache_off[rtype]))
  581. {
  582. bool* cached_found = (bool*)alloca(nResources*sizeof(bool));
  583. int nFound = m_permissionsCache.lookup(sec_user, rlist, cached_found);
  584. if (nFound < nResources)
  585. {
  586. IArrayOf<ISecResource> rlist2;
  587. int i;
  588. for (i=0; i < nResources; i++)
  589. {
  590. if (*(cached_found+i) == false)
  591. {
  592. ISecResource& secRes = rlist.item(i);
  593. secRes.Link();
  594. rlist2.append(secRes);
  595. //DBGLOG("CACHE: Fetching permissions for %s:%s", sec_user.getName(), secRes.getName());
  596. }
  597. }
  598. rc = m_ldap_client->authorize(rtype, sec_user, rlist2);
  599. if (rc)
  600. m_permissionsCache.add(sec_user, rlist2);
  601. }
  602. else
  603. rc = true;
  604. }
  605. else
  606. {
  607. rc = m_ldap_client->authorize(rtype, sec_user, rlist);
  608. }
  609. return rc;
  610. }
  611. int CLdapSecManager::authorizeEx(SecResourceType rtype, ISecUser & user, const char * resourcename, bool doAuthentication)
  612. {
  613. if(!resourcename || !*resourcename)
  614. return SecAccess_Full;
  615. Owned<ISecResourceList> rlist;
  616. rlist.setown(createResourceList("resources"));
  617. rlist->addResource(resourcename);
  618. bool ok = authorizeEx(rtype, user, rlist.get(), doAuthentication);
  619. if(ok)
  620. return rlist->queryResource(0)->getAccessFlags();
  621. else
  622. return -1;
  623. }
  624. int CLdapSecManager::getAccessFlagsEx(SecResourceType rtype, ISecUser & user, const char * resourcename)
  625. {
  626. if(!resourcename || !*resourcename)
  627. return -1;
  628. Owned<ISecResourceList> rlist0;
  629. rlist0.setown(createResourceList("resources"));
  630. rlist0->addResource(resourcename);
  631. CLdapSecResourceList * reslist = (CLdapSecResourceList*)rlist0.get();
  632. if(!reslist)
  633. return -1;
  634. IArrayOf<ISecResource>& rlist = reslist->getResourceList();
  635. int nResources = rlist.length();
  636. int ri;
  637. for(ri = 0; ri < nResources; ri++)
  638. {
  639. ISecResource* res = &rlist.item(ri);
  640. if(res != NULL)
  641. res->setResourceType(rtype);
  642. }
  643. if (nResources <= 0)
  644. return -1;
  645. bool ok = false;
  646. time_t tctime = getThreadCreateTime();
  647. if ((m_permissionsCache.isCacheEnabled() || (m_permissionsCache.isTransactionalEnabled() && tctime > 0)) && (!m_cache_off[rtype]))
  648. {
  649. bool* cached_found = (bool*)alloca(nResources*sizeof(bool));
  650. int nFound = m_permissionsCache.lookup(user, rlist, cached_found);
  651. if (nFound < nResources)
  652. {
  653. IArrayOf<ISecResource> rlist2;
  654. int i;
  655. for (i=0; i < nResources; i++)
  656. {
  657. if (*(cached_found+i) == false)
  658. {
  659. ISecResource& secRes = rlist.item(i);
  660. secRes.Link();
  661. rlist2.append(secRes);
  662. //DBGLOG("CACHE: Fetching permissions for %s:%s", sec_user.getName(), secRes.getName());
  663. }
  664. }
  665. ok = m_ldap_client->authorize(rtype, user, rlist2);
  666. if (ok)
  667. m_permissionsCache.add(user, rlist2);
  668. }
  669. else
  670. ok = true;
  671. }
  672. else
  673. {
  674. ok = m_ldap_client->authorize(rtype, user, rlist);
  675. }
  676. //bool ok = authorizeEx(rtype, user, rlist.get());
  677. if(ok)
  678. return rlist0->queryResource(0)->getAccessFlags();
  679. else
  680. return -1;
  681. }
  682. bool CLdapSecManager::authorize(ISecUser& sec_user, ISecResourceList * Resources)
  683. {
  684. return authorizeEx(RT_DEFAULT, sec_user, Resources);
  685. }
  686. int CLdapSecManager::authorizeFileScope(ISecUser & user, const char * filescope)
  687. {
  688. if(filescope == 0 || filescope[0] == '\0')
  689. return SecAccess_Full;
  690. Owned<ISecResourceList> rlist;
  691. rlist.setown(createResourceList("FileScope"));
  692. rlist->addResource(filescope);
  693. bool ok = authorizeFileScope(user, rlist.get());
  694. if(ok)
  695. return rlist->queryResource(0)->getAccessFlags();
  696. else
  697. return -1;
  698. }
  699. bool CLdapSecManager::authorizeFileScope(ISecUser & user, ISecResourceList * resources)
  700. {
  701. return authorizeEx(RT_FILE_SCOPE, user, resources);
  702. }
  703. int CLdapSecManager::authorizeWorkunitScope(ISecUser & user, const char * wuscope)
  704. {
  705. if(wuscope == 0 || wuscope[0] == '\0')
  706. return SecAccess_Full;
  707. Owned<ISecResourceList> rlist;
  708. rlist.setown(createResourceList("WorkunitScope"));
  709. rlist->addResource(wuscope);
  710. bool ok = authorizeWorkunitScope(user, rlist.get());
  711. if(ok)
  712. return rlist->queryResource(0)->getAccessFlags();
  713. else
  714. return -1;
  715. }
  716. bool CLdapSecManager::authorizeWorkunitScope(ISecUser & user, ISecResourceList * resources)
  717. {
  718. return authorizeEx(RT_WORKUNIT_SCOPE, user, resources);
  719. }
  720. bool CLdapSecManager::addResourcesEx(SecResourceType rtype, ISecUser& sec_user, ISecResourceList * resources, SecPermissionType ptype, const char* basedn)
  721. {
  722. CLdapSecResourceList * reslist = (CLdapSecResourceList*)resources;
  723. if(!reslist)
  724. return true;
  725. IArrayOf<ISecResource>& rlist = reslist->getResourceList();
  726. if(rlist.length() <= 0)
  727. return true;
  728. return m_ldap_client->addResources(rtype, sec_user, rlist, ptype, basedn);
  729. }
  730. bool CLdapSecManager::addResourceEx(SecResourceType rtype, ISecUser& user, const char* resourcename, SecPermissionType ptype, const char* basedn)
  731. {
  732. Owned<ISecResourceList> rlist;
  733. rlist.setown(createResourceList("resources"));
  734. rlist->addResource(resourcename);
  735. return addResourcesEx(rtype, user, rlist.get(), ptype, basedn);
  736. }
  737. bool CLdapSecManager::addResources(ISecUser& sec_user, ISecResourceList * resources)
  738. {
  739. return addResourcesEx(RT_DEFAULT, sec_user, resources);
  740. }
  741. bool CLdapSecManager::addUser(ISecUser & user)
  742. {
  743. if(&user == NULL)
  744. {
  745. DBGLOG("CLdapSecManager::addUser - user is NULL");
  746. return false;
  747. }
  748. bool ok = m_ldap_client->addUser(user);
  749. if(!ok)
  750. return false;
  751. return m_pp->retrieveUserInfo(user);
  752. }
  753. ISecUser * CLdapSecManager::lookupUser(unsigned uid)
  754. {
  755. return m_ldap_client->lookupUser(uid);
  756. }
  757. ISecUser * CLdapSecManager::findUser(const char * username)
  758. {
  759. if(username == NULL || strlen(username) == 0)
  760. {
  761. DBGLOG("findUser - username is empty");
  762. return NULL;
  763. }
  764. Owned<ISecUser> user;
  765. user.setown(createUser(username));
  766. try
  767. {
  768. bool ok = m_pp->retrieveUserInfo(*user);
  769. if(ok)
  770. {
  771. return LINK(user.get());
  772. }
  773. else
  774. {
  775. return NULL;
  776. }
  777. }
  778. catch(IException*)
  779. {
  780. return NULL;
  781. }
  782. catch(...)
  783. {
  784. return NULL;
  785. }
  786. }
  787. ISecUserIterator * CLdapSecManager::getAllUsers()
  788. {
  789. synchronized block(m_monitor);
  790. m_user_array.popAll(true);
  791. m_ldap_client->retrieveUsers(m_user_array);
  792. return new ArrayIIteratorOf<IUserArray, ISecUser, ISecUserIterator>(m_user_array);
  793. }
  794. void CLdapSecManager::searchUsers(const char* searchstr, IUserArray& users)
  795. {
  796. m_ldap_client->retrieveUsers(searchstr, users);
  797. }
  798. void CLdapSecManager::getAllUsers(IUserArray& users)
  799. {
  800. m_ldap_client->retrieveUsers(users);
  801. }
  802. bool CLdapSecManager::getResources(SecResourceType rtype, const char * basedn, IArrayOf<ISecResource> & resources)
  803. {
  804. return m_ldap_client->getResources(rtype, basedn, "", resources);
  805. }
  806. bool CLdapSecManager::getResourcesEx(SecResourceType rtype, const char * basedn, const char* searchstr, IArrayOf<ISecResource> & resources)
  807. {
  808. return m_ldap_client->getResourcesEx(rtype, basedn, "", searchstr, resources);
  809. }
  810. void CLdapSecManager::setExtraParam(const char * name, const char * value)
  811. {
  812. if(name == NULL || name[0] == '\0')
  813. return;
  814. if (!m_extraparams)
  815. m_extraparams.setown(createProperties(false));
  816. m_extraparams->setProp(name, value);
  817. if(value != NULL && value[0] != '\0')
  818. {
  819. if(stricmp(name, "resourcesBasedn") == 0)
  820. m_ldap_client->setResourceBasedn(value, RT_DEFAULT);
  821. else if(stricmp(name, "workunitsBasedn") == 0)
  822. m_ldap_client->setResourceBasedn(value, RT_WORKUNIT_SCOPE);
  823. }
  824. }
  825. IAuthMap * CLdapSecManager::createAuthMap(IPropertyTree * authconfig)
  826. {
  827. CAuthMap* authmap = new CAuthMap(this);
  828. IPropertyTreeIterator *loc_iter = NULL;
  829. loc_iter = authconfig->getElements(".//Location");
  830. if (loc_iter != NULL)
  831. {
  832. IPropertyTree *location = NULL;
  833. loc_iter->first();
  834. while(loc_iter->isValid())
  835. {
  836. location = &loc_iter->query();
  837. if (location)
  838. {
  839. StringBuffer pathstr, rstr, required, description;
  840. location->getProp("@path", pathstr);
  841. location->getProp("@resource", rstr);
  842. location->getProp("@required", required);
  843. location->getProp("@description", description);
  844. if(pathstr.length() == 0)
  845. throw MakeStringException(-1, "path empty in Authenticate/Location");
  846. if(rstr.length() == 0)
  847. throw MakeStringException(-1, "resource empty in Authenticate/Location");
  848. ISecResourceList* rlist = authmap->queryResourceList(pathstr.str());
  849. if(rlist == NULL)
  850. {
  851. rlist = createResourceList("ldapsecurity");
  852. authmap->add(pathstr.str(), rlist);
  853. }
  854. ISecResource* rs = rlist->addResource(rstr.str());
  855. unsigned requiredaccess = str2perm(required.str());
  856. rs->setRequiredAccessFlags(requiredaccess);
  857. rs->setDescription(description.str());
  858. }
  859. loc_iter->next();
  860. }
  861. loc_iter->Release();
  862. loc_iter = NULL;
  863. }
  864. authmap->addToBackend();
  865. return authmap;
  866. }
  867. IAuthMap * CLdapSecManager::createFeatureMap(IPropertyTree * authconfig)
  868. {
  869. CAuthMap* feature_authmap = new CAuthMap(this);
  870. IPropertyTreeIterator *feature_iter = NULL;
  871. feature_iter = authconfig->getElements(".//Feature");
  872. if (feature_iter != NULL)
  873. {
  874. IPropertyTree *feature = NULL;
  875. feature_iter->first();
  876. while(feature_iter->isValid())
  877. {
  878. feature = &feature_iter->query();
  879. if (feature)
  880. {
  881. StringBuffer pathstr, rstr, required, description;
  882. feature->getProp("@path", pathstr);
  883. feature->getProp("@resource", rstr);
  884. feature->getProp("@required", required);
  885. feature->getProp("@description", description);
  886. ISecResourceList* rlist = feature_authmap->queryResourceList(pathstr.str());
  887. if(rlist == NULL)
  888. {
  889. rlist = createResourceList(pathstr.str());
  890. feature_authmap->add(pathstr.str(), rlist);
  891. }
  892. ISecResource* rs = rlist->addResource(rstr.str());
  893. unsigned requiredaccess = str2perm(required.str());
  894. rs->setRequiredAccessFlags(requiredaccess);
  895. rs->setDescription(description.str());
  896. }
  897. feature_iter->next();
  898. }
  899. feature_iter->Release();
  900. feature_iter = NULL;
  901. }
  902. feature_authmap->addToBackend();
  903. return feature_authmap;
  904. }
  905. bool CLdapSecManager::updateUser(ISecUser& user, const char* newPassword)
  906. {
  907. // Authenticate User first
  908. if(!authenticate(&user))
  909. {
  910. return false;
  911. }
  912. //Update password if authenticated
  913. bool ok = m_ldap_client->updateUser(user, newPassword);
  914. if(ok && m_permissionsCache.isCacheEnabled() && !m_usercache_off)
  915. {
  916. m_permissionsCache.removeFromUserCache(user);
  917. }
  918. return ok;
  919. }
  920. bool CLdapSecManager::updateUser(const char* type, ISecUser& user)
  921. {
  922. bool ok = m_ldap_client->updateUser(type, user);
  923. if(ok && m_permissionsCache.isCacheEnabled() && !m_usercache_off)
  924. m_permissionsCache.removeFromUserCache(user);
  925. return ok;
  926. }
  927. bool CLdapSecManager::updateUser(const char* username, const char* newPassword)
  928. {
  929. return m_ldap_client->updateUser(username, newPassword);
  930. }
  931. void CLdapSecManager::getAllGroups(StringArray & groups)
  932. {
  933. m_ldap_client->getAllGroups(groups);
  934. }
  935. bool CLdapSecManager::getPermissionsArray(const char* basedn, SecResourceType rtype, const char* name, IArrayOf<CPermission>& permissions)
  936. {
  937. return m_ldap_client->getPermissionsArray(basedn, rtype, name, permissions);
  938. }
  939. void CLdapSecManager::addGroup(const char* groupname)
  940. {
  941. m_ldap_client->addGroup(groupname);
  942. }
  943. void CLdapSecManager::deleteGroup(const char* groupname)
  944. {
  945. m_ldap_client->deleteGroup(groupname);
  946. }
  947. bool CLdapSecManager::changePermission(CPermissionAction& action)
  948. {
  949. return m_ldap_client->changePermission(action);
  950. }
  951. void CLdapSecManager::getGroups(const char* username, StringArray & groups)
  952. {
  953. m_ldap_client->getGroups(username, groups);
  954. }
  955. void CLdapSecManager::changeUserGroup(const char* action, const char* username, const char* groupname)
  956. {
  957. m_ldap_client->changeUserGroup(action, username, groupname);
  958. }
  959. bool CLdapSecManager::deleteUser(ISecUser* user)
  960. {
  961. return m_ldap_client->deleteUser(user);
  962. }
  963. void CLdapSecManager::getGroupMembers(const char* groupname, StringArray & users)
  964. {
  965. m_ldap_client->getGroupMembers(groupname, users);
  966. }
  967. void CLdapSecManager::deleteResource(SecResourceType rtype, const char * name, const char * basedn)
  968. {
  969. m_ldap_client->deleteResource(rtype, name, basedn);
  970. time_t tctime = getThreadCreateTime();
  971. if ((m_permissionsCache.isCacheEnabled() || (m_permissionsCache.isTransactionalEnabled() && tctime > 0)) && (!m_cache_off[rtype]))
  972. m_permissionsCache.remove(rtype, name);
  973. }
  974. void CLdapSecManager::renameResource(SecResourceType rtype, const char * oldname, const char * newname, const char * basedn)
  975. {
  976. m_ldap_client->renameResource(rtype, oldname, newname, basedn);
  977. time_t tctime = getThreadCreateTime();
  978. if ((m_permissionsCache.isCacheEnabled() || (m_permissionsCache.isTransactionalEnabled() && tctime > 0)) && (!m_cache_off[rtype]))
  979. m_permissionsCache.remove(rtype, oldname);
  980. }
  981. void CLdapSecManager::copyResource(SecResourceType rtype, const char * oldname, const char * newname, const char * basedn)
  982. {
  983. m_ldap_client->copyResource(rtype, oldname, newname, basedn);
  984. }
  985. void CLdapSecManager::normalizeDn(const char* dn, StringBuffer& ndn)
  986. {
  987. m_ldap_client->normalizeDn(dn, ndn);
  988. }
  989. bool CLdapSecManager::isSuperUser(ISecUser* user)
  990. {
  991. return m_ldap_client->isSuperUser(user);
  992. }
  993. ILdapConfig* CLdapSecManager::queryConfig()
  994. {
  995. return m_ldap_client->queryConfig();
  996. }
  997. void CLdapSecManager::cacheSwitch(SecResourceType rtype, bool on)
  998. {
  999. m_cache_off[rtype] = !on;
  1000. // To make things simple, turning off any resource type's permission cache turns off the userCache.
  1001. if(!on)
  1002. m_usercache_off = true;
  1003. }
  1004. int CLdapSecManager::countUsers(const char* searchstr, int limit)
  1005. {
  1006. return m_ldap_client->countUsers(searchstr, limit);
  1007. }
  1008. int CLdapSecManager::countResources(const char* basedn, const char* searchstr, int limit)
  1009. {
  1010. return m_ldap_client->countResources(basedn, searchstr, limit);
  1011. }
  1012. bool CLdapSecManager::getUserInfo(ISecUser& user, const char* infotype)
  1013. {
  1014. return m_ldap_client->getUserInfo(user, infotype);
  1015. }
  1016. extern "C"
  1017. {
  1018. LDAPSECURITY_API ISecManager * newLdapSecManager(const char *serviceName, IPropertyTree &config)
  1019. {
  1020. return new CLdapSecManager(serviceName, config);
  1021. }
  1022. LDAPSECURITY_API ISecManager * newDefaultSecManager(const char *serviceName, IPropertyTree &config)
  1023. {
  1024. return new CDefaultSecurityManager(serviceName, &config);
  1025. }
  1026. LDAPSECURITY_API ISecManager * newLocalSecManager(const char *serviceName, IPropertyTree &config)
  1027. {
  1028. return new CLocalSecurityManager(serviceName, &config);
  1029. }
  1030. LDAPSECURITY_API IAuthMap *newDefaultAuthMap(IPropertyTree* config)
  1031. {
  1032. CAuthMap* authmap = new CAuthMap(NULL);
  1033. IPropertyTreeIterator *loc_iter = NULL;
  1034. loc_iter = config->getElements(".//Location");
  1035. if (loc_iter != NULL)
  1036. {
  1037. IPropertyTree *location = NULL;
  1038. loc_iter->first();
  1039. while(loc_iter->isValid())
  1040. {
  1041. location = &loc_iter->query();
  1042. if (location)
  1043. {
  1044. StringBuffer pathstr, rstr;
  1045. location->getProp("@path", pathstr);
  1046. authmap->add(pathstr.str(), NULL);
  1047. }
  1048. loc_iter->next();
  1049. }
  1050. loc_iter->Release();
  1051. loc_iter = NULL;
  1052. }
  1053. return authmap;
  1054. }
  1055. }