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