1 /* backend.c - routines for dealing with back-end databases */
16 #include "back-ldbm/external.h"
19 #include "back-bdb2/external.h"
22 #include "back-passwd/external.h"
25 #include "back-perl/external.h"
28 #include "back-shell/external.h"
31 #include "back-tcl/external.h"
34 static BackendInfo binfo[] = {
36 {"ldbm", ldbm_back_initialize},
39 {"bdb2", bdb2_back_initialize},
42 {"passwd", passwd_back_initialize},
45 {"perl", perl_back_initialize},
48 {"shell", shell_back_initialize},
51 {"tcl", tcl_back_initialize},
57 BackendInfo *backendInfo = NULL;
60 BackendDB *backendDB = NULL;
62 int backend_init(void)
66 if((nBackendInfo != 0) || (backendInfo != NULL)) {
67 /* already initialized */
68 Debug( LDAP_DEBUG_ANY,
69 "backend_init: already initialized.\n", 0, 0, 0 );
74 binfo[nBackendInfo].bi_type != NULL;
77 rc = binfo[nBackendInfo].bi_init(
78 &binfo[nBackendInfo] );
81 Debug( LDAP_DEBUG_ANY,
82 "backend_init: initialized for type \"%s\"\n",
83 binfo[nBackendInfo].bi_type, 0, 0 );
85 /* destroy those we've already inited */
90 if ( binfo[nBackendInfo].bi_destroy ) {
91 binfo[nBackendInfo].bi_destroy(
92 &binfo[nBackendInfo] );
99 if ( nBackendInfo > 0) {
104 Debug( LDAP_DEBUG_ANY,
105 "backend_init: failed\n",
111 int backend_startup(int n)
116 if( ! ( nBackendDB > 0 ) ) {
118 Debug( LDAP_DEBUG_ANY,
119 "backend_startup: %d databases to startup.\n",
125 /* startup a specific backend database */
126 Debug( LDAP_DEBUG_TRACE,
127 "backend_startup: starting database %d\n",
130 /* make sure, n does not exceed the number of backend databases */
131 if ( n >= nbackends ) {
133 Debug( LDAP_DEBUG_ANY,
134 "backend_startup: database number %d exceeding maximum (%d)\n",
139 if ( backendDB[n].bd_info->bi_open ) {
140 rc = backendDB[n].bd_info->bi_open(
141 backendDB[n].bd_info );
145 Debug( LDAP_DEBUG_ANY,
146 "backend_startup: bi_open failed!\n",
151 if ( backendDB[n].bd_info->bi_db_open ) {
152 rc = backendDB[n].bd_info->bi_db_open(
157 Debug( LDAP_DEBUG_ANY,
158 "backend_startup: bi_db_open failed!\n",
166 /* open each backend type */
167 for( i = 0; i < nBackendInfo; i++ ) {
168 if( backendInfo[i].bi_nDB == 0) {
169 /* no database of this type, don't open */
173 if( backendInfo[i].bi_open ) {
174 rc = backendInfo[i].bi_open(
179 Debug( LDAP_DEBUG_ANY,
180 "backend_startup: bi_open %d failed!\n",
186 /* open each backend database */
187 for( i = 0; i < nBackendDB; i++ ) {
188 if ( backendDB[i].bd_info->bi_db_open ) {
189 rc = backendDB[i].bd_info->bi_db_open(
194 Debug( LDAP_DEBUG_ANY,
195 "backend_startup: bi_db_open %d failed!\n",
204 int backend_shutdown(int n)
210 /* shutdown a specific backend database */
212 /* make sure, n does not exceed the number of backend databases */
213 if ( n >= nbackends ) {
215 Debug( LDAP_DEBUG_ANY,
216 "backend_startup: database number %d exceeding maximum (%d)\n",
221 if ( backendDB[n].bd_info->bi_nDB == 0 ) {
222 /* no database of this type, we never opened it */
226 if ( backendDB[n].bd_info->bi_db_close ) {
227 backendDB[n].bd_info->bi_db_close(
231 if( backendDB[n].bd_info->bi_close ) {
232 backendDB[n].bd_info->bi_close(
233 backendDB[n].bd_info );
239 /* close each backend database */
240 for( i = 0; i < nBackendDB; i++ ) {
243 if ( backendDB[i].bd_info->bi_db_close ) {
244 backendDB[i].bd_info->bi_db_close(
249 Debug( LDAP_DEBUG_ANY,
250 "backend_close: bi_close %s failed!\n",
255 /* close each backend type */
256 for( i = 0; i < nBackendInfo; i++ ) {
257 if( backendInfo[i].bi_nDB == 0 ) {
258 /* no database of this type */
262 if( backendInfo[i].bi_close ) {
263 backendInfo[i].bi_close(
271 int backend_destroy(void)
275 /* destroy each backend database */
276 for( i = 0; i < nBackendDB; i++ ) {
277 if ( backendDB[i].bd_info->bi_db_destroy ) {
278 backendDB[i].bd_info->bi_db_destroy(
283 /* destroy each backend type */
284 for( i = 0; i < nBackendInfo; i++ ) {
285 if( backendInfo[i].bi_destroy ) {
286 backendInfo[i].bi_destroy(
294 BackendInfo* backend_info(char *type)
298 /* search for the backend type */
299 for( i = 0; i < nBackendInfo; i++ ) {
300 if( strcasecmp(backendInfo[i].bi_type, type) == 0 ) {
301 return &backendInfo[i];
315 BackendInfo *bi = backend_info(type);
319 fprintf( stderr, "Unrecognized database type (%s)\n", type );
323 backendDB = (BackendDB *) ch_realloc(
325 (nBackendDB + 1) * sizeof(Backend) );
327 memset( &backendDB[nbackends], '\0', sizeof(Backend) );
329 be = &backends[nbackends++];
332 be->be_sizelimit = defsize;
333 be->be_timelimit = deftime;
336 rc = bi->bi_db_init( be );
340 fprintf( stderr, "database init failed (%s)\n", type );
354 for ( i = 0; i < nbackends; i++ ) {
355 if ( backends[i].bd_info->bi_db_close != NULL ) {
356 (*backends[i].bd_info->bi_db_close)( &backends[i] );
362 select_backend( char * dn )
364 int i, j, len, dnlen;
366 dnlen = strlen( dn );
367 for ( i = 0; i < nbackends; i++ ) {
368 for ( j = 0; backends[i].be_suffix != NULL &&
369 backends[i].be_suffix[j] != NULL; j++ )
371 len = strlen( backends[i].be_suffix[j] );
377 if ( strcmp( backends[i].be_suffix[j],
378 dn + (dnlen - len) ) == 0 ) {
379 return( &backends[i] );
384 /* if no proper suffix could be found then check for aliases */
385 for ( i = 0; i < nbackends; i++ ) {
387 backends[i].be_suffixAlias != NULL &&
388 backends[i].be_suffixAlias[j] != NULL;
391 len = strlen( backends[i].be_suffixAlias[j] );
397 if ( strcmp( backends[i].be_suffixAlias[j],
398 dn + (dnlen - len) ) == 0 ) {
399 return( &backends[i] );
404 #ifdef LDAP_ALLOW_NULL_SEARCH_BASE
405 /* Add greg@greg.rim.or.jp
406 * It's quick hack for cheap client
407 * Some browser offer a NULL base at ldap_search
409 * Should only be used as a last resort. -Kdz
412 Debug( LDAP_DEBUG_TRACE,
413 "select_backend: use default backend\n", 0, 0, 0 );
414 return( &backends[0] );
416 #endif /* LDAP_ALLOW_NULL_SEARCH_BASE */
429 for ( i = 0; be->be_suffix != NULL && be->be_suffix[i] != NULL; i++ ) {
430 if ( strcmp( be->be_suffix[i], suffix ) == 0 ) {
439 be_isroot( Backend *be, char *ndn )
443 if ( ndn == NULL || be->be_root_ndn == NULL ) {
447 rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
453 be_root_dn( Backend *be )
457 if ( be->be_root_dn == NULL ) {
461 return be->be_root_dn;
465 be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
469 if ( ! be_isroot( be, ndn ) ) {
474 ldap_pvt_thread_mutex_lock( &crypt_mutex );
477 result = lutil_passwd( cred->bv_val, be->be_root_pw );
480 ldap_pvt_thread_mutex_unlock( &crypt_mutex );
494 for ( i = 0; i < nbackends; i++ ) {
495 if ( backends[i].be_unbind != NULL ) {
496 (*backends[i].be_unbind)( &backends[i], conn, op );
503 #ifdef SLAPD_ACLGROUPS
510 char *objectclassValue,
515 return( be->be_group(be, target, gr_ndn, op_ndn,
516 objectclassValue, groupattrName) );