1 /* search.c - monitor backend search function */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/search.c,v 1.39.2.5 2008/02/11 23:26:47 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2008 The OpenLDAP Foundation.
6 * Portions Copyright 2001-2003 Pierangelo Masarati.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
18 * This work was initially developed by Pierangelo Masarati for inclusion
19 * in OpenLDAP Software.
26 #include <ac/string.h>
27 #include <ac/socket.h>
30 #include "back-monitor.h"
31 #include "proto-back-monitor.h"
34 monitor_send_children(
40 monitor_info_t
*mi
= ( monitor_info_t
* )op
->o_bd
->be_private
;
44 *e_nonvolatile
= NULL
;
49 mp
= ( monitor_entry_t
* )e_parent
->e_private
;
50 e_nonvolatile
= e
= mp
->mp_children
;
52 if ( MONITOR_HAS_VOLATILE_CH( mp
) ) {
53 monitor_entry_create( op
, rs
, NULL
, e_parent
, &e_ch
);
55 monitor_cache_release( mi
, e_parent
);
57 /* no volatile entries? */
59 /* no persistent entries? return */
64 /* volatile entries */
66 /* if no persistent, return only volatile */
70 /* else append persistent to volatile */
74 mp
= ( monitor_entry_t
* )e_tmp
->e_private
;
77 if ( e_tmp
== NULL
) {
87 for ( monitor_cache_lock( e
); e
!= NULL
; ) {
88 monitor_entry_update( op
, rs
, e
);
90 if ( op
->o_abandon
) {
91 /* FIXME: may leak generated children */
92 if ( nonvolatile
== 0 ) {
93 for ( e_tmp
= e
; e_tmp
!= NULL
; ) {
94 mp
= ( monitor_entry_t
* )e_tmp
->e_private
;
97 monitor_cache_release( mi
, e
);
99 if ( e_tmp
== e_nonvolatile
) {
105 monitor_cache_release( mi
, e
);
108 return SLAPD_ABANDON
;
111 rc
= test_filter( op
, e
, op
->oq_search
.rs_filter
);
112 if ( rc
== LDAP_COMPARE_TRUE
) {
115 rc
= send_search_entry( op
, rs
);
119 mp
= ( monitor_entry_t
* )e
->e_private
;
123 rc
= monitor_send_children( op
, rs
, e
, sub
);
125 /* FIXME: may leak generated children */
126 if ( nonvolatile
== 0 ) {
127 for ( ; e_tmp
!= NULL
; ) {
128 mp
= ( monitor_entry_t
* )e_tmp
->e_private
;
131 monitor_cache_release( mi
, e
);
133 if ( e_tmp
== e_nonvolatile
) {
143 if ( e_tmp
!= NULL
) {
144 monitor_cache_lock( e_tmp
);
148 /* otherwise the recursive call already released */
149 monitor_cache_release( mi
, e
);
153 if ( e
== e_nonvolatile
) {
162 monitor_back_search( Operation
*op
, SlapReply
*rs
)
164 monitor_info_t
*mi
= ( monitor_info_t
* )op
->o_bd
->be_private
;
165 int rc
= LDAP_SUCCESS
;
166 Entry
*e
= NULL
, *matched
= NULL
;
169 Debug( LDAP_DEBUG_TRACE
, "=> monitor_back_search\n", 0, 0, 0 );
172 /* get entry with reader lock */
173 monitor_cache_dn2entry( op
, rs
, &op
->o_req_ndn
, &e
, &matched
);
175 rs
->sr_err
= LDAP_NO_SUCH_OBJECT
;
177 if ( !access_allowed_mask( op
, matched
,
178 slap_schema
.si_ad_entry
,
179 NULL
, ACL_DISCLOSE
, NULL
, NULL
) )
183 rs
->sr_matched
= matched
->e_dn
;
187 send_ldap_result( op
, rs
);
189 monitor_cache_release( mi
, matched
);
190 rs
->sr_matched
= NULL
;
196 /* NOTE: __NEW__ "search" access is required
197 * on searchBase object */
198 if ( !access_allowed_mask( op
, e
, slap_schema
.si_ad_entry
,
199 NULL
, ACL_SEARCH
, NULL
, &mask
) )
201 monitor_cache_release( mi
, e
);
203 if ( !ACL_GRANT( mask
, ACL_DISCLOSE
) ) {
204 rs
->sr_err
= LDAP_NO_SUCH_OBJECT
;
206 rs
->sr_err
= LDAP_INSUFFICIENT_ACCESS
;
209 send_ldap_result( op
, rs
);
214 rs
->sr_attrs
= op
->oq_search
.rs_attrs
;
215 switch ( op
->oq_search
.rs_scope
) {
216 case LDAP_SCOPE_BASE
:
217 monitor_entry_update( op
, rs
, e
);
218 rc
= test_filter( op
, e
, op
->oq_search
.rs_filter
);
219 if ( rc
== LDAP_COMPARE_TRUE
) {
222 send_search_entry( op
, rs
);
226 monitor_cache_release( mi
, e
);
229 case LDAP_SCOPE_ONELEVEL
:
230 case LDAP_SCOPE_SUBORDINATE
:
231 rc
= monitor_send_children( op
, rs
, e
,
232 op
->oq_search
.rs_scope
== LDAP_SCOPE_SUBORDINATE
);
235 case LDAP_SCOPE_SUBTREE
:
236 monitor_entry_update( op
, rs
, e
);
237 rc
= test_filter( op
, e
, op
->oq_search
.rs_filter
);
238 if ( rc
== LDAP_COMPARE_TRUE
) {
241 send_search_entry( op
, rs
);
245 rc
= monitor_send_children( op
, rs
, e
, 1 );
249 rc
= LDAP_UNWILLING_TO_PERFORM
;
250 monitor_cache_release( mi
, e
);
255 if ( rs
->sr_err
!= SLAPD_ABANDON
) {
256 send_ldap_result( op
, rs
);