]> git.sur5r.net Git - openldap/blob - servers/slapd/backend.c
dc63e252317a8be054352b1169c883377f48f6c1
[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 ( strcasecmp( 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 ( strcasecmp( 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 ( strcasecmp( 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 *dn )
227 {
228         int rc;
229         char *ndn;
230
231         if ( dn == NULL || be->be_rootdn == NULL ) {
232                 return( 0 );
233         }
234
235         ndn = dn_normalize_case( ch_strdup( dn ) );
236         rc = strcmp( be->be_rootdn, ndn ) ? 0 : 1;
237
238         free(ndn);
239         return(rc);
240 }
241
242 int
243 be_isroot_pw( Backend *be, char *dn, struct berval *cred )
244 {
245         int result;
246
247         if ( ! be_isroot( be, dn ) ) {
248                 return( 0 );
249         }
250
251 #ifdef SLAPD_CRYPT
252         pthread_mutex_lock( &crypt_mutex );
253 #endif
254
255         result = lutil_passwd( cred->bv_val, be->be_rootpw );
256
257 #ifdef SLAPD_CRYPT
258         pthread_mutex_unlock( &crypt_mutex );
259 #endif
260
261         return result == 0;
262 }
263
264 void
265 be_close( void )
266 {
267         int     i;
268
269         for ( i = 0; i < nbackends; i++ ) {
270                 if ( backends[i].be_close != NULL ) {
271                         (*backends[i].be_close)( &backends[i] );
272                 }
273         }
274 }
275
276
277 void
278 be_unbind(
279         Connection   *conn,
280         Operation    *op
281 )
282 {
283         int     i;
284
285         for ( i = 0; i < nbackends; i++ ) {
286                 if ( backends[i].be_unbind != NULL ) {
287                         (*backends[i].be_unbind)( &backends[i], conn, op );
288                 }
289         }
290 }
291
292 #ifdef SLAPD_ACLGROUPS
293 int 
294 be_group(
295         Backend *be,
296         Entry   *e,
297         char    *bdn,
298         char    *edn,
299         char    *objectclassValue,
300         char    *groupattrName
301 )
302 {
303         if (be->be_group)
304                 return(be->be_group(be, e, bdn, edn,
305                                         objectclassValue, groupattrName));
306         else
307                 return(1);
308 }
309 #endif