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