]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/modify.c
Patch: ACL #access-id#<invalid-DN> granted access to everyone (ITS#2006)
[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 (newSuperior && new_pdn)
340   ch_free(new_pdn);
341  if (new_dn)
342   ch_free(new_dn);
343  Debug(LDAP_DEBUG_TRACE,"<==backsql_modrdn()\n",0,0,0);
344  return 0;
345 }
346
347 int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
348 {
349  backsql_info *bi=(backsql_info*)be->be_private;
350  SQLHDBC dbh;
351  SQLHSTMT sth;
352  unsigned long new_keyval;
353  long i;
354  RETCODE rc;
355  backsql_oc_map_rec *oc=NULL;
356  backsql_at_map_rec *at_rec=NULL;
357  backsql_entryID parent_id,*res;
358  Attribute *at;
359  struct berval *at_val;
360  char *pdn;
361  int pno,po;/*first parameter no, parameter order*/
362  int prc; /*procedure return code*/
363
364  Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): adding entry '%s'\n",e->e_dn,0,0);
365  if (dn_validate(e->e_dn)==NULL)
366  {
367   Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): invalid dn '%s' -- aborting\n",e->e_dn,0,0);
368  }
369  for(at=e->e_attrs;at!=NULL;at=at->a_next)
370  {
371   /*Debug(LDAP_DEBUG_TRACE,"backsql_add(): scanning entry -- %s\n",at->a_type,0,0);*/
372   if (!strcasecmp(at->a_desc->ad_cname.bv_val,"objectclass"))
373   {
374    oc=backsql_oc_with_name(bi,at->a_vals[0]->bv_val);
375    break;
376   }
377  }
378
379  if (oc==NULL)
380  {
381   Debug(LDAP_DEBUG_TRACE,"backsql_add(): cannot determine objectclass of entry -- aborting\n",0,0,0);
382   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
383   return 1;
384  }
385  if (oc->create_proc == NULL)
386  {
387   Debug(LDAP_DEBUG_TRACE,"backsql_add(): create procedure is not defined for this objectclass - aborting\n",0,0,0);
388   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
389   return 1;
390  }
391
392  dbh=backsql_get_db_conn(be,conn);
393  if (!dbh)
394  {
395   Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not get connection handle - exiting\n",0,0,0);
396   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
397   return 1;
398  }
399
400  SQLAllocStmt(dbh, &sth);
401  SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
402
403  Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",oc->create_proc,0,0);
404  rc=SQLExecDirect(sth,oc->create_proc,SQL_NTS);
405  if (rc != SQL_SUCCESS)
406  {
407   Debug(LDAP_DEBUG_TRACE,"backsql_add(): create_proc execution failed\n",0,0,0);
408   backsql_PrintErrors(bi->db_env,dbh,sth,rc);
409   SQLFreeStmt(sth,SQL_DROP);
410   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
411   return 1;
412  }
413  SQLFreeStmt(sth,SQL_RESET_PARAMS);
414  Debug(LDAP_DEBUG_TRACE,"backsql_add(): create_proc returned keyval=%d\n",new_keyval,0,0);
415
416  for(at=e->e_attrs;at!=NULL;at=at->a_next)
417  {
418   at_rec=backsql_at_with_name(oc,at->a_desc->ad_cname.bv_val); 
419   
420   if (at_rec==NULL)
421   {
422    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);
423    continue;
424   }
425   if (at_rec->add_proc==NULL)
426   {
427    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);
428    continue;
429   }
430   
431   for(i=0,at_val=at->a_vals[0];at_val!=NULL;i++,at_val=at->a_vals[i])
432   {
433         if (at_rec->expect_return & BACKSQL_ADD)
434         {
435          pno=1;
436          SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
437         }
438         else
439          pno=0;
440         po=(at_rec->param_order & BACKSQL_ADD)>0;
441         SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
442         /*check for syntax needed here - maybe need binary bind?*/
443         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);
444    Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",at_rec->add_proc,0,0);
445    rc=SQLExecDirect(sth,at_rec->add_proc,SQL_NTS);
446    if (rc!=SQL_SUCCESS)
447    {
448         Debug(LDAP_DEBUG_TRACE,"backsql_add(): add_proc execution failed\n",0,0,0);
449         backsql_PrintErrors(bi->db_env,dbh,sth,rc);
450    }
451   }
452  }
453  SQLFreeStmt(sth,SQL_RESET_PARAMS); 
454  pdn=dn_parent(be,e->e_dn);
455  res=backsql_dn2id(bi,&parent_id,dbh,pdn);
456  if (res==NULL)
457  {
458   Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not lookup parent entry for new record ('%s')\n",
459                                                                                                 pdn,0,0);
460   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
461   return 1;
462  }
463  backsql_BindParamStr(sth,1,e->e_dn,BACKSQL_MAX_DN_LEN);
464  SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&oc->id,0,0);
465  SQLBindParameter(sth,3,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&parent_id.id,0,0);
466  SQLBindParameter(sth,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_keyval,0,0);
467  rc=SQLExecDirect(sth,bi->insentry_query,SQL_NTS);
468  if (rc != SQL_SUCCESS)
469  {
470   Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not insert ldap_entries record\n",0,0,0);
471   backsql_PrintErrors(bi->db_env,dbh,sth,rc);
472   /*execute delete_proc to delete data added !!!*/
473   SQLFreeStmt(sth,SQL_DROP);
474   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
475   return 1;
476  }
477  SQLFreeStmt(sth,SQL_DROP);
478  send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
479  return 0;
480 }
481
482 int backsql_delete(BackendDB *be,Connection *conn,Operation *op,
483         const char *dn,const char *ndn)
484 {
485  backsql_info *bi=(backsql_info*)be->be_private;
486  SQLHDBC dbh;
487  SQLHSTMT sth;
488  RETCODE rc;
489  backsql_oc_map_rec *oc=NULL;
490  backsql_entryID e_id,*res;
491  int pno;/*first parameter no, parameter order*/
492
493  Debug(LDAP_DEBUG_TRACE,"==>backsql_delete(): deleting entry '%s'\n",ndn,0,0);
494  dbh=backsql_get_db_conn(be,conn);
495  if (!dbh)
496  {
497   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not get connection handle - exiting\n",0,0,0);
498   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
499   return 1;
500  }
501  res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
502  if (res==NULL)
503  {
504   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not lookup entry id\n",0,0,0);
505   send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
506   return 1;
507  }
508
509  oc=backsql_oc_with_id(bi,e_id.oc_id);
510  if (oc==NULL)
511  {
512   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): cannot determine objectclass of entry -- aborting\n",0,0,0);
513   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
514   return 1;
515  }
516  if (oc->delete_proc == NULL)
517  {
518   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): delete procedure is not defined for this objectclass - aborting\n",0,0,0);
519   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
520   return 1;
521  }
522
523  SQLAllocStmt(dbh, &sth);
524  if (oc->expect_return)
525  {
526   pno=1;
527   SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&rc,0,0);
528  }
529  else
530   pno=0;
531  SQLBindParameter(sth,(SQLUSMALLINT)(pno+1),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
532  /*SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,0,0);*/
533
534  Debug(LDAP_DEBUG_TRACE,"backsql_delete(): executing '%s'\n",oc->delete_proc,0,0);
535  rc=SQLExecDirect(sth,oc->delete_proc,SQL_NTS);
536  if (rc != SQL_SUCCESS)
537  {
538   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): delete_proc execution failed\n",0,0,0);
539   backsql_PrintErrors(bi->db_env,dbh,sth,rc);
540   SQLFreeStmt(sth,SQL_DROP);
541   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
542   return 1;
543  }
544  SQLFreeStmt(sth,SQL_RESET_PARAMS);
545
546  SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.id,0,0);
547  rc=SQLExecDirect(sth,bi->delentry_query,SQL_NTS);
548  if (rc != SQL_SUCCESS)
549  {
550   Debug(LDAP_DEBUG_TRACE,"backsql_delete(): failed to delete record from ldap_entries\n",0,0,0);
551   backsql_PrintErrors(bi->db_env,dbh,sth,rc);
552   SQLFreeStmt(sth,SQL_DROP);
553   send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
554   return 1;
555  }
556  SQLFreeStmt(sth,SQL_DROP);
557
558  send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
559  Debug(LDAP_DEBUG_TRACE,"<==backsql_delete()\n",0,0,0);
560  return 0;
561 }
562
563 #endif /* SLAPD_SQL */