1 /* backend.c - routines for dealing with back-end databases */
16 #include "back-ldbm/external.h"
19 #include "back-passwd/external.h"
22 #include "back-perl/external.h"
25 #include "back-shell/external.h"
28 static BackendInfo binfo[] = {
30 {"ldbm", ldbm_back_initialize},
33 {"passwd", passwd_back_initialize},
36 {"perl", perl_back_initialize},
39 {"shell", shell_back_initialize},
45 BackendInfo *backendInfo = NULL;
48 BackendDB *backendDB = NULL;
50 int backend_init(void)
54 if((nBackendInfo != 0) || (backendInfo != NULL)) {
55 /* already initialized */
56 Debug( LDAP_DEBUG_ANY,
57 "backend_init: already initialized.\n", 0, 0, 0 );
62 binfo[nBackendInfo].bi_type != NULL;
65 rc = binfo[nBackendInfo].bi_init(
66 &binfo[nBackendInfo] );
69 Debug( LDAP_DEBUG_ANY,
70 "backend_init: initialized for type \"%s\"\n",
71 binfo[nBackendInfo].bi_type, 0, 0 );
73 /* destroy those we've already inited */
78 if ( binfo[nBackendInfo].bi_destroy ) {
79 binfo[nBackendInfo].bi_destroy(
80 &binfo[nBackendInfo] );
87 if ( nBackendInfo > 0) {
92 Debug( LDAP_DEBUG_ANY,
93 "backend_init: failed\n",
99 int backend_startup(int n)
104 if( ! ( nBackendDB > 0 ) ) {
106 Debug( LDAP_DEBUG_ANY,
107 "backend_startup: %d databases to startup.\n",
113 /* startup a specific backend database */
114 Debug( LDAP_DEBUG_TRACE,
115 "backend_startup: starting database %d\n",
118 if ( backendDB[n].bd_info->bi_open ) {
119 rc = backendDB[n].bd_info->bi_open(
120 backendDB[n].bd_info );
124 Debug( LDAP_DEBUG_TRACE,
125 "backend_startup: bi_open failed!\n",
130 if ( backendDB[n].bd_info->bi_db_open ) {
131 rc = backendDB[n].bd_info->bi_db_open(
136 Debug( LDAP_DEBUG_TRACE,
137 "backend_startup: bi_db_open failed!\n",
145 /* open each backend type */
146 for( i = 0; i < nBackendInfo; i++ ) {
147 if( backendInfo[i].bi_open ) {
148 rc = backendInfo[i].bi_open(
153 Debug( LDAP_DEBUG_TRACE,
154 "backend_startup: bi_open %d failed!\n",
160 /* open each backend database */
161 for( i = 0; i < nBackendDB; i++ ) {
162 if ( backendDB[i].bd_info->bi_db_open ) {
163 rc = backendDB[i].bd_info->bi_db_open(
168 Debug( LDAP_DEBUG_TRACE,
169 "backend_startup: bi_db_open %d failed!\n",
178 int backend_shutdown(int n)
183 /* shutdown a specific backend database */
185 if ( backendDB[n].bd_info->bi_db_close ) {
186 backendDB[n].bd_info->bi_db_close(
190 if( backendDB[n].bd_info->bi_close ) {
191 backendDB[n].bd_info->bi_close(
192 backendDB[n].bd_info );
198 /* close each backend database */
199 for( i = 0; i < nBackendDB; i++ ) {
200 if ( backendDB[i].bd_info->bi_db_close ) {
201 backendDB[i].bd_info->bi_db_close(
206 /* close each backend type */
207 for( i = 0; i < nBackendInfo; i++ ) {
208 if( backendInfo[i].bi_close ) {
209 backendInfo[i].bi_close(
217 int backend_destroy(void)
221 /* destroy each backend database */
222 for( i = 0; i < nBackendDB; i++ ) {
223 if ( backendDB[i].bd_info->bi_db_destroy ) {
224 backendDB[i].bd_info->bi_db_destroy(
229 /* destroy each backend type */
230 for( i = 0; i < nBackendInfo; i++ ) {
231 if( backendInfo[i].bi_destroy ) {
232 backendInfo[i].bi_destroy(
240 BackendInfo* backend_info(char *type)
244 /* search for the backend type */
245 for( i = 0; i < nBackendInfo; i++ ) {
246 if( strcasecmp(backendInfo[i].bi_type, type) == 0 ) {
247 return &backendInfo[i];
261 BackendInfo *bi = backend_info(type);
265 fprintf( stderr, "Unrecognized database type (%s)\n", type );
269 backendDB = (BackendDB *) ch_realloc(
271 (nBackendDB + 1) * sizeof(Backend) );
273 memset( &backendDB[nbackends], '\0', sizeof(Backend) );
275 be = &backends[nbackends++];
278 be->be_sizelimit = defsize;
279 be->be_timelimit = deftime;
282 rc = bi->bi_db_init( be );
286 fprintf( stderr, "database init failed (%s)\n", type );
299 for ( i = 0; i < nbackends; i++ ) {
300 if ( backends[i].bd_info->bi_db_close != NULL ) {
301 (*backends[i].bd_info->bi_db_close)( &backends[i] );
307 select_backend( char * dn )
309 int i, j, len, dnlen;
311 dnlen = strlen( dn );
312 for ( i = 0; i < nbackends; i++ ) {
313 for ( j = 0; backends[i].be_suffix != NULL &&
314 backends[i].be_suffix[j] != NULL; j++ )
316 len = strlen( backends[i].be_suffix[j] );
322 if ( strcmp( backends[i].be_suffix[j],
323 dn + (dnlen - len) ) == 0 ) {
324 return( &backends[i] );
329 /* if no proper suffix could be found then check for aliases */
330 for ( i = 0; i < nbackends; i++ ) {
332 backends[i].be_suffixAlias != NULL &&
333 backends[i].be_suffixAlias[j] != NULL;
336 len = strlen( backends[i].be_suffixAlias[j] );
342 if ( strcmp( backends[i].be_suffixAlias[j],
343 dn + (dnlen - len) ) == 0 ) {
344 return( &backends[i] );
349 #ifdef LDAP_ALLOW_NULL_SEARCH_BASE
350 /* Add greg@greg.rim.or.jp
351 * It's quick hack for cheap client
352 * Some browser offer a NULL base at ldap_search
354 * Should only be used as a last resort. -Kdz
357 Debug( LDAP_DEBUG_TRACE,
358 "select_backend: use default backend\n", 0, 0, 0 );
359 return( &backends[0] );
361 #endif /* LDAP_ALLOW_NULL_SEARCH_BASE */
374 for ( i = 0; be->be_suffix != NULL && be->be_suffix[i] != NULL; i++ ) {
375 if ( strcmp( be->be_suffix[i], suffix ) == 0 ) {
384 be_isroot( Backend *be, char *ndn )
388 if ( ndn == NULL || be->be_root_ndn == NULL ) {
392 rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
398 be_root_dn( Backend *be )
402 if ( be->be_root_dn == NULL ) {
406 return be->be_root_dn;
410 be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
414 if ( ! be_isroot( be, ndn ) ) {
419 ldap_pvt_thread_mutex_lock( &crypt_mutex );
422 result = lutil_passwd( cred->bv_val, be->be_root_pw );
425 ldap_pvt_thread_mutex_unlock( &crypt_mutex );
439 for ( i = 0; i < nbackends; i++ ) {
440 if ( backends[i].be_unbind != NULL ) {
441 (*backends[i].be_unbind)( &backends[i], conn, op );
448 #ifdef SLAPD_ACLGROUPS
455 char *objectclassValue,
460 return( be->be_group(be, target, gr_ndn, op_ndn,
461 objectclassValue, groupattrName) );