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 static BackendInfo binfo[] = {
33 {"ldbm", ldbm_back_initialize},
36 {"bdb2", bdb2_back_initialize},
39 {"passwd", passwd_back_initialize},
42 {"perl", perl_back_initialize},
45 {"shell", shell_back_initialize},
51 BackendInfo *backendInfo = NULL;
54 BackendDB *backendDB = NULL;
56 int backend_init(void)
60 if((nBackendInfo != 0) || (backendInfo != NULL)) {
61 /* already initialized */
62 Debug( LDAP_DEBUG_ANY,
63 "backend_init: already initialized.\n", 0, 0, 0 );
68 binfo[nBackendInfo].bi_type != NULL;
71 rc = binfo[nBackendInfo].bi_init(
72 &binfo[nBackendInfo] );
75 Debug( LDAP_DEBUG_ANY,
76 "backend_init: initialized for type \"%s\"\n",
77 binfo[nBackendInfo].bi_type, 0, 0 );
79 /* destroy those we've already inited */
84 if ( binfo[nBackendInfo].bi_destroy ) {
85 binfo[nBackendInfo].bi_destroy(
86 &binfo[nBackendInfo] );
93 if ( nBackendInfo > 0) {
98 Debug( LDAP_DEBUG_ANY,
99 "backend_init: failed\n",
105 int backend_startup(int n)
110 if( ! ( nBackendDB > 0 ) ) {
112 Debug( LDAP_DEBUG_ANY,
113 "backend_startup: %d databases to startup.\n",
119 /* startup a specific backend database */
120 Debug( LDAP_DEBUG_TRACE,
121 "backend_startup: starting database %d\n",
124 /* make sure, n does not exceed the number of backend databases */
125 if ( n >= nbackends ) {
127 Debug( LDAP_DEBUG_ANY,
128 "backend_startup: database number %d exceeding maximum (%d)\n",
133 if ( backendDB[n].bd_info->bi_open ) {
134 rc = backendDB[n].bd_info->bi_open(
135 backendDB[n].bd_info );
139 Debug( LDAP_DEBUG_ANY,
140 "backend_startup: bi_open failed!\n",
145 if ( backendDB[n].bd_info->bi_db_open ) {
146 rc = backendDB[n].bd_info->bi_db_open(
151 Debug( LDAP_DEBUG_ANY,
152 "backend_startup: bi_db_open failed!\n",
160 /* open each backend type */
161 for( i = 0; i < nBackendInfo; i++ ) {
162 if( backendInfo[i].bi_nDB == 0) {
163 /* no database of this type, don't open */
167 if( backendInfo[i].bi_open ) {
168 rc = backendInfo[i].bi_open(
173 Debug( LDAP_DEBUG_ANY,
174 "backend_startup: bi_open %d failed!\n",
180 /* open each backend database */
181 for( i = 0; i < nBackendDB; i++ ) {
184 /* open the backend type, if not done already */
185 bi = backendDB[i].bd_info;
187 if( bi->bi_nDB == 0) {
188 /* no database of this type, don't open */
189 Debug(LDAP_DEBUG_ANY,
190 "backend_startup: there should be no database (%d) of %s type.!\n",
196 if ( backendDB[i].bd_info->bi_db_open ) {
197 rc = backendDB[i].bd_info->bi_db_open(
202 Debug( LDAP_DEBUG_ANY,
203 "backend_startup: bi_db_open %d failed!\n",
212 int backend_shutdown(int n)
218 /* shutdown a specific backend database */
220 /* make sure, n does not exceed the number of backend databases */
221 if ( n >= nbackends ) {
223 Debug( LDAP_DEBUG_ANY,
224 "backend_startup: database number %d exceeding maximum (%d)\n",
229 if ( backendDB[n].bd_info->bi_nDB == 0 ) {
230 /* no database of this type, we never opened it */
234 if ( backendDB[n].bd_info->bi_db_close ) {
235 backendDB[n].bd_info->bi_db_close(
239 if( backendDB[n].bd_info->bi_close ) {
240 backendDB[n].bd_info->bi_close(
241 backendDB[n].bd_info );
247 /* close each backend database */
248 for( i = 0; i < nBackendDB; i++ ) {
251 if ( backendDB[i].bd_info->bi_db_close ) {
252 backendDB[i].bd_info->bi_db_close(
257 Debug( LDAP_DEBUG_ANY,
258 "backend_close: bi_close %s failed!\n",
263 /* close each backend type */
264 for( i = 0; i < nBackendInfo; i++ ) {
265 if( backendInfo[i].bi_nDB == 0 ) {
266 /* no database of this type */
270 if( backendInfo[i].bi_close ) {
271 backendInfo[i].bi_close(
279 int backend_destroy(void)
283 /* destroy each backend database */
284 for( i = 0; i < nBackendDB; i++ ) {
285 if ( backendDB[i].bd_info->bi_db_destroy ) {
286 backendDB[i].bd_info->bi_db_destroy(
291 /* destroy each backend type */
292 for( i = 0; i < nBackendInfo; i++ ) {
293 if( backendInfo[i].bi_destroy ) {
294 backendInfo[i].bi_destroy(
302 BackendInfo* backend_info(char *type)
306 /* search for the backend type */
307 for( i = 0; i < nBackendInfo; i++ ) {
308 if( strcasecmp(backendInfo[i].bi_type, type) == 0 ) {
309 return &backendInfo[i];
323 BackendInfo *bi = backend_info(type);
327 fprintf( stderr, "Unrecognized database type (%s)\n", type );
331 backendDB = (BackendDB *) ch_realloc(
333 (nBackendDB + 1) * sizeof(Backend) );
335 memset( &backendDB[nbackends], '\0', sizeof(Backend) );
337 be = &backends[nbackends++];
340 be->be_sizelimit = defsize;
341 be->be_timelimit = deftime;
344 rc = bi->bi_db_init( be );
348 fprintf( stderr, "database init failed (%s)\n", type );
362 for ( i = 0; i < nbackends; i++ ) {
363 if ( backends[i].bd_info->bi_db_close != NULL ) {
364 (*backends[i].bd_info->bi_db_close)( &backends[i] );
370 select_backend( char * dn )
372 int i, j, len, dnlen;
374 dnlen = strlen( dn );
375 for ( i = 0; i < nbackends; i++ ) {
376 for ( j = 0; backends[i].be_suffix != NULL &&
377 backends[i].be_suffix[j] != NULL; j++ )
379 len = strlen( backends[i].be_suffix[j] );
385 if ( strcmp( backends[i].be_suffix[j],
386 dn + (dnlen - len) ) == 0 ) {
387 return( &backends[i] );
392 /* if no proper suffix could be found then check for aliases */
393 for ( i = 0; i < nbackends; i++ ) {
395 backends[i].be_suffixAlias != NULL &&
396 backends[i].be_suffixAlias[j] != NULL;
399 len = strlen( backends[i].be_suffixAlias[j] );
405 if ( strcmp( backends[i].be_suffixAlias[j],
406 dn + (dnlen - len) ) == 0 ) {
407 return( &backends[i] );
412 #ifdef LDAP_ALLOW_NULL_SEARCH_BASE
413 /* Add greg@greg.rim.or.jp
414 * It's quick hack for cheap client
415 * Some browser offer a NULL base at ldap_search
417 * Should only be used as a last resort. -Kdz
420 Debug( LDAP_DEBUG_TRACE,
421 "select_backend: use default backend\n", 0, 0, 0 );
422 return( &backends[0] );
424 #endif /* LDAP_ALLOW_NULL_SEARCH_BASE */
437 for ( i = 0; be->be_suffix != NULL && be->be_suffix[i] != NULL; i++ ) {
438 if ( strcmp( be->be_suffix[i], suffix ) == 0 ) {
447 be_isroot( Backend *be, char *ndn )
451 if ( ndn == NULL || be->be_root_ndn == NULL ) {
455 rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
461 be_root_dn( Backend *be )
465 if ( be->be_root_dn == NULL ) {
469 return be->be_root_dn;
473 be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
477 if ( ! be_isroot( be, ndn ) ) {
482 ldap_pvt_thread_mutex_lock( &crypt_mutex );
485 result = lutil_passwd( cred->bv_val, be->be_root_pw );
488 ldap_pvt_thread_mutex_unlock( &crypt_mutex );
502 for ( i = 0; i < nbackends; i++ ) {
503 if ( backends[i].be_unbind != NULL ) {
504 (*backends[i].be_unbind)( &backends[i], conn, op );
511 #ifdef SLAPD_ACLGROUPS
518 char *objectclassValue,
523 return( be->be_group(be, target, gr_ndn, op_ndn,
524 objectclassValue, groupattrName) );