aci.cpp 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #pragma warning(disable:4786)
  15. #include "platform.h"
  16. #include "aci.ipp"
  17. #include "ldapsecurity.ipp"
  18. /****************************************************************
  19. 1 - SunOne aci syntax -
  20. http://support.sas.com/rnd/itech/doc9/admin_ldap/security/ld_acc.html
  21. (target="ldap:///dn")(targetattr="attrname")
  22. [(targetfilter="rfc2254-style filter")]
  23. ( version 3.0; acl "name"; (allow | deny)
  24. (read, write, search, compare, selfwrite, add, delete )
  25. (userdn | groupdn)="ldap:///dn";)
  26. 2 - OpenLdap aci syntax -
  27. http://www.openldap.org/faq/data/cache/634.html
  28. < aci > ::= < acl syntax >
  29. < acl syntax > ::= <familyOID> + '#' + <scope > + '#'
  30. + < rights > + '#' + < dnType >
  31. + '#' + < subjectDn >
  32. < subjectDn > ::= < printable string >
  33. < familyOid > ::= < oid >
  34. < scope > ::= "entry" | "subtree" | <level>
  35. < level > ::= numericstring
  36. < dnType > ::= "access-id" | "role" | "group" | "self"
  37. < rights > ::= [ ] | [ < right > + [ '$'
  38. + <right> ] * ]
  39. < right > ::= <action > + ';' + <permissions>
  40. + ';' + <attrs>
  41. < action > ::= "grant" | "deny"
  42. < permissions > ::= [ ] | [ < permission >
  43. + [ ',' + <permission> ] * ]
  44. < attrs > ::= [ < attributeString>
  45. + [ ',' + < attributeString > ] * ]
  46. < attributeString > ::= "[all]" | "[entry]"
  47. | <printableString >
  48. < permission > ::= "r" | "s" | "w" | "c"
  49. examples -
  50. OpenLDAPaci: 1#entry#grant;r,w,s,c;[all]#group#cn=enterprise admins,ou=groups,o=acme
  51. OpenLDAPaci: 2#entry#grant;r,w,s,c;[all]#group#cn=dallas admins,ou=groups,l=dallas,o=acme
  52. OpenLDAPaci: 3#entry#grant;r,w,s,c;userPassword,mail;r,s,c;[all]#access-id#uid=user1,ou=people,l=dallas,o=acme
  53. OpenLDAPaci: 4#entry#grant;r,s,c;[all]#group#cn=all acme,ou=groups,o=acme
  54. 3 - The ietf draft that none of them conform to (openldap is close) -
  55. http://www.ietf.org/proceedings/02mar/I-D/draft-ietf-ldapext-acl-model-08.txt
  56. *****************************************************************/
  57. interface IAci : implements IInterface
  58. {
  59. virtual StringBuffer& target() = 0;
  60. virtual StringArray& userdns() = 0;
  61. virtual StringArray& groupdns() = 0;
  62. virtual bool isDeny() = 0;
  63. virtual int permission() = 0;
  64. virtual StringBuffer& serialize(StringBuffer& acibuf) = 0;
  65. virtual void debugPrintout() = 0;
  66. };
  67. /****************************************************************
  68. * Class CAci
  69. ****************************************************************/
  70. class CAci : public CInterface, implements IAci
  71. {
  72. private:
  73. StringBuffer m_targetattr;
  74. StringBuffer m_target;
  75. StringBuffer m_version;
  76. StringBuffer m_name;
  77. StringArray m_perms;
  78. bool m_isDeny;
  79. StringArray m_userdns;
  80. StringArray m_groupdns;
  81. int m_permission;
  82. public:
  83. IMPLEMENT_IINTERFACE;
  84. CAci(bool _isDeny, int _perm, ACT_TYPE _act_type, const char* _dn)
  85. {
  86. m_isDeny = _isDeny;
  87. m_targetattr.append("*");
  88. m_version.append("3.0");
  89. Owned<IJlibDateTime> timeNow = createDateTimeNow();
  90. SCMStringBuffer dateString;
  91. timeNow->getDateString(dateString);
  92. m_name.appendf("%s_%d", dateString.str(), getRandom());
  93. if(_act_type == GROUP_ACT)
  94. m_groupdns.append(_dn);
  95. else
  96. m_userdns.append(_dn);
  97. if((_perm & NewSecAccess_Full) == NewSecAccess_Full)
  98. {
  99. m_perms.append("all");
  100. }
  101. else
  102. {
  103. if((_perm & NewSecAccess_Write) == NewSecAccess_Write)
  104. m_perms.append("write");
  105. if((_perm & NewSecAccess_Read) == NewSecAccess_Read)
  106. m_perms.append("read");
  107. if((_perm & NewSecAccess_Access) == NewSecAccess_Access)
  108. {
  109. m_perms.append("compare");
  110. m_perms.append("search");
  111. }
  112. }
  113. m_permission = _perm;
  114. }
  115. CAci(const char* acistr)
  116. {
  117. //targetattr
  118. const char* curptr = strstr(acistr, "(targetattr");
  119. if(curptr != NULL)
  120. {
  121. while(*curptr != '"' && *curptr != '\0')
  122. curptr++;
  123. if(*curptr != '\0')
  124. curptr++;
  125. while(*curptr != '"' && curptr != '\0')
  126. {
  127. m_targetattr.append(*curptr);
  128. curptr++;
  129. }
  130. }
  131. // target
  132. curptr = strstr(acistr, "(target ");
  133. if(curptr == NULL)
  134. curptr = strstr(acistr, "target=");
  135. if(curptr != NULL)
  136. {
  137. while(*curptr != '"' && *curptr != '\0')
  138. curptr++;
  139. if(*curptr != '\0')
  140. curptr++;
  141. if(strncmp(curptr, "ldap:///", 8) == 0)
  142. curptr += 8;
  143. while(*curptr != '"' && curptr != '\0')
  144. {
  145. m_target.append(*curptr);
  146. curptr++;
  147. }
  148. }
  149. curptr = strstr(acistr, "(version ");
  150. if(curptr != NULL)
  151. {
  152. //version
  153. while(*curptr != ' ' && *curptr != '\0')
  154. curptr++;
  155. if(*curptr != '\0')
  156. curptr++;
  157. while(*curptr != ';' && *curptr != '\0')
  158. {
  159. m_version.append(*curptr);
  160. curptr++;
  161. }
  162. if(*curptr != '\0')
  163. curptr++;
  164. //name
  165. while(*curptr != ' ' && *curptr != '\0')
  166. curptr++;
  167. if(*curptr != '\0')
  168. curptr++;
  169. while(*curptr != '"' && *curptr != '\0')
  170. curptr++;
  171. if(*curptr != '\0')
  172. curptr++;
  173. while(*curptr != '"' && *curptr != '\0')
  174. {
  175. m_name.append(*curptr++);
  176. }
  177. //permissions
  178. StringBuffer allow;
  179. while(*curptr == ' ' || *curptr == ';' || *curptr == '"')
  180. curptr++;
  181. while(*curptr != ' ' && *curptr != '\0')
  182. allow.append(*curptr++);
  183. m_isDeny = false;
  184. if(strcmp(allow.str(), "deny") == 0)
  185. m_isDeny = true;
  186. while(*curptr != '(' && *curptr != '\0')
  187. curptr++;
  188. if(*curptr != '\0')
  189. curptr++;
  190. while(*curptr != '\0')
  191. {
  192. StringBuffer curperm;
  193. while(*curptr != ',' && *curptr != ')')
  194. {
  195. curperm.append(*curptr);
  196. curptr++;
  197. }
  198. m_perms.append(curperm.str());
  199. if(*curptr != '\0')
  200. curptr++;
  201. if(*(curptr-1) == ')')
  202. break;
  203. }
  204. // user/group dns
  205. while(*curptr != '(' && *curptr != '\0')
  206. curptr++;
  207. if(*curptr != '\0')
  208. curptr++;
  209. while(*curptr != '\0')
  210. {
  211. while(*curptr == ' ')
  212. curptr++;
  213. StringBuffer dnname;
  214. while(*curptr != ' ' && *curptr != '=' && *curptr != '\0')
  215. {
  216. dnname.append(*curptr);
  217. curptr++;
  218. }
  219. while(*curptr != '"' && *curptr != '\0')
  220. curptr++;
  221. if(*curptr != '\0')
  222. curptr++;
  223. if(strncmp(curptr, "ldap:///", 8) == 0)
  224. curptr += 8;
  225. StringBuffer dn;
  226. while(*curptr != '"' && *curptr != '\0')
  227. {
  228. dn.append(*curptr);
  229. curptr++;
  230. }
  231. if(*curptr != '\0')
  232. curptr++;
  233. if(stricmp(dnname.str(), "userdn") == 0)
  234. m_userdns.append(dn.str());
  235. else if(stricmp(dnname.str(), "groupdn") == 0)
  236. m_groupdns.append(dn.str());
  237. while(*curptr == ' ')
  238. curptr++;
  239. if(*curptr == ')')
  240. break;
  241. while(*curptr != ' ' && *curptr != '\0')
  242. curptr++;
  243. }
  244. }
  245. //calculate the secperm
  246. m_permission = 0;
  247. ForEachItemIn(y, m_perms)
  248. {
  249. const char* onepermstr = m_perms.item(y);
  250. if(onepermstr == NULL || *onepermstr == '\0')
  251. continue;
  252. if(stricmp(onepermstr, "all") == 0)
  253. {
  254. m_permission |= NewSecAccess_Full;
  255. break;
  256. }
  257. else if(stricmp(onepermstr, "read") == 0)
  258. {
  259. m_permission |= NewSecAccess_Read;
  260. }
  261. else if(stricmp(onepermstr, "write") == 0)
  262. {
  263. m_permission |= NewSecAccess_Write;
  264. }
  265. else if(stricmp(onepermstr, "compare") == 0 || stricmp(onepermstr, "search") == 0)
  266. {
  267. m_permission |= NewSecAccess_Access;
  268. }
  269. }
  270. }
  271. virtual StringBuffer& target()
  272. {
  273. return m_target;
  274. }
  275. virtual StringArray& userdns()
  276. {
  277. return m_userdns;
  278. }
  279. virtual StringArray& groupdns()
  280. {
  281. return m_groupdns;
  282. }
  283. virtual bool isDeny()
  284. {
  285. return m_isDeny;
  286. }
  287. virtual int permission()
  288. {
  289. return m_permission;
  290. }
  291. virtual StringBuffer& serialize(StringBuffer& acibuf)
  292. {
  293. acibuf.appendf("(targetattr = \"%s\") (version %s;acl \"%s\";", m_targetattr.str(), m_version.str(), m_name.str());
  294. acibuf.append(m_isDeny?"deny (":"allow (");
  295. unsigned i;
  296. for(i = 0; i < m_perms.length(); i++)
  297. {
  298. if(i > 0)
  299. acibuf.append(",");
  300. acibuf.append(m_perms.item(i));
  301. }
  302. acibuf.append(")(");
  303. int ind = 0;
  304. for(i = 0; i < m_userdns.length(); i++)
  305. {
  306. if(ind > 0)
  307. acibuf.append(" or ");
  308. acibuf.appendf("userdn = \"ldap:///%s\"", m_userdns.item(i));
  309. ind++;
  310. }
  311. for(i = 0; i < m_groupdns.length(); i++)
  312. {
  313. if(ind > 0)
  314. acibuf.append(" or ");
  315. acibuf.appendf("groupdn = \"ldap:///%s\"", m_groupdns.item(i));
  316. ind++;
  317. }
  318. acibuf.append(");)");
  319. return acibuf;
  320. }
  321. virtual void debugPrintout()
  322. {
  323. printf("name: %s\nversion: %s\ntarget: <%s>\ntargetattr: <%s>\n", m_name.str(), m_version.str(), m_target.str(), m_targetattr.str());
  324. if(m_isDeny)
  325. printf("deny:\n");
  326. else
  327. printf("allow:\n");
  328. unsigned y;
  329. for(y = 0; y < m_perms.length(); y++)
  330. {
  331. printf("\t%s\n", m_perms.item(y));
  332. }
  333. printf("\nuserdns:\n");
  334. for(y = 0; y < m_userdns.length(); y++)
  335. {
  336. printf("\t%s\n", m_userdns.item(y));
  337. }
  338. printf("groupdns:\n");
  339. for(y = 0; y < m_groupdns.length(); y++)
  340. {
  341. printf("\t%s\n", m_groupdns.item(y));
  342. }
  343. }
  344. };
  345. /****************************************************************
  346. * Class COpenLdapAci
  347. ****************************************************************/
  348. class COpenLdapAci : public CInterface, implements IAci
  349. {
  350. private:
  351. StringBuffer m_name;
  352. StringBuffer m_target;
  353. StringBuffer m_perms;
  354. StringArray m_userdns;
  355. StringArray m_groupdns;
  356. bool m_isDeny;
  357. int m_permission;
  358. public:
  359. IMPLEMENT_IINTERFACE;
  360. COpenLdapAci(bool _isDeny, int _perm, ACT_TYPE _act_type, const char* _dn)
  361. {
  362. m_isDeny = _isDeny;
  363. Owned<IJlibDateTime> timeNow = createDateTimeNow();
  364. SCMStringBuffer dateString;
  365. timeNow->getDateString(dateString);
  366. m_name.appendf("%s_%d", dateString.str(), getRandom());
  367. if(_act_type == GROUP_ACT)
  368. m_groupdns.append(_dn);
  369. else
  370. m_userdns.append(_dn);
  371. if((_perm & NewSecAccess_Full) == NewSecAccess_Full)
  372. {
  373. m_perms.append("r,w,d");
  374. }
  375. else
  376. {
  377. if((_perm & NewSecAccess_Write) == NewSecAccess_Write)
  378. {
  379. if(m_perms.length() != 0)
  380. m_perms.append(",");
  381. m_perms.append("w");
  382. }
  383. if((_perm & NewSecAccess_Read) == NewSecAccess_Read)
  384. {
  385. if(m_perms.length() != 0)
  386. m_perms.append(",");
  387. m_perms.append("r");
  388. }
  389. }
  390. m_permission = _perm;
  391. }
  392. COpenLdapAci(const char* acistr)
  393. {
  394. if(!acistr || !*acistr)
  395. return;
  396. const char* bptr = acistr;
  397. const char* eptr = acistr;
  398. // <OID>
  399. while(*bptr == ' ')
  400. bptr++;
  401. eptr = strchr(bptr, '#');
  402. if(eptr == NULL)
  403. throw MakeStringException(-1, "Invalid OpenLDAPaci format");
  404. m_name.append(eptr - bptr, bptr);
  405. //skip <scope>
  406. eptr++;
  407. eptr = strchr(eptr, '#');
  408. if(!eptr)
  409. throw MakeStringException(-1, "Invalid OpenLDAPaci format");
  410. //process <rights>
  411. bptr = eptr + 1;
  412. while(*bptr == ' ')
  413. bptr++;
  414. eptr = strchr(bptr, '#');
  415. if(!eptr)
  416. throw MakeStringException(-1, "Invalid OpenLDAPaci format");
  417. if(strncmp(bptr, "deny", 4) == 0)
  418. {
  419. m_isDeny = true;
  420. bptr += 4;
  421. }
  422. else if(strncmp(bptr, "grant", 5) == 0)
  423. {
  424. m_isDeny = false;
  425. bptr += 5;
  426. }
  427. else
  428. throw MakeStringException(-1, "Invalid OpenLDAPaci format");
  429. while(bptr <= eptr && (*bptr == ' ' || *bptr == ';'))
  430. bptr++;
  431. while(bptr <= eptr && *bptr != ';')
  432. {
  433. m_perms.append(*bptr);
  434. bptr++;
  435. }
  436. // <dntype>
  437. bool isGroup = false;
  438. eptr = strchr(bptr, '#');
  439. if(eptr == NULL)
  440. throw MakeStringException(-1, "Invalid OpenLDAPaci format");
  441. bptr = eptr + 1;
  442. while(*bptr == ' ')
  443. bptr++;
  444. if(strncmp(bptr, "group", 5) == 0 || strncmp(bptr, "role", 4) == 0)
  445. isGroup = true;
  446. // <subjectDN>
  447. eptr = strchr(bptr, '#');
  448. if(eptr == NULL)
  449. throw MakeStringException(-1, "Invalid OpenLDAPaci format");
  450. bptr = eptr + 1;
  451. while(*bptr == ' ')
  452. bptr++;
  453. if(isGroup)
  454. {
  455. m_groupdns.append(bptr);
  456. }
  457. else
  458. {
  459. m_userdns.append(bptr);
  460. }
  461. //calculate the secperm
  462. m_permission = 0;
  463. if(strchr(m_perms.str(), 'r') != NULL && strchr(m_perms.str(), 'w') != NULL && strchr(m_perms.str(), 'd') != NULL)
  464. {
  465. m_permission |= NewSecAccess_Full;
  466. }
  467. else
  468. {
  469. if(strchr(m_perms.str(), 'r') != NULL)
  470. {
  471. m_permission |= NewSecAccess_Read;
  472. }
  473. if(strchr(m_perms.str(), 'w') != 0)
  474. {
  475. m_permission |= NewSecAccess_Write;
  476. }
  477. }
  478. }
  479. virtual StringBuffer& target()
  480. {
  481. return m_target;
  482. }
  483. virtual StringArray& userdns()
  484. {
  485. return m_userdns;
  486. }
  487. virtual StringArray& groupdns()
  488. {
  489. return m_groupdns;
  490. }
  491. virtual bool isDeny()
  492. {
  493. return m_isDeny;
  494. }
  495. virtual int permission()
  496. {
  497. return m_permission;
  498. }
  499. virtual StringBuffer& serialize(StringBuffer& acibuf)
  500. {
  501. acibuf.appendf("%s#entry#%s;%s;[all]#", m_name.str(), m_isDeny?"deny":"grant", m_perms.str());
  502. if(m_groupdns.length() > 0)
  503. acibuf.appendf("group#%s", m_groupdns.item(0));
  504. else if(m_userdns.length() > 0)
  505. acibuf.appendf("access-id#%s", m_userdns.item(0));
  506. return acibuf;
  507. }
  508. virtual void debugPrintout()
  509. {
  510. printf("name: %s\n", m_name.str());
  511. if(m_isDeny)
  512. printf("deny:\n");
  513. else
  514. printf("allow:\n");
  515. printf("\t%s\n", m_perms.str());
  516. printf("\nuserdns:\n");
  517. unsigned y;
  518. for(y = 0; y < m_userdns.length(); y++)
  519. {
  520. printf("\t%s\n", m_userdns.item(y));
  521. }
  522. printf("groupdns:\n");
  523. for(y = 0; y < m_groupdns.length(); y++)
  524. {
  525. printf("\t%s\n", m_groupdns.item(y));
  526. }
  527. }
  528. };
  529. int NewSec2Sec(int newsec)
  530. {
  531. int sec = 0;
  532. if(newsec == -1)
  533. return -1;
  534. if(newsec == NewSecAccess_Full)
  535. return SecAccess_Full;
  536. if((newsec & NewSecAccess_Write) == NewSecAccess_Write)
  537. sec |= SecAccess_Write;
  538. if((newsec & NewSecAccess_Read) == NewSecAccess_Read)
  539. sec |= SecAccess_Read;
  540. if((newsec & NewSecAccess_Access) == NewSecAccess_Access)
  541. sec |= SecAccess_Access;
  542. return sec;
  543. }
  544. /****************************************************************
  545. * Class CAciList
  546. ****************************************************************/
  547. class CAciList : public CInterface, implements IInterface
  548. {
  549. private:
  550. IArrayOf<IAci> m_acilist;
  551. LdapServerType m_servertype;
  552. public:
  553. IMPLEMENT_IINTERFACE;
  554. CAciList(LdapServerType servertype, MemoryBuffer& acibuf)
  555. {
  556. m_servertype = servertype;
  557. const char* acistr = acibuf.toByteArray();
  558. int len = acibuf.length();
  559. int ci = 0;
  560. while(ci < len)
  561. {
  562. int bp = ci;
  563. while(acistr[ci] != '\0' && ci < len)
  564. ci++;
  565. if(servertype == IPLANET)
  566. m_acilist.append(*(new CAci(acistr+bp)));
  567. else
  568. m_acilist.append(*(new COpenLdapAci(acistr+bp)));
  569. while(acistr[ci] == '\0' && ci < len)
  570. ci++;
  571. }
  572. }
  573. bool getPermissions(ISecUser& user, ISecResource& resource, ILdapClient* ldapclient, const char* dn)
  574. {
  575. const char* res_name = resource.getName();
  576. ILdapConfig* ldapconfig = ldapclient->getLdapConfig();
  577. if(stricmp(ldapconfig->getSysUser(), user.getName()) == 0)
  578. {
  579. resource.setAccessFlags(SecAccess_Full);
  580. return true;
  581. }
  582. int perm = 0;
  583. if(m_acilist.length() == 0)
  584. {
  585. perm = -1;
  586. }
  587. else
  588. {
  589. int allow = 0;
  590. int deny = 0;
  591. ForEachItemIn(x, m_acilist)
  592. {
  593. IAci& aci = m_acilist.item(x);
  594. bool applicable = false;
  595. // check if target matches the dn of the resource
  596. if(aci.target().length() > 0 && (dn == NULL || stricmp(aci.target().str(), dn) != 0))
  597. continue;
  598. //check if this aci is applicable to this user
  599. StringBuffer userdn;
  600. userdn.append("uid=").append(user.getName()).append(",").append(ldapconfig->getUserBasedn());
  601. ForEachItemIn(z, aci.userdns())
  602. {
  603. const char* onedn = aci.userdns().item(z);
  604. if(onedn != NULL && (stricmp(onedn, "anyone") == 0 || stricmp(onedn, userdn.str()) == 0))
  605. {
  606. applicable = true;
  607. break;
  608. }
  609. }
  610. if(!applicable)
  611. {
  612. // See if the user belongs to one of the groups
  613. ForEachItemIn(g, aci.groupdns())
  614. {
  615. const char* onegdn = aci.groupdns().item(g);
  616. if(onegdn == NULL || *onegdn == '\0')
  617. continue;
  618. if(ldapclient->userInGroup(userdn.str(), onegdn))
  619. {
  620. applicable =true;
  621. break;
  622. }
  623. }
  624. }
  625. if(applicable)
  626. {
  627. if(aci.isDeny())
  628. deny |= aci.permission();
  629. else
  630. allow |= aci.permission();
  631. }
  632. }
  633. perm = allow & (~deny);
  634. perm = NewSec2Sec(perm);
  635. }
  636. resource.setAccessFlags(perm);
  637. return true;
  638. }
  639. void getPermissionsArray(IArrayOf<CPermission>& permissions)
  640. {
  641. ForEachItemIn(x, m_acilist)
  642. {
  643. IAci& aci = m_acilist.item(x);
  644. int allows = 0;
  645. int denies = 0;
  646. if(aci.isDeny())
  647. denies = aci.permission();
  648. else
  649. allows = aci.permission();
  650. unsigned i;
  651. for(i = 0; i < aci.groupdns().length(); i++)
  652. {
  653. const char* dn = aci.groupdns().item(i);
  654. if(dn == NULL || dn[0] == '\0')
  655. continue;
  656. StringBuffer name;
  657. LdapUtils::getName(dn, name);
  658. bool found = false;
  659. ForEachItemIn(x, permissions)
  660. {
  661. CPermission& p = permissions.item(x);
  662. if(stricmp(p.getAccount_name(), name.str()) == 0 && p.getAccount_type() == GROUP_ACT)
  663. {
  664. p.setAllows(p.getAllows() | allows);
  665. p.setDenies(p.getDenies() | denies);
  666. found = true;
  667. }
  668. }
  669. if(!found)
  670. {
  671. CPermission* p = new CPermission(name.str(), GROUP_ACT, allows, denies);
  672. permissions.append(*p);
  673. }
  674. }
  675. for(i = 0; i < aci.userdns().length(); i++)
  676. {
  677. const char* dn = aci.userdns().item(i);
  678. if(dn == NULL || dn[0] == '\0')
  679. continue;
  680. StringBuffer name;
  681. LdapUtils::getName(dn, name);
  682. bool found = false;
  683. ForEachItemIn(x, permissions)
  684. {
  685. CPermission& p = permissions.item(x);
  686. if(stricmp(p.getAccount_name(), name.str()) == 0 && p.getAccount_type() == USER_ACT)
  687. {
  688. p.setAllows(p.getAllows() | allows);
  689. p.setDenies(p.getDenies() | denies);
  690. found = true;
  691. }
  692. }
  693. if(!found)
  694. {
  695. CPermission* p = new CPermission(name.str(), USER_ACT, allows, denies);
  696. permissions.append(*p);
  697. }
  698. }
  699. }
  700. }
  701. void changePermission(CPermissionAction& action)
  702. {
  703. if(action.m_account_type == GROUP_ACT && strncmp(action.m_account_name.str(), "cn=Directory Administrators", strlen("cn=Directory Administrators")) == 0)
  704. {
  705. if(stricmp(action.m_action.str(), "delete") != 0 && action.m_denies != 0)
  706. throw MakeStringException(-1, "Please don't set deny permissions for Directory Administrators");
  707. }
  708. if(action.m_account_type == USER_ACT && stricmp(action.m_account_name.str(), "anyone") == 0)
  709. {
  710. if(stricmp(action.m_action.str(), "delete") != 0 && action.m_denies != 0)
  711. throw MakeStringException(-1, "Please don't set deny permissions for anyone");
  712. }
  713. // if not add (means it's either update or delete), delete original aci.
  714. if(stricmp(action.m_action.str(), "add") != 0)
  715. {
  716. ForEachItemInRev(i, m_acilist)
  717. {
  718. IAci* aci = &m_acilist.item(i);
  719. if(action.m_account_type == GROUP_ACT)
  720. {
  721. ForEachItemInRev(j, aci->groupdns())
  722. {
  723. const char* grpdn = aci->groupdns().item(j);
  724. if(stricmp(grpdn, action.m_account_name.str()) == 0)
  725. {
  726. aci->groupdns().remove(j);
  727. break;
  728. }
  729. }
  730. }
  731. else
  732. {
  733. ForEachItemInRev(j, aci->userdns())
  734. {
  735. const char* usrdn = aci->userdns().item(j);
  736. if(stricmp(usrdn, action.m_account_name.str()) == 0)
  737. {
  738. aci->userdns().remove(j);
  739. break;
  740. }
  741. }
  742. }
  743. if(aci->groupdns().length() + aci->userdns().length() == 0)
  744. m_acilist.remove(i);
  745. }
  746. }
  747. // If not delete (means it's update or add), add the new aci
  748. if(stricmp(action.m_action.str(), "delete") != 0)
  749. {
  750. if(action.m_allows != 0)
  751. {
  752. if(m_servertype == IPLANET)
  753. m_acilist.append(*(new CAci(false, action.m_allows, action.m_account_type, action.m_account_name)));
  754. else
  755. m_acilist.append(*(new COpenLdapAci(false, action.m_allows, action.m_account_type, action.m_account_name)));
  756. }
  757. if(action.m_denies != 0)
  758. {
  759. if(m_servertype == IPLANET)
  760. m_acilist.append(*(new CAci(true, action.m_denies, action.m_account_type, action.m_account_name)));
  761. else
  762. m_acilist.append(*(new COpenLdapAci(true, action.m_denies, action.m_account_type, action.m_account_name)));
  763. }
  764. }
  765. }
  766. void debugPrintout()
  767. {
  768. ForEachItemIn(x, m_acilist)
  769. {
  770. printf("---------\n");
  771. IAci& aci = m_acilist.item(x);
  772. aci.debugPrintout();
  773. }
  774. }
  775. MemoryBuffer& serialize(MemoryBuffer& aclbuf)
  776. {
  777. ForEachItemIn(x, m_acilist)
  778. {
  779. IAci* aci = &m_acilist.item(x);
  780. if(aci == NULL)
  781. continue;
  782. StringBuffer acibuf;
  783. aci->serialize(acibuf);
  784. aclbuf.append(acibuf.length(), acibuf.str());
  785. aclbuf.append('\0');
  786. }
  787. return aclbuf;
  788. }
  789. };
  790. /****************************************************************
  791. * Class AciProcessor
  792. ****************************************************************/
  793. AciProcessor::AciProcessor(IPropertyTree* cfg)
  794. {
  795. if(cfg == NULL)
  796. throw MakeStringException(-1, "AciProcessor() - config is NULL");
  797. m_cfg.set(cfg);
  798. m_sidcache.setown(createPTree());
  799. m_cfg->getProp(".//@ldapAddress", m_server);
  800. }
  801. bool AciProcessor::getPermissions(ISecUser& user, IArrayOf<CSecurityDescriptor>& sdlist, IArrayOf<ISecResource>& resources)
  802. {
  803. for(unsigned i = 0; i < sdlist.length(); i++)
  804. {
  805. CSecurityDescriptor& sd = sdlist.item(i);
  806. ISecResource& res = resources.item(i);
  807. CAciList acilist(m_servertype, sd.getDescriptor());
  808. acilist.getPermissions(user, res, m_ldap_client, sd.getDn());
  809. }
  810. return true;
  811. }
  812. CSecurityDescriptor* AciProcessor::createDefaultSD(ISecUser& user, ISecResource* resource, SecPermissionType ptype)
  813. {
  814. return createDefaultSD(user, resource->getName(), ptype);
  815. }
  816. StringBuffer& AciProcessor::sec2aci(int secperm, StringBuffer& aciperm)
  817. {
  818. throw MakeStringException(-1, "You should call the implementation of the child class");
  819. }
  820. CSecurityDescriptor* AciProcessor::createDefaultSD(ISecUser& user, const char* name, SecPermissionType ptype)
  821. {
  822. throw MakeStringException(-1, "You should call the implementation of the child class");
  823. }
  824. CSecurityDescriptor* AciProcessor::createDefaultSD(ISecUser& user, ISecResource* resource, MemoryBuffer& initial_sd)
  825. {
  826. throw MakeStringException(-1, "You should call the implementation of the child class");
  827. }
  828. bool AciProcessor::retrieveUserInfo(ISecUser& user)
  829. {
  830. CLdapSecUser* ldapuser = (CLdapSecUser*)&user;
  831. const char* username = user.getName();
  832. if(username == NULL || strlen(username) == 0)
  833. {
  834. DBGLOG("AciProcessor::retrieveUserInfo : username is empty");
  835. return false;
  836. }
  837. const char* fullname = user.getFullName();
  838. if((fullname == NULL || *fullname == '\0') && m_ldap_client != NULL)
  839. {
  840. m_ldap_client->getUserInfo(user);
  841. }
  842. return true;
  843. }
  844. void AciProcessor::getCachedSid(const char* name, MemoryBuffer& sid)
  845. {
  846. StringBuffer buf;
  847. if(toXpath(name, buf))
  848. {
  849. synchronized block(m_mutex);
  850. m_sidcache->getPropBin(buf.str(), sid);
  851. }
  852. }
  853. void AciProcessor::cacheSid(const char* name, int len, const void* sidbuf)
  854. {
  855. StringBuffer buf;
  856. if(toXpath(name, buf))
  857. {
  858. synchronized block(m_mutex);
  859. m_sidcache->addPropBin(buf.str(), len, sidbuf);
  860. }
  861. }
  862. void AciProcessor::lookupSid(const char* act_name, MemoryBuffer& act_sid, ACT_TYPE acttype)
  863. {
  864. throw MakeStringException(-1, "You shouldn't need function lookupSid");
  865. act_sid.clear();
  866. MemoryBuffer mb;
  867. getCachedSid(act_name, mb);
  868. if(mb.length() > 0)
  869. {
  870. act_sid.append(mb.length(), mb.toByteArray());
  871. }
  872. else
  873. {
  874. if(m_ldap_client != NULL)
  875. {
  876. m_ldap_client->lookupSid(act_name, act_sid, acttype);
  877. cacheSid(act_name, act_sid.length(), (const void*)act_sid.toByteArray());
  878. }
  879. }
  880. }
  881. int AciProcessor::sdSegments(CSecurityDescriptor* sd)
  882. {
  883. if(sd == NULL || sd->getDescriptor().length() == 0)
  884. return 0;
  885. const char* sdptr = sd->getDescriptor().toByteArray();
  886. unsigned curind = 0;
  887. int segs = 0;
  888. bool endofone = true;
  889. while(curind < sd->getDescriptor().length())
  890. {
  891. if(*sdptr == '\0')
  892. {
  893. while(*sdptr == '\0' && curind < sd->getDescriptor().length())
  894. {
  895. sdptr++;
  896. curind++;
  897. }
  898. endofone = true;
  899. }
  900. else
  901. {
  902. if(endofone)
  903. {
  904. segs++;
  905. endofone = false;
  906. }
  907. sdptr++;
  908. curind++;
  909. }
  910. }
  911. return segs;
  912. }
  913. bool AciProcessor::getPermissionsArray(CSecurityDescriptor *sd, IArrayOf<CPermission>& permissions)
  914. {
  915. CAciList acilist(m_servertype, sd->getDescriptor());
  916. acilist.getPermissionsArray(permissions);
  917. return true;
  918. }
  919. CSecurityDescriptor* AciProcessor::changePermission(CSecurityDescriptor* initialsd, CPermissionAction& action)
  920. {
  921. CAciList acl(m_servertype, initialsd->getDescriptor());
  922. acl.changePermission(action);
  923. MemoryBuffer resultbuf;
  924. acl.serialize(resultbuf);
  925. CSecurityDescriptor* csd = new CSecurityDescriptor(action.m_rname.str());
  926. csd->setDescriptor(resultbuf.length(), (void*)resultbuf.toByteArray());
  927. return csd;
  928. }
  929. /****************************************************************
  930. * Class CIPlanetAciProcessor
  931. ****************************************************************/
  932. StringBuffer& CIPlanetAciProcessor::sec2aci(int secperm, StringBuffer& aciperm)
  933. {
  934. if(secperm == -1 || secperm == SecAccess_None)
  935. return aciperm;
  936. if(secperm >= SecAccess_Full)
  937. {
  938. aciperm.append("all");
  939. return aciperm;
  940. }
  941. // compare or search maps to SecAccess_Access, read to SecAccess_Read and write to SecAccess_Write
  942. if((secperm & SecAccess_Access) == SecAccess_Access)
  943. aciperm.append("compare search");
  944. if((secperm & SecAccess_Read) == SecAccess_Read)
  945. aciperm.append(" read");
  946. if((secperm & SecAccess_Write) == SecAccess_Write)
  947. aciperm.append(" write");
  948. return aciperm;
  949. }
  950. CSecurityDescriptor* CIPlanetAciProcessor::createDefaultSD(ISecUser& user, const char* name, SecPermissionType ptype)
  951. {
  952. CSecurityDescriptor* csd = new CSecurityDescriptor(name);
  953. if(ptype != PT_ADMINISTRATORS_ONLY)
  954. {
  955. if(DEFAULT_AUTHENTICATED_USERS_PERMISSION != SecAccess_None)
  956. {
  957. StringBuffer defaultperm;
  958. sec2aci(DEFAULT_AUTHENTICATED_USERS_PERMISSION, defaultperm);
  959. StringBuffer default_sd;
  960. default_sd.append("(targetattr = \"*\") (version 3.0;acl \"default_aci\";allow (").append(defaultperm.str()).append(")(userdn = \"ldap:///anyone\");)");
  961. csd->setDescriptor(default_sd.length(), (void*)default_sd.str());
  962. }
  963. }
  964. else
  965. {
  966. ILdapConfig* ldapconfig = m_ldap_client->getLdapConfig();
  967. StringBuffer default_sd;
  968. default_sd.append("(targetattr = \"*\") (version 3.0;acl \"default_aci\";allow (all)(groupdn = \"ldap:///cn=Directory Administrators,").append(ldapconfig->getBasedn()).append("\");)");
  969. csd->setDescriptor(default_sd.length(), (void*)default_sd.str());
  970. }
  971. return csd;
  972. }
  973. CSecurityDescriptor* CIPlanetAciProcessor::createDefaultSD(ISecUser& user, ISecResource* resource, MemoryBuffer& initial_sd)
  974. {
  975. if(resource == NULL)
  976. return NULL;
  977. CSecurityDescriptor* csd = new CSecurityDescriptor(resource->getName());
  978. if(initial_sd.length() > 0)
  979. csd->setDescriptor(initial_sd.length(), (void *)initial_sd.toByteArray());
  980. const char* userbasedn = NULL;
  981. if(m_ldap_client != NULL)
  982. {
  983. ILdapConfig* ldapconfig = m_ldap_client->getLdapConfig();
  984. if(ldapconfig != NULL)
  985. userbasedn = ldapconfig->getUserBasedn();
  986. }
  987. if(userbasedn == NULL)
  988. return csd;
  989. if(&user != NULL && DEFAULT_OWNER_PERMISSION != SecAccess_None)
  990. {
  991. StringBuffer defaultperm;
  992. sec2aci(DEFAULT_OWNER_PERMISSION, defaultperm);
  993. StringBuffer default_sd;
  994. default_sd.append("(targetattr = \"*\") (version 3.0;acl \"default_aci\";allow (").append(defaultperm.str()).append(")");
  995. default_sd.append("(userdn = \"ldap:///");
  996. default_sd.append("uid=").append(user.getName());
  997. default_sd.append(",").append(userbasedn).append("\");)");
  998. csd->appendDescriptor(default_sd.length(), (void*)default_sd.str());
  999. }
  1000. return csd;
  1001. }
  1002. /****************************************************************
  1003. * Class COpenLdapAciProcessor
  1004. ****************************************************************/
  1005. StringBuffer& COpenLdapAciProcessor::sec2aci(int secperm, StringBuffer& aciperm)
  1006. {
  1007. if(secperm == -1 || secperm == SecAccess_None)
  1008. return aciperm;
  1009. if(secperm >= SecAccess_Full)
  1010. {
  1011. aciperm.append("r,w,d");
  1012. return aciperm;
  1013. }
  1014. // compare or search maps to SecAccess_Access, read to SecAccess_Read and write to SecAccess_Write
  1015. if((secperm & SecAccess_Read) == SecAccess_Read)
  1016. {
  1017. if(aciperm.length() > 0)
  1018. aciperm.append(",");
  1019. aciperm.append("r");
  1020. }
  1021. if((secperm & SecAccess_Write) == SecAccess_Write)
  1022. {
  1023. if(aciperm.length() > 0)
  1024. aciperm.append(",");
  1025. aciperm.append("w");
  1026. }
  1027. return aciperm;
  1028. }
  1029. CSecurityDescriptor* COpenLdapAciProcessor::createDefaultSD(ISecUser& user, const char* name, SecPermissionType ptype)
  1030. {
  1031. CSecurityDescriptor* csd = new CSecurityDescriptor(name);
  1032. if(ptype != PT_ADMINISTRATORS_ONLY)
  1033. {
  1034. if(DEFAULT_AUTHENTICATED_USERS_PERMISSION != SecAccess_None)
  1035. {
  1036. StringBuffer defaultperm;
  1037. sec2aci(DEFAULT_AUTHENTICATED_USERS_PERMISSION, defaultperm);
  1038. StringBuffer default_sd;
  1039. default_sd.appendf("default_aci#entry#grant;%s;[all]#access-id#anyone", defaultperm.str());
  1040. csd->setDescriptor(default_sd.length(), (void*)default_sd.str());
  1041. }
  1042. }
  1043. else
  1044. {
  1045. ILdapConfig* ldapconfig = m_ldap_client->getLdapConfig();
  1046. StringBuffer default_sd;
  1047. default_sd.appendf("default_aci#entry#grant;r,w,d;[all]#group#cn=Directory Administrators,%s", ldapconfig->getBasedn());
  1048. csd->setDescriptor(default_sd.length(), (void*)default_sd.str());
  1049. }
  1050. return csd;
  1051. }
  1052. CSecurityDescriptor* COpenLdapAciProcessor::createDefaultSD(ISecUser& user, ISecResource* resource, MemoryBuffer& initial_sd)
  1053. {
  1054. if(resource == NULL)
  1055. return NULL;
  1056. CSecurityDescriptor* csd = new CSecurityDescriptor(resource->getName());
  1057. if(initial_sd.length() > 0)
  1058. csd->setDescriptor(initial_sd.length(), (void *)initial_sd.toByteArray());
  1059. const char* userbasedn = NULL;
  1060. if(m_ldap_client != NULL)
  1061. {
  1062. ILdapConfig* ldapconfig = m_ldap_client->getLdapConfig();
  1063. if(ldapconfig != NULL)
  1064. userbasedn = ldapconfig->getUserBasedn();
  1065. }
  1066. if(userbasedn == NULL)
  1067. return csd;
  1068. if(&user != NULL && DEFAULT_OWNER_PERMISSION != SecAccess_None)
  1069. {
  1070. StringBuffer defaultperm;
  1071. sec2aci(DEFAULT_OWNER_PERMISSION, defaultperm);
  1072. StringBuffer default_sd;
  1073. default_sd.appendf("default_aci#entry#grant;%s;[all]#access-id#uid=%s,%s", defaultperm.str(), user.getName(), userbasedn);
  1074. csd->appendDescriptor(default_sd.length(), (void*)default_sd.str());
  1075. }
  1076. return csd;
  1077. }