X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-sql%2Fconfig.c;h=197787ce5a39d1e5b34c41db39320b80550d44fd;hb=569344fb86fd1e7b4b304598839c157aa92e5447;hp=d88a57396d590554e58e6f27d0061b6c0f004b7c;hpb=3c598e89fb34a892d369a138daa8c3314294493c;p=openldap diff --git a/servers/slapd/back-sql/config.c b/servers/slapd/back-sql/config.c index d88a57396d..197787ce5a 100644 --- a/servers/slapd/back-sql/config.c +++ b/servers/slapd/back-sql/config.c @@ -1,8 +1,10 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1999-2004 The OpenLDAP Foundation. + * Copyright 1999-2011 The OpenLDAP Foundation. * Portions Copyright 1999 Dmitry Kovalev. + * Portions Copyright 2002 Pierangelo Masarati. + * Portions Copyright 2004 Mark Adamson. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -15,20 +17,30 @@ */ /* ACKNOWLEDGEMENTS: * This work was initially developed by Dmitry Kovalev for inclusion - * by OpenLDAP Software. + * by OpenLDAP Software. Additional significant contributors include + * Pierangelo Masarati. */ #include "portable.h" -#ifdef SLAPD_SQL - #include #include "ac/string.h" #include + #include "slap.h" -#include "back-sql.h" -#include "sql-wrap.h" -#include "util.h" +#include "ldif.h" +#include "proto-sql.h" + +static int +create_baseObject( + BackendDB *be, + const char *fname, + int lineno ); + +static int +read_baseObject( + BackendDB *be, + const char *fname ); int backsql_db_config( @@ -38,10 +50,10 @@ backsql_db_config( int argc, char **argv ) { - backsql_info *si = (backsql_info *)be->be_private; + backsql_info *bi = (backsql_info *)be->be_private; Debug( LDAP_DEBUG_TRACE, "==>backsql_db_config()\n", 0, 0, 0 ); - assert( si ); + assert( bi != NULL ); if ( !strcasecmp( argv[ 0 ], "dbhost" ) ) { if ( argc < 2 ) { @@ -51,10 +63,10 @@ backsql_db_config( fname, lineno, 0 ); return 1; } - si->dbhost = ch_strdup( argv[ 1 ] ); + bi->sql_dbhost = ch_strdup( argv[ 1 ] ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): hostname=%s\n", - si->dbhost, 0, 0 ); + bi->sql_dbhost, 0, 0 ); } else if ( !strcasecmp( argv[ 0 ], "dbuser" ) ) { if ( argc < 2 ) { @@ -64,9 +76,9 @@ backsql_db_config( fname, lineno, 0 ); return 1; } - si->dbuser = ch_strdup( argv[ 1 ] ); + bi->sql_dbuser = ch_strdup( argv[ 1 ] ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbuser=%s\n", - si->dbuser, 0, 0 ); + bi->sql_dbuser, 0, 0 ); } else if ( !strcasecmp( argv[ 0 ], "dbpasswd" ) ) { if ( argc < 2 ) { @@ -76,9 +88,9 @@ backsql_db_config( fname, lineno, 0 ); return 1; } - si->dbpasswd = ch_strdup( argv[ 1 ] ); + bi->sql_dbpasswd = ch_strdup( argv[ 1 ] ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " - "dbpasswd=%s\n", /* si->dbpasswd */ "xxxx", 0, 0 ); + "dbpasswd=%s\n", /* bi->sql_dbpasswd */ "xxxx", 0, 0 ); } else if ( !strcasecmp( argv[ 0 ], "dbname" ) ) { if ( argc < 2 ) { @@ -88,9 +100,9 @@ backsql_db_config( "directive\n", fname, lineno, 0 ); return 1; } - si->dbname = ch_strdup( argv[ 1 ] ); + bi->sql_dbname = ch_strdup( argv[ 1 ] ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbname=%s\n", - si->dbname, 0, 0 ); + bi->sql_dbname, 0, 0 ); } else if ( !strcasecmp( argv[ 0 ], "concat_pattern" ) ) { if ( argc < 2 ) { @@ -101,7 +113,7 @@ backsql_db_config( fname, lineno, 0 ); return 1; } - if ( backsql_split_pattern( argv[ 1 ], &si->concat_func, 2 ) ) { + if ( backsql_split_pattern( argv[ 1 ], &bi->sql_concat_func, 2 ) ) { Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): " "unable to parse pattern \"%s\"\n" @@ -121,9 +133,9 @@ backsql_db_config( fname, lineno, 0 ); return 1; } - ber_str2bv( argv[ 1 ], 0, 1, &si->subtree_cond ); + ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_subtree_cond ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " - "subtree_cond=%s\n", si->subtree_cond.bv_val, 0, 0 ); + "subtree_cond=%s\n", bi->sql_subtree_cond.bv_val, 0, 0 ); } else if ( !strcasecmp( argv[ 0 ], "children_cond" ) ) { if ( argc < 2 ) { @@ -134,9 +146,22 @@ backsql_db_config( fname, lineno, 0 ); return 1; } - ber_str2bv( argv[ 1 ], 0, 1, &si->children_cond ); + ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_children_cond ); + Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " + "children_cond=%s\n", bi->sql_children_cond.bv_val, 0, 0 ); + + } else if ( !strcasecmp( argv[ 0 ], "dn_match_cond" ) ) { + if ( argc < 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing SQL condition " + "in \"dn_match_cond\" directive\n", + fname, lineno, 0 ); + return 1; + } + ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_dn_match_cond ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " - "subtree_cond=%s\n", si->children_cond.bv_val, 0, 0 ); + "children_cond=%s\n", bi->sql_dn_match_cond.bv_val, 0, 0 ); } else if ( !strcasecmp( argv[ 0 ], "oc_query" ) ) { if ( argc < 2 ) { @@ -147,9 +172,9 @@ backsql_db_config( fname, lineno, 0 ); return 1; } - si->oc_query = ch_strdup( argv[ 1 ] ); + bi->sql_oc_query = ch_strdup( argv[ 1 ] ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " - "oc_query=%s\n", si->oc_query, 0, 0 ); + "oc_query=%s\n", bi->sql_oc_query, 0, 0 ); } else if ( !strcasecmp( argv[ 0 ], "at_query" ) ) { if ( argc < 2 ) { @@ -160,22 +185,24 @@ backsql_db_config( fname, lineno, 0 ); return 1; } - si->at_query = ch_strdup( argv[ 1 ] ); + bi->sql_at_query = ch_strdup( argv[ 1 ] ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " - "at_query=%s\n", si->at_query, 0, 0 ); + "at_query=%s\n", bi->sql_at_query, 0, 0 ); - } else if ( !strcasecmp( argv[ 0 ], "insentry_query" ) ) { + } else if ( !strcasecmp( argv[ 0 ], "insentry_stmt" ) || + !strcasecmp( argv[ 0 ], "insentry_query" ) ) + { if ( argc < 2 ) { Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): " "missing SQL statement " - "in \"insentry_query\" directive\n", + "in \"insentry_stmt\" directive\n", fname, lineno, 0 ); return 1; } - si->insentry_query = ch_strdup( argv[ 1 ] ); + bi->sql_insentry_stmt = ch_strdup( argv[ 1 ] ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " - "insentry_query=%s\n", si->insentry_query, 0, 0 ); + "insentry_stmt=%s\n", bi->sql_insentry_stmt, 0, 0 ); } else if ( !strcasecmp( argv[ 0 ], "create_needs_select" ) ) { if ( argc < 2 ) { @@ -188,10 +215,10 @@ backsql_db_config( } if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { - si->bsql_flags |= BSQLF_CREATE_NEEDS_SELECT; + bi->sql_flags |= BSQLF_CREATE_NEEDS_SELECT; } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { - si->bsql_flags &= ~BSQLF_CREATE_NEEDS_SELECT; + bi->sql_flags &= ~BSQLF_CREATE_NEEDS_SELECT; } else { Debug( LDAP_DEBUG_TRACE, @@ -204,7 +231,7 @@ backsql_db_config( } Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " "create_needs_select =%s\n", - BACKSQL_CREATE_NEEDS_SELECT( si ) ? "yes" : "no", + BACKSQL_CREATE_NEEDS_SELECT( bi ) ? "yes" : "no", 0, 0 ); } else if ( !strcasecmp( argv[ 0 ], "upper_func" ) ) { @@ -216,9 +243,9 @@ backsql_db_config( fname, lineno, 0 ); return 1; } - ber_str2bv( argv[ 1 ], 0, 1, &si->upper_func ); + ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_upper_func ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " - "upper_func=%s\n", si->upper_func.bv_val, 0, 0 ); + "upper_func=%s\n", bi->sql_upper_func.bv_val, 0, 0 ); } else if ( !strcasecmp( argv[ 0 ], "upper_needs_cast" ) ) { if ( argc < 2 ) { @@ -231,10 +258,10 @@ backsql_db_config( } if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { - si->bsql_flags |= BSQLF_UPPER_NEEDS_CAST; + bi->sql_flags |= BSQLF_UPPER_NEEDS_CAST; } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { - si->bsql_flags &= ~BSQLF_UPPER_NEEDS_CAST; + bi->sql_flags &= ~BSQLF_UPPER_NEEDS_CAST; } else { Debug( LDAP_DEBUG_TRACE, @@ -247,7 +274,7 @@ backsql_db_config( } Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " "upper_needs_cast =%s\n", - BACKSQL_UPPER_NEEDS_CAST( si ) ? "yes" : "no", 0, 0 ); + BACKSQL_UPPER_NEEDS_CAST( bi ) ? "yes" : "no", 0, 0 ); } else if ( !strcasecmp( argv[ 0 ], "strcast_func" ) ) { if ( argc < 2 ) { @@ -258,24 +285,56 @@ backsql_db_config( fname, lineno, 0 ); return 1; } - ber_str2bv( argv[ 1 ], 0, 1, &si->strcast_func ); + ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_strcast_func ); + Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " + "strcast_func=%s\n", bi->sql_strcast_func.bv_val, 0, 0 ); + + } else if ( !strcasecmp( argv[ 0 ], "delentry_stmt" ) || + !strcasecmp( argv[ 0 ], "delentry_query" ) ) + { + if ( argc < 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing SQL statement " + "in \"delentry_stmt\" directive\n", + fname, lineno, 0 ); + return 1; + } + bi->sql_delentry_stmt = ch_strdup( argv[ 1 ] ); + Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " + "delentry_stmt=%s\n", bi->sql_delentry_stmt, 0, 0 ); + + } else if ( !strcasecmp( argv[ 0 ], "renentry_stmt" ) || + !strcasecmp( argv[ 0 ], "renentry_query" ) ) + { + if ( argc < 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing SQL statement " + "in \"renentry_stmt\" directive\n", + fname, lineno, 0 ); + return 1; + } + bi->sql_renentry_stmt = ch_strdup( argv[ 1 ] ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " - "strcast_func=%s\n", si->strcast_func.bv_val, 0, 0 ); + "renentry_stmt=%s\n", bi->sql_renentry_stmt, 0, 0 ); - } else if ( !strcasecmp( argv[ 0 ], "delentry_query" ) ) { + } else if ( !strcasecmp( argv[ 0 ], "delobjclasses_stmt" ) || + !strcasecmp( argv[ 0 ], "delobjclasses_query" ) ) + { if ( argc < 2 ) { Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): " "missing SQL statement " - "in \"delentry_query\" directive\n", + "in \"delobjclasses_stmt\" directive\n", fname, lineno, 0 ); return 1; } - si->delentry_query = ch_strdup( argv[ 1 ] ); + bi->sql_delobjclasses_stmt = ch_strdup( argv[ 1 ] ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " - "delentry_query=%s\n", si->delentry_query, 0, 0 ); + "delobjclasses_stmt=%s\n", bi->sql_delobjclasses_stmt, 0, 0 ); - } else if ( !strcasecmp( argv[ 0 ], "has_ldapinfo_dn_ru") ) { + } else if ( !strcasecmp( argv[ 0 ], "has_ldapinfo_dn_ru" ) ) { if ( argc < 2 ) { Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): " @@ -286,12 +345,12 @@ backsql_db_config( } if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { - si->bsql_flags |= BSQLF_HAS_LDAPINFO_DN_RU; - si->bsql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU; + bi->sql_flags |= BSQLF_HAS_LDAPINFO_DN_RU; + bi->sql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU; } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { - si->bsql_flags &= ~BSQLF_HAS_LDAPINFO_DN_RU; - si->bsql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU; + bi->sql_flags &= ~BSQLF_HAS_LDAPINFO_DN_RU; + bi->sql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU; } else { Debug( LDAP_DEBUG_TRACE, @@ -304,9 +363,9 @@ backsql_db_config( } Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " "has_ldapinfo_dn_ru=%s\n", - BACKSQL_HAS_LDAPINFO_DN_RU( si ) ? "yes" : "no", 0, 0 ); + BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ? "yes" : "no", 0, 0 ); - } else if ( !strcasecmp( argv[ 0 ], "fail_if_no_mapping") ) { + } else if ( !strcasecmp( argv[ 0 ], "fail_if_no_mapping" ) ) { if ( argc < 2 ) { Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): " @@ -317,10 +376,10 @@ backsql_db_config( } if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { - si->bsql_flags |= BSQLF_FAIL_IF_NO_MAPPING; + bi->sql_flags |= BSQLF_FAIL_IF_NO_MAPPING; } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { - si->bsql_flags &= ~BSQLF_FAIL_IF_NO_MAPPING; + bi->sql_flags &= ~BSQLF_FAIL_IF_NO_MAPPING; } else { Debug( LDAP_DEBUG_TRACE, @@ -333,7 +392,283 @@ backsql_db_config( } Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " "fail_if_no_mapping=%s\n", - BACKSQL_FAIL_IF_NO_MAPPING( si ) ? "yes" : "no", 0, 0 ); + BACKSQL_FAIL_IF_NO_MAPPING( bi ) ? "yes" : "no", 0, 0 ); + + } else if ( !strcasecmp( argv[ 0 ], "allow_orphans" ) ) { + if ( argc < 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing { yes | no }" + "in \"allow_orphans\" directive\n", + fname, lineno, 0 ); + return 1; + } + + if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { + bi->sql_flags |= BSQLF_ALLOW_ORPHANS; + + } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { + bi->sql_flags &= ~BSQLF_ALLOW_ORPHANS; + + } else { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "\"allow_orphans\" directive arg " + "must be \"yes\" or \"no\"\n", + fname, lineno, 0 ); + return 1; + + } + Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " + "allow_orphans=%s\n", + BACKSQL_ALLOW_ORPHANS( bi ) ? "yes" : "no", 0, 0 ); + + } else if ( !strcasecmp( argv[ 0 ], "baseobject" ) ) { + if ( be->be_suffix == NULL ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): : " + "must be defined after \"suffix\"\n", + fname, lineno, 0 ); + return 1; + } + + if ( bi->sql_baseObject ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): : " + "\"baseObject\" already provided (will be overwritten)\n", + fname, lineno, 0 ); + entry_free( bi->sql_baseObject ); + } + + switch ( argc ) { + case 1: + return create_baseObject( be, fname, lineno ); + + case 2: + return read_baseObject( be, argv[ 1 ] ); + + default: + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "trailing values " + "in \"baseObject\" directive?\n", + fname, lineno, 0 ); + return 1; + } + + } else if ( !strcasecmp( argv[ 0 ], "sqllayer" ) ) { + if ( backsql_api_config( bi, argv[ 1 ], argc - 2, &argv[ 2 ] ) ) + { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "unable to load sqllayer \"%s\"\n", + fname, lineno, argv[ 1 ] ); + return 1; + } + + } else if ( !strcasecmp( argv[ 0 ], "id_query" ) ) { + if ( argc < 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing SQL condition " + "in \"id_query\" directive\n", + fname, lineno, 0 ); + return 1; + } + bi->sql_id_query = ch_strdup( argv[ 1 ] ); + Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " + "id_query=%s\n", bi->sql_id_query, 0, 0 ); + + } else if ( !strcasecmp( argv[ 0 ], "use_subtree_shortcut" ) ) { + if ( argc < 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing { yes | no }" + "in \"use_subtree_shortcut\" directive\n", + fname, lineno, 0 ); + return 1; + } + + if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { + bi->sql_flags |= BSQLF_USE_SUBTREE_SHORTCUT; + + } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { + bi->sql_flags &= ~BSQLF_USE_SUBTREE_SHORTCUT; + + } else { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "\"use_subtree_shortcut\" directive arg " + "must be \"yes\" or \"no\"\n", + fname, lineno, 0 ); + return 1; + + } + Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " + "use_subtree_shortcut=%s\n", + BACKSQL_USE_SUBTREE_SHORTCUT( bi ) ? "yes" : "no", + 0, 0 ); + + } else if ( !strcasecmp( argv[ 0 ], "fetch_all_attrs" ) ) { + if ( argc < 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing { yes | no }" + "in \"fetch_all_attrs\" directive\n", + fname, lineno, 0 ); + return 1; + } + + if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { + bi->sql_flags |= BSQLF_FETCH_ALL_ATTRS; + + } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { + bi->sql_flags &= ~BSQLF_FETCH_ALL_ATTRS; + + } else { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "\"fetch_all_attrs\" directive arg " + "must be \"yes\" or \"no\"\n", + fname, lineno, 0 ); + return 1; + + } + Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " + "fetch_all_attrs=%s\n", + BACKSQL_FETCH_ALL_ATTRS( bi ) ? "yes" : "no", + 0, 0 ); + + } else if ( !strcasecmp( argv[ 0 ], "fetch_attrs" ) ) { + char *str, *s, *next; + const char *delimstr = ","; + + if ( argc < 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing " + "in \"fetch_all_attrs \" directive\n", + fname, lineno, 0 ); + return 1; + } + + str = ch_strdup( argv[ 1 ] ); + for ( s = ldap_pvt_strtok( str, delimstr, &next ); + s != NULL; + s = ldap_pvt_strtok( NULL, delimstr, &next ) ) + { + if ( strlen( s ) == 1 ) { + if ( *s == '*' ) { + bi->sql_flags |= BSQLF_FETCH_ALL_USERATTRS; + argv[ 1 ][ s - str ] = ','; + + } else if ( *s == '+' ) { + bi->sql_flags |= BSQLF_FETCH_ALL_OPATTRS; + argv[ 1 ][ s - str ] = ','; + } + } + } + ch_free( str ); + bi->sql_anlist = str2anlist( bi->sql_anlist, argv[ 1 ], delimstr ); + if ( bi->sql_anlist == NULL ) { + return -1; + } + + } else if ( !strcasecmp( argv[ 0 ], "check_schema" ) ) { + if ( argc != 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing { yes | no }" + "in \"check_schema\" directive\n", + fname, lineno, 0 ); + return 1; + } + + if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { + bi->sql_flags |= BSQLF_CHECK_SCHEMA; + + } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { + bi->sql_flags &= ~BSQLF_CHECK_SCHEMA; + + } else { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "\"check_schema\" directive arg " + "must be \"yes\" or \"no\"\n", + fname, lineno, 0 ); + return 1; + + } + Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " + "check_schema=%s\n", + BACKSQL_CHECK_SCHEMA( bi ) ? "yes" : "no", + 0, 0 ); + + } else if ( !strcasecmp( argv[ 0 ], "aliasing_keyword" ) ) { + if ( argc != 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing arg " + "in \"aliasing_keyword \" directive\n", + fname, lineno, 0 ); + return 1; + } + + if ( ! BER_BVISNULL( &bi->sql_aliasing ) ) { + ch_free( bi->sql_aliasing.bv_val ); + } + + ber_str2bv( argv[ 1 ], strlen( argv[ 1 ] ) + 1, 1, + &bi->sql_aliasing ); + /* add a trailing space... */ + bi->sql_aliasing.bv_val[ bi->sql_aliasing.bv_len - 1] = ' '; + + } else if ( !strcasecmp( argv[ 0 ], "aliasing_quote" ) ) { + if ( argc != 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing arg " + "in \"aliasing_quote \" directive\n", + fname, lineno, 0 ); + return 1; + } + + if ( ! BER_BVISNULL( &bi->sql_aliasing_quote ) ) { + ch_free( bi->sql_aliasing_quote.bv_val ); + } + + ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_aliasing_quote ); + + } else if ( !strcasecmp( argv[ 0 ], "autocommit" ) ) { + if ( argc != 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing arg " + "in \"autocommit {NO|yes}\" directive\n", + fname, lineno, 0 ); + return 1; + } + + if ( !strcasecmp( argv[ 1 ], "yes" ) || + !strcasecmp( argv[ 1 ], "TRUE" ) || + !strcasecmp( argv[ 1 ], "on" ) ) + { + bi->sql_flags |= BSQLF_AUTOCOMMIT_ON; + + } else if ( !strcasecmp( argv[ 1 ], "no" ) || + !strcasecmp( argv[ 1 ], "FALSE" ) || + !strcasecmp( argv[ 1 ], "off" ) ) + { + bi->sql_flags &= ~BSQLF_AUTOCOMMIT_ON; + + } else { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "invalid arg " + "in \"autocommit {NO|yes}\" directive\n", + fname, lineno, 0 ); + return 1; + } } else { return SLAP_CONF_UNKNOWN; @@ -342,5 +677,221 @@ backsql_db_config( return 0; } -#endif /* SLAPD_SQL */ +/* + * Read the entries specified in fname and merge the attributes + * to the user defined baseObject entry. Note that if we find any errors + * what so ever, we will discard the entire entries, print an + * error message and return. + */ +static int +read_baseObject( + BackendDB *be, + const char *fname ) +{ + backsql_info *bi = (backsql_info *)be->be_private; + LDIFFP *fp; + int rc = 0, lineno = 0, lmax = 0, ldifrc; + char *buf = NULL; + + assert( fname != NULL ); + + fp = ldif_open( fname, "r" ); + if ( fp == NULL ) { + Debug( LDAP_DEBUG_ANY, + "could not open back-sql baseObject " + "attr file \"%s\" - absolute path?\n", + fname, 0, 0 ); + perror( fname ); + return LDAP_OTHER; + } + + bi->sql_baseObject = entry_alloc(); + if ( bi->sql_baseObject == NULL ) { + Debug( LDAP_DEBUG_ANY, + "read_baseObject_file: entry_alloc failed", 0, 0, 0 ); + ldif_close( fp ); + return LDAP_NO_MEMORY; + } + bi->sql_baseObject->e_name = be->be_suffix[0]; + bi->sql_baseObject->e_nname = be->be_nsuffix[0]; + bi->sql_baseObject->e_attrs = NULL; + + while (( ldifrc = ldif_read_record( fp, &lineno, &buf, &lmax )) > 0 ) { + Entry *e = str2entry( buf ); + Attribute *a; + + if( e == NULL ) { + fprintf( stderr, "back-sql baseObject: " + "could not parse entry (line=%d)\n", + lineno ); + rc = LDAP_OTHER; + break; + } + + /* make sure the DN is the database's suffix */ + if ( !be_issuffix( be, &e->e_nname ) ) { + fprintf( stderr, + "back-sql: invalid baseObject - " + "dn=\"%s\" (line=%d)\n", + e->e_name.bv_val, lineno ); + entry_free( e ); + rc = LDAP_OTHER; + break; + } + + /* + * we found a valid entry, so walk thru all the attributes in the + * entry, and add each attribute type and description to baseObject + */ + for ( a = e->e_attrs; a != NULL; a = a->a_next ) { + if ( attr_merge( bi->sql_baseObject, a->a_desc, + a->a_vals, + ( a->a_nvals == a->a_vals ) ? + NULL : a->a_nvals ) ) + { + rc = LDAP_OTHER; + break; + } + } + + entry_free( e ); + if ( rc ) { + break; + } + } + + if ( ldifrc < 0 ) + rc = LDAP_OTHER; + + if ( rc ) { + entry_free( bi->sql_baseObject ); + bi->sql_baseObject = NULL; + } + + ch_free( buf ); + + ldif_close( fp ); + + Debug( LDAP_DEBUG_CONFIG, "back-sql baseObject file \"%s\" read.\n", + fname, 0, 0 ); + + return rc; +} + +static int +create_baseObject( + BackendDB *be, + const char *fname, + int lineno ) +{ + backsql_info *bi = (backsql_info *)be->be_private; + LDAPRDN rdn; + char *p; + int rc, iAVA; + char buf[1024]; + + snprintf( buf, sizeof(buf), + "dn: %s\n" + "objectClass: extensibleObject\n" + "description: builtin baseObject for back-sql\n" + "description: all entries mapped " + "in table \"ldap_entries\" " + "must have " + "\"" BACKSQL_BASEOBJECT_IDSTR "\" " + "in the \"parent\" column", + be->be_suffix[0].bv_val ); + + bi->sql_baseObject = str2entry( buf ); + if ( bi->sql_baseObject == NULL ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "unable to parse baseObject entry\n", + fname, lineno, 0 ); + return 1; + } + + if ( BER_BVISEMPTY( &be->be_suffix[ 0 ] ) ) { + return 0; + } + + rc = ldap_bv2rdn( &be->be_suffix[ 0 ], &rdn, (char **)&p, + LDAP_DN_FORMAT_LDAP ); + if ( rc != LDAP_SUCCESS ) { + snprintf( buf, sizeof(buf), + "unable to extract RDN " + "from baseObject DN \"%s\" (%d: %s)", + be->be_suffix[ 0 ].bv_val, + rc, ldap_err2string( rc ) ); + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): %s\n", + fname, lineno, buf ); + return 1; + } + + for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) { + LDAPAVA *ava = rdn[ iAVA ]; + AttributeDescription *ad = NULL; + slap_syntax_transform_func *transf = NULL; + struct berval bv = BER_BVNULL; + const char *text = NULL; + + assert( ava != NULL ); + + rc = slap_bv2ad( &ava->la_attr, &ad, &text ); + if ( rc != LDAP_SUCCESS ) { + snprintf( buf, sizeof(buf), + "AttributeDescription of naming " + "attribute #%d from baseObject " + "DN \"%s\": %d: %s", + iAVA, be->be_suffix[ 0 ].bv_val, + rc, ldap_err2string( rc ) ); + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): %s\n", + fname, lineno, buf ); + return 1; + } + + transf = ad->ad_type->sat_syntax->ssyn_pretty; + if ( transf ) { + /* + * transform value by pretty function + * if value is empty, use empty_bv + */ + rc = ( *transf )( ad->ad_type->sat_syntax, + ava->la_value.bv_len + ? &ava->la_value + : (struct berval *) &slap_empty_bv, + &bv, NULL ); + + if ( rc != LDAP_SUCCESS ) { + snprintf( buf, sizeof(buf), + "prettying of attribute #%d " + "from baseObject " + "DN \"%s\" failed: %d: %s", + iAVA, be->be_suffix[ 0 ].bv_val, + rc, ldap_err2string( rc ) ); + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "%s\n", + fname, lineno, buf ); + return 1; + } + } + + if ( !BER_BVISNULL( &bv ) ) { + if ( ava->la_flags & LDAP_AVA_FREE_VALUE ) { + ber_memfree( ava->la_value.bv_val ); + } + ava->la_value = bv; + ava->la_flags |= LDAP_AVA_FREE_VALUE; + } + + attr_merge_normalize_one( bi->sql_baseObject, + ad, &ava->la_value, NULL ); + } + + ldap_rdnfree( rdn ); + + return 0; +}