acl_ext.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. #include "acl.h"
  42. static void acl__done_aclpb ( struct acl_pblock *aclpb );
  43. #ifdef FOR_DEBUGGING
  44. static void acl__dump_stats ( struct acl_pblock *aclpb , const char *block_type);
  45. static char * acl__get_aclpb_type ( Acl_PBlock *aclpb );
  46. #endif
  47. static Acl_PBlock * acl__get_aclpb_from_pool ( );
  48. static int acl__put_aclpb_back_to_pool ( Acl_PBlock *aclpb );
  49. static Acl_PBlock * acl__malloc_aclpb ( );
  50. static void acl__free_aclpb ( Acl_PBlock **aclpb_ptr);
  51. static PRLock *aclext_get_lock ();
  52. struct acl_pbqueue {
  53. Acl_PBlock *aclq_free;
  54. Acl_PBlock *aclq_busy;
  55. short aclq_nfree;
  56. short aclq_nbusy;
  57. PRLock *aclq_lock;
  58. };
  59. typedef struct acl_pbqueue Acl_PBqueue;
  60. static Acl_PBqueue *aclQueue;
  61. /* structure with information for each extension */
  62. typedef struct acl_ext
  63. {
  64. char *object_name; /* name of the object extended */
  65. int object_type; /* handle to the extended object */
  66. int handle; /* extension handle */
  67. } acl_ext;
  68. static acl_ext acl_ext_list [ACL_EXT_ALL];
  69. /*
  70. * EXTENSION INITIALIZATION, CONSTRUCTION, & DESTRUCTION
  71. *
  72. */
  73. int
  74. acl_init_ext ()
  75. {
  76. int rc;
  77. acl_ext_list[ACL_EXT_OPERATION].object_name = SLAPI_EXT_OPERATION;
  78. rc = slapi_register_object_extension(plugin_name, SLAPI_EXT_OPERATION,
  79. acl_operation_ext_constructor,
  80. acl_operation_ext_destructor,
  81. &acl_ext_list[ACL_EXT_OPERATION].object_type,
  82. &acl_ext_list[ACL_EXT_OPERATION].handle);
  83. if ( rc != 0 ) return rc;
  84. acl_ext_list[ACL_EXT_CONNECTION].object_name = SLAPI_EXT_CONNECTION;
  85. rc = slapi_register_object_extension(plugin_name, SLAPI_EXT_CONNECTION,
  86. acl_conn_ext_constructor,
  87. acl_conn_ext_destructor,
  88. &acl_ext_list[ACL_EXT_CONNECTION].object_type,
  89. &acl_ext_list[ACL_EXT_CONNECTION].handle);
  90. return rc;
  91. }
  92. /* Interface to get the extensions */
  93. void *
  94. acl_get_ext (ext_type type, void *object)
  95. {
  96. struct acl_ext ext;
  97. void *data;
  98. if ( type >= ACL_EXT_ALL ) {
  99. slapi_log_error ( SLAPI_LOG_ACL, plugin_name,
  100. "Invalid extension type:%d\n", type );
  101. return NULL;
  102. }
  103. /* find the requested extension */
  104. ext = acl_ext_list [type];
  105. data = slapi_get_object_extension(ext.object_type, object, ext.handle);
  106. return data;
  107. }
  108. void
  109. acl_set_ext (ext_type type, void *object, void *data)
  110. {
  111. if ( type < ACL_EXT_ALL )
  112. {
  113. struct acl_ext ext = acl_ext_list [type];
  114. slapi_set_object_extension ( ext.object_type, object, ext.handle, data );
  115. }
  116. }
  117. /****************************************************************************
  118. * Global lock array so that private extension between connection and operation
  119. * co-exist
  120. *
  121. ******************************************************************************/
  122. struct ext_lockArray {
  123. PRLock **lockArray;
  124. int numlocks;
  125. };
  126. static struct ext_lockArray extLockArray;
  127. /* PKBxxx: make this a configurable. Start with 2 * maxThreads */
  128. #define ACLEXT_MAX_LOCKS 40
  129. int
  130. aclext_alloc_lockarray ( )
  131. {
  132. int i;
  133. PRLock *lock;
  134. extLockArray.lockArray =
  135. (PRLock **) slapi_ch_calloc ( ACLEXT_MAX_LOCKS, sizeof ( PRLock *) );
  136. for ( i = 0; i < ACLEXT_MAX_LOCKS; i++) {
  137. if (NULL == (lock = PR_NewLock()) ) {
  138. slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
  139. "Unable to allocate locks used for private extension\n");
  140. return 1;
  141. }
  142. extLockArray.lockArray[i] = lock;
  143. }
  144. extLockArray.numlocks = ACLEXT_MAX_LOCKS;
  145. return 0;
  146. }
  147. /*
  148. * Not in use! The connection table still has references to these locks.
  149. * We need to free these after freeing the connection table in daemon.c
  150. */
  151. void
  152. aclext_free_lockarray()
  153. {
  154. int i = 0;
  155. for ( i = 0; i < ACLEXT_MAX_LOCKS; i++) {
  156. if(extLockArray.lockArray[i]){
  157. PR_DestroyLock(extLockArray.lockArray[i]);
  158. extLockArray.lockArray[i] = NULL;
  159. }
  160. }
  161. slapi_ch_free((void **)&extLockArray.lockArray);
  162. }
  163. static PRUint32 slot_id =0;
  164. static PRLock *
  165. aclext_get_lock ()
  166. {
  167. PRUint16 slot = slot_id % ACLEXT_MAX_LOCKS;
  168. slot_id++;
  169. return ( extLockArray.lockArray[slot] );
  170. }
  171. /****************************************************************************/
  172. /* CONNECTION EXTENSION SPECIFIC */
  173. /****************************************************************************/
  174. void *
  175. acl_conn_ext_constructor ( void *object, void *parent )
  176. {
  177. struct acl_cblock *ext = NULL;
  178. ext = (struct acl_cblock * ) slapi_ch_calloc (1, sizeof (struct acl_cblock ) );
  179. if (( ext->aclcb_lock = aclext_get_lock () ) == NULL ) {
  180. slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
  181. "Unable to get Read/Write lock for CONNECTION extension\n");
  182. slapi_ch_free ( (void **) &ext );
  183. return NULL;
  184. }
  185. ext->aclcb_sdn = slapi_sdn_new ();
  186. /* store the signatures */
  187. ext->aclcb_aclsignature = acl_get_aclsignature();
  188. /* eval_context */
  189. ext->aclcb_eval_context.acle_handles_matched_target = (int *)
  190. slapi_ch_calloc (aclpb_max_selected_acls, sizeof (int));
  191. ext->aclcb_state = -1;
  192. return ext;
  193. }
  194. void
  195. acl_conn_ext_destructor ( void *ext, void *object, void *parent )
  196. {
  197. struct acl_cblock *aclcb = ext;
  198. PRLock *shared_lock;
  199. if ( NULL == aclcb ) return;
  200. PR_Lock ( aclcb->aclcb_lock );
  201. shared_lock = aclcb->aclcb_lock;
  202. acl_clean_aclEval_context ( &aclcb->aclcb_eval_context, 0 /* clean*/ );
  203. slapi_sdn_free ( &aclcb->aclcb_sdn );
  204. slapi_ch_free ( (void **)&(aclcb->aclcb_eval_context.acle_handles_matched_target));
  205. aclcb->aclcb_lock = NULL;
  206. slapi_ch_free ( (void **) &aclcb );
  207. PR_Unlock ( shared_lock );
  208. }
  209. /****************************************************************************/
  210. /* OPERATION EXTENSION SPECIFIC */
  211. /****************************************************************************/
  212. void *
  213. acl_operation_ext_constructor ( void *object, void *parent )
  214. {
  215. Acl_PBlock *aclpb = NULL;
  216. TNF_PROBE_0_DEBUG(acl_operation_ext_constructor_start ,"ACL","");
  217. /* This means internal operations */
  218. if ( NULL == parent) {
  219. TNF_PROBE_1_DEBUG(acl_operation_ext_constructor_end ,"ACL","",
  220. tnf_string,internal_op,"");
  221. return NULL;
  222. }
  223. aclpb = acl__get_aclpb_from_pool();
  224. if ( NULL == aclpb ) {
  225. slapi_log_error ( SLAPI_LOG_FATAL, plugin_name,
  226. "Operation extension allocation Failed\n");
  227. }
  228. TNF_PROBE_0_DEBUG(acl_operation_ext_constructor_end ,"ACL","");
  229. return aclpb;
  230. }
  231. void
  232. acl_operation_ext_destructor ( void *ext, void *object, void *parent )
  233. {
  234. struct acl_cblock *aclcb = NULL;
  235. struct acl_pblock *aclpb = NULL;
  236. TNF_PROBE_0_DEBUG(acl_operation_ext_destructor_start ,"ACL","");
  237. if ( (NULL == parent ) || (NULL == ext)) {
  238. TNF_PROBE_1_DEBUG(acl_operation_ext_destructor_end ,"ACL","",
  239. tnf_string,internal_op,"");
  240. return;
  241. }
  242. aclpb = (Acl_PBlock *) ext;
  243. if ( (NULL == aclpb) ||
  244. (NULL == aclpb->aclpb_pblock) ||
  245. (!(aclpb->aclpb_state & ACLPB_INITIALIZED)))
  246. goto clean_aclpb;
  247. if ( NULL == aclpb->aclpb_authorization_sdn ) {
  248. slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "NULL aclcb_autorization_sdn\n");
  249. goto clean_aclpb;
  250. }
  251. /* get the connection extension */
  252. aclcb = (struct acl_cblock *) acl_get_ext ( ACL_EXT_CONNECTION, parent );
  253. /* We are about to get out of this connection. Move all the
  254. ** cached information to the acl private block which hangs
  255. ** from the connection struct.
  256. */
  257. if ( aclcb && aclcb->aclcb_lock &&
  258. ( (aclpb->aclpb_state & ACLPB_UPD_ACLCB_CACHE ) ||
  259. (aclpb->aclpb_state & ACLPB_INCR_ACLCB_CACHE ) ) ) {
  260. aclEvalContext *c_evalContext;
  261. int attr_only = 0;
  262. PRLock *shared_lock = aclcb->aclcb_lock;
  263. if (aclcb->aclcb_lock ) PR_Lock ( shared_lock );
  264. else {
  265. goto clean_aclpb;
  266. }
  267. if ( !aclcb->aclcb_lock ) {
  268. slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "aclcb lock released! aclcb cache can't be refreshed\n");
  269. PR_Unlock ( shared_lock );
  270. goto clean_aclpb;
  271. }
  272. /* We need to refresh the aclcb cache */
  273. if ( aclpb->aclpb_state & ACLPB_UPD_ACLCB_CACHE )
  274. acl_clean_aclEval_context ( &aclcb->aclcb_eval_context, 0 /* clean*/ );
  275. if ( aclpb->aclpb_prev_entryEval_context.acle_numof_attrs ) {
  276. c_evalContext = &aclpb->aclpb_prev_entryEval_context;
  277. } else {
  278. c_evalContext = &aclpb->aclpb_curr_entryEval_context;
  279. }
  280. if (( aclpb->aclpb_state & ACLPB_INCR_ACLCB_CACHE ) &&
  281. ! ( aclpb->aclpb_state & ACLPB_UPD_ACLCB_CACHE ))
  282. attr_only = 1;
  283. acl_copyEval_context ( NULL, c_evalContext, &aclcb->aclcb_eval_context, attr_only );
  284. aclcb->aclcb_aclsignature = aclpb->aclpb_signature;
  285. if ( aclcb->aclcb_sdn &&
  286. (0 != slapi_sdn_compare ( aclcb->aclcb_sdn,
  287. aclpb->aclpb_authorization_sdn ) ) ) {
  288. slapi_sdn_set_ndn_byval( aclcb->aclcb_sdn,
  289. slapi_sdn_get_ndn ( aclpb->aclpb_authorization_sdn ) );
  290. }
  291. aclcb->aclcb_state = 0;
  292. aclcb->aclcb_state |= ACLCB_HAS_CACHED_EVALCONTEXT;
  293. PR_Unlock ( shared_lock );
  294. }
  295. clean_aclpb:
  296. if ( aclpb ) {
  297. if ( aclpb->aclpb_proxy ) {
  298. TNF_PROBE_0_DEBUG(acl_proxy_aclpbdoneback_start ,"ACL","");
  299. acl__done_aclpb( aclpb->aclpb_proxy );
  300. /* Put back to the Pool */
  301. acl__put_aclpb_back_to_pool ( aclpb->aclpb_proxy );
  302. aclpb->aclpb_proxy = NULL;
  303. TNF_PROBE_0_DEBUG(acl_proxy_aclpbdoneback_end ,"ACL","");
  304. }
  305. TNF_PROBE_0_DEBUG(acl_aclpbdoneback_start ,"ACL","");
  306. acl__done_aclpb( aclpb);
  307. acl__put_aclpb_back_to_pool ( aclpb );
  308. TNF_PROBE_0_DEBUG(acl_aclpbdoneback_end ,"ACL","");
  309. }
  310. TNF_PROBE_0_DEBUG(acl_operation_ext_destructor_end ,"ACL","");
  311. }
  312. /****************************************************************************/
  313. /* FUNCTIONS TO MANAGE THE ACLPB POOL */
  314. /****************************************************************************/
  315. /*
  316. * Get the right acl pblock
  317. */
  318. struct acl_pblock *
  319. acl_get_aclpb ( Slapi_PBlock *pb, int type )
  320. {
  321. Acl_PBlock *aclpb = NULL;
  322. void *op = NULL;
  323. slapi_pblock_get ( pb, SLAPI_OPERATION, &op );
  324. aclpb = (Acl_PBlock *) acl_get_ext ( ACL_EXT_OPERATION, op );
  325. if (NULL == aclpb ) return NULL;
  326. if ( type == ACLPB_BINDDN_PBLOCK )
  327. return aclpb;
  328. else if ( type == ACLPB_PROXYDN_PBLOCK )
  329. return aclpb->aclpb_proxy;
  330. else
  331. slapi_log_error ( SLAPI_LOG_FATAL, plugin_name,
  332. "acl_get_aclpb: Invalid aclpb type %d\n", type );
  333. return NULL;
  334. }
  335. /*
  336. * Create a new proxy acl pblock
  337. *
  338. */
  339. struct acl_pblock *
  340. acl_new_proxy_aclpb( Slapi_PBlock *pb )
  341. {
  342. void *op;
  343. Acl_PBlock *aclpb = NULL;
  344. Acl_PBlock *proxy_aclpb = NULL;
  345. slapi_pblock_get ( pb, SLAPI_OPERATION, &op );
  346. aclpb = (Acl_PBlock *) acl_get_ext ( ACL_EXT_OPERATION, op );
  347. if (NULL == aclpb ) return NULL;
  348. proxy_aclpb = acl__get_aclpb_from_pool();
  349. if (NULL == proxy_aclpb) return NULL;
  350. proxy_aclpb->aclpb_type = ACLPB_TYPE_PROXY;
  351. aclpb->aclpb_proxy = proxy_aclpb;
  352. return proxy_aclpb;
  353. }
  354. static int
  355. acl__handle_config_entry (Slapi_Entry *e, void *callback_data )
  356. {
  357. *(int * )callback_data = slapi_entry_attr_get_int( e, "nsslapd-threadnumber");
  358. return 0;
  359. }
  360. static int
  361. acl__handle_plugin_config_entry (Slapi_Entry *e, void *callback_data )
  362. {
  363. int value = slapi_entry_attr_get_int(e, ATTR_ACLPB_MAX_SELECTED_ACLS);
  364. if (value) {
  365. aclpb_max_selected_acls = value;
  366. aclpb_max_cache_results = value;
  367. } else {
  368. aclpb_max_selected_acls = DEFAULT_ACLPB_MAX_SELECTED_ACLS;
  369. aclpb_max_cache_results = DEFAULT_ACLPB_MAX_SELECTED_ACLS;
  370. }
  371. return 0;
  372. }
  373. /*
  374. * Create a pool of acl pblock. Created during the ACL plugin
  375. * initialization.
  376. */
  377. int
  378. acl_create_aclpb_pool ()
  379. {
  380. Acl_PBlock *aclpb;
  381. Acl_PBlock *prev_aclpb;
  382. Acl_PBlock *first_aclpb;
  383. int i;
  384. int maxThreads= 0;
  385. int callbackData= 0;
  386. slapi_search_internal_callback( "cn=config", LDAP_SCOPE_BASE, "(objectclass=*)",
  387. NULL, 0 /* attrsonly */,
  388. &maxThreads/* callback_data */,
  389. NULL /* controls */,
  390. NULL /* result_callback */,
  391. acl__handle_config_entry,
  392. NULL /* referral_callback */);
  393. slapi_search_internal_callback( ACL_PLUGIN_CONFIG_ENTRY_DN, LDAP_SCOPE_BASE, "(objectclass=*)",
  394. NULL, 0 /* attrsonly */,
  395. &callbackData /* callback_data, not used in this case */,
  396. NULL /* controls */,
  397. NULL /* result_callback */,
  398. acl__handle_plugin_config_entry,
  399. NULL /* referral_callback */);
  400. /* Create a pool pf aclpb */
  401. maxThreads = 2 * maxThreads;
  402. aclQueue = ( Acl_PBqueue *) slapi_ch_calloc ( 1, sizeof (Acl_PBqueue) );
  403. aclQueue->aclq_lock = PR_NewLock();
  404. if ( NULL == aclQueue->aclq_lock ) {
  405. /* ERROR */
  406. return 1;
  407. }
  408. prev_aclpb = NULL;
  409. first_aclpb = NULL;
  410. for ( i = 0; i < maxThreads; i++ ) {
  411. aclpb = acl__malloc_aclpb ();
  412. if ( 0 == i) first_aclpb = aclpb;
  413. aclpb->aclpb_prev = prev_aclpb;
  414. if ( prev_aclpb ) prev_aclpb->aclpb_next = aclpb;
  415. prev_aclpb = aclpb;
  416. }
  417. /* Since this is the begining, everybody is in free list */
  418. aclQueue->aclq_free = first_aclpb;
  419. aclQueue->aclq_nfree = maxThreads;
  420. return 0;
  421. }
  422. /*
  423. * Destroys the Acl_PBlock pool. To be called at shutdown,
  424. * from function registered as SLAPI_PLUGIN_CLOSE_FN
  425. */
  426. void
  427. acl_destroy_aclpb_pool ()
  428. {
  429. Acl_PBlock *currentPbBlock;
  430. Acl_PBlock *nextPbBlock;
  431. if (!aclQueue) {
  432. /* Nothing to do */
  433. return;
  434. }
  435. /* Free all busy pbBlocks in queue */
  436. currentPbBlock = aclQueue->aclq_busy;
  437. while (currentPbBlock) {
  438. nextPbBlock = currentPbBlock->aclpb_next;
  439. acl__free_aclpb(&currentPbBlock);
  440. currentPbBlock = nextPbBlock;
  441. }
  442. /* Free all free pbBlocks in queue */
  443. currentPbBlock = aclQueue->aclq_free;
  444. while (currentPbBlock) {
  445. nextPbBlock = currentPbBlock->aclpb_next;
  446. acl__free_aclpb(&currentPbBlock);
  447. currentPbBlock = nextPbBlock;
  448. }
  449. PR_DestroyLock(aclQueue->aclq_lock);
  450. slapi_ch_free((void**)&aclQueue);
  451. }
  452. /*
  453. * Get a FREE acl pblock from the pool.
  454. *
  455. */
  456. static Acl_PBlock *
  457. acl__get_aclpb_from_pool ( )
  458. {
  459. Acl_PBlock *aclpb = NULL;
  460. Acl_PBlock *t_aclpb = NULL;
  461. PR_Lock (aclQueue->aclq_lock );
  462. /* Get the first aclpb from the FREE List */
  463. aclpb = aclQueue->aclq_free;
  464. if ( aclpb ) {
  465. t_aclpb = aclpb->aclpb_next;
  466. if ( t_aclpb ) t_aclpb->aclpb_prev = NULL;
  467. aclQueue->aclq_free = t_aclpb;
  468. /* make the this an orphon */
  469. aclpb->aclpb_prev = aclpb->aclpb_next = NULL;
  470. aclQueue->aclq_nfree--;
  471. } else {
  472. slapi_log_error ( SLAPI_LOG_ACL, plugin_name,
  473. "Unable to find a free aclpb\n");
  474. aclpb = acl__malloc_aclpb ();
  475. }
  476. /* Now move it to the FRONT of busy list */
  477. t_aclpb = aclQueue->aclq_busy;
  478. aclpb->aclpb_next = t_aclpb;
  479. if ( t_aclpb ) t_aclpb->aclpb_prev = aclpb;
  480. aclQueue->aclq_busy = aclpb;
  481. aclQueue->aclq_nbusy++;
  482. PR_Unlock (aclQueue->aclq_lock );
  483. return aclpb;
  484. }
  485. /*
  486. * Put the acl pblock into the FREE pool.
  487. *
  488. */
  489. static int
  490. acl__put_aclpb_back_to_pool ( Acl_PBlock *aclpb )
  491. {
  492. Acl_PBlock *p_aclpb, *n_aclpb;
  493. PR_Lock (aclQueue->aclq_lock );
  494. /* Remove it from the busy list */
  495. n_aclpb = aclpb->aclpb_next;
  496. p_aclpb = aclpb->aclpb_prev;
  497. if ( p_aclpb ) {
  498. p_aclpb->aclpb_next = n_aclpb;
  499. if ( n_aclpb ) n_aclpb->aclpb_prev = p_aclpb;
  500. } else {
  501. aclQueue->aclq_busy = n_aclpb;
  502. if ( n_aclpb ) n_aclpb->aclpb_prev = NULL;
  503. }
  504. aclQueue->aclq_nbusy--;
  505. /* Put back to the FREE list */
  506. aclpb->aclpb_prev = NULL;
  507. n_aclpb = aclQueue->aclq_free;
  508. aclpb->aclpb_next = n_aclpb;
  509. if ( n_aclpb ) n_aclpb->aclpb_prev = aclpb;
  510. aclQueue->aclq_free = aclpb;
  511. aclQueue->aclq_nfree++;
  512. PR_Unlock (aclQueue->aclq_lock );
  513. return 0;
  514. }
  515. /*
  516. * Allocate the basic acl pb
  517. *
  518. */
  519. static Acl_PBlock *
  520. acl__malloc_aclpb ( )
  521. {
  522. Acl_PBlock *aclpb = NULL;
  523. aclpb = ( Acl_PBlock *) slapi_ch_calloc ( 1, sizeof ( Acl_PBlock) );
  524. /* Now set the propert we need for ACL evaluations */
  525. if ((aclpb->aclpb_proplist = PListNew(NULL)) == NULL) {
  526. slapi_log_error (SLAPI_LOG_FATAL, plugin_name,
  527. "Unable to allocate the aclprop PList\n");
  528. goto error;
  529. }
  530. if (PListInitProp(aclpb->aclpb_proplist, 0, DS_PROP_ACLPB, aclpb, 0) < 0) {
  531. slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
  532. "Unable to set the ACL PBLOCK in the Plist\n");
  533. goto error;
  534. }
  535. if (PListInitProp(aclpb->aclpb_proplist, 0, DS_ATTR_USERDN, aclpb, 0) < 0) {
  536. slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
  537. "Unable to set the USER DN in the Plist\n");
  538. goto error;
  539. }
  540. if (PListInitProp(aclpb->aclpb_proplist, 0, DS_ATTR_AUTHTYPE, aclpb, 0) < 0) {
  541. slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
  542. "Unable to set the AUTH TYPE in the Plist\n");
  543. goto error;
  544. }
  545. if (PListInitProp(aclpb->aclpb_proplist, 0, DS_ATTR_LDAPI, aclpb, 0) < 0) {
  546. slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
  547. "Unable to set the AUTH TYPE in the Plist\n");
  548. goto error;
  549. }
  550. if (PListInitProp(aclpb->aclpb_proplist, 0, DS_ATTR_ENTRY, aclpb, 0) < 0) {
  551. slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
  552. "Unable to set the ENTRY TYPE in the Plist\n");
  553. goto error;
  554. }
  555. if (PListInitProp(aclpb->aclpb_proplist, 0, DS_ATTR_SSF, aclpb, 0) < 0) {
  556. slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
  557. "Unable to set the SSF in the Plist\n");
  558. goto error;
  559. }
  560. /*
  561. * ACL_ATTR_IP and ACL_ATTR_DNS are initialized lazily in the
  562. * IpGetter and DnsGetter functions.
  563. * They are removed from the aclpb property list at acl__aclpb_done()
  564. * time.
  565. */
  566. /* allocate the acleval struct */
  567. aclpb->aclpb_acleval = (ACLEvalHandle_t *) ACL_EvalNew(NULL, NULL);
  568. if (aclpb->aclpb_acleval == NULL) {
  569. slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
  570. "Unable to allocate the acleval block\n");
  571. goto error;
  572. }
  573. /*
  574. * This is a libaccess routine.
  575. * Need to setup subject and resource property information
  576. */
  577. ACL_EvalSetSubject(NULL, aclpb->aclpb_acleval, aclpb->aclpb_proplist);
  578. /* allocate some space for attr name */
  579. aclpb->aclpb_Evalattr = (char *) slapi_ch_malloc (ACLPB_MAX_ATTR_LEN);
  580. aclpb->aclpb_deny_handles = (aci_t **) slapi_ch_calloc (1,
  581. ACLPB_INCR_LIST_HANDLES * sizeof (aci_t *));
  582. aclpb->aclpb_allow_handles = (aci_t **) slapi_ch_calloc (1,
  583. ACLPB_INCR_LIST_HANDLES * sizeof (aci_t *));
  584. aclpb->aclpb_deny_handles_size = ACLPB_INCR_LIST_HANDLES;
  585. aclpb->aclpb_allow_handles_size = ACLPB_INCR_LIST_HANDLES;
  586. /* allocate the array for bases */
  587. aclpb->aclpb_grpsearchbase = (char **)
  588. slapi_ch_calloc (ACLPB_INCR_BASES, sizeof(char *));
  589. aclpb->aclpb_grpsearchbase_size = ACLPB_INCR_BASES;
  590. aclpb->aclpb_numof_bases = 0;
  591. /* Make sure aclpb_search_base is initialized to NULL..tested elsewhere! */
  592. aclpb->aclpb_search_base = NULL;
  593. aclpb->aclpb_authorization_sdn = slapi_sdn_new ();
  594. aclpb->aclpb_curr_entry_sdn = slapi_sdn_new();
  595. aclpb->aclpb_aclContainer = acllist_get_aciContainer_new ();
  596. /* hash table to store macro matched values from targets */
  597. aclpb->aclpb_macro_ht = acl_ht_new();
  598. /* allocate arrays for handles */
  599. aclpb->aclpb_handles_index = (int *)
  600. slapi_ch_calloc (aclpb_max_selected_acls, sizeof (int));
  601. aclpb->aclpb_base_handles_index = (int *)
  602. slapi_ch_calloc (aclpb_max_selected_acls, sizeof (int));
  603. /* allocate arrays for result cache */
  604. aclpb->aclpb_cache_result = (r_cache_t *)
  605. slapi_ch_calloc (aclpb_max_cache_results + 1 /* 1 for cache overflow warning */,
  606. sizeof (r_cache_t));
  607. /* allocate arrays for target handles in eval_context */
  608. aclpb->aclpb_curr_entryEval_context.acle_handles_matched_target = (int *)
  609. slapi_ch_calloc (aclpb_max_selected_acls, sizeof (int));
  610. aclpb->aclpb_prev_entryEval_context.acle_handles_matched_target = (int *)
  611. slapi_ch_calloc (aclpb_max_selected_acls, sizeof (int));
  612. aclpb->aclpb_prev_opEval_context.acle_handles_matched_target = (int *)
  613. slapi_ch_calloc (aclpb_max_selected_acls, sizeof (int));
  614. return aclpb;
  615. error:
  616. acl__free_aclpb(&aclpb);
  617. return NULL;
  618. }
  619. /*
  620. * Free the acl pb. To be used at shutdown (SLAPI_PLUGIN_CLOSE_FN)
  621. * when we free the aclQueue
  622. */
  623. static void
  624. acl__free_aclpb ( Acl_PBlock **aclpb_ptr)
  625. {
  626. Acl_PBlock *aclpb = NULL;
  627. if (aclpb_ptr == NULL || *aclpb_ptr == NULL)
  628. return; // Nothing to do
  629. aclpb = *aclpb_ptr;
  630. if (aclpb->aclpb_acleval) {
  631. ACL_EvalDestroyNoDecrement(NULL, NULL, aclpb->aclpb_acleval);
  632. }
  633. if (aclpb->aclpb_proplist)
  634. PListDestroy(aclpb->aclpb_proplist);
  635. slapi_ch_free((void**)&(aclpb->aclpb_handles_index));
  636. slapi_ch_free((void**)&(aclpb->aclpb_base_handles_index));
  637. slapi_ch_free((void**)&(aclpb->aclpb_cache_result));
  638. slapi_ch_free((void**)
  639. &(aclpb->aclpb_curr_entryEval_context.acle_handles_matched_target));
  640. slapi_ch_free((void**)
  641. &(aclpb->aclpb_prev_entryEval_context.acle_handles_matched_target));
  642. slapi_ch_free((void**)
  643. &(aclpb->aclpb_prev_opEval_context.acle_handles_matched_target));
  644. slapi_sdn_free(&aclpb->aclpb_authorization_sdn);
  645. slapi_sdn_free(&aclpb->aclpb_curr_entry_sdn);
  646. if(aclpb->aclpb_macro_ht){
  647. acl_ht_free_all_entries_and_values(aclpb->aclpb_macro_ht);
  648. PR_HashTableDestroy(aclpb->aclpb_macro_ht);
  649. aclpb->aclpb_macro_ht = NULL;
  650. }
  651. slapi_ch_free((void**)&(aclpb->aclpb_allow_handles));
  652. slapi_ch_free((void**)&(aclpb->aclpb_deny_handles));
  653. acllist_free_aciContainer(&aclpb->aclpb_aclContainer);
  654. slapi_ch_free((void**)&(aclpb->aclpb_aclContainer));
  655. slapi_ch_free_string(&aclpb->aclpb_Evalattr);
  656. slapi_ch_array_free(aclpb->aclpb_grpsearchbase);
  657. slapi_ch_free((void**)aclpb_ptr);
  658. }
  659. /* Initializes the aclpb */
  660. void
  661. acl_init_aclpb ( Slapi_PBlock *pb, Acl_PBlock *aclpb, const char *ndn, int copy_from_aclcb)
  662. {
  663. struct acl_cblock *aclcb = NULL;
  664. char *authType;
  665. void *conn;
  666. int op_type;
  667. intptr_t ssf = 0;
  668. if ( NULL == aclpb ) {
  669. slapi_log_error ( SLAPI_LOG_FATAL, plugin_name, "acl_init_aclpb:No ACLPB\n");
  670. return;
  671. }
  672. /* See if we have initialized already */
  673. if (aclpb->aclpb_state & ACLPB_INITIALIZED) return;
  674. slapi_pblock_get ( pb, SLAPI_OPERATION_TYPE, &op_type );
  675. if ( op_type == SLAPI_OPERATION_BIND || op_type == SLAPI_OPERATION_UNBIND )
  676. return;
  677. /* We indicate the initialize here becuase, if something goes wrong, it's cleaned up
  678. ** properly.
  679. */
  680. aclpb->aclpb_state = ACLPB_INITIALIZED;
  681. /* We make an anonymous user a non null dn which is empty */
  682. if (ndn && *ndn != '\0' )
  683. slapi_sdn_set_ndn_byval ( aclpb->aclpb_authorization_sdn, ndn );
  684. else
  685. slapi_sdn_set_ndn_byval ( aclpb->aclpb_authorization_sdn, "" );
  686. /* reset scoped entry cache to be empty */
  687. aclpb->aclpb_scoped_entry_anominfo.anom_e_nummatched = 0;
  688. if (PListAssignValue(aclpb->aclpb_proplist, DS_ATTR_USERDN,
  689. slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn), 0) < 0) {
  690. slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
  691. "Unable to set the USER DN in the Plist\n");
  692. return;
  693. }
  694. slapi_pblock_get ( pb, SLAPI_OPERATION_AUTHTYPE, &authType );
  695. if (PListAssignValue(aclpb->aclpb_proplist, DS_ATTR_AUTHTYPE, authType, 0) < 0) {
  696. slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
  697. "Unable to set the AUTH TYPE in the Plist\n");
  698. return;
  699. }
  700. if(slapi_is_ldapi_conn(pb)){
  701. if(PListAssignValue(aclpb->aclpb_proplist, DS_ATTR_LDAPI, "yes", 0) < 0){
  702. slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
  703. "Unable to set the AUTH TYPE in the Plist\n");
  704. return;
  705. }
  706. }
  707. slapi_pblock_get ( pb, SLAPI_OPERATION_SSF, &ssf);
  708. if (PListAssignValue(aclpb->aclpb_proplist, DS_ATTR_SSF, (const void *)ssf, 0) < 0) {
  709. slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
  710. "Unable to set the SSF in the Plist\n");
  711. return;
  712. }
  713. /* PKBxxx: We should be getting it from the OP struct */
  714. slapi_pblock_get ( pb, SLAPI_CONN_CERT, &aclpb->aclpb_clientcert );
  715. /* See if the we have already a cached info about user's group */
  716. aclg_init_userGroup ( aclpb, ndn, 0 /* get lock */ );
  717. slapi_pblock_get( pb, SLAPI_BE_MAXNESTLEVEL, &aclpb->aclpb_max_nesting_level );
  718. slapi_pblock_get( pb, SLAPI_SEARCH_SIZELIMIT, &aclpb->aclpb_max_member_sizelimit );
  719. if ( aclpb->aclpb_max_member_sizelimit == 0 ) {
  720. aclpb->aclpb_max_member_sizelimit = SLAPD_DEFAULT_LOOKTHROUGHLIMIT;
  721. } else if ( aclpb->aclpb_max_member_sizelimit < -1 ) {
  722. /* handle the case of a negtive size limit either set or due
  723. * to bug bz1065971. The member size limit should be dropped,
  724. * but for backward compatibility to the best we can
  725. */
  726. aclpb->aclpb_max_member_sizelimit = -1;
  727. }
  728. slapi_pblock_get( pb, SLAPI_OPERATION_TYPE, &aclpb->aclpb_optype );
  729. aclpb->aclpb_signature = acl_get_aclsignature();
  730. aclpb->aclpb_last_cache_result = 0;
  731. aclpb->aclpb_pblock = pb;
  732. PR_ASSERT ( aclpb->aclpb_pblock != NULL );
  733. /* get the connection */
  734. slapi_pblock_get ( pb, SLAPI_CONNECTION, &conn);
  735. aclcb = (struct acl_cblock *) acl_get_ext ( ACL_EXT_CONNECTION, conn );
  736. if (NULL == aclcb || NULL == aclcb->aclcb_lock) {
  737. /* This could happen if the client is dead and we are in
  738. ** process of abondoning this operation
  739. */
  740. slapi_log_error( SLAPI_LOG_ACL, plugin_name,
  741. "No CONNECTION extension\n");
  742. } else if ( aclcb->aclcb_state == -1 ) {
  743. /* indicate that we need to update the cache */
  744. aclpb->aclpb_state |= ACLPB_UPD_ACLCB_CACHE;
  745. aclcb->aclcb_state = 0; /* Nore this is ACLCB and not ACLPB */
  746. } else if ( copy_from_aclcb ){
  747. char *cdn;
  748. Slapi_DN *c_sdn; /* client SDN */
  749. /* check if the operation is abandoned or not.*/
  750. if ( slapi_op_abandoned ( pb ) ) {
  751. return;
  752. }
  753. slapi_pblock_get ( pb, SLAPI_CONN_DN, &cdn ); /* We *must* free cdn! */
  754. c_sdn = slapi_sdn_new_dn_passin( cdn );
  755. PR_Lock ( aclcb->aclcb_lock );
  756. /*
  757. * since PR_Lock is taken,
  758. * we can mark the connection extension ok to be destroyed.
  759. */
  760. if ( (aclcb->aclcb_aclsignature != acl_get_aclsignature()) ||
  761. ( (NULL == cdn) && aclcb->aclcb_sdn ) ||
  762. (cdn && (NULL == aclcb->aclcb_sdn )) ||
  763. (cdn && aclcb->aclcb_sdn && ( 0 != slapi_sdn_compare ( c_sdn, aclcb->aclcb_sdn ) ))) {
  764. /* cleanup the aclcb cache */
  765. acl_clean_aclEval_context ( &aclcb->aclcb_eval_context, 0 /*clean*/ );
  766. aclcb->aclcb_state = 0;
  767. aclcb->aclcb_aclsignature = 0;
  768. slapi_sdn_done ( aclcb->aclcb_sdn );
  769. }
  770. slapi_sdn_free ( &c_sdn );
  771. /* COPY the cached information from ACLCB --> ACLPB */
  772. if ( aclcb->aclcb_state & ACLCB_HAS_CACHED_EVALCONTEXT) {
  773. acl_copyEval_context ( aclpb, &aclcb->aclcb_eval_context ,
  774. &aclpb->aclpb_prev_opEval_context, 0 );
  775. aclpb->aclpb_state |= ACLPB_HAS_ACLCB_EVALCONTEXT;
  776. }
  777. PR_Unlock ( aclcb->aclcb_lock );
  778. }
  779. }
  780. /* Cleans up the aclpb */
  781. static void
  782. acl__done_aclpb ( struct acl_pblock *aclpb )
  783. {
  784. int i;
  785. int dump_aclpb_info = 0;
  786. int rc=-1;
  787. char *tmp_ptr=NULL;
  788. /*
  789. ** First, let's do some sanity checks to see if we have everything what
  790. ** it should be.
  791. */
  792. /* Nothing needs to be cleaned up in this case */
  793. if (!(aclpb->aclpb_state & ACLPB_INITIALIZED))
  794. return;
  795. /* Check the state */
  796. if (aclpb->aclpb_state & ~ACLPB_STATE_ALL) {
  797. slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
  798. "The aclpb.state value (%d) is incorrect. Exceeded the limit (%d)\n",
  799. aclpb->aclpb_state, ACLPB_STATE_ALL);
  800. dump_aclpb_info = 1;
  801. }
  802. #ifdef FOR_DEBUGGING
  803. acl__dump_stats ( aclpb, acl__get_aclpb_type(aclpb));
  804. #endif
  805. /* reset the usergroup cache */
  806. aclg_reset_userGroup ( aclpb );
  807. if ( aclpb->aclpb_res_type & ~ACLPB_RESTYPE_ALL ) {
  808. slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
  809. "The aclpb res_type value (%d) has exceeded. Limit is (%d)\n",
  810. aclpb->aclpb_res_type, ACLPB_RESTYPE_ALL );
  811. dump_aclpb_info = 1;
  812. }
  813. if ( dump_aclpb_info ) {
  814. const char *ndn;
  815. slapi_log_error ( SLAPI_LOG_FATAL, plugin_name,
  816. "ACLPB value is:%p\n", aclpb );
  817. ndn = slapi_sdn_get_ndn ( aclpb->aclpb_curr_entry_sdn );
  818. slapi_log_error ( SLAPI_LOG_FATAL, plugin_name, "curr_entry:%p num_entries:%d curr_dn:%p\n",
  819. aclpb->aclpb_curr_entry ? (char *) aclpb->aclpb_curr_entry : "NULL",
  820. aclpb->aclpb_num_entries,
  821. ndn ? ndn : "NULL");
  822. slapi_log_error ( SLAPI_LOG_FATAL, plugin_name, "Last attr:%p, Plist:%p acleval: %p\n",
  823. aclpb->aclpb_Evalattr ? aclpb->aclpb_Evalattr : "NULL",
  824. aclpb->aclpb_proplist ? (char *) aclpb->aclpb_proplist : "NULL",
  825. aclpb->aclpb_acleval ? (char *) aclpb->aclpb_acleval : "NULL" );
  826. }
  827. /* Now Free the contents or clean it */
  828. slapi_sdn_done ( aclpb->aclpb_curr_entry_sdn );
  829. if (aclpb->aclpb_Evalattr)
  830. aclpb->aclpb_Evalattr[0] = '\0';
  831. /* deallocate the contents of the base array */
  832. for (i=0; i < aclpb->aclpb_numof_bases; i++) {
  833. if (aclpb->aclpb_grpsearchbase[i])
  834. slapi_ch_free ( (void **)&aclpb->aclpb_grpsearchbase[i] );
  835. }
  836. aclpb->aclpb_numof_bases = 0;
  837. acl_clean_aclEval_context ( &aclpb->aclpb_prev_opEval_context, 0 /*claen*/ );
  838. acl_clean_aclEval_context ( &aclpb->aclpb_prev_entryEval_context, 0 /*clean*/ );
  839. acl_clean_aclEval_context ( &aclpb->aclpb_curr_entryEval_context, 0/*clean*/ );
  840. if ( aclpb->aclpb_client_entry ) slapi_entry_free ( aclpb->aclpb_client_entry );
  841. aclpb->aclpb_client_entry = NULL;
  842. slapi_sdn_done ( aclpb->aclpb_authorization_sdn );
  843. aclpb->aclpb_pblock = NULL;
  844. slapi_ch_free_string(&aclpb->aclpb_search_base );
  845. for ( i=0; i < aclpb->aclpb_num_deny_handles; i++ )
  846. aclpb->aclpb_deny_handles[i] = NULL;
  847. aclpb->aclpb_num_deny_handles = 0;
  848. for ( i=0; i < aclpb->aclpb_num_allow_handles; i++ )
  849. aclpb->aclpb_allow_handles[i] = NULL;
  850. aclpb->aclpb_num_allow_handles = 0;
  851. /* clear results cache */
  852. memset((char*)aclpb->aclpb_cache_result, 0,
  853. sizeof(struct result_cache)*aclpb->aclpb_last_cache_result);
  854. aclpb->aclpb_last_cache_result = 0;
  855. aclpb->aclpb_handles_index[0] = -1;
  856. aclpb->aclpb_base_handles_index[0] = -1;
  857. aclpb->aclpb_stat_acllist_scanned = 0;
  858. aclpb->aclpb_stat_aclres_matched = 0;
  859. aclpb->aclpb_stat_total_entries = 0;
  860. aclpb->aclpb_stat_anom_list_scanned = 0;
  861. aclpb->aclpb_stat_num_copycontext = 0;
  862. aclpb->aclpb_stat_num_copy_attrs = 0;
  863. aclpb->aclpb_stat_num_tmatched_acls = 0;
  864. aclpb->aclpb_clientcert = NULL;
  865. aclpb->aclpb_proxy = NULL;
  866. acllist_done_aciContainer ( aclpb->aclpb_aclContainer );
  867. /*
  868. * Here, decide which things need to be freed/removed/whatever from the
  869. * aclpb_proplist.
  870. */
  871. /*
  872. * The DS_ATTR_DNS property contains the name of the client machine.
  873. *
  874. * The value pointed to by this property is stored in the pblock--it
  875. * points to the SLAPI_CLIENT_DNS object. So, that memory will
  876. * be freed elsewhere.
  877. *
  878. * It's removed here from the aclpb_proplist as it would be an error to
  879. * allow it to persist in the aclpb which is an operation time thing.
  880. * If we leave it here the next time this aclpb gets used, the DnsGetter
  881. * is not called by LASDnsEval/ACL_GetAttribute() as it thinks the
  882. * ACL_ATTR_DNS has already been initialized.
  883. *
  884. */
  885. if ((rc = PListFindValue(aclpb->aclpb_proplist, ACL_ATTR_DNS,
  886. (void **)&tmp_ptr, NULL)) > 0) {
  887. PListDeleteProp(aclpb->aclpb_proplist, rc, NULL);
  888. }
  889. /* reset the LDAPI property */
  890. PListAssignValue(aclpb->aclpb_proplist, DS_ATTR_LDAPI, NULL, 0);
  891. /*
  892. * Remove the DS_ATTR_IP property from the property list.
  893. * The value of this property is just the property pointer
  894. * (an unsigned long) so that gets freed too when we delete the
  895. * property.
  896. * It's removed here from the aclpb_proplist as it would be an error to
  897. * allow it to persist in the aclpb which is an operation time thing.
  898. * If we leave it here the next time this aclpb gets used, the DnsGetter
  899. * is not called by LASIpEval/ACL_GetAttribute() as it thinks the
  900. * ACL_ATTR_IP has already been initialized.
  901. */
  902. if ((rc = PListFindValue(aclpb->aclpb_proplist, ACL_ATTR_IP,
  903. (void **)&tmp_ptr, NULL)) > 0) {
  904. PListDeleteProp(aclpb->aclpb_proplist, rc, NULL);
  905. }
  906. /*
  907. * The DS_ATTR_USERDN value comes from aclpb_authorization_sdn.
  908. * This memory
  909. * is freed above using aclpb_authorization_sdn so we don't need to free it here
  910. * before overwriting the old value.
  911. */
  912. PListAssignValue(aclpb->aclpb_proplist, DS_ATTR_USERDN, NULL, 0);
  913. /*
  914. * The DS_ATTR_AUTHTYPE value is a pointer into the pblock, so
  915. * we do not need to free that memory before overwriting the value.
  916. */
  917. PListAssignValue(aclpb->aclpb_proplist, DS_ATTR_AUTHTYPE, NULL, 0);
  918. /*
  919. * DO NOT overwrite the aclpb pointer--it is initialized at malloc_aclpb
  920. * time and is kept within the aclpb.
  921. *
  922. * PListAssignValue(aclpb->aclpb_proplist, DS_PROP_ACLPB, NULL, 0);
  923. */
  924. /*
  925. * The DS_ATTR_ENTRY value was a pointer to the entry being evaluated
  926. * by the ACL code. That entry comes from outside the context of
  927. * the acl code and so is dealt with out there. Ergo, here we can just
  928. * lose the pointer to that entry.
  929. */
  930. PListAssignValue(aclpb->aclpb_proplist, DS_ATTR_ENTRY, NULL, 0);
  931. aclpb->aclpb_signature = 0;
  932. /* reset scoped entry cache to be empty */
  933. aclpb->aclpb_scoped_entry_anominfo.anom_e_nummatched = 0;
  934. /* Free up any of the string values left in the macro ht and remove
  935. * the entries.*/
  936. acl_ht_free_all_entries_and_values(aclpb->aclpb_macro_ht);
  937. /* Finally, set it to the no use state */
  938. aclpb->aclpb_state = 0;
  939. }
  940. #ifdef FOR_DEBUGGING
  941. static char *
  942. acl__get_aclpb_type ( Acl_PBlock *aclpb )
  943. {
  944. if (aclpb->aclpb_state & ACLPB_TYPE_PROXY)
  945. return ACLPB_TYPE_PROXY_STR;
  946. return ACLPB_TYPE_MAIN_STR;
  947. }
  948. static void
  949. acl__dump_stats ( struct acl_pblock *aclpb , const char *block_type)
  950. {
  951. PRUint64 connid = 0;
  952. int opid = 0;
  953. Slapi_PBlock *pb = NULL;
  954. pb = aclpb->aclpb_pblock;
  955. if ( pb ) {
  956. slapi_pblock_get ( pb, SLAPI_CONN_ID, &connid );
  957. slapi_pblock_get ( pb, SLAPI_OPERATION_ID, &opid );
  958. }
  959. /* DUMP STAT INFO */
  960. slapi_log_error( SLAPI_LOG_ACL, plugin_name,
  961. "**** ACL OPERATION STAT BEGIN ( aclpb:%p Block type: %s): Conn:%" PRIu64 " Operation:%d *******\n",
  962. aclpb, block_type, connid, opid );
  963. slapi_log_error( SLAPI_LOG_ACL, plugin_name, "\tNumber of entries scanned: %d\n",
  964. aclpb->aclpb_stat_total_entries);
  965. slapi_log_error( SLAPI_LOG_ACL, plugin_name, "\tNumber of times ACL List scanned: %d\n",
  966. aclpb->aclpb_stat_acllist_scanned);
  967. slapi_log_error( SLAPI_LOG_ACL, plugin_name, "\tNumber of ACLs with target matched:%d\n",
  968. aclpb->aclpb_stat_num_tmatched_acls);
  969. slapi_log_error( SLAPI_LOG_ACL, plugin_name, "\tNumber of times acl resource matched:%d\n",
  970. aclpb->aclpb_stat_aclres_matched);
  971. slapi_log_error( SLAPI_LOG_ACL, plugin_name, "\tNumber of times ANOM list scanned:%d\n",
  972. aclpb->aclpb_stat_anom_list_scanned);
  973. slapi_log_error( SLAPI_LOG_ACL, plugin_name, "\tNumber of times Context was copied:%d\n",
  974. aclpb->aclpb_stat_num_copycontext);
  975. slapi_log_error( SLAPI_LOG_ACL, plugin_name, "\tNumber of times Attrs was copied:%d\n",
  976. aclpb->aclpb_stat_num_copy_attrs);
  977. slapi_log_error( SLAPI_LOG_ACL, plugin_name, " **** ACL OPERATION STAT END *******\n");
  978. }
  979. #endif
  980. /****************************************************************************/
  981. /* E N D */
  982. /****************************************************************************/