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