]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/config.c
Move CSN invocations to backends
[openldap] / servers / slapd / back-sql / config.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2005 The OpenLDAP Foundation.
5  * Portions Copyright 1999 Dmitry Kovalev.
6  * Portions Copyright 2002 Pierangelo Masarati.
7  * Portions Copyright 2004 Mark Adamson.
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 "ac/string.h"
28 #include <sys/types.h>
29
30 #include "slap.h"
31 #include "ldif.h"
32 #include "proto-sql.h"
33
34 static int
35 create_baseObject(
36         BackendDB       *be,
37         const char      *fname,
38         int             lineno );
39
40 static int
41 read_baseObject(
42         BackendDB       *be,
43         const char      *fname );
44
45 int
46 backsql_db_config(
47         BackendDB       *be,
48         const char      *fname,
49         int             lineno,
50         int             argc,
51         char            **argv )
52 {
53         backsql_info    *bi = (backsql_info *)be->be_private;
54
55         Debug( LDAP_DEBUG_TRACE, "==>backsql_db_config()\n", 0, 0, 0 );
56         assert( bi != NULL );
57   
58         if ( !strcasecmp( argv[ 0 ], "dbhost" ) ) {
59                 if ( argc < 2 ) {
60                         Debug( LDAP_DEBUG_TRACE, 
61                                 "<==backsql_db_config (%s line %d): "
62                                 "missing hostname in \"dbhost\" directive\n",
63                                 fname, lineno, 0 );
64                         return 1;
65                 }
66                 bi->sql_dbhost = ch_strdup( argv[ 1 ] );
67                 Debug( LDAP_DEBUG_TRACE,
68                         "<==backsql_db_config(): hostname=%s\n",
69                         bi->sql_dbhost, 0, 0 );
70
71         } else if ( !strcasecmp( argv[ 0 ], "dbuser" ) ) {
72                 if ( argc < 2 ) {
73                         Debug( LDAP_DEBUG_TRACE, 
74                                 "<==backsql_db_config (%s line %d): "
75                                 "missing username in \"dbuser\" directive\n",
76                                 fname, lineno, 0 );
77                         return 1;
78                 }
79                 bi->sql_dbuser = ch_strdup( argv[ 1 ] );
80                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbuser=%s\n",
81                         bi->sql_dbuser, 0, 0 );
82
83         } else if ( !strcasecmp( argv[ 0 ], "dbpasswd" ) ) {
84                 if ( argc < 2 ) {
85                         Debug( LDAP_DEBUG_TRACE, 
86                                 "<==backsql_db_config (%s line %d): "
87                                 "missing password in \"dbpasswd\" directive\n",
88                                 fname, lineno, 0 );
89                         return 1;
90                 }
91                 bi->sql_dbpasswd = ch_strdup( argv[ 1 ] );
92                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
93                         "dbpasswd=%s\n", /* bi->sql_dbpasswd */ "xxxx", 0, 0 );
94
95         } else if ( !strcasecmp( argv[ 0 ], "dbname" ) ) {
96                 if ( argc < 2 ) {
97                         Debug( LDAP_DEBUG_TRACE, 
98                                 "<==backsql_db_config (%s line %d): "
99                                 "missing database name in \"dbname\" "
100                                 "directive\n", fname, lineno, 0 );
101                         return 1;
102                 }
103                 bi->sql_dbname = ch_strdup( argv[ 1 ] );
104                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbname=%s\n",
105                         bi->sql_dbname, 0, 0 );
106
107         } else if ( !strcasecmp( argv[ 0 ], "concat_pattern" ) ) {
108                 if ( argc < 2 ) {
109                         Debug( LDAP_DEBUG_TRACE, 
110                                 "<==backsql_db_config (%s line %d): "
111                                 "missing pattern"
112                                 "in \"concat_pattern\" directive\n",
113                                 fname, lineno, 0 );
114                         return 1;
115                 }
116                 if ( backsql_split_pattern( argv[ 1 ], &bi->sql_concat_func, 2 ) ) {
117                         Debug( LDAP_DEBUG_TRACE, 
118                                 "<==backsql_db_config (%s line %d): "
119                                 "unable to parse pattern \"%s\"\n"
120                                 "in \"concat_pattern\" directive\n",
121                                 fname, lineno, argv[ 1 ] );
122                         return 1;
123                 }
124                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
125                         "concat_pattern=\"%s\"\n", argv[ 1 ], 0, 0 );
126
127         } else if ( !strcasecmp( argv[ 0 ], "subtree_cond" ) ) {
128                 if ( argc < 2 ) {
129                         Debug( LDAP_DEBUG_TRACE, 
130                                 "<==backsql_db_config (%s line %d): "
131                                 "missing SQL condition "
132                                 "in \"subtree_cond\" directive\n",
133                                 fname, lineno, 0 );
134                         return 1;
135                 }
136                 ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_subtree_cond );
137                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
138                         "subtree_cond=%s\n", bi->sql_subtree_cond.bv_val, 0, 0 );
139
140         } else if ( !strcasecmp( argv[ 0 ], "children_cond" ) ) {
141                 if ( argc < 2 ) {
142                         Debug( LDAP_DEBUG_TRACE, 
143                                 "<==backsql_db_config (%s line %d): "
144                                 "missing SQL condition "
145                                 "in \"children_cond\" directive\n",
146                                 fname, lineno, 0 );
147                         return 1;
148                 }
149                 ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_children_cond );
150                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
151                         "subtree_cond=%s\n", bi->sql_children_cond.bv_val, 0, 0 );
152
153         } else if ( !strcasecmp( argv[ 0 ], "oc_query" ) ) {
154                 if ( argc < 2 ) {
155                         Debug( LDAP_DEBUG_TRACE, 
156                                 "<==backsql_db_config (%s line %d): "
157                                 "missing SQL statement "
158                                 "in \"oc_query\" directive\n",
159                                 fname, lineno, 0 );
160                         return 1;
161                 }
162                 bi->sql_oc_query = ch_strdup( argv[ 1 ] );
163                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
164                         "oc_query=%s\n", bi->sql_oc_query, 0, 0 );
165
166         } else if ( !strcasecmp( argv[ 0 ], "at_query" ) ) {
167                 if ( argc < 2 ) {
168                         Debug( LDAP_DEBUG_TRACE,
169                                 "<==backsql_db_config (%s line %d): "
170                                 "missing SQL statement "
171                                 "in \"at_query\" directive\n",
172                                 fname, lineno, 0 );
173                         return 1;
174                 }
175                 bi->sql_at_query = ch_strdup( argv[ 1 ] );
176                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
177                         "at_query=%s\n", bi->sql_at_query, 0, 0 );
178
179         } else if ( !strcasecmp( argv[ 0 ], "insentry_stmt" ) ||
180                         !strcasecmp( argv[ 0 ], "insentry_query" ) )
181         {
182                 if ( argc < 2 ) {
183                         Debug( LDAP_DEBUG_TRACE, 
184                                 "<==backsql_db_config (%s line %d): "
185                                 "missing SQL statement "
186                                 "in \"insentry_stmt\" directive\n",
187                                 fname, lineno, 0 );
188                         return 1;
189                 }
190                 bi->sql_insentry_stmt = ch_strdup( argv[ 1 ] );
191                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
192                         "insentry_stmt=%s\n", bi->sql_insentry_stmt, 0, 0 );
193
194         } else if ( !strcasecmp( argv[ 0 ], "create_needs_select" ) ) {
195                 if ( argc < 2 ) {
196                         Debug( LDAP_DEBUG_TRACE,
197                                 "<==backsql_db_config (%s line %d): "
198                                 "missing { yes | no }"
199                                 "in \"create_needs_select\" directive\n",
200                                 fname, lineno, 0 );
201                         return 1;
202                 }
203
204                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
205                         bi->sql_flags |= BSQLF_CREATE_NEEDS_SELECT;
206
207                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
208                         bi->sql_flags &= ~BSQLF_CREATE_NEEDS_SELECT;
209
210                 } else {
211                         Debug( LDAP_DEBUG_TRACE,
212                                 "<==backsql_db_config (%s line %d): "
213                                 "\"create_needs_select\" directive arg "
214                                 "must be \"yes\" or \"no\"\n",
215                                 fname, lineno, 0 );
216                         return 1;
217
218                 }
219                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
220                         "create_needs_select =%s\n", 
221                         BACKSQL_CREATE_NEEDS_SELECT( bi ) ? "yes" : "no",
222                         0, 0 );
223
224         } else if ( !strcasecmp( argv[ 0 ], "upper_func" ) ) {
225                 if ( argc < 2 ) {
226                         Debug( LDAP_DEBUG_TRACE,
227                                 "<==backsql_db_config (%s line %d): "
228                                 "missing function name "
229                                 "in \"upper_func\" directive\n",
230                                 fname, lineno, 0 );
231                         return 1;
232                 }
233                 ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_upper_func );
234                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
235                         "upper_func=%s\n", bi->sql_upper_func.bv_val, 0, 0 );
236
237         } else if ( !strcasecmp( argv[ 0 ], "upper_needs_cast" ) ) {
238                 if ( argc < 2 ) {
239                         Debug( LDAP_DEBUG_TRACE,
240                                 "<==backsql_db_config (%s line %d): "
241                                 "missing { yes | no }"
242                                 "in \"upper_needs_cast\" directive\n",
243                                 fname, lineno, 0 );
244                         return 1;
245                 }
246
247                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
248                         bi->sql_flags |= BSQLF_UPPER_NEEDS_CAST;
249
250                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
251                         bi->sql_flags &= ~BSQLF_UPPER_NEEDS_CAST;
252
253                 } else {
254                         Debug( LDAP_DEBUG_TRACE,
255                                 "<==backsql_db_config (%s line %d): "
256                                 "\"upper_needs_cast\" directive arg "
257                                 "must be \"yes\" or \"no\"\n",
258                                 fname, lineno, 0 );
259                         return 1;
260
261                 }
262                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
263                         "upper_needs_cast =%s\n", 
264                         BACKSQL_UPPER_NEEDS_CAST( bi ) ? "yes" : "no", 0, 0 );
265
266         } else if ( !strcasecmp( argv[ 0 ], "strcast_func" ) ) {
267                 if ( argc < 2 ) {
268                         Debug( LDAP_DEBUG_TRACE,
269                                 "<==backsql_db_config (%s line %d): "
270                                 "missing function name "
271                                 "in \"strcast_func\" directive\n",
272                                 fname, lineno, 0 );
273                         return 1;
274                 }
275                 ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_strcast_func );
276                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
277                         "strcast_func=%s\n", bi->sql_strcast_func.bv_val, 0, 0 );
278
279         } else if ( !strcasecmp( argv[ 0 ], "delentry_stmt" ) ||
280                         !strcasecmp( argv[ 0 ], "delentry_query" ) )
281         {
282                 if ( argc < 2 ) {
283                         Debug( LDAP_DEBUG_TRACE,
284                                 "<==backsql_db_config (%s line %d): "
285                                 "missing SQL statement "
286                                 "in \"delentry_stmt\" directive\n",
287                                 fname, lineno, 0 );
288                         return 1;
289                 }
290                 bi->sql_delentry_stmt = ch_strdup( argv[ 1 ] );
291                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
292                         "delentry_stmt=%s\n", bi->sql_delentry_stmt, 0, 0 );
293
294         } else if ( !strcasecmp( argv[ 0 ], "renentry_stmt" ) ||
295                         !strcasecmp( argv[ 0 ], "renentry_query" ) )
296         {
297                 if ( argc < 2 ) {
298                         Debug( LDAP_DEBUG_TRACE,
299                                 "<==backsql_db_config (%s line %d): "
300                                 "missing SQL statement "
301                                 "in \"renentry_stmt\" directive\n",
302                                 fname, lineno, 0 );
303                         return 1;
304                 }
305                 bi->sql_renentry_stmt = ch_strdup( argv[ 1 ] );
306                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
307                         "renentry_stmt=%s\n", bi->sql_renentry_stmt, 0, 0 );
308
309         } else if ( !strcasecmp( argv[ 0 ], "delobjclasses_stmt" ) ||
310                         !strcasecmp( argv[ 0 ], "delobjclasses_query" ) )
311         {
312                 if ( argc < 2 ) {
313                         Debug( LDAP_DEBUG_TRACE,
314                                 "<==backsql_db_config (%s line %d): "
315                                 "missing SQL statement "
316                                 "in \"delobjclasses_stmt\" directive\n",
317                                 fname, lineno, 0 );
318                         return 1;
319                 }
320                 bi->sql_delobjclasses_stmt = ch_strdup( argv[ 1 ] );
321                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
322                         "delobjclasses_stmt=%s\n", bi->sql_delobjclasses_stmt, 0, 0 );
323
324         } else if ( !strcasecmp( argv[ 0 ], "has_ldapinfo_dn_ru" ) ) {
325                 if ( argc < 2 ) {
326                         Debug( LDAP_DEBUG_TRACE,
327                                 "<==backsql_db_config (%s line %d): "
328                                 "missing { yes | no }"
329                                 "in \"has_ldapinfo_dn_ru\" directive\n",
330                                 fname, lineno, 0 );
331                         return 1;
332                 }
333
334                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
335                         bi->sql_flags |= BSQLF_HAS_LDAPINFO_DN_RU;
336                         bi->sql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU;
337
338                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
339                         bi->sql_flags &= ~BSQLF_HAS_LDAPINFO_DN_RU;
340                         bi->sql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU;
341
342                 } else {
343                         Debug( LDAP_DEBUG_TRACE,
344                                 "<==backsql_db_config (%s line %d): "
345                                 "\"has_ldapinfo_dn_ru\" directive arg "
346                                 "must be \"yes\" or \"no\"\n",
347                                 fname, lineno, 0 );
348                         return 1;
349
350                 }
351                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
352                         "has_ldapinfo_dn_ru=%s\n", 
353                         BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ? "yes" : "no", 0, 0 );
354
355         } else if ( !strcasecmp( argv[ 0 ], "fail_if_no_mapping" ) ) {
356                 if ( argc < 2 ) {
357                         Debug( LDAP_DEBUG_TRACE,
358                                 "<==backsql_db_config (%s line %d): "
359                                 "missing { yes | no }"
360                                 "in \"fail_if_no_mapping\" directive\n",
361                                 fname, lineno, 0 );
362                         return 1;
363                 }
364
365                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
366                         bi->sql_flags |= BSQLF_FAIL_IF_NO_MAPPING;
367
368                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
369                         bi->sql_flags &= ~BSQLF_FAIL_IF_NO_MAPPING;
370
371                 } else {
372                         Debug( LDAP_DEBUG_TRACE,
373                                 "<==backsql_db_config (%s line %d): "
374                                 "\"fail_if_no_mapping\" directive arg "
375                                 "must be \"yes\" or \"no\"\n",
376                                 fname, lineno, 0 );
377                         return 1;
378
379                 }
380                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
381                         "fail_if_no_mapping=%s\n", 
382                         BACKSQL_FAIL_IF_NO_MAPPING( bi ) ? "yes" : "no", 0, 0 );
383
384         } else if ( !strcasecmp( argv[ 0 ], "allow_orphans" ) ) {
385                 if ( argc < 2 ) {
386                         Debug( LDAP_DEBUG_TRACE,
387                                 "<==backsql_db_config (%s line %d): "
388                                 "missing { yes | no }"
389                                 "in \"allow_orphans\" directive\n",
390                                 fname, lineno, 0 );
391                         return 1;
392                 }
393
394                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
395                         bi->sql_flags |= BSQLF_ALLOW_ORPHANS;
396
397                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
398                         bi->sql_flags &= ~BSQLF_ALLOW_ORPHANS;
399
400                 } else {
401                         Debug( LDAP_DEBUG_TRACE,
402                                 "<==backsql_db_config (%s line %d): "
403                                 "\"allow_orphans\" directive arg "
404                                 "must be \"yes\" or \"no\"\n",
405                                 fname, lineno, 0 );
406                         return 1;
407
408                 }
409                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
410                         "allow_orphans=%s\n", 
411                         BACKSQL_ALLOW_ORPHANS( bi ) ? "yes" : "no", 0, 0 );
412
413         } else if ( !strcasecmp( argv[ 0 ], "baseobject" ) ) {
414                 if ( be->be_suffix == NULL ) {
415                         Debug( LDAP_DEBUG_TRACE,
416                                 "<==backsql_db_config (%s line %d): : "
417                                 "must be defined after \"suffix\"\n",
418                                 fname, lineno, 0 );
419                         return 1;
420                 }
421
422                 if ( bi->sql_baseObject ) {
423                         Debug( LDAP_DEBUG_TRACE,
424                                 "<==backsql_db_config (%s line %d): : "
425                                 "\"baseObject\" already provided (will be overwritten)\n",
426                                 fname, lineno, 0 );
427                         entry_free( bi->sql_baseObject );
428                 }
429         
430                 switch ( argc ) {
431                 case 1:
432                         return create_baseObject( be, fname, lineno );
433
434                 case 2:
435                         return read_baseObject( be, argv[ 1 ] );
436
437                 default:
438                         Debug( LDAP_DEBUG_TRACE,
439                                 "<==backsql_db_config (%s line %d): "
440                                 "trailing values "
441                                 "in \"baseObject\" directive?\n",
442                                 fname, lineno, 0 );
443                         return 1;
444                 }
445
446         } else if ( !strcasecmp( argv[ 0 ], "sqllayer" ) ) {
447                 if ( backsql_api_config( bi, argv[ 1 ], argc - 2, &argv[ 2 ] ) )
448                 {
449                         Debug( LDAP_DEBUG_TRACE,
450                                 "<==backsql_db_config (%s line %d): "
451                                 "unable to load sqllayer \"%s\"\n",
452                                 fname, lineno, argv[ 1 ] );
453                         return 1;
454                 }
455
456         } else if ( !strcasecmp( argv[ 0 ], "id_query" ) ) {
457                 if ( argc < 2 ) {
458                         Debug( LDAP_DEBUG_TRACE, 
459                                 "<==backsql_db_config (%s line %d): "
460                                 "missing SQL condition "
461                                 "in \"id_query\" directive\n",
462                                 fname, lineno, 0 );
463                         return 1;
464                 }
465                 bi->sql_id_query = ch_strdup( argv[ 1 ] );
466                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
467                         "id_query=%s\n", bi->sql_id_query, 0, 0 );
468
469         } else if ( !strcasecmp( argv[ 0 ], "use_subtree_shortcut" ) ) {
470                 if ( argc < 2 ) {
471                         Debug( LDAP_DEBUG_TRACE,
472                                 "<==backsql_db_config (%s line %d): "
473                                 "missing { yes | no }"
474                                 "in \"use_subtree_shortcut\" directive\n",
475                                 fname, lineno, 0 );
476                         return 1;
477                 }
478
479                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
480                         bi->sql_flags |= BSQLF_USE_SUBTREE_SHORTCUT;
481
482                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
483                         bi->sql_flags &= ~BSQLF_USE_SUBTREE_SHORTCUT;
484
485                 } else {
486                         Debug( LDAP_DEBUG_TRACE,
487                                 "<==backsql_db_config (%s line %d): "
488                                 "\"use_subtree_shortcut\" directive arg "
489                                 "must be \"yes\" or \"no\"\n",
490                                 fname, lineno, 0 );
491                         return 1;
492
493                 }
494                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
495                         "use_subtree_shortcut=%s\n", 
496                         BACKSQL_USE_SUBTREE_SHORTCUT( bi ) ? "yes" : "no",
497                         0, 0 );
498
499         } else if ( !strcasecmp( argv[ 0 ], "fetch_all_attrs" ) ) {
500                 if ( argc < 2 ) {
501                         Debug( LDAP_DEBUG_TRACE,
502                                 "<==backsql_db_config (%s line %d): "
503                                 "missing { yes | no }"
504                                 "in \"fetch_all_attrs\" directive\n",
505                                 fname, lineno, 0 );
506                         return 1;
507                 }
508
509                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
510                         bi->sql_flags |= BSQLF_FETCH_ALL_ATTRS;
511
512                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
513                         bi->sql_flags &= ~BSQLF_FETCH_ALL_ATTRS;
514
515                 } else {
516                         Debug( LDAP_DEBUG_TRACE,
517                                 "<==backsql_db_config (%s line %d): "
518                                 "\"fetch_all_attrs\" directive arg "
519                                 "must be \"yes\" or \"no\"\n",
520                                 fname, lineno, 0 );
521                         return 1;
522
523                 }
524                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
525                         "fetch_all_attrs=%s\n", 
526                         BACKSQL_FETCH_ALL_ATTRS( bi ) ? "yes" : "no",
527                         0, 0 );
528
529         } else if ( !strcasecmp( argv[ 0 ], "fetch_attrs" ) ) {
530                 char    *str, *s, *next;
531                 char    delimstr[] = ",";
532
533                 if ( argc < 2 ) {
534                         Debug( LDAP_DEBUG_TRACE,
535                                 "<==backsql_db_config (%s line %d): "
536                                 "missing <attrlist>"
537                                 "in \"fetch_all_attrs <attrlist>\" directive\n",
538                                 fname, lineno, 0 );
539                         return 1;
540                 }
541
542                 str = ch_strdup( argv[ 1 ] );
543                 for ( s = ldap_pvt_strtok( str, delimstr, &next );
544                                 s != NULL;
545                                 s = ldap_pvt_strtok( NULL, delimstr, &next ) )
546                 {
547                         if ( strlen( s ) == 1 ) {
548                                 if ( *s == '*' ) {
549                                         bi->sql_flags |= BSQLF_FETCH_ALL_USERATTRS;
550                                         argv[ 1 ][ s - str ] = ',';
551
552                                 } else if ( *s == '+' ) {
553                                         bi->sql_flags |= BSQLF_FETCH_ALL_OPATTRS;
554                                         argv[ 1 ][ s - str ] = ',';
555                                 }
556                         }
557                 }
558                 ch_free( str );
559                 bi->sql_anlist = str2anlist( bi->sql_anlist, argv[ 1 ], delimstr );
560                 if ( bi->sql_anlist == NULL ) {
561                         return -1;
562                 }
563
564         } else if ( !strcasecmp( argv[ 0 ], "check_schema" ) ) {
565                 if ( argc != 2 ) {
566                         Debug( LDAP_DEBUG_TRACE,
567                                 "<==backsql_db_config (%s line %d): "
568                                 "missing { yes | no }"
569                                 "in \"check_schema\" directive\n",
570                                 fname, lineno, 0 );
571                         return 1;
572                 }
573
574                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
575                         bi->sql_flags |= BSQLF_CHECK_SCHEMA;
576
577                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
578                         bi->sql_flags &= ~BSQLF_CHECK_SCHEMA;
579
580                 } else {
581                         Debug( LDAP_DEBUG_TRACE,
582                                 "<==backsql_db_config (%s line %d): "
583                                 "\"check_schema\" directive arg "
584                                 "must be \"yes\" or \"no\"\n",
585                                 fname, lineno, 0 );
586                         return 1;
587
588                 }
589                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
590                         "check_schema=%s\n", 
591                         BACKSQL_CHECK_SCHEMA( bi ) ? "yes" : "no",
592                         0, 0 );
593
594         } else if ( !strcasecmp( argv[ 0 ], "aliasing_keyword" ) ) {
595                 if ( argc != 2 ) {
596                         Debug( LDAP_DEBUG_TRACE,
597                                 "<==backsql_db_config (%s line %d): "
598                                 "missing arg "
599                                 "in \"aliasing_keyword <string>\" directive\n",
600                                 fname, lineno, 0 );
601                         return 1;
602                 }
603
604                 if ( ! BER_BVISNULL( &bi->sql_aliasing ) ) {
605                         ch_free( bi->sql_aliasing.bv_val );
606                 }
607
608                 ber_str2bv( argv[ 1 ], strlen( argv[ 1 ] ) + 1, 1,
609                         &bi->sql_aliasing );
610                 /* add a trailing space... */
611                 bi->sql_aliasing.bv_val[ bi->sql_aliasing.bv_len - 1] = ' ';
612
613         } else if ( !strcasecmp( argv[ 0 ], "aliasing_quote" ) ) {
614                 if ( argc != 2 ) {
615                         Debug( LDAP_DEBUG_TRACE,
616                                 "<==backsql_db_config (%s line %d): "
617                                 "missing arg "
618                                 "in \"aliasing_quote <string>\" directive\n",
619                                 fname, lineno, 0 );
620                         return 1;
621                 }
622
623                 if ( ! BER_BVISNULL( &bi->sql_aliasing_quote ) ) {
624                         ch_free( bi->sql_aliasing_quote.bv_val );
625                 }
626
627                 ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_aliasing_quote );
628
629         } else {
630                 return SLAP_CONF_UNKNOWN;
631         }
632
633         return 0;
634 }
635
636 /*
637  * Read the entries specified in fname and merge the attributes
638  * to the user defined baseObject entry. Note that if we find any errors
639  * what so ever, we will discard the entire entries, print an
640  * error message and return.
641  */
642 static int
643 read_baseObject( 
644         BackendDB       *be,
645         const char      *fname )
646 {
647         backsql_info    *bi = (backsql_info *)be->be_private;
648         LDIFFP          *fp;
649         int             rc = 0, lineno = 0, lmax = 0;
650         char            *buf = NULL;
651
652         assert( fname != NULL );
653
654         fp = ldif_open( fname, "r" );
655         if ( fp == NULL ) {
656                 Debug( LDAP_DEBUG_ANY,
657                         "could not open back-sql baseObject "
658                         "attr file \"%s\" - absolute path?\n",
659                         fname, 0, 0 );
660                 perror( fname );
661                 return LDAP_OTHER;
662         }
663
664         bi->sql_baseObject = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) );
665         if ( bi->sql_baseObject == NULL ) {
666                 Debug( LDAP_DEBUG_ANY,
667                         "read_baseObject_file: SLAP_CALLOC failed", 0, 0, 0 );
668                 ldif_close( fp );
669                 return LDAP_NO_MEMORY;
670         }
671         bi->sql_baseObject->e_name = be->be_suffix[0];
672         bi->sql_baseObject->e_nname = be->be_nsuffix[0];
673         bi->sql_baseObject->e_attrs = NULL;
674
675         while ( ldif_read_record( fp, &lineno, &buf, &lmax ) ) {
676                 Entry           *e = str2entry( buf );
677                 Attribute       *a;
678
679                 if( e == NULL ) {
680                         fprintf( stderr, "back-sql baseObject: "
681                                         "could not parse entry (line=%d)\n",
682                                         lineno );
683                         rc = LDAP_OTHER;
684                         break;
685                 }
686
687                 /* make sure the DN is the database's suffix */
688                 if ( !be_issuffix( be, &e->e_nname ) ) {
689                         fprintf( stderr,
690                                 "back-sql: invalid baseObject - "
691                                 "dn=\"%s\" (line=%d)\n",
692                                 e->e_name.bv_val, lineno );
693                         entry_free( e );
694                         rc = EXIT_FAILURE;
695                         break;
696                 }
697
698                 /*
699                  * we found a valid entry, so walk thru all the attributes in the
700                  * entry, and add each attribute type and description to baseObject
701                  */
702                 for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
703                         if ( attr_merge( bi->sql_baseObject, a->a_desc,
704                                                 a->a_vals,
705                                                 ( a->a_nvals == a->a_vals ) ?
706                                                 NULL : a->a_nvals ) )
707                         {
708                                 rc = LDAP_OTHER;
709                                 break;
710                         }
711                 }
712
713                 entry_free( e );
714                 if ( rc ) {
715                         break;
716                 }
717         }
718
719         if ( rc ) {
720                 entry_free( bi->sql_baseObject );
721                 bi->sql_baseObject = NULL;
722         }
723
724         ch_free( buf );
725
726         ldif_close( fp );
727
728         Debug( LDAP_DEBUG_CONFIG, "back-sql baseObject file \"%s\" read.\n",
729                         fname, 0, 0 );
730
731         return rc;
732 }
733
734 static int
735 create_baseObject(
736         BackendDB       *be,
737         const char      *fname,
738         int             lineno )
739 {
740         backsql_info    *bi = (backsql_info *)be->be_private;
741         LDAPRDN         rdn;
742         char            *p;
743         int             rc, iAVA;
744         char            buf[1024];
745
746         snprintf( buf, sizeof(buf),
747                         "dn: %s\n"
748                         "objectClass: extensibleObject\n"
749                         "description: builtin baseObject for back-sql\n"
750                         "description: all entries mapped "
751                         "in the \"ldap_entries\" table\n"
752                         "description: must have "
753                         "\"" BACKSQL_BASEOBJECT_IDSTR "\" "
754                         "in the \"parent\" column",
755                         be->be_suffix[0].bv_val );
756
757         bi->sql_baseObject = str2entry( buf );
758         if ( bi->sql_baseObject == NULL ) {
759                 Debug( LDAP_DEBUG_TRACE,
760                         "<==backsql_db_config (%s line %d): "
761                         "unable to parse baseObject entry\n",
762                         fname, lineno, 0 );
763                 return 1;
764         }
765
766         if ( BER_BVISEMPTY( &be->be_suffix[ 0 ] ) ) {
767                 return 0;
768         }
769
770         rc = ldap_bv2rdn( &be->be_suffix[ 0 ], &rdn, (char **)&p,
771                         LDAP_DN_FORMAT_LDAP );
772         if ( rc != LDAP_SUCCESS ) {
773                 snprintf( buf, sizeof(buf),
774                         "unable to extract RDN "
775                         "from baseObject DN \"%s\" (%d: %s)",
776                         be->be_suffix[ 0 ].bv_val,
777                         rc, ldap_err2string( rc ) );
778                 Debug( LDAP_DEBUG_TRACE,
779                         "<==backsql_db_config (%s line %d): %s\n",
780                         fname, lineno, buf );
781                 return 1;
782         }
783
784         for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
785                 LDAPAVA                         *ava = rdn[ iAVA ];
786                 AttributeDescription            *ad = NULL;
787                 slap_syntax_transform_func      *transf = NULL;
788                 struct berval                   bv = BER_BVNULL;
789                 const char                      *text = NULL;
790
791                 assert( ava != NULL );
792
793                 rc = slap_bv2ad( &ava->la_attr, &ad, &text );
794                 if ( rc != LDAP_SUCCESS ) {
795                         snprintf( buf, sizeof(buf),
796                                 "AttributeDescription of naming "
797                                 "attribute #%d from baseObject "
798                                 "DN \"%s\": %d: %s",
799                                 iAVA, be->be_suffix[ 0 ].bv_val,
800                                 rc, ldap_err2string( rc ) );
801                         Debug( LDAP_DEBUG_TRACE,
802                                 "<==backsql_db_config (%s line %d): %s\n",
803                                 fname, lineno, buf );
804                         return 1;
805                 }
806                 
807                 transf = ad->ad_type->sat_syntax->ssyn_pretty;
808                 if ( transf ) {
809                         /*
810                          * transform value by pretty function
811                          *      if value is empty, use empty_bv
812                          */
813                         rc = ( *transf )( ad->ad_type->sat_syntax,
814                                 ava->la_value.bv_len
815                                         ? &ava->la_value
816                                         : (struct berval *) &slap_empty_bv,
817                                 &bv, NULL );
818         
819                         if ( rc != LDAP_SUCCESS ) {
820                                 snprintf( buf, sizeof(buf),
821                                         "prettying of attribute #%d "
822                                         "from baseObject "
823                                         "DN \"%s\" failed: %d: %s",
824                                         iAVA, be->be_suffix[ 0 ].bv_val,
825                                         rc, ldap_err2string( rc ) );
826                                 Debug( LDAP_DEBUG_TRACE,
827                                         "<==backsql_db_config (%s line %d): "
828                                         "%s\n",
829                                         fname, lineno, buf );
830                                 return 1;
831                         }
832                 }
833
834                 if ( !BER_BVISNULL( &bv ) ) {
835                         if ( ava->la_flags & LDAP_AVA_FREE_VALUE ) {
836                                 ber_memfree( ava->la_value.bv_val );
837                         }
838                         ava->la_value = bv;
839                         ava->la_flags |= LDAP_AVA_FREE_VALUE;
840                 }
841
842                 attr_merge_normalize_one( bi->sql_baseObject,
843                                 ad, &ava->la_value, NULL );
844         }
845
846         ldap_rdnfree( rdn );
847
848         return 0;
849 }
850