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