1 /* backend.c - routines for dealing with back-end databases */
17 #include "back-ldap/external.h"
20 #include "back-ldbm/external.h"
23 #include "back-bdb2/external.h"
26 #include "back-passwd/external.h"
29 #include "back-perl/external.h"
32 #include "back-shell/external.h"
35 #include "back-tcl/external.h"
38 static BackendInfo binfo[] = {
40 {"ldap", ldap_back_initialize},
43 {"ldbm", ldbm_back_initialize},
46 {"bdb2", bdb2_back_initialize},
49 {"passwd", passwd_back_initialize},
52 {"perl", perl_back_initialize},
55 {"shell", shell_back_initialize},
58 {"tcl", tcl_back_initialize},
64 BackendInfo *backendInfo = NULL;
67 BackendDB *backendDB = NULL;
69 int backend_init(void)
73 if((nBackendInfo != 0) || (backendInfo != NULL)) {
74 /* already initialized */
75 Debug( LDAP_DEBUG_ANY,
76 "backend_init: already initialized.\n", 0, 0, 0 );
81 binfo[nBackendInfo].bi_type != NULL;
84 rc = binfo[nBackendInfo].bi_init(
85 &binfo[nBackendInfo] );
88 Debug( LDAP_DEBUG_ANY,
89 "backend_init: initialized for type \"%s\"\n",
90 binfo[nBackendInfo].bi_type, 0, 0 );
92 /* destroy those we've already inited */
97 if ( binfo[nBackendInfo].bi_destroy ) {
98 binfo[nBackendInfo].bi_destroy(
99 &binfo[nBackendInfo] );
106 if ( nBackendInfo > 0) {
111 Debug( LDAP_DEBUG_ANY,
112 "backend_init: failed\n",
118 int backend_startup(int n)
123 if( ! ( nBackendDB > 0 ) ) {
125 Debug( LDAP_DEBUG_ANY,
126 "backend_startup: %d databases to startup.\n",
132 /* startup a specific backend database */
133 Debug( LDAP_DEBUG_TRACE,
134 "backend_startup: starting database %d\n",
137 /* make sure, n does not exceed the number of backend databases */
138 if ( n >= nbackends ) {
140 Debug( LDAP_DEBUG_ANY,
141 "backend_startup: database number %d exceeding maximum (%d)\n",
146 if ( backendDB[n].bd_info->bi_open ) {
147 rc = backendDB[n].bd_info->bi_open(
148 backendDB[n].bd_info );
152 Debug( LDAP_DEBUG_ANY,
153 "backend_startup: bi_open failed!\n",
158 if ( backendDB[n].bd_info->bi_db_open ) {
159 rc = backendDB[n].bd_info->bi_db_open(
164 Debug( LDAP_DEBUG_ANY,
165 "backend_startup: bi_db_open failed!\n",
173 /* open each backend type */
174 for( i = 0; i < nBackendInfo; i++ ) {
175 if( backendInfo[i].bi_nDB == 0) {
176 /* no database of this type, don't open */
180 if( backendInfo[i].bi_open ) {
181 rc = backendInfo[i].bi_open(
186 Debug( LDAP_DEBUG_ANY,
187 "backend_startup: bi_open %d failed!\n",
193 /* open each backend database */
194 for( i = 0; i < nBackendDB; i++ ) {
195 if ( backendDB[i].bd_info->bi_db_open ) {
196 rc = backendDB[i].bd_info->bi_db_open(
201 Debug( LDAP_DEBUG_ANY,
202 "backend_startup: bi_db_open %d failed!\n",
211 int backend_shutdown(int n)
217 /* shutdown a specific backend database */
219 /* make sure, n does not exceed the number of backend databases */
220 if ( n >= nbackends ) {
222 Debug( LDAP_DEBUG_ANY,
223 "backend_startup: database number %d exceeding maximum (%d)\n",
228 if ( backendDB[n].bd_info->bi_nDB == 0 ) {
229 /* no database of this type, we never opened it */
233 if ( backendDB[n].bd_info->bi_db_close ) {
234 backendDB[n].bd_info->bi_db_close(
238 if( backendDB[n].bd_info->bi_close ) {
239 backendDB[n].bd_info->bi_close(
240 backendDB[n].bd_info );
246 /* close each backend database */
247 for( i = 0; i < nBackendDB; i++ ) {
250 if ( backendDB[i].bd_info->bi_db_close ) {
251 backendDB[i].bd_info->bi_db_close(
256 Debug( LDAP_DEBUG_ANY,
257 "backend_close: bi_close %s failed!\n",
262 /* close each backend type */
263 for( i = 0; i < nBackendInfo; i++ ) {
264 if( backendInfo[i].bi_nDB == 0 ) {
265 /* no database of this type */
269 if( backendInfo[i].bi_close ) {
270 backendInfo[i].bi_close(
278 int backend_destroy(void)
282 /* destroy each backend database */
283 for( i = 0; i < nBackendDB; i++ ) {
284 if ( backendDB[i].bd_info->bi_db_destroy ) {
285 backendDB[i].bd_info->bi_db_destroy(
290 /* destroy each backend type */
291 for( i = 0; i < nBackendInfo; i++ ) {
292 if( backendInfo[i].bi_destroy ) {
293 backendInfo[i].bi_destroy(
301 BackendInfo* backend_info(char *type)
305 /* search for the backend type */
306 for( i = 0; i < nBackendInfo; i++ ) {
307 if( strcasecmp(backendInfo[i].bi_type, type) == 0 ) {
308 return &backendInfo[i];
322 BackendInfo *bi = backend_info(type);
326 fprintf( stderr, "Unrecognized database type (%s)\n", type );
330 backendDB = (BackendDB *) ch_realloc(
332 (nBackendDB + 1) * sizeof(Backend) );
334 memset( &backendDB[nbackends], '\0', sizeof(Backend) );
336 be = &backends[nbackends++];
339 be->be_sizelimit = defsize;
340 be->be_timelimit = deftime;
343 rc = bi->bi_db_init( be );
347 fprintf( stderr, "database init failed (%s)\n", type );
361 for ( i = 0; i < nbackends; i++ ) {
362 if ( backends[i].bd_info->bi_db_close ) {
363 (*backends[i].bd_info->bi_db_close)( &backends[i] );
369 select_backend( char * dn )
371 int i, j, len, dnlen;
373 dnlen = strlen( dn );
374 for ( i = 0; i < nbackends; i++ ) {
375 for ( j = 0; backends[i].be_nsuffix != NULL &&
376 backends[i].be_nsuffix[j] != NULL; j++ )
378 len = strlen( backends[i].be_nsuffix[j] );
384 if ( strcmp( backends[i].be_nsuffix[j],
385 dn + (dnlen - len) ) == 0 ) {
386 return( &backends[i] );
391 /* if no proper suffix could be found then check for aliases */
392 for ( i = 0; i < nbackends; i++ ) {
394 backends[i].be_suffixAlias != NULL &&
395 backends[i].be_suffixAlias[j] != NULL;
398 len = strlen( backends[i].be_suffixAlias[j] );
404 if ( strcmp( backends[i].be_suffixAlias[j],
405 dn + (dnlen - len) ) == 0 ) {
406 return( &backends[i] );
411 #ifdef LDAP_ALLOW_NULL_SEARCH_BASE
412 /* Add greg@greg.rim.or.jp
413 * It's quick hack for cheap client
414 * Some browser offer a NULL base at ldap_search
416 * Should only be used as a last resort. -Kdz
419 Debug( LDAP_DEBUG_TRACE,
420 "select_backend: use default backend\n", 0, 0, 0 );
421 return( &backends[0] );
423 #endif /* LDAP_ALLOW_NULL_SEARCH_BASE */
436 for ( i = 0; be->be_nsuffix != NULL && be->be_nsuffix[i] != NULL; i++ ) {
437 if ( strcmp( be->be_nsuffix[i], suffix ) == 0 ) {
446 be_isroot( Backend *be, char *ndn )
450 if ( ndn == NULL || be->be_root_ndn == NULL ) {
454 rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
460 be_root_dn( Backend *be )
462 if ( be->be_root_dn == NULL ) {
466 return be->be_root_dn;
470 be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
474 if ( ! be_isroot( be, ndn ) ) {
479 ldap_pvt_thread_mutex_lock( &crypt_mutex );
482 result = lutil_passwd( cred->bv_val, be->be_root_pw );
485 ldap_pvt_thread_mutex_unlock( &crypt_mutex );
492 be_entry_release_rw( Backend *be, Entry *e, int rw )
494 if ( be->be_release ) {
495 /* free and release entry from backend */
496 return be->be_release( be, e, rw );
512 for ( i = 0; i < nbackends; i++ ) {
513 if ( backends[i].be_unbind ) {
514 (*backends[i].be_unbind)( &backends[i], conn, op );
521 #ifdef SLAPD_ACLGROUPS
528 char *objectclassValue,
533 return( be->be_group(be, target, gr_ndn, op_ndn,
534 objectclassValue, groupattrName) );