aci.cpp 38 KB

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