]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/init.c
3d4e30242fbbda57de828d00eec374d8b2a62a57
[openldap] / servers / slapd / back-sql / init.c
1 /*
2  *       Copyright 1999, Dmitry Kovalev <mit@openldap.org>, All rights reserved.
3  *
4  *       Redistribution and use in source and binary forms are permitted only
5  *       as authorized by the OpenLDAP Public License.  A copy of this
6  *       license is available at http://www.OpenLDAP.org/license.html or
7  *       in file LICENSE in the top-level directory of the distribution.
8  */
9
10 #include "portable.h"
11
12 #ifdef SLAPD_SQL
13
14 #include <stdio.h>
15 #include <sys/types.h>
16 #include "slap.h"
17 #include "ldap_pvt.h"
18 #include "back-sql.h"
19 #include "sql-wrap.h"
20 #include "schema-map.h"
21 #include "util.h"
22
23 #ifdef SLAPD_SQL_DYNAMIC
24
25 int
26 backsql_LTX_init_module(
27         int             argc, 
28         char            *argv[] )
29 {
30         BackendInfo bi;
31
32         memset( &bi, '\0', sizeof( bi ) );
33         bi.bi_type = "sql";
34         bi.bi_init = backbacksql_initialize;
35
36         backend_add( &bi );
37         return 0;
38 }
39
40 #endif /* SLAPD_SHELL_DYNAMIC */
41
42 int
43 sql_back_initialize(
44         BackendInfo     *bi )
45
46         Debug( LDAP_DEBUG_TRACE,"==>backsql_initialize()\n", 0, 0, 0 );
47         
48         bi->bi_open = 0;
49         bi->bi_config = 0;
50         bi->bi_close = 0;
51         bi->bi_destroy = 0;
52
53         bi->bi_db_init = backsql_db_init;
54         bi->bi_db_config = backsql_db_config;
55         bi->bi_db_open = backsql_db_open;
56         bi->bi_db_close = backsql_db_close;
57         bi->bi_db_destroy = backsql_db_destroy;
58
59 #ifdef BACKSQL_ALL_DONE
60         bi->bi_op_abandon = backsql_abandon;
61         bi->bi_op_compare = backsql_compare;
62 #else
63         bi->bi_op_abandon = 0;
64         bi->bi_op_compare = 0;
65 #endif
66         bi->bi_op_bind = backsql_bind;
67         bi->bi_op_unbind = backsql_unbind;
68         bi->bi_op_search = backsql_search;
69         bi->bi_op_modify = backsql_modify;
70         bi->bi_op_modrdn = backsql_modrdn;
71         bi->bi_op_add = backsql_add;
72         bi->bi_op_delete = backsql_delete;
73         
74         bi->bi_acl_group = 0;
75         bi->bi_acl_attribute = 0;
76         bi->bi_chk_referrals = 0;
77         bi->bi_operational = backsql_operational;
78  
79         bi->bi_connection_init = 0;
80         bi->bi_connection_destroy = backsql_connection_destroy;
81         
82         Debug( LDAP_DEBUG_TRACE,"<==backsql_initialize()\n", 0, 0, 0 );
83         return 0;
84 }
85
86
87 int
88 backsql_destroy( 
89         BackendInfo     *bi )
90 {
91         Debug( LDAP_DEBUG_TRACE, "==>backsql_destroy()\n", 0, 0, 0 );
92         Debug( LDAP_DEBUG_TRACE, "<==backsql_destroy()\n", 0, 0, 0 );
93         return 0;
94 }
95
96 int
97 backsql_db_init(
98         BackendDB       *bd )
99 {
100         backsql_info *si;
101  
102         Debug( LDAP_DEBUG_TRACE, "==>backsql_db_init()\n", 0, 0, 0 );
103         si = (backsql_info *)ch_calloc( 1, sizeof( backsql_info ) );
104         memset( si, '\0', sizeof( backsql_info ) );
105         ldap_pvt_thread_mutex_init( &si->dbconn_mutex );
106         ldap_pvt_thread_mutex_init( &si->schema_mutex );
107         backsql_init_db_env( si );
108
109         bd->be_private = si;
110         Debug( LDAP_DEBUG_TRACE, "<==backsql_db_init()\n", 0, 0, 0 );
111         return 0;
112 }
113
114 int
115 backsql_db_destroy(
116         BackendDB       *bd )
117 {
118         backsql_info *si = (backsql_info*)bd->be_private;
119  
120         Debug( LDAP_DEBUG_TRACE, "==>backsql_db_destroy()\n", 0, 0, 0 );
121         ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
122         backsql_free_db_env( si );
123         ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
124         ldap_pvt_thread_mutex_destroy( &si->dbconn_mutex );
125         ldap_pvt_thread_mutex_lock( &si->schema_mutex );
126         backsql_destroy_schema_map( si );
127         ldap_pvt_thread_mutex_unlock( &si->schema_mutex );
128         ldap_pvt_thread_mutex_destroy( &si->schema_mutex );
129         free( si->dbname );
130         free( si->dbuser );
131         if ( si->dbpasswd ) {
132                 free( si->dbpasswd );
133         }
134         if ( si->dbhost ) {
135                 free( si->dbhost );
136         }
137         if ( si->upper_func.bv_val ) {
138                 free( si->upper_func.bv_val );
139                 free( si->upper_func_open.bv_val );
140                 free( si->upper_func_close.bv_val );
141         }
142         
143         free( si->subtree_cond.bv_val );
144         free( si->oc_query );
145         free( si->at_query );
146         free( si->insentry_query );
147         free( si->delentry_query );
148         free( si );
149         
150         Debug( LDAP_DEBUG_TRACE, "<==backsql_db_destroy()\n", 0, 0, 0 );
151         return 0;
152 }
153
154 int
155 backsql_db_open(
156         BackendDB       *bd )
157 {
158         backsql_info    *si = (backsql_info*)bd->be_private;
159         Connection      tmp;
160         SQLHDBC         dbh;
161         ber_len_t       idq_len;
162         struct berval   bv;
163
164         Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): "
165                 "testing RDBMS connection\n", 0, 0, 0 );
166         if ( si->dbname == NULL ) {
167                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
168                         "datasource name not specified "
169                         "(use \"dbname\" directive in slapd.conf)\n", 0, 0, 0 );
170                 return 1;
171         }
172
173         if ( si->concat_func == NULL ) {
174                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
175                         "concat func not specified (use \"concat_pattern\" "
176                         "directive in slapd.conf)\n", 0, 0, 0 );
177
178                 if ( backsql_split_pattern( backsql_def_concat_func, 
179                                 &si->concat_func, 2 ) ) {
180                         Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
181                                 "unable to parse pattern '%s'",
182                                 backsql_def_concat_func, 0, 0 );
183                         return 1;
184                 }
185         }
186
187         /*
188          * Prepare cast string as required
189          */
190         if ( si->upper_func.bv_val ) {
191                 char buf[1024];
192
193                 if ( BACKSQL_UPPER_NEEDS_CAST( si ) ) {
194                         snprintf( buf, sizeof( buf ), 
195                                 "%s(cast (" /* ? as varchar(%d))) */ , 
196                                 si->upper_func.bv_val );
197                         ber_str2bv( buf, 0, 1, &si->upper_func_open );
198
199                         snprintf( buf, sizeof( buf ),
200                                 /* (cast(? */ " as varchar(%d)))",
201                                 BACKSQL_MAX_DN_LEN );
202                         ber_str2bv( buf, 0, 1, &si->upper_func_close );
203
204                 } else {
205                         snprintf( buf, sizeof( buf ), "%s(" /* ?) */ ,
206                                         si->upper_func.bv_val );
207                         ber_str2bv( buf, 0, 1, &si->upper_func_open );
208
209                         ber_str2bv( /* (? */ ")", 0, 1, &si->upper_func_close );
210                 }
211         }
212         
213         if ( si->dbuser == NULL ) {
214                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
215                         "user name not specified "
216                         "(use \"dbuser\" directive in slapd.conf)\n", 0, 0, 0 );
217                 return 1;
218         }
219         
220         if ( si->subtree_cond.bv_val == NULL ) {
221                 /*
222                  * Prepare concat function for subtree search condition
223                  */
224                 struct berval   concat;
225                 ber_len_t       len = 0;
226                 struct berval   values[] = {
227                         { sizeof( "'%'" ) - 1,  "'%'" },
228                         { sizeof( "?" ) - 1,    "?" },
229                         { 0,                    NULL }
230                 };
231
232                 if ( backsql_prepare_pattern( si->concat_func, values, 
233                                 &concat ) ) {
234                         Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
235                                 "unable to prepare CONCAT pattern", 0, 0, 0 );
236                         return 1;
237                 }
238                         
239                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
240                         "subtree search SQL condition not specified "
241                         "(use \"subtree_cond\" directive in slapd.conf)\n", 
242                         0, 0, 0);
243
244                 si->subtree_cond.bv_val = NULL;
245                 si->subtree_cond.bv_len = 0;
246
247                 if ( si->upper_func.bv_val ) {
248
249                         /*
250                          * UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%',?))
251                          */
252
253                         backsql_strfcat( &si->subtree_cond, &len, "blbbb",
254                                         &si->upper_func,
255                                         (ber_len_t)sizeof( "(ldap_entries.dn) LIKE " ) - 1,
256                                                 "(ldap_entries.dn) LIKE ",
257                                         &si->upper_func_open,
258                                         &concat,
259                                         &si->upper_func_close );
260
261                 } else {
262
263                         /*
264                          * ldap_entries.dn LIKE CONCAT('%',?)
265                          */
266
267                         backsql_strfcat( &si->subtree_cond, &len, "lb",
268                                         (ber_len_t)sizeof( "ldap_entries.dn LIKE " ) - 1,
269                                                 "ldap_entries.dn LIKE ",
270                                         &concat );
271                 }
272                         
273                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
274                         "setting '%s' as default\n",
275                         si->subtree_cond.bv_val, 0, 0 );
276         }
277
278         if ( si->children_cond.bv_val == NULL ) {
279                 /*
280                  * Prepare concat function for children search condition
281                  */
282                 struct berval   concat;
283                 ber_len_t       len = 0;
284                 struct berval   values[] = {
285                         { sizeof( "'%,'" ) - 1, "'%,'" },
286                         { sizeof( "?" ) - 1,    "?" },
287                         { 0,                    NULL }
288                 };
289
290                 if ( backsql_prepare_pattern( si->concat_func, values, 
291                                 &concat ) ) {
292                         Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
293                                 "unable to prepare CONCAT pattern", 0, 0, 0 );
294                         return 1;
295                 }
296                         
297                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
298                         "children search SQL condition not specified "
299                         "(use \"children_cond\" directive in slapd.conf)\n", 
300                         0, 0, 0);
301
302                 si->children_cond.bv_val = NULL;
303                 si->children_cond.bv_len = 0;
304
305                 if ( si->upper_func.bv_val ) {
306
307                         /*
308                          * UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%,',?))
309                          */
310
311                         backsql_strfcat( &si->children_cond, &len, "blbbb",
312                                         &si->upper_func,
313                                         (ber_len_t)sizeof( "(ldap_entries.dn) LIKE " ) - 1,
314                                                 "(ldap_entries.dn) LIKE ",
315                                         &si->upper_func_open,
316                                         &concat,
317                                         &si->upper_func_close );
318
319                 } else {
320
321                         /*
322                          * ldap_entries.dn LIKE CONCAT('%,',?)
323                          */
324
325                         backsql_strfcat( &si->children_cond, &len, "lb",
326                                         (ber_len_t)sizeof( "ldap_entries.dn LIKE " ) - 1,
327                                                 "ldap_entries.dn LIKE ",
328                                         &concat );
329                 }
330                         
331                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
332                         "setting '%s' as default\n",
333                         si->children_cond.bv_val, 0, 0 );
334         }
335
336         if ( si->oc_query == NULL ) {
337                 if ( BACKSQL_CREATE_NEEDS_SELECT( si ) ) {
338                         si->oc_query =
339                                 ch_strdup( backsql_def_needs_select_oc_query );
340
341                 } else {
342                         si->oc_query = ch_strdup( backsql_def_oc_query );
343                 }
344
345                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
346                         "objectclass mapping SQL statement not specified "
347                         "(use \"oc_query\" directive in slapd.conf)\n", 
348                         0, 0, 0 );
349                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
350                         "setting '%s' by default\n", si->oc_query, 0, 0 );
351         }
352         
353         if ( si->at_query == NULL ) {
354                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
355                         "attribute mapping SQL statement not specified "
356                         "(use \"at_query\" directive in slapd.conf)\n",
357                         0, 0, 0 );
358                 Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
359                         "setting '%s' by default\n",
360                         backsql_def_at_query, 0, 0 );
361                 si->at_query = ch_strdup( backsql_def_at_query );
362         }
363         
364         if ( si->insentry_query == NULL ) {
365                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
366                         "entry insertion SQL statement not specified "
367                         "(use \"insentry_query\" directive in slapd.conf)\n",
368                         0, 0, 0 );
369                 Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
370                         "setting '%s' by default\n",
371                         backsql_def_insentry_query, 0, 0 );
372                 si->insentry_query = ch_strdup( backsql_def_insentry_query );
373         }
374         
375         if ( si->delentry_query == NULL ) {
376                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
377                         "entry deletion SQL statement not specified "
378                         "(use \"delentry_query\" directive in slapd.conf)\n",
379                         0, 0, 0 );
380                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
381                         "setting '%s' by default\n",
382                         backsql_def_delentry_query, 0, 0 );
383                 si->delentry_query = ch_strdup( backsql_def_delentry_query );
384         }
385
386
387         tmp.c_connid =- 1;
388         if ( backsql_get_db_conn( bd, &tmp, &dbh ) != LDAP_SUCCESS ) {
389                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
390                         "connection failed, exiting\n", 0, 0, 0 );
391                 return 1;
392         }
393
394         /*
395          * Prepare ID selection query
396          */
397         si->id_query = NULL;
398         idq_len = 0;
399
400         bv.bv_val = NULL;
401         bv.bv_len = 0;
402         if ( si->upper_func.bv_val == NULL ) {
403                 backsql_strcat( &bv, &idq_len, backsql_id_query, 
404                                 "dn=?", NULL );
405         } else {
406                 if ( BACKSQL_HAS_LDAPINFO_DN_RU( si ) ) {
407                         backsql_strcat( &bv, &idq_len, backsql_id_query,
408                                         "dn_ru=?", NULL );
409                 } else {
410                         if ( BACKSQL_USE_REVERSE_DN( si ) ) {
411                                 backsql_strfcat( &bv, &idq_len, "sbl",
412                                                 backsql_id_query,
413                                                 &si->upper_func, 
414                                                 (ber_len_t)sizeof( "(dn)=?" ) - 1, "(dn)=?" );
415                         } else {
416                                 backsql_strfcat( &bv, &idq_len, "sblbcb",
417                                                 backsql_id_query,
418                                                 &si->upper_func, 
419                                                 (ber_len_t)sizeof( "(dn)=" ) - 1, "(dn)=",
420                                                 &si->upper_func_open, 
421                                                 '?', 
422                                                 &si->upper_func_close );
423                         }
424                 }
425         }
426         si->id_query = bv.bv_val;
427
428         /*
429          * Prepare children ID selection query
430          */
431         si->has_children_query = NULL;
432         idq_len = 0;
433
434         bv.bv_val = NULL;
435         bv.bv_len = 0;
436         backsql_strfcat( &bv, &idq_len, "sb", 
437                         "select count(*) from ldap_entries where ",
438                         &si->children_cond );
439         si->has_children_query = bv.bv_val;
440  
441         backsql_free_db_conn( bd, &tmp );
442         if ( !BACKSQL_SCHEMA_LOADED( si ) ) {
443                 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
444                         "test failed, schema map not loaded - exiting\n",
445                         0, 0, 0 );
446                 return 1;
447         }
448         
449         Debug( LDAP_DEBUG_TRACE, "<==backsql_db_open(): "
450                 "test succeeded, schema map loaded\n", 0, 0, 0 );
451         return 0;
452 }
453
454 int
455 backsql_db_close(
456         BackendDB       *bd )
457 {
458         Debug( LDAP_DEBUG_TRACE, "==>backsql_db_close()\n", 0, 0, 0 );
459         Debug( LDAP_DEBUG_TRACE, "<==backsql_db_close()\n", 0, 0, 0 );
460         return 0;
461 }
462
463 int
464 backsql_connection_destroy(
465         BackendDB       *be,
466         Connection      *conn )
467 {
468         Debug( LDAP_DEBUG_TRACE, "==>backsql_connection_destroy()\n", 0, 0, 0 );
469         backsql_free_db_conn( be, conn );
470         Debug( LDAP_DEBUG_TRACE, "<==backsql_connection_destroy()\n", 0, 0, 0 );
471         return 0;
472 }
473
474 #endif /* SLAPD_SQL */
475