2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2004 The OpenLDAP Foundation.
5 * Portions Copyright 1999 Dmitry Kovalev.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
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>.
17 * This work was initially developed by Dmitry Kovalev for inclusion
18 * by OpenLDAP Software.
24 #include "ac/string.h"
25 #include <sys/types.h>
29 #include "proto-sql.h"
50 backsql_info *bi = (backsql_info *)be->be_private;
52 Debug( LDAP_DEBUG_TRACE, "==>backsql_db_config()\n", 0, 0, 0 );
55 if ( !strcasecmp( argv[ 0 ], "dbhost" ) ) {
57 Debug( LDAP_DEBUG_TRACE,
58 "<==backsql_db_config (%s line %d): "
59 "missing hostname in \"dbhost\" directive\n",
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 );
68 } else if ( !strcasecmp( argv[ 0 ], "dbuser" ) ) {
70 Debug( LDAP_DEBUG_TRACE,
71 "<==backsql_db_config (%s line %d): "
72 "missing username in \"dbuser\" directive\n",
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 );
80 } else if ( !strcasecmp( argv[ 0 ], "dbpasswd" ) ) {
82 Debug( LDAP_DEBUG_TRACE,
83 "<==backsql_db_config (%s line %d): "
84 "missing password in \"dbpasswd\" directive\n",
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 );
92 } else if ( !strcasecmp( argv[ 0 ], "dbname" ) ) {
94 Debug( LDAP_DEBUG_TRACE,
95 "<==backsql_db_config (%s line %d): "
96 "missing database name in \"dbname\" "
97 "directive\n", fname, lineno, 0 );
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 );
104 } else if ( !strcasecmp( argv[ 0 ], "concat_pattern" ) ) {
106 Debug( LDAP_DEBUG_TRACE,
107 "<==backsql_db_config (%s line %d): "
109 "in \"concat_pattern\" directive\n",
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 ] );
121 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
122 "concat_pattern=\"%s\"\n", argv[ 1 ], 0, 0 );
124 } else if ( !strcasecmp( argv[ 0 ], "subtree_cond" ) ) {
126 Debug( LDAP_DEBUG_TRACE,
127 "<==backsql_db_config (%s line %d): "
128 "missing SQL condition "
129 "in \"subtree_cond\" directive\n",
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 );
137 } else if ( !strcasecmp( argv[ 0 ], "children_cond" ) ) {
139 Debug( LDAP_DEBUG_TRACE,
140 "<==backsql_db_config (%s line %d): "
141 "missing SQL condition "
142 "in \"children_cond\" directive\n",
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 );
150 } else if ( !strcasecmp( argv[ 0 ], "oc_query" ) ) {
152 Debug( LDAP_DEBUG_TRACE,
153 "<==backsql_db_config (%s line %d): "
154 "missing SQL statement "
155 "in \"oc_query\" directive\n",
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 );
163 } else if ( !strcasecmp( argv[ 0 ], "at_query" ) ) {
165 Debug( LDAP_DEBUG_TRACE,
166 "<==backsql_db_config (%s line %d): "
167 "missing SQL statement "
168 "in \"at_query\" directive\n",
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 );
176 } else if ( !strcasecmp( argv[ 0 ], "insentry_query" ) ) {
178 Debug( LDAP_DEBUG_TRACE,
179 "<==backsql_db_config (%s line %d): "
180 "missing SQL statement "
181 "in \"insentry_query\" directive\n",
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 );
189 } else if ( !strcasecmp( argv[ 0 ], "create_needs_select" ) ) {
191 Debug( LDAP_DEBUG_TRACE,
192 "<==backsql_db_config (%s line %d): "
193 "missing { yes | no }"
194 "in \"create_needs_select\" directive\n",
199 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
200 bi->sql_flags |= BSQLF_CREATE_NEEDS_SELECT;
202 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
203 bi->sql_flags &= ~BSQLF_CREATE_NEEDS_SELECT;
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",
214 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
215 "create_needs_select =%s\n",
216 BACKSQL_CREATE_NEEDS_SELECT( bi ) ? "yes" : "no",
219 } else if ( !strcasecmp( argv[ 0 ], "upper_func" ) ) {
221 Debug( LDAP_DEBUG_TRACE,
222 "<==backsql_db_config (%s line %d): "
223 "missing function name "
224 "in \"upper_func\" directive\n",
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 );
232 } else if ( !strcasecmp( argv[ 0 ], "upper_needs_cast" ) ) {
234 Debug( LDAP_DEBUG_TRACE,
235 "<==backsql_db_config (%s line %d): "
236 "missing { yes | no }"
237 "in \"upper_needs_cast\" directive\n",
242 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
243 bi->sql_flags |= BSQLF_UPPER_NEEDS_CAST;
245 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
246 bi->sql_flags &= ~BSQLF_UPPER_NEEDS_CAST;
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",
257 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
258 "upper_needs_cast =%s\n",
259 BACKSQL_UPPER_NEEDS_CAST( bi ) ? "yes" : "no", 0, 0 );
261 } else if ( !strcasecmp( argv[ 0 ], "strcast_func" ) ) {
263 Debug( LDAP_DEBUG_TRACE,
264 "<==backsql_db_config (%s line %d): "
265 "missing function name "
266 "in \"strcast_func\" directive\n",
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 );
274 } else if ( !strcasecmp( argv[ 0 ], "delentry_query" ) ) {
276 Debug( LDAP_DEBUG_TRACE,
277 "<==backsql_db_config (%s line %d): "
278 "missing SQL statement "
279 "in \"delentry_query\" directive\n",
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 );
287 } else if ( !strcasecmp( argv[ 0 ], "delobjclasses_query" ) ) {
289 Debug( LDAP_DEBUG_TRACE,
290 "<==backsql_db_config (%s line %d): "
291 "missing SQL statement "
292 "in \"delobjclasses_query\" directive\n",
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 );
300 } else if ( !strcasecmp( argv[ 0 ], "delreferrals_query" ) ) {
302 Debug( LDAP_DEBUG_TRACE,
303 "<==backsql_db_config (%s line %d): "
304 "missing SQL statement "
305 "in \"delreferrals_query\" directive\n",
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 );
313 } else if ( !strcasecmp( argv[ 0 ], "has_ldapinfo_dn_ru") ) {
315 Debug( LDAP_DEBUG_TRACE,
316 "<==backsql_db_config (%s line %d): "
317 "missing { yes | no }"
318 "in \"has_ldapinfo_dn_ru\" directive\n",
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;
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;
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",
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 );
344 } else if ( !strcasecmp( argv[ 0 ], "fail_if_no_mapping") ) {
346 Debug( LDAP_DEBUG_TRACE,
347 "<==backsql_db_config (%s line %d): "
348 "missing { yes | no }"
349 "in \"fail_if_no_mapping\" directive\n",
354 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
355 bi->sql_flags |= BSQLF_FAIL_IF_NO_MAPPING;
357 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
358 bi->sql_flags &= ~BSQLF_FAIL_IF_NO_MAPPING;
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",
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 );
373 } else if ( !strcasecmp( argv[ 0 ], "allow_orphans") ) {
375 Debug( LDAP_DEBUG_TRACE,
376 "<==backsql_db_config (%s line %d): "
377 "missing { yes | no }"
378 "in \"allow_orphans\" directive\n",
383 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
384 bi->sql_flags |= BSQLF_ALLOW_ORPHANS;
386 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
387 bi->sql_flags &= ~BSQLF_ALLOW_ORPHANS;
390 Debug( LDAP_DEBUG_TRACE,
391 "<==backsql_db_config (%s line %d): "
392 "\"allow_orphans\" directive arg "
393 "must be \"yes\" or \"no\"\n",
398 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
399 "allow_orphans=%s\n",
400 BACKSQL_ALLOW_ORPHANS( bi ) ? "yes" : "no", 0, 0 );
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",
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",
416 entry_free( bi->sql_baseObject );
421 return create_baseObject( be, fname, lineno );
424 return read_baseObject( be, argv[ 1 ] );
427 Debug( LDAP_DEBUG_TRACE,
428 "<==backsql_db_config (%s line %d): "
430 "in \"baseObject\" directive?\n",
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 ] );
445 return SLAP_CONF_UNKNOWN;
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.
462 backsql_info *bi = (backsql_info *)be->be_private;
464 int rc = 0, lineno = 0, lmax = 0;
469 fp = fopen( fname, "r" );
471 Debug( LDAP_DEBUG_ANY,
472 "could not open back-sql baseObject attr file \"%s\" - absolute path?\n",
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 );
483 return LDAP_NO_MEMORY;
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;
489 while ( ldif_read_record( fp, &lineno, &buf, &lmax ) ) {
490 Entry *e = str2entry( buf );
494 fprintf( stderr, "back-sql baseObject: could not parse entry (line=%d)\n",
500 /* make sure the DN is the database's suffix */
501 if ( !be_issuffix( be, &e->e_nname ) ) {
503 "back-sql: invalid baseObject - dn=\"%s\" (line=%d)\n",
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
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 ) )
530 entry_free( bi->sql_baseObject );
531 bi->sql_baseObject = NULL;
538 Debug( LDAP_DEBUG_CONFIG, "back-sql baseObject file \"%s\" read.\n", fname, 0, 0 );
549 backsql_info *bi = (backsql_info *)be->be_private;
555 snprintf( buf, sizeof(buf),
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 );
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",
573 if ( BER_BVISEMPTY( &be->be_suffix[ 0 ] ) ) {
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 );
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;
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 "
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 );
611 transf = ad->ad_type->sat_syntax->ssyn_pretty;
614 * transform value by pretty function
615 * if value is empty, use empty_bv
617 rc = ( *transf )( ad->ad_type->sat_syntax,
620 : (struct berval *) &slap_empty_bv,
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 );
636 if ( !BER_BVISNULL( &bv ) ) {
637 if ( ava->la_flags & LDAP_AVA_FREE_VALUE ) {
638 ber_memfree( ava->la_value.bv_val );
641 ava->la_flags |= LDAP_AVA_FREE_VALUE;
644 attr_merge_normalize_one( bi->sql_baseObject,
645 ad, &ava->la_value, NULL );