Back to index

openldap  2.4.31
api.c
Go to the documentation of this file.
00001 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00002  *
00003  * Copyright 1999-2012 The OpenLDAP Foundation.
00004  * Portions Copyright 1999 Dmitry Kovalev.
00005  * Portions Copyright 2004 Pierangelo Masarati.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 /* ACKNOWLEDGEMENTS:
00017  * This work was initially developed by Dmitry Kovalev for inclusion
00018  * by OpenLDAP Software.  Additional significant contributors include
00019  * Pierangelo Masarati.
00020  */
00021 
00022 #include "portable.h"
00023 
00024 #include <stdio.h>
00025 #include <sys/types.h>
00026 #include "ac/string.h"
00027 
00028 #include "slap.h"
00029 #include "proto-sql.h"
00030 
00031 static backsql_api *backsqlapi;
00032 
00033 int
00034 backsql_api_config( backsql_info *bi, const char *name, int argc, char *argv[] )
00035 {
00036        backsql_api   *ba;
00037 
00038        assert( bi != NULL );
00039        assert( name != NULL );
00040 
00041        for ( ba = backsqlapi; ba; ba = ba->ba_next ) {
00042               if ( strcasecmp( name, ba->ba_name ) == 0 ) {
00043                      backsql_api   *ba2;
00044 
00045                      ba2 = ch_malloc( sizeof( backsql_api ) );
00046                      *ba2 = *ba;
00047 
00048                      if ( ba2->ba_config ) {
00049                             if ( ( *ba2->ba_config )( ba2, argc, argv ) ) {
00050                                    ch_free( ba2 );
00051                                    return 1;
00052                             }
00053                             ba2->ba_argc = argc;
00054                             if ( argc ) {
00055                                    int i;
00056                                    ba2->ba_argv = ch_malloc( argc * sizeof(char *));
00057                                    for ( i=0; i<argc; i++ )
00058                                           ba2->ba_argv[i] = ch_strdup( argv[i] );
00059                             }
00060                      }
00061                      
00062                      ba2->ba_next = bi->sql_api;
00063                      bi->sql_api = ba2;
00064                      return 0;
00065               }
00066        }
00067 
00068        return 1;
00069 }
00070 
00071 int
00072 backsql_api_destroy( backsql_info *bi )
00073 {
00074        backsql_api   *ba;
00075 
00076        assert( bi != NULL );
00077 
00078        ba = bi->sql_api;
00079 
00080        if ( ba == NULL ) {
00081               return 0;
00082        }
00083 
00084        for ( ; ba; ba = ba->ba_next ) {
00085               if ( ba->ba_destroy ) {
00086                      (void)( *ba->ba_destroy )( ba );
00087               }
00088        }
00089 
00090        return 0;
00091 }
00092 
00093 int
00094 backsql_api_register( backsql_api *ba )
00095 {
00096        backsql_api   *ba2;
00097 
00098        assert( ba != NULL );
00099        assert( ba->ba_private == NULL );
00100 
00101        if ( ba->ba_name == NULL ) {
00102               fprintf( stderr, "API module has no name\n" );
00103               exit(EXIT_FAILURE);
00104        }
00105 
00106        for ( ba2 = backsqlapi; ba2; ba2 = ba2->ba_next ) {
00107               if ( strcasecmp( ba->ba_name, ba2->ba_name ) == 0 ) {
00108                      fprintf( stderr, "API module \"%s\" already defined\n", ba->ba_name );
00109                      exit( EXIT_FAILURE );
00110               }
00111        }
00112 
00113        ba->ba_next = backsqlapi;
00114        backsqlapi = ba;
00115 
00116        return 0;
00117 }
00118 
00119 int
00120 backsql_api_dn2odbc( Operation *op, SlapReply *rs, struct berval *dn )
00121 {
00122        backsql_info  *bi = (backsql_info *)op->o_bd->be_private;
00123        backsql_api   *ba;
00124        int           rc;
00125        struct berval bv;
00126 
00127        ba = bi->sql_api;
00128 
00129        if ( ba == NULL ) {
00130               return 0;
00131        }
00132 
00133        ber_dupbv( &bv, dn );
00134 
00135        for ( ; ba; ba = ba->ba_next ) {
00136               if ( ba->ba_dn2odbc ) {
00137                      /*
00138                       * The dn2odbc() helper is supposed to rewrite
00139                       * the contents of bv, freeing the original value
00140                       * with ch_free() if required and replacing it 
00141                       * with a newly allocated one using ch_malloc() 
00142                       * or companion functions.
00143                       *
00144                       * NOTE: it is supposed to __always__ free
00145                       * the value of bv in case of error, and reset
00146                       * it with BER_BVZERO() .
00147                       */
00148                      rc = ( *ba->ba_dn2odbc )( op, rs, &bv );
00149 
00150                      if ( rc ) {
00151                             /* in case of error, dn2odbc() must cleanup */
00152                             assert( BER_BVISNULL( &bv ) );
00153 
00154                             return rc;
00155                      }
00156               }
00157        }
00158 
00159        assert( !BER_BVISNULL( &bv ) );
00160 
00161        *dn = bv;
00162 
00163        return 0;
00164 }
00165 
00166 int
00167 backsql_api_odbc2dn( Operation *op, SlapReply *rs, struct berval *dn )
00168 {
00169        backsql_info  *bi = (backsql_info *)op->o_bd->be_private;
00170        backsql_api   *ba;
00171        int           rc;
00172        struct berval bv;
00173 
00174        ba = bi->sql_api;
00175 
00176        if ( ba == NULL ) {
00177               return 0;
00178        }
00179 
00180        ber_dupbv( &bv, dn );
00181 
00182        for ( ; ba; ba = ba->ba_next ) {
00183               if ( ba->ba_dn2odbc ) {
00184                      rc = ( *ba->ba_odbc2dn )( op, rs, &bv );
00185                      /*
00186                       * The odbc2dn() helper is supposed to rewrite
00187                       * the contents of bv, freeing the original value
00188                       * with ch_free() if required and replacing it 
00189                       * with a newly allocated one using ch_malloc() 
00190                       * or companion functions.
00191                       *
00192                       * NOTE: it is supposed to __always__ free
00193                       * the value of bv in case of error, and reset
00194                       * it with BER_BVZERO() .
00195                       */
00196                      if ( rc ) {
00197                             /* in case of error, odbc2dn() must cleanup */
00198                             assert( BER_BVISNULL( &bv ) );
00199 
00200                             return rc;
00201                      }
00202               }
00203        }
00204 
00205        assert( !BER_BVISNULL( &bv ) );
00206 
00207        *dn = bv;
00208 
00209        return 0;
00210 }
00211