]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/modify.c
changes for 2.0-beta
[openldap] / servers / slapd / back-sql / modify.c
1 /*
2  *       Copyright 1999, Dmitry Kovalev <mit@openldap.org>, All rights reserved.
3  *
4  *       Redistribution and use in source and binary forms are permitted only
5  *       as authorized by the OpenLDAP Public License.  A copy of this
6  *       license is available at http://www.OpenLDAP.org/license.html or
7  *       in file LICENSE in the top-level directory of the distribution.
8  */
9
10 #include "portable.h"
11
12 #ifdef SLAPD_SQL
13
14 #include <stdio.h>
15 #include <sys/types.h>
16 #include <string.h>
17 #include "slap.h"
18 #include "back-sql.h"
19 #include "sql-wrap.h"
20 #include "schema-map.h"
21 #include "entry-id.h"
22 #include "util.h"
23
24 int backsql_modify(BackendDB *be,Connection *conn,Operation *op,
25         const char *dn,const char *ndn,Modifications *modlist)
26 {
27  backsql_info *bi=(backsql_info*)be->be_private;
28  SQLHDBC dbh;
29  SQLHSTMT sth;
30  RETCODE rc;
31  backsql_oc_map_rec *oc=NULL;
32  backsql_entryID e_id,*res;
33  Modification *c_mod;
34  Modifications *ml;
35  backsql_at_map_rec *at=NULL;
36  struct berval *at_val;
37  int i;
38  int pno,po;//first parameter no, parameter order
39  int prc; //procedure return code
40
41  Debug(LDAP_DEBUG_TRACE,"==>backsql_modify(): changing entry '%s'\n",ndn,0,0);
42  dbh=backsql_get_db_conn(be,conn);
43  if (!dbh)
44  {
45   Debug(LDAP_DEBUG_TRACE,"backsql_modify(): could not get connection handle - exiting\n",0,0,0);
46   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
47   return 1;
48  }
49  res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
50  if (res==NULL)
51  {
52   Debug(LDAP_DEBUG_TRACE,"backsql_modify(): could not lookup entry id\n",0,0,0);
53   send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
54   return 1;
55  }
56
57  oc=backsql_oc_with_id(bi,e_id.oc_id);
58  if (oc==NULL)
59  {
60   Debug(LDAP_DEBUG_TRACE,"backsql_modify(): cannot determine objectclass of entry -- aborting\n",0,0,0);
61   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
62   return 1;
63  }
64
65  SQLAllocStmt(dbh, &sth);
66
67  Debug(LDAP_DEBUG_TRACE,"backsql_modify(): traversing modifications list\n",0,0,0);
68  for(ml=modlist;ml!=NULL;ml=ml->sml_next)
69  {
70   c_mod=&ml->sml_mod;
71   Debug(LDAP_DEBUG_TRACE,"backsql_modify(): attribute '%s'\n",c_mod->sm_desc->ad_cname->bv_val,0,0);
72   at=backsql_at_with_name(oc,c_mod->sm_desc->ad_cname->bv_val);
73   if (at==NULL)
74   {
75    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);
76    continue;
77   }
78   
79   switch(c_mod->sm_op)
80   {
81    case LDAP_MOD_REPLACE:
82                         {
83                          SQLHSTMT asth;
84                          BACKSQL_ROW_NTS row;
85                          
86                          Debug(LDAP_DEBUG_TRACE,"backsql_modify(): replacing values for attribute '%s'\n",at->name,0,0);
87              if (at->add_proc==NULL)
88                          {
89                           Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add procedure is not defined for this attribute ('%s') - unable to perform replacements\n",at->name,0,0);
90                           break;
91                          }
92 del_all:
93                          
94                          if ((rc=backsql_Prepare(dbh,&asth,at->query,0)) != SQL_SUCCESS)
95                          {
96                           Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error preparing query\n",0,0,0);
97                           backsql_PrintErrors(bi->db_env,dbh,asth,rc);
98                           break;
99                          }
100
101                          if (backsql_BindParamID(asth,1,&e_id.keyval) != SQL_SUCCESS)
102                          {
103                           Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error binding key value parameter\n",0,0,0);
104                           backsql_PrintErrors(bi->db_env,dbh,asth,rc);
105                           SQLFreeStmt(asth,SQL_DROP);
106                           break;
107                          }
108
109                          if ((rc=SQLExecute(asth)) != SQL_SUCCESS && rc!= SQL_SUCCESS_WITH_INFO)
110                          {
111                           Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error executing attribute query\n",0,0,0);
112                           backsql_PrintErrors(bi->db_env,dbh,asth,rc);
113                           SQLFreeStmt(asth,SQL_DROP);
114                           break;
115                          }
116
117                          backsql_BindRowAsStrings(asth,&row);
118                          while ((rc=SQLFetch(asth)) == SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO)
119                          {
120                           for (i=0;i<row.ncols;i++)
121                           {
122                            if (at->expect_return & BACKSQL_DEL)
123                            {
124                             pno=1;
125                             SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
126                            }
127                            else
128                             pno=0;
129                            po=(at->param_order & BACKSQL_DEL)>0;
130                            SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
131                            //check for syntax needed here - maybe need binary bind?
132                            SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,row.cols[i],strlen(row.cols[i]),0);
133                          
134                            Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0);
135                            rc=SQLExecDirect(sth,at->delete_proc,SQL_NTS);
136                            if (rc!=SQL_SUCCESS)
137                                 {
138                              Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete_proc execution failed\n",0,0,0);
139                              backsql_PrintErrors(bi->db_env,dbh,sth,rc);
140                                 }
141                           }
142                          }
143                          backsql_FreeRow(&row);
144              SQLFreeStmt(asth,SQL_DROP);
145                         }
146                         //PASSTHROUGH - to add new attributes -- do NOT add break
147   case LDAP_MOD_ADD:
148                         if (at->add_proc==NULL)
149                         {
150                          Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add procedure is not defined for this attribute ('%s')\n",at->name,0,0);
151                          break;
152                         }
153                         if (c_mod->sm_bvalues==NULL)
154                         {
155                          Debug(LDAP_DEBUG_TRACE,"backsql_modify(): no values given to add for attribute '%s'\n",at->name,0,0);
156                          break;
157                         }
158                         Debug(LDAP_DEBUG_TRACE,"backsql_modify(): adding new values for attribute '%s'\n",at->name,0,0);
159                         for(i=0,at_val=c_mod->sm_bvalues[0];at_val!=NULL;i++,at_val=c_mod->sm_bvalues[i])
160                         {
161                          if (at->expect_return & BACKSQL_ADD)
162                          {
163                           pno=1;
164                           SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
165                          }
166                          else
167                           pno=0;
168                          po=(at->param_order & BACKSQL_ADD)>0;
169                          SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
170                          //check for syntax needed here - maybe need binary bind?
171                          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);
172                          
173                          Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->add_proc,0,0);
174                          rc=SQLExecDirect(sth,at->add_proc,SQL_NTS);
175                          if (rc!=SQL_SUCCESS)
176                          {
177                           Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add_proc execution failed\n",0,0,0);
178                           backsql_PrintErrors(bi->db_env,dbh,sth,rc);
179                          }
180                         }
181                         break;
182   case LDAP_MOD_DELETE:
183                         if (at->delete_proc==NULL)
184                         {
185                          Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete procedure is not defined for this attribute ('%s')\n",at->name,0,0);
186                          break;
187                         }
188                         if (c_mod->sm_bvalues==NULL)
189                         {
190                          Debug(LDAP_DEBUG_TRACE,"backsql_modify(): no values given to delete for attribute '%s' -- deleting all values\n",at->name,0,0);
191                          goto del_all;
192                         }
193             Debug(LDAP_DEBUG_TRACE,"backsql_modify(): deleting values for attribute '%s'\n",at->name,0,0);
194                         for(i=0,at_val=c_mod->sm_bvalues[0];at_val!=NULL;i++,at_val=c_mod->sm_bvalues[i])
195                         {
196                          if (at->expect_return & BACKSQL_DEL)
197                           {
198                            pno=1;
199                            SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
200                           }
201                          else
202                           pno=0;
203                          po=(at->param_order & BACKSQL_DEL)>0;
204                          SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
205                          //check for syntax needed here - maybe need binary bind?
206                          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);
207                            
208                          Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0);
209                          rc=SQLExecDirect(sth,at->delete_proc,SQL_NTS);
210                          if (rc!=SQL_SUCCESS)
211                          {
212                           Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete_proc execution failed\n",0,0,0);
213                           backsql_PrintErrors(bi->db_env,dbh,sth,rc);
214                          }
215                         }
216                         break;
217   }
218   SQLFreeStmt(sth,SQL_RESET_PARAMS);
219  }
220
221  SQLFreeStmt(sth,SQL_DROP);
222  send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
223  Debug(LDAP_DEBUG_TRACE,"<==backsql_modify()\n",0,0,0);
224  return 0;
225 }
226
227 int backsql_modrdn(BackendDB *be,Connection *conn,Operation *op,
228         const char *dn,const char *ndn,const char *newrdn,int deleteoldrdn,const char *newSuperior)
229 {
230  backsql_info *bi=(backsql_info*)be->be_private;
231  SQLHDBC dbh;
232  SQLHSTMT sth;
233  RETCODE rc;
234  backsql_oc_map_rec *oc=NULL;
235  backsql_entryID e_id,pe_id,new_pid,*res;
236  backsql_at_map_rec *at=NULL;
237  char *p_dn=NULL,*new_pdn=NULL, *new_dn;
238  
239  
240  Debug(LDAP_DEBUG_TRACE,"==>backsql_modrdn() renaming entry '%s', newrdn='%s', newSuperior='%s'\n",dn,newrdn,newSuperior);
241  dbh=backsql_get_db_conn(be,conn);
242  if (!dbh)
243  {
244   Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not get connection handle - exiting\n",0,0,0);
245   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
246   return 1;
247  }
248  res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
249  if (res==NULL)
250  {
251   Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not lookup entry id\n",0,0,0);
252   send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
253   return 1;
254  }
255  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): entry id is %d\n",e_id.id,0,0);
256
257  p_dn=dn_parent(be,ndn);
258
259  if (newSuperior)
260   new_pdn=dn_validate(ch_strdup(newSuperior));
261  else
262    new_pdn=p_dn;
263
264  SQLAllocStmt(dbh, &sth);
265
266  if (newSuperior && !strcasecmp(p_dn,new_pdn))
267  {
268   Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): newSuperior is equal to old parent - aborting\n",0,0,0);
269   send_ldap_result(conn,op,LDAP_OTHER,"",NULL,NULL,NULL);
270   goto modrdn_return;
271  }
272
273  if (newSuperior && !strcasecmp(ndn,new_pdn))
274  {
275   Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): newSuperior is equal to entry being moved - aborting\n",0,0,0);
276   send_ldap_result(conn,op,LDAP_OTHER,"",NULL,NULL,NULL);
277   goto modrdn_return;
278  }
279
280  build_new_dn( &new_dn, dn, new_pdn, newrdn ); 
281  if (!dn_validate(new_dn))
282  {
283   Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): new dn is invalid ('%s') - aborting\n",new_dn,0,0);
284   send_ldap_result(conn,op,LDAP_OTHER,"",NULL,NULL,NULL);
285   goto modrdn_return;
286  }
287  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): new entry dn is '%s'\n",new_dn,0,0);
288
289  res=backsql_dn2id(bi,&pe_id,dbh,(char*)p_dn);
290  if (res==NULL)
291  {
292   Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not lookup old parent entry id\n",0,0,0);
293   send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
294   goto modrdn_return;
295  }
296  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): old parent entry id is %d\n",pe_id.id,0,0);
297
298  res=backsql_dn2id(bi,&new_pid,dbh,(char*)new_pdn);
299  if (res==NULL)
300  {
301   Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not lookup new parent entry id\n",0,0,0);
302   send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
303   goto modrdn_return;
304  }
305  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): new parent entry id is %d\n",new_pid.id,0,0);
306
307  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): executing delentry_query\n",0,0,0);
308  SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.id,0,0);
309  rc=SQLExecDirect(sth,bi->delentry_query,SQL_NTS);
310  if (rc != SQL_SUCCESS)
311  {
312   Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): failed to delete record from ldap_entries\n",0,0,0);
313   backsql_PrintErrors(bi->db_env,dbh,sth,rc);
314   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
315   goto modrdn_return;
316  }
317
318  SQLFreeStmt(sth,SQL_RESET_PARAMS);
319
320  Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): executing insentry_query\n",0,0,0);
321  backsql_BindParamStr(sth,1,new_dn,BACKSQL_MAX_DN_LEN);
322  SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&e_id.oc_id,0,0);
323  SQLBindParameter(sth,3,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_pid.id,0,0);
324  SQLBindParameter(sth,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
325  rc=SQLExecDirect(sth,bi->insentry_query,SQL_NTS);
326  if (rc != SQL_SUCCESS)
327  {
328   Debug(LDAP_DEBUG_TRACE,"backsql_modrdn(): could not insert ldap_entries record\n",0,0,0);
329   backsql_PrintErrors(bi->db_env,dbh,sth,rc);
330   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
331   goto modrdn_return;
332  }
333
334  //should process deleteoldrdn here...
335
336  send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
337 modrdn_return:
338  SQLFreeStmt(sth,SQL_DROP);
339  if (p_dn)
340   ch_free(p_dn);
341  if (newSuperior && new_pdn)
342   ch_free(new_pdn);
343  if (new_dn)
344   ch_free(new_dn);
345  Debug(LDAP_DEBUG_TRACE,"<==backsql_modrdn()\n",0,0,0);
346  return 0;
347 }
348
349 int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
350 {
351  backsql_info *bi=(backsql_info*)be->be_private;
352  SQLHDBC dbh;
353  SQLHSTMT sth;
354  unsigned long new_keyval;
355  long i;
356  RETCODE rc;
357  backsql_oc_map_rec *oc=NULL;
358  backsql_at_map_rec *at_rec=NULL;
359  backsql_entryID parent_id,*res;
360  Attribute *at;
361  struct berval *at_val;
362  char *pdn;
363  int pno,po;//first parameter no, parameter order
364  int prc; //procedure return code
365
366  Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): adding entry '%s'\n",e->e_dn,0,0);
367  if (dn_validate(e->e_dn)==NULL)
368  {
369   Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): invalid dn '%s' -- aborting\n",e->e_dn,0,0);
370  }
371  for(at=e->e_attrs;at!=NULL;at=at->a_next)
372  {
373   //Debug(LDAP_DEBUG_TRACE,"backsql_add(): scanning entry -- %s\n",at->a_type,0,0);
374   if (!strcasecmp(at->a_desc->ad_cname->bv_val,"objectclass"))
375   {
376    oc=backsql_oc_with_name(bi,at->a_vals[0]->bv_val);
377    break;
378   }
379  }
380
381  if (oc==NULL)
382  {
383   Debug(LDAP_DEBUG_TRACE,"backsql_add(): cannot determine objectclass of entry -- aborting\n",0,0,0);
384   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
385   return 1;
386  }
387  if (oc->create_proc == NULL)
388  {
389   Debug(LDAP_DEBUG_TRACE,"backsql_add(): create procedure is not defined for this objectclass - aborting\n",0,0,0);
390   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
391   return 1;
392  }
393
394  dbh=backsql_get_db_conn(be,conn);
395  if (!dbh)
396  {
397   Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not get connection handle - exiting\n",0,0,0);
398   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
399   return 1;
400  }
401
402  SQLAllocStmt(dbh, &sth);
403  SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
404
405  Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",oc->create_proc,0,0);
406  rc=SQLExecDirect(sth,oc->create_proc,SQL_NTS);
407  if (rc != SQL_SUCCESS)
408  {
409   Debug(LDAP_DEBUG_TRACE,"backsql_add(): create_proc execution failed\n",0,0,0);
410   backsql_PrintErrors(bi->db_env,dbh,sth,rc);
411   SQLFreeStmt(sth,SQL_DROP);
412   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
413   return 1;
414  }
415  SQLFreeStmt(sth,SQL_RESET_PARAMS);
416  Debug(LDAP_DEBUG_TRACE,"backsql_add(): create_proc returned keyval=%d\n",new_keyval,0,0);
417
418  for(at=e->e_attrs;at!=NULL;at=at->a_next)
419  {
420   at_rec=backsql_at_with_name(oc,at->a_desc->ad_cname->bv_val); 
421   
422   if (at_rec==NULL)
423   {
424    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);
425    continue;
426   }
427   if (at_rec->add_proc==NULL)
428   {
429    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);
430    continue;
431   }
432   
433   for(i=0,at_val=at->a_vals[0];at_val!=NULL;i++,at_val=at->a_vals[i])
434   {
435         if (at_rec->expect_return & BACKSQL_ADD)
436         {
437          pno=1;
438          SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
439         }
440         else
441          pno=0;
442         po=(at_rec->param_order & BACKSQL_ADD)>0;
443         SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
444         //check for syntax needed here - maybe need binary bind?
445         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);
446    Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",at_rec->add_proc,0,0);
447    rc=SQLExecDirect(sth,at_rec->add_proc,SQL_NTS);
448    if (rc!=SQL_SUCCESS)
449    {
450         Debug(LDAP_DEBUG_TRACE,"backsql_add(): add_proc execution failed\n",0,0,0);
451         backsql_PrintErrors(bi->db_env,dbh,sth,rc);
452    }
453   }
454  }
455  SQLFreeStmt(sth,SQL_RESET_PARAMS); 
456  pdn=dn_parent(be,e->e_dn);
457  res=backsql_dn2id(bi,&parent_id,dbh,pdn);
458  if (res==NULL)
459  {
460   Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not lookup parent entry for new record ('%s')\n",
461                                                                                                 pdn,0,0);
462   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
463   return 1;
464  }
465  free(pdn);
466  backsql_BindParamStr(sth,1,e->e_dn,BACKSQL_MAX_DN_LEN);
467  SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&oc->id,0,0);
468  SQLBindParameter(sth,3,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&parent_id.id,0,0);
469  SQLBindParameter(sth,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_keyval,0,0);
470  rc=SQLExecDirect(sth,bi->insentry_query,SQL_NTS);
471  if (rc != SQL_SUCCESS)
472  {
473   Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not insert ldap_entries record\n",0,0,0);
474   backsql_PrintErrors(bi->db_env,dbh,sth,rc);
475   //execute delete_proc to delete data added !!!
476   SQLFreeStmt(sth,SQL_DROP);
477   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
478   return 1;
479  }
480  SQLFreeStmt(sth,SQL_DROP);
481  send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
482  return 0;
483 }
484
485 int backsql_delete(BackendDB *be,Connection *conn,Operation *op,
486         const char *dn,const char *ndn)
487 {
488  backsql_info *bi=(backsql_info*)be->be_private;
489  SQLHDBC dbh;
490  SQLHSTMT sth;
491  RETCODE rc;
492  backsql_oc_map_rec *oc=NULL;
493  backsql_entryID e_id,*res;
494  int pno;//first parameter no, parameter order
495
496  Debug(LDAP_DEBUG_TRACE,"==>backsql_delete(): deleting entry '%s'\n",ndn,0,0);
497  dbh=backsql_get_db_conn(be,conn);
498  if (!dbh)
499  {
500   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not get connection handle - exiting\n",0,0,0);
501   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
502   return 1;
503  }
504  res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
505  if (res==NULL)
506  {
507   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not lookup entry id\n",0,0,0);
508   send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
509   return 1;
510  }
511
512  oc=backsql_oc_with_id(bi,e_id.oc_id);
513  if (oc==NULL)
514  {
515   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): cannot determine objectclass of entry -- aborting\n",0,0,0);
516   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
517   return 1;
518  }
519  if (oc->delete_proc == NULL)
520  {
521   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): delete procedure is not defined for this objectclass - aborting\n",0,0,0);
522   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
523   return 1;
524  }
525
526  SQLAllocStmt(dbh, &sth);
527  if (oc->expect_return)
528  {
529   pno=1;
530   SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&rc,0,0);
531  }
532  else
533   pno=0;
534  SQLBindParameter(sth,(SQLUSMALLINT)(pno+1),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
535  //SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,0,0);
536
537  Debug(LDAP_DEBUG_TRACE,"backsql_delete(): executing '%s'\n",oc->delete_proc,0,0);
538  rc=SQLExecDirect(sth,oc->delete_proc,SQL_NTS);
539  if (rc != SQL_SUCCESS)
540  {
541   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): delete_proc execution failed\n",0,0,0);
542   backsql_PrintErrors(bi->db_env,dbh,sth,rc);
543   SQLFreeStmt(sth,SQL_DROP);
544   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
545   return 1;
546  }
547  SQLFreeStmt(sth,SQL_RESET_PARAMS);
548
549  SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.id,0,0);
550  rc=SQLExecDirect(sth,bi->delentry_query,SQL_NTS);
551  if (rc != SQL_SUCCESS)
552  {
553   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): failed to delete record from ldap_entries\n",0,0,0);
554   backsql_PrintErrors(bi->db_env,dbh,sth,rc);
555   SQLFreeStmt(sth,SQL_DROP);
556   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
557   return 1;
558  }
559  SQLFreeStmt(sth,SQL_DROP);
560
561  send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
562  Debug(LDAP_DEBUG_TRACE,"<==backsql_delete()\n",0,0,0);
563  return 0;
564 }
565
566 #endif /* SLAPD_SQL */