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