From b8af4a67ea9f0342204602e172df9954409b11f4 Mon Sep 17 00:00:00 2001 From: Dmitry Kovalev Date: Fri, 26 May 2000 16:03:32 +0000 Subject: [PATCH] Summary of changes: - filter -> SQL translation bugfixes - several memory leaks fixups - improved configurability: - allows definition of uppercasing function to support CIS matching on databases that do case sensitive compares (this fixes up Oracle issues, example updated) - allows more flexibility in stored procedures interface (different parameter order, optional return codes - see samples, and comments in backsql.h) - synchronize function interfaces to recent changes in prototypes ("const" clauses etc.) made for all backends (those changes led to compile-time errors) --- servers/slapd/back-sql/back-sql.h | 4 +- servers/slapd/back-sql/bind.c | 8 +- servers/slapd/back-sql/config.c | 38 ++++-- servers/slapd/back-sql/docs/bugs | 6 - servers/slapd/back-sql/docs/install | 8 +- servers/slapd/back-sql/entry-id.c | 13 +- servers/slapd/back-sql/entry-id.h | 12 +- servers/slapd/back-sql/external.h | 10 ++ servers/slapd/back-sql/init.c | 32 ++++- servers/slapd/back-sql/modify.c | 121 +++++++++++------- servers/slapd/back-sql/other.c | 6 +- .../back-sql/rdbms_depend/mssql/create.sql | 7 +- .../rdbms_depend/mssql/test_metadata.sql | 50 ++++---- .../back-sql/rdbms_depend/mysql/create.sql | 7 +- .../rdbms_depend/mysql/test_metadata.sql | 48 +++---- .../back-sql/rdbms_depend/oracle/create.sql | 7 +- .../rdbms_depend/oracle/create_testdb.sql | 16 ++- .../back-sql/rdbms_depend/oracle/slapd.conf | 3 +- .../rdbms_depend/oracle/test_metadata.sql | 48 +++---- servers/slapd/back-sql/schema-map.c | 40 +++--- servers/slapd/back-sql/schema-map.h | 18 +++ servers/slapd/back-sql/search.c | 86 ++++++++----- servers/slapd/back-sql/sql-types.h | 2 +- servers/slapd/back-sql/sql-wrap.c | 6 +- servers/slapd/back-sql/sql-wrap.h | 2 +- servers/slapd/back-sql/util.c | 15 ++- servers/slapd/back-sql/util.h | 11 +- 27 files changed, 392 insertions(+), 232 deletions(-) diff --git a/servers/slapd/back-sql/back-sql.h b/servers/slapd/back-sql/back-sql.h index ef18a01dab..a63ca8eb9e 100644 --- a/servers/slapd/back-sql/back-sql.h +++ b/servers/slapd/back-sql/back-sql.h @@ -2,7 +2,7 @@ #define __BACKSQL_H__ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this @@ -27,6 +27,8 @@ typedef struct char *subtree_cond; char *oc_query,*at_query; char *insentry_query,*delentry_query; + char *id_query; + char *upper_func; Avlnode *db_conns; Avlnode *oc_by_name; Avlnode *oc_by_id; diff --git a/servers/slapd/back-sql/bind.c b/servers/slapd/back-sql/bind.c index b383d5f1b8..08b2ab2f61 100644 --- a/servers/slapd/back-sql/bind.c +++ b/servers/slapd/back-sql/bind.c @@ -1,5 +1,5 @@ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this @@ -17,8 +17,8 @@ #include "back-sql.h" #include "sql-wrap.h" -int backsql_bind(Backend *be,Connection *conn,Operation *op, - char *dn,char *ndn,int method,struct berval *cred,char** edn) +int backsql_bind(BackendDB *be,Connection *conn,Operation *op, + const char *dn,const char *ndn,int method,struct berval *cred,char** edn) { Debug(LDAP_DEBUG_TRACE,"==>backsql_bind()\n",0,0,0); //for now, just return OK, allowing to test modify operations @@ -27,7 +27,7 @@ int backsql_bind(Backend *be,Connection *conn,Operation *op, return 0; } -int backsql_unbind(Backend *be,Connection *conn,Operation *op) +int backsql_unbind(BackendDB *be,Connection *conn,Operation *op) { Debug(LDAP_DEBUG_TRACE,"==>backsql_unbind()\n",0,0,0); backsql_free_db_conn(be,conn); diff --git a/servers/slapd/back-sql/config.c b/servers/slapd/back-sql/config.c index db24349c1f..85c9cabf09 100644 --- a/servers/slapd/back-sql/config.c +++ b/servers/slapd/back-sql/config.c @@ -1,5 +1,5 @@ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this @@ -38,7 +38,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char * } else { - si->dbhost=strdup(argv[1]); + si->dbhost=ch_strdup(argv[1]); Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): hostname=%s\n",si->dbhost,0,0); } return(0); @@ -53,7 +53,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char * } else { - si->dbuser=strdup(argv[1]); + si->dbuser=ch_strdup(argv[1]); Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbuser=%s\n",argv[1],0,0); } return(0); @@ -68,7 +68,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char * } else { - si->dbpasswd=strdup(argv[1]); + si->dbpasswd=ch_strdup(argv[1]); Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbpasswd=%s\n",si->dbpasswd,0,0); } return(0); @@ -83,7 +83,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char * } else { - si->dbname=strdup(argv[1]); + si->dbname=ch_strdup(argv[1]); Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbname=%s\n",si->dbname,0,0); } return(0); @@ -98,7 +98,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char * } else { - si->subtree_cond=strdup(argv[1]); + si->subtree_cond=ch_strdup(argv[1]); Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): subtree_cond=%s\n",si->subtree_cond,0,0); } return(0); @@ -113,7 +113,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char * } else { - si->oc_query=strdup(argv[1]); + si->oc_query=ch_strdup(argv[1]); Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): oc_query=%s\n",si->oc_query,0,0); } return(0); @@ -128,7 +128,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char * } else { - si->at_query=strdup(argv[1]); + si->at_query=ch_strdup(argv[1]); Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): at_query=%s\n",si->at_query,0,0); } return(0); @@ -143,12 +143,27 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char * } else { - si->insentry_query=strdup(argv[1]); + si->insentry_query=ch_strdup(argv[1]); Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): insentry_query=%s\n",si->insentry_query,0,0); } return(0); } + if (!strcasecmp(argv[0],"upper_func")) + { + if (argc<2) + { + Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing function name in upper_func directive\n", + fname,lineno,0); + } + else + { + si->upper_func=ch_strdup(argv[1]); + Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): upper_func=%s\n",si->upper_func,0,0); + } + return(0); + } + if (!strcasecmp(argv[0],"delentry_query")) { if (argc<2) @@ -158,7 +173,7 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char * } else { - si->delentry_query=strdup(argv[1]); + si->delentry_query=ch_strdup(argv[1]); Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): delentry_query=%s\n",si->delentry_query,0,0); } return(0); @@ -168,4 +183,5 @@ int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char * fname,lineno,argv[0]); return 0; } -#endif /* SLAPD_SQL */ \ No newline at end of file + +#endif /* SLAPD_SQL */ diff --git a/servers/slapd/back-sql/docs/bugs b/servers/slapd/back-sql/docs/bugs index 6c503e6445..c39e3f60bf 100644 --- a/servers/slapd/back-sql/docs/bugs +++ b/servers/slapd/back-sql/docs/bugs @@ -25,12 +25,6 @@ 6.1 (glibc 2.1.2) (the same code behaves differently when built on 6.0 and 6.1) my problem was solved by upgrading iODBC to 3.0 beta - but it is kinda strange that beta works better than release (and release still works fine on 6.0) -8) Oracle does case-sensitive comparison of strings by default, so back-sql - becomes sensitive too when using Oracle. Later I'll add some option to slapd.conf - that would allow to set some function to process values before comparison - (something like "before_match UPPER", so that back-sql could generate - something like "select ... from ... where ... and UPPER(colname)=UPPER(?) or - UPPER(colname) LIKE UPPER(...)") 9) ldapsearch sometimes refuses to show some attributes ("NOT PRINTABLE" diags) on Win32 (on linux everything's fine -- at least with mySQL) \ No newline at end of file diff --git a/servers/slapd/back-sql/docs/install b/servers/slapd/back-sql/docs/install index afa3f2dbed..f5dab3a67e 100644 --- a/servers/slapd/back-sql/docs/install +++ b/servers/slapd/back-sql/docs/install @@ -1,14 +1,14 @@ 1. Build To build slapd with back-sql under Unix you need to build and install iODBC 2.50.3 (later versions should probably work). Then, run -"configure --enable-sql [--with-iodbc-includes=] [--with-iodbc-libs=]", -this should build back-sql-enabled slapd. +"configure --enable-sql", +this should build back-sql-enabled slapd, provided that you have iODBC +libraries and include files in include/library paths. Under Win32/MSVC++, I modified the workspace so that back-sql is built into slapd automatically, since MS odbc32 is included in standard library pack, and it does no bad even if you don't plan to use it. I also could provide -precompiled executables for those who don't have MSVC later (when back-sql -comes into some stable state). +precompiled executables for those who don't have MSVC. 2. Tune datasources and slapd.conf Next, you need to define ODBC datasource with data you want to publish diff --git a/servers/slapd/back-sql/entry-id.c b/servers/slapd/back-sql/entry-id.c index 92cceedd5e..9bdbbaa52b 100644 --- a/servers/slapd/back-sql/entry-id.c +++ b/servers/slapd/back-sql/entry-id.c @@ -1,5 +1,5 @@ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this @@ -30,16 +30,15 @@ backsql_entryID* backsql_free_entryID(backsql_entryID* id) return next; } -backsql_entryID* backsql_dn2id(backsql_entryID *id,SQLHDBC dbh,char *dn) +backsql_entryID* backsql_dn2id(backsql_info *bi,backsql_entryID *id,SQLHDBC dbh,char *dn) { - static char id_query[]="SELECT id,keyval,objclass FROM ldap_entries WHERE dn=?"; SQLHSTMT sth; BACKSQL_ROW_NTS row; //SQLINTEGER nrows=0; RETCODE rc; Debug(LDAP_DEBUG_TRACE,"==>backsql_dn2id(): dn='%s'\n",dn,0,0); - backsql_Prepare(dbh,&sth,id_query,0); + backsql_Prepare(dbh,&sth,bi->id_query,0); if ((rc=backsql_BindParamStr(sth,1,dn,BACKSQL_MAX_DN_LEN)) != SQL_SUCCESS) { Debug(LDAP_DEBUG_TRACE,"backsql_dn2id(): error binding dn parameter:\n",0,0,0); @@ -66,7 +65,7 @@ backsql_entryID* backsql_dn2id(backsql_entryID *id,SQLHDBC dbh,char *dn) id->id=atoi(row.cols[0]); id->keyval=atoi(row.cols[1]); id->oc_id=atoi(row.cols[2]); - id->dn=strdup(dn); + id->dn=ch_strdup(dn); id->next=NULL; } else @@ -147,7 +146,7 @@ Entry* backsql_id2entry(backsql_srch_info *bsi,Entry* e,backsql_entryID* eid) bsi->c_eid=eid; e->e_attrs=NULL; if (bsi->base_dn != NULL) - e->e_dn=strdup(bsi->c_eid->dn); + e->e_dn=ch_strdup(bsi->c_eid->dn); if (bsi->attrs!=NULL) { @@ -179,4 +178,4 @@ Entry* backsql_id2entry(backsql_srch_info *bsi,Entry* e,backsql_entryID* eid) return e; } -#endif /* SLAPD_SQL */ \ No newline at end of file +#endif /* SLAPD_SQL */ diff --git a/servers/slapd/back-sql/entry-id.h b/servers/slapd/back-sql/entry-id.h index 0411eaa63f..6ade0e071d 100644 --- a/servers/slapd/back-sql/entry-id.h +++ b/servers/slapd/back-sql/entry-id.h @@ -1,6 +1,16 @@ #ifndef __BACKSQL_ENTRYID_H__ #define __BACKSQL_ENTRYID_H__ +/* + * Copyright 1999, Dmitry Kovalev , All rights reserved. + * + * Redistribution and use in source and binary forms are permitted only + * as authorized by the OpenLDAP Public License. A copy of this + * license is available at http://www.OpenLDAP.org/license.html or + * in file LICENSE in the top-level directory of the distribution. + */ + + typedef struct __backsql_entryID { unsigned long id; @@ -10,7 +20,7 @@ typedef struct __backsql_entryID struct __backsql_entryID *next; }backsql_entryID; -backsql_entryID* backsql_dn2id(backsql_entryID* id,SQLHDBC dbh,char *dn); +backsql_entryID* backsql_dn2id(backsql_info *bi,backsql_entryID* id,SQLHDBC dbh,char *dn); backsql_entryID* backsql_free_entryID(backsql_entryID* id);//returns next #endif \ No newline at end of file diff --git a/servers/slapd/back-sql/external.h b/servers/slapd/back-sql/external.h index 2cec859a9d..3f9bd7cd4d 100644 --- a/servers/slapd/back-sql/external.h +++ b/servers/slapd/back-sql/external.h @@ -2,6 +2,16 @@ #ifndef _SQL_EXTERNAL_H #define _SQL_EXTERNAL_H +/* + * Copyright 1999, Dmitry Kovalev , All rights reserved. + * + * Redistribution and use in source and binary forms are permitted only + * as authorized by the OpenLDAP Public License. A copy of this + * license is available at http://www.OpenLDAP.org/license.html or + * in file LICENSE in the top-level directory of the distribution. + */ + + LDAP_BEGIN_DECL extern int sql_back_initialize LDAP_P(( BackendInfo *bi )); diff --git a/servers/slapd/back-sql/init.c b/servers/slapd/back-sql/init.c index 6e8a9db9af..6740fcf454 100644 --- a/servers/slapd/back-sql/init.c +++ b/servers/slapd/back-sql/init.c @@ -1,5 +1,5 @@ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this @@ -116,6 +116,8 @@ int backsql_db_destroy(BackendDB *bd) free(si->dbpasswd); if (si->dbhost) free(si->dbhost); + if (si->upper_func) + free(si->upper_func); free(si->subtree_cond); free(si->oc_query); free(si->at_query); @@ -131,6 +133,7 @@ int backsql_db_open (BackendDB *bd) backsql_info *si=(backsql_info*)bd->be_private; Connection tmp; SQLHDBC dbh; + int idq_len; Debug(LDAP_DEBUG_TRACE,"==>backsql_db_open(): testing RDBMS connection\n",0,0,0); if (si->dbname==NULL) @@ -147,32 +150,42 @@ int backsql_db_open (BackendDB *bd) { Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): subtree search SQL condition not specified (use subtree_cond directive in slapd.conf)\n",0,0,0); Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' as default\n",backsql_def_subtree_cond,0,0); - si->subtree_cond=strdup(backsql_def_subtree_cond); + si->subtree_cond=ch_strdup(backsql_def_subtree_cond); } if (si->oc_query==NULL) { Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): objectclass mapping SQL statement not specified (use oc_query directive in slapd.conf)\n",0,0,0); Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_oc_query,0,0); - si->oc_query=strdup(backsql_def_oc_query); + si->oc_query=ch_strdup(backsql_def_oc_query); } if (si->at_query==NULL) { Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): attribute mapping SQL statement not specified (use at_query directive in slapd.conf)\n",0,0,0); Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_at_query,0,0); - si->at_query=strdup(backsql_def_at_query); + si->at_query=ch_strdup(backsql_def_at_query); } if (si->insentry_query==NULL) { Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): entry insertion SQL statement not specified (use insentry_query directive in slapd.conf)\n",0,0,0); Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_insentry_query,0,0); - si->insentry_query=strdup(backsql_def_insentry_query); + si->insentry_query=ch_strdup(backsql_def_insentry_query); } if (si->delentry_query==NULL) { Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): entry deletion SQL statement not specified (use delentry_query directive in slapd.conf)\n",0,0,0); Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_delentry_query,0,0); - si->delentry_query=strdup(backsql_def_delentry_query); + si->delentry_query=ch_strdup(backsql_def_delentry_query); } + si->id_query=NULL; + idq_len=0; + if (si->upper_func==NULL) + { + si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,"dn=?",NULL); + } + else + { + si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,si->upper_func,"(dn)=",si->upper_func,"(?)",NULL); + } tmp.c_connid=-1; dbh=backsql_get_db_conn(bd,&tmp); if (!dbh) @@ -181,6 +194,11 @@ int backsql_db_open (BackendDB *bd) return 1; } backsql_free_db_conn(bd,&tmp); + if (!si->schema_loaded) + { + Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): test failed, schema map not loaded - exiting\n",0,0,0); + return 1; + } Debug(LDAP_DEBUG_TRACE,"<==backsql_db_open(): test succeeded, schema map loaded\n",0,0,0); return 0; } @@ -192,4 +210,4 @@ int backsql_db_close(BackendDB *bd) return 0; } -#endif /* SLAPD_SQL */ \ No newline at end of file +#endif /* SLAPD_SQL */ diff --git a/servers/slapd/back-sql/modify.c b/servers/slapd/back-sql/modify.c index c4a8eb3dc1..bc1ce05873 100644 --- a/servers/slapd/back-sql/modify.c +++ b/servers/slapd/back-sql/modify.c @@ -1,5 +1,5 @@ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this @@ -22,7 +22,7 @@ #include "util.h" int backsql_modify(BackendDB *be,Connection *conn,Operation *op, - char *dn,char *ndn,LDAPModList *modlist) + const char *dn,const char *ndn,LDAPModList *modlist) { backsql_info *bi=(backsql_info*)be->be_private; SQLHDBC dbh; @@ -34,9 +34,10 @@ int backsql_modify(BackendDB *be,Connection *conn,Operation *op, backsql_at_map_rec *at=NULL; struct berval *at_val; int i; + int pno,po;//first parameter no, parameter order + int prc; //procedure return code - dn=dn_validate(dn); - Debug(LDAP_DEBUG_TRACE,"==>backsql_modify(): changing entry '%s'\n",dn,0,0); + Debug(LDAP_DEBUG_TRACE,"==>backsql_modify(): changing entry '%s'\n",ndn,0,0); dbh=backsql_get_db_conn(be,conn); if (!dbh) { @@ -44,7 +45,7 @@ int backsql_modify(BackendDB *be,Connection *conn,Operation *op, send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL); return 1; } - res=backsql_dn2id(&e_id,dbh,dn); + res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn); if (res==NULL) { Debug(LDAP_DEBUG_TRACE,"backsql_modify(): could not lookup entry id\n",0,0,0); @@ -69,16 +70,14 @@ int backsql_modify(BackendDB *be,Connection *conn,Operation *op, at=backsql_at_with_name(oc,c_mod->ml_type); if (at==NULL) { - Debug(LDAP_DEBUG_TRACE,"backsql_add(): attribute provided is not registered in this objectclass ('%s')\n",c_mod->ml_type,0,0); + Debug(LDAP_DEBUG_TRACE,"backsql_modify(): attribute provided is not registered in this objectclass ('%s')\n",c_mod->ml_type,0,0); continue; } - SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0); + switch(c_mod->ml_op) { case LDAP_MOD_REPLACE: { - char *query; - int qlen; SQLHSTMT asth; BACKSQL_ROW_NTS row; @@ -89,27 +88,17 @@ int backsql_modify(BackendDB *be,Connection *conn,Operation *op, break; } del_all: - query=NULL; - qlen=0; - query=backsql_strcat(query,&qlen,"SELECT ",at->sel_expr," AS ",at->name, - " FROM ",at->from_tbls, - " WHERE ",oc->keytbl,".",oc->keycol,"=?",NULL); - if (at->join_where!=NULL && at->join_where[0]!='\0') - query=backsql_strcat(query,&qlen," AND ",at->join_where,NULL); - - Debug(LDAP_DEBUG_TRACE,"backsql_modify() constructed query to get all existing values: %s\n",query,0,0); - if ((rc=backsql_Prepare(dbh,&asth,query,0)) != SQL_SUCCESS) + + if ((rc=backsql_Prepare(dbh,&asth,at->query,0)) != SQL_SUCCESS) { - Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error preparing query\n",0,0,0); + Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error preparing query\n",0,0,0); backsql_PrintErrors(bi->db_env,dbh,asth,rc); - free(query); break; } - free(query); if (backsql_BindParamID(asth,1,&e_id.keyval) != SQL_SUCCESS) { - Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error binding key value parameter\n",0,0,0); + Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error binding key value parameter\n",0,0,0); backsql_PrintErrors(bi->db_env,dbh,asth,rc); SQLFreeStmt(asth,SQL_DROP); break; @@ -117,7 +106,7 @@ del_all: if ((rc=SQLExecute(asth)) != SQL_SUCCESS && rc!= SQL_SUCCESS_WITH_INFO) { - Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error executing attribute query\n",0,0,0); + Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error executing attribute query\n",0,0,0); backsql_PrintErrors(bi->db_env,dbh,asth,rc); SQLFreeStmt(asth,SQL_DROP); break; @@ -128,7 +117,18 @@ del_all: { for (i=0;iexpect_return & BACKSQL_DEL) + { + pno=1; + SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0); + } + else + pno=0; + po=(at->param_order & BACKSQL_DEL)>0; + SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0); + //check for syntax needed here - maybe need binary bind? + SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,row.cols[i],strlen(row.cols[i]),0); + Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0); rc=SQLExecDirect(sth,at->delete_proc,SQL_NTS); if (rc!=SQL_SUCCESS) @@ -156,8 +156,18 @@ del_all: Debug(LDAP_DEBUG_TRACE,"backsql_modify(): adding new values for attribute '%s'\n",at->name,0,0); for(i=0,at_val=c_mod->ml_bvalues[0];at_val!=NULL;i++,at_val=c_mod->ml_bvalues[i]) { - //check for syntax here - maybe need binary bind? - SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0); + if (at->expect_return & BACKSQL_ADD) + { + pno=1; + SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0); + } + else + pno=0; + po=(at->param_order & BACKSQL_ADD)>0; + SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0); + //check for syntax needed here - maybe need binary bind? + SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0); + Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->add_proc,0,0); rc=SQLExecDirect(sth,at->add_proc,SQL_NTS); if (rc!=SQL_SUCCESS) @@ -181,8 +191,18 @@ del_all: Debug(LDAP_DEBUG_TRACE,"backsql_modify(): deleting values for attribute '%s'\n",at->name,0,0); for(i=0,at_val=c_mod->ml_bvalues[0];at_val!=NULL;i++,at_val=c_mod->ml_bvalues[i]) { - //check for syntax here - maybe need binary bind? - SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0); + if (at->expect_return & BACKSQL_DEL) + { + pno=1; + SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0); + } + else + pno=0; + po=(at->param_order & BACKSQL_DEL)>0; + SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0); + //check for syntax needed here - maybe need binary bind? + SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0); + Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0); rc=SQLExecDirect(sth,at->delete_proc,SQL_NTS); if (rc!=SQL_SUCCESS) @@ -203,7 +223,7 @@ del_all: } int backsql_modrdn(BackendDB *be,Connection *conn,Operation *op, - char *dn,char *ndn,char *newrdn,int deleteoldrdn,char *newSuperior) + const char *dn,const char *ndn,const char *newrdn,int deleteoldrdn,const char *newSuperior) { Debug(LDAP_DEBUG_TRACE,"==>backsql_modrdn()\n",0,0,0); return 0; @@ -223,6 +243,8 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e) Attribute *at; struct berval *at_val; char *pdn; + int pno,po;//first parameter no, parameter order + int prc; //procedure return code Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): adding entry '%s'\n",e->e_dn,0,0); if (dn_validate(e->e_dn)==NULL) @@ -262,7 +284,6 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e) SQLAllocStmt(dbh, &sth); SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0); - //SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,0,0); Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",oc->create_proc,0,0); rc=SQLExecDirect(sth,oc->create_proc,SQL_NTS); @@ -290,13 +311,20 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e) Debug(LDAP_DEBUG_TRACE,"backsql_add(): add procedure is not defined for this attribute ('%s')\n",at->a_type,0,0); continue; } - SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_keyval,0,0); + for(i=0,at_val=at->a_vals[0];at_val!=NULL;i++,at_val=at->a_vals[i]) { - //if (at->a_syntax==SYNTAX_BIN) - // SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_BINARY,0,0,at_val->bv_val,0,0); - //else - SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0); + if (at_rec->expect_return & BACKSQL_ADD) + { + pno=1; + SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0); + } + else + pno=0; + po=(at_rec->param_order & BACKSQL_ADD)>0; + SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0); + //check for syntax needed here - maybe need binary bind? + SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0); Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",at_rec->add_proc,0,0); rc=SQLExecDirect(sth,at_rec->add_proc,SQL_NTS); if (rc!=SQL_SUCCESS) @@ -308,7 +336,7 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e) } SQLFreeStmt(sth,SQL_RESET_PARAMS); pdn=dn_parent(be,e->e_dn); - res=backsql_dn2id(&parent_id,dbh,pdn); + res=backsql_dn2id(bi,&parent_id,dbh,pdn); if (res==NULL) { Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not lookup parent entry for new record ('%s')\n", @@ -337,7 +365,7 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e) } int backsql_delete(BackendDB *be,Connection *conn,Operation *op, - char *dn,char *ndn) + const char *dn,const char *ndn) { backsql_info *bi=(backsql_info*)be->be_private; SQLHDBC dbh; @@ -345,9 +373,9 @@ int backsql_delete(BackendDB *be,Connection *conn,Operation *op, RETCODE rc; backsql_oc_map_rec *oc=NULL; backsql_entryID e_id,*res; + int pno;//first parameter no, parameter order - dn=dn_validate(dn); - Debug(LDAP_DEBUG_TRACE,"==>backsql_delete(): deleting entry '%s'\n",dn,0,0); + Debug(LDAP_DEBUG_TRACE,"==>backsql_delete(): deleting entry '%s'\n",ndn,0,0); dbh=backsql_get_db_conn(be,conn); if (!dbh) { @@ -355,7 +383,7 @@ int backsql_delete(BackendDB *be,Connection *conn,Operation *op, send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL); return 1; } - res=backsql_dn2id(&e_id,dbh,dn); + res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn); if (res==NULL) { Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not lookup entry id\n",0,0,0); @@ -378,7 +406,14 @@ int backsql_delete(BackendDB *be,Connection *conn,Operation *op, } SQLAllocStmt(dbh, &sth); - SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0); + if (oc->expect_return) + { + pno=1; + SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&rc,0,0); + } + else + pno=0; + SQLBindParameter(sth,(SQLUSMALLINT)(pno+1),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0); //SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,0,0); Debug(LDAP_DEBUG_TRACE,"backsql_delete(): executing '%s'\n",oc->delete_proc,0,0); @@ -410,4 +445,4 @@ int backsql_delete(BackendDB *be,Connection *conn,Operation *op, return 0; } -#endif /* SLAPD_SQL */ \ No newline at end of file +#endif /* SLAPD_SQL */ diff --git a/servers/slapd/back-sql/other.c b/servers/slapd/back-sql/other.c index 6cd1943375..b4a3fa0100 100644 --- a/servers/slapd/back-sql/other.c +++ b/servers/slapd/back-sql/other.c @@ -1,5 +1,5 @@ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this @@ -23,7 +23,7 @@ int backsql_dummy() } int backsql_compare(BackendDB *be,Connection *conn,Operation *op, - char *dn,char *ndn,Ava *ava) + const char *dn,const char *ndn,Ava *ava) { Debug(LDAP_DEBUG_TRACE,"==>backsql_compare()\n",0,0,0); return 0; @@ -37,4 +37,4 @@ int backsql_abandon( BackendDB *be, return 0; } -#endif /* SLAPD_SQL */ \ No newline at end of file +#endif /* SLAPD_SQL */ diff --git a/servers/slapd/back-sql/rdbms_depend/mssql/create.sql b/servers/slapd/back-sql/rdbms_depend/mssql/create.sql index 654d07f5a4..1ac2e1f17f 100644 --- a/servers/slapd/back-sql/rdbms_depend/mssql/create.sql +++ b/servers/slapd/back-sql/rdbms_depend/mssql/create.sql @@ -7,7 +7,9 @@ CREATE TABLE ldap_attrs ( join_where varchar (255) NULL , add_proc varchar (255) NULL , modify_proc varchar (255) NULL , - delete_proc varchar (255) NULL + delete_proc varchar (255) NULL , + param_order int NOT NULL, + expect_return int NOT NULL ) GO @@ -26,7 +28,8 @@ CREATE TABLE ldap_objclasses ( keytbl varchar (64) NOT NULL , keycol varchar (64) NOT NULL , create_proc varchar (255) NULL , - delete_proc varchar (255) NULL + delete_proc varchar (255) NULL, + expect_return int NOT NULL ) GO diff --git a/servers/slapd/back-sql/rdbms_depend/mssql/test_metadata.sql b/servers/slapd/back-sql/rdbms_depend/mssql/test_metadata.sql index c09d2236e8..d401ad28da 100644 --- a/servers/slapd/back-sql/rdbms_depend/mssql/test_metadata.sql +++ b/servers/slapd/back-sql/rdbms_depend/mssql/test_metadata.sql @@ -1,56 +1,56 @@ SET IDENTITY_INSERT ldap_objclasses ON -insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc) -values (1,'person','persons','id','{call create_person(?)}','{call delete_person(?)}') +insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) +values (1,'person','persons','id','{call create_person(?)}','{call delete_person(?)}',0) -insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc) -values (2,'document','documents','id','{call create_document(?)}','{call delete_document(?)}') +insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) +values (2,'document','documents','id','{call create_document(?)}','{call delete_document(?)}',0) -insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc) -values (3,'organization','institutes','id','{call create_org(?)}','{call delete_org(?)}') +insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) +values (3,'organization','institutes','id','{call create_org(?)}','{call delete_org(?)}',0) SET IDENTITY_INSERT ldap_objclasses OFF SET IDENTITY_INSERT ldap_attrs ON -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (1,1,'cn','persons.name','persons',NULL,'{call set_person_name(?,?)}', - NULL,NULL) + NULL,NULL,0,0) -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (2,1,'telephoneNumber','phones.phone','persons,phones', 'phones.pers_id=persons.id','{call add_phone(?,?)}', - NULL,'{call delete_phone(?,?)}') + NULL,'{call delete_phone(?,?)}',0,0) -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (3,1,'sn','persons.name','persons',NULL,'{call set_person_name(?,?)}', - NULL,NULL) + NULL,NULL,0,0) -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (4,2,'abstract','documents.abstract','documents',NULL,'{call set_doc_abstract(?,?)}', - NULL,NULL) - -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) + NULL,NULL,0,0) + +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (5,2,'documentTitle','documents.title','documents',NULL,'{call set_doc_title(?,?)}', - NULL,NULL) + NULL,NULL,0,0) -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (6,2,'documentAuthor','persons.name','persons,documents,authors_docs', 'persons.id=authors_docs.pers_id AND documents.id=authors_docs.doc_id', - NULL,NULL,NULL) + NULL,NULL,NULL,0,0) -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (7,3,'o','institutes.name','institutes',NULL,'{call set_org_name(?,?)}', - NULL,NULL) + NULL,NULL,0,0) -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (8,1,'documentDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons', 'ldap_entries.keyval=documents.id AND ldap_entries.objclass=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id', - '{call make_doc_link(?,?)}',NULL,'{call del_doc_link(?,?)}') + '{call make_doc_link(?,?)}',NULL,'{call del_doc_link(?,?)}',0,0) -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (9,2,'authorDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons', 'ldap_entries.keyval=persons.id AND ldap_entries.objclass=1 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id', - '{call make_author_link(?,?)}',NULL,'{call del_author_link(?,?)}') + '{call make_author_link(?,?)}',NULL,'{call del_author_link(?,?)}',0,0) SET IDENTITY_INSERT ldap_attrs OFF diff --git a/servers/slapd/back-sql/rdbms_depend/mysql/create.sql b/servers/slapd/back-sql/rdbms_depend/mysql/create.sql index 1ff885a7ac..964b310e97 100644 --- a/servers/slapd/back-sql/rdbms_depend/mysql/create.sql +++ b/servers/slapd/back-sql/rdbms_depend/mysql/create.sql @@ -7,7 +7,9 @@ CREATE TABLE ldap_attrs ( join_where varchar(255), add_proc varchar(255), modify_proc varchar(255), - delete_proc varchar(255) + delete_proc varchar(255), + param_order tinyint NOT NULL, + expect_return tinyint NOT NULL ); @@ -26,7 +28,8 @@ CREATE TABLE ldap_objclasses ( keytbl varchar(64) NOT NULL , keycol varchar(64) NOT NULL , create_proc varchar(255), - delete_proc varchar(255) + delete_proc varchar(255), + expect_return tinyint NOT NULL ); ALTER TABLE ldap_entries ADD diff --git a/servers/slapd/back-sql/rdbms_depend/mysql/test_metadata.sql b/servers/slapd/back-sql/rdbms_depend/mysql/test_metadata.sql index 735a26b79f..ccf23dc84e 100644 --- a/servers/slapd/back-sql/rdbms_depend/mysql/test_metadata.sql +++ b/servers/slapd/back-sql/rdbms_depend/mysql/test_metadata.sql @@ -1,43 +1,43 @@ -insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc) -values (1,'person','persons','id',NULL,NULL); +insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) +values (1,'person','persons','id',"insert into persons (name) values ('');\n select last_insert_id();",NULL,0); -insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc) -values (2,'document','documents','id',NULL,NULL); +insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) +values (2,'document','documents','id',NULL,NULL,0); -insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc) -values (3,'organization','institutes','id',NULL,NULL); +insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) +values (3,'organization','institutes','id',NULL,NULL,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) -values (1,1,'cn','persons.name','persons',NULL,NULL,NULL,NULL); +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) +values (1,1,'cn','persons.name','persons',NULL,NULL,NULL,NULL,3,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (2,1,'telephoneNumber','phones.phone','persons,phones', - 'phones.pers_id=persons.id',NULL,NULL,NULL); + 'phones.pers_id=persons.id',NULL,NULL,NULL,3,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) -values (3,1,'sn','persons.name','persons',NULL,NULL,NULL,NULL); +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) +values (3,1,'sn','persons.name','persons',NULL,NULL,NULL,NULL,3,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) -values (4,2,'abstract','documents.abstract','documents',NULL,NULL,NULL,NULL); +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) +values (4,2,'abstract','documents.abstract','documents',NULL,NULL,NULL,NULL,3,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) -values (5,2,'documentTitle','documents.title','documents',NULL,NULL,NULL,NULL); +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) +values (5,2,'documentTitle','documents.title','documents',NULL,NULL,NULL,NULL,3,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (6,2,'documentAuthor','persons.name','persons,documents,authors_docs', 'persons.id=authors_docs.pers_id AND documents.id=authors_docs.doc_id', - NULL,NULL,NULL); + NULL,NULL,NULL,3,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) -values (7,3,'o','institutes.name','institutes',NULL,NULL,NULL,NULL); +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) +values (7,3,'o','institutes.name','institutes',NULL,NULL,NULL,NULL,3,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (8,1,'documentDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons', 'ldap_entries.keyval=documents.id AND ldap_entries.objclass=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id', - NULL,NULL,NULL); + NULL,NULL,NULL,3,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (9,2,'authorDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons', 'ldap_entries.keyval=persons.id AND ldap_entries.objclass=1 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id', - NULL,NULL,NULL); + NULL,NULL,NULL,3,0); diff --git a/servers/slapd/back-sql/rdbms_depend/oracle/create.sql b/servers/slapd/back-sql/rdbms_depend/oracle/create.sql index a5377200d3..0d968e1a76 100644 --- a/servers/slapd/back-sql/rdbms_depend/oracle/create.sql +++ b/servers/slapd/back-sql/rdbms_depend/oracle/create.sql @@ -7,7 +7,9 @@ CREATE TABLE ldap_attrs ( join_where varchar2(255), add_proc varchar2(255), modify_proc varchar2(255), - delete_proc varchar2(255) + delete_proc varchar2(255), + param_order NUMBER NOT NULL, + expect_return NUMBER NOT NULL ); @@ -26,7 +28,8 @@ CREATE TABLE ldap_objclasses ( keytbl varchar2(64) NOT NULL , keycol varchar2(64) NOT NULL , create_proc varchar2(255), - delete_proc varchar2(255) + delete_proc varchar2(255), + expect_return NUMBER NOT NULL ); diff --git a/servers/slapd/back-sql/rdbms_depend/oracle/create_testdb.sql b/servers/slapd/back-sql/rdbms_depend/oracle/create_testdb.sql index 1fd3e11cc4..36ac2373b6 100644 --- a/servers/slapd/back-sql/rdbms_depend/oracle/create_testdb.sql +++ b/servers/slapd/back-sql/rdbms_depend/oracle/create_testdb.sql @@ -143,40 +143,46 @@ UPDATE documents SET abstract=new_abstract WHERE id=keyval; END; / -CREATE OR REPLACE PROCEDURE make_author_link (keyval IN NUMBER, author_dn IN varchar2) AS +CREATE OR REPLACE FUNCTION make_author_link (keyval IN NUMBER, author_dn IN varchar2) RETURN NUMBER AS per_id NUMBER; BEGIN SELECT keyval INTO per_id FROM ldap_entries WHERE objclass=1 AND dn=author_dn; IF NOT (per_id IS NULL) THEN INSERT INTO authors_docs (doc_id,pers_id) VALUES (keyval,per_id); + RETURN 1; END IF; +RETURN 0; END; / -CREATE OR REPLACE PROCEDURE make_doc_link (keyval IN NUMBER, doc_dn IN varchar2) AS +CREATE OR REPLACE FUNCTION make_doc_link (keyval IN NUMBER, doc_dn IN varchar2) RETURN NUMBER AS docid NUMBER; BEGIN SELECT keyval INTO docid FROM ldap_entries WHERE objclass=2 AND dn=doc_dn; IF NOT (docid IS NULL) THEN INSERT INTO authors_docs (pers_id,doc_id) VALUES (keyval,docid); + RETURN 1; END IF; +RETURN 0; END; / -CREATE OR REPLACE PROCEDURE del_doc_link (keyval IN NUMBER, doc_dn IN varchar2) AS +CREATE OR REPLACE FUNCTION del_doc_link (keyval IN NUMBER, doc_dn IN varchar2) RETURN NUMBER AS docid NUMBER; BEGIN SELECT keyval INTO docid FROM ldap_entries WHERE objclass=2 AND dn=doc_dn; IF NOT (docid IS NULL) THEN DELETE FROM authors_docs WHERE pers_id=keyval AND doc_id=docid; + RETURN 1; END IF; +RETURN 0; END; / -CREATE PROCEDURE del_author_link (keyval IN NUMBER, author_dn IN varchar2) AS +CREATE OR REPLACE FUNCTION del_author_link (keyval IN NUMBER, author_dn IN varchar2) RETURN NUMBER AS per_id NUMBER; BEGIN SELECT keyval INTO per_id FROM ldap_entries @@ -184,7 +190,9 @@ SELECT keyval INTO per_id FROM ldap_entries IF NOT (per_id IS NULL) THEN DELETE FROM authors_docs WHERE doc_id=keyval AND pers_id=per_id; + RETURN 1; END IF; + RETURN 0; END; / diff --git a/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf b/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf index 4a40559cb3..bb7ba453be 100644 --- a/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf +++ b/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf @@ -37,5 +37,6 @@ rootpw secret dbname ldap_ora8 dbuser ldap dbpasswd ldap -subtree_cond "ldap_entries.dn LIKE CONCAT('%',?)" +subtree_cond "UPPER(ldap_entries.dn) LIKE CONCAT('%',UPPER(?))" insentry_query "INSERT INTO ldap_entries (id,dn,objclass,parent,keyval) VALUES (ldap_entry_ids.nextval,?,?,?,?)" +upper_func UPPER diff --git a/servers/slapd/back-sql/rdbms_depend/oracle/test_metadata.sql b/servers/slapd/back-sql/rdbms_depend/oracle/test_metadata.sql index ad2e8b9727..0d44ee0a6f 100644 --- a/servers/slapd/back-sql/rdbms_depend/oracle/test_metadata.sql +++ b/servers/slapd/back-sql/rdbms_depend/oracle/test_metadata.sql @@ -1,49 +1,49 @@ -insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc) -values (1,'person','persons','id','{call create_person(?)}','{call delete_person(?)}'); +insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) +values (1,'person','persons','id','{call create_person(?)}','{call delete_person(?)}',0); -insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc) -values (2,'document','documents','id','{call create_document(?)}','{call delete_document(?)}'); +insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) +values (2,'document','documents','id','{call create_document(?)}','{call delete_document(?)}',0); -insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc) -values (3,'organization','institutes','id','{call create_org(?)}','{call delete_org(?)}'); +insert into ldap_objclasses (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) +values (3,'organization','institutes','id','{call create_org(?)}','{call delete_org(?)}',0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (1,1,'cn','persons.name','persons',NULL,'{call set_person_name(?,?)}', - NULL,NULL); + NULL,NULL,0,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (2,1,'telephoneNumber','phones.phone','persons,phones', 'phones.pers_id=persons.id','{call add_phone(?,?)}', - NULL,'{call delete_phone(?,?)}'); + NULL,'{call delete_phone(?,?)}',0,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (3,1,'sn','persons.name','persons',NULL,'{call set_person_name(?,?)}', - NULL,NULL); + NULL,NULL,0,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (4,2,'abstract','documents.abstract','documents',NULL,'{call set_doc_abstract(?,?)}', - NULL,NULL); + NULL,NULL,0,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (5,2,'documentTitle','documents.title','documents',NULL,'{call set_doc_title(?,?)}', - NULL,NULL); + NULL,NULL,0,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (6,2,'documentAuthor','persons.name','persons,documents,authors_docs', 'persons.id=authors_docs.pers_id AND documents.id=authors_docs.doc_id', - NULL,NULL,NULL); + NULL,NULL,NULL,0,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (7,3,'o','institutes.name','institutes',NULL,'{call set_org_name(?,?)}', - NULL,NULL); + NULL,NULL,0,0); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (8,1,'documentDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons', 'ldap_entries.keyval=documents.id AND ldap_entries.objclass=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id', - '{call make_doc_link(?,?)}',NULL,'{call del_doc_link(?,?)}'); + '{?=call make_doc_link(?,?)}',NULL,'{?=call del_doc_link(?,?)}',0,3); -insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc) +insert into ldap_attrs (id,oc_id,name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return) values (9,2,'authorDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons', 'ldap_entries.keyval=persons.id AND ldap_entries.objclass=1 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id', - '{call make_author_link(?,?)}',NULL,'{call del_author_link(?,?)}'); + '{?=call make_author_link(?,?)}',NULL,'{?=call del_author_link(?,?)}',0,3); diff --git a/servers/slapd/back-sql/schema-map.c b/servers/slapd/back-sql/schema-map.c index cc37a4a005..ed5f0692c7 100644 --- a/servers/slapd/back-sql/schema-map.c +++ b/servers/slapd/back-sql/schema-map.c @@ -1,5 +1,5 @@ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this @@ -84,19 +84,21 @@ int backsql_load_schema_map(backsql_info *si,SQLHDBC dbh) { oc_map=(backsql_oc_map_rec*)ch_calloc(1,sizeof(backsql_oc_map_rec)); oc_map->id=atoi(oc_row.cols[0]); - oc_map->name=strdup(oc_row.cols[1]); - oc_map->keytbl=strdup(oc_row.cols[2]); - oc_map->keycol=strdup(oc_row.cols[3]); - oc_map->create_proc=(oc_row.is_null[4]<0)?NULL:strdup(oc_row.cols[4]); - oc_map->delete_proc=(oc_row.is_null[5]<0)?NULL:strdup(oc_row.cols[5]); + oc_map->name=ch_strdup(oc_row.cols[1]); + oc_map->keytbl=ch_strdup(oc_row.cols[2]); + oc_map->keycol=ch_strdup(oc_row.cols[3]); + oc_map->create_proc=(oc_row.is_null[4]<0)?NULL:ch_strdup(oc_row.cols[4]); + oc_map->delete_proc=(oc_row.is_null[5]<0)?NULL:ch_strdup(oc_row.cols[5]); + oc_map->expect_return=atoi(oc_row.cols[6]); + oc_map->attrs=NULL; avl_insert(&si->oc_by_name,oc_map,(AVL_CMP)backsql_cmp_oc_name,backsql_dummy); avl_insert(&si->oc_by_id,oc_map,(AVL_CMP)backsql_cmp_oc_id,backsql_dummy); oc_id=oc_map->id; Debug(LDAP_DEBUG_TRACE,"load_schema_map(): objectclass '%s': keytbl='%s' keycol='%s' ", - oc_row.cols[1],oc_row.cols[2],oc_row.cols[3]); - Debug(LDAP_DEBUG_TRACE,"create_proc='%s' delete_proc='%s' ; attributes:\n",oc_row.cols[4], - oc_row.cols[5],0); + oc_map->name,oc_map->keytbl,oc_map->keycol); + Debug(LDAP_DEBUG_TRACE,"create_proc='%s' delete_proc='%s' expect_return=%d; attributes:\n", + oc_map->create_proc,oc_map->delete_proc,oc_map->expect_return); if ((rc=SQLExecute(at_sth)) != SQL_SUCCESS) { Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error executing at_query: \n",0,0,0); @@ -113,23 +115,25 @@ int backsql_load_schema_map(backsql_info *si,SQLHDBC dbh) at_row.cols[4],at_row.cols[5]); Debug(LDAP_DEBUG_TRACE,"delete_proc='%s'\n",at_row.cols[6],0,0); at_map=(backsql_at_map_rec*)ch_calloc(1,sizeof(backsql_at_map_rec)); - at_map->name=strdup(at_row.cols[0]); - at_map->sel_expr=strdup(at_row.cols[1]); + at_map->name=ch_strdup(at_row.cols[0]); + at_map->sel_expr=ch_strdup(at_row.cols[1]); tmps=NULL;tmpslen=0; backsql_merge_from_clause(&tmps,&tmpslen,at_row.cols[2]); - at_map->from_tbls=strdup(tmps); + at_map->from_tbls=ch_strdup(tmps); ch_free(tmps); - at_map->join_where=strdup((at_row.is_null[3]<0)?"":at_row.cols[3]); - at_map->add_proc=(at_row.is_null[4]<0)?NULL:strdup(at_row.cols[4]); - at_map->modify_proc=(at_row.is_null[5]<0)?NULL:strdup(at_row.cols[5]); - at_map->delete_proc=(at_row.is_null[6]<0)?NULL:strdup(at_row.cols[6]); + at_map->join_where=ch_strdup((at_row.is_null[3]<0)?"":at_row.cols[3]); + at_map->add_proc=(at_row.is_null[4]<0)?NULL:ch_strdup(at_row.cols[4]); + at_map->modify_proc=(at_row.is_null[5]<0)?NULL:ch_strdup(at_row.cols[5]); + at_map->delete_proc=(at_row.is_null[6]<0)?NULL:ch_strdup(at_row.cols[6]); + at_map->param_order=atoi(at_row.cols[7]); + at_map->expect_return=atoi(at_row.cols[8]); tmps=NULL;tmpslen=0; tmps=backsql_strcat(tmps,&tmpslen,"SELECT ",at_map->sel_expr," AS ",at_map->name, " FROM ",at_map->from_tbls, " WHERE ",oc_map->keytbl,".",oc_map->keycol,"=?",NULL); if (at_map->join_where!=NULL && at_map->join_where[0]!='\0') tmps=backsql_strcat(tmps,&tmpslen," AND ",at_map->join_where,NULL); - at_map->query=strdup(tmps); + at_map->query=ch_strdup(tmps); ch_free(tmps); Debug(LDAP_DEBUG_TRACE,"load_schema_map(): preconstructed query '%s'\n",at_map->query,0,0); avl_insert(&oc_map->attrs,at_map,(AVL_CMP)backsql_cmp_attr,backsql_dummy); @@ -236,4 +240,4 @@ int backsql_destroy_schema_map(backsql_info *si) return 0; } -#endif /* SLAPD_SQL */ \ No newline at end of file +#endif /* SLAPD_SQL */ diff --git a/servers/slapd/back-sql/schema-map.h b/servers/slapd/back-sql/schema-map.h index 2d79258732..3d9830930c 100644 --- a/servers/slapd/back-sql/schema-map.h +++ b/servers/slapd/back-sql/schema-map.h @@ -1,6 +1,16 @@ #ifndef __BACKSQL_SCHEMA_MAP_H__ #define __BACKSQL_SCHEMA_MAP_H__ +/* + * Copyright 1999, Dmitry Kovalev , All rights reserved. + * + * Redistribution and use in source and binary forms are permitted only + * as authorized by the OpenLDAP Public License. A copy of this + * license is available at http://www.OpenLDAP.org/license.html or + * in file LICENSE in the top-level directory of the distribution. + */ + + typedef struct { char *name; @@ -8,6 +18,7 @@ typedef struct char *keycol; char *create_proc;//expected to return keyval of newly created entry char *delete_proc;//supposed to expect keyval as parameter and delete all the attributes as well + int expect_return; //flags whether delete_proc is a function (whether back-sql should bind first parameter as output for return code) unsigned long id; Avlnode *attrs; }backsql_oc_map_rec; @@ -22,8 +33,15 @@ typedef struct char *modify_proc; //supposed to expect two binded values: entry keyval and old and new values of attr char *delete_proc; //supposed to expect 2 binded values: entry keyval and attr. value to delete char *query; //for optimization purposes attribute load query is preconstructed from parts on schemamap load time + //following flags are bitmasks (first bit used for add_proc, second - for modify, third - for delete_proc) + int param_order; //order of parameters for procedures above; 1 means "data then keyval", 0 means "keyval then data" + int expect_return; //flags whether one or more of procedures is a function (whether back-sql should bind first parameter as output for return code) }backsql_at_map_rec; +//defines to support bitmasks above +#define BACKSQL_ADD 1 +#define BACKSQL_DEL 2 + int backsql_load_schema_map(backsql_info *si,SQLHDBC dbh); backsql_oc_map_rec* backsql_oc_with_name(backsql_info *si,char* objclass); backsql_oc_map_rec* backsql_oc_with_id(backsql_info *si,unsigned long id); diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index 7e983dec61..6bc9fefd90 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -1,5 +1,5 @@ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this @@ -39,14 +39,14 @@ int backsql_attrlist_add(backsql_srch_info *bsi,char *at_name) } Debug(LDAP_DEBUG_TRACE,"==>backsql_attrlist_add(): adding '%s' to list\n",at_name,0,0); bsi->attrs=(char**)ch_realloc(bsi->attrs,(n_attrs+2)*sizeof(char*)); - bsi->attrs[n_attrs]=strdup(at_name); + bsi->attrs[n_attrs]=ch_strdup(at_name); bsi->attrs[n_attrs+1]=NULL; return 1; } void backsql_init_search(backsql_srch_info *bsi,backsql_info *bi,char *nbase,int scope, int slimit,int tlimit,time_t stoptime,Filter *filter, - SQLHDBC dbh,Backend *be,Connection *conn,Operation *op,char **attrs) + SQLHDBC dbh,BackendDB *be,Connection *conn,Operation *op,char **attrs) { char **p; bsi->base_dn=nbase; @@ -85,9 +85,6 @@ int backsql_process_filter_list(backsql_srch_info *bsi,Filter *f,int op) { res=backsql_process_filter(bsi,f); - if (res==-1) - bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len," 1=0 ",NULL); - f=f->f_next; if (f==NULL) break; @@ -114,19 +111,35 @@ int backsql_process_sub_filter(backsql_srch_info *bsi,Filter *f) backsql_at_map_rec *at=backsql_at_with_name(bsi->oc,f->f_sub_type); - bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr, + bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",NULL); + + if (bsi->bi->upper_func) + { + bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len, + bsi->bi->upper_func,"(",at->sel_expr,")", + " LIKE '",NULL); + } + else + { + bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,at->sel_expr, " LIKE '",NULL); + } if (f->f_sub_initial!=NULL) - bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_initial,NULL); + { + bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_initial->bv_val,NULL); + } bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"%",NULL); if (f->f_sub_any!=NULL) for(i=0;f->f_sub_any[i]!=NULL;i++) - bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_any[i],"%",NULL); + { + //Debug(LDAP_DEBUG_TRACE,"==>backsql_process_sub_filter(): sub_any='%s'\n",f->f_sub_any[i]->bv_val,0,0); + bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_any[i]->bv_val,"%",NULL); + } if (f->f_sub_final!=NULL) - bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_final,NULL); + bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,f->f_sub_final->bv_val,NULL); bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"')",NULL); @@ -179,6 +192,7 @@ int backsql_process_filter(backsql_srch_info *bsi,Filter *f) { Debug(LDAP_DEBUG_TRACE,"backsql_process_filter(): attribute '%s' is not defined for objectclass '%s'\n", at_name,bsi->oc->name,0); + bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len," 1=0 ",NULL); return -1; } @@ -195,8 +209,17 @@ int backsql_process_filter(backsql_srch_info *bsi,Filter *f) switch(f->f_choice) { case LDAP_FILTER_EQUALITY: - bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,"='", - f->f_avvalue.bv_val,"')",NULL); + //maybe we should check type of at->sel_expr here somehow, + //to know whether upper_func is applicable, but for now + //upper_func stuff is made for Oracle, where UPPER is + //safely applicable to NUMBER etc. + if (bsi->bi->upper_func) + bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(", + bsi->bi->upper_func,"(",at->sel_expr,")='", + f->f_avvalue.bv_val,"')",NULL); + else + bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,"='", + f->f_avvalue.bv_val,"')",NULL); break; case LDAP_FILTER_GE: bsi->flt_where=backsql_strcat(bsi->flt_where,&bsi->fwhere_len,"(",at->sel_expr,">=", @@ -247,8 +270,16 @@ char* backsql_srch_query(backsql_srch_info *bsi) switch(bsi->scope) { case LDAP_SCOPE_BASE: - bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len, + if (bsi->bi->upper_func) + { + bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len, + bsi->bi->upper_func,"(","ldap_entries.dn)=(?)",NULL); + } + else + { + bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len, "ldap_entries.dn=?",NULL); + } break; case LDAP_SCOPE_ONELEVEL: bsi->join_where=backsql_strcat(bsi->join_where,&bsi->jwhere_len, @@ -318,7 +349,7 @@ int backsql_oc_get_candidates(backsql_oc_map_rec *oc,backsql_srch_info *bsi) } break; case LDAP_SCOPE_ONELEVEL: - res=backsql_dn2id(&base_id,bsi->dbh,bsi->base_dn); + res=backsql_dn2id(bsi->bi,&base_id,bsi->dbh,bsi->base_dn); if (res==NULL) { Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): could not retrieve base_dn id - no such entry\n",0,0,0); @@ -360,15 +391,15 @@ int backsql_oc_get_candidates(backsql_oc_map_rec *oc,backsql_srch_info *bsi) } */ - Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): adding entry id=%s, keyval=%s dn='%s'\n", - row.cols[0],row.cols[1],row.cols[3]); c_id=(backsql_entryID*)ch_calloc(1,sizeof(backsql_entryID)); c_id->id=atoi(row.cols[0]); c_id->keyval=atoi(row.cols[1]); c_id->oc_id=bsi->oc->id; - c_id->dn=strdup(row.cols[3]); + c_id->dn=ch_strdup(row.cols[3]); c_id->next=bsi->id_list; bsi->id_list=c_id; + Debug(LDAP_DEBUG_TRACE,"backsql_oc_get_candidates(): added entry id=%d, keyval=%d dn='%s'\n", + c_id->id,c_id->keyval,row.cols[3]); } backsql_FreeRow(&row); SQLFreeStmt(sth,SQL_DROP); @@ -376,10 +407,9 @@ int backsql_oc_get_candidates(backsql_oc_map_rec *oc,backsql_srch_info *bsi) return 1; } - -int backsql_search(Backend *be,Connection *conn,Operation *op, - char *base, char *nbase, int scope,int deref,int slimit,int tlimit, - Filter *filter, char *filterstr,char **attrs,int attrsonly) +int backsql_search(BackendDB *be,Connection *conn,Operation *op, + const char *base, const char *nbase, int scope,int deref,int slimit,int tlimit, + Filter *filter, const char *filterstr,char **attrs,int attrsonly) { backsql_info *bi=(backsql_info*)be->be_private; SQLHDBC dbh; @@ -392,9 +422,8 @@ int backsql_search(Backend *be,Connection *conn,Operation *op, backsql_srch_info srch_info; backsql_entryID *eid=NULL; - base=dn_validate(base); Debug(LDAP_DEBUG_TRACE,"==>backsql_search(): base='%s', filter='%s', scope=%d,", - base,filterstr,scope); + nbase,filterstr,scope); Debug(LDAP_DEBUG_TRACE," deref=%d, attrsonly=%d, attributes to load: %s\n", deref,attrsonly,attrs==NULL?"all":"custom list"); dbh=backsql_get_db_conn(be,conn); @@ -427,11 +456,8 @@ int backsql_search(Backend *be,Connection *conn,Operation *op, be->be_sizelimit : slimit; } - //backsql_init_search(&srch_info,bi,nbase/*!!!!!!!!*/,scope,slimit,tlimit,stoptime,filter,dbh, -// be,conn,op,attrs); - backsql_init_search(&srch_info,bi,base/*don't know so far how to make Oracle do CIS search on VARCHAR2*/, - scope,slimit,tlimit,stoptime,filter,dbh, - be,conn,op,attrs); + backsql_init_search(&srch_info,bi,(char*)nbase,scope,slimit,tlimit,stoptime,filter,dbh, + be,conn,op,attrs); //for each objectclass we try to construct query which gets IDs //of entries matching LDAP query filter and scope (or at least candidates), @@ -494,7 +520,7 @@ int backsql_search(Backend *be,Connection *conn,Operation *op, for(eid=srch_info.id_list;eid!=NULL;eid=backsql_free_entryID(eid)); - //free bsi->attrs!!!!!!!!!!!!!!!!!!!!!!!!!!! + charray_free(srch_info.attrs); if (nentries>0) send_search_result( conn, op, @@ -507,4 +533,4 @@ int backsql_search(Backend *be,Connection *conn,Operation *op, return 0; } -#endif /* SLAPD_SQL */ \ No newline at end of file +#endif /* SLAPD_SQL */ diff --git a/servers/slapd/back-sql/sql-types.h b/servers/slapd/back-sql/sql-types.h index 45af97e827..f709cd3b17 100644 --- a/servers/slapd/back-sql/sql-types.h +++ b/servers/slapd/back-sql/sql-types.h @@ -2,7 +2,7 @@ #define __BACKSQL_SQL_TYPES_H__ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this diff --git a/servers/slapd/back-sql/sql-wrap.c b/servers/slapd/back-sql/sql-wrap.c index 770ab597fe..4b54c9961b 100644 --- a/servers/slapd/back-sql/sql-wrap.c +++ b/servers/slapd/back-sql/sql-wrap.c @@ -1,5 +1,5 @@ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this @@ -138,7 +138,7 @@ RETCODE backsql_BindRowAsStrings(SQLHSTMT sth,BACKSQL_ROW_NTS *row) { rc=SQLDescribeCol(sth,(SQLSMALLINT)i,&colname[0],(SQLUINTEGER)sizeof(colname)-1,&name_len,&col_type, (UDWORD*) &col_prec,&col_scale,&col_null); - row->col_names[i-1]=strdup(colname); + row->col_names[i-1]=ch_strdup(colname); //Debug(LDAP_DEBUG_TRACE,"backsql_BindRowAsStrings: col_name=%s, col_prec[%d]=%d\n",colname,(int)i,(int)col_prec); if (col_type == SQL_LONGVARCHAR || col_type== SQL_LONGVARBINARY) { @@ -313,4 +313,4 @@ SQLHDBC backsql_get_db_conn(Backend *be,Connection *ldapc) return dbc->dbh; } -#endif /* SLAPD_SQL */ \ No newline at end of file +#endif /* SLAPD_SQL */ diff --git a/servers/slapd/back-sql/sql-wrap.h b/servers/slapd/back-sql/sql-wrap.h index 4669b6436a..64067f1088 100644 --- a/servers/slapd/back-sql/sql-wrap.h +++ b/servers/slapd/back-sql/sql-wrap.h @@ -2,7 +2,7 @@ #define __BACKSQL_SQL_WRAP_H__ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this diff --git a/servers/slapd/back-sql/util.c b/servers/slapd/back-sql/util.c index 4ed26c6cf1..5965182b3a 100644 --- a/servers/slapd/back-sql/util.c +++ b/servers/slapd/back-sql/util.c @@ -1,5 +1,5 @@ /* - * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved. + * Copyright 1999, Dmitry Kovalev , All rights reserved. * * Redistribution and use in source and binary forms are permitted only * as authorized by the OpenLDAP Public License. A copy of this @@ -20,11 +20,12 @@ #include "util.h" -char backsql_def_oc_query[]="SELECT id,name,keytbl,keycol,create_proc,delete_proc FROM ldap_objclasses"; -char backsql_def_at_query[]="SELECT name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc FROM ldap_attrs WHERE oc_id=?"; +char backsql_def_oc_query[]="SELECT id,name,keytbl,keycol,create_proc,delete_proc,expect_return FROM ldap_objclasses"; +char backsql_def_at_query[]="SELECT name,sel_expr,from_tbls,join_where,add_proc,modify_proc,delete_proc,param_order,expect_return FROM ldap_attrs WHERE oc_id=?"; char backsql_def_delentry_query[]="DELETE FROM ldap_entries WHERE id=?"; char backsql_def_insentry_query[]="INSERT INTO ldap_entries (dn,objclass,parent,keyval) VALUES (?,?,?,?)"; char backsql_def_subtree_cond[]="ldap_entries.dn LIKE CONCAT('%',?)"; +char backsql_id_query[]="SELECT id,keyval,objclass FROM ldap_entries WHERE "; char* backsql_strcat(char* dest,int *buflen, ...) @@ -78,7 +79,7 @@ int backsql_entry_addattr(Entry *e,char *at_name,char *at_val,unsigned int at_va { //Debug(LDAP_DEBUG_TRACE,"backsql_addattr(): creating new attribute\n",0,0,0); c_at=(Attribute *)ch_calloc(sizeof(Attribute),1); - c_at->a_type=strdup(at_name); + c_at->a_type=ch_strdup(at_name); c_at->a_syntax=SYNTAX_CIS; c_at->a_vals=(struct berval**)ch_calloc(sizeof(struct berval *),1); c_at->a_vals[0]=NULL; @@ -143,10 +144,10 @@ int backsql_merge_from_clause(char **dest_from,int *dest_len,char *src_from) //Debug(LDAP_DEBUG_TRACE,"==>backsql_merge_from_clause(): dest_from='%s',src_from='%s'\n", // dest_from,src_from,0); - srcc=strdup(src_from); + srcc=ch_strdup(src_from); p=srcc; while(*p) - {//4832041 + { s=backsql_get_table_spec(&p); // Debug(LDAP_DEBUG_TRACE,"backsql_merge_from_clause(): p='%s' s='%s'\n",p,s,0); if (*dest_from==NULL) @@ -164,4 +165,4 @@ int backsql_merge_from_clause(char **dest_from,int *dest_len,char *src_from) return 1; } -#endif /* SLAPD_SQL */ \ No newline at end of file +#endif /* SLAPD_SQL */ diff --git a/servers/slapd/back-sql/util.h b/servers/slapd/back-sql/util.h index b3e8bd23a4..1fe0cbab2c 100644 --- a/servers/slapd/back-sql/util.h +++ b/servers/slapd/back-sql/util.h @@ -1,6 +1,15 @@ #ifndef __BACKSQL_UTIL_H__ #define __BACKSQL_UTIL_H__ +/* + * Copyright 1999, Dmitry Kovalev , All rights reserved. + * + * Redistribution and use in source and binary forms are permitted only + * as authorized by the OpenLDAP Public License. A copy of this + * license is available at http://www.OpenLDAP.org/license.html or + * in file LICENSE in the top-level directory of the distribution. + */ + #include "entry-id.h" #include "schema-map.h" @@ -44,7 +53,7 @@ Entry* backsql_id2entry(backsql_srch_info *bsi,Entry* e,backsql_entryID* id); extern char backsql_def_oc_query[],backsql_def_at_query[], backsql_def_delentry_query[],backsql_def_insentry_query[], - backsql_def_subtree_cond[]; + backsql_def_subtree_cond[],backsql_id_query[]; int backsql_merge_from_clause(char **dest_from,int *dest_len,char *src_from); -- 2.39.5