From a8674f59d735094c1dc09c0f68eb0518a570a469 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Tue, 24 Aug 2004 10:31:02 +0000 Subject: [PATCH] fix various issues; line up with new tests --- servers/slapd/back-sql/add.c | 313 ++++++++++-------- servers/slapd/back-sql/entry-id.c | 12 + servers/slapd/back-sql/external.h | 2 +- servers/slapd/back-sql/init.c | 12 +- .../rdbms_depend/mysql/testdb_metadata.sql | 21 +- .../rdbms_depend/pgsql/testdb_metadata.sql | 30 +- servers/slapd/back-sql/schema-map.c | 171 ++++++++-- servers/slapd/back-sql/search.c | 123 ++++++- servers/slapd/back-sql/sql-wrap.c | 16 +- servers/slapd/back-sql/util.c | 2 +- 10 files changed, 483 insertions(+), 219 deletions(-) diff --git a/servers/slapd/back-sql/add.c b/servers/slapd/back-sql/add.c index b3e51aea4c..d561a6ef11 100644 --- a/servers/slapd/back-sql/add.c +++ b/servers/slapd/back-sql/add.c @@ -35,14 +35,14 @@ * - the first occurrence of objectClass, which is used * to determine how to build the SQL entry (FIXME ?!?) * - operational attributes - * empty attributes (FIXME ?!?) + * - empty attributes (FIXME ?!?) */ #define backsql_attr_skip(ad,vals) \ ( \ ( (ad) == slap_schema.si_ad_objectClass \ - && (vals)[ 1 ].bv_val == NULL ) \ + && BER_BVISNULL( &((vals)[ 1 ]) ) ) \ || is_at_operational( (ad)->ad_type ) \ - || ( (vals)[ 0 ].bv_val == NULL ) \ + || ( (vals) && BER_BVISNULL( &((vals)[ 0 ]) ) ) \ ) int @@ -290,6 +290,11 @@ del_all: } backsql_FreeRow( &row ); SQLFreeStmt( asth, SQL_DROP ); + + /* LDAP_MOD_DELETE gets here if all values must be deleted */ + if ( c_mod->sm_op == LDAP_MOD_DELETE ) { + break; + } } /* @@ -509,6 +514,153 @@ done:; return rs->sr_err; } +static int +backsql_add_attr( + Operation *op, + SlapReply *rs, + SQLHDBC dbh, + SQLHSTMT *sth, + backsql_oc_map_rec *oc, + Attribute *at, + unsigned long new_keyval ) +{ + backsql_info *bi = (backsql_info*)op->o_bd->be_private; + backsql_at_map_rec *at_rec = NULL; + struct berval *at_val; + unsigned long i; + RETCODE rc; + /* first parameter #, parameter order */ + SQLUSMALLINT pno, po; + /* procedure return code */ + int prc; + SQLUSMALLINT currpos; + + at_rec = backsql_ad2at( oc, at->a_desc ); + + if ( at_rec == NULL ) { + Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " + "attribute \"%s\" is not registered " + "in objectclass \"%s\"\n", + op->oq_add.rs_e->e_name.bv_val, + at->a_desc->ad_cname.bv_val, + BACKSQL_OC_NAME( oc ) ); + + if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) { + rs->sr_text = "operation not permitted " + "within namingContext"; + return rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + } + + return LDAP_SUCCESS; + } + + if ( at_rec->bam_add_proc == NULL ) { + Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " + "add procedure is not defined " + "for attribute \"%s\" " + "of structuralObjectClass \"%s\"\n", + op->oq_add.rs_e->e_name.bv_val, + at->a_desc->ad_cname.bv_val, + BACKSQL_OC_NAME( oc ) ); + + if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) { + rs->sr_text = "operation not permitted " + "within namingContext"; + return rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + } + + return LDAP_SUCCESS; + } + + for ( i = 0, at_val = &at->a_vals[ i ]; + at_val->bv_val != NULL; + i++, at_val = &at->a_vals[ i ] ) + { + char logbuf[] = "val[18446744073709551615UL], id=18446744073709551615UL"; + + /* + * Do not deal with the objectClass that is used + * to build the entry + */ + if ( at->a_desc == slap_schema.si_ad_objectClass ) { + if ( bvmatch( at_val, &oc->bom_oc->soc_cname ) ) + { + continue; + } + } + +#ifdef BACKSQL_REALLOC_STMT + rc = backsql_Prepare( dbh, sth, at_rec->bam_add_proc, 0 ); + if ( rc != SQL_SUCCESS ) { + + if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) { + rs->sr_text = "SQL-backend error"; + return rs->sr_err = LDAP_OTHER; + } + + return LDAP_SUCCESS; + } +#endif /* BACKSQL_REALLOC_STMT */ + + if ( BACKSQL_IS_ADD( at_rec->bam_expect_return ) ) { + pno = 1; + SQLBindParameter( *sth, 1, SQL_PARAM_OUTPUT, + SQL_C_ULONG, SQL_INTEGER, + 0, 0, &prc, 0, 0 ); + } else { + pno = 0; + } + + po = ( BACKSQL_IS_ADD( at_rec->bam_param_order ) ) > 0; + currpos = pno + 1 + po; + SQLBindParameter( *sth, currpos, + SQL_PARAM_INPUT, SQL_C_ULONG, + SQL_INTEGER, 0, 0, &new_keyval, 0, 0 ); + currpos = pno + 2 - po; + + /* + * check for syntax needed here + * maybe need binary bind? + */ + + backsql_BindParamStr( *sth, currpos, + at_val->bv_val, at_val->bv_len + 1 ); + +#ifdef LDAP_DEBUG + snprintf( logbuf, sizeof( logbuf ), "val[%d], id=%ld", + i, new_keyval ); + Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " + "executing \"%s\" %s\n", + op->oq_add.rs_e->e_name.bv_val, + at_rec->bam_add_proc, logbuf ); +#endif +#ifndef BACKSQL_REALLOC_STMT + rc = SQLExecDirect( *sth, at_rec->bam_add_proc, SQL_NTS ); +#else /* BACKSQL_REALLOC_STMT */ + rc = SQLExecute( *sth ); +#endif /* BACKSQL_REALLOC_STMT */ + if ( rc != SQL_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, + " backsql_add(\"%s\"): " + "add_proc execution failed\n", + op->oq_add.rs_e->e_name.bv_val, 0, 0 ); + backsql_PrintErrors( bi->db_env, dbh, *sth, rc ); + + if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) { + rs->sr_text = "SQL-backend error"; + return rs->sr_err = LDAP_OTHER; + } + } +#ifndef BACKSQL_REALLOC_STMT + SQLFreeStmt( *sth, SQL_RESET_PARAMS ); +#else /* BACKSQL_REALLOC_STMT */ + SQLFreeStmt( *sth, SQL_DROP ); +#endif /* BACKSQL_REALLOC_STMT */ + } + + return LDAP_SUCCESS; +} + int backsql_add( Operation *op, SlapReply *rs ) { @@ -522,7 +674,8 @@ backsql_add( Operation *op, SlapReply *rs ) backsql_at_map_rec *at_rec = NULL; backsql_entryID parent_id = BACKSQL_ENTRYID_INIT; Entry p; - Attribute *at; + Attribute *at, + *at_objectClass = NULL; struct berval *at_val; struct berval pdn; /* first parameter #, parameter order */ @@ -879,141 +1032,23 @@ backsql_add( Operation *op, SlapReply *rs ) /* * Skip: * - the first occurrence of objectClass, which is used - * to determine how to bulid the SQL entry (FIXME ?!?) + * to determine how to build the SQL entry (FIXME ?!?) * - operational attributes - * empty attributes (FIXME ?!?) + * - empty attributes (FIXME ?!?) */ if ( backsql_attr_skip( at->a_desc, at->a_vals ) ) { continue; } - at_rec = backsql_ad2at( oc, at->a_desc ); - - if ( at_rec == NULL ) { - Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " - "attribute \"%s\" is not registered " - "in objectclass \"%s\"\n", - op->oq_add.rs_e->e_name.bv_val, - at->a_desc->ad_cname.bv_val, - BACKSQL_OC_NAME( oc ) ); - - if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) { - rs->sr_err = LDAP_UNWILLING_TO_PERFORM; - rs->sr_text = "operation not permitted " - "within namingContext"; - goto done; - } - + if ( at->a_desc == slap_schema.si_ad_objectClass ) { + at_objectClass = at; continue; } - - if ( at_rec->bam_add_proc == NULL ) { - Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " - "add procedure is not defined " - "for attribute \"%s\" " - "of structuralObjectClass \"%s\"\n", - op->oq_add.rs_e->e_name.bv_val, - at->a_desc->ad_cname.bv_val, - BACKSQL_OC_NAME( oc ) ); - if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) { - rs->sr_err = LDAP_UNWILLING_TO_PERFORM; - rs->sr_text = "operation not permitted " - "within namingContext"; - goto done; - } - - continue; - } - - for ( i = 0, at_val = &at->a_vals[ i ]; - at_val->bv_val != NULL; - i++, at_val = &at->a_vals[ i ] ) - { - char logbuf[] = "val[18446744073709551615UL], id=18446744073709551615UL"; - -#ifdef BACKSQL_REALLOC_STMT - rc = backsql_Prepare( dbh, &sth, at_rec->bam_add_proc, 0 ); - if ( rc != SQL_SUCCESS ) { - - if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) { - rs->sr_err = LDAP_OTHER; - rs->sr_text = "SQL-backend error"; - goto done; - } - - goto next_attr; - } -#endif /* BACKSQL_REALLOC_STMT */ - - if ( BACKSQL_IS_ADD( at_rec->bam_expect_return ) ) { - pno = 1; - SQLBindParameter( sth, 1, SQL_PARAM_OUTPUT, - SQL_C_ULONG, SQL_INTEGER, - 0, 0, &prc, 0, 0 ); - } else { - pno = 0; - } - - po = ( BACKSQL_IS_ADD( at_rec->bam_param_order ) ) > 0; - currpos = pno + 1 + po; - SQLBindParameter( sth, currpos, - SQL_PARAM_INPUT, SQL_C_ULONG, - SQL_INTEGER, 0, 0, &new_keyval, 0, 0 ); - currpos = pno + 2 - po; - - /* - * Do not deal with the objectClass that is used - * to build the entry - */ - if ( at->a_desc == slap_schema.si_ad_objectClass ) { - if ( bvmatch( at_val, &oc->bom_oc->soc_cname ) ) { - continue; - } - } - - /* - * check for syntax needed here - * maybe need binary bind? - */ - - backsql_BindParamStr( sth, currpos, - at_val->bv_val, at_val->bv_len + 1 ); - -#ifdef LDAP_DEBUG - snprintf( logbuf, sizeof( logbuf ), "val[%d], id=%ld", - i, new_keyval ); - Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " - "executing \"%s\" %s\n", - op->oq_add.rs_e->e_name.bv_val, - at_rec->bam_add_proc, logbuf ); -#endif -#ifndef BACKSQL_REALLOC_STMT - rc = SQLExecDirect( sth, at_rec->bam_add_proc, SQL_NTS ); -#else /* BACKSQL_REALLOC_STMT */ - rc = SQLExecute( sth ); -#endif /* BACKSQL_REALLOC_STMT */ - if ( rc != SQL_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - " backsql_add(\"%s\"): " - "add_proc execution failed\n", - op->oq_add.rs_e->e_name.bv_val, 0, 0 ); - backsql_PrintErrors( bi->db_env, dbh, sth, rc ); - - if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) { - rs->sr_err = LDAP_OTHER; - rs->sr_text = "SQL-backend error"; - goto done; - } - } -#ifndef BACKSQL_REALLOC_STMT - SQLFreeStmt( sth, SQL_RESET_PARAMS ); -#else /* BACKSQL_REALLOC_STMT */ - SQLFreeStmt( sth, SQL_DROP ); -#endif /* BACKSQL_REALLOC_STMT */ + rs->sr_err = backsql_add_attr( op, rs, dbh, &sth, oc, at, new_keyval ); + if ( rs->sr_err != LDAP_SUCCESS ) { + goto done; } - -next_attr:; } #ifdef BACKSQL_REALLOC_STMT @@ -1068,14 +1103,27 @@ next_attr:; rs->sr_text = "SQL-backend error"; goto done; } - + + /* FIXME: need ldap_entries.id of newly added entry */ + if ( at_objectClass ) { + rs->sr_err = backsql_add_attr( op, rs, dbh, &sth, oc, at_objectClass, new_keyval ); + if ( rs->sr_err != LDAP_SUCCESS ) { + goto done; + } + } + SQLFreeStmt( sth, SQL_DROP ); +done:; /* * Commit only if all operations succeed */ - SQLTransact( SQL_NULL_HENV, dbh, - op->o_noop ? SQL_ROLLBACK : SQL_COMMIT ); + if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) { + SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT ); + } else { + SQLTransact( SQL_NULL_HENV, dbh, SQL_ROLLBACK ); + + } /* * FIXME: NOOP does not work for add -- it works for all @@ -1088,7 +1136,6 @@ next_attr:; * in deleting that row. */ -done:; send_ldap_result( op, rs ); if ( !BER_BVISNULL( &realdn ) diff --git a/servers/slapd/back-sql/entry-id.c b/servers/slapd/back-sql/entry-id.c index 747f8bf968..b6cecd659e 100644 --- a/servers/slapd/back-sql/entry-id.c +++ b/servers/slapd/back-sql/entry-id.c @@ -341,6 +341,18 @@ backsql_get_attr_vals( void *v_at, void *v_bsi ) return 1; } +#ifdef BACKSQL_TRACE +#ifdef BACKSQL_ARBITRARY_KEY + Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): " + "query=%s keyval=%s\n", at->bam_query, + bsi->bsi_c_eid->eid_keyval.bv_val, 0 ); +#else /* !BACKSQL_ARBITRARY_KEY */ + Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): " + "query=%s keyval=%d\n", at->bam_query, + bsi->bsi_c_eid->eid_keyval, 0 ); +#endif /* ! BACKSQL_ARBITRARY_KEY */ +#endif /* BACKSQL_TRACE */ + rc = SQLExecute( sth ); if ( ! BACKSQL_SUCCESS( rc ) ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): " diff --git a/servers/slapd/back-sql/external.h b/servers/slapd/back-sql/external.h index 527172aa1b..57c05321be 100644 --- a/servers/slapd/back-sql/external.h +++ b/servers/slapd/back-sql/external.h @@ -23,7 +23,7 @@ LDAP_BEGIN_DECL -extern BI_init sql_back_initialize; +extern BI_init backsql_initialize; extern BI_destroy backsql_destroy; extern BI_db_init backsql_db_init; diff --git a/servers/slapd/back-sql/init.c b/servers/slapd/back-sql/init.c index d2d0e98083..f92406278b 100644 --- a/servers/slapd/back-sql/init.c +++ b/servers/slapd/back-sql/init.c @@ -41,7 +41,7 @@ init_module( memset( &bi, '\0', sizeof( bi ) ); bi.bi_type = "sql"; - bi.bi_init = sql_back_initialize; + bi.bi_init = backsql_initialize; backend_add( &bi ); return 0; @@ -50,7 +50,7 @@ init_module( #endif /* SLAPD_SQL == SLAPD_MOD_DYNAMIC */ int -sql_back_initialize( +backsql_initialize( BackendInfo *bi ) { static char *controls[] = { @@ -177,7 +177,7 @@ backsql_db_open( ber_len_t idq_len; struct berbuf bb = BB_NULL; - Operation otmp; + Operation otmp = { 0 }; Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): " "testing RDBMS connection\n", 0, 0, 0 ); @@ -383,7 +383,7 @@ backsql_db_open( si->delentry_query = ch_strdup( backsql_def_delentry_query ); } - otmp.o_connid = -1; + otmp.o_connid = (unsigned long)(-1); otmp.o_bd = bd; if ( backsql_get_db_conn( &otmp, &dbh ) != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " @@ -399,6 +399,7 @@ backsql_db_open( if ( si->upper_func.bv_val == NULL ) { backsql_strcat( &bb, backsql_id_query, "dn=?", NULL ); + } else { if ( BACKSQL_HAS_LDAPINFO_DN_RU( si ) ) { backsql_strcat( &bb, backsql_id_query, @@ -461,13 +462,14 @@ backsql_db_close( int backsql_connection_destroy( Backend *bd, Connection *c ) { - Operation o; + Operation o = { 0 }; o.o_bd = bd; o.o_connid = c->c_connid; Debug( LDAP_DEBUG_TRACE, "==>backsql_connection_destroy()\n", 0, 0, 0 ); backsql_free_db_conn( &o ); Debug( LDAP_DEBUG_TRACE, "<==backsql_connection_destroy()\n", 0, 0, 0 ); + return 0; } diff --git a/servers/slapd/back-sql/rdbms_depend/mysql/testdb_metadata.sql b/servers/slapd/back-sql/rdbms_depend/mysql/testdb_metadata.sql index 4958b1fc16..8933a4c878 100644 --- a/servers/slapd/back-sql/rdbms_depend/mysql/testdb_metadata.sql +++ b/servers/slapd/back-sql/rdbms_depend/mysql/testdb_metadata.sql @@ -66,6 +66,11 @@ values (10,2,'documentIdentifier','concat(''document '',documents.id)','document insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (11,3,'o','institutes.name','institutes',NULL,NULL,NULL,3,0); +insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) +values (12,3,'dc','lower(institutes.name)','institutes,ldap_entries AS dcObject,ldap_entry_objclasses as auxObjectClass', + 'institutes.id=dcObject.keyval AND dcObject.oc_map_id=3 AND dcObject.id=auxObjectClass.entry_id AND auxObjectClass.oc_name=''dcObject''', + NULL,NULL,3,0); + -- entries mapping: each entry must appear in this table, with a unique DN rooted at the database naming context -- id a unique number > 0 identifying the entry -- dn the DN of the entry, in "pretty" form @@ -73,32 +78,32 @@ values (11,3,'o','institutes.name','institutes',NULL,NULL,NULL,3,0); -- parent the "ldap_entries.id" of the parent of this objectClass; 0 if it is the "suffix" of the database -- keyval the value of the "keytbl.keycol" defined for this objectClass insert into ldap_entries (id,dn,oc_map_id,parent,keyval) -values (1,'o=Example,c=RU',3,0,1); +values (1,'dc=example,dc=com',3,0,1); insert into ldap_entries (id,dn,oc_map_id,parent,keyval) -values (2,'cn=Mitya Kovalev,o=Example,c=RU',1,1,1); +values (2,'cn=Mitya Kovalev,dc=example,dc=com',1,1,1); insert into ldap_entries (id,dn,oc_map_id,parent,keyval) -values (3,'cn=Torvlobnor Puzdoy,o=Example,c=RU',1,1,2); +values (3,'cn=Torvlobnor Puzdoy,dc=example,dc=com',1,1,2); insert into ldap_entries (id,dn,oc_map_id,parent,keyval) -values (4,'cn=Akakiy Zinberstein,o=Example,c=RU',1,1,3); +values (4,'cn=Akakiy Zinberstein,dc=example,dc=com',1,1,3); insert into ldap_entries (id,dn,oc_map_id,parent,keyval) -values (5,'documentTitle=book1,o=Example,c=RU',2,1,1); +values (5,'documentTitle=book1,dc=example,dc=com',2,1,1); insert into ldap_entries (id,dn,oc_map_id,parent,keyval) -values (6,'documentTitle=book2,o=Example,c=RU',2,1,2); +values (6,'documentTitle=book2,dc=example,dc=com',2,1,2); -- objectClass mapping: entries that have multiple objectClass instances are listed here with the objectClass name (view them as auxiliary objectClass) -- entry_id the "ldap_entries.id" of the entry this objectClass value must be added -- oc_name the name of the objectClass; it MUST match the name of an objectClass that is loaded in slapd's schema insert into ldap_entry_objclasses (entry_id,oc_name) -values (4,'referral'); +values (1,'dcObject'); insert into ldap_entry_objclasses (entry_id,oc_name) -values (2,'posixAccount'); +values (4,'referral'); -- referrals mapping: entries that should be treated as referrals are stored here -- entry_id the "ldap_entries.id" of the entry that should be treated as a referral diff --git a/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql b/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql index d42103370a..cf2ffa452f 100644 --- a/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql +++ b/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql @@ -47,6 +47,8 @@ insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where, insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (11,3,'o','institutes.name','institutes',NULL,'update institutes set name=? where id=?',NULL,3,0); +insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (12,3,'dc','lower(institutes.name)','institutes,ldap_entries AS dcObject,ldap_entry_objclasses as auxObjectClass','institutes.id=dcObject.keyval AND dcObject.oc_map_id=3 AND dcObject.id=auxObjectClass.entry_id AND auxObjectClass.oc_name=''dcObject''',NULL,NULL,3,0); + -- entries mapping: each entry must appear in this table, with a unique DN rooted at the database naming context -- id a unique number > 0 identifying the entry @@ -54,25 +56,25 @@ insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where, -- oc_map_id the "ldap_oc_mappings.id" of the main objectClass of this entry (view it as the structuralObjectClass) -- parent the "ldap_entries.id" of the parent of this objectClass; 0 if it is the "suffix" of the database -- keyval the value of the "keytbl.keycol" defined for this objectClass -insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (1,'o=Example,c=RU',3,0,1); +insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (1,'dc=example,dc=com',3,0,1); -insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (2,'cn=Mitya Kovalev,o=Example,c=RU',1,1,1); +insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (2,'cn=Mitya Kovalev,dc=example,dc=com',1,1,1); -insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (3,'cn=Torvlobnor Puzdoy,o=Example,c=RU',1,1,2); +insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (3,'cn=Torvlobnor Puzdoy,dc=example,dc=com',1,1,2); -insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (4,'cn=Akakiy Zinberstein,o=Example,c=RU',1,1,3); +insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (4,'cn=Akakiy Zinberstein,dc=example,dc=com',1,1,3); -insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (5,'documentTitle=book1,o=Example,c=RU',2,1,1); +insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (5,'documentTitle=book1,dc=example,dc=com',2,1,1); -insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (6,'documentTitle=book2,o=Example,c=RU',2,1,2); +insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (6,'documentTitle=book2,dc=example,dc=com',2,1,2); -- objectClass mapping: entries that have multiple objectClass instances are listed here with the objectClass name (view them as auxiliary objectClass) -- entry_id the "ldap_entries.id" of the entry this objectClass value must be added -- oc_name the name of the objectClass; it MUST match the name of an objectClass that is loaded in slapd's schema -insert into ldap_entry_objclasses (entry_id,oc_name) values (4,'referral'); +insert into ldap_entry_objclasses (entry_id,oc_name) values (1,'dcObject'); -insert into ldap_entry_objclasses (entry_id,oc_name) values (2,'posixAccount'); +insert into ldap_entry_objclasses (entry_id,oc_name) values (4,'referral'); -- referrals mapping: entries that should be treated as referrals are stored here -- entry_id the "ldap_entries.id" of the entry that should be treated as a referral @@ -85,7 +87,7 @@ create function create_person () returns int as ' select setval (''persons_id_seq'', (select case when max(id) is null then 1 else max(id) end from persons)); insert into persons (id,name,surname) - values (nextval(''persons_id_seq''),'''',''''); + values ((select case when max(id) is null then 1 else nextval(''persons_id_seq'') end from persons),'''',''''); select max(id) from persons ' language 'sql'; @@ -110,6 +112,8 @@ as ' delete from phones where pers_id = $1; delete from authors_docs where pers_id = $1; delete from persons where id = $1; + delete from ldap_entry_objclasses where entry_id=(select id from ldap_entries where oc_map_id=1 and keyval = $1); + delete from ldap_referrals where entry_id=(select id from ldap_entries where oc_map_id=1 and keyval = $1); select $1 as return ' language 'sql'; @@ -131,13 +135,15 @@ create function create_doc () returns int as ' select setval (''documents_id_seq'', (select case when max(id) is null then 1 else max(id) end from documents)); insert into documents (id,title,abstract) - values (nextval(''documents_id_seq''),'''',''''); + values ((select case when max(id) is null then 1 else nextval(''documents_id_seq'') end from documents),'''',''''); select max(id) from documents ' language 'sql'; create function delete_doc (int) returns int as ' delete from documents where id = $1; + delete from ldap_entry_objclasses where entry_id=(select id from ldap_entries where oc_map_id=2 and keyval = $1); + delete from ldap_referrals where entry_id=(select id from ldap_entries where oc_map_id=2 and keyval = $1); select $1 as return ' language 'sql'; @@ -145,13 +151,15 @@ create function create_o () returns int as ' select setval (''institutes_id_seq'', (select case when max(id) is null then 1 else max(id) end from institutes)); insert into institutes (id,name) - values (nextval(''institutes_id_seq''),''''); + values ((select case when max(id) is null then 1 else nextval(''institutes_id_seq'') end from institutes),''''); select max(id) from institutes ' language 'sql'; create function delete_o (int) returns int as ' delete from institutes where id = $1; + delete from ldap_entry_objclasses where entry_id=(select id from ldap_entries where oc_map_id=3 and keyval = $1); + delete from ldap_referrals where entry_id=(select id from ldap_entries where oc_map_id=3 and keyval = $1); select $1 as return ' language 'sql'; diff --git a/servers/slapd/back-sql/schema-map.c b/servers/slapd/back-sql/schema-map.c index e7d701b8bc..29b1e06a0a 100644 --- a/servers/slapd/back-sql/schema-map.c +++ b/servers/slapd/back-sql/schema-map.c @@ -33,24 +33,34 @@ #define BACKSQL_DUPLICATE (-1) +/* NOTE: by default, cannot just compare pointers because + * objectClass/attributeType order would be machine-dependent + * (and tests would fail!); however, if you don't want to run + * tests, or see attributeTypes written in the same order + * they are defined, define */ +/* #undef BACKSQL_USE_PTR_CMP */ + /* * Uses the pointer to the ObjectClass structure */ static int backsql_cmp_oc( const void *v_m1, const void *v_m2 ) { - const backsql_oc_map_rec *m1 = v_m1, *m2 = v_m2; + const backsql_oc_map_rec *m1 = v_m1, + *m2 = v_m2; -#if 0 +#ifdef BACKSQL_USE_PTR_CMP return SLAP_PTRCMP( m1->bom_oc, m2->bom_oc ); -#endif +#else /* ! BACKSQL_USE_PTR_CMP */ return ber_bvcmp( &m1->bom_oc->soc_cname, &m2->bom_oc->soc_cname ); +#endif /* ! BACKSQL_USE_PTR_CMP */ } static int backsql_cmp_oc_id( const void *v_m1, const void *v_m2 ) { - const backsql_oc_map_rec *m1 = v_m1, *m2 = v_m2; + const backsql_oc_map_rec *m1 = v_m1, + *m2 = v_m2; return ( m1->bom_id < m2->bom_id ? -1 : ( m1->bom_id > m2->bom_id ? 1 : 0 ) ); } @@ -61,21 +71,27 @@ backsql_cmp_oc_id( const void *v_m1, const void *v_m2 ) static int backsql_cmp_attr( const void *v_m1, const void *v_m2 ) { - const backsql_at_map_rec *m1 = v_m1, *m2 = v_m2; + const backsql_at_map_rec *m1 = v_m1, + *m2 = v_m2; -#if 0 +#ifdef BACKSQL_USE_PTR_CMP return SLAP_PTRCMP( m1->bam_ad, m2->bam_ad ); -#endif +#else /* ! BACKSQL_USE_PTR_CMP */ return ber_bvcmp( &m1->bam_ad->ad_cname, &m2->bam_ad->ad_cname ); +#endif /* ! BACKSQL_USE_PTR_CMP */ } int backsql_dup_attr( void *v_m1, void *v_m2 ) { - backsql_at_map_rec *m1 = v_m1, *m2 = v_m2; + backsql_at_map_rec *m1 = v_m1, + *m2 = v_m2; assert( m1->bam_ad == m2->bam_ad ); - + + /* duplicate definitions of attributeTypes are appended; + * this allows to define multiple rules for the same + * attributeType. Use with care! */ for ( ; m1->bam_next ; m1 = m1->bam_next ); m1->bam_next = m2; m2->bam_next = NULL; @@ -103,7 +119,7 @@ backsql_make_attr_query( &oc_map->bom_keycol, (ber_len_t)STRLENOF( "=?" ), "=?" ); - if ( at_map->bam_join_where.bv_val != NULL ) { + if ( !BER_BVISNULL( &at_map->bam_join_where ) ) { backsql_strfcat( &bb, "lb", (ber_len_t)STRLENOF( " AND " ), " AND ", &at_map->bam_join_where ); @@ -140,23 +156,56 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map ) backsql_merge_from_clause( &bb, &oc_map->bom_keytbl ); at_map->bam_from_tbls = bb.bb_val; - bb.bb_val.bv_val = NULL; - bb.bb_val.bv_len = 0; + BER_BVZERO( &bb.bb_val ); bb.bb_len = 0; backsql_strfcat( &bb, "lbcblb", - (ber_len_t)STRLENOF( "ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entries.keyval=" ), - "ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entries.keyval=", + (ber_len_t)STRLENOF( "ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entries.keyval=" ), + "ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entries.keyval=", &oc_map->bom_keytbl, '.', &oc_map->bom_keycol, (ber_len_t)STRLENOF( " and ldap_entries.oc_map_id=" ), " and ldap_entries.oc_map_id=", &sbv ); + at_map->bam_join_where = bb.bb_val; at_map->bam_oc = oc_map->bom_oc; - at_map->bam_join_where = bb.bb_val; + at_map->bam_add_proc = NULL; + { + char tmp[] = + "INSERT INTO ldap_entry_objclasses " + "(entry_id,oc_name) VALUES " + "((SELECT id FROM ldap_entries " + "WHERE oc_map_id=" + "18446744073709551615UL " /* 64 bit ULONG */ + "AND keyval=?),?)"; + snprintf( tmp, sizeof(tmp), + "INSERT INTO ldap_entry_objclasses " + "(entry_id,oc_name) VALUES " + "((SELECT id FROM ldap_entries " + "WHERE oc_map_id=%lu " + "AND keyval=?),?)", oc_map->bom_id ); + at_map->bam_add_proc = ch_strdup( tmp ); + } + at_map->bam_delete_proc = NULL; + { + char tmp[] = + "DELETE FROM ldap_entry_objclasses " + "WHERE entry_id=(SELECT id FROM ldap_entries " + "WHERE oc_map_id=" + "18446744073709551615UL " /* 64 bit ULONG */ + "AND keyval=?) AND oc_name=?"; + snprintf( tmp, sizeof(tmp), + "DELETE FROM ldap_entry_objclasses " + "WHERE entry_id=(SELECT id FROM ldap_entries " + "WHERE oc_map_id=%lu" + "AND keyval=?) AND oc_name=?", + oc_map->bom_id ); + at_map->bam_delete_proc = ch_strdup( tmp ); + } + at_map->bam_param_order = 0; at_map->bam_expect_return = 0; at_map->bam_next = NULL; @@ -169,6 +218,22 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map ) oc_map->bom_oc->soc_cname.bv_val, 0 ); } + /* FIXME: whe need to correct the objectClass join_where + * after the attribute query is built */ + ch_free( at_map->bam_join_where.bv_val ); + BER_BVZERO( &bb.bb_val ); + bb.bb_len = 0; + backsql_strfcat( &bb, "lbcblb", + (ber_len_t)STRLENOF( "ldap_entries.keyval=" ), + "ldap_entries.keyval=", + &oc_map->bom_keytbl, + '.', + &oc_map->bom_keycol, + (ber_len_t)STRLENOF( " AND ldap_entries.oc_map_id=" ), + " AND ldap_entries.oc_map_id=", + &sbv ); + at_map->bam_join_where = bb.bb_val; + /* referral attribute */ at_map = (backsql_at_map_rec *)ch_calloc( 1, sizeof( backsql_at_map_rec ) ); @@ -181,23 +246,57 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map ) backsql_merge_from_clause( &bb, &oc_map->bom_keytbl ); at_map->bam_from_tbls = bb.bb_val; - bb.bb_val.bv_val = NULL; - bb.bb_val.bv_len = 0; + BER_BVZERO( &bb.bb_val ); bb.bb_len = 0; backsql_strfcat( &bb, "lbcblb", - (ber_len_t)STRLENOF( "ldap_entries.id=ldap_referrals.entry_id and ldap_entries.keyval=" ), - "ldap_entries.id=ldap_referrals.entry_id and ldap_entries.keyval=", + (ber_len_t)STRLENOF( "ldap_entries.id=ldap_referrals.entry_id AND ldap_entries.keyval=" ), + "ldap_entries.id=ldap_referrals.entry_id AND ldap_entries.keyval=", &oc_map->bom_keytbl, '.', &oc_map->bom_keycol, - (ber_len_t)STRLENOF( " and ldap_entries.oc_map_id=" ), - " and ldap_entries.oc_map_id=", + (ber_len_t)STRLENOF( " AND ldap_entries.oc_map_id=" ), + " AND ldap_entries.oc_map_id=", &sbv ); - at_map->bam_oc = NULL; at_map->bam_join_where = bb.bb_val; + + at_map->bam_oc = NULL; + at_map->bam_add_proc = NULL; + { + char tmp[] = + "INSERT INTO ldap_referrals " + "(entry_id,url) VALUES " + "((SELECT id FROM ldap_entries " + "WHERE oc_map_id=" + "18446744073709551615UL " /* 64 bit ULONG */ + "AND keyval=?),?)"; + snprintf( tmp, sizeof(tmp), + "INSERT INTO ldap_referrals " + "(entry_id,url) VALUES " + "((SELECT id FROM ldap_entries " + "WHERE oc_map_id=%lu " + "AND keyval=?),?)", oc_map->bom_id ); + at_map->bam_add_proc = ch_strdup( tmp ); + } + at_map->bam_delete_proc = NULL; + { + char tmp[] = + "DELETE FROM ldap_referrals " + "WHERE entry_id=(SELECT id FROM ldap_entries " + "WHERE oc_map_id=" + "18446744073709551615UL " /* 64 bit ULONG */ + "AND keyval=?) and url=?"; + snprintf( tmp, sizeof(tmp), + "DELETE FROM ldap_referrals " + "WHERE entry_id=(SELECT id FROM ldap_entries " + "WHERE oc_map_id=%lu" + "AND keyval=?) and url=?", + oc_map->bom_id ); + at_map->bam_delete_proc = ch_strdup( tmp ); + } + at_map->bam_param_order = 0; at_map->bam_expect_return = 0; at_map->bam_next = NULL; @@ -295,8 +394,7 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas ) ber_str2bv( at_row.cols[ 1 ], 0, 1, &at_map->bam_sel_expr ); if ( at_row.value_len[ 8 ] < 0 ) { - at_map->bam_sel_expr_u.bv_val = NULL; - at_map->bam_sel_expr_u.bv_len = 0; + BER_BVZERO( &at_map->bam_sel_expr_u ); } else { ber_str2bv( at_row.cols[ 8 ], 0, 1, @@ -307,8 +405,7 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas ) backsql_merge_from_clause( &bb, &bv ); at_map->bam_from_tbls = bb.bb_val; if ( at_row.value_len[ 3 ] < 0 ) { - at_map->bam_join_where.bv_val = NULL; - at_map->bam_join_where.bv_len = 0; + BER_BVZERO( &at_map->bam_join_where ); } else { ber_str2bv( at_row.cols[ 3 ], 0, 1, @@ -339,7 +436,9 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas ) oc_map->bom_oc->soc_cname.bv_val, 0 ); } - if ( bas->bas_si->upper_func.bv_val && at_map->bam_sel_expr_u.bv_val == NULL ) { + if ( !BER_BVISNULL( &bas->bas_si->upper_func ) && + BER_BVISNULL( &at_map->bam_sel_expr_u ) ) + { struct berbuf bb = BB_NULL; backsql_strfcat( &bb, "bcbc", @@ -353,6 +452,12 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas ) backsql_FreeRow( &at_row ); SQLFreeStmt( bas->bas_sth, SQL_CLOSE ); + Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(\"%s\"): " + "autoadding 'objectClass' and 'ref' mappings\n", + BACKSQL_OC_NAME( oc_map ), 0, 0 ); + + (void)backsql_add_sysmaps( oc_map ); + return BACKSQL_AVL_CONTINUE; } @@ -481,12 +586,6 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh ) "add=%d, del=%d; attributes:\n", BACKSQL_IS_ADD( oc_map->bom_expect_return ), BACKSQL_IS_DEL( oc_map->bom_expect_return ), 0 ); - - Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): " - "autoadding 'objectClass' and 'ref' mappings\n", - 0, 0, 0 ); - - backsql_add_sysmaps( oc_map ); } backsql_FreeRow( &oc_row ); @@ -736,10 +835,10 @@ backsql_free_attr( void *v_at ) Debug( LDAP_DEBUG_TRACE, "==>free_attr(): \"%s\"\n", at->bam_ad->ad_cname.bv_val, 0, 0 ); ch_free( at->bam_sel_expr.bv_val ); - if ( at->bam_from_tbls.bv_val != NULL ) { + if ( !BER_BVISNULL( &at->bam_from_tbls ) ) { ch_free( at->bam_from_tbls.bv_val ); } - if ( at->bam_join_where.bv_val != NULL ) { + if ( !BER_BVISNULL( &at->bam_join_where ) ) { ch_free( at->bam_join_where.bv_val ); } if ( at->bam_add_proc != NULL ) { @@ -753,7 +852,7 @@ backsql_free_attr( void *v_at ) } /* TimesTen */ - if ( at->bam_sel_expr_u.bv_val ) { + if ( !BER_BVISNULL( &at->bam_sel_expr_u ) ) { ch_free( at->bam_sel_expr_u.bv_val ); } diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index ed43829b12..7f9c4ab8ab 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -25,6 +25,7 @@ #include #include #include "ac/string.h" +#include "ac/ctype.h" #include "slap.h" #include "lber_pvt.h" @@ -142,6 +143,7 @@ backsql_init_search( } else if ( BACKSQL_NCMP( &p->an_name, &NoAttrs ) == 0 ) { continue; + } else if ( p->an_desc == slap_schema.si_ad_objectClass ) { is_oc = 1; } @@ -409,11 +411,55 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, } backsql_strfcat( &bsi->bsi_flt_where, "l", - (ber_len_t)sizeof( /* (' */ "')" ) - 1, /* ( */ "')" ); + (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); return 1; } +static int +backsql_merge_from_tbls( backsql_srch_info *bsi, struct berval *from_tbls ) +{ + if ( BER_BVISNULL( from_tbls ) ) { + return LDAP_SUCCESS; + } + + if ( !BER_BVISNULL( &bsi->bsi_from.bb_val ) ) { + char *start, *end, *tmp; + + tmp = ch_strdup( from_tbls->bv_val ); + + for ( start = tmp, end = strchr( start, ',' ); start; ) { + if ( end ) { + end[0] = '\0'; + } + + if ( strstr( bsi->bsi_from.bb_val.bv_val, start) == NULL ) + { + backsql_strfcat( &bsi->bsi_from, "cs", ',', start ); + } + + if ( end ) { + /* in case there are spaces after the comma... */ + for ( start = &end[1]; isspace( start[0] ); start++ ); + if ( start[0] ) { + end = strchr( start, ',' ); + } else { + start = NULL; + } + } else { + start = NULL; + } + } + + ch_free( tmp ); + + } else { + backsql_strfcat( &bsi->bsi_from, "b", from_tbls ); + } + + return LDAP_SUCCESS; +} + static int backsql_process_filter( backsql_srch_info *bsi, Filter *f ) { @@ -446,7 +492,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) case LDAP_FILTER_NOT: backsql_strfcat( &bsi->bsi_flt_where, "l", - (ber_len_t)sizeof( "NOT (" /* ) */ ) - 1, + (ber_len_t)STRLENOF( "NOT (" /* ) */ ), "NOT (" /* ) */ ); rc = backsql_process_filter( bsi, f->f_not ); backsql_strfcat( &bsi->bsi_flt_where, "c", /* ( */ ')' ); @@ -523,19 +569,32 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) * - a search for "top" will return everything */ if ( is_object_subclass( oc, bsi->bsi_oc->bom_oc ) ) { - goto filter_oc_success; + static struct berval ldap_entry_objclasses = BER_BVC( "ldap_entry_objclasses" ); + + backsql_merge_from_tbls( bsi, &ldap_entry_objclasses ); + + backsql_strfcat( &bsi->bsi_flt_where, "lbl", + (ber_len_t)STRLENOF( "1=1 OR (ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entry_objclasses.oc_name='" /* ') */ ), + "1=1 OR (ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entry_objclasses.oc_name='" /* ') */, + &bsi->bsi_oc->bom_oc->soc_cname, + (ber_len_t)STRLENOF( /* (' */ "')" ), + /* (' */ "')" ); + bsi->bsi_status = LDAP_SUCCESS; + rc = 1; + goto done; } break; } case LDAP_FILTER_PRESENT: -filter_oc_success:; backsql_strfcat( &bsi->bsi_flt_where, "l", (ber_len_t)STRLENOF( "1=1" ), "1=1" ); bsi->bsi_status = LDAP_SUCCESS; rc = 1; goto done; + + /* FIXME: LDAP_FILTER_EXT? */ default: Debug( LDAP_DEBUG_TRACE, @@ -675,7 +734,7 @@ backsql_process_filter_eq( backsql_srch_info *bsi, backsql_at_map_rec *at, backsql_strfcat( &bsi->bsi_flt_where, "bl", filter_value, - (ber_len_t)sizeof( /* (' */ "')" ) - 1, + (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); @@ -686,7 +745,7 @@ backsql_process_filter_eq( backsql_srch_info *bsi, backsql_at_map_rec *at, &at->bam_sel_expr, (ber_len_t)STRLENOF( "='" ), "='", filter_value, - (ber_len_t)sizeof( /* (' */ "')" ) - 1, + (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); } @@ -716,7 +775,7 @@ backsql_process_filter_like( backsql_srch_info *bsi, backsql_at_map_rec *at, backsql_strfcat( &bsi->bsi_flt_where, "bl", filter_value, - (ber_len_t)sizeof( /* (' */ "%')" ) - 1, + (ber_len_t)STRLENOF( /* (' */ "%')" ), /* (' */ "%')" ); ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); @@ -728,7 +787,7 @@ backsql_process_filter_like( backsql_srch_info *bsi, backsql_at_map_rec *at, (ber_len_t)STRLENOF( " LIKE '%" ), " LIKE '%", filter_value, - (ber_len_t)sizeof( /* (' */ "%')" ) - 1, + (ber_len_t)STRLENOF( /* (' */ "%')" ), /* (' */ "%')" ); } @@ -747,16 +806,18 @@ backsql_process_filter_attr( backsql_srch_info *bsi, Filter *f, backsql_at_map_r Debug( LDAP_DEBUG_TRACE, "==>backsql_process_filter_attr(%s)\n", at->bam_ad->ad_cname.bv_val, 0, 0 ); - backsql_merge_from_clause( &bsi->bsi_from, &at->bam_from_tbls ); - /* * need to add this attribute to list of attrs to load, * so that we can do test_filter() later */ backsql_attrlist_add( bsi, at->bam_ad ); + backsql_merge_from_tbls( bsi, &at->bam_from_tbls ); + if ( !BER_BVISNULL( &at->bam_join_where ) - && strstr( bsi->bsi_join_where.bb_val.bv_val, at->bam_join_where.bv_val ) == NULL ) { + && strstr( bsi->bsi_join_where.bb_val.bv_val, + at->bam_join_where.bv_val ) == NULL ) + { backsql_strfcat( &bsi->bsi_join_where, "lb", (ber_len_t)STRLENOF( " AND " ), " AND ", &at->bam_join_where ); @@ -855,7 +916,7 @@ equality_match:; backsql_strfcat( &bsi->bsi_flt_where, "bl", filter_value, - (ber_len_t)sizeof( /* (' */ "')" ) - 1, + (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); @@ -867,17 +928,17 @@ equality_match:; &ordering, '\'', &f->f_av_value, - (ber_len_t)sizeof( /* (' */ "')" ) - 1, + (ber_len_t)STRLENOF( /* (' */ "')" ), /* ( */ "')" ); } break; case LDAP_FILTER_PRESENT: backsql_strfcat( &bsi->bsi_flt_where, "lbl", - (ber_len_t)sizeof( "NOT (" /* ) */) - 1, + (ber_len_t)STRLENOF( "NOT (" /* ) */), "NOT (", /* ) */ &at->bam_sel_expr, - (ber_len_t)sizeof( /* ( */ " IS NULL)" ) - 1, + (ber_len_t)STRLENOF( /* ( */ " IS NULL)" ), /* ( */ " IS NULL)" ); break; @@ -943,10 +1004,10 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query ) if ( !BER_BVISNULL( &bi->strcast_func ) ) { backsql_strfcat( &bsi->bsi_sel, "blbl", &bi->strcast_func, - (ber_len_t)sizeof( "('" /* ') */ ) - 1, + (ber_len_t)STRLENOF( "('" /* ') */ ), "('" /* ') */ , &bsi->bsi_oc->bom_oc->soc_cname, - (ber_len_t)sizeof( /* (' */ "')" ) - 1, + (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); } else { backsql_strfcat( &bsi->bsi_sel, "cbc", @@ -1387,7 +1448,7 @@ backsql_search( Operation *op, SlapReply *rs ) if ( op->o_req_ndn.bv_len > BACKSQL_MAX_DN_LEN ) { Debug( LDAP_DEBUG_TRACE, "backsql_search(): " - "search base length (%ld) exceeds max length (%ld)\n", + "search base length (%ld) exceeds max length (%d)\n", op->o_req_ndn.bv_len, BACKSQL_MAX_DN_LEN, 0 ); /* * FIXME: a LDAP_NO_SUCH_OBJECT could be appropriate @@ -1501,6 +1562,32 @@ backsql_search( Operation *op, SlapReply *rs ) continue; } + /* check scope */ + switch ( op->ors_scope ) { + case LDAP_SCOPE_BASE: + case BACKSQL_SCOPE_BASE_LIKE: + if ( !bvmatch( &user_entry.e_nname, &op->o_req_ndn ) ) { + goto next_entry; + } + break; + + case LDAP_SCOPE_ONE: + { + struct berval rdn = user_entry.e_nname; + rdn.bv_len -= op->o_req_ndn.bv_len + STRLENOF( "," ); + if ( !dnIsOneLevelRDN( &rdn ) ) { + goto next_entry; + } + /* fall thru */ + } + + case LDAP_SCOPE_SUBTREE: + if ( !dnIsSuffix( &user_entry.e_nname, &op->o_req_ndn ) ) { + goto next_entry; + } + break; + } + if ( !manageDSAit && op->ors_scope != LDAP_SCOPE_BASE && op->ors_scope != BACKSQL_SCOPE_BASE_LIKE && diff --git a/servers/slapd/back-sql/sql-wrap.c b/servers/slapd/back-sql/sql-wrap.c index 86b4689316..7709f817de 100644 --- a/servers/slapd/back-sql/sql-wrap.c +++ b/servers/slapd/back-sql/sql-wrap.c @@ -145,6 +145,7 @@ backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row ) #endif /* BACKSQL_TRACE */ backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC, sth, rc ); + } else { #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: " @@ -270,6 +271,7 @@ int backsql_init_db_env( backsql_info *si ) { RETCODE rc; + int ret = SQL_SUCCESS; Debug( LDAP_DEBUG_TRACE, "==>backsql_init_db_env()\n", 0, 0, 0 ); rc = SQLAllocEnv( &si->db_env ); @@ -278,9 +280,10 @@ backsql_init_db_env( backsql_info *si ) 0, 0, 0 ); backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC, SQL_NULL_HENV, rc ); + ret = SQL_ERROR; } - Debug( LDAP_DEBUG_TRACE, "<==backsql_init_db_env()\n", 0, 0, 0 ); - return SQL_SUCCESS; + Debug( LDAP_DEBUG_TRACE, "<==backsql_init_db_env()=%d\n", ret, 0, 0 ); + return ret; } int @@ -303,7 +306,7 @@ backsql_free_db_env( backsql_info *si ) } static int -backsql_open_db_conn( backsql_info *si, int ldap_cid, backsql_db_conn **pdbc ) +backsql_open_db_conn( backsql_info *si, unsigned long ldap_cid, backsql_db_conn **pdbc ) { /* TimesTen */ char DBMSName[ 32 ]; @@ -389,7 +392,8 @@ int backsql_free_db_conn( Operation *op ) { backsql_info *si = (backsql_info *)op->o_bd->be_private; - backsql_db_conn tmp, *conn; + backsql_db_conn tmp = { 0 }, + *conn; Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_conn()\n", 0, 0, 0 ); tmp.ldap_cid = op->o_connid; @@ -414,8 +418,8 @@ int backsql_get_db_conn( Operation *op, SQLHDBC *dbh ) { backsql_info *si = (backsql_info *)op->o_bd->be_private; - backsql_db_conn *dbc; - backsql_db_conn tmp; + backsql_db_conn *dbc, + tmp = { 0 }; int rc = LDAP_SUCCESS; Debug( LDAP_DEBUG_TRACE, "==>backsql_get_db_conn()\n", 0, 0, 0 ); diff --git a/servers/slapd/back-sql/util.c b/servers/slapd/back-sql/util.c index 4fb534ae26..d70b884da3 100644 --- a/servers/slapd/back-sql/util.c +++ b/servers/slapd/back-sql/util.c @@ -173,7 +173,7 @@ backsql_strfcat( struct berbuf *dest, const char *fmt, ... ) cslen = va_arg( strs, ber_len_t ); cstr = va_arg( strs, char * ); break; - + /* string */ case 's': cstr = va_arg( strs, char * ); -- 2.39.5