1/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 2 * 3 * Copyright 1999-2011 The OpenLDAP Foundation. 4 * Portions Copyright 1999 Dmitry Kovalev. 5 * Portions Copyright 2004 Pierangelo Masarati. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted only as authorized by the OpenLDAP 10 * Public License. 11 * 12 * A copy of this license is available in the file LICENSE in the 13 * top-level directory of the distribution or, alternatively, at 14 * <http://www.OpenLDAP.org/license.html>. 15 */ 16/* ACKNOWLEDGEMENTS: 17 * This work was initially developed by Dmitry Kovalev for inclusion 18 * by OpenLDAP Software. Additional significant contributors include 19 * Pierangelo Masarati. 20 */ 21 22#include "portable.h" 23 24#include <stdio.h> 25#include <sys/types.h> 26#include "ac/string.h" 27 28#include "slap.h" 29#include "proto-sql.h" 30 31static backsql_api *backsqlapi; 32 33int 34backsql_api_config( backsql_info *bi, const char *name, int argc, char *argv[] ) 35{ 36 backsql_api *ba; 37 38 assert( bi != NULL ); 39 assert( name != NULL ); 40 41 for ( ba = backsqlapi; ba; ba = ba->ba_next ) { 42 if ( strcasecmp( name, ba->ba_name ) == 0 ) { 43 backsql_api *ba2; 44 45 ba2 = ch_malloc( sizeof( backsql_api ) ); 46 *ba2 = *ba; 47 48 if ( ba2->ba_config ) { 49 if ( ( *ba2->ba_config )( ba2, argc, argv ) ) { 50 ch_free( ba2 ); 51 return 1; 52 } 53 ba2->ba_argc = argc; 54 if ( argc ) { 55 int i; 56 ba2->ba_argv = ch_malloc( argc * sizeof(char *)); 57 for ( i=0; i<argc; i++ ) 58 ba2->ba_argv[i] = ch_strdup( argv[i] ); 59 } 60 } 61 62 ba2->ba_next = bi->sql_api; 63 bi->sql_api = ba2; 64 return 0; 65 } 66 } 67 68 return 1; 69} 70 71int 72backsql_api_destroy( backsql_info *bi ) 73{ 74 backsql_api *ba; 75 76 assert( bi != NULL ); 77 78 ba = bi->sql_api; 79 80 if ( ba == NULL ) { 81 return 0; 82 } 83 84 for ( ; ba; ba = ba->ba_next ) { 85 if ( ba->ba_destroy ) { 86 (void)( *ba->ba_destroy )( ba ); 87 } 88 } 89 90 return 0; 91} 92 93int 94backsql_api_register( backsql_api *ba ) 95{ 96 backsql_api *ba2; 97 98 assert( ba != NULL ); 99 assert( ba->ba_private == NULL ); 100 101 if ( ba->ba_name == NULL ) { 102 fprintf( stderr, "API module has no name\n" ); 103 exit(EXIT_FAILURE); 104 } 105 106 for ( ba2 = backsqlapi; ba2; ba2 = ba2->ba_next ) { 107 if ( strcasecmp( ba->ba_name, ba2->ba_name ) == 0 ) { 108 fprintf( stderr, "API module \"%s\" already defined\n", ba->ba_name ); 109 exit( EXIT_FAILURE ); 110 } 111 } 112 113 ba->ba_next = backsqlapi; 114 backsqlapi = ba; 115 116 return 0; 117} 118 119int 120backsql_api_dn2odbc( Operation *op, SlapReply *rs, struct berval *dn ) 121{ 122 backsql_info *bi = (backsql_info *)op->o_bd->be_private; 123 backsql_api *ba; 124 int rc; 125 struct berval bv; 126 127 ba = bi->sql_api; 128 129 if ( ba == NULL ) { 130 return 0; 131 } 132 133 ber_dupbv( &bv, dn ); 134 135 for ( ; ba; ba = ba->ba_next ) { 136 if ( ba->ba_dn2odbc ) { 137 /* 138 * The dn2odbc() helper is supposed to rewrite 139 * the contents of bv, freeing the original value 140 * with ch_free() if required and replacing it 141 * with a newly allocated one using ch_malloc() 142 * or companion functions. 143 * 144 * NOTE: it is supposed to __always__ free 145 * the value of bv in case of error, and reset 146 * it with BER_BVZERO() . 147 */ 148 rc = ( *ba->ba_dn2odbc )( op, rs, &bv ); 149 150 if ( rc ) { 151 /* in case of error, dn2odbc() must cleanup */ 152 assert( BER_BVISNULL( &bv ) ); 153 154 return rc; 155 } 156 } 157 } 158 159 assert( !BER_BVISNULL( &bv ) ); 160 161 *dn = bv; 162 163 return 0; 164} 165 166int 167backsql_api_odbc2dn( Operation *op, SlapReply *rs, struct berval *dn ) 168{ 169 backsql_info *bi = (backsql_info *)op->o_bd->be_private; 170 backsql_api *ba; 171 int rc; 172 struct berval bv; 173 174 ba = bi->sql_api; 175 176 if ( ba == NULL ) { 177 return 0; 178 } 179 180 ber_dupbv( &bv, dn ); 181 182 for ( ; ba; ba = ba->ba_next ) { 183 if ( ba->ba_dn2odbc ) { 184 rc = ( *ba->ba_odbc2dn )( op, rs, &bv ); 185 /* 186 * The odbc2dn() helper is supposed to rewrite 187 * the contents of bv, freeing the original value 188 * with ch_free() if required and replacing it 189 * with a newly allocated one using ch_malloc() 190 * or companion functions. 191 * 192 * NOTE: it is supposed to __always__ free 193 * the value of bv in case of error, and reset 194 * it with BER_BVZERO() . 195 */ 196 if ( rc ) { 197 /* in case of error, odbc2dn() must cleanup */ 198 assert( BER_BVISNULL( &bv ) ); 199 200 return rc; 201 } 202 } 203 } 204 205 assert( !BER_BVISNULL( &bv ) ); 206 207 *dn = bv; 208 209 return 0; 210} 211 212