xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-sql/api.c (revision 6cf6fe02a981b55727c49c3d37b0d8191a98c0ee)
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