1 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 2 * 3 * Copyright 1999-2008 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 31 static backsql_api *backsqlapi; 32 33 int 34 backsql_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 } 54 55 ba2->ba_next = bi->sql_api; 56 bi->sql_api = ba2; 57 return 0; 58 } 59 } 60 61 return 1; 62 } 63 64 int 65 backsql_api_destroy( backsql_info *bi ) 66 { 67 backsql_api *ba; 68 69 assert( bi != NULL ); 70 71 ba = bi->sql_api; 72 73 if ( ba == NULL ) { 74 return 0; 75 } 76 77 for ( ; ba; ba = ba->ba_next ) { 78 if ( ba->ba_destroy ) { 79 (void)( *ba->ba_destroy )( ba ); 80 } 81 } 82 83 return 0; 84 } 85 86 int 87 backsql_api_register( backsql_api *ba ) 88 { 89 backsql_api *ba2; 90 91 assert( ba != NULL ); 92 assert( ba->ba_private == NULL ); 93 94 if ( ba->ba_name == NULL ) { 95 fprintf( stderr, "API module has no name\n" ); 96 exit(EXIT_FAILURE); 97 } 98 99 for ( ba2 = backsqlapi; ba2; ba2 = ba2->ba_next ) { 100 if ( strcasecmp( ba->ba_name, ba2->ba_name ) == 0 ) { 101 fprintf( stderr, "API module \"%s\" already defined\n", ba->ba_name ); 102 exit( EXIT_FAILURE ); 103 } 104 } 105 106 ba->ba_next = backsqlapi; 107 backsqlapi = ba; 108 109 return 0; 110 } 111 112 int 113 backsql_api_dn2odbc( Operation *op, SlapReply *rs, struct berval *dn ) 114 { 115 backsql_info *bi = (backsql_info *)op->o_bd->be_private; 116 backsql_api *ba; 117 int rc; 118 struct berval bv; 119 120 ba = bi->sql_api; 121 122 if ( ba == NULL ) { 123 return 0; 124 } 125 126 ber_dupbv( &bv, dn ); 127 128 for ( ; ba; ba = ba->ba_next ) { 129 if ( ba->ba_dn2odbc ) { 130 /* 131 * The dn2odbc() helper is supposed to rewrite 132 * the contents of bv, freeing the original value 133 * with ch_free() if required and replacing it 134 * with a newly allocated one using ch_malloc() 135 * or companion functions. 136 * 137 * NOTE: it is supposed to __always__ free 138 * the value of bv in case of error, and reset 139 * it with BER_BVZERO() . 140 */ 141 rc = ( *ba->ba_dn2odbc )( op, rs, &bv ); 142 143 if ( rc ) { 144 /* in case of error, dn2odbc() must cleanup */ 145 assert( BER_BVISNULL( &bv ) ); 146 147 return rc; 148 } 149 } 150 } 151 152 assert( !BER_BVISNULL( &bv ) ); 153 154 *dn = bv; 155 156 return 0; 157 } 158 159 int 160 backsql_api_odbc2dn( Operation *op, SlapReply *rs, struct berval *dn ) 161 { 162 backsql_info *bi = (backsql_info *)op->o_bd->be_private; 163 backsql_api *ba; 164 int rc; 165 struct berval bv; 166 167 ba = bi->sql_api; 168 169 if ( ba == NULL ) { 170 return 0; 171 } 172 173 ber_dupbv( &bv, dn ); 174 175 for ( ; ba; ba = ba->ba_next ) { 176 if ( ba->ba_dn2odbc ) { 177 rc = ( *ba->ba_odbc2dn )( op, rs, &bv ); 178 /* 179 * The odbc2dn() helper is supposed to rewrite 180 * the contents of bv, freeing the original value 181 * with ch_free() if required and replacing it 182 * with a newly allocated one using ch_malloc() 183 * or companion functions. 184 * 185 * NOTE: it is supposed to __always__ free 186 * the value of bv in case of error, and reset 187 * it with BER_BVZERO() . 188 */ 189 if ( rc ) { 190 /* in case of error, odbc2dn() must cleanup */ 191 assert( BER_BVISNULL( &bv ) ); 192 193 return rc; 194 } 195 } 196 } 197 198 assert( !BER_BVISNULL( &bv ) ); 199 200 *dn = bv; 201 202 return 0; 203 } 204 205