2 * Copyright 1999, Dmitry Kovalev <mit@openldap.org>, All rights reserved.
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.
15 #include <sys/types.h>
20 #include "schema-map.h"
24 int backsql_modify(BackendDB *be,Connection *conn,Operation *op,
25 const char *dn,const char *ndn,LDAPModList *modlist)
27 backsql_info *bi=(backsql_info*)be->be_private;
31 backsql_oc_map_rec *oc=NULL;
32 backsql_entryID e_id,*res;
34 backsql_at_map_rec *at=NULL;
35 struct berval *at_val;
37 int pno,po;//first parameter no, parameter order
38 int prc; //procedure return code
40 Debug(LDAP_DEBUG_TRACE,"==>backsql_modify(): changing entry '%s'\n",ndn,0,0);
41 dbh=backsql_get_db_conn(be,conn);
44 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): could not get connection handle - exiting\n",0,0,0);
45 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
48 res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
51 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): could not lookup entry id\n",0,0,0);
52 send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
56 oc=backsql_oc_with_id(bi,e_id.oc_id);
59 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): cannot determine objectclass of entry -- aborting\n",0,0,0);
60 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
64 SQLAllocStmt(dbh, &sth);
66 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): traversing modifications list\n",0,0,0);
67 for(c_mod=modlist;c_mod!=NULL;c_mod=c_mod->ml_next)
69 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): attribute '%s'\n",c_mod->ml_type,0,0);
70 at=backsql_at_with_name(oc,c_mod->ml_type);
73 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): attribute provided is not registered in this objectclass ('%s')\n",c_mod->ml_type,0,0);
79 case LDAP_MOD_REPLACE:
84 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): replacing values for attribute '%s'\n",at->name,0,0);
85 if (at->add_proc==NULL)
87 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add procedure is not defined for this attribute ('%s') - unable to perform replacements\n",at->name,0,0);
92 if ((rc=backsql_Prepare(dbh,&asth,at->query,0)) != SQL_SUCCESS)
94 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error preparing query\n",0,0,0);
95 backsql_PrintErrors(bi->db_env,dbh,asth,rc);
99 if (backsql_BindParamID(asth,1,&e_id.keyval) != SQL_SUCCESS)
101 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error binding key value parameter\n",0,0,0);
102 backsql_PrintErrors(bi->db_env,dbh,asth,rc);
103 SQLFreeStmt(asth,SQL_DROP);
107 if ((rc=SQLExecute(asth)) != SQL_SUCCESS && rc!= SQL_SUCCESS_WITH_INFO)
109 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): error executing attribute query\n",0,0,0);
110 backsql_PrintErrors(bi->db_env,dbh,asth,rc);
111 SQLFreeStmt(asth,SQL_DROP);
115 backsql_BindRowAsStrings(asth,&row);
116 while ((rc=SQLFetch(asth)) == SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO)
118 for (i=0;i<row.ncols;i++)
120 if (at->expect_return & BACKSQL_DEL)
123 SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
127 po=(at->param_order & BACKSQL_DEL)>0;
128 SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
129 //check for syntax needed here - maybe need binary bind?
130 SQLBindParameter(sth,(SQLUSMALLINT)(pno+2-po),SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,row.cols[i],strlen(row.cols[i]),0);
132 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0);
133 rc=SQLExecDirect(sth,at->delete_proc,SQL_NTS);
136 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete_proc execution failed\n",0,0,0);
137 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
141 backsql_FreeRow(&row);
142 SQLFreeStmt(asth,SQL_DROP);
144 //PASSTHROUGH - to add new attributes -- do NOT add break
146 if (at->add_proc==NULL)
148 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add procedure is not defined for this attribute ('%s')\n",at->name,0,0);
151 if (c_mod->ml_bvalues==NULL)
153 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): no values given to add for attribute '%s'\n",at->name,0,0);
156 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): adding new values for attribute '%s'\n",at->name,0,0);
157 for(i=0,at_val=c_mod->ml_bvalues[0];at_val!=NULL;i++,at_val=c_mod->ml_bvalues[i])
159 if (at->expect_return & BACKSQL_ADD)
162 SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
166 po=(at->param_order & BACKSQL_ADD)>0;
167 SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
168 //check for syntax needed here - maybe need binary bind?
169 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);
171 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->add_proc,0,0);
172 rc=SQLExecDirect(sth,at->add_proc,SQL_NTS);
175 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add_proc execution failed\n",0,0,0);
176 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
180 case LDAP_MOD_DELETE:
181 if (at->delete_proc==NULL)
183 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete procedure is not defined for this attribute ('%s')\n",at->name,0,0);
186 if (c_mod->ml_bvalues==NULL)
188 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): no values given to delete for attribute '%s' -- deleting all values\n",at->name,0,0);
191 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): deleting values for attribute '%s'\n",at->name,0,0);
192 for(i=0,at_val=c_mod->ml_bvalues[0];at_val!=NULL;i++,at_val=c_mod->ml_bvalues[i])
194 if (at->expect_return & BACKSQL_DEL)
197 SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
201 po=(at->param_order & BACKSQL_DEL)>0;
202 SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
203 //check for syntax needed here - maybe need binary bind?
204 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);
206 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0);
207 rc=SQLExecDirect(sth,at->delete_proc,SQL_NTS);
210 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete_proc execution failed\n",0,0,0);
211 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
216 SQLFreeStmt(sth,SQL_RESET_PARAMS);
219 SQLFreeStmt(sth,SQL_DROP);
220 send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
221 Debug(LDAP_DEBUG_TRACE,"<==backsql_modify()\n",0,0,0);
225 int backsql_modrdn(BackendDB *be,Connection *conn,Operation *op,
226 const char *dn,const char *ndn,const char *newrdn,int deleteoldrdn,const char *newSuperior)
228 Debug(LDAP_DEBUG_TRACE,"==>backsql_modrdn()\n",0,0,0);
232 int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
234 backsql_info *bi=(backsql_info*)be->be_private;
237 unsigned long new_keyval;
240 backsql_oc_map_rec *oc=NULL;
241 backsql_at_map_rec *at_rec=NULL;
242 backsql_entryID parent_id,*res;
244 struct berval *at_val;
246 int pno,po;//first parameter no, parameter order
247 int prc; //procedure return code
249 Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): adding entry '%s'\n",e->e_dn,0,0);
250 if (dn_validate(e->e_dn)==NULL)
252 Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): invalid dn '%s' -- aborting\n",e->e_dn,0,0);
254 for(at=e->e_attrs;at!=NULL;at=at->a_next)
256 //Debug(LDAP_DEBUG_TRACE,"backsql_add(): scanning entry -- %s\n",at->a_type,0,0);
257 if (!strcasecmp(at->a_type,"objectclass"))
259 oc=backsql_oc_with_name(bi,at->a_vals[0]->bv_val);
266 Debug(LDAP_DEBUG_TRACE,"backsql_add(): cannot determine objectclass of entry -- aborting\n",0,0,0);
267 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
270 if (oc->create_proc == NULL)
272 Debug(LDAP_DEBUG_TRACE,"backsql_add(): create procedure is not defined for this objectclass - aborting\n",0,0,0);
273 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
277 dbh=backsql_get_db_conn(be,conn);
280 Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not get connection handle - exiting\n",0,0,0);
281 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
285 SQLAllocStmt(dbh, &sth);
286 SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
288 Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",oc->create_proc,0,0);
289 rc=SQLExecDirect(sth,oc->create_proc,SQL_NTS);
290 if (rc != SQL_SUCCESS)
292 Debug(LDAP_DEBUG_TRACE,"backsql_add(): create_proc execution failed\n",0,0,0);
293 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
294 SQLFreeStmt(sth,SQL_DROP);
295 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
298 SQLFreeStmt(sth,SQL_RESET_PARAMS);
299 Debug(LDAP_DEBUG_TRACE,"backsql_add(): create_proc returned keyval=%d\n",new_keyval,0,0);
301 for(at=e->e_attrs;at!=NULL;at=at->a_next)
303 at_rec=backsql_at_with_name(oc,at->a_type);
306 Debug(LDAP_DEBUG_TRACE,"backsql_add(): attribute provided is not registered in this objectclass ('%s')\n",at->a_type,0,0);
309 if (at_rec->add_proc==NULL)
311 Debug(LDAP_DEBUG_TRACE,"backsql_add(): add procedure is not defined for this attribute ('%s')\n",at->a_type,0,0);
315 for(i=0,at_val=at->a_vals[0];at_val!=NULL;i++,at_val=at->a_vals[i])
317 if (at_rec->expect_return & BACKSQL_ADD)
320 SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&prc,0,0);
324 po=(at_rec->param_order & BACKSQL_ADD)>0;
325 SQLBindParameter(sth,(SQLUSMALLINT)(pno+1+po),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
326 //check for syntax needed here - maybe need binary bind?
327 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);
328 Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",at_rec->add_proc,0,0);
329 rc=SQLExecDirect(sth,at_rec->add_proc,SQL_NTS);
332 Debug(LDAP_DEBUG_TRACE,"backsql_add(): add_proc execution failed\n",0,0,0);
333 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
337 SQLFreeStmt(sth,SQL_RESET_PARAMS);
338 pdn=dn_parent(be,e->e_dn);
339 res=backsql_dn2id(bi,&parent_id,dbh,pdn);
342 Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not lookup parent entry for new record ('%s')\n",
344 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
348 backsql_BindParamStr(sth,1,e->e_dn,BACKSQL_MAX_DN_LEN);
349 SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&oc->id,0,0);
350 SQLBindParameter(sth,3,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&parent_id.id,0,0);
351 SQLBindParameter(sth,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_keyval,0,0);
352 rc=SQLExecDirect(sth,bi->insentry_query,SQL_NTS);
353 if (rc != SQL_SUCCESS)
355 Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not insert ldap_entries record\n",0,0,0);
356 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
357 //execute delete_proc to delete data added !!!
358 SQLFreeStmt(sth,SQL_DROP);
359 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
362 SQLFreeStmt(sth,SQL_DROP);
363 send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
367 int backsql_delete(BackendDB *be,Connection *conn,Operation *op,
368 const char *dn,const char *ndn)
370 backsql_info *bi=(backsql_info*)be->be_private;
374 backsql_oc_map_rec *oc=NULL;
375 backsql_entryID e_id,*res;
376 int pno;//first parameter no, parameter order
378 Debug(LDAP_DEBUG_TRACE,"==>backsql_delete(): deleting entry '%s'\n",ndn,0,0);
379 dbh=backsql_get_db_conn(be,conn);
382 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not get connection handle - exiting\n",0,0,0);
383 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
386 res=backsql_dn2id(bi,&e_id,dbh,(char*)ndn);
389 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not lookup entry id\n",0,0,0);
390 send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
394 oc=backsql_oc_with_id(bi,e_id.oc_id);
397 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): cannot determine objectclass of entry -- aborting\n",0,0,0);
398 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
401 if (oc->delete_proc == NULL)
403 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): delete procedure is not defined for this objectclass - aborting\n",0,0,0);
404 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
408 SQLAllocStmt(dbh, &sth);
409 if (oc->expect_return)
412 SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&rc,0,0);
416 SQLBindParameter(sth,(SQLUSMALLINT)(pno+1),SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
417 //SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,0,0);
419 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): executing '%s'\n",oc->delete_proc,0,0);
420 rc=SQLExecDirect(sth,oc->delete_proc,SQL_NTS);
421 if (rc != SQL_SUCCESS)
423 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): delete_proc execution failed\n",0,0,0);
424 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
425 SQLFreeStmt(sth,SQL_DROP);
426 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
429 SQLFreeStmt(sth,SQL_RESET_PARAMS);
431 SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.id,0,0);
432 rc=SQLExecDirect(sth,bi->delentry_query,SQL_NTS);
433 if (rc != SQL_SUCCESS)
435 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): failed to delete record from ldap_entries\n",0,0,0);
436 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
437 SQLFreeStmt(sth,SQL_DROP);
438 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
441 SQLFreeStmt(sth,SQL_DROP);
443 send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
444 Debug(LDAP_DEBUG_TRACE,"<==backsql_delete()\n",0,0,0);
448 #endif /* SLAPD_SQL */