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