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