ldapsecurity.cpp 32 KB

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