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",
100 int backend_startup(int n)
105 if( ! ( nBackendDB > 0 ) ) {
107 Debug( LDAP_DEBUG_ANY,
108 "backend_startup: %d databases to startup.\n",
114 /* startup a specific backend database */
115 Debug( LDAP_DEBUG_TRACE,
116 "backend_startup: starting database %d\n",
119 if ( backendDB[n].bd_info->bi_open ) {
120 rc = backendDB[n].bd_info->bi_open(
121 backendDB[n].bd_info );
125 Debug( LDAP_DEBUG_TRACE,
126 "backend_startup: bi_open failed!\n",
131 if ( backendDB[n].bd_info->bi_db_open ) {
132 rc = backendDB[n].bd_info->bi_db_open(
137 Debug( LDAP_DEBUG_TRACE,
138 "backend_startup: bi_db_open failed!\n",
146 /* open each backend type */
147 for( i = 0; i < nBackendInfo; i++ ) {
148 if( backendInfo[i].bi_open ) {
149 rc = backendInfo[i].bi_open(
154 Debug( LDAP_DEBUG_TRACE,
155 "backend_startup: bi_open %d failed!\n",
161 /* open each backend database */
162 for( i = 0; i < nBackendDB; i++ ) {
163 if ( backendDB[i].bd_info->bi_db_open ) {
164 rc = backendDB[i].bd_info->bi_db_open(
169 Debug( LDAP_DEBUG_TRACE,
170 "backend_startup: bi_db_open %d failed!\n",
179 int backend_shutdown(int n)
184 /* shutdown a specific backend database */
186 if ( backendDB[n].bd_info->bi_db_close ) {
187 backendDB[n].bd_info->bi_db_close(
191 if( backendDB[n].bd_info->bi_close ) {
192 backendDB[n].bd_info->bi_close(
193 backendDB[n].bd_info );
199 /* close each backend database */
200 for( i = 0; i < nBackendDB; i++ ) {
201 if ( backendDB[i].bd_info->bi_db_close ) {
202 backendDB[i].bd_info->bi_db_close(
207 /* close each backend type */
208 for( i = 0; i < nBackendInfo; i++ ) {
209 if( backendInfo[i].bi_close ) {
210 backendInfo[i].bi_close(
218 int backend_destroy(void)
222 /* destroy each backend database */
223 for( i = 0; i < nBackendDB; i++ ) {
224 if ( backendDB[i].bd_info->bi_db_destroy ) {
225 backendDB[i].bd_info->bi_db_destroy(
230 /* destroy each backend type */
231 for( i = 0; i < nBackendInfo; i++ ) {
232 if( backendInfo[i].bi_close ) {
233 backendInfo[i].bi_close(
241 BackendInfo* backend_info(char *type)
245 /* search for the backend type */
246 for( i = 0; i < nBackendInfo; i++ ) {
247 if( strcasecmp(backendInfo[i].bi_type, type) == 0 ) {
248 return &backendInfo[i];
262 BackendInfo *bi = backend_info(type);
266 fprintf( stderr, "Unrecognized database type (%s)\n", type );
270 backendDB = (BackendDB *) ch_realloc(
272 (nBackendDB + 1) * sizeof(Backend) );
274 memset( &backendDB[nbackends], '\0', sizeof(Backend) );
276 be = &backends[nbackends++];
279 be->be_sizelimit = defsize;
280 be->be_timelimit = deftime;
283 rc = bi->bi_db_init( be );
287 fprintf( stderr, "database init failed (%s)\n", type );
300 for ( i = 0; i < nbackends; i++ ) {
301 if ( backends[i].bd_info->bi_db_close != NULL ) {
302 (*backends[i].bd_info->bi_db_close)( &backends[i] );
308 select_backend( char * dn )
310 int i, j, len, dnlen;
312 dnlen = strlen( dn );
313 for ( i = 0; i < nbackends; i++ ) {
314 for ( j = 0; backends[i].be_suffix != NULL &&
315 backends[i].be_suffix[j] != NULL; j++ )
317 len = strlen( backends[i].be_suffix[j] );
323 if ( strcmp( backends[i].be_suffix[j],
324 dn + (dnlen - len) ) == 0 ) {
325 return( &backends[i] );
330 /* if no proper suffix could be found then check for aliases */
331 for ( i = 0; i < nbackends; i++ ) {
333 backends[i].be_suffixAlias != NULL &&
334 backends[i].be_suffixAlias[j] != NULL;
337 len = strlen( backends[i].be_suffixAlias[j] );
343 if ( strcmp( backends[i].be_suffixAlias[j],
344 dn + (dnlen - len) ) == 0 ) {
345 return( &backends[i] );
350 #ifdef LDAP_ALLOW_NULL_SEARCH_BASE
351 /* Add greg@greg.rim.or.jp
352 * It's quick hack for cheap client
353 * Some browser offer a NULL base at ldap_search
355 * Should only be used as a last resort. -Kdz
358 Debug( LDAP_DEBUG_TRACE,
359 "select_backend: use default backend\n", 0, 0, 0 );
360 return( &backends[0] );
362 #endif /* LDAP_ALLOW_NULL_SEARCH_BASE */
375 for ( i = 0; be->be_suffix != NULL && be->be_suffix[i] != NULL; i++ ) {
376 if ( strcmp( be->be_suffix[i], suffix ) == 0 ) {
385 be_isroot( Backend *be, char *ndn )
389 if ( ndn == NULL || be->be_root_ndn == NULL ) {
393 rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
399 be_root_dn( Backend *be )
403 if ( be->be_root_dn == NULL ) {
407 return be->be_root_dn;
411 be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
415 if ( ! be_isroot( be, ndn ) ) {
420 ldap_pvt_thread_mutex_lock( &crypt_mutex );
423 result = lutil_passwd( cred->bv_val, be->be_root_pw );
426 ldap_pvt_thread_mutex_unlock( &crypt_mutex );
440 for ( i = 0; i < nbackends; i++ ) {
441 if ( backends[i].be_unbind != NULL ) {
442 (*backends[i].be_unbind)( &backends[i], conn, op );
449 #ifdef SLAPD_ACLGROUPS
456 char *objectclassValue,
461 return( be->be_group(be, target, gr_ndn, op_ndn,
462 objectclassValue, groupattrName) );