]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/config.c
afc0dcf09a40cfec777dfe4805f38eb2ae080055
[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-2004 The OpenLDAP Foundation.
5  * Portions Copyright 1999 Dmitry Kovalev.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* ACKNOWLEDGEMENTS:
17  * This work was initially developed by Dmitry Kovalev for inclusion
18  * by OpenLDAP Software.
19  */
20
21 #include "portable.h"
22
23 #ifdef SLAPD_SQL
24
25 #include <stdio.h>
26 #include "ac/string.h"
27 #include <sys/types.h>
28
29 #include "slap.h"
30 #include "ldif.h"
31 #include "proto-sql.h"
32
33 static int
34 create_baseObject(
35         BackendDB       *be,
36         const char      *fname,
37         int             lineno );
38
39 static int
40 read_baseObject(
41         BackendDB       *be,
42         const char      *fname );
43
44 int
45 backsql_db_config(
46         BackendDB       *be,
47         const char      *fname,
48         int             lineno,
49         int             argc,
50         char            **argv )
51 {
52         backsql_info    *bi = (backsql_info *)be->be_private;
53
54         Debug( LDAP_DEBUG_TRACE, "==>backsql_db_config()\n", 0, 0, 0 );
55         assert( bi );
56   
57         if ( !strcasecmp( argv[ 0 ], "dbhost" ) ) {
58                 if ( argc < 2 ) {
59                         Debug( LDAP_DEBUG_TRACE, 
60                                 "<==backsql_db_config (%s line %d): "
61                                 "missing hostname in \"dbhost\" directive\n",
62                                 fname, lineno, 0 );
63                         return 1;
64                 }
65                 bi->sql_dbhost = ch_strdup( argv[ 1 ] );
66                 Debug( LDAP_DEBUG_TRACE,
67                         "<==backsql_db_config(): hostname=%s\n",
68                         bi->sql_dbhost, 0, 0 );
69
70         } else if ( !strcasecmp( argv[ 0 ], "dbuser" ) ) {
71                 if ( argc < 2 ) {
72                         Debug( LDAP_DEBUG_TRACE, 
73                                 "<==backsql_db_config (%s line %d): "
74                                 "missing username in \"dbuser\" directive\n",
75                                 fname, lineno, 0 );
76                         return 1;
77                 }
78                 bi->sql_dbuser = ch_strdup( argv[ 1 ] );
79                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbuser=%s\n",
80                         bi->sql_dbuser, 0, 0 );
81
82         } else if ( !strcasecmp( argv[ 0 ], "dbpasswd" ) ) {
83                 if ( argc < 2 ) {
84                         Debug( LDAP_DEBUG_TRACE, 
85                                 "<==backsql_db_config (%s line %d): "
86                                 "missing password in \"dbpasswd\" directive\n",
87                                 fname, lineno, 0 );
88                         return 1;
89                 }
90                 bi->sql_dbpasswd = ch_strdup( argv[ 1 ] );
91                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
92                         "dbpasswd=%s\n", /* bi->sql_dbpasswd */ "xxxx", 0, 0 );
93
94         } else if ( !strcasecmp( argv[ 0 ], "dbname" ) ) {
95                 if ( argc < 2 ) {
96                         Debug( LDAP_DEBUG_TRACE, 
97                                 "<==backsql_db_config (%s line %d): "
98                                 "missing database name in \"dbname\" "
99                                 "directive\n", fname, lineno, 0 );
100                         return 1;
101                 }
102                 bi->sql_dbname = ch_strdup( argv[ 1 ] );
103                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbname=%s\n",
104                         bi->sql_dbname, 0, 0 );
105
106         } else if ( !strcasecmp( argv[ 0 ], "concat_pattern" ) ) {
107                 if ( argc < 2 ) {
108                         Debug( LDAP_DEBUG_TRACE, 
109                                 "<==backsql_db_config (%s line %d): "
110                                 "missing pattern"
111                                 "in \"concat_pattern\" directive\n",
112                                 fname, lineno, 0 );
113                         return 1;
114                 }
115                 if ( backsql_split_pattern( argv[ 1 ], &bi->sql_concat_func, 2 ) ) {
116                         Debug( LDAP_DEBUG_TRACE, 
117                                 "<==backsql_db_config (%s line %d): "
118                                 "unable to parse pattern \"%s\"\n"
119                                 "in \"concat_pattern\" directive\n",
120                                 fname, lineno, argv[ 1 ] );
121                         return 1;
122                 }
123                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
124                         "concat_pattern=\"%s\"\n", argv[ 1 ], 0, 0 );
125
126         } else if ( !strcasecmp( argv[ 0 ], "subtree_cond" ) ) {
127                 if ( argc < 2 ) {
128                         Debug( LDAP_DEBUG_TRACE, 
129                                 "<==backsql_db_config (%s line %d): "
130                                 "missing SQL condition "
131                                 "in \"subtree_cond\" directive\n",
132                                 fname, lineno, 0 );
133                         return 1;
134                 }
135                 ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_subtree_cond );
136                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
137                         "subtree_cond=%s\n", bi->sql_subtree_cond.bv_val, 0, 0 );
138
139         } else if ( !strcasecmp( argv[ 0 ], "children_cond" ) ) {
140                 if ( argc < 2 ) {
141                         Debug( LDAP_DEBUG_TRACE, 
142                                 "<==backsql_db_config (%s line %d): "
143                                 "missing SQL condition "
144                                 "in \"children_cond\" directive\n",
145                                 fname, lineno, 0 );
146                         return 1;
147                 }
148                 ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_children_cond );
149                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
150                         "subtree_cond=%s\n", bi->sql_children_cond.bv_val, 0, 0 );
151
152         } else if ( !strcasecmp( argv[ 0 ], "oc_query" ) ) {
153                 if ( argc < 2 ) {
154                         Debug( LDAP_DEBUG_TRACE, 
155                                 "<==backsql_db_config (%s line %d): "
156                                 "missing SQL statement "
157                                 "in \"oc_query\" directive\n",
158                                 fname, lineno, 0 );
159                         return 1;
160                 }
161                 bi->sql_oc_query = ch_strdup( argv[ 1 ] );
162                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
163                         "oc_query=%s\n", bi->sql_oc_query, 0, 0 );
164
165         } else if ( !strcasecmp( argv[ 0 ], "at_query" ) ) {
166                 if ( argc < 2 ) {
167                         Debug( LDAP_DEBUG_TRACE,
168                                 "<==backsql_db_config (%s line %d): "
169                                 "missing SQL statement "
170                                 "in \"at_query\" directive\n",
171                                 fname, lineno, 0 );
172                         return 1;
173                 }
174                 bi->sql_at_query = ch_strdup( argv[ 1 ] );
175                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
176                         "at_query=%s\n", bi->sql_at_query, 0, 0 );
177
178         } else if ( !strcasecmp( argv[ 0 ], "insentry_query" ) ) {
179                 if ( argc < 2 ) {
180                         Debug( LDAP_DEBUG_TRACE, 
181                                 "<==backsql_db_config (%s line %d): "
182                                 "missing SQL statement "
183                                 "in \"insentry_query\" directive\n",
184                                 fname, lineno, 0 );
185                         return 1;
186                 }
187                 bi->sql_insentry_query = ch_strdup( argv[ 1 ] );
188                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
189                         "insentry_query=%s\n", bi->sql_insentry_query, 0, 0 );
190
191         } else if ( !strcasecmp( argv[ 0 ], "create_needs_select" ) ) {
192                 if ( argc < 2 ) {
193                         Debug( LDAP_DEBUG_TRACE,
194                                 "<==backsql_db_config (%s line %d): "
195                                 "missing { yes | no }"
196                                 "in \"create_needs_select\" directive\n",
197                                 fname, lineno, 0 );
198                         return 1;
199                 }
200
201                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
202                         bi->sql_flags |= BSQLF_CREATE_NEEDS_SELECT;
203
204                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
205                         bi->sql_flags &= ~BSQLF_CREATE_NEEDS_SELECT;
206
207                 } else {
208                         Debug( LDAP_DEBUG_TRACE,
209                                 "<==backsql_db_config (%s line %d): "
210                                 "\"create_needs_select\" directive arg "
211                                 "must be \"yes\" or \"no\"\n",
212                                 fname, lineno, 0 );
213                         return 1;
214
215                 }
216                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
217                         "create_needs_select =%s\n", 
218                         BACKSQL_CREATE_NEEDS_SELECT( bi ) ? "yes" : "no",
219                         0, 0 );
220
221         } else if ( !strcasecmp( argv[ 0 ], "upper_func" ) ) {
222                 if ( argc < 2 ) {
223                         Debug( LDAP_DEBUG_TRACE,
224                                 "<==backsql_db_config (%s line %d): "
225                                 "missing function name "
226                                 "in \"upper_func\" directive\n",
227                                 fname, lineno, 0 );
228                         return 1;
229                 }
230                 ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_upper_func );
231                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
232                         "upper_func=%s\n", bi->sql_upper_func.bv_val, 0, 0 );
233
234         } else if ( !strcasecmp( argv[ 0 ], "upper_needs_cast" ) ) {
235                 if ( argc < 2 ) {
236                         Debug( LDAP_DEBUG_TRACE,
237                                 "<==backsql_db_config (%s line %d): "
238                                 "missing { yes | no }"
239                                 "in \"upper_needs_cast\" directive\n",
240                                 fname, lineno, 0 );
241                         return 1;
242                 }
243
244                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
245                         bi->sql_flags |= BSQLF_UPPER_NEEDS_CAST;
246
247                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
248                         bi->sql_flags &= ~BSQLF_UPPER_NEEDS_CAST;
249
250                 } else {
251                         Debug( LDAP_DEBUG_TRACE,
252                                 "<==backsql_db_config (%s line %d): "
253                                 "\"upper_needs_cast\" directive arg "
254                                 "must be \"yes\" or \"no\"\n",
255                                 fname, lineno, 0 );
256                         return 1;
257
258                 }
259                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
260                         "upper_needs_cast =%s\n", 
261                         BACKSQL_UPPER_NEEDS_CAST( bi ) ? "yes" : "no", 0, 0 );
262
263         } else if ( !strcasecmp( argv[ 0 ], "strcast_func" ) ) {
264                 if ( argc < 2 ) {
265                         Debug( LDAP_DEBUG_TRACE,
266                                 "<==backsql_db_config (%s line %d): "
267                                 "missing function name "
268                                 "in \"strcast_func\" directive\n",
269                                 fname, lineno, 0 );
270                         return 1;
271                 }
272                 ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_strcast_func );
273                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
274                         "strcast_func=%s\n", bi->sql_strcast_func.bv_val, 0, 0 );
275
276         } else if ( !strcasecmp( argv[ 0 ], "delentry_query" ) ) {
277                 if ( argc < 2 ) {
278                         Debug( LDAP_DEBUG_TRACE,
279                                 "<==backsql_db_config (%s line %d): "
280                                 "missing SQL statement "
281                                 "in \"delentry_query\" directive\n",
282                                 fname, lineno, 0 );
283                         return 1;
284                 }
285                 bi->sql_delentry_query = ch_strdup( argv[ 1 ] );
286                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
287                         "delentry_query=%s\n", bi->sql_delentry_query, 0, 0 );
288
289         } else if ( !strcasecmp( argv[ 0 ], "delobjclasses_query" ) ) {
290                 if ( argc < 2 ) {
291                         Debug( LDAP_DEBUG_TRACE,
292                                 "<==backsql_db_config (%s line %d): "
293                                 "missing SQL statement "
294                                 "in \"delobjclasses_query\" directive\n",
295                                 fname, lineno, 0 );
296                         return 1;
297                 }
298                 bi->sql_delobjclasses_query = ch_strdup( argv[ 1 ] );
299                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
300                         "delobjclasses_query=%s\n", bi->sql_delobjclasses_query, 0, 0 );
301
302         } else if ( !strcasecmp( argv[ 0 ], "delreferrals_query" ) ) {
303                 if ( argc < 2 ) {
304                         Debug( LDAP_DEBUG_TRACE,
305                                 "<==backsql_db_config (%s line %d): "
306                                 "missing SQL statement "
307                                 "in \"delreferrals_query\" directive\n",
308                                 fname, lineno, 0 );
309                         return 1;
310                 }
311                 bi->sql_delreferrals_query = ch_strdup( argv[ 1 ] );
312                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
313                         "delreferrals_query=%s\n", bi->sql_delreferrals_query, 0, 0 );
314
315         } else if ( !strcasecmp( argv[ 0 ], "has_ldapinfo_dn_ru") ) {
316                 if ( argc < 2 ) {
317                         Debug( LDAP_DEBUG_TRACE,
318                                 "<==backsql_db_config (%s line %d): "
319                                 "missing { yes | no }"
320                                 "in \"has_ldapinfo_dn_ru\" directive\n",
321                                 fname, lineno, 0 );
322                         return 1;
323                 }
324
325                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
326                         bi->sql_flags |= BSQLF_HAS_LDAPINFO_DN_RU;
327                         bi->sql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU;
328
329                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
330                         bi->sql_flags &= ~BSQLF_HAS_LDAPINFO_DN_RU;
331                         bi->sql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU;
332
333                 } else {
334                         Debug( LDAP_DEBUG_TRACE,
335                                 "<==backsql_db_config (%s line %d): "
336                                 "\"has_ldapinfo_dn_ru\" directive arg "
337                                 "must be \"yes\" or \"no\"\n",
338                                 fname, lineno, 0 );
339                         return 1;
340
341                 }
342                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
343                         "has_ldapinfo_dn_ru=%s\n", 
344                         BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ? "yes" : "no", 0, 0 );
345
346         } else if ( !strcasecmp( argv[ 0 ], "fail_if_no_mapping") ) {
347                 if ( argc < 2 ) {
348                         Debug( LDAP_DEBUG_TRACE,
349                                 "<==backsql_db_config (%s line %d): "
350                                 "missing { yes | no }"
351                                 "in \"fail_if_no_mapping\" directive\n",
352                                 fname, lineno, 0 );
353                         return 1;
354                 }
355
356                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
357                         bi->sql_flags |= BSQLF_FAIL_IF_NO_MAPPING;
358
359                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
360                         bi->sql_flags &= ~BSQLF_FAIL_IF_NO_MAPPING;
361
362                 } else {
363                         Debug( LDAP_DEBUG_TRACE,
364                                 "<==backsql_db_config (%s line %d): "
365                                 "\"fail_if_no_mapping\" directive arg "
366                                 "must be \"yes\" or \"no\"\n",
367                                 fname, lineno, 0 );
368                         return 1;
369
370                 }
371                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
372                         "fail_if_no_mapping=%s\n", 
373                         BACKSQL_FAIL_IF_NO_MAPPING( bi ) ? "yes" : "no", 0, 0 );
374
375         } else if ( !strcasecmp( argv[ 0 ], "allow_orphans") ) {
376                 if ( argc < 2 ) {
377                         Debug( LDAP_DEBUG_TRACE,
378                                 "<==backsql_db_config (%s line %d): "
379                                 "missing { yes | no }"
380                                 "in \"allow_orphans\" directive\n",
381                                 fname, lineno, 0 );
382                         return 1;
383                 }
384
385                 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
386                         bi->sql_flags |= BSQLF_ALLOW_ORPHANS;
387
388                 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
389                         bi->sql_flags &= ~BSQLF_ALLOW_ORPHANS;
390
391                 } else {
392                         Debug( LDAP_DEBUG_TRACE,
393                                 "<==backsql_db_config (%s line %d): "
394                                 "\"allow_orphans\" directive arg "
395                                 "must be \"yes\" or \"no\"\n",
396                                 fname, lineno, 0 );
397                         return 1;
398
399                 }
400                 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
401                         "allow_orphans=%s\n", 
402                         BACKSQL_ALLOW_ORPHANS( bi ) ? "yes" : "no", 0, 0 );
403
404         } else if ( !strcasecmp( argv[ 0 ], "baseobject" ) ) {
405                 if ( be->be_suffix == NULL ) {
406                         Debug( LDAP_DEBUG_TRACE,
407                                 "<==backsql_db_config (%s line %d): : "
408                                 "must be defined after \"suffix\"\n",
409                                 fname, lineno, 0 );
410                         return 1;
411                 }
412
413                 if ( bi->sql_baseObject ) {
414                         Debug( LDAP_DEBUG_TRACE,
415                                 "<==backsql_db_config (%s line %d): : "
416                                 "\"baseObject\" already provided (will be overwritten)\n",
417                                 fname, lineno, 0 );
418                         entry_free( bi->sql_baseObject );
419                 }
420         
421                 switch ( argc ) {
422                 case 1:
423                         return create_baseObject( be, fname, lineno );
424
425                 case 2:
426                         return read_baseObject( be, argv[ 1 ] );
427
428                 default:
429                         Debug( LDAP_DEBUG_TRACE,
430                                 "<==backsql_db_config (%s line %d): "
431                                 "trailing values "
432                                 "in \"baseObject\" directive?\n",
433                                 fname, lineno, 0 );
434                         return 1;
435                 }
436
437         } else if ( !strcasecmp( argv[ 0 ], "sqllayer") ) {
438                 if ( backsql_api_config( bi, argv[ 1 ] ) ) {
439                         Debug( LDAP_DEBUG_TRACE,
440                                 "<==backsql_db_config (%s line %d): "
441                                 "unable to load sqllayer \"%s\"\n",
442                                 fname, lineno, argv[ 1 ] );
443                         return 1;
444                 }
445
446         } else {
447                 return SLAP_CONF_UNKNOWN;
448         }
449
450         return 0;
451 }
452
453 /*
454  * Read the entries specified in fname and merge the attributes
455  * to the user defined baseObject entry. Note that if we find any errors
456  * what so ever, we will discard the entire entries, print an
457  * error message and return.
458  */
459 static int
460 read_baseObject( 
461         BackendDB       *be,
462         const char      *fname )
463 {
464         backsql_info    *bi = (backsql_info *)be->be_private;
465         FILE            *fp;
466         int             rc = 0, lineno = 0, lmax = 0;
467         char            *buf = NULL;
468
469         assert( fname );
470
471         fp = fopen( fname, "r" );
472         if ( fp == NULL ) {
473                 Debug( LDAP_DEBUG_ANY,
474                         "could not open back-sql baseObject attr file \"%s\" - absolute path?\n",
475                         fname, 0, 0 );
476                 perror( fname );
477                 return LDAP_OTHER;
478         }
479
480         bi->sql_baseObject = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) );
481         if ( bi->sql_baseObject == NULL ) {
482                 Debug( LDAP_DEBUG_ANY,
483                         "read_baseObject_file: SLAP_CALLOC failed", 0, 0, 0 );
484                 fclose( fp );
485                 return LDAP_NO_MEMORY;
486         }
487         bi->sql_baseObject->e_name = be->be_suffix[0];
488         bi->sql_baseObject->e_nname = be->be_nsuffix[0];
489         bi->sql_baseObject->e_attrs = NULL;
490
491         while ( ldif_read_record( fp, &lineno, &buf, &lmax ) ) {
492                 Entry           *e = str2entry( buf );
493                 Attribute       *a;
494
495                 if( e == NULL ) {
496                         fprintf( stderr, "back-sql baseObject: could not parse entry (line=%d)\n",
497                                 lineno );
498                         rc = LDAP_OTHER;
499                         break;
500                 }
501
502                 /* make sure the DN is the database's suffix */
503                 if ( !be_issuffix( be, &e->e_nname ) ) {
504                         fprintf( stderr,
505                                 "back-sql: invalid baseObject - dn=\"%s\" (line=%d)\n",
506                                 e->e_dn, lineno );
507                         entry_free( e );
508                         rc = EXIT_FAILURE;
509                         break;
510                 }
511
512                 /*
513                  * we found a valid entry, so walk thru all the attributes in the
514                  * entry, and add each attribute type and description to baseObject
515                  */
516                 for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
517                         if ( attr_merge( bi->sql_baseObject, a->a_desc, a->a_vals,
518                                 ( a->a_nvals == a->a_vals ) ? NULL : a->a_nvals ) )
519                         {
520                                 rc = LDAP_OTHER;
521                                 break;
522                         }
523                 }
524
525                 entry_free( e );
526                 if ( rc ) {
527                         break;
528                 }
529         }
530
531         if ( rc ) {
532                 entry_free( bi->sql_baseObject );
533                 bi->sql_baseObject = NULL;
534         }
535
536         ch_free( buf );
537
538         fclose( fp );
539
540         Debug( LDAP_DEBUG_CONFIG, "back-sql baseObject file \"%s\" read.\n", fname, 0, 0 );
541
542         return rc;
543 }
544
545 static int
546 create_baseObject(
547         BackendDB       *be,
548         const char      *fname,
549         int             lineno )
550 {
551         backsql_info    *bi = (backsql_info *)be->be_private;
552         LDAPRDN         rdn;
553         char            *p;
554         int             rc, iAVA;
555         char            buf[1024];
556
557         snprintf( buf, sizeof(buf),
558                         "dn: %s\n"
559                         "objectClass: extensibleObject\n"
560                         "description: builtin baseObject for back-sql\n"
561                         "description: all entries mapped in the \"ldap_entries\" table\n"
562                         "description: must have \"" BACKSQL_BASEOBJECT_IDSTR "\" "
563                                 "in the \"parent\" column",
564                         be->be_suffix[0].bv_val );
565
566         bi->sql_baseObject = str2entry( buf );
567         if ( bi->sql_baseObject == NULL ) {
568                 Debug( LDAP_DEBUG_TRACE,
569                         "<==backsql_db_config (%s line %d): "
570                         "unable to parse baseObject entry\n",
571                         fname, lineno, 0 );
572                 return 1;
573         }
574
575         if ( BER_BVISEMPTY( &be->be_suffix[ 0 ] ) ) {
576                 return 0;
577         }
578
579         rc = ldap_bv2rdn( &be->be_suffix[ 0 ], &rdn, (char **) &p, LDAP_DN_FORMAT_LDAP );
580         if ( rc != LDAP_SUCCESS ) {
581                 snprintf( buf, sizeof(buf),
582                         "unable to extract RDN from baseObject DN \"%s\" (%d: %s)",
583                         be->be_suffix[ 0 ].bv_val, rc, ldap_err2string( rc ) );
584                 Debug( LDAP_DEBUG_TRACE,
585                         "<==backsql_db_config (%s line %d): %s\n",
586                         fname, lineno, buf );
587                 return 1;
588         }
589
590         for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
591                 LDAPAVA                         *ava = rdn[ iAVA ];
592                 AttributeDescription            *ad = NULL;
593                 slap_syntax_transform_func      *transf = NULL;
594                 struct berval                   bv = BER_BVNULL;
595                 const char                      *text = NULL;
596
597                 assert( ava );
598
599                 rc = slap_bv2ad( &ava->la_attr, &ad, &text );
600                 if ( rc != LDAP_SUCCESS ) {
601                         snprintf( buf, sizeof(buf),
602                                 "AttributeDescription of naming "
603                                 "attribute #%d from baseObject "
604                                 "DN \"%s\": %d: %s",
605                                 iAVA, be->be_suffix[ 0 ].bv_val,
606                                 rc, ldap_err2string( rc ) );
607                         Debug( LDAP_DEBUG_TRACE,
608                                 "<==backsql_db_config (%s line %d): %s\n",
609                                 fname, lineno, buf );
610                         return 1;
611                 }
612                 
613                 transf = ad->ad_type->sat_syntax->ssyn_pretty;
614                 if ( transf ) {
615                         /*
616                          * transform value by pretty function
617                          *      if value is empty, use empty_bv
618                          */
619                         rc = ( *transf )( ad->ad_type->sat_syntax,
620                                 ava->la_value.bv_len
621                                         ? &ava->la_value
622                                         : (struct berval *) &slap_empty_bv,
623                                 &bv, NULL );
624         
625                         if ( rc != LDAP_SUCCESS ) {
626                                 snprintf( buf, sizeof(buf),
627                                         "prettying of attribute #%d from baseObject "
628                                         "DN \"%s\" failed: %d: %s",
629                                         iAVA, be->be_suffix[ 0 ].bv_val,
630                                         rc, ldap_err2string( rc ) );
631                                 Debug( LDAP_DEBUG_TRACE,
632                                         "<==backsql_db_config (%s line %d): %s\n",
633                                         fname, lineno, buf );
634                                 return 1;
635                         }
636                 }
637
638                 if ( !BER_BVISNULL( &bv ) ) {
639                         if ( ava->la_flags & LDAP_AVA_FREE_VALUE ) {
640                                 ber_memfree( ava->la_value.bv_val );
641                         }
642                         ava->la_value = bv;
643                         ava->la_flags |= LDAP_AVA_FREE_VALUE;
644                 }
645
646                 attr_merge_normalize_one( bi->sql_baseObject,
647                                 ad, &ava->la_value, NULL );
648         }
649
650         ldap_rdnfree( rdn );
651
652         return 0;
653 }
654
655 #endif /* SLAPD_SQL */
656