]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/backend.c
Import Ben Collins <bcollins@debian.org> Back-TCL for SLAPD.
[openldap] / servers / slapd / backend.c
index 445db7bbb1592c83b0b53241a9110301263936d1..b59e4c1d5890e805bc0897202c511e875fd54230 100644 (file)
 
 #include "slap.h"
 
+#ifdef SLAPD_LDBM
+#include "back-ldbm/external.h"
+#endif
+#ifdef SLAPD_BDB2
+#include "back-bdb2/external.h"
+#endif
+#ifdef SLAPD_PASSWD
+#include "back-passwd/external.h"
+#endif
+#ifdef SLAPD_PERL
+#include "back-perl/external.h"
+#endif
+#ifdef SLAPD_SHELL
+#include "back-shell/external.h"
+#endif
+#ifdef SLAPD_TCL
+#include "back-tcl/external.h"
+#endif
+
+static BackendInfo binfo[] = {
+#ifdef SLAPD_LDBM
+       {"ldbm",        ldbm_back_initialize},
+#endif
+#ifdef SLAPD_BDB2
+       {"bdb2",        bdb2_back_initialize},
+#endif
+#ifdef SLAPD_PASSWD
+       {"passwd",      passwd_back_initialize},
+#endif
+#ifdef SLAPD_PERL
+       {"perl",        perl_back_initialize},
+#endif
+#ifdef SLAPD_SHELL
+       {"shell",       shell_back_initialize},
+#endif
+#ifdef SLAPD_TCL
+       {"tcl",         tcl_back_initialize},
+#endif
+       {NULL}
+};
 
-#define BACKEND_GRAB_SIZE      10
+int                    nBackendInfo = 0;
+BackendInfo    *backendInfo = NULL;
 
-int            nbackends;
-Backend                *backends;
-static int     maxbackends;
+int                    nBackendDB = 0; 
+BackendDB      *backendDB = NULL;
 
-Backend *
-new_backend(
+int backend_init(void)
+{
+       int rc = -1;
+
+       if((nBackendInfo != 0) || (backendInfo != NULL)) {
+               /* already initialized */
+               Debug( LDAP_DEBUG_ANY,
+                       "backend_init: already initialized.\n", 0, 0, 0 );
+               return -1;
+       }
+
+       for( ;
+               binfo[nBackendInfo].bi_type !=  NULL;
+               nBackendInfo++ )
+       {
+               rc = binfo[nBackendInfo].bi_init(
+                       &binfo[nBackendInfo] );
+
+               if(rc != 0) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "backend_init: initialized for type \"%s\"\n",
+                                       binfo[nBackendInfo].bi_type, 0, 0 );
+
+                       /* destroy those we've already inited */
+                       for( nBackendInfo--;
+                               nBackendInfo >= 0 ;
+                               nBackendInfo-- )
+                       { 
+                               if ( binfo[nBackendInfo].bi_destroy ) {
+                                       binfo[nBackendInfo].bi_destroy(
+                                               &binfo[nBackendInfo] );
+                               }
+                       }
+                       return rc;
+               }
+       }
+
+       if ( nBackendInfo > 0) {
+               backendInfo = binfo;
+               return 0;
+       }
+
+       Debug( LDAP_DEBUG_ANY,
+               "backend_init: failed\n",
+               0, 0, 0 );
+
+       return rc;
+}
+
+int backend_startup(int n)
+{
+       int i;
+       int rc = 0;
+
+       if( ! ( nBackendDB > 0 ) ) {
+               /* no databases */
+               Debug( LDAP_DEBUG_ANY,
+                       "backend_startup: %d databases to startup.\n",
+                       nBackendDB, 0, 0 );
+               return 1;
+       }
+
+       if(n >= 0) {
+               /* startup a specific backend database */
+               Debug( LDAP_DEBUG_TRACE,
+                       "backend_startup: starting database %d\n",
+                       n, 0, 0 );
+
+               /* make sure, n does not exceed the number of backend databases */
+               if ( n >= nbackends ) {
+
+                       Debug( LDAP_DEBUG_ANY,
+                               "backend_startup: database number %d exceeding maximum (%d)\n",
+                               n, nbackends, 0 );
+                       return 1;
+               }
+
+               if ( backendDB[n].bd_info->bi_open ) {
+                       rc = backendDB[n].bd_info->bi_open(
+                               backendDB[n].bd_info );
+               }
+
+               if(rc != 0) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "backend_startup: bi_open failed!\n",
+                               0, 0, 0 );
+                       return rc;
+               }
+
+               if ( backendDB[n].bd_info->bi_db_open ) {
+                       rc = backendDB[n].bd_info->bi_db_open(
+                               &backendDB[n] );
+               }
+
+               if(rc != 0) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "backend_startup: bi_db_open failed!\n",
+                               0, 0, 0 );
+                       return rc;
+               }
+
+               return rc;
+       }
+
+       /* open each backend type */
+       for( i = 0; i < nBackendInfo; i++ ) {
+               if( backendInfo[i].bi_nDB == 0) {
+                       /* no database of this type, don't open */
+                       continue;
+               }
+
+               if( backendInfo[i].bi_open ) {
+                       rc = backendInfo[i].bi_open(
+                               &backendInfo[i] );
+               }
+
+               if(rc != 0) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "backend_startup: bi_open %d failed!\n",
+                               i, 0, 0 );
+                       return rc;
+               }
+       }
+
+       /* open each backend database */
+       for( i = 0; i < nBackendDB; i++ ) {
+               if ( backendDB[i].bd_info->bi_db_open ) {
+                       rc = backendDB[i].bd_info->bi_db_open(
+                               &backendDB[i] );
+               }
+
+               if(rc != 0) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "backend_startup: bi_db_open %d failed!\n",
+                               i, 0, 0 );
+                       return rc;
+               }
+       }
+
+       return rc;
+}
+
+int backend_shutdown(int n)
+{
+       int i;
+       int rc = 0;
+
+       if(n >= 0) {
+               /* shutdown a specific backend database */
+
+               /* make sure, n does not exceed the number of backend databases */
+               if ( n >= nbackends ) {
+
+                       Debug( LDAP_DEBUG_ANY,
+                               "backend_startup: database number %d exceeding maximum (%d)\n",
+                               n, nbackends, 0 );
+                       return 1;
+               }
+
+               if ( backendDB[n].bd_info->bi_nDB == 0 ) {
+                       /* no database of this type, we never opened it */
+                       return 0;
+               }
+
+               if ( backendDB[n].bd_info->bi_db_close ) {
+                       backendDB[n].bd_info->bi_db_close(
+                               &backendDB[n] );
+               }
+
+               if( backendDB[n].bd_info->bi_close ) {
+                       backendDB[n].bd_info->bi_close(
+                               backendDB[n].bd_info );
+               }
+
+               return 0;
+       }
+
+       /* close each backend database */
+       for( i = 0; i < nBackendDB; i++ ) {
+               BackendInfo  *bi;
+
+               if ( backendDB[i].bd_info->bi_db_close ) {
+                       backendDB[i].bd_info->bi_db_close(
+                               &backendDB[i] );
+               }
+
+               if(rc != 0) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "backend_close: bi_close %s failed!\n",
+                               bi->bi_type, 0, 0 );
+               }
+       }
+
+       /* close each backend type */
+       for( i = 0; i < nBackendInfo; i++ ) {
+               if( backendInfo[i].bi_nDB == 0 ) {
+                       /* no database of this type */
+                       continue;
+               }
+
+               if( backendInfo[i].bi_close ) {
+                       backendInfo[i].bi_close(
+                               &backendInfo[i] );
+               }
+       }
+
+       return 0;
+}
+
+int backend_destroy(void)
+{
+       int i;
+
+       /* destroy each backend database */
+       for( i = 0; i < nBackendDB; i++ ) {
+               if ( backendDB[i].bd_info->bi_db_destroy ) {
+                       backendDB[i].bd_info->bi_db_destroy(
+                               &backendDB[i] );
+               }
+       }
+
+       /* destroy each backend type */
+       for( i = 0; i < nBackendInfo; i++ ) {
+               if( backendInfo[i].bi_destroy ) {
+                       backendInfo[i].bi_destroy(
+                               &backendInfo[i] );
+               }
+       }
+
+       return 0;
+}
+
+BackendInfo* backend_info(char *type)
+{
+       int i;
+
+       /* search for the backend type */
+       for( i = 0; i < nBackendInfo; i++ ) {
+               if( strcasecmp(backendInfo[i].bi_type, type) == 0 ) {
+                       return &backendInfo[i];
+               }
+       }
+
+       return NULL;
+}
+
+
+BackendDB *
+backend_db_init(
     char       *type
 )
 {
        Backend *be;
-       int     foundit;
-
-       if ( nbackends == maxbackends ) {
-               maxbackends += BACKEND_GRAB_SIZE;
-               backends = (Backend *) ch_realloc( (char *) backends,
-                   maxbackends * sizeof(Backend) );
-               memset( &backends[nbackends], '\0', BACKEND_GRAB_SIZE *
-                   sizeof(Backend) );
+       BackendInfo *bi = backend_info(type);
+       int     rc = 0;
+
+       if( bi == NULL ) {
+               fprintf( stderr, "Unrecognized database type (%s)\n", type );
+               return NULL;
        }
 
+       backendDB = (BackendDB *) ch_realloc(
+                       (char *) backendDB,
+                   (nBackendDB + 1) * sizeof(Backend) );
+
+       memset( &backendDB[nbackends], '\0', sizeof(Backend) );
+
        be = &backends[nbackends++];
+
+       be->bd_info = bi;
        be->be_sizelimit = defsize;
        be->be_timelimit = deftime;
-       foundit = 0;
 
-#ifdef SLAPD_LDBM
-       if ( strcasecmp( type, "ldbm" ) == 0 ) {
-               be->be_bind = ldbm_back_bind;
-               be->be_unbind = ldbm_back_unbind;
-               be->be_search = ldbm_back_search;
-               be->be_compare = ldbm_back_compare;
-               be->be_modify = ldbm_back_modify;
-               be->be_modrdn = ldbm_back_modrdn;
-               be->be_add = ldbm_back_add;
-               be->be_delete = ldbm_back_delete;
-               be->be_abandon = ldbm_back_abandon;
-               be->be_config = ldbm_back_config;
-               be->be_init = ldbm_back_init;
-               be->be_close = ldbm_back_close;
-#ifdef SLAPD_ACLGROUPS
-               be->be_group = ldbm_back_group;
-#endif
-               be->be_type = "ldbm";
-               foundit = 1;
+       if(bi->bi_db_init) {
+               rc = bi->bi_db_init( be );
        }
-#endif
 
-#ifdef SLAPD_PASSWD
-       if ( strcasecmp( type, "passwd" ) == 0 ) {
-               be->be_bind = NULL;
-               be->be_unbind = NULL;
-               be->be_search = passwd_back_search;
-               be->be_compare = NULL;
-               be->be_modify = NULL;
-               be->be_modrdn = NULL;
-               be->be_add = NULL;
-               be->be_delete = NULL;
-               be->be_abandon = NULL;
-               be->be_config = passwd_back_config;
-               be->be_init = NULL;
-               be->be_close = NULL;
-#ifdef SLAPD_ACLGROUPS
-               be->be_group = NULL;
-#endif
-               be->be_type = "passwd";
-               foundit = 1;
+       if(rc != 0) {
+               fprintf( stderr, "database init failed (%s)\n", type );
+               nbackends--;
+               return NULL;
        }
-#endif
 
-#ifdef SLAPD_SHELL
-       if ( strcasecmp( type, "shell" ) == 0 ) {
-               be->be_bind = shell_back_bind;
-               be->be_unbind = shell_back_unbind;
-               be->be_search = shell_back_search;
-               be->be_compare = shell_back_compare;
-               be->be_modify = shell_back_modify;
-               be->be_modrdn = shell_back_modrdn;
-               be->be_add = shell_back_add;
-               be->be_delete = shell_back_delete;
-               be->be_abandon = shell_back_abandon;
-               be->be_config = shell_back_config;
-               be->be_init = shell_back_init;
-               be->be_close = NULL;
-#ifdef SLAPD_ACLGROUPS
-               be->be_group = NULL;
-#endif
-               be->be_type = "shell";
-               foundit = 1;
-       }
-#endif
+       bi->bi_nDB++;
+       return( be );
+}
 
-       if ( be->be_init != NULL ) {
-               (*be->be_init)( be );
-       }
+void
+be_db_close( void )
+{
+       int     i;
 
-       if ( foundit == 0 ) {
-               fprintf( stderr, "Unrecognized database type (%s)\n", type );
-               exit( 1 );
+       for ( i = 0; i < nbackends; i++ ) {
+               if ( backends[i].bd_info->bi_db_close != NULL ) {
+                       (*backends[i].bd_info->bi_db_close)( &backends[i] );
+               }
        }
-
-       return( be );
 }
 
 Backend *
@@ -134,7 +374,7 @@ select_backend( char * dn )
                                continue;
                        }
 
-                       if ( strcasecmp( backends[i].be_suffix[j],
+                       if ( strcmp( backends[i].be_suffix[j],
                            dn + (dnlen - len) ) == 0 ) {
                                return( &backends[i] );
                        }
@@ -154,7 +394,7 @@ select_backend( char * dn )
                                 continue;
                         }
 
-                        if ( strcasecmp( backends[i].be_suffixAlias[j],
+                        if ( strcmp( backends[i].be_suffixAlias[j],
                             dn + (dnlen - len) ) == 0 ) {
                                 return( &backends[i] );
                         }
@@ -187,7 +427,7 @@ be_issuffix(
        int     i;
 
        for ( i = 0; be->be_suffix != NULL && be->be_suffix[i] != NULL; i++ ) {
-               if ( strcasecmp( be->be_suffix[i], suffix ) == 0 ) {
+               if ( strcmp( be->be_suffix[i], suffix ) == 0 ) {
                        return( 1 );
                }
        }
@@ -196,54 +436,55 @@ be_issuffix(
 }
 
 int
-be_isroot( Backend *be, char *dn )
+be_isroot( Backend *be, char *ndn )
 {
-       if ( dn == NULL ) {
+       int rc;
+
+       if ( ndn == NULL || be->be_root_ndn == NULL ) {
                return( 0 );
        }
 
-       return( be->be_rootdn != NULL
-               ? strcasecmp( be->be_rootdn, dn ) == 0
-           : 0 );
+       rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
+
+       return(rc);
+}
+
+char *
+be_root_dn( Backend *be )
+{
+       int rc;
+
+       if ( be->be_root_dn == NULL ) {
+               return( "" );
+       }
+
+       return be->be_root_dn;
 }
 
 int
-be_isroot_pw( Backend *be, char *dn, struct berval *cred )
+be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
 {
        int result;
 
-       if ( ! be_isroot( be, dn ) ) {
+       if ( ! be_isroot( be, ndn ) ) {
                return( 0 );
        }
 
 #ifdef SLAPD_CRYPT
-       pthread_mutex_lock( &crypt_mutex );
+       ldap_pvt_thread_mutex_lock( &crypt_mutex );
 #endif
 
-       result = lutil_passwd( cred->bv_val, be->be_rootpw );
+       result = lutil_passwd( cred->bv_val, be->be_root_pw );
 
 #ifdef SLAPD_CRYPT
-       pthread_mutex_unlock( &crypt_mutex );
+       ldap_pvt_thread_mutex_unlock( &crypt_mutex );
 #endif
 
        return result == 0;
 }
 
-void
-be_close( void )
-{
-       int     i;
-
-       for ( i = 0; i < nbackends; i++ ) {
-               if ( backends[i].be_close != NULL ) {
-                       (*backends[i].be_close)( &backends[i] );
-               }
-       }
-}
-
-
-void
-be_unbind(
+int
+backend_unbind(
        Connection   *conn,
        Operation    *op
 )
@@ -255,23 +496,25 @@ be_unbind(
                        (*backends[i].be_unbind)( &backends[i], conn, op );
                }
        }
+
+       return 0;
 }
 
 #ifdef SLAPD_ACLGROUPS
 int 
-be_group(
+backend_group(
        Backend *be,
-       Entry   *e,
-       char    *bdn,
-       char    *edn,
+       Entry   *target,
+       char    *gr_ndn,
+       char    *op_ndn,
        char    *objectclassValue,
        char    *groupattrName
 )
 {
-        if (be->be_group)
-                return(be->be_group(be, e, bdn, edn,
-                                       objectclassValue, groupattrName));
-        else
-                return(1);
+       if (be->be_group)
+               return( be->be_group(be, target, gr_ndn, op_ndn,
+                       objectclassValue, groupattrName) );
+       else
+               return(1);
 }
 #endif