]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/search.c
notices
[openldap] / servers / slapd / back-monitor / search.c
1 /* search.c - monitor backend search function */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2003 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* ACKNOWLEDGEMENTS:
17  * This work was initially developed by Pierangelo Masarati for inclusion
18  * in OpenLDAP Software.
19  */
20 /* This is an altered version */
21 /*
22  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
23  * 
24  * This work has beed deveolped for the OpenLDAP Foundation 
25  * in the hope that it may be useful to the Open Source community, 
26  * but WITHOUT ANY WARRANTY.
27  * 
28  * Permission is granted to anyone to use this software for any purpose
29  * on any computer system, and to alter it and redistribute it, subject
30  * to the following restrictions:
31  * 
32  * 1. The author and SysNet s.n.c. are not responsible for the consequences
33  *    of use of this software, no matter how awful, even if they arise from
34  *    flaws in it.
35  * 
36  * 2. The origin of this software must not be misrepresented, either by
37  *    explicit claim or by omission.  Since few users ever read sources,
38  *    credits should appear in the documentation.
39  * 
40  * 3. Altered versions must be plainly marked as such, and must not be
41  *    misrepresented as being the original software.  Since few users
42  *    ever read sources, credits should appear in the documentation.
43  *    SysNet s.n.c. cannot be responsible for the consequences of the
44  *    alterations.
45  * 
46  * 4. This notice may not be removed or altered.
47  */
48
49 #include "portable.h"
50
51 #include <stdio.h>
52
53 #include <ac/string.h>
54 #include <ac/socket.h>
55
56 #include "slap.h"
57 #include "back-monitor.h"
58 #include "proto-back-monitor.h"
59
60 static int
61 monitor_send_children(
62         Operation       *op,
63         SlapReply       *rs,
64         Entry           *e_parent,
65         int             sub
66 )
67 {
68         struct monitorinfo      *mi =
69                 (struct monitorinfo *) op->o_bd->be_private;
70         Entry                   *e, *e_tmp, *e_ch;
71         struct monitorentrypriv *mp;
72         int                     rc;
73
74         mp = ( struct monitorentrypriv * )e_parent->e_private;
75         e = mp->mp_children;
76
77         e_ch = NULL;
78         if ( MONITOR_HAS_VOLATILE_CH( mp ) ) {
79                 monitor_entry_create( op, NULL, e_parent, &e_ch );
80         }
81         monitor_cache_release( mi, e_parent );
82
83         /* no volatile entries? */
84         if ( e_ch == NULL ) {
85                 /* no persistent entries? return */
86                 if ( e == NULL ) {
87                         return( 0 );
88                 }
89         
90         /* volatile entries */
91         } else {
92                 /* if no persistent, return only volatile */
93                 if ( e == NULL ) {
94                         e = e_ch;
95                         monitor_cache_lock( e_ch );
96
97                 /* else append persistent to volatile */
98                 } else {
99                         e_tmp = e_ch;
100                         do {
101                                 mp = ( struct monitorentrypriv * )e_tmp->e_private;
102                                 e_tmp = mp->mp_next;
103         
104                                 if ( e_tmp == NULL ) {
105                                         mp->mp_next = e;
106                                         break;
107                                 }
108                         } while ( e_tmp );
109                         e = e_ch;
110                 }
111         }
112
113         /* return entries */
114         for ( ; e != NULL; ) {
115                 mp = ( struct monitorentrypriv * )e->e_private;
116
117                 monitor_entry_update( op, e );
118                 
119                 rc = test_filter( op, e, op->oq_search.rs_filter );
120                 if ( rc == LDAP_COMPARE_TRUE ) {
121                         rs->sr_entry = e;
122                         send_search_entry( op, rs );
123                         rs->sr_entry = NULL;
124                 }
125
126                 if ( ( mp->mp_children || MONITOR_HAS_VOLATILE_CH( mp ) )
127                                 && sub ) {
128                         rc = monitor_send_children( op, rs, e, sub );
129                         if ( rc ) {
130                                 return( rc );
131                         }
132                 }
133
134                 e_tmp = mp->mp_next;
135                 if ( e_tmp != NULL ) {
136                         monitor_cache_lock( e_tmp );
137                 }
138                 monitor_cache_release( mi, e );
139                 e = e_tmp;
140         }
141         
142         return( 0 );
143 }
144
145 int
146 monitor_back_search( Operation *op, SlapReply *rs )
147 {
148         struct monitorinfo      *mi
149                 = (struct monitorinfo *) op->o_bd->be_private;
150         int             rc = LDAP_SUCCESS;
151         Entry           *e, *matched = NULL;
152
153 #ifdef NEW_LOGGING
154         LDAP_LOG( BACK_MON, ENTRY,
155                    "monitor_back_search: enter\n", 0, 0, 0 );
156 #else
157         Debug(LDAP_DEBUG_TRACE, "=> monitor_back_search\n%s%s%s", "", "", "");
158 #endif
159
160
161         /* get entry with reader lock */
162         monitor_cache_dn2entry( op, &op->o_req_ndn, &e, &matched );
163         if ( e == NULL ) {
164                 rs->sr_err = LDAP_NO_SUCH_OBJECT;
165                 if ( matched ) {
166                         rs->sr_matched = matched->e_dn;
167                 }
168
169                 send_ldap_result( op, rs );
170                 if ( matched ) {
171                         monitor_cache_release( mi, matched );
172                         rs->sr_matched = NULL;
173                 }
174
175                 return( 0 );
176         }
177
178         rs->sr_attrs = op->oq_search.rs_attrs;
179         switch ( op->oq_search.rs_scope ) {
180         case LDAP_SCOPE_BASE:
181                 monitor_entry_update( op, e );
182                 rc = test_filter( op, e, op->oq_search.rs_filter );
183                 if ( rc == LDAP_COMPARE_TRUE ) {
184                         rs->sr_entry = e;
185                         send_search_entry( op, rs );
186                         rs->sr_entry = NULL;
187                 }
188                 rc = LDAP_SUCCESS;
189                 monitor_cache_release( mi, e );
190                 break;
191
192         case LDAP_SCOPE_ONELEVEL:
193                 rc = monitor_send_children( op, rs, e, 0 );
194                 if ( rc ) {
195                         rc = LDAP_OTHER;
196                 }
197                 
198                 break;
199
200         case LDAP_SCOPE_SUBTREE:
201                 monitor_entry_update( op, e );
202                 rc = test_filter( op, e, op->oq_search.rs_filter );
203                 if ( rc == LDAP_COMPARE_TRUE ) {
204                         rs->sr_entry = e;
205                         send_search_entry( op, rs );
206                         rs->sr_entry = NULL;
207                 }
208
209                 rc = monitor_send_children( op, rs, e, 1 );
210                 if ( rc ) {
211                         rc = LDAP_OTHER;
212                 }
213
214                 break;
215         }
216         
217         rs->sr_attrs = NULL;
218         rs->sr_err = rc;
219         send_ldap_result( op, rs );
220
221         return( rc == LDAP_SUCCESS ? 0 : 1 );
222 }
223