ldapsecurity.cpp 35 KB

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