ldapsecurity.cpp 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659
  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. #define AXA_API DECL_EXPORT
  14. #include "ldapsecurity.ipp"
  15. #include "ldapsecurity.hpp"
  16. #include "authmap.ipp"
  17. #include "digisign.hpp"
  18. #include "caching.hpp"
  19. using namespace cryptohelper;
  20. #include "workunit.hpp"
  21. /**********************************************************
  22. * CLdapSecUser *
  23. **********************************************************/
  24. // An empty static properties instance is shared by all instances because this
  25. // implementation of the interface does not manage per-instance properties.
  26. Owned<IProperties> CLdapSecUser::sm_emptyParameters(createProperties(false));
  27. CLdapSecUser::CLdapSecUser(const char *name, const char *pw) :
  28. m_pw(pw), m_authenticateStatus(AS_UNKNOWN)
  29. {
  30. setName(name);
  31. setUserID(0);
  32. setPosixenabled(false);
  33. setSessionToken(0);
  34. setSignature(nullptr);
  35. }
  36. CLdapSecUser::~CLdapSecUser()
  37. {
  38. }
  39. //non-interfaced functions
  40. void CLdapSecUser::setUserID(unsigned userid)
  41. {
  42. m_userid = userid;
  43. }
  44. void CLdapSecUser::setUserSid(int sidlen, const char* sid)
  45. {
  46. m_usersid.clear();
  47. m_usersid.append(sidlen, sid);
  48. }
  49. MemoryBuffer& CLdapSecUser::getUserSid()
  50. {
  51. return m_usersid;
  52. }
  53. //interface ISecUser
  54. SecFeatureSet CLdapSecUser::queryFeatures(SecFeatureSupportLevel level) const
  55. {
  56. switch (level)
  57. {
  58. case SFSL_Safe:
  59. return s_safeFeatures;
  60. case SFSL_Implemented:
  61. return s_implementedFeatures;
  62. case SFSL_Unsafe:
  63. return SUF_ALL_FEATURES & ~s_safeFeatures;
  64. default:
  65. return SUF_NO_FEATURES;
  66. }
  67. }
  68. const char * CLdapSecUser::getName()
  69. {
  70. return m_name.get();
  71. }
  72. bool CLdapSecUser::setName(const char * name)
  73. {
  74. if(name != NULL)
  75. {
  76. const char* atsign = strchr(name, '@');
  77. if(atsign != NULL)
  78. {
  79. m_name.set(name, atsign - name);
  80. m_realm.set(atsign + 1);
  81. }
  82. else
  83. {
  84. m_name.set(name);
  85. }
  86. }
  87. return TRUE;
  88. }
  89. const char * CLdapSecUser::getFullName()
  90. {
  91. return m_fullname.get();
  92. }
  93. bool CLdapSecUser::setFullName(const char * name)
  94. {
  95. if(name != NULL)
  96. {
  97. m_fullname.set(name);
  98. }
  99. return true;
  100. }
  101. const char * CLdapSecUser::getFirstName()
  102. {
  103. return m_firstname.get();
  104. }
  105. bool CLdapSecUser::setFirstName(const char * fname)
  106. {
  107. if(fname != NULL)
  108. {
  109. m_firstname.set(fname);
  110. }
  111. return true;
  112. }
  113. const char * CLdapSecUser::getLastName()
  114. {
  115. return m_lastname.get();
  116. }
  117. bool CLdapSecUser::setLastName(const char * lname)
  118. {
  119. if(lname != NULL)
  120. {
  121. m_lastname.set(lname);
  122. }
  123. return true;
  124. }
  125. const char * CLdapSecUser::getEmployeeID()
  126. {
  127. return m_employeeID.get();
  128. }
  129. bool CLdapSecUser::setEmployeeID(const char * emplID)
  130. {
  131. m_employeeID.set(emplID);
  132. return true;
  133. }
  134. const char * CLdapSecUser::getEmployeeNumber()
  135. {
  136. return m_employeeNumber.get();
  137. }
  138. bool CLdapSecUser::setEmployeeNumber(const char * emplNumber)
  139. {
  140. m_employeeNumber.set(emplNumber);
  141. return true;
  142. }
  143. const char * CLdapSecUser::getDistinguishedName()
  144. {
  145. return m_distinguishedName.get();
  146. }
  147. bool CLdapSecUser::setDistinguishedName(const char * dn)
  148. {
  149. m_distinguishedName.set(dn);
  150. return true;
  151. }
  152. const char * CLdapSecUser::getRealm()
  153. {
  154. return m_realm.get();
  155. }
  156. bool CLdapSecUser::setRealm(const char * name)
  157. {
  158. m_realm.set(name);
  159. return TRUE;
  160. }
  161. const char * CLdapSecUser::getFqdn()
  162. {
  163. return m_Fqdn.get();
  164. }
  165. bool CLdapSecUser::setFqdn(const char * Fqdn)
  166. {
  167. m_Fqdn.set(Fqdn);
  168. return true;
  169. }
  170. const char *CLdapSecUser::getPeer()
  171. {
  172. return m_Peer.get();
  173. }
  174. bool CLdapSecUser::setPeer(const char *Peer)
  175. {
  176. m_Peer.set(Peer);
  177. return true;
  178. }
  179. ISecCredentials & CLdapSecUser::credentials()
  180. {
  181. return *this;
  182. }
  183. unsigned CLdapSecUser::getUserID()
  184. {
  185. return m_userid;
  186. }
  187. //interface ISecCredentials
  188. bool CLdapSecUser::setPassword(const char * pw)
  189. {
  190. m_pw.set(pw);
  191. return TRUE;
  192. }
  193. const char* CLdapSecUser::getPassword()
  194. {
  195. return m_pw;
  196. }
  197. bool CLdapSecUser::setEncodedPassword(SecPasswordEncoding enc, void * pw, unsigned length, void * salt, unsigned saltlen)
  198. {
  199. return FALSE; //not supported yet
  200. }
  201. void CLdapSecUser::setSessionToken(unsigned token)
  202. {
  203. m_sessionToken = token;
  204. }
  205. unsigned CLdapSecUser::getSessionToken()
  206. {
  207. return m_sessionToken;
  208. }
  209. void CLdapSecUser::setSignature(const char * signature)
  210. {
  211. m_signature.clear().append(signature);
  212. }
  213. const char * CLdapSecUser::getSignature()
  214. {
  215. return m_signature.str();
  216. }
  217. void CLdapSecUser::copyTo(ISecUser& destination)
  218. {
  219. if (this == &destination)
  220. return;
  221. CLdapSecUser* dest = dynamic_cast<CLdapSecUser*>(&destination);
  222. if(!dest)
  223. return;
  224. dest->setAuthenticateStatus(getAuthenticateStatus());
  225. dest->setName(getName());
  226. dest->setFullName(getFullName());
  227. dest->setFirstName(getFirstName());
  228. dest->setLastName(getLastName());
  229. dest->setEmployeeID(getEmployeeID());
  230. dest->setEmployeeNumber(getEmployeeNumber());
  231. dest->setRealm(getRealm());
  232. dest->credentials().setPassword(credentials().getPassword());
  233. dest->setUserSid(m_usersid.length(), m_usersid.toByteArray());
  234. dest->setUserID(m_userid);
  235. dest->setPasswordExpiration(m_passwordExpiration);
  236. dest->setDistinguishedName(m_distinguishedName);
  237. dest->credentials().setSessionToken(m_sessionToken);
  238. dest->credentials().setSignature(m_signature.str());
  239. }
  240. ISecUser * CLdapSecUser::clone()
  241. {
  242. CLdapSecUser* newuser = new CLdapSecUser(m_name.get(), m_pw.get());
  243. if(newuser)
  244. copyTo(*newuser);
  245. return newuser;
  246. }
  247. /**********************************************************
  248. * CLdapSecResource *
  249. **********************************************************/
  250. CLdapSecResource::CLdapSecResource(const char *name) : m_name(name), m_access(SecAccess_None), m_required_access(SecAccess_None), m_parameters(createProperties(false))
  251. {
  252. m_resourcetype = RT_DEFAULT;
  253. }
  254. void CLdapSecResource::addAccess(SecAccessFlags flags)
  255. {
  256. m_access = (SecAccessFlags)((int)m_access | (int)flags);
  257. }
  258. void CLdapSecResource::setAccessFlags(SecAccessFlags flags)
  259. {
  260. m_access = flags;
  261. }
  262. void CLdapSecResource::setRequiredAccessFlags(SecAccessFlags flags)
  263. {
  264. m_required_access = flags;
  265. }
  266. SecAccessFlags CLdapSecResource::getRequiredAccessFlags()
  267. {
  268. return m_required_access;
  269. }
  270. //interface ISecResource : extends IInterface
  271. const char * CLdapSecResource::getName()
  272. {
  273. return m_name.get();
  274. }
  275. SecAccessFlags CLdapSecResource::getAccessFlags()
  276. {
  277. return m_access;
  278. }
  279. int CLdapSecResource::addParameter(const char* name, const char* value)
  280. {
  281. m_parameters->setProp(name, value);
  282. return 0;
  283. }
  284. const char * CLdapSecResource::getParameter(const char * name)
  285. {
  286. return m_parameters->queryProp(name);
  287. }
  288. IPropertyIterator * CLdapSecResource::getParameterIterator() const
  289. {
  290. return m_parameters->getIterator();
  291. }
  292. void CLdapSecResource::setDescription(const char* description)
  293. {
  294. m_description.clear().append(description);
  295. }
  296. const char* CLdapSecResource::getDescription()
  297. {
  298. return m_description.str();
  299. }
  300. void CLdapSecResource::setValue(const char* value)
  301. {
  302. m_value.clear();
  303. m_value.append(value);
  304. }
  305. const char* CLdapSecResource::getValue()
  306. {
  307. return m_value.str();
  308. }
  309. ISecResource * CLdapSecResource::clone()
  310. {
  311. CLdapSecResource* _res = new CLdapSecResource(m_name.get());
  312. if(!_res)
  313. return NULL;
  314. _res->setResourceType(m_resourcetype);
  315. _res->setValue(m_value.str());
  316. _res->m_access = m_access;
  317. _res->m_required_access = m_required_access;
  318. _res->setDescription(m_description.str());
  319. Owned<IPropertyIterator> Itr = m_parameters->getIterator();
  320. ForEach(*Itr)
  321. {
  322. _res->addParameter(Itr->getPropKey(),m_parameters->queryProp(Itr->getPropKey()));
  323. }
  324. return _res;
  325. }
  326. void CLdapSecResource::copy(ISecResource* from)
  327. {
  328. if(!from)
  329. return;
  330. CLdapSecResource* ldapfrom = dynamic_cast<CLdapSecResource*>(from);
  331. if(!ldapfrom)
  332. return;
  333. m_access = ldapfrom->m_access;
  334. setDescription(ldapfrom->m_description.str());
  335. // The destination properties are reset to an empty default state so the
  336. // result of the copy is a copy and not a merge. The IProperties interface
  337. // does not provide ways to manage existing content with lower overhead.
  338. m_parameters.setown(createProperties());
  339. Owned<IPropertyIterator> Itr = ldapfrom->m_parameters->getIterator();
  340. ForEach(*Itr)
  341. {
  342. addParameter(Itr->getPropKey(), ldapfrom->m_parameters->queryProp(Itr->getPropKey()));
  343. }
  344. return;
  345. }
  346. SecResourceType CLdapSecResource::getResourceType()
  347. {
  348. return m_resourcetype;
  349. }
  350. void CLdapSecResource::setResourceType(SecResourceType resourcetype)
  351. {
  352. m_resourcetype = resourcetype;
  353. }
  354. /**********************************************************
  355. * CLdapSecResourceList *
  356. **********************************************************/
  357. CLdapSecResourceList::CLdapSecResourceList(const char *name) : m_complete(0)
  358. {
  359. m_name.set(name);
  360. }
  361. void CLdapSecResourceList::setAuthorizationComplete(bool value)
  362. {
  363. m_complete=value;
  364. }
  365. IArrayOf<ISecResource>& CLdapSecResourceList::getResourceList()
  366. {
  367. return m_rlist;
  368. }
  369. //interface ISecResourceList : extends IInterface
  370. bool CLdapSecResourceList::isAuthorizationComplete()
  371. {
  372. return m_complete;
  373. }
  374. ISecResourceList * CLdapSecResourceList::clone()
  375. {
  376. CLdapSecResourceList* _newList = new CLdapSecResourceList(m_name.get());
  377. if(!_newList)
  378. return NULL;
  379. copyTo(*_newList);
  380. return _newList;
  381. }
  382. bool CLdapSecResourceList::copyTo(ISecResourceList& destination)
  383. {
  384. ForEachItemIn(x, m_rlist)
  385. {
  386. CLdapSecResource* res = (CLdapSecResource*)(&(m_rlist.item(x)));
  387. if(res)
  388. destination.addResource(res->clone());
  389. }
  390. return false;
  391. }
  392. ISecResource* CLdapSecResourceList::addResource(const char * name)
  393. {
  394. if(!name || !*name)
  395. {
  396. DBGLOG("CLdapSecResourceList::addResource resource name must be provided");
  397. return NULL;
  398. }
  399. ISecResource* resource = m_rmap[name];
  400. if(resource == NULL)
  401. {
  402. resource = new CLdapSecResource(name);
  403. m_rlist.append(*resource);
  404. m_rmap[name] = resource;
  405. }
  406. return resource;
  407. }
  408. void CLdapSecResourceList::addResource(ISecResource * resource)
  409. {
  410. if(resource == NULL)
  411. {
  412. DBGLOG("CLdapSecResourceList::addResource2 ISecResource cannot be NULL");
  413. return;
  414. }
  415. const char* name = resource->getName();
  416. if(!name || !*name)
  417. {
  418. DBGLOG("CLdapSecResourceList::addResource2 resource name must be provided");
  419. return;
  420. }
  421. ISecResource* r = m_rmap[name];
  422. if(r == NULL)
  423. {
  424. m_rlist.append(*resource);
  425. m_rmap[name] = resource;
  426. }
  427. }
  428. bool CLdapSecResourceList::addCustomResource(const char * name, const char * config)
  429. {
  430. return false;
  431. }
  432. ISecResource * CLdapSecResourceList::getResource(const char * Resource)
  433. {
  434. if(!Resource || !*Resource)
  435. {
  436. DBGLOG("CLdapSecResourceList::getResource resource name must be provided");
  437. return NULL;
  438. }
  439. ISecResource* r = m_rmap[Resource];
  440. if(r)
  441. return LINK(r);
  442. else
  443. return NULL;
  444. }
  445. void CLdapSecResourceList::clear()
  446. {
  447. m_rlist.kill();
  448. }
  449. int CLdapSecResourceList::count()
  450. {
  451. return m_rlist.length();
  452. }
  453. const char* CLdapSecResourceList::getName()
  454. {
  455. return m_name.get();
  456. }
  457. ISecResource * CLdapSecResourceList::queryResource(unsigned seq)
  458. {
  459. if(seq < m_rlist.length())
  460. return &(m_rlist.item(seq));
  461. else
  462. return NULL;
  463. }
  464. ISecPropertyIterator * CLdapSecResourceList::getPropertyItr()
  465. {
  466. return new ArrayIIteratorOf<IArrayOf<struct ISecResource>, ISecProperty, ISecPropertyIterator>(m_rlist);
  467. }
  468. ISecProperty* CLdapSecResourceList::findProperty(const char* name)
  469. {
  470. if(!name || !*name)
  471. {
  472. DBGLOG("CLdapSecResourceList::findProperty property name must be provided");
  473. return NULL;
  474. }
  475. return m_rmap[name];
  476. }
  477. /**********************************************************
  478. * CLdapSecManager *
  479. **********************************************************/
  480. CLdapSecManager::CLdapSecManager(const char *serviceName, const char *config)
  481. {
  482. IPropertyTree* cfg = createPTreeFromXMLString(config, ipt_caseInsensitive);
  483. if(cfg == NULL)
  484. {
  485. throw MakeStringException(-1, "createPTreeFromXMLString() failed for %s", config);
  486. }
  487. init(serviceName, cfg);
  488. }
  489. void CLdapSecManager::init(const char *serviceName, IPropertyTree* cfg)
  490. {
  491. for(int i = 0; i < RT_SCOPE_MAX; i++)
  492. m_cache_off[i] = false;
  493. m_cache_off[RT_VIEW_SCOPE] = true;
  494. m_usercache_off = false;
  495. m_cfg.setown(cfg);
  496. cfg->getProp(".//@ldapAddress", m_server);
  497. cfg->getProp(".//@description", m_description);
  498. ILdapClient* ldap_client = createLdapClient(cfg);
  499. IPermissionProcessor* pp;
  500. if(ldap_client->getServerType() == ACTIVE_DIRECTORY)
  501. pp = new PermissionProcessor(cfg);
  502. else if(ldap_client->getServerType() == IPLANET)
  503. pp = new CIPlanetAciProcessor(cfg);
  504. else if(ldap_client->getServerType() == OPEN_LDAP)
  505. {
  506. if (0 == stricmp(ldap_client->getLdapConfig()->getCfgServerType(), "389DirectoryServer"))//uses iPlanet style ACI
  507. pp = new CIPlanetAciProcessor(cfg);
  508. else
  509. pp = new COpenLdapAciProcessor(cfg);
  510. }
  511. else
  512. throwUnexpected();
  513. pp->setLdapClient(ldap_client);
  514. ldap_client->init(pp);
  515. m_ldap_client.setown(ldap_client);
  516. m_pp.setown(pp);
  517. int cacheTimeoutMinutes = cfg->getPropInt("@cacheTimeout", DEFAULT_RESOURCE_CACHE_TIMEOUT_MINUTES);//config value is in minutes
  518. if (cfg->getPropBool("@sharedCache", true))
  519. m_permissionsCache.setown(CPermissionsCache::getInstance(cfg->queryProp("@name")));
  520. else
  521. m_permissionsCache.setown(new CPermissionsCache());
  522. m_permissionsCache->setCacheTimeout( 60 * cacheTimeoutMinutes);
  523. m_permissionsCache->setTransactionalEnabled(true);
  524. m_permissionsCache->setSecManager(this);
  525. m_passwordExpirationWarningDays = cfg->getPropInt(".//@passwordExpirationWarningDays", 10); //Default to 10 days
  526. m_checkViewPermissions = cfg->getPropBool(".//@checkViewPermissions", false);
  527. };
  528. CLdapSecManager::CLdapSecManager(const char *serviceName, IPropertyTree &config)
  529. {
  530. init(serviceName, &config);
  531. }
  532. CLdapSecManager::~CLdapSecManager()
  533. {
  534. }
  535. //interface ISecManager : extends IInterface
  536. SecFeatureSet CLdapSecManager::queryFeatures(SecFeatureSupportLevel level) const
  537. {
  538. switch (level)
  539. {
  540. case SFSL_Implemented:
  541. return s_implementedFeatures;
  542. case SFSL_Safe:
  543. return s_safeFeatures;
  544. case SFSL_Unsafe:
  545. return SMF_ALL_FEATURES & ~s_safeFeatures;
  546. default:
  547. return SMF_NO_FEATURES;
  548. }
  549. }
  550. ISecUser * CLdapSecManager::createUser(const char * user_name, IEspSecureContext* secureContext)
  551. {
  552. return (new CLdapSecUser(user_name, NULL));
  553. }
  554. ISecResourceList * CLdapSecManager::createResourceList(const char * rlname, IEspSecureContext* secureContext)
  555. {
  556. return (new CLdapSecResourceList(rlname));
  557. }
  558. bool CLdapSecManager::subscribe(ISecAuthenticEvents & events, IEspSecureContext* secureContext)
  559. {
  560. m_subscriber.set(&events);
  561. return true;
  562. }
  563. bool CLdapSecManager::unsubscribe(ISecAuthenticEvents & events, IEspSecureContext* secureContext)
  564. {
  565. if (&events == m_subscriber.get())
  566. {
  567. m_subscriber.set(NULL);
  568. }
  569. return true;
  570. }
  571. bool CLdapSecManager::authenticate(ISecUser* user)
  572. {
  573. if(!user)
  574. {
  575. DBGLOG("CLdapSecManager::authenticate user cannot be NULL");
  576. return false;
  577. }
  578. bool isCaching = m_permissionsCache->isCacheEnabled() && !m_usercache_off;//caching enabled?
  579. bool isUserCached = false;
  580. Owned<ISecUser> cachedUser = new CLdapSecUser(user->getName(), "");
  581. if(isCaching)
  582. {
  583. user->copyTo(*(cachedUser.get()));//copy user to cachedUser
  584. isUserCached = m_permissionsCache->lookup(*cachedUser);//populate cachedUser with cached values
  585. }
  586. if (AS_AUTHENTICATED == user->getAuthenticateStatus())
  587. {
  588. if(isCaching && !isUserCached)
  589. m_permissionsCache->add(*user);
  590. return true;
  591. }
  592. //Verify provided user signature if present.
  593. //User signatures are calculated and saved when a user is first authenticated,
  594. //and are meant to help eliminate the need to call LDAP to authenticate
  595. //the same user when there is no caching enabled
  596. IDigitalSignatureManager * pDSM = nullptr;
  597. if (!isEmptyString(user->credentials().getSignature()))
  598. {
  599. if (isUserCached)
  600. {
  601. if (streq(cachedUser->credentials().getSignature(), user->credentials().getSignature()))
  602. {
  603. user->setAuthenticateStatus(AS_AUTHENTICATED);
  604. return true;
  605. }
  606. else
  607. {
  608. WARNLOG("Digital signature for %s does not match cached signature", user->getName());
  609. user->setAuthenticateStatus(AS_INVALID_CREDENTIALS);
  610. return false;
  611. }
  612. }
  613. else
  614. {
  615. pDSM = queryDigitalSignatureManagerInstanceFromEnv();
  616. if (pDSM && pDSM->isDigiVerifierConfigured() && !isEmptyString(user->credentials().getSignature()))
  617. {
  618. if (!pDSM->digiVerify(user->credentials().getSignature(), user->getName()))//digital signature valid?
  619. {
  620. user->setAuthenticateStatus(AS_INVALID_CREDENTIALS);
  621. WARNLOG("Invalid digital signature for user %s", user->getName());
  622. return false;
  623. }
  624. else
  625. {
  626. user->setAuthenticateStatus(AS_AUTHENTICATED);
  627. if(isCaching && !isUserCached)
  628. m_permissionsCache->add(*user);
  629. return true;
  630. }
  631. }
  632. }
  633. }
  634. if (isUserCached && cachedUser->getAuthenticateStatus() == AS_AUTHENTICATED)//only authenticated users will be cached
  635. {
  636. return true;
  637. }
  638. //User not in cache. Look for session token, or call LDAP to authenticate
  639. if (0 != user->credentials().getSessionToken())//check for token existence
  640. {
  641. user->setAuthenticateStatus(AS_AUTHENTICATED);
  642. }
  643. else if (m_ldap_client->authenticate(*user)) //call LDAP to authenticate
  644. user->setAuthenticateStatus(AS_AUTHENTICATED);
  645. if (AS_AUTHENTICATED == user->getAuthenticateStatus())
  646. {
  647. if (isCaching)
  648. m_permissionsCache->add(*user);
  649. else if (isEmptyString(user->credentials().getPassword()) && (0 == user->credentials().getSessionToken()) && isEmptyString(user->credentials().getSignature()))
  650. {
  651. //No need to sign if password or authenticated session based user
  652. if (!pDSM)
  653. pDSM = queryDigitalSignatureManagerInstanceFromEnv();
  654. if (pDSM && pDSM->isDigiSignerConfigured())
  655. {
  656. //Set user digital signature
  657. StringBuffer b64Signature;
  658. pDSM->digiSign(b64Signature, user->getName());
  659. user->credentials().setSignature(b64Signature);
  660. }
  661. }
  662. }
  663. return AS_AUTHENTICATED == user->getAuthenticateStatus();
  664. }
  665. bool CLdapSecManager::authorizeEx(SecResourceType rtype, ISecUser& sec_user, ISecResourceList * Resources, IEspSecureContext* secureContext)
  666. {
  667. if(!authenticate(&sec_user))
  668. {
  669. return false;
  670. }
  671. CLdapSecResourceList * reslist = (CLdapSecResourceList*)Resources;
  672. if(!reslist)
  673. return true;
  674. IArrayOf<ISecResource>& rlist = reslist->getResourceList();
  675. int nResources = rlist.length();
  676. int ri;
  677. for(ri = 0; ri < nResources; ri++)
  678. {
  679. ISecResource* res = &rlist.item(ri);
  680. if(res != NULL)
  681. res->setResourceType(rtype);
  682. }
  683. if (nResources <= 0)
  684. return true;
  685. bool rc;
  686. time_t tctime = getThreadCreateTime();
  687. if ((m_permissionsCache->isCacheEnabled() || (m_permissionsCache->isTransactionalEnabled() && tctime > 0)) && (!m_cache_off[rtype]))
  688. {
  689. bool* cached_found = (bool*)alloca(nResources*sizeof(bool));
  690. int nFound = m_permissionsCache->lookup(sec_user, rlist, cached_found);
  691. if (nFound < nResources)
  692. {
  693. IArrayOf<ISecResource> rlist2;
  694. int i;
  695. for (i=0; i < nResources; i++)
  696. {
  697. if (*(cached_found+i) == false)
  698. {
  699. ISecResource& secRes = rlist.item(i);
  700. secRes.Link();
  701. rlist2.append(secRes);
  702. //DBGLOG("CACHE: Fetching permissions for %s:%s", sec_user.getName(), secRes.getName());
  703. }
  704. }
  705. rc = m_ldap_client->authorize(rtype, sec_user, rlist2);
  706. if (rc)
  707. m_permissionsCache->add(sec_user, rlist2);
  708. }
  709. else
  710. rc = true;
  711. }
  712. else
  713. {
  714. rc = m_ldap_client->authorize(rtype, sec_user, rlist, reslist->getName());
  715. }
  716. return rc;
  717. }
  718. SecAccessFlags CLdapSecManager::authorizeEx(SecResourceType rtype, ISecUser & user, const char * resourcename, IEspSecureContext* secureContext)
  719. {
  720. if(!resourcename || !*resourcename)
  721. return SecAccess_Full;
  722. Owned<ISecResourceList> rlist;
  723. rlist.setown(createResourceList("resources", secureContext));
  724. rlist->addResource(resourcename);
  725. bool ok = authorizeEx(rtype, user, rlist.get(), secureContext);
  726. if(ok)
  727. return rlist->queryResource(0)->getAccessFlags();
  728. else
  729. return SecAccess_Unavailable;
  730. }
  731. bool CLdapSecManager::authorizeEx(SecResourceType rtype, ISecUser& sec_user, ISecResourceList * Resources, bool doAuthentication)
  732. {
  733. if(doAuthentication && !authenticate(&sec_user))
  734. {
  735. return false;
  736. }
  737. CLdapSecResourceList * reslist = (CLdapSecResourceList*)Resources;
  738. if(!reslist)
  739. return true;
  740. IArrayOf<ISecResource>& rlist = reslist->getResourceList();
  741. int nResources = rlist.length();
  742. int ri;
  743. for(ri = 0; ri < nResources; ri++)
  744. {
  745. ISecResource* res = &rlist.item(ri);
  746. if(res != NULL)
  747. res->setResourceType(rtype);
  748. }
  749. if (nResources <= 0)
  750. return true;
  751. bool rc;
  752. time_t tctime = getThreadCreateTime();
  753. if ((m_permissionsCache->isCacheEnabled() || (m_permissionsCache->isTransactionalEnabled() && tctime > 0)) && (!m_cache_off[rtype]))
  754. {
  755. bool* cached_found = (bool*)alloca(nResources*sizeof(bool));
  756. int nFound = m_permissionsCache->lookup(sec_user, rlist, cached_found);
  757. if (nFound < nResources)
  758. {
  759. IArrayOf<ISecResource> rlist2;
  760. int i;
  761. for (i=0; i < nResources; i++)
  762. {
  763. if (*(cached_found+i) == false)
  764. {
  765. ISecResource& secRes = rlist.item(i);
  766. secRes.Link();
  767. rlist2.append(secRes);
  768. //DBGLOG("CACHE: Fetching permissions for %s:%s", sec_user.getName(), secRes.getName());
  769. }
  770. }
  771. rc = m_ldap_client->authorize(rtype, sec_user, rlist2);
  772. if (rc)
  773. m_permissionsCache->add(sec_user, rlist2);
  774. }
  775. else
  776. rc = true;
  777. }
  778. else
  779. {
  780. rc = m_ldap_client->authorize(rtype, sec_user, rlist);
  781. }
  782. return rc;
  783. }
  784. SecAccessFlags CLdapSecManager::authorizeEx(SecResourceType rtype, ISecUser & user, const char * resourcename, bool doAuthentication)
  785. {
  786. if(!resourcename || !*resourcename)
  787. return SecAccess_Full;
  788. Owned<ISecResourceList> rlist;
  789. rlist.setown(createResourceList("resources"));
  790. rlist->addResource(resourcename);
  791. bool ok = authorizeEx(rtype, user, rlist.get(), doAuthentication);
  792. if(ok)
  793. return rlist->queryResource(0)->getAccessFlags();
  794. else
  795. return SecAccess_Unavailable;
  796. }
  797. SecAccessFlags CLdapSecManager::getAccessFlagsEx(SecResourceType rtype, ISecUser & user, const char * resourcename, IEspSecureContext* secureContext)
  798. {
  799. if(!resourcename || !*resourcename)
  800. return SecAccess_Unavailable;
  801. Owned<ISecResourceList> rlist0;
  802. rlist0.setown(createResourceList("resources", secureContext));
  803. rlist0->addResource(resourcename);
  804. CLdapSecResourceList * reslist = (CLdapSecResourceList*)rlist0.get();
  805. if(!reslist)
  806. return SecAccess_Unavailable;
  807. IArrayOf<ISecResource>& rlist = reslist->getResourceList();
  808. int nResources = rlist.length();
  809. int ri;
  810. for(ri = 0; ri < nResources; ri++)
  811. {
  812. ISecResource* res = &rlist.item(ri);
  813. if(res != NULL)
  814. res->setResourceType(rtype);
  815. }
  816. if (nResources <= 0)
  817. return SecAccess_Unavailable;
  818. bool ok = false;
  819. time_t tctime = getThreadCreateTime();
  820. if ((m_permissionsCache->isCacheEnabled() || (m_permissionsCache->isTransactionalEnabled() && tctime > 0)) && (!m_cache_off[rtype]))
  821. {
  822. bool* cached_found = (bool*)alloca(nResources*sizeof(bool));
  823. int nFound = m_permissionsCache->lookup(user, rlist, cached_found);
  824. if (nFound < nResources)
  825. {
  826. IArrayOf<ISecResource> rlist2;
  827. int i;
  828. for (i=0; i < nResources; i++)
  829. {
  830. if (*(cached_found+i) == false)
  831. {
  832. ISecResource& secRes = rlist.item(i);
  833. secRes.Link();
  834. rlist2.append(secRes);
  835. //DBGLOG("CACHE: Fetching permissions for %s:%s", sec_user.getName(), secRes.getName());
  836. }
  837. }
  838. ok = m_ldap_client->authorize(rtype, user, rlist2);
  839. if (ok)
  840. m_permissionsCache->add(user, rlist2);
  841. }
  842. else
  843. ok = true;
  844. }
  845. else
  846. {
  847. ok = m_ldap_client->authorize(rtype, user, rlist);
  848. }
  849. //bool ok = authorizeEx(rtype, user, rlist.get());
  850. if(ok)
  851. return rlist0->queryResource(0)->getAccessFlags();
  852. else
  853. return SecAccess_Unavailable;
  854. }
  855. bool CLdapSecManager::authorize(ISecUser& sec_user, ISecResourceList * Resources, IEspSecureContext* secureContext)
  856. {
  857. return authorizeEx(RT_DEFAULT, sec_user, Resources, secureContext);
  858. }
  859. SecAccessFlags CLdapSecManager::authorizeFileScope(ISecUser & user, const char * filescope, IEspSecureContext* secureContext)
  860. {
  861. if(filescope == 0 || filescope[0] == '\0')
  862. return SecAccess_Full;
  863. StringBuffer managedFilescope;
  864. if(m_permissionsCache->isCacheEnabled() && !m_usercache_off)
  865. {
  866. SecAccessFlags accessFlags;
  867. //See if file scope in question is managed by LDAP permissions.
  868. // If not, return default file permission (dont call out to LDAP)
  869. // If is, look in cache for permission of longest matching managed scope strings. If found return that permission (no call to LDAP),
  870. // otherwise a call to LDAP "authorizeFileScope" is necessary, specifying the longest matching managed scope string
  871. bool gotPerms = m_permissionsCache->queryPermsManagedFileScope(user, filescope, managedFilescope, &accessFlags);
  872. if (gotPerms)
  873. return accessFlags;
  874. }
  875. Owned<ISecResourceList> rlist;
  876. rlist.setown(createResourceList("FileScope", secureContext));
  877. rlist->addResource(managedFilescope.length() ? managedFilescope.str() : filescope );
  878. bool ok = authorizeFileScope(user, rlist.get(), secureContext);
  879. if(ok)
  880. return rlist->queryResource(0)->getAccessFlags();
  881. else
  882. return SecAccess_Unavailable;
  883. }
  884. bool CLdapSecManager::authorizeFileScope(ISecUser & user, ISecResourceList * resources, IEspSecureContext* secureContext)
  885. {
  886. return authorizeEx(RT_FILE_SCOPE, user, resources, secureContext);
  887. }
  888. bool CLdapSecManager::authorizeViewScope(ISecUser & user, StringArray & filenames, StringArray & columnnames)
  889. {
  890. if (filenames.length() != columnnames.length())
  891. {
  892. PROGLOG("Error authorizing view scope: number of filenames (%d) do not match number of columnnames (%d).", filenames.length(), columnnames.length());
  893. return false;
  894. }
  895. const char* username = user.getName();
  896. StringArray viewnames, viewdescriptions, viewManagedBy;
  897. queryAllViews(viewnames, viewdescriptions, viewManagedBy);
  898. // All views where user belongs must pass
  899. ForEachItemIn(i, viewnames)
  900. {
  901. const char* viewname = viewnames.item(i);
  902. if (userInView(username, viewname))
  903. {
  904. Owned<ISecResourceList> resList;
  905. resList.setown(new CLdapSecResourceList(viewname));
  906. // Inefficient loop because we are adding same used columns all over again for each views.
  907. // we can improve the performance later if there is a way to rename and reuse same ISecResourceList for each view.
  908. ForEachItemIn(j, filenames)
  909. {
  910. StringBuffer resourceName;
  911. resourceName.append("QueryAccessedColumns");
  912. resourceName.append(j);
  913. ISecResource* res = resList->addResource(resourceName);
  914. res->addParameter("file", filenames.item(j));
  915. res->addParameter("column", columnnames.item(j));
  916. }
  917. if (!authorizeEx(RT_VIEW_SCOPE, user, resList.get()))
  918. {
  919. PROGLOG("View scope authorization denied by a view %s for a user %s", viewname, username);
  920. return false;
  921. }
  922. }
  923. }
  924. return true;
  925. }
  926. SecAccessFlags CLdapSecManager::authorizeWorkunitScope(ISecUser & user, const char * wuscope, IEspSecureContext* secureContext)
  927. {
  928. if(wuscope == 0 || wuscope[0] == '\0')
  929. return SecAccess_Full;
  930. Owned<ISecResourceList> rlist;
  931. rlist.setown(createResourceList("WorkunitScope", secureContext));
  932. rlist->addResource(wuscope);
  933. bool ok = authorizeWorkunitScope(user, rlist.get(), secureContext);
  934. if(ok)
  935. return rlist->queryResource(0)->getAccessFlags();
  936. else
  937. return SecAccess_Unavailable;
  938. }
  939. bool CLdapSecManager::authorizeWorkunitScope(ISecUser & user, ISecResourceList * resources, IEspSecureContext* secureContext)
  940. {
  941. return authorizeEx(RT_WORKUNIT_SCOPE, user, resources, secureContext);
  942. }
  943. bool CLdapSecManager::addResourcesEx(SecResourceType rtype, ISecUser& sec_user, ISecResourceList * resources, SecPermissionType ptype, const char* basedn, IEspSecureContext* secureContext)
  944. {
  945. CLdapSecResourceList * reslist = (CLdapSecResourceList*)resources;
  946. if(!reslist)
  947. return true;
  948. IArrayOf<ISecResource>& rlist = reslist->getResourceList();
  949. if(rlist.length() <= 0)
  950. return true;
  951. return m_ldap_client->addResources(rtype, sec_user, rlist, ptype, basedn);
  952. }
  953. bool CLdapSecManager::addResourceEx(SecResourceType rtype, ISecUser& user, const char* resourcename, SecPermissionType ptype, const char* basedn, IEspSecureContext* secureContext)
  954. {
  955. Owned<ISecResourceList> rlist;
  956. rlist.setown(createResourceList("resources", secureContext));
  957. rlist->addResource(resourcename);
  958. return addResourcesEx(rtype, user, rlist.get(), ptype, basedn, secureContext);
  959. }
  960. bool CLdapSecManager::addResources(ISecUser& sec_user, ISecResourceList * resources, IEspSecureContext* secureContext)
  961. {
  962. return addResourcesEx(RT_DEFAULT, sec_user, resources, PT_ADMINISTRATORS_ONLY, nullptr, secureContext);
  963. }
  964. bool CLdapSecManager::addUser(ISecUser & user, IEspSecureContext* secureContext)
  965. {
  966. bool ok = m_ldap_client->addUser(user);
  967. if(!ok)
  968. return false;
  969. return m_pp->retrieveUserInfo(user);
  970. }
  971. ISecUser * CLdapSecManager::lookupUser(unsigned uid, IEspSecureContext* secureContext)
  972. {
  973. return m_ldap_client->lookupUser(uid);
  974. }
  975. ISecUser * CLdapSecManager::findUser(const char * username, IEspSecureContext* secureContext)
  976. {
  977. if(username == NULL || strlen(username) == 0)
  978. {
  979. DBGLOG("findUser - username is empty");
  980. return NULL;
  981. }
  982. Owned<ISecUser> user;
  983. user.setown(createUser(username, secureContext));
  984. try
  985. {
  986. bool ok = m_pp->retrieveUserInfo(*user);
  987. if(ok)
  988. {
  989. return LINK(user.get());
  990. }
  991. else
  992. {
  993. return NULL;
  994. }
  995. }
  996. catch(IException*)
  997. {
  998. return NULL;
  999. }
  1000. catch(...)
  1001. {
  1002. return NULL;
  1003. }
  1004. }
  1005. ISecUserIterator * CLdapSecManager::getAllUsers(IEspSecureContext* secureContext)
  1006. {
  1007. synchronized block(m_monitor);
  1008. m_user_array.popAll(true);
  1009. m_ldap_client->retrieveUsers(m_user_array);
  1010. return new ArrayIIteratorOf<IUserArray, ISecUser, ISecUserIterator>(m_user_array);
  1011. }
  1012. void CLdapSecManager::searchUsers(const char* searchstr, IUserArray& users)
  1013. {
  1014. m_ldap_client->retrieveUsers(searchstr, users);
  1015. }
  1016. ISecItemIterator* CLdapSecManager::getUsersSorted(const char* userName, UserField* sortOrder, const unsigned pageStartFrom,
  1017. const unsigned pageSize, unsigned* total, __int64* cacheHint)
  1018. {
  1019. return m_ldap_client->getUsersSorted(userName, sortOrder, pageStartFrom, pageSize, total, cacheHint);
  1020. }
  1021. void CLdapSecManager::getAllUsers(IUserArray& users)
  1022. {
  1023. m_ldap_client->retrieveUsers(users);
  1024. }
  1025. bool CLdapSecManager::getResources(SecResourceType rtype, const char * basedn, IArrayOf<ISecResource> & resources, IEspSecureContext* secureContext)
  1026. {
  1027. return m_ldap_client->getResources(rtype, basedn, "", "", resources);
  1028. }
  1029. bool CLdapSecManager::getResourcesEx(SecResourceType rtype, const char * basedn, const char* searchstr, IArrayOf<ISecResource> & resources)
  1030. {
  1031. return m_ldap_client->getResources(rtype, basedn, "", searchstr, resources);
  1032. }
  1033. ISecItemIterator* CLdapSecManager::getResourcesSorted(SecResourceType rtype, const char * basedn, const char * resourceName, unsigned extraNameFilter,
  1034. ResourceField* sortOrder, const unsigned pageStartFrom, const unsigned pageSize, unsigned *total, __int64 *cachehint)
  1035. {
  1036. return m_ldap_client->getResourcesSorted(rtype, basedn, resourceName, extraNameFilter, sortOrder, pageStartFrom, pageSize, total, cachehint);
  1037. }
  1038. ISecItemIterator* CLdapSecManager::getResourcePermissionsSorted(const char* name, enum ACCOUNT_TYPE_REQ accountType, const char* baseDN, const char* rtype, const char* prefix,
  1039. ResourcePermissionField* sortOrder, const unsigned pageStartFrom, const unsigned pageSize, unsigned *total, __int64 *cachehint)
  1040. {
  1041. return m_ldap_client->getResourcePermissionsSorted(name, accountType, baseDN, rtype, prefix, sortOrder, pageStartFrom, pageSize, total, cachehint);
  1042. }
  1043. void CLdapSecManager::setExtraParam(const char * name, const char * value, IEspSecureContext* secureContext)
  1044. {
  1045. if(name == NULL || name[0] == '\0')
  1046. {
  1047. DBGLOG("CLdapSecManager::setExtraParam name must be provided");
  1048. return;
  1049. }
  1050. if (!m_extraparams)
  1051. m_extraparams.setown(createProperties(false));
  1052. m_extraparams->setProp(name, value);
  1053. if(value != NULL && value[0] != '\0')
  1054. {
  1055. if(stricmp(name, "resourcesBasedn") == 0)
  1056. m_ldap_client->setResourceBasedn(value, RT_DEFAULT);
  1057. else if(stricmp(name, "workunitsBasedn") == 0)
  1058. m_ldap_client->setResourceBasedn(value, RT_WORKUNIT_SCOPE);
  1059. }
  1060. }
  1061. IAuthMap * CLdapSecManager::createAuthMap(IPropertyTree * authconfig, IEspSecureContext* secureContext)
  1062. {
  1063. CAuthMap* authmap = new CAuthMap();
  1064. IPropertyTreeIterator *loc_iter = NULL;
  1065. loc_iter = authconfig->getElements(".//Location");
  1066. if (loc_iter != NULL)
  1067. {
  1068. IPropertyTree *location = NULL;
  1069. loc_iter->first();
  1070. while(loc_iter->isValid())
  1071. {
  1072. location = &loc_iter->query();
  1073. if (location)
  1074. {
  1075. StringBuffer pathstr, rstr, required, description;
  1076. location->getProp("@path", pathstr);
  1077. location->getProp("@resource", rstr);
  1078. location->getProp("@required", required);
  1079. location->getProp("@description", description);
  1080. if(rstr.length() == 0)
  1081. throw MakeStringException(-1, "resource empty in Authenticate/Location");
  1082. if(pathstr.length() == 0)
  1083. throw MakeStringException(-1, "path empty in Authenticate/Location for resource '%s'", rstr.str());
  1084. ISecResourceList* rlist = authmap->queryResourceList(pathstr.str());
  1085. if(rlist == NULL)
  1086. {
  1087. rlist = createResourceList("ldapsecurity", secureContext);
  1088. authmap->add(pathstr.str(), rlist);
  1089. }
  1090. ISecResource* rs = rlist->addResource(rstr.str());
  1091. SecAccessFlags requiredaccess = str2perm(required.str());
  1092. rs->setRequiredAccessFlags(requiredaccess);
  1093. rs->setDescription(description.str());
  1094. }
  1095. loc_iter->next();
  1096. }
  1097. loc_iter->Release();
  1098. loc_iter = NULL;
  1099. }
  1100. authmap->shareWithManager(*this, secureContext);
  1101. return authmap;
  1102. }
  1103. IAuthMap * CLdapSecManager::createFeatureMap(IPropertyTree * authconfig, IEspSecureContext* secureContext)
  1104. {
  1105. CAuthMap* feature_authmap = new CAuthMap();
  1106. IPropertyTreeIterator *feature_iter = NULL;
  1107. feature_iter = authconfig->getElements(".//Feature");
  1108. if (feature_iter != NULL)
  1109. {
  1110. IPropertyTree *feature = NULL;
  1111. feature_iter->first();
  1112. while(feature_iter->isValid())
  1113. {
  1114. feature = &feature_iter->query();
  1115. if (feature)
  1116. {
  1117. StringBuffer pathstr, rstr, required, description;
  1118. feature->getProp("@path", pathstr);
  1119. feature->getProp("@resource", rstr);
  1120. feature->getProp("@required", required);
  1121. feature->getProp("@description", description);
  1122. ISecResourceList* rlist = feature_authmap->queryResourceList(pathstr.str());
  1123. if(rlist == NULL)
  1124. {
  1125. if(rstr.length() == 0)
  1126. throw MakeStringException(-1, "resource empty in Feature Map");
  1127. if(pathstr.length() == 0)
  1128. throw MakeStringException(-1, "path empty in Feature Map for resource '%s'", rstr.str());
  1129. rlist = createResourceList(pathstr.str(), secureContext);
  1130. feature_authmap->add(pathstr.str(), rlist);
  1131. }
  1132. ISecResource* rs = rlist->addResource(rstr.str());
  1133. SecAccessFlags requiredaccess = str2perm(required.str());
  1134. rs->setRequiredAccessFlags(requiredaccess);
  1135. rs->setDescription(description.str());
  1136. }
  1137. feature_iter->next();
  1138. }
  1139. feature_iter->Release();
  1140. feature_iter = NULL;
  1141. }
  1142. feature_authmap->shareWithManager(*this, secureContext);
  1143. return feature_authmap;
  1144. }
  1145. bool CLdapSecManager::updateUserPassword(ISecUser& user, const char* newPassword, const char* currPassword, IEspSecureContext* secureContext)
  1146. {
  1147. // Authenticate User first
  1148. if(!authenticate(&user) && user.getAuthenticateStatus() != AS_PASSWORD_VALID_BUT_EXPIRED)
  1149. {
  1150. return false;
  1151. }
  1152. bool ok = m_ldap_client->updateUserPassword(user, newPassword, currPassword);
  1153. return ok;
  1154. }
  1155. bool CLdapSecManager::updateUser(const char* type, ISecUser& user)
  1156. {
  1157. bool ok = m_ldap_client->updateUser(type, user);
  1158. if(ok && m_permissionsCache->isCacheEnabled() && !m_usercache_off)
  1159. m_permissionsCache->removeFromUserCache(user);
  1160. return ok;
  1161. }
  1162. bool CLdapSecManager::updateUserPassword(const char* username, const char* newPassword)
  1163. {
  1164. return m_ldap_client->updateUserPassword(username, newPassword);
  1165. }
  1166. void CLdapSecManager::getAllGroups(StringArray & groups, StringArray & managedBy, StringArray & descriptions, IEspSecureContext* secureContext)
  1167. {
  1168. m_ldap_client->getAllGroups(groups, managedBy, descriptions);
  1169. }
  1170. ISecItemIterator* CLdapSecManager::getGroupsSorted(GroupField* sortOrder, const unsigned pageStartFrom, const unsigned pageSize,
  1171. unsigned *total, __int64 *cachehint)
  1172. {
  1173. return m_ldap_client->getGroupsSorted(sortOrder, pageStartFrom, pageSize, total, cachehint);
  1174. }
  1175. ISecItemIterator* CLdapSecManager::getGroupMembersSorted(const char* groupName, UserField* sortOrder, const unsigned pageStartFrom, const unsigned pageSize,
  1176. unsigned *total, __int64 *cachehint)
  1177. {
  1178. return m_ldap_client->getGroupMembersSorted(groupName, sortOrder, pageStartFrom, pageSize, total, cachehint);
  1179. }
  1180. bool CLdapSecManager::getPermissionsArray(const char* basedn, SecResourceType rtype, const char* name, IArrayOf<CPermission>& permissions)
  1181. {
  1182. return m_ldap_client->getPermissionsArray(basedn, rtype, name, permissions);
  1183. }
  1184. void CLdapSecManager::addGroup(const char* groupname, const char * groupOwner, const char * groupDesc)
  1185. {
  1186. m_ldap_client->addGroup(groupname, groupOwner, groupDesc);
  1187. }
  1188. void CLdapSecManager::deleteGroup(const char* groupname)
  1189. {
  1190. m_ldap_client->deleteGroup(groupname);
  1191. }
  1192. bool CLdapSecManager::changePermission(CPermissionAction& action)
  1193. {
  1194. return m_ldap_client->changePermission(action);
  1195. }
  1196. void CLdapSecManager::getGroups(const char* username, StringArray & groups)
  1197. {
  1198. m_ldap_client->getGroups(username, groups);
  1199. }
  1200. void CLdapSecManager::changeUserGroup(const char* action, const char* username, const char* groupname)
  1201. {
  1202. m_ldap_client->changeUserGroup(action, username, groupname);
  1203. }
  1204. bool CLdapSecManager::deleteUser(ISecUser* user)
  1205. {
  1206. return m_ldap_client->deleteUser(user);
  1207. }
  1208. void CLdapSecManager::getGroupMembers(const char* groupname, StringArray & users)
  1209. {
  1210. m_ldap_client->getGroupMembers(groupname, users);
  1211. }
  1212. void CLdapSecManager::deleteResource(SecResourceType rtype, const char * name, const char * basedn, IEspSecureContext* secureContext)
  1213. {
  1214. m_ldap_client->deleteResource(rtype, name, basedn);
  1215. time_t tctime = getThreadCreateTime();
  1216. if ((m_permissionsCache->isCacheEnabled() || (m_permissionsCache->isTransactionalEnabled() && tctime > 0)) && (!m_cache_off[rtype]))
  1217. m_permissionsCache->remove(rtype, name);
  1218. }
  1219. void CLdapSecManager::renameResource(SecResourceType rtype, const char * oldname, const char * newname, const char * basedn, IEspSecureContext* secureContext)
  1220. {
  1221. m_ldap_client->renameResource(rtype, oldname, newname, basedn);
  1222. time_t tctime = getThreadCreateTime();
  1223. if ((m_permissionsCache->isCacheEnabled() || (m_permissionsCache->isTransactionalEnabled() && tctime > 0)) && (!m_cache_off[rtype]))
  1224. m_permissionsCache->remove(rtype, oldname);
  1225. }
  1226. void CLdapSecManager::copyResource(SecResourceType rtype, const char * oldname, const char * newname, const char * basedn, IEspSecureContext* secureContext)
  1227. {
  1228. m_ldap_client->copyResource(rtype, oldname, newname, basedn);
  1229. }
  1230. void CLdapSecManager::normalizeDn(const char* dn, StringBuffer& ndn)
  1231. {
  1232. m_ldap_client->normalizeDn(dn, ndn);
  1233. }
  1234. bool CLdapSecManager::isSuperUser(ISecUser* user)
  1235. {
  1236. return m_ldap_client->isSuperUser(user);
  1237. }
  1238. ILdapConfig* CLdapSecManager::queryConfig()
  1239. {
  1240. return m_ldap_client->queryConfig();
  1241. }
  1242. void CLdapSecManager::cacheSwitch(SecResourceType rtype, bool on, IEspSecureContext* secureContext)
  1243. {
  1244. m_cache_off[rtype] = !on;
  1245. // To make things simple, turning off any resource type's permission cache turns off the userCache.
  1246. if(!on)
  1247. m_usercache_off = true;
  1248. }
  1249. int CLdapSecManager::countUsers(const char* searchstr, int limit)
  1250. {
  1251. return m_ldap_client->countUsers(searchstr, limit);
  1252. }
  1253. int CLdapSecManager::countResources(const char* basedn, const char* searchstr, int limit)
  1254. {
  1255. return m_ldap_client->countResources(basedn, searchstr, limit);
  1256. }
  1257. bool CLdapSecManager::getUserInfo(ISecUser& user, const char* infotype)
  1258. {
  1259. return m_ldap_client->getUserInfo(user, infotype);
  1260. }
  1261. bool CLdapSecManager::createUserScopes(IEspSecureContext* secureContext)
  1262. {
  1263. Owned<ISecUserIterator> it = getAllUsers(secureContext);
  1264. it->first();
  1265. bool rc = true;
  1266. while(it->isValid())
  1267. {
  1268. ISecUser &user = it->get();
  1269. if (!m_ldap_client->createUserScope(user))
  1270. {
  1271. PROGLOG("CLdapSecManager::createUserScopes Error creating user scope for user '%s'", user.getName());
  1272. rc = false;
  1273. }
  1274. it->next();
  1275. }
  1276. return rc;
  1277. }
  1278. aindex_t CLdapSecManager::getManagedScopeTree(SecResourceType rtype, const char * basedn, IArrayOf<ISecResource>& scopes, IEspSecureContext* secureContext)
  1279. {
  1280. return m_ldap_client->getManagedScopeTree(nullptr, rtype, basedn, scopes);
  1281. }
  1282. SecAccessFlags CLdapSecManager::queryDefaultPermission(ISecUser& user, IEspSecureContext* secureContext)
  1283. {
  1284. return m_ldap_client->queryDefaultPermission(user);
  1285. }
  1286. bool CLdapSecManager::clearPermissionsCache(ISecUser& user, IEspSecureContext* secureContext)
  1287. {
  1288. if(m_permissionsCache->isCacheEnabled())
  1289. {
  1290. if (!isEmptyString(user.getName()) && !isEmptyString(user.credentials().getPassword()) && !authenticate(&user))
  1291. {
  1292. PROGLOG("User %s not authorized to clear permissions cache", user.getName());
  1293. return false;
  1294. }
  1295. if (!isSuperUser(&user))
  1296. {
  1297. PROGLOG("User %s denied, only a superuser can clear permissions cache", user.getName());
  1298. return false;
  1299. }
  1300. m_permissionsCache->flush();
  1301. }
  1302. return true;
  1303. }
  1304. bool CLdapSecManager::authenticateUser(ISecUser & user, bool *superUser, IEspSecureContext* secureContext)
  1305. {
  1306. if (!authenticate(&user))
  1307. return false;
  1308. if (superUser)
  1309. *superUser = isSuperUser(&user);
  1310. return true;
  1311. }
  1312. bool CLdapSecManager::logoutUser(ISecUser & user, IEspSecureContext* secureContext)
  1313. {
  1314. //remove user from permissions cache
  1315. m_permissionsCache->removeFromUserCache(user);
  1316. user.setAuthenticateStatus(AS_UNKNOWN);
  1317. user.credentials().setSessionToken(0);
  1318. return true;
  1319. }
  1320. bool CLdapSecManager::retrieveUserData(ISecUser& requestedUser, ISecUser* requestingUser, IEspSecureContext* secureContext)
  1321. {
  1322. return false;
  1323. }
  1324. //Data View related interfaces
  1325. void CLdapSecManager::createView(const char* viewName, const char * viewDescription)
  1326. {
  1327. m_ldap_client->createView(viewName, viewDescription);
  1328. }
  1329. void CLdapSecManager::deleteView(const char* viewName)
  1330. {
  1331. m_ldap_client->deleteView(viewName);
  1332. }
  1333. void CLdapSecManager::queryAllViews(StringArray & viewNames, StringArray & viewDescriptions, StringArray & viewManagedBy)
  1334. {
  1335. m_ldap_client->queryAllViews(viewNames, viewDescriptions, viewManagedBy);
  1336. }
  1337. void CLdapSecManager::addViewColumns(const char* viewName, StringArray & files, StringArray & columns)
  1338. {
  1339. m_ldap_client->addViewColumns(viewName, files, columns);
  1340. }
  1341. void CLdapSecManager::removeViewColumns(const char* viewName, StringArray & files, StringArray & columns)
  1342. {
  1343. m_ldap_client->removeViewColumns(viewName, files, columns);
  1344. }
  1345. void CLdapSecManager::queryViewColumns(const char* viewName, StringArray & files, StringArray & columns)
  1346. {
  1347. m_ldap_client->queryViewColumns(viewName, files, columns);
  1348. }
  1349. void CLdapSecManager::addViewMembers(const char* viewName, StringArray & viewUsers, StringArray & viewGroups)
  1350. {
  1351. m_ldap_client->addViewMembers(viewName, viewUsers, viewGroups);
  1352. }
  1353. void CLdapSecManager::removeViewMembers(const char* viewName, StringArray & viewUsers, StringArray & viewGroups)
  1354. {
  1355. m_ldap_client->removeViewMembers(viewName, viewUsers, viewGroups);
  1356. }
  1357. void CLdapSecManager::queryViewMembers(const char* viewName, StringArray & viewUsers, StringArray & viewGroups)
  1358. {
  1359. m_ldap_client->queryViewMembers(viewName, viewUsers, viewGroups);
  1360. }
  1361. bool CLdapSecManager::userInView(const char * user, const char* viewName)
  1362. {
  1363. return m_ldap_client->userInView(user, viewName);
  1364. }
  1365. extern "C"
  1366. {
  1367. LDAPSECURITY_API ISecManager * newLdapSecManager(const char *serviceName, IPropertyTree &config)
  1368. {
  1369. return new CLdapSecManager(serviceName, config);
  1370. }
  1371. LDAPSECURITY_API IAuthMap *newDefaultAuthMap(IPropertyTree* config)
  1372. {
  1373. CAuthMap* authmap = new CAuthMap();
  1374. IPropertyTreeIterator *loc_iter = NULL;
  1375. loc_iter = config->getElements(".//Location");
  1376. if (loc_iter != NULL)
  1377. {
  1378. IPropertyTree *location = NULL;
  1379. loc_iter->first();
  1380. while(loc_iter->isValid())
  1381. {
  1382. location = &loc_iter->query();
  1383. if (location)
  1384. {
  1385. StringBuffer pathstr;
  1386. location->getProp("@path", pathstr);
  1387. if (pathstr.isEmpty())
  1388. {
  1389. StringBuffer rstr;
  1390. location->getProp("@resource", rstr);
  1391. throw MakeStringException(-1, "path empty in DefaultAuthMap for resource '%s'", rstr.isEmpty() ? "unspecified" : rstr.str());
  1392. }
  1393. authmap->add(pathstr.str(), NULL);
  1394. }
  1395. loc_iter->next();
  1396. }
  1397. loc_iter->Release();
  1398. loc_iter = NULL;
  1399. }
  1400. return authmap;
  1401. }
  1402. }