1 /* slapi_overlay.c - SLAPI overlay */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/slapi/slapi_overlay.c,v 1.40.2.7 2008/06/02 18:00:53 quanah Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2008 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 * This work was initially developed by Luke Howard for inclusion
18 * in OpenLDAP Software.
25 #include <ac/string.h>
26 #include <ac/socket.h>
34 static slap_overinst slapi
;
35 static int slapi_over_initialized
= 0;
37 static int slapi_over_response( Operation
*op
, SlapReply
*rs
);
38 static int slapi_over_cleanup( Operation
*op
, SlapReply
*rs
);
41 slapi_over_pblock_new( Operation
*op
, SlapReply
*rs
)
45 pb
= slapi_pblock_new();
47 pb
->pb_conn
= op
->o_conn
;
51 PBLOCK_ASSERT_OP( pb
, op
->o_tag
);
57 slapi_op_internal_p( Operation
*op
, SlapReply
*rs
, slap_callback
*cb
)
60 Slapi_PBlock
*pb
= NULL
;
64 * Abstraction violating check for SLAPI internal operations
65 * allows pblock to remain consistent when invoking internal
68 for ( pcb
= op
->o_callback
; pcb
!= NULL
; pcb
= pcb
->sc_next
) {
69 if ( pcb
->sc_response
== slapi_int_response
) {
70 pb
= (Slapi_PBlock
*)pcb
->sc_private
;
71 PBLOCK_ASSERT_INTOP( pb
, 0 );
79 pb
= slapi_over_pblock_new( op
, rs
);
82 cb
->sc_response
= slapi_over_response
;
83 cb
->sc_cleanup
= slapi_over_cleanup
;
85 cb
->sc_next
= op
->o_callback
;
93 slapi_over_compute_output(
94 computed_attr_context
*c
,
95 Slapi_Attr
*attribute
,
100 AttributeDescription
*desc
;
103 if ( c
== NULL
|| attribute
== NULL
|| entry
== NULL
) {
107 rs
= (SlapReply
*)c
->cac_private
;
109 assert( rs
->sr_entry
== entry
);
111 desc
= attribute
->a_desc
;
113 if ( rs
->sr_attrs
== NULL
) {
114 /* All attrs request, skip operational attributes */
115 if ( is_at_operational( desc
->ad_type
) ) {
119 /* Specific attributes requested */
120 if ( is_at_operational( desc
->ad_type
) ) {
121 if ( !SLAP_OPATTRS( rs
->sr_attr_flags
) &&
122 !ad_inlist( desc
, rs
->sr_attrs
) ) {
126 if ( !SLAP_USERATTRS( rs
->sr_attr_flags
) &&
127 !ad_inlist( desc
, rs
->sr_attrs
) ) {
133 /* XXX perhaps we should check for existing attributes and merge */
134 for ( a
= &rs
->sr_operational_attrs
; *a
!= NULL
; a
= &(*a
)->a_next
)
137 *a
= slapi_attr_dup( attribute
);
143 slapi_over_aux_operational( Operation
*op
, SlapReply
*rs
)
145 /* Support for computed attribute plugins */
146 computed_attr_context ctx
;
149 if ( slapi_op_internal_p( op
, rs
, NULL
) ) {
150 return SLAP_CB_CONTINUE
;
153 ctx
.cac_pb
= slapi_over_pblock_new( op
, rs
);
155 ctx
.cac_private
= rs
;
157 if ( rs
->sr_entry
!= NULL
) {
159 * For each client requested attribute, call the plugins.
161 if ( rs
->sr_attrs
!= NULL
) {
162 for ( anp
= rs
->sr_attrs
; anp
->an_name
.bv_val
!= NULL
; anp
++ ) {
163 if ( compute_evaluator( &ctx
, anp
->an_name
.bv_val
,
164 rs
->sr_entry
, slapi_over_compute_output
) == 1 ) {
170 * Technically we shouldn't be returning operational attributes
171 * when the user requested only user attributes. We'll let the
172 * plugin decide whether to be naughty or not.
174 compute_evaluator( &ctx
, "*", rs
->sr_entry
, slapi_over_compute_output
);
178 slapi_pblock_destroy( ctx
.cac_pb
);
180 return SLAP_CB_CONTINUE
;
184 * We need this function to call frontendDB (global) plugins before
185 * database plugins, if we are invoked by a slap_callback.
188 slapi_over_call_plugins( Slapi_PBlock
*pb
, int type
)
190 int rc
= 1; /* means no plugins called */
193 PBLOCK_ASSERT_OP( pb
, 0 );
196 if ( !be_match( op
->o_bd
, frontendDB
) ) {
197 rc
= slapi_int_call_plugins( frontendDB
, type
, pb
);
200 rc
= slapi_int_call_plugins( op
->o_bd
, type
, pb
);
207 slapi_over_search( Operation
*op
, SlapReply
*rs
, int type
)
212 assert( rs
->sr_type
== REP_SEARCH
|| rs
->sr_type
== REP_SEARCHREF
);
214 /* create a new pblock to not trample on result controls */
215 pb
= slapi_over_pblock_new( op
, rs
);
217 rc
= slapi_over_call_plugins( pb
, type
);
218 if ( rc
>= 0 ) /* 1 means no plugins called */
219 rc
= SLAP_CB_CONTINUE
;
221 rc
= LDAP_SUCCESS
; /* confusing: don't abort, but don't send */
223 slapi_pblock_destroy(pb
);
229 * Call pre- and post-result plugins
232 slapi_over_result( Operation
*op
, SlapReply
*rs
, int type
)
234 Slapi_PBlock
*pb
= SLAPI_OPERATION_PBLOCK( op
);
236 assert( rs
->sr_type
== REP_RESULT
|| rs
->sr_type
== REP_SASL
|| rs
->sr_type
== REP_EXTENDED
);
238 slapi_over_call_plugins( pb
, type
);
240 return SLAP_CB_CONTINUE
;
245 slapi_op_bind_callback( Operation
*op
, SlapReply
*rs
, int prc
)
248 case SLAPI_BIND_SUCCESS
:
249 /* Continue with backend processing */
251 case SLAPI_BIND_FAIL
:
252 /* Failure, frontend (that's us) sends result */
253 rs
->sr_err
= LDAP_INVALID_CREDENTIALS
;
254 send_ldap_result( op
, rs
);
257 case SLAPI_BIND_ANONYMOUS
: /* undocumented */
258 default: /* plugin sent result or no plugins called */
259 BER_BVZERO( &op
->orb_edn
);
261 if ( rs
->sr_err
== LDAP_SUCCESS
) {
263 * Plugin will have called slapi_pblock_set(LDAP_CONN_DN) which
264 * will have set conn->c_dn and conn->c_ndn
266 if ( BER_BVISNULL( &op
->o_conn
->c_ndn
) && prc
== 1 ) {
267 /* No plugins were called; continue processing */
270 ldap_pvt_thread_mutex_lock( &op
->o_conn
->c_mutex
);
271 if ( !BER_BVISEMPTY( &op
->o_conn
->c_ndn
) ) {
272 ber_len_t max
= sockbuf_max_incoming_auth
;
273 ber_sockbuf_ctrl( op
->o_conn
->c_sb
,
274 LBER_SB_OPT_SET_MAX_INCOMING
, &max
);
276 ldap_pvt_thread_mutex_unlock( &op
->o_conn
->c_mutex
);
278 /* log authorization identity */
279 Statslog( LDAP_DEBUG_STATS
,
280 "%s BIND dn=\"%s\" mech=%s (SLAPI) ssf=0\n",
282 BER_BVISNULL( &op
->o_conn
->c_dn
)
283 ? "<empty>" : op
->o_conn
->c_dn
.bv_val
,
284 BER_BVISNULL( &op
->orb_mech
)
285 ? "<empty>" : op
->orb_mech
.bv_val
, 0, 0 );
296 slapi_op_search_callback( Operation
*op
, SlapReply
*rs
, int prc
)
298 Slapi_PBlock
*pb
= SLAPI_OPERATION_PBLOCK( op
);
300 /* check preoperation result code */
305 rs
->sr_err
= LDAP_SUCCESS
;
307 if ( pb
->pb_intop
== 0 &&
308 slapi_int_call_plugins( op
->o_bd
, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN
, pb
) == 0 ) {
310 * The plugin can set the SLAPI_SEARCH_FILTER.
311 * SLAPI_SEARCH_STRFILER is not normative.
313 op
->o_tmpfree( op
->ors_filterstr
.bv_val
, op
->o_tmpmemctx
);
314 filter2bv_x( op
, op
->ors_filter
, &op
->ors_filterstr
);
320 struct slapi_op_info
{
321 int soi_preop
; /* preoperation plugin parameter */
322 int soi_postop
; /* postoperation plugin parameter */
323 int soi_internal_preop
; /* internal preoperation plugin parameter */
324 int soi_internal_postop
; /* internal postoperation plugin parameter */
325 int (*soi_callback
)(Operation
*, SlapReply
*, int); /* preoperation result handler */
326 } slapi_op_dispatch_table
[] = {
328 SLAPI_PLUGIN_PRE_BIND_FN
,
329 SLAPI_PLUGIN_POST_BIND_FN
,
330 SLAPI_PLUGIN_INTERNAL_PRE_BIND_FN
,
331 SLAPI_PLUGIN_INTERNAL_POST_BIND_FN
,
332 slapi_op_bind_callback
335 SLAPI_PLUGIN_PRE_UNBIND_FN
,
336 SLAPI_PLUGIN_POST_UNBIND_FN
,
337 SLAPI_PLUGIN_INTERNAL_PRE_UNBIND_FN
,
338 SLAPI_PLUGIN_INTERNAL_POST_UNBIND_FN
,
342 SLAPI_PLUGIN_PRE_SEARCH_FN
,
343 SLAPI_PLUGIN_POST_SEARCH_FN
,
344 SLAPI_PLUGIN_INTERNAL_PRE_SEARCH_FN
,
345 SLAPI_PLUGIN_INTERNAL_POST_SEARCH_FN
,
346 slapi_op_search_callback
349 SLAPI_PLUGIN_PRE_COMPARE_FN
,
350 SLAPI_PLUGIN_POST_COMPARE_FN
,
351 SLAPI_PLUGIN_INTERNAL_PRE_COMPARE_FN
,
352 SLAPI_PLUGIN_INTERNAL_POST_COMPARE_FN
,
356 SLAPI_PLUGIN_PRE_MODIFY_FN
,
357 SLAPI_PLUGIN_POST_MODIFY_FN
,
358 SLAPI_PLUGIN_INTERNAL_PRE_MODIFY_FN
,
359 SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN
,
363 SLAPI_PLUGIN_PRE_MODRDN_FN
,
364 SLAPI_PLUGIN_POST_MODRDN_FN
,
365 SLAPI_PLUGIN_INTERNAL_PRE_MODRDN_FN
,
366 SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN
,
370 SLAPI_PLUGIN_PRE_ADD_FN
,
371 SLAPI_PLUGIN_POST_ADD_FN
,
372 SLAPI_PLUGIN_INTERNAL_PRE_ADD_FN
,
373 SLAPI_PLUGIN_INTERNAL_POST_ADD_FN
,
377 SLAPI_PLUGIN_PRE_DELETE_FN
,
378 SLAPI_PLUGIN_POST_DELETE_FN
,
379 SLAPI_PLUGIN_INTERNAL_PRE_DELETE_FN
,
380 SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN
,
384 SLAPI_PLUGIN_PRE_ABANDON_FN
,
385 SLAPI_PLUGIN_POST_ABANDON_FN
,
386 SLAPI_PLUGIN_INTERNAL_PRE_ABANDON_FN
,
387 SLAPI_PLUGIN_INTERNAL_POST_ABANDON_FN
,
400 slapi_tag2op( ber_tag_t tag
)
411 case LDAP_REQ_DELETE
:
414 case LDAP_REQ_MODRDN
:
417 case LDAP_REQ_MODIFY
:
420 case LDAP_REQ_COMPARE
:
423 case LDAP_REQ_SEARCH
:
426 case LDAP_REQ_UNBIND
:
437 /* Add SLAPI_RESCONTROLS to rs->sr_ctrls, with care, because
438 * rs->sr_ctrls could be allocated on the stack */
440 slapi_over_merge_controls( Operation
*op
, SlapReply
*rs
)
442 Slapi_PBlock
*pb
= SLAPI_OPERATION_PBLOCK( op
);
443 LDAPControl
**ctrls
= NULL
;
444 LDAPControl
**slapi_ctrls
= NULL
;
445 size_t n_slapi_ctrls
= 0;
446 size_t n_rs_ctrls
= 0;
449 slapi_pblock_get( pb
, SLAPI_RESCONTROLS
, (void **)&slapi_ctrls
);
451 n_slapi_ctrls
= slapi_int_count_controls( slapi_ctrls
);
452 n_rs_ctrls
= slapi_int_count_controls( rs
->sr_ctrls
);
454 slapi_pblock_set( pb
, SLAPI_X_OLD_RESCONTROLS
, (void *)rs
->sr_ctrls
);
456 if ( n_slapi_ctrls
== 0 )
457 return LDAP_SUCCESS
; /* no SLAPI controls */
459 ctrls
= (LDAPControl
**) op
->o_tmpalloc(
460 ( n_slapi_ctrls
+ n_rs_ctrls
+ 1 ) * sizeof(LDAPControl
*),
463 for ( i
= 0; i
< n_slapi_ctrls
; i
++ ) {
464 ctrls
[i
] = slapi_ctrls
[i
];
466 if ( rs
->sr_ctrls
!= NULL
) {
467 for ( i
= 0; i
< n_rs_ctrls
; i
++ ) {
468 ctrls
[n_slapi_ctrls
+ i
] = rs
->sr_ctrls
[i
];
471 ctrls
[n_slapi_ctrls
+ n_rs_ctrls
] = NULL
;
473 rs
->sr_ctrls
= ctrls
;
479 slapi_over_unmerge_controls( Operation
*op
, SlapReply
*rs
)
481 Slapi_PBlock
*pb
= SLAPI_OPERATION_PBLOCK( op
);
482 LDAPControl
**rs_ctrls
= NULL
;
484 slapi_pblock_get( pb
, SLAPI_X_OLD_RESCONTROLS
, (void **)&rs_ctrls
);
486 if ( rs_ctrls
== NULL
|| rs
->sr_ctrls
== rs_ctrls
) {
487 /* no copying done */
491 op
->o_tmpfree( rs
->sr_ctrls
, op
->o_tmpmemctx
);
492 rs
->sr_ctrls
= rs_ctrls
;
498 slapi_over_response( Operation
*op
, SlapReply
*rs
)
500 Slapi_PBlock
*pb
= SLAPI_OPERATION_PBLOCK( op
);
501 int rc
= SLAP_CB_CONTINUE
;
503 if ( pb
->pb_intop
== 0 ) {
504 switch ( rs
->sr_type
) {
508 rc
= slapi_over_result( op
, rs
, SLAPI_PLUGIN_PRE_RESULT_FN
);
511 rc
= slapi_over_search( op
, rs
, SLAPI_PLUGIN_PRE_ENTRY_FN
);
514 rc
= slapi_over_search( op
, rs
, SLAPI_PLUGIN_PRE_REFERRAL_FN
);
521 slapi_over_merge_controls( op
, rs
);
527 slapi_over_cleanup( Operation
*op
, SlapReply
*rs
)
529 Slapi_PBlock
*pb
= SLAPI_OPERATION_PBLOCK( op
);
530 int rc
= SLAP_CB_CONTINUE
;
532 slapi_over_unmerge_controls( op
, rs
);
534 if ( pb
->pb_intop
== 0 ) {
535 switch ( rs
->sr_type
) {
539 rc
= slapi_over_result( op
, rs
, SLAPI_PLUGIN_POST_RESULT_FN
);
542 rc
= slapi_over_search( op
, rs
, SLAPI_PLUGIN_POST_ENTRY_FN
);
545 rc
= slapi_over_search( op
, rs
, SLAPI_PLUGIN_POST_REFERRAL_FN
);
556 slapi_op_func( Operation
*op
, SlapReply
*rs
)
559 slap_operation_t which
;
560 struct slapi_op_info
*opinfo
;
566 int preop_type
, postop_type
;
569 if ( !slapi_plugins_used
)
570 return SLAP_CB_CONTINUE
;
573 * Find the SLAPI operation information for this LDAP
574 * operation; this will contain the preop and postop
575 * plugin types, as well as optional callbacks for
576 * setting up the SLAPI environment.
578 which
= slapi_tag2op( op
->o_tag
);
579 if ( which
>= op_last
) {
580 /* invalid operation, but let someone else deal with it */
581 return SLAP_CB_CONTINUE
;
584 opinfo
= &slapi_op_dispatch_table
[which
];
585 if ( opinfo
== NULL
) {
586 /* no SLAPI plugin types for this operation */
587 return SLAP_CB_CONTINUE
;
590 internal_op
= slapi_op_internal_p( op
, rs
, &cb
);
593 preop_type
= opinfo
->soi_internal_preop
;
594 postop_type
= opinfo
->soi_internal_postop
;
596 preop_type
= opinfo
->soi_preop
;
597 postop_type
= opinfo
->soi_postop
;
600 if ( preop_type
== 0 ) {
601 /* no SLAPI plugin types for this operation */
603 rc
= SLAP_CB_CONTINUE
;
607 pb
= SLAPI_OPERATION_PBLOCK( op
);
609 /* cache backend so we call correct postop plugins */
610 be
= pb
->pb_op
->o_bd
;
612 rc
= slapi_int_call_plugins( be
, preop_type
, pb
);
615 * soi_callback is responsible for examining the result code
616 * of the preoperation plugin and determining whether to
617 * abort. This is needed because of special SLAPI behaviour
618 e with bind preoperation plugins.
620 * The soi_callback function is also used to reset any values
621 * returned from the preoperation plugin before calling the
622 * backend (for the success case).
624 if ( opinfo
->soi_callback
== NULL
) {
625 /* default behaviour is preop plugin can abort operation */
631 rc
= (opinfo
->soi_callback
)( op
, rs
, rc
);
637 * Call actual backend (or next overlay in stack). We need to
638 * do this rather than returning SLAP_CB_CONTINUE and calling
639 * postoperation plugins in a response handler to match the
640 * behaviour of SLAPI in OpenLDAP 2.2, where postoperation
641 * plugins are called after the backend has completely
642 * finished processing the operation.
644 on
= (slap_overinst
*)op
->o_bd
->bd_info
;
647 rc
= overlay_op_walk( op
, rs
, which
, oi
, on
->on_next
);
650 * Call postoperation plugins
652 slapi_int_call_plugins( be
, postop_type
, pb
);
655 if ( !internal_op
) {
656 slapi_pblock_destroy(pb
);
657 cb
.sc_private
= NULL
;
660 op
->o_callback
= cb
.sc_next
;
666 slapi_over_extended( Operation
*op
, SlapReply
*rs
)
674 slapi_int_get_extop_plugin( &op
->ore_reqoid
, &callback
);
675 if ( callback
== NULL
) {
676 return SLAP_CB_CONTINUE
;
679 internal_op
= slapi_op_internal_p( op
, rs
, &cb
);
681 return SLAP_CB_CONTINUE
;
684 pb
= SLAPI_OPERATION_PBLOCK( op
);
686 rc
= (*callback
)( pb
);
687 if ( rc
== SLAPI_PLUGIN_EXTENDED_SENT_RESULT
) {
689 } else if ( rc
== SLAPI_PLUGIN_EXTENDED_NOT_HANDLED
) {
690 rc
= SLAP_CB_CONTINUE
;
694 assert( rs
->sr_rspoid
!= NULL
);
696 send_ldap_extended( op
, rs
);
699 slapi_ch_free_string( (char **)&rs
->sr_rspoid
);
702 if ( rs
->sr_rspdata
!= NULL
)
703 ber_bvfree( rs
->sr_rspdata
);
708 slapi_pblock_destroy( pb
);
709 op
->o_callback
= cb
.sc_next
;
715 slapi_over_access_allowed(
718 AttributeDescription
*desc
,
720 slap_access_t access
,
721 AccessControlState
*state
,
728 SlapReply rs
= { REP_RESULT
};
730 internal_op
= slapi_op_internal_p( op
, &rs
, &cb
);
732 cb
.sc_response
= NULL
;
733 cb
.sc_cleanup
= NULL
;
735 pb
= SLAPI_OPERATION_PBLOCK( op
);
737 rc
= slapi_int_access_allowed( op
, e
, desc
, val
, access
, state
);
739 rc
= SLAP_CB_CONTINUE
;
742 if ( !internal_op
) {
743 slapi_pblock_destroy( pb
);
746 op
->o_callback
= cb
.sc_next
;
752 slapi_over_acl_group(
755 struct berval
*gr_ndn
,
756 struct berval
*op_ndn
,
757 ObjectClass
*group_oc
,
758 AttributeDescription
*group_at
)
763 BackendDB
*be
= op
->o_bd
;
765 SlapReply rs
= { REP_RESULT
};
767 op
->o_bd
= select_backend( gr_ndn
, 0 );
769 for ( g
= op
->o_groups
; g
; g
= g
->ga_next
) {
770 if ( g
->ga_be
!= op
->o_bd
|| g
->ga_oc
!= group_oc
||
771 g
->ga_at
!= group_at
|| g
->ga_len
!= gr_ndn
->bv_len
)
775 if ( strcmp( g
->ga_ndn
, gr_ndn
->bv_val
) == 0 ) {
784 if ( target
!= NULL
&& dn_match( &target
->e_nname
, gr_ndn
) ) {
788 rc
= be_entry_get_rw( op
, gr_ndn
, group_oc
, group_at
, 0, &e
);
794 internal_op
= slapi_op_internal_p( op
, &rs
, &cb
);
796 cb
.sc_response
= NULL
;
797 cb
.sc_cleanup
= NULL
;
799 pb
= SLAPI_OPERATION_PBLOCK( op
);
801 slapi_pblock_set( pb
, SLAPI_X_GROUP_ENTRY
, (void *)e
);
802 slapi_pblock_set( pb
, SLAPI_X_GROUP_OPERATION_DN
, (void *)op_ndn
->bv_val
);
803 slapi_pblock_set( pb
, SLAPI_X_GROUP_ATTRIBUTE
, (void *)group_at
->ad_cname
.bv_val
);
804 slapi_pblock_set( pb
, SLAPI_X_GROUP_TARGET_ENTRY
, (void *)target
);
806 rc
= slapi_over_call_plugins( pb
, SLAPI_X_PLUGIN_PRE_GROUP_FN
);
807 if ( rc
>= 0 ) /* 1 means no plugins called */
808 rc
= SLAP_CB_CONTINUE
;
810 rc
= pb
->pb_rs
->sr_err
;
812 slapi_pblock_delete_param( pb
, SLAPI_X_GROUP_ENTRY
);
813 slapi_pblock_delete_param( pb
, SLAPI_X_GROUP_OPERATION_DN
);
814 slapi_pblock_delete_param( pb
, SLAPI_X_GROUP_ATTRIBUTE
);
815 slapi_pblock_delete_param( pb
, SLAPI_X_GROUP_TARGET_ENTRY
);
818 slapi_pblock_destroy( pb
);
821 be_entry_release_r( op
, e
);
824 op
->o_callback
= cb
.sc_next
;
826 rc
= LDAP_NO_SUCH_OBJECT
; /* return SLAP_CB_CONTINUE for correctness? */
829 if ( op
->o_tag
!= LDAP_REQ_BIND
&& !op
->o_do_not_cache
&&
830 rc
!= SLAP_CB_CONTINUE
) {
831 g
= op
->o_tmpalloc( sizeof( GroupAssertion
) + gr_ndn
->bv_len
,
837 g
->ga_len
= gr_ndn
->bv_len
;
838 strcpy( g
->ga_ndn
, gr_ndn
->bv_val
);
839 g
->ga_next
= op
->o_groups
;
843 * XXX don't call POST_GROUP_FN, I have no idea what the point of
844 * that plugin function was anyway
859 pb
= slapi_pblock_new();
861 rc
= slapi_int_call_plugins( be
, SLAPI_PLUGIN_START_FN
, pb
);
863 slapi_pblock_destroy( pb
);
876 pb
= slapi_pblock_new();
878 rc
= slapi_int_call_plugins( be
, SLAPI_PLUGIN_CLOSE_FN
, pb
);
880 slapi_pblock_destroy( pb
);
888 memset( &slapi
, 0, sizeof(slapi
) );
890 slapi
.on_bi
.bi_type
= SLAPI_OVERLAY_NAME
;
892 slapi
.on_bi
.bi_op_bind
= slapi_op_func
;
893 slapi
.on_bi
.bi_op_unbind
= slapi_op_func
;
894 slapi
.on_bi
.bi_op_search
= slapi_op_func
;
895 slapi
.on_bi
.bi_op_compare
= slapi_op_func
;
896 slapi
.on_bi
.bi_op_modify
= slapi_op_func
;
897 slapi
.on_bi
.bi_op_modrdn
= slapi_op_func
;
898 slapi
.on_bi
.bi_op_add
= slapi_op_func
;
899 slapi
.on_bi
.bi_op_delete
= slapi_op_func
;
900 slapi
.on_bi
.bi_op_abandon
= slapi_op_func
;
901 slapi
.on_bi
.bi_op_cancel
= slapi_op_func
;
903 slapi
.on_bi
.bi_db_open
= slapi_over_db_open
;
904 slapi
.on_bi
.bi_db_close
= slapi_over_db_close
;
906 slapi
.on_bi
.bi_extended
= slapi_over_extended
;
907 slapi
.on_bi
.bi_access_allowed
= slapi_over_access_allowed
;
908 slapi
.on_bi
.bi_operational
= slapi_over_aux_operational
;
909 slapi
.on_bi
.bi_acl_group
= slapi_over_acl_group
;
911 return overlay_register( &slapi
);
914 int slapi_over_is_inst( BackendDB
*be
)
916 return overlay_is_inst( be
, SLAPI_OVERLAY_NAME
);
919 int slapi_over_config( BackendDB
*be
, ConfigReply
*cr
)
921 if ( slapi_over_initialized
== 0 ) {
924 /* do global initializaiton */
925 ldap_pvt_thread_mutex_init( &slapi_hn_mutex
);
926 ldap_pvt_thread_mutex_init( &slapi_time_mutex
);
927 ldap_pvt_thread_mutex_init( &slapi_printmessage_mutex
);
929 if ( slapi_log_file
== NULL
)
930 slapi_log_file
= slapi_ch_strdup( LDAP_RUNDIR LDAP_DIRSEP
"errors" );
932 rc
= slapi_int_init_object_extensions();
936 rc
= slapi_over_init();
940 slapi_over_initialized
= 1;
943 return overlay_config( be
, SLAPI_OVERLAY_NAME
, -1, NULL
, cr
);
946 #endif /* LDAP_SLAPI */