]> git.sur5r.net Git - openldap/blob - servers/slapd/backend.c
Fix index_change_values NULL vals bug (ITS#238)
[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         if ( be->be_init != NULL ) {
110                 (*be->be_init)( be );
111         }
112
113         if ( foundit == 0 ) {
114                 fprintf( stderr, "Unrecognized database type (%s)\n", type );
115                 exit( 1 );
116         }
117
118         return( be );
119 }
120
121 Backend *
122 select_backend( char * dn )
123 {
124         int     i, j, len, dnlen;
125
126         dnlen = strlen( dn );
127         for ( i = 0; i < nbackends; i++ ) {
128                 for ( j = 0; backends[i].be_suffix != NULL &&
129                     backends[i].be_suffix[j] != NULL; j++ )
130                 {
131                         len = strlen( backends[i].be_suffix[j] );
132
133                         if ( len > dnlen ) {
134                                 continue;
135                         }
136
137                         if ( strcmp( backends[i].be_suffix[j],
138                             dn + (dnlen - len) ) == 0 ) {
139                                 return( &backends[i] );
140                         }
141                 }
142         }
143
144         /* if no proper suffix could be found then check for aliases */
145         for ( i = 0; i < nbackends; i++ ) {
146                 for ( j = 0; 
147                       backends[i].be_suffixAlias != NULL && 
148                       backends[i].be_suffixAlias[j] != NULL; 
149                       j += 2 )
150                 {
151                         len = strlen( backends[i].be_suffixAlias[j] );
152
153                         if ( len > dnlen ) {
154                                 continue;
155                         }
156
157                         if ( strcmp( backends[i].be_suffixAlias[j],
158                             dn + (dnlen - len) ) == 0 ) {
159                                 return( &backends[i] );
160                         }
161                 }
162         }
163
164 #ifdef LDAP_ALLOW_NULL_SEARCH_BASE
165         /* Add greg@greg.rim.or.jp
166          * It's quick hack for cheap client
167          * Some browser offer a NULL base at ldap_search
168          *
169          * Should only be used as a last resort. -Kdz
170          */
171         if(dnlen == 0) {
172                 Debug( LDAP_DEBUG_TRACE,
173                         "select_backend: use default backend\n", 0, 0, 0 );
174                 return( &backends[0] );
175         }
176 #endif /* LDAP_ALLOW_NULL_SEARCH_BASE */
177
178         return( NULL );
179 }
180
181 int
182 be_issuffix(
183     Backend     *be,
184     char        *suffix
185 )
186 {
187         int     i;
188
189         for ( i = 0; be->be_suffix != NULL && be->be_suffix[i] != NULL; i++ ) {
190                 if ( strcmp( be->be_suffix[i], suffix ) == 0 ) {
191                         return( 1 );
192                 }
193         }
194
195         return( 0 );
196 }
197
198 int
199 be_isroot( Backend *be, char *ndn )
200 {
201         int rc;
202
203         if ( ndn == NULL || be->be_root_ndn == NULL ) {
204                 return( 0 );
205         }
206
207         rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
208
209         return(rc);
210 }
211
212 char *
213 be_root_dn( Backend *be )
214 {
215         int rc;
216
217         if ( be->be_root_dn == NULL ) {
218                 return( "" );
219         }
220
221         return be->be_root_dn;
222 }
223
224 int
225 be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
226 {
227         int result;
228
229         if ( ! be_isroot( be, ndn ) ) {
230                 return( 0 );
231         }
232
233 #ifdef SLAPD_CRYPT
234         ldap_pvt_thread_mutex_lock( &crypt_mutex );
235 #endif
236
237         result = lutil_passwd( cred->bv_val, be->be_root_pw );
238
239 #ifdef SLAPD_CRYPT
240         ldap_pvt_thread_mutex_unlock( &crypt_mutex );
241 #endif
242
243         return result == 0;
244 }
245
246 void
247 be_close( void )
248 {
249         int     i;
250
251         for ( i = 0; i < nbackends; i++ ) {
252                 if ( backends[i].be_close != NULL ) {
253                         (*backends[i].be_close)( &backends[i] );
254                 }
255         }
256 }
257
258
259 void
260 be_unbind(
261         Connection   *conn,
262         Operation    *op
263 )
264 {
265         int     i;
266
267         for ( i = 0; i < nbackends; i++ ) {
268                 if ( backends[i].be_unbind != NULL ) {
269                         (*backends[i].be_unbind)( &backends[i], conn, op );
270                 }
271         }
272 }
273
274 #ifdef SLAPD_ACLGROUPS
275 int 
276 be_group(
277         Backend *be,
278         Entry   *target,
279         char    *gr_ndn,
280         char    *op_ndn,
281         char    *objectclassValue,
282         char    *groupattrName
283 )
284 {
285         if (be->be_group)
286                 return( be->be_group(be, target, gr_ndn, op_ndn,
287                         objectclassValue, groupattrName) );
288         else
289                 return(1);
290 }
291 #endif