acleffectiverights.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright 2004 Netscape Communications Corporation
  3. * All rights reserved.
  4. * END COPYRIGHT BLOCK **/
  5. #include "acl.h"
  6. static int
  7. _ger_g_permission_granted ( Slapi_PBlock *pb, Slapi_Entry *e, char **errbuf )
  8. {
  9. char *proxydn = NULL;
  10. Slapi_DN *requestor_sdn, *entry_sdn;
  11. char *errtext = NULL;
  12. int isroot;
  13. int rc;
  14. /*
  15. * Theorically, we should check if the entry has "g"
  16. * permission granted to the requestor. If granted,
  17. * allows the effective rights on that entry and its
  18. * attributes within the entry to be returned for
  19. * ANY subject.
  20. *
  21. * "G" permission granting has not been implemented yet,
  22. * the current release assumes that "g" permission be
  23. * granted to root and owner of any entry.
  24. */
  25. /*
  26. * The requestor may be either the bind dn or a proxy dn
  27. */
  28. acl_get_proxyauth_dn ( pb, &proxydn, &errtext );
  29. if ( proxydn != NULL )
  30. {
  31. requestor_sdn = slapi_sdn_new_dn_passin ( proxydn );
  32. }
  33. else
  34. {
  35. requestor_sdn = &(pb->pb_op->o_sdn);
  36. }
  37. if ( slapi_sdn_get_dn (requestor_sdn) == NULL )
  38. {
  39. slapi_log_error (SLAPI_LOG_ACL, plugin_name,
  40. "_ger_g_permission_granted: anonymous has no g permission\n" );
  41. rc = LDAP_INSUFFICIENT_ACCESS;
  42. goto bailout;
  43. }
  44. isroot = slapi_dn_isroot ( slapi_sdn_get_dn (requestor_sdn) );
  45. if ( isroot )
  46. {
  47. /* Root has "g" permission on any entry */
  48. rc = LDAP_SUCCESS;
  49. goto bailout;
  50. }
  51. entry_sdn = slapi_entry_get_sdn ( e );
  52. if ( entry_sdn == NULL || slapi_sdn_get_dn (entry_sdn) == NULL )
  53. {
  54. rc = LDAP_SUCCESS;
  55. goto bailout;
  56. }
  57. if ( slapi_sdn_compare ( requestor_sdn, entry_sdn ) == 0 )
  58. {
  59. /* Owner has "g" permission on his own entry */
  60. rc = LDAP_SUCCESS;
  61. goto bailout;
  62. }
  63. aclutil_str_appened ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
  64. slapi_log_error (SLAPI_LOG_ACL, plugin_name,
  65. "_ger_g_permission_granted: %s\n", *errbuf);
  66. rc = LDAP_INSUFFICIENT_ACCESS;
  67. bailout:
  68. if ( proxydn )
  69. {
  70. /* The ownership of proxydn has passed to requestor_sdn */
  71. slapi_sdn_free ( &requestor_sdn );
  72. }
  73. return rc;
  74. }
  75. static int
  76. _ger_parse_control ( Slapi_PBlock *pb, char **subjectndn, int *iscritical, char **errbuf )
  77. {
  78. LDAPControl **requestcontrols;
  79. struct berval *subjectber;
  80. BerElement *ber;
  81. if (NULL == subjectndn)
  82. {
  83. return LDAP_OPERATIONS_ERROR;
  84. }
  85. *subjectndn = NULL;
  86. /*
  87. * Get the control
  88. */
  89. slapi_pblock_get ( pb, SLAPI_REQCONTROLS, (void *) &requestcontrols );
  90. slapi_control_present ( requestcontrols,
  91. LDAP_CONTROL_GET_EFFECTIVE_RIGHTS,
  92. &subjectber,
  93. iscritical );
  94. if ( subjectber == NULL || subjectber->bv_val == NULL ||
  95. subjectber->bv_len == 0 )
  96. {
  97. aclutil_str_appened ( errbuf, "get-effective-rights: missing subject" );
  98. slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
  99. return LDAP_INVALID_SYNTAX;
  100. }
  101. if ( strncasecmp ( "dn:", subjectber->bv_val, 3 ) == 0 )
  102. {
  103. /*
  104. * This is a non-standard support to allow the subject being a plain
  105. * or base64 encoding string. Hence users using -J option in
  106. * ldapsearch don't have to do BER encoding for the subject.
  107. */
  108. *subjectndn = slapi_ch_malloc ( subjectber->bv_len + 1 );
  109. strncpy ( *subjectndn, subjectber->bv_val, subjectber->bv_len );
  110. *(*subjectndn + subjectber->bv_len) = '\0';
  111. }
  112. else
  113. {
  114. ber = ber_init (subjectber);
  115. if ( ber == NULL )
  116. {
  117. aclutil_str_appened ( errbuf, "get-effective-rights: ber_init failed for the subject" );
  118. slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
  119. return LDAP_OPERATIONS_ERROR;
  120. }
  121. /* "a" means to allocate storage as needed for octet string */
  122. if ( ber_scanf (ber, "a", subjectndn) == LBER_ERROR )
  123. {
  124. aclutil_str_appened ( errbuf, "get-effective-rights: invalid ber tag in the subject" );
  125. slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
  126. ber_free ( ber, 1 );
  127. return LDAP_INVALID_SYNTAX;
  128. }
  129. ber_free ( ber, 1 );
  130. }
  131. /*
  132. * The current implementation limits the subject to authorization ID
  133. * (see section 9 of RFC 2829) only. It also only supports the "dnAuthzId"
  134. * flavor, which looks like "dn:<DN>" where null <DN> is for anonymous.
  135. */
  136. if ( NULL == *subjectndn || strlen (*subjectndn) < 3 ||
  137. strncasecmp ( "dn:", *subjectndn, 3 ) != 0 )
  138. {
  139. aclutil_str_appened ( errbuf, "get-effective-rights: subject is not dnAuthzId" );
  140. slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
  141. return LDAP_INVALID_SYNTAX;
  142. }
  143. strcpy ( *subjectndn, *subjectndn + 3 );
  144. slapi_dn_normalize ( *subjectndn );
  145. return LDAP_SUCCESS;
  146. }
  147. static void
  148. _ger_release_gerpb (
  149. Slapi_PBlock **gerpb,
  150. void **aclcb, /* original aclcb */
  151. Slapi_PBlock *pb /* original pb */
  152. )
  153. {
  154. if ( *gerpb )
  155. {
  156. /* Return conn to pb */
  157. slapi_pblock_set ( *gerpb, SLAPI_CONNECTION, NULL );
  158. slapi_pblock_destroy ( *gerpb );
  159. *gerpb = NULL;
  160. }
  161. /* Put the original aclcb back to pb */
  162. if ( *aclcb )
  163. {
  164. Connection *conn = NULL;
  165. slapi_pblock_get ( pb, SLAPI_CONNECTION, &conn );
  166. if (conn)
  167. {
  168. struct aclcb *geraclcb;
  169. geraclcb = (struct aclcb *) acl_get_ext ( ACL_EXT_CONNECTION, conn );
  170. acl_conn_ext_destructor ( geraclcb, NULL, NULL );
  171. acl_set_ext ( ACL_EXT_CONNECTION, conn, *aclcb );
  172. *aclcb = NULL;
  173. }
  174. }
  175. }
  176. static int
  177. _ger_new_gerpb (
  178. Slapi_PBlock *pb,
  179. Slapi_Entry *e,
  180. const char *subjectndn,
  181. Slapi_PBlock **gerpb,
  182. void **aclcb, /* original aclcb */
  183. char **errbuf
  184. )
  185. {
  186. Connection *conn;
  187. struct acl_cblock *geraclcb;
  188. Acl_PBlock *aclpb, *geraclpb;
  189. Operation *op, *gerop;
  190. int rc = LDAP_SUCCESS;
  191. *aclcb = NULL;
  192. *gerpb = slapi_pblock_new ();
  193. if ( *gerpb == NULL )
  194. {
  195. rc = LDAP_NO_MEMORY;
  196. goto bailout;
  197. }
  198. {
  199. /* aclpb initialization needs the backend */
  200. Slapi_Backend *be;
  201. slapi_pblock_get ( pb, SLAPI_BACKEND, &be );
  202. slapi_pblock_set ( *gerpb, SLAPI_BACKEND, be );
  203. }
  204. {
  205. int isroot = slapi_dn_isroot ( subjectndn );
  206. slapi_pblock_set ( *gerpb, SLAPI_REQUESTOR_ISROOT, &isroot );
  207. }
  208. /* Save requestor's aclcb and set subjectdn's one */
  209. {
  210. slapi_pblock_get ( pb, SLAPI_CONNECTION, &conn );
  211. slapi_pblock_set ( *gerpb, SLAPI_CONNECTION, conn );
  212. /* Can't share the conn->aclcb because of different context */
  213. geraclcb = (struct acl_cblock *) acl_conn_ext_constructor ( NULL, NULL);
  214. if ( geraclcb == NULL )
  215. {
  216. rc = LDAP_NO_MEMORY;
  217. goto bailout;
  218. }
  219. slapi_sdn_set_ndn_byval ( geraclcb->aclcb_sdn, subjectndn );
  220. *aclcb = acl_get_ext ( ACL_EXT_CONNECTION, conn );
  221. acl_set_ext ( ACL_EXT_CONNECTION, conn, (void *) geraclcb );
  222. }
  223. {
  224. gerop = operation_new ( OP_FLAG_INTERNAL );
  225. if ( gerop == NULL )
  226. {
  227. rc = LDAP_NO_MEMORY;
  228. goto bailout;
  229. }
  230. /*
  231. * conn is a no-use parameter in the functions
  232. * chained down from factory_create_extension
  233. */
  234. gerop->o_extension = factory_create_extension ( get_operation_object_type(), (void *)gerop, (void *)conn );
  235. slapi_pblock_set ( *gerpb, SLAPI_OPERATION, gerop );
  236. slapi_sdn_set_dn_byval ( &gerop->o_sdn, subjectndn );
  237. geraclpb = acl_get_ext ( ACL_EXT_OPERATION, (void *)gerop);
  238. acl_init_aclpb ( *gerpb, geraclpb, subjectndn, 0 );
  239. geraclpb->aclpb_res_type |= ACLPB_EFFECTIVE_RIGHTS;
  240. }
  241. bailout:
  242. if ( rc != LDAP_SUCCESS )
  243. {
  244. _ger_release_gerpb ( gerpb, aclcb, pb );
  245. }
  246. return rc;
  247. }
  248. /*
  249. * Callers should have already allocated *gerstr to hold at least
  250. * "entryLevelRights: adnvxxx\n".
  251. */
  252. unsigned long
  253. _ger_get_entry_rights (
  254. Slapi_PBlock *gerpb,
  255. Slapi_Entry *e,
  256. const char *subjectndn,
  257. char *gerstr,
  258. char **errbuf
  259. )
  260. {
  261. unsigned long entryrights = 0;
  262. Slapi_RDN *rdn = NULL;
  263. const char *rdnstr = NULL;
  264. char *equalsign = NULL;
  265. char *rdntype = NULL;
  266. strcpy ( gerstr, "entryLevelRights: " );
  267. slapi_log_error (SLAPI_LOG_ACL, plugin_name,
  268. "_ger_get_entry_rights: SLAPI_ACL_READ\n" );
  269. if (acl_access_allowed(gerpb, e, "*", NULL, SLAPI_ACL_READ) == LDAP_SUCCESS)
  270. {
  271. /* v - view e */
  272. entryrights |= SLAPI_ACL_READ;
  273. strcat (gerstr, "v");
  274. }
  275. slapi_log_error (SLAPI_LOG_ACL, plugin_name,
  276. "_ger_get_entry_rights: SLAPI_ACL_ADD\n" );
  277. if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_ADD) == LDAP_SUCCESS)
  278. {
  279. /* a - add child entry below e */
  280. entryrights |= SLAPI_ACL_ADD;
  281. strcat (gerstr, "a");
  282. }
  283. slapi_log_error (SLAPI_LOG_ACL, plugin_name,
  284. "_ger_get_entry_rights: SLAPI_ACL_DELETE\n" );
  285. if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_DELETE) == LDAP_SUCCESS)
  286. {
  287. /* d - delete e */
  288. entryrights |= SLAPI_ACL_DELETE;
  289. strcat (gerstr, "d");
  290. }
  291. /*
  292. * Some limitation/simplification applied here:
  293. * - The modrdn right requires the rights to delete the old rdn and
  294. * the new one. However we have no knowledge of what the new rdn
  295. * is going to be.
  296. * - In multi-valued RDN case, we check the right on
  297. * the first rdn type only for now.
  298. */
  299. rdn = slapi_rdn_new_dn ( slapi_entry_get_ndn (e) );
  300. rdnstr = slapi_rdn_get_rdn ( rdn );
  301. if ( NULL != (equalsign = strchr ( rdnstr, '=' )) )
  302. {
  303. rdntype = slapi_ch_malloc ( equalsign-rdnstr+1 );
  304. strncpy ( rdntype, rdnstr, equalsign-rdnstr );
  305. rdntype [ equalsign-rdnstr ] = '\0';
  306. slapi_log_error (SLAPI_LOG_ACL, plugin_name,
  307. "_ger_get_entry_rights: SLAPI_ACL_WRITE_DEL & _ADD %s\n", rdntype );
  308. if (acl_access_allowed(gerpb, e, rdntype, NULL,
  309. ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS &&
  310. acl_access_allowed(gerpb, e, rdntype, NULL,
  311. ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS)
  312. {
  313. /* n - rename e */
  314. entryrights |= SLAPI_ACL_WRITE;
  315. strcat (gerstr, "n");
  316. }
  317. slapi_ch_free ( (void**) &rdntype );
  318. }
  319. slapi_rdn_free ( &rdn );
  320. done:
  321. if ( entryrights == 0 )
  322. {
  323. strcat (gerstr, "none");
  324. }
  325. strcat (gerstr, "\n");
  326. return entryrights;
  327. }
  328. /*
  329. * *gerstr should point to a heap buffer since it may need
  330. * to expand dynamically.
  331. */
  332. unsigned long
  333. _ger_get_attr_rights (
  334. Slapi_PBlock *gerpb,
  335. Slapi_Entry *e,
  336. const char *subjectndn,
  337. char *type,
  338. char **gerstr,
  339. int *gerstrsize,
  340. int isfirstattr,
  341. char **errbuf
  342. )
  343. {
  344. unsigned long attrrights = 0;
  345. /* Enough space for " $type:rwoscxx" ? */
  346. if ( (*gerstrsize - strlen(*gerstr)) < (strlen(type) + 16) )
  347. {
  348. /* slapi_ch_realloc() exits if realloc() failed */
  349. *gerstrsize += 256;
  350. *gerstr = slapi_ch_realloc ( *gerstr, *gerstrsize );
  351. }
  352. if (!isfirstattr)
  353. {
  354. strcat ( *gerstr, ", " );
  355. }
  356. sprintf ( *gerstr + strlen(*gerstr), "%s:", type );
  357. slapi_log_error (SLAPI_LOG_ACL, plugin_name,
  358. "_ger_get_attr_rights: SLAPI_ACL_READ %s\n", type );
  359. if (acl_access_allowed(gerpb, e, type, NULL, SLAPI_ACL_READ) == LDAP_SUCCESS)
  360. {
  361. /* r - read the values of type */
  362. attrrights |= SLAPI_ACL_READ;
  363. strcat (*gerstr, "r");
  364. }
  365. slapi_log_error (SLAPI_LOG_ACL, plugin_name,
  366. "_ger_get_attr_rights: SLAPI_ACL_SEARCH %s\n", type );
  367. if (acl_access_allowed(gerpb, e, type, NULL, SLAPI_ACL_SEARCH) == LDAP_SUCCESS)
  368. {
  369. /* s - search the values of type */
  370. attrrights |= SLAPI_ACL_SEARCH;
  371. strcat (*gerstr, "s");
  372. }
  373. slapi_log_error (SLAPI_LOG_ACL, plugin_name,
  374. "_ger_get_attr_rights: SLAPI_ACL_COMPARE %s\n", type );
  375. if (acl_access_allowed(gerpb, e, type, NULL, SLAPI_ACL_COMPARE) == LDAP_SUCCESS)
  376. {
  377. /* c - compare the values of type */
  378. attrrights |= SLAPI_ACL_COMPARE;
  379. strcat (*gerstr, "c");
  380. }
  381. slapi_log_error (SLAPI_LOG_ACL, plugin_name,
  382. "_ger_get_attr_rights: SLAPI_ACL_WRITE_ADD %s\n", type );
  383. if (acl_access_allowed(gerpb, e, type, NULL, ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS)
  384. {
  385. /* w - add the values of type */
  386. attrrights |= ACLPB_SLAPI_ACL_WRITE_ADD;
  387. strcat (*gerstr, "w");
  388. }
  389. slapi_log_error (SLAPI_LOG_ACL, plugin_name,
  390. "_ger_get_attr_rights: SLAPI_ACL_WRITE_DEL %s\n", type );
  391. if (acl_access_allowed(gerpb, e, type, NULL, ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS)
  392. {
  393. /* o - delete the values of type */
  394. attrrights |= ACLPB_SLAPI_ACL_WRITE_DEL;
  395. strcat (*gerstr, "o");
  396. }
  397. /* If subjectdn has no general write right, check for self write */
  398. if ( 0 == (attrrights & (ACLPB_SLAPI_ACL_WRITE_DEL | ACLPB_SLAPI_ACL_WRITE_ADD)) )
  399. {
  400. struct berval val;
  401. val.bv_val = (char *)subjectndn;
  402. val.bv_len = strlen (subjectndn);
  403. if (acl_access_allowed(gerpb, e, type, &val, ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS)
  404. {
  405. /* W - add self to the attribute */
  406. attrrights |= ACLPB_SLAPI_ACL_WRITE_ADD;
  407. strcat (*gerstr, "W");
  408. }
  409. if (acl_access_allowed(gerpb, e, type, &val, ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS)
  410. {
  411. /* O - delete self from the attribute */
  412. attrrights |= ACLPB_SLAPI_ACL_WRITE_DEL;
  413. strcat (*gerstr, "O");
  414. }
  415. }
  416. if ( attrrights == 0 )
  417. {
  418. strcat (*gerstr, "none");
  419. }
  420. return attrrights;
  421. }
  422. void
  423. _ger_get_attrs_rights (
  424. Slapi_PBlock *gerpb,
  425. Slapi_Entry *e,
  426. const char *subjectndn,
  427. char **attrs,
  428. char **gerstr,
  429. int *gerstrsize,
  430. char **errbuf
  431. )
  432. {
  433. int isfirstattr = 1;
  434. /* gerstr was initially allocated with enough space for one more line */
  435. strcat ( *gerstr, "attributeLevelRights: " );
  436. if (attrs && *attrs)
  437. {
  438. int i;
  439. for ( i = 0; attrs[i]; i++ )
  440. {
  441. _ger_get_attr_rights ( gerpb, e, subjectndn, attrs[i], gerstr, gerstrsize, isfirstattr, errbuf );
  442. isfirstattr = 0;
  443. }
  444. }
  445. else
  446. {
  447. Slapi_Attr *prevattr = NULL, *attr;
  448. char *type;
  449. while ( slapi_entry_next_attr ( e, prevattr, &attr ) == 0 )
  450. {
  451. if ( ! slapi_attr_flag_is_set (attr, SLAPI_ATTR_FLAG_OPATTR) )
  452. {
  453. slapi_attr_get_type ( attr, &type );
  454. _ger_get_attr_rights ( gerpb, e, subjectndn, type, gerstr, gerstrsize, isfirstattr, errbuf );
  455. isfirstattr = 0;
  456. }
  457. prevattr = attr;
  458. }
  459. }
  460. if ( isfirstattr )
  461. {
  462. /* not a single attribute was retrived or specified */
  463. strcat ( *gerstr, "*:none" );
  464. }
  465. return;
  466. }
  467. /*
  468. * controlType = LDAP_CONTROL_GET_EFFECTIVE_RIGHTS;
  469. * criticality = n/a;
  470. * controlValue = OCTET STRING of BER encoding of the SEQUENCE of
  471. * ENUMERATED LDAP code
  472. */
  473. void
  474. _ger_set_response_control (
  475. Slapi_PBlock *pb,
  476. int iscritical,
  477. int rc
  478. )
  479. {
  480. LDAPControl **resultctrls = NULL;
  481. LDAPControl gerrespctrl;
  482. BerElement *ber = NULL;
  483. struct berval *berval = NULL;
  484. int found = 0;
  485. int i;
  486. if ( (ber = der_alloc ()) == NULL )
  487. {
  488. goto bailout;
  489. }
  490. /* begin sequence, enumeration, end sequence */
  491. ber_printf ( ber, "{e}", rc );
  492. if ( ber_flatten ( ber, &berval ) != LDAP_SUCCESS )
  493. {
  494. goto bailout;
  495. }
  496. gerrespctrl.ldctl_oid = LDAP_CONTROL_GET_EFFECTIVE_RIGHTS;
  497. gerrespctrl.ldctl_iscritical = iscritical;
  498. gerrespctrl.ldctl_value.bv_val = berval->bv_val;
  499. gerrespctrl.ldctl_value.bv_len = berval->bv_len;
  500. slapi_pblock_get ( pb, SLAPI_RESCONTROLS, &resultctrls );
  501. for (i = 0; resultctrls && resultctrls[i]; i++)
  502. {
  503. if (strcmp(resultctrls[i]->ldctl_oid, LDAP_CONTROL_GET_EFFECTIVE_RIGHTS) == 0)
  504. {
  505. /*
  506. * We get here if search returns more than one entry
  507. * and this is not the first entry.
  508. */
  509. ldap_control_free ( resultctrls[i] );
  510. resultctrls[i] = slapi_dup_control (&gerrespctrl);
  511. found = 1;
  512. break;
  513. }
  514. }
  515. if ( !found )
  516. {
  517. /* slapi_pblock_set() will dup the control */
  518. slapi_pblock_set ( pb, SLAPI_ADD_RESCONTROL, &gerrespctrl );
  519. }
  520. bailout:
  521. ber_free ( ber, 1 ); /* ber_free() checks for NULL param */
  522. ber_bvfree ( berval ); /* ber_bvfree() checks for NULL param */
  523. }
  524. int
  525. acl_get_effective_rights (
  526. Slapi_PBlock *pb,
  527. Slapi_Entry *e, /* target entry */
  528. char **attrs, /* Attribute of the entry */
  529. struct berval *val, /* value of attr. NOT USED */
  530. int access, /* requested access rights */
  531. char **errbuf
  532. )
  533. {
  534. Slapi_PBlock *gerpb = NULL;
  535. void *aclcb = NULL;
  536. char *subjectndn = NULL;
  537. char *gerstr = NULL;
  538. int gerstrsize = 1024;
  539. unsigned long entryrights;
  540. int iscritical = 1;
  541. int rc;
  542. *errbuf = '\0';
  543. gerstr = slapi_ch_malloc ( gerstrsize );
  544. /*
  545. * Get the subject
  546. */
  547. rc = _ger_parse_control (pb, &subjectndn, &iscritical, errbuf );
  548. if ( rc != LDAP_SUCCESS )
  549. {
  550. goto bailout;
  551. }
  552. /*
  553. * The requestor should have g permission on the entry
  554. * to get the effective rights.
  555. */
  556. rc = _ger_g_permission_granted (pb, e, errbuf);
  557. if ( rc != LDAP_SUCCESS )
  558. {
  559. goto bailout;
  560. }
  561. /*
  562. * Construct a new pb
  563. */
  564. rc = _ger_new_gerpb ( pb, e, subjectndn, &gerpb, &aclcb, errbuf );
  565. if ( rc != LDAP_SUCCESS )
  566. {
  567. goto bailout;
  568. }
  569. /* Get entry level effective rights */
  570. entryrights = _ger_get_entry_rights ( gerpb, e, subjectndn, gerstr, errbuf );
  571. /*
  572. * Attribute level effective rights may not be NULL
  573. * even if entry level's is.
  574. */
  575. _ger_get_attrs_rights ( gerpb, e, subjectndn, attrs, &gerstr, &gerstrsize, errbuf );
  576. bailout:
  577. /*
  578. * Now construct the response control
  579. */
  580. _ger_set_response_control ( pb, iscritical, rc );
  581. if ( rc != LDAP_SUCCESS )
  582. {
  583. sprintf ( gerstr, "entryLevelRights: %d\nattributeLevelRights: *:%d", rc, rc );
  584. }
  585. slapi_log_error (SLAPI_LOG_ACLSUMMARY, plugin_name,
  586. "###### Effective Rights on Entry (%s) for Subject (%s) ######\n",
  587. slapi_entry_get_ndn (e), subjectndn);
  588. slapi_log_error (SLAPI_LOG_ACLSUMMARY, plugin_name, "%s\n", gerstr);
  589. /* Restore pb */
  590. _ger_release_gerpb ( &gerpb, &aclcb, pb );
  591. /*
  592. * General plugin uses SLAPI_RESULT_TEXT for error text. Here
  593. * SLAPI_PB_RESULT_TEXT is exclusively shared with add, dse and schema.
  594. * slapi_pblock_set() will free any previous data, and
  595. * pblock_done() will free SLAPI_PB_RESULT_TEXT.
  596. */
  597. slapi_pblock_set (pb, SLAPI_PB_RESULT_TEXT, gerstr);
  598. if ( !iscritical )
  599. {
  600. /*
  601. * If return code is not LDAP_SUCCESS, the server would
  602. * abort sending the data of the entry to the client.
  603. */
  604. rc = LDAP_SUCCESS;
  605. }
  606. slapi_ch_free ( (void **) &subjectndn );
  607. slapi_ch_free ( (void **) &gerstr );
  608. return rc;
  609. }