Home | History | Annotate | Line # | Download | only in back-sql
      1 /*	$NetBSD: api.c,v 1.4 2025/09/05 21:16:31 christos Exp $	*/
      2 
      3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      4  *
      5  * Copyright 1999-2024 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.4 2025/09/05 21:16:31 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