]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-sql/modify.c
Add a safety check to bvcasechr
[openldap] / servers / slapd / back-sql / modify.c
index c4a8eb3dc1efc58b0e44cd6a5f7d33bc74e78428..9514da01552c760cbb3c5140c9195b495b93d0f7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *      Copyright 1999, Dmitry Kovalev (zmit@mail.ru), All rights reserved.
+ *      Copyright 1999, Dmitry Kovalev <mit@openldap.org>, 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,Modifications *modlist)
 {
  backsql_info *bi=(backsql_info*)be->be_private;
  SQLHDBC dbh;
@@ -30,13 +30,15 @@ int backsql_modify(BackendDB *be,Connection *conn,Operation *op,
  RETCODE rc;
  backsql_oc_map_rec *oc=NULL;
  backsql_entryID e_id,*res;
- LDAPModList *c_mod;
+ Modification *c_mod;
+ Modifications *ml;
  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 +46,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);
@@ -63,22 +65,21 @@ int backsql_modify(BackendDB *be,Connection *conn,Operation *op,
  SQLAllocStmt(dbh, &sth);
 
  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): traversing modifications list\n",0,0,0);
- for(c_mod=modlist;c_mod!=NULL;c_mod=c_mod->ml_next)
+ for(ml=modlist;ml!=NULL;ml=ml->sml_next)
  {
-  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): attribute '%s'\n",c_mod->ml_type,0,0);
-  at=backsql_at_with_name(oc,c_mod->ml_type);
+  c_mod=&ml->sml_mod;
+  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): attribute '%s'\n",c_mod->sm_desc->ad_cname.bv_val,0,0);
+  at=backsql_at_with_name(oc,c_mod->sm_desc->ad_cname.bv_val);
   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->sm_desc->ad_cname.bv_val,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)
+  
+  switch(c_mod->sm_op)
   {
    case LDAP_MOD_REPLACE:
                        {
-                        char *query;
-                        int qlen;
                         SQLHSTMT asth;
                         BACKSQL_ROW_NTS row;
                         
@@ -89,27 +90,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 +108,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 +119,18 @@ del_all:
                         {
                          for (i=0;i<row.ncols;i++)
                          {
-                          SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,row.cols[i],strlen(row.cols[i]),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,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)
@@ -141,23 +143,33 @@ del_all:
                         backsql_FreeRow(&row);
              SQLFreeStmt(asth,SQL_DROP);
                        }
-                       //PASSTHROUGH - to add new attributes -- do NOT add break
+                       /*PASSTHROUGH - to add new attributes -- do NOT add break*/
   case LDAP_MOD_ADD:
                        if (at->add_proc==NULL)
                        {
                         Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add procedure is not defined for this attribute ('%s')\n",at->name,0,0);
                         break;
                        }
-                       if (c_mod->ml_bvalues==NULL)
+                       if (c_mod->sm_bvalues==NULL)
                        {
                         Debug(LDAP_DEBUG_TRACE,"backsql_modify(): no values given to add for attribute '%s'\n",at->name,0,0);
                         break;
                        }
                        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])
+                       for(i=0,at_val=c_mod->sm_bvalues[0];at_val!=NULL;i++,at_val=c_mod->sm_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)
@@ -173,16 +185,26 @@ del_all:
                         Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete procedure is not defined for this attribute ('%s')\n",at->name,0,0);
                         break;
                        }
-                       if (c_mod->ml_bvalues==NULL)
+                       if (c_mod->sm_bvalues==NULL)
                        {
                         Debug(LDAP_DEBUG_TRACE,"backsql_modify(): no values given to delete for attribute '%s' -- deleting all values\n",at->name,0,0);
                         goto 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])
+                       for(i=0,at_val=c_mod->sm_bvalues[0];at_val!=NULL;i++,at_val=c_mod->sm_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,9 +225,122 @@ 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);
+ backsql_info *bi=(backsql_info*)be->be_private;
+ SQLHDBC dbh;
+ SQLHSTMT sth;
+ RETCODE rc;
+ backsql_oc_map_rec *oc=NULL;
+ backsql_entryID e_id,pe_id,new_pid,*res;
+ backsql_at_map_rec *at=NULL;
+ char *p_dn=NULL,*new_pdn=NULL, *new_dn;
+ Debug(LDAP_DEBUG_TRACE,"==>backsql_modrdn() renaming entry '%s', newrdn='%s', newSuperior='%s'\n",dn,newrdn,newSuperior);
+ dbh=backsql_get_db_conn(be,conn);
+ if (!dbh)
+ {
+  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not get connection handle - exiting\n",0,0,0);
+  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
+  return 1;
+ }
+ res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
+ if (res==NULL)
+ {
+  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not lookup entry id\n",0,0,0);
+  send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
+  return 1;
+ }
+ Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): entry id is %d\n",e_id.id,0,0);
+
+ p_dn=dn_parent(be,ndn);
+
+ if (newSuperior)
+  new_pdn=dn_validate(ch_strdup(newSuperior));
+ else
+   new_pdn=p_dn;
+
+ SQLAllocStmt(dbh, &sth);
+
+ if (newSuperior && !strcasecmp(p_dn,new_pdn))
+ {
+  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): newSuperior is equal to old parent - aborting\n",0,0,0);
+  send_ldap_result(conn,op,LDAP_OTHER,"",NULL,NULL,NULL);
+  goto modrdn_return;
+ }
+
+ if (newSuperior && !strcasecmp(ndn,new_pdn))
+ {
+  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): newSuperior is equal to entry being moved - aborting\n",0,0,0);
+  send_ldap_result(conn,op,LDAP_OTHER,"",NULL,NULL,NULL);
+  goto modrdn_return;
+ }
+
+ build_new_dn( &new_dn, dn, new_pdn, newrdn ); 
+ if (!dn_validate(new_dn))
+ {
+  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): new dn is invalid ('%s') - aborting\n",new_dn,0,0);
+  send_ldap_result(conn,op,LDAP_OTHER,"",NULL,NULL,NULL);
+  goto modrdn_return;
+ }
+ Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): new entry dn is '%s'\n",new_dn,0,0);
+
+ res=backsql_dn2id(bi,&pe_id,dbh,(char*)p_dn);
+ if (res==NULL)
+ {
+  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not lookup old parent entry id\n",0,0,0);
+  send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
+  goto modrdn_return;
+ }
+ Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): old parent entry id is %d\n",pe_id.id,0,0);
+
+ res=backsql_dn2id(bi,&new_pid,dbh,(char*)new_pdn);
+ if (res==NULL)
+ {
+  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not lookup new parent entry id\n",0,0,0);
+  send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
+  goto modrdn_return;
+ }
+ Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): new parent entry id is %d\n",new_pid.id,0,0);
+
+ Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): executing delentry_query\n",0,0,0);
+ SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.id,0,0);
+ rc=SQLExecDirect(sth,bi->delentry_query,SQL_NTS);
+ if (rc != SQL_SUCCESS)
+ {
+  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): failed to delete record from ldap_entries\n",0,0,0);
+  backsql_PrintErrors(bi->db_env,dbh,sth,rc);
+  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
+  goto modrdn_return;
+ }
+
+ SQLFreeStmt(sth,SQL_RESET_PARAMS);
+
+ Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): executing insentry_query\n",0,0,0);
+ backsql_BindParamStr(sth,1,new_dn,BACKSQL_MAX_DN_LEN);
+ SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&e_id.oc_id,0,0);
+ SQLBindParameter(sth,3,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_pid.id,0,0);
+ SQLBindParameter(sth,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
+ rc=SQLExecDirect(sth,bi->insentry_query,SQL_NTS);
+ if (rc != SQL_SUCCESS)
+ {
+  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not insert ldap_entries record\n",0,0,0);
+  backsql_PrintErrors(bi->db_env,dbh,sth,rc);
+  send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
+  goto modrdn_return;
+ }
+
+ /*should process deleteoldrdn here...*/
+
+ send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
+modrdn_return:
+ SQLFreeStmt(sth,SQL_DROP);
+ if (newSuperior && new_pdn)
+  ch_free(new_pdn);
+ if (new_dn)
+  ch_free(new_dn);
+ Debug(LDAP_DEBUG_TRACE,"<==backsql_modrdn()\n",0,0,0);
  return 0;
 }
 
@@ -223,6 +358,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)
@@ -231,8 +368,8 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
  }
  for(at=e->e_attrs;at!=NULL;at=at->a_next)
  {
-  //Debug(LDAP_DEBUG_TRACE,"backsql_add(): scanning entry -- %s\n",at->a_type,0,0);
-  if (!strcasecmp(at->a_type,"objectclass"))
+  /*Debug(LDAP_DEBUG_TRACE,"backsql_add(): scanning entry -- %s\n",at->a_type,0,0);*/
+  if (!strcasecmp(at->a_desc->ad_cname.bv_val,"objectclass"))
   {
    oc=backsql_oc_with_name(bi,at->a_vals[0]->bv_val);
    break;
@@ -262,7 +399,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);
@@ -279,24 +415,32 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
 
  for(at=e->e_attrs;at!=NULL;at=at->a_next)
  {
-  at_rec=backsql_at_with_name(oc,at->a_type);
+  at_rec=backsql_at_with_name(oc,at->a_desc->ad_cname.bv_val); 
+  
   if (at_rec==NULL)
   {
-   Debug(LDAP_DEBUG_TRACE,"backsql_add(): attribute provided is not registered in this objectclass ('%s')\n",at->a_type,0,0);
+   Debug(LDAP_DEBUG_TRACE,"backsql_add(): attribute provided is not registered in this objectclass ('%s')\n",at->a_desc->ad_cname.bv_val,0,0);
    continue;
   }
   if (at_rec->add_proc==NULL)
   {
-   Debug(LDAP_DEBUG_TRACE,"backsql_add(): add procedure is not defined for this attribute ('%s')\n",at->a_type,0,0);
+   Debug(LDAP_DEBUG_TRACE,"backsql_add(): add procedure is not defined for this attribute ('%s')\n",at->a_desc->ad_cname.bv_val,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 +452,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",
@@ -316,7 +460,6 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
   return 1;
  }
- free(pdn);
  backsql_BindParamStr(sth,1,e->e_dn,BACKSQL_MAX_DN_LEN);
  SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&oc->id,0,0);
  SQLBindParameter(sth,3,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&parent_id.id,0,0);
@@ -326,7 +469,7 @@ int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
  {
   Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not insert ldap_entries record\n",0,0,0);
   backsql_PrintErrors(bi->db_env,dbh,sth,rc);
-  //execute delete_proc to delete data added !!!
+  /*execute delete_proc to delete data added !!!*/
   SQLFreeStmt(sth,SQL_DROP);
   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
   return 1;
@@ -337,7 +480,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 +488,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 +498,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,8 +521,15 @@ 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);
- //SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,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);
  rc=SQLExecDirect(sth,oc->delete_proc,SQL_NTS);
@@ -410,4 +560,4 @@ int backsql_delete(BackendDB *be,Connection *conn,Operation *op,
  return 0;
 }
 
-#endif /* SLAPD_SQL */
\ No newline at end of file
+#endif /* SLAPD_SQL */