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