From eb0421c471342edfe4900fbd9d5b9fd9a7c650d8 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Mon, 17 Jan 2005 19:32:28 +0000 Subject: [PATCH] fix several schema checking issues; add rename specific statement for entry renaming without losing ID (helps e.g. in renaming referrals, otherwise referential integrity would prevent del/add because of referenced stuff in ldap_referrals and ldap_entry_objclasses); referrals need schemacheck off otherwise objectClass chain is invalid (they need to be attached to another objectClass by now; will address this later) --- servers/slapd/back-sql/add.c | 8 +- servers/slapd/back-sql/back-sql.h | 1 + servers/slapd/back-sql/bind.c | 10 ++- servers/slapd/back-sql/compare.c | 10 ++- servers/slapd/back-sql/config.c | 15 ++++ servers/slapd/back-sql/init.c | 18 +++++ servers/slapd/back-sql/modify.c | 38 +++++++++- servers/slapd/back-sql/modrdn.c | 108 +++++++++++---------------- servers/slapd/back-sql/operational.c | 3 +- servers/slapd/back-sql/proto-sql.h | 1 + servers/slapd/back-sql/search.c | 8 +- servers/slapd/back-sql/util.c | 2 + 12 files changed, 138 insertions(+), 84 deletions(-) diff --git a/servers/slapd/back-sql/add.c b/servers/slapd/back-sql/add.c index 96a9ef10df..2453443d87 100644 --- a/servers/slapd/back-sql/add.c +++ b/servers/slapd/back-sql/add.c @@ -43,11 +43,13 @@ * - operational attributes * - empty attributes */ +#define backsql_opattr_skip(ad) \ + (is_at_operational( (ad)->ad_type ) && (ad) != slap_schema.si_ad_ref ) #define backsql_attr_skip(ad, vals) \ ( \ ( (ad) == slap_schema.si_ad_objectClass \ && (vals) && BER_BVISNULL( &((vals)[ 1 ]) ) ) \ - || is_at_operational( (ad)->ad_type ) \ + || backsql_opattr_skip( (ad) ) \ || ( (vals) && BER_BVISNULL( &((vals)[ 0 ]) ) ) \ ) @@ -316,7 +318,7 @@ backsql_modify_internal( #if 0 /* NOTE: some day we'll have to pass * the normalized values as well */ - BerVarray nvalues; + BerVarray sm_nvalues; #endif backsql_at_map_rec *at = NULL; struct berval *at_val; @@ -951,7 +953,7 @@ backsql_add( Operation *op, SlapReply *rs ) unsigned long new_keyval = 0; RETCODE rc; backsql_oc_map_rec *oc = NULL; - backsql_srch_info bsi; + backsql_srch_info bsi = { 0 }; Entry p = { 0 }, *e = NULL; Attribute *at, *at_objectClass = NULL; diff --git a/servers/slapd/back-sql/back-sql.h b/servers/slapd/back-sql/back-sql.h index e91736288b..6c79a7b0c4 100644 --- a/servers/slapd/back-sql/back-sql.h +++ b/servers/slapd/back-sql/back-sql.h @@ -474,6 +474,7 @@ typedef struct backsql_info { *sql_at_query; char *sql_insentry_stmt, *sql_delentry_stmt, + *sql_renentry_stmt, *sql_delobjclasses_stmt, *sql_delreferrals_stmt; char *sql_id_query; diff --git a/servers/slapd/back-sql/bind.c b/servers/slapd/back-sql/bind.c index 3ce75c1f08..5817d06af6 100644 --- a/servers/slapd/back-sql/bind.c +++ b/servers/slapd/back-sql/bind.c @@ -34,7 +34,7 @@ backsql_bind( Operation *op, SlapReply *rs ) SQLHDBC dbh = SQL_NULL_HDBC; Entry e = { 0 }; Attribute *a; - backsql_srch_info bsi; + backsql_srch_info bsi = { 0 }; AttributeName anlist[2]; int rc; @@ -101,10 +101,12 @@ backsql_bind( Operation *op, SlapReply *rs ) } error_return:; - (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); + if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) { + (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); + } - if ( bsi.bsi_e ) { - entry_clean( bsi.bsi_e ); + if ( !BER_BVISNULL( &e.e_nname ) ) { + entry_clean( &e ); } if ( bsi.bsi_attrs != NULL ) { diff --git a/servers/slapd/back-sql/compare.c b/servers/slapd/back-sql/compare.c index 4dfb365a0b..3a87819622 100644 --- a/servers/slapd/back-sql/compare.c +++ b/servers/slapd/back-sql/compare.c @@ -34,7 +34,7 @@ backsql_compare( Operation *op, SlapReply *rs ) SQLHDBC dbh = SQL_NULL_HDBC; Entry e = { 0 }; Attribute *a = NULL; - backsql_srch_info bsi; + backsql_srch_info bsi = { 0 }; int rc; AttributeName anlist[2], *anlistp = NULL; @@ -174,10 +174,12 @@ return_results:; rs->sr_ref = NULL; } - (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); + if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) { + (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); + } - if ( bsi.bsi_e ) { - entry_clean( bsi.bsi_e ); + if ( !BER_BVISNULL( &e.e_nname ) ) { + entry_clean( &e ); } if ( bsi.bsi_attrs != NULL ) { diff --git a/servers/slapd/back-sql/config.c b/servers/slapd/back-sql/config.c index c45c70716e..51d50e6a6a 100644 --- a/servers/slapd/back-sql/config.c +++ b/servers/slapd/back-sql/config.c @@ -291,6 +291,21 @@ backsql_db_config( 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(): " + "renentry_stmt=%s\n", bi->sql_renentry_stmt, 0, 0 ); + } else if ( !strcasecmp( argv[ 0 ], "delobjclasses_stmt" ) || !strcasecmp( argv[ 0 ], "delobjclasses_query" ) ) { diff --git a/servers/slapd/back-sql/init.c b/servers/slapd/back-sql/init.c index 3ebdfea0a9..11aa1ffd38 100644 --- a/servers/slapd/back-sql/init.c +++ b/servers/slapd/back-sql/init.c @@ -47,6 +47,12 @@ sql_back_initialize( bi->bi_controls = controls; + bi->bi_flags |= +#if 0 + SLAP_BFLAG_INCREMENT | +#endif + SLAP_BFLAG_REFERRALS; + Debug( LDAP_DEBUG_TRACE,"==>sql_back_initialize()\n", 0, 0, 0 ); bi->bi_db_init = backsql_db_init; @@ -137,6 +143,7 @@ backsql_db_destroy( free( bi->sql_at_query ); free( bi->sql_insentry_stmt ); free( bi->sql_delentry_stmt ); + free( bi->sql_renentry_stmt ); free( bi->sql_delobjclasses_stmt ); free( bi->sql_delreferrals_stmt ); @@ -375,6 +382,17 @@ backsql_db_open( bi->sql_delentry_stmt = ch_strdup( backsql_def_delentry_stmt ); } + if ( bi->sql_renentry_stmt == NULL ) { + Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " + "entry deletion SQL statement not specified " + "(use \"renentry_stmt\" directive in slapd.conf)\n", + 0, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " + "setting \"%s\" by default\n", + backsql_def_renentry_stmt, 0, 0 ); + bi->sql_renentry_stmt = ch_strdup( backsql_def_renentry_stmt ); + } + if ( bi->sql_delobjclasses_stmt == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " "objclasses deletion SQL statement not specified " diff --git a/servers/slapd/back-sql/modify.c b/servers/slapd/back-sql/modify.c index ac9a197155..b4de864199 100644 --- a/servers/slapd/back-sql/modify.c +++ b/servers/slapd/back-sql/modify.c @@ -143,7 +143,6 @@ backsql_modify( Operation *op, SlapReply *rs ) goto done; } - /* FIXME: need the whole entry (ITS#3480) */ if ( !acl_check_modlist( op, &m, op->oq_modify.rs_modlist ) ) { rs->sr_err = LDAP_INSUFFICIENT_ACCESS; e = &m; @@ -153,7 +152,36 @@ backsql_modify( Operation *op, SlapReply *rs ) rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &bsi.bsi_base_id, op->oq_modify.rs_modlist ); + if ( rs->sr_err != LDAP_SUCCESS ) { + e = &m; + goto do_transact; + } + + if ( global_schemacheck ) { + char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' }; + entry_clean( &m ); + + bsi.bsi_e = &m; + rs->sr_err = backsql_id2entry( &bsi, &bsi.bsi_base_id ); + if ( rs->sr_err != LDAP_SUCCESS ) { + e = &m; + goto do_transact; + } + + rs->sr_err = entry_schema_check( op->o_bd, &m, + NULL, + &rs->sr_text, textbuf, sizeof( textbuf ) ); + if ( rs->sr_err != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " + "entry failed schema check -- aborting\n", + m.e_name.bv_val, 0, 0 ); + e = NULL; + goto do_transact; + } + } + +do_transact:; /* * Commit only if all operations succeed */ @@ -182,10 +210,12 @@ done:; send_ldap_result( op, rs ); - (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); + if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) { + (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); + } - if ( bsi.bsi_e != NULL ) { - entry_clean( bsi.bsi_e ); + if ( !BER_BVISNULL( &m.e_nname ) ) { + entry_clean( &m ); } if ( bsi.bsi_attrs != NULL ) { diff --git a/servers/slapd/back-sql/modrdn.c b/servers/slapd/back-sql/modrdn.c index a722e9f398..d5aa697f8c 100644 --- a/servers/slapd/back-sql/modrdn.c +++ b/servers/slapd/back-sql/modrdn.c @@ -291,32 +291,11 @@ backsql_modrdn( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): new entry dn is \"%s\"\n", new_dn.bv_val, 0, 0 ); - - Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " - "executing delentry_stmt\n", 0, 0, 0 ); - - rc = backsql_Prepare( dbh, &sth, bi->sql_delentry_stmt, 0 ); - if ( rc != SQL_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - " backsql_modrdn(): " - "error preparing delentry_stmt\n", 0, 0, 0 ); - backsql_PrintErrors( bi->sql_db_env, dbh, - sth, rc ); - - rs->sr_text = "SQL-backend error"; - rs->sr_err = LDAP_OTHER; - e = NULL; - goto done; - } - - rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT, &e_id.eid_id ); - if ( rc != SQL_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - " backsql_delete(): " - "error binding entry ID parameter " - "for objectClass %s\n", - oc->bom_oc->soc_cname.bv_val, 0, 0 ); - backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); + realnew_dn = new_dn; + if ( backsql_api_dn2odbc( op, rs, &realnew_dn ) ) { + Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(\"%s\"): " + "backsql_api_dn2odbc(\"%s\") failed\n", + op->o_req_dn.bv_val, realnew_dn.bv_val, 0 ); SQLFreeStmt( sth, SQL_DROP ); rs->sr_text = "SQL-backend error"; @@ -325,29 +304,14 @@ backsql_modrdn( Operation *op, SlapReply *rs ) goto done; } - rc = SQLExecute( sth ); - if ( rc != SQL_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " - "failed to delete record from ldap_entries\n", - 0, 0, 0 ); - backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); - SQLFreeStmt( sth, SQL_DROP ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "SQL-backend error"; - e = NULL; - goto done; - } - - SQLFreeStmt( sth, SQL_DROP ); - Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " - "executing insentry_stmt\n", 0, 0, 0 ); + "executing renentry_stmt\n", 0, 0, 0 ); - rc = backsql_Prepare( dbh, &sth, bi->sql_insentry_stmt, 0 ); + rc = backsql_Prepare( dbh, &sth, bi->sql_renentry_stmt, 0 ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " - "error preparing insentry_stmt\n", 0, 0, 0 ); + "error preparing renentry_stmt\n", 0, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); @@ -357,19 +321,6 @@ backsql_modrdn( Operation *op, SlapReply *rs ) goto done; } - realnew_dn = new_dn; - if ( backsql_api_dn2odbc( op, rs, &realnew_dn ) ) { - Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(\"%s\"): " - "backsql_api_dn2odbc(\"%s\") failed\n", - op->o_req_dn.bv_val, realnew_dn.bv_val, 0 ); - SQLFreeStmt( sth, SQL_DROP ); - - rs->sr_text = "SQL-backend error"; - rs->sr_err = LDAP_OTHER; - e = NULL; - goto done; - } - rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &realnew_dn ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, @@ -386,11 +337,11 @@ backsql_modrdn( Operation *op, SlapReply *rs ) goto done; } - rc = backsql_BindParamInt( sth, 2, SQL_PARAM_INPUT, &e_id.eid_oc_id ); + rc = backsql_BindParamID( sth, 2, SQL_PARAM_INPUT, &n_id.eid_id ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add_attr(): " - "error binding objectClass ID parameter for objectClass %s\n", + "error binding parent ID parameter for objectClass %s\n", oc->bom_oc->soc_cname.bv_val, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); @@ -402,11 +353,11 @@ backsql_modrdn( Operation *op, SlapReply *rs ) goto done; } - rc = backsql_BindParamID( sth, 3, SQL_PARAM_INPUT, &n_id.eid_id ); + rc = backsql_BindParamID( sth, 3, SQL_PARAM_INPUT, &e_id.eid_keyval ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add_attr(): " - "error binding parent ID parameter for objectClass %s\n", + "error binding entry ID parameter for objectClass %s\n", oc->bom_oc->soc_cname.bv_val, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); @@ -418,11 +369,11 @@ backsql_modrdn( Operation *op, SlapReply *rs ) goto done; } - rc = backsql_BindParamID( sth, 4, SQL_PARAM_INPUT, &e_id.eid_keyval ); + rc = backsql_BindParamID( sth, 4, SQL_PARAM_INPUT, &e_id.eid_id ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add_attr(): " - "error binding entry ID parameter for objectClass %s\n", + "error binding ID parameter for objectClass %s\n", oc->bom_oc->soc_cname.bv_val, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); @@ -437,7 +388,7 @@ backsql_modrdn( Operation *op, SlapReply *rs ) rc = SQLExecute( sth ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): " - "could not insert ldap_entries record\n", 0, 0, 0 ); + "could not rename ldap_entries record\n", 0, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); rs->sr_err = LDAP_OTHER; @@ -490,7 +441,34 @@ backsql_modrdn( Operation *op, SlapReply *rs ) oc = backsql_id2oc( bi, e_id.eid_oc_id ); rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id, mod ); - e = &r; + if ( rs->sr_err != LDAP_SUCCESS ) { + e = &r; + goto done; + } + + if ( global_schemacheck ) { + char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' }; + + entry_clean( &r ); + + bsi.bsi_e = &r; + rs->sr_err = backsql_id2entry( &bsi, &e_id ); + if ( rs->sr_err != LDAP_SUCCESS ) { + e = &r; + goto done; + } + + rs->sr_err = entry_schema_check( op->o_bd, &r, + NULL, + &rs->sr_text, textbuf, sizeof( textbuf ) ); + if ( rs->sr_err != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " + "entry failed schema check -- aborting\n", + r.e_name.bv_val, 0, 0 ); + e = NULL; + goto done; + } + } done:; #ifdef SLAP_ACL_HONOR_DISCLOSE diff --git a/servers/slapd/back-sql/operational.c b/servers/slapd/back-sql/operational.c index d997703d98..e0f4af3b1a 100644 --- a/servers/slapd/back-sql/operational.c +++ b/servers/slapd/back-sql/operational.c @@ -180,7 +180,7 @@ backsql_operational( && !got[ BACKSQL_OP_ENTRYUUID ] && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryUUID ) == NULL ) { - backsql_srch_info bsi; + backsql_srch_info bsi = { 0 }; rc = backsql_init_search( &bsi, &rs->sr_entry->e_nname, LDAP_SCOPE_BASE, @@ -197,6 +197,7 @@ backsql_operational( *ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id ); (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); + if ( bsi.bsi_attrs != NULL ) { op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx ); } diff --git a/servers/slapd/back-sql/proto-sql.h b/servers/slapd/back-sql/proto-sql.h index e3cd9b82ff..f0a8237f9f 100644 --- a/servers/slapd/back-sql/proto-sql.h +++ b/servers/slapd/back-sql/proto-sql.h @@ -224,6 +224,7 @@ extern char backsql_def_needs_select_oc_query[], backsql_def_at_query[], backsql_def_delentry_stmt[], + backsql_def_renentry_stmt[], backsql_def_insentry_stmt[], backsql_def_delobjclasses_stmt[], backsql_def_delreferrals_stmt[], diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index d6524d1609..9440a920c4 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -1789,7 +1789,7 @@ backsql_search( Operation *op, SlapReply *rs ) base_entry = { 0 }; int manageDSAit; time_t stoptime = 0; - backsql_srch_info bsi; + backsql_srch_info bsi = { 0 }; backsql_entryID *eid = NULL; struct berval nbase = BER_BVNULL, realndn = BER_BVNULL; @@ -2303,7 +2303,7 @@ backsql_entry_get( int rw, Entry **ent ) { - backsql_srch_info bsi; + backsql_srch_info bsi = { 0 }; SQLHDBC dbh = SQL_NULL_HDBC; int rc; SlapReply rs = { 0 }; @@ -2331,7 +2331,9 @@ backsql_entry_get( dbh, op, &rs, at ? anlist : NULL, BACKSQL_ISF_GET_ENTRY ); - (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); + if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) { + (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); + } if ( rc == LDAP_SUCCESS ) { diff --git a/servers/slapd/back-sql/util.c b/servers/slapd/back-sql/util.c index 337b6bf975..0b971b0241 100644 --- a/servers/slapd/back-sql/util.c +++ b/servers/slapd/back-sql/util.c @@ -48,6 +48,8 @@ char backsql_def_at_query[] = "param_order,expect_return,sel_expr_u FROM ldap_attr_mappings " "WHERE oc_map_id=?"; char backsql_def_delentry_stmt[] = "DELETE FROM ldap_entries WHERE id=?"; +char backsql_def_renentry_stmt[] = + "UPDATE ldap_entries SET dn=?,parent=?,keyval=? WHERE id=?"; char backsql_def_insentry_stmt[] = "INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) " "VALUES (?,?,?,?)"; -- 2.39.5