1 /* backend.c - routines for dealing with back-end databases */
17 #include "back-ldbm/external.h"
20 #include "back-bdb2/external.h"
23 #include "back-passwd/external.h"
26 #include "back-perl/external.h"
29 #include "back-shell/external.h"
32 #include "back-tcl/external.h"
35 static BackendInfo binfo[] = {
37 {"ldbm", ldbm_back_initialize},
40 {"bdb2", bdb2_back_initialize},
43 {"passwd", passwd_back_initialize},
46 {"perl", perl_back_initialize},
49 {"shell", shell_back_initialize},
52 {"tcl", tcl_back_initialize},
58 BackendInfo *backendInfo = NULL;
61 BackendDB *backendDB = NULL;
63 int backend_init(void)
67 if((nBackendInfo != 0) || (backendInfo != NULL)) {
68 /* already initialized */
69 Debug( LDAP_DEBUG_ANY,
70 "backend_init: already initialized.\n", 0, 0, 0 );
75 binfo[nBackendInfo].bi_type != NULL;
78 rc = binfo[nBackendInfo].bi_init(
79 &binfo[nBackendInfo] );
82 Debug( LDAP_DEBUG_ANY,
83 "backend_init: initialized for type \"%s\"\n",
84 binfo[nBackendInfo].bi_type, 0, 0 );
86 /* destroy those we've already inited */
91 if ( binfo[nBackendInfo].bi_destroy ) {
92 binfo[nBackendInfo].bi_destroy(
93 &binfo[nBackendInfo] );
100 if ( nBackendInfo > 0) {
105 Debug( LDAP_DEBUG_ANY,
106 "backend_init: failed\n",
112 int backend_startup(int n)
117 if( ! ( nBackendDB > 0 ) ) {
119 Debug( LDAP_DEBUG_ANY,
120 "backend_startup: %d databases to startup.\n",
126 /* startup a specific backend database */
127 Debug( LDAP_DEBUG_TRACE,
128 "backend_startup: starting database %d\n",
131 /* make sure, n does not exceed the number of backend databases */
132 if ( n >= nbackends ) {
134 Debug( LDAP_DEBUG_ANY,
135 "backend_startup: database number %d exceeding maximum (%d)\n",
140 if ( backendDB[n].bd_info->bi_open ) {
141 rc = backendDB[n].bd_info->bi_open(
142 backendDB[n].bd_info );
146 Debug( LDAP_DEBUG_ANY,
147 "backend_startup: bi_open failed!\n",
152 if ( backendDB[n].bd_info->bi_db_open ) {
153 rc = backendDB[n].bd_info->bi_db_open(
158 Debug( LDAP_DEBUG_ANY,
159 "backend_startup: bi_db_open failed!\n",
167 /* open each backend type */
168 for( i = 0; i < nBackendInfo; i++ ) {
169 if( backendInfo[i].bi_nDB == 0) {
170 /* no database of this type, don't open */
174 if( backendInfo[i].bi_open ) {
175 rc = backendInfo[i].bi_open(
180 Debug( LDAP_DEBUG_ANY,
181 "backend_startup: bi_open %d failed!\n",
187 /* open each backend database */
188 for( i = 0; i < nBackendDB; i++ ) {
189 if ( backendDB[i].bd_info->bi_db_open ) {
190 rc = backendDB[i].bd_info->bi_db_open(
195 Debug( LDAP_DEBUG_ANY,
196 "backend_startup: bi_db_open %d failed!\n",
205 int backend_shutdown(int n)
211 /* shutdown a specific backend database */
213 /* make sure, n does not exceed the number of backend databases */
214 if ( n >= nbackends ) {
216 Debug( LDAP_DEBUG_ANY,
217 "backend_startup: database number %d exceeding maximum (%d)\n",
222 if ( backendDB[n].bd_info->bi_nDB == 0 ) {
223 /* no database of this type, we never opened it */
227 if ( backendDB[n].bd_info->bi_db_close ) {
228 backendDB[n].bd_info->bi_db_close(
232 if( backendDB[n].bd_info->bi_close ) {
233 backendDB[n].bd_info->bi_close(
234 backendDB[n].bd_info );
240 /* close each backend database */
241 for( i = 0; i < nBackendDB; i++ ) {
244 if ( backendDB[i].bd_info->bi_db_close ) {
245 backendDB[i].bd_info->bi_db_close(
250 Debug( LDAP_DEBUG_ANY,
251 "backend_close: bi_close %s failed!\n",
256 /* close each backend type */
257 for( i = 0; i < nBackendInfo; i++ ) {
258 if( backendInfo[i].bi_nDB == 0 ) {
259 /* no database of this type */
263 if( backendInfo[i].bi_close ) {
264 backendInfo[i].bi_close(
272 int backend_destroy(void)
276 /* destroy each backend database */
277 for( i = 0; i < nBackendDB; i++ ) {
278 if ( backendDB[i].bd_info->bi_db_destroy ) {
279 backendDB[i].bd_info->bi_db_destroy(
284 /* destroy each backend type */
285 for( i = 0; i < nBackendInfo; i++ ) {
286 if( backendInfo[i].bi_destroy ) {
287 backendInfo[i].bi_destroy(
295 BackendInfo* backend_info(char *type)
299 /* search for the backend type */
300 for( i = 0; i < nBackendInfo; i++ ) {
301 if( strcasecmp(backendInfo[i].bi_type, type) == 0 ) {
302 return &backendInfo[i];
316 BackendInfo *bi = backend_info(type);
320 fprintf( stderr, "Unrecognized database type (%s)\n", type );
324 backendDB = (BackendDB *) ch_realloc(
326 (nBackendDB + 1) * sizeof(Backend) );
328 memset( &backendDB[nbackends], '\0', sizeof(Backend) );
330 be = &backends[nbackends++];
333 be->be_sizelimit = defsize;
334 be->be_timelimit = deftime;
337 rc = bi->bi_db_init( be );
341 fprintf( stderr, "database init failed (%s)\n", type );
355 for ( i = 0; i < nbackends; i++ ) {
356 if ( backends[i].bd_info->bi_db_close ) {
357 (*backends[i].bd_info->bi_db_close)( &backends[i] );
363 select_backend( char * dn )
365 int i, j, len, dnlen;
367 dnlen = strlen( dn );
368 for ( i = 0; i < nbackends; i++ ) {
369 for ( j = 0; backends[i].be_suffix != NULL &&
370 backends[i].be_suffix[j] != NULL; j++ )
372 len = strlen( backends[i].be_suffix[j] );
378 if ( strcmp( backends[i].be_suffix[j],
379 dn + (dnlen - len) ) == 0 ) {
380 return( &backends[i] );
385 /* if no proper suffix could be found then check for aliases */
386 for ( i = 0; i < nbackends; i++ ) {
388 backends[i].be_suffixAlias != NULL &&
389 backends[i].be_suffixAlias[j] != NULL;
392 len = strlen( backends[i].be_suffixAlias[j] );
398 if ( strcmp( backends[i].be_suffixAlias[j],
399 dn + (dnlen - len) ) == 0 ) {
400 return( &backends[i] );
405 #ifdef LDAP_ALLOW_NULL_SEARCH_BASE
406 /* Add greg@greg.rim.or.jp
407 * It's quick hack for cheap client
408 * Some browser offer a NULL base at ldap_search
410 * Should only be used as a last resort. -Kdz
413 Debug( LDAP_DEBUG_TRACE,
414 "select_backend: use default backend\n", 0, 0, 0 );
415 return( &backends[0] );
417 #endif /* LDAP_ALLOW_NULL_SEARCH_BASE */
430 for ( i = 0; be->be_suffix != NULL && be->be_suffix[i] != NULL; i++ ) {
431 if ( strcmp( be->be_suffix[i], suffix ) == 0 ) {
440 be_isroot( Backend *be, char *ndn )
444 if ( ndn == NULL || be->be_root_ndn == NULL ) {
448 rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
454 be_root_dn( Backend *be )
456 if ( be->be_root_dn == NULL ) {
460 return be->be_root_dn;
464 be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
468 if ( ! be_isroot( be, ndn ) ) {
473 ldap_pvt_thread_mutex_lock( &crypt_mutex );
476 result = lutil_passwd( cred->bv_val, be->be_root_pw );
479 ldap_pvt_thread_mutex_unlock( &crypt_mutex );
493 for ( i = 0; i < nbackends; i++ ) {
494 if ( backends[i].be_unbind ) {
495 (*backends[i].be_unbind)( &backends[i], conn, op );
502 #ifdef SLAPD_ACLGROUPS
509 char *objectclassValue,
514 return( be->be_group(be, target, gr_ndn, op_ndn,
515 objectclassValue, groupattrName) );