]> git.sur5r.net Git - openldap/blob - servers/slapd/backend.c
Fix dbcache/entry lock deadlock. If dbcache lock is held, it's
[openldap] / servers / slapd / backend.c
1 /* backend.c - routines for dealing with back-end databases */
2
3
4 #include "portable.h"
5
6 #include <stdio.h>
7
8 #include <ac/string.h>
9 #include <ac/socket.h>
10
11 #include <sys/stat.h>
12
13 #include "slap.h"
14
15
16 #define BACKEND_GRAB_SIZE       10
17
18 int             nbackends;
19 Backend         *backends;
20 static int      maxbackends;
21
22 Backend *
23 new_backend(
24     char        *type
25 )
26 {
27         Backend *be;
28         int     foundit;
29
30         if ( nbackends == maxbackends ) {
31                 maxbackends += BACKEND_GRAB_SIZE;
32                 backends = (Backend *) ch_realloc( (char *) backends,
33                     maxbackends * sizeof(Backend) );
34                 memset( &backends[nbackends], '\0', BACKEND_GRAB_SIZE *
35                     sizeof(Backend) );
36         }
37
38         be = &backends[nbackends++];
39         be->be_sizelimit = defsize;
40         be->be_timelimit = deftime;
41         foundit = 0;
42
43 #ifdef SLAPD_LDBM
44         if ( strcasecmp( type, "ldbm" ) == 0 ) {
45                 be->be_bind = ldbm_back_bind;
46                 be->be_unbind = ldbm_back_unbind;
47                 be->be_search = ldbm_back_search;
48                 be->be_compare = ldbm_back_compare;
49                 be->be_modify = ldbm_back_modify;
50                 be->be_modrdn = ldbm_back_modrdn;
51                 be->be_add = ldbm_back_add;
52                 be->be_delete = ldbm_back_delete;
53                 be->be_abandon = ldbm_back_abandon;
54                 be->be_config = ldbm_back_config;
55                 be->be_init = ldbm_back_init;
56                 be->be_close = ldbm_back_close;
57 #ifdef SLAPD_ACLGROUPS
58                 be->be_group = ldbm_back_group;
59 #endif
60                 be->be_type = "ldbm";
61                 foundit = 1;
62         }
63 #endif
64
65 #ifdef SLAPD_PASSWD
66         if ( strcasecmp( type, "passwd" ) == 0 ) {
67                 be->be_bind = NULL;
68                 be->be_unbind = NULL;
69                 be->be_search = passwd_back_search;
70                 be->be_compare = NULL;
71                 be->be_modify = NULL;
72                 be->be_modrdn = NULL;
73                 be->be_add = NULL;
74                 be->be_delete = NULL;
75                 be->be_abandon = NULL;
76                 be->be_config = passwd_back_config;
77                 be->be_init = NULL;
78                 be->be_close = NULL;
79 #ifdef SLAPD_ACLGROUPS
80                 be->be_group = NULL;
81 #endif
82                 be->be_type = "passwd";
83                 foundit = 1;
84         }
85 #endif
86
87 #ifdef SLAPD_SHELL
88         if ( strcasecmp( type, "shell" ) == 0 ) {
89                 be->be_bind = shell_back_bind;
90                 be->be_unbind = shell_back_unbind;
91                 be->be_search = shell_back_search;
92                 be->be_compare = shell_back_compare;
93                 be->be_modify = shell_back_modify;
94                 be->be_modrdn = shell_back_modrdn;
95                 be->be_add = shell_back_add;
96                 be->be_delete = shell_back_delete;
97                 be->be_abandon = shell_back_abandon;
98                 be->be_config = shell_back_config;
99                 be->be_init = shell_back_init;
100                 be->be_close = NULL;
101 #ifdef SLAPD_ACLGROUPS
102                 be->be_group = NULL;
103 #endif
104                 be->be_type = "shell";
105                 foundit = 1;
106         }
107 #endif
108
109
110 #ifdef SLAPD_PERL
111         if ( strcasecmp( type, "perl" ) == 0 ) {
112 #ifdef notdef
113                 be->be_abandon = perl_back_abandon;
114                 be->be_bind = perl_back_bind;
115 #else
116                 be->be_abandon = NULL;
117                 be->be_bind = NULL;
118 #endif
119                 be->be_unbind = perl_back_unbind;
120                 be->be_search = perl_back_search;
121                 be->be_compare = perl_back_compare;
122                 be->be_modify = perl_back_modify;
123                 be->be_modrdn = perl_back_modrdn;
124                 be->be_add = perl_back_add;
125                 be->be_delete = perl_back_delete;
126                 be->be_config = perl_back_config;
127                 be->be_init = perl_back_init;
128                 be->be_close = perl_back_close;
129                 be->be_type = "perl";
130                 foundit = 1;
131         }
132 #endif
133
134
135
136         if ( be->be_init != NULL ) {
137                 (*be->be_init)( be );
138         }
139
140         if ( foundit == 0 ) {
141                 fprintf( stderr, "Unrecognized database type (%s)\n", type );
142                 exit( 1 );
143         }
144
145         return( be );
146 }
147
148 Backend *
149 select_backend( char * dn )
150 {
151         int     i, j, len, dnlen;
152
153         dnlen = strlen( dn );
154         for ( i = 0; i < nbackends; i++ ) {
155                 for ( j = 0; backends[i].be_suffix != NULL &&
156                     backends[i].be_suffix[j] != NULL; j++ )
157                 {
158                         len = strlen( backends[i].be_suffix[j] );
159
160                         if ( len > dnlen ) {
161                                 continue;
162                         }
163
164                         if ( strcmp( backends[i].be_suffix[j],
165                             dn + (dnlen - len) ) == 0 ) {
166                                 return( &backends[i] );
167                         }
168                 }
169         }
170
171         /* if no proper suffix could be found then check for aliases */
172         for ( i = 0; i < nbackends; i++ ) {
173                 for ( j = 0; 
174                       backends[i].be_suffixAlias != NULL && 
175                       backends[i].be_suffixAlias[j] != NULL; 
176                       j += 2 )
177                 {
178                         len = strlen( backends[i].be_suffixAlias[j] );
179
180                         if ( len > dnlen ) {
181                                 continue;
182                         }
183
184                         if ( strcmp( backends[i].be_suffixAlias[j],
185                             dn + (dnlen - len) ) == 0 ) {
186                                 return( &backends[i] );
187                         }
188                 }
189         }
190
191 #ifdef LDAP_ALLOW_NULL_SEARCH_BASE
192         /* Add greg@greg.rim.or.jp
193          * It's quick hack for cheap client
194          * Some browser offer a NULL base at ldap_search
195          *
196          * Should only be used as a last resort. -Kdz
197          */
198         if(dnlen == 0) {
199                 Debug( LDAP_DEBUG_TRACE,
200                         "select_backend: use default backend\n", 0, 0, 0 );
201                 return( &backends[0] );
202         }
203 #endif /* LDAP_ALLOW_NULL_SEARCH_BASE */
204
205         return( NULL );
206 }
207
208 int
209 be_issuffix(
210     Backend     *be,
211     char        *suffix
212 )
213 {
214         int     i;
215
216         for ( i = 0; be->be_suffix != NULL && be->be_suffix[i] != NULL; i++ ) {
217                 if ( strcmp( be->be_suffix[i], suffix ) == 0 ) {
218                         return( 1 );
219                 }
220         }
221
222         return( 0 );
223 }
224
225 int
226 be_isroot( Backend *be, char *ndn )
227 {
228         int rc;
229
230         if ( ndn == NULL || be->be_root_ndn == NULL ) {
231                 return( 0 );
232         }
233
234         rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
235
236         return(rc);
237 }
238
239 char *
240 be_root_dn( Backend *be )
241 {
242         int rc;
243
244         if ( be->be_root_dn == NULL ) {
245                 return( "" );
246         }
247
248         return be->be_root_dn;
249 }
250
251 int
252 be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
253 {
254         int result;
255
256         if ( ! be_isroot( be, ndn ) ) {
257                 return( 0 );
258         }
259
260 #ifdef SLAPD_CRYPT
261         ldap_pvt_thread_mutex_lock( &crypt_mutex );
262 #endif
263
264         result = lutil_passwd( cred->bv_val, be->be_root_pw );
265
266 #ifdef SLAPD_CRYPT
267         ldap_pvt_thread_mutex_unlock( &crypt_mutex );
268 #endif
269
270         return result == 0;
271 }
272
273 void
274 be_close( void )
275 {
276         int     i;
277
278         for ( i = 0; i < nbackends; i++ ) {
279                 if ( backends[i].be_close != NULL ) {
280                         (*backends[i].be_close)( &backends[i] );
281                 }
282         }
283 }
284
285
286 void
287 be_unbind(
288         Connection   *conn,
289         Operation    *op
290 )
291 {
292         int     i;
293
294         for ( i = 0; i < nbackends; i++ ) {
295                 if ( backends[i].be_unbind != NULL ) {
296                         (*backends[i].be_unbind)( &backends[i], conn, op );
297                 }
298         }
299 }
300
301 #ifdef SLAPD_ACLGROUPS
302 int 
303 be_group(
304         Backend *be,
305         Entry   *target,
306         char    *gr_ndn,
307         char    *op_ndn,
308         char    *objectclassValue,
309         char    *groupattrName
310 )
311 {
312         if (be->be_group)
313                 return( be->be_group(be, target, gr_ndn, op_ndn,
314                         objectclassValue, groupattrName) );
315         else
316                 return(1);
317 }
318 #endif