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