2 * Copyright 1999, Dmitry Kovalev (zmit@mail.ru), 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 char *dn,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;
39 Debug(LDAP_DEBUG_TRACE,"==>backsql_modify(): changing entry '%s'\n",dn,0,0);
40 dbh=backsql_get_db_conn(be,conn);
43 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): could not get connection handle - exiting\n",0,0,0);
44 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
47 res=backsql_dn2id(&e_id,dbh,dn);
50 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): could not lookup entry id\n",0,0,0);
51 send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
55 oc=backsql_oc_with_id(bi,e_id.oc_id);
58 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): cannot determine objectclass of entry -- aborting\n",0,0,0);
59 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
63 SQLAllocStmt(dbh, &sth);
65 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): traversing modifications list\n",0,0,0);
66 for(c_mod=modlist;c_mod!=NULL;c_mod=c_mod->ml_next)
68 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): attribute '%s'\n",c_mod->ml_type,0,0);
69 at=backsql_at_with_name(oc,c_mod->ml_type);
72 Debug(LDAP_DEBUG_TRACE,"backsql_add(): attribute provided is not registered in this objectclass ('%s')\n",c_mod->ml_type,0,0);
75 SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
78 case LDAP_MOD_REPLACE:
85 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): replacing values for attribute '%s'\n",at->name,0,0);
86 if (at->add_proc==NULL)
88 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add procedure is not defined for this attribute ('%s') - unable to perform replacements\n",at->name,0,0);
94 query=backsql_strcat(query,&qlen,"SELECT ",at->sel_expr," AS ",at->name,
95 " FROM ",at->from_tbls,
96 " WHERE ",oc->keytbl,".",oc->keycol,"=?",NULL);
97 if (at->join_where!=NULL && at->join_where[0]!='\0')
98 query=backsql_strcat(query,&qlen," AND ",at->join_where,NULL);
100 Debug(LDAP_DEBUG_TRACE,"backsql_modify() constructed query to get all existing values: %s\n",query,0,0);
101 if ((rc=backsql_Prepare(dbh,&asth,query,0)) != SQL_SUCCESS)
103 Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error preparing query\n",0,0,0);
104 backsql_PrintErrors(bi->db_env,dbh,asth,rc);
110 if (backsql_BindParamID(asth,1,&e_id.keyval) != SQL_SUCCESS)
112 Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error binding key value parameter\n",0,0,0);
113 backsql_PrintErrors(bi->db_env,dbh,asth,rc);
114 SQLFreeStmt(asth,SQL_DROP);
118 if ((rc=SQLExecute(asth)) != SQL_SUCCESS && rc!= SQL_SUCCESS_WITH_INFO)
120 Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error executing attribute query\n",0,0,0);
121 backsql_PrintErrors(bi->db_env,dbh,asth,rc);
122 SQLFreeStmt(asth,SQL_DROP);
126 backsql_BindRowAsStrings(asth,&row);
127 while ((rc=SQLFetch(asth)) == SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO)
129 for (i=0;i<row.ncols;i++)
131 SQLBindParameter(sth,2,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 //check for syntax here - maybe need binary bind?
160 SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
161 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->add_proc,0,0);
162 rc=SQLExecDirect(sth,at->add_proc,SQL_NTS);
165 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): add_proc execution failed\n",0,0,0);
166 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
170 case LDAP_MOD_DELETE:
171 if (at->delete_proc==NULL)
173 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete procedure is not defined for this attribute ('%s')\n",at->name,0,0);
176 if (c_mod->ml_bvalues==NULL)
178 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): no values given to delete for attribute '%s' -- deleting all values\n",at->name,0,0);
181 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): deleting values for attribute '%s'\n",at->name,0,0);
182 for(i=0,at_val=c_mod->ml_bvalues[0];at_val!=NULL;i++,at_val=c_mod->ml_bvalues[i])
184 //check for syntax here - maybe need binary bind?
185 SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
186 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): executing '%s'\n",at->delete_proc,0,0);
187 rc=SQLExecDirect(sth,at->delete_proc,SQL_NTS);
190 Debug(LDAP_DEBUG_TRACE,"backsql_modify(): delete_proc execution failed\n",0,0,0);
191 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
196 SQLFreeStmt(sth,SQL_RESET_PARAMS);
199 SQLFreeStmt(sth,SQL_DROP);
200 send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
201 Debug(LDAP_DEBUG_TRACE,"<==backsql_modify()\n",0,0,0);
205 int backsql_modrdn(BackendDB *be,Connection *conn,Operation *op,
206 char *dn,char *ndn,char *newrdn,int deleteoldrdn,char *newSuperior)
208 Debug(LDAP_DEBUG_TRACE,"==>backsql_modrdn()\n",0,0,0);
212 int backsql_add(BackendDB *be,Connection *conn,Operation *op,Entry *e)
214 backsql_info *bi=(backsql_info*)be->be_private;
217 unsigned long new_keyval;
220 backsql_oc_map_rec *oc=NULL;
221 backsql_at_map_rec *at_rec=NULL;
222 backsql_entryID parent_id,*res;
224 struct berval *at_val;
227 Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): adding entry '%s'\n",e->e_dn,0,0);
228 if (dn_validate(e->e_dn)==NULL)
230 Debug(LDAP_DEBUG_TRACE,"==>backsql_add(): invalid dn '%s' -- aborting\n",e->e_dn,0,0);
232 for(at=e->e_attrs;at!=NULL;at=at->a_next)
234 //Debug(LDAP_DEBUG_TRACE,"backsql_add(): scanning entry -- %s\n",at->a_type,0,0);
235 if (!strcasecmp(at->a_type,"objectclass"))
237 oc=backsql_oc_with_name(bi,at->a_vals[0]->bv_val);
244 Debug(LDAP_DEBUG_TRACE,"backsql_add(): cannot determine objectclass of entry -- aborting\n",0,0,0);
245 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
248 if (oc->create_proc == NULL)
250 Debug(LDAP_DEBUG_TRACE,"backsql_add(): create procedure is not defined for this objectclass - aborting\n",0,0,0);
251 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
255 dbh=backsql_get_db_conn(be,conn);
258 Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not get connection handle - exiting\n",0,0,0);
259 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
263 SQLAllocStmt(dbh, &sth);
264 SQLBindParameter(sth,1,SQL_PARAM_OUTPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&new_keyval,0,0);
265 //SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,0,0);
267 Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",oc->create_proc,0,0);
268 rc=SQLExecDirect(sth,oc->create_proc,SQL_NTS);
269 if (rc != SQL_SUCCESS)
271 Debug(LDAP_DEBUG_TRACE,"backsql_add(): create_proc execution failed\n",0,0,0);
272 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
273 SQLFreeStmt(sth,SQL_DROP);
274 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
277 SQLFreeStmt(sth,SQL_RESET_PARAMS);
278 Debug(LDAP_DEBUG_TRACE,"backsql_add(): create_proc returned keyval=%d\n",new_keyval,0,0);
280 for(at=e->e_attrs;at!=NULL;at=at->a_next)
282 at_rec=backsql_at_with_name(oc,at->a_type);
285 Debug(LDAP_DEBUG_TRACE,"backsql_add(): attribute provided is not registered in this objectclass ('%s')\n",at->a_type,0,0);
288 if (at_rec->add_proc==NULL)
290 Debug(LDAP_DEBUG_TRACE,"backsql_add(): add procedure is not defined for this attribute ('%s')\n",at->a_type,0,0);
293 SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_keyval,0,0);
294 for(i=0,at_val=at->a_vals[0];at_val!=NULL;i++,at_val=at->a_vals[i])
296 //if (at->a_syntax==SYNTAX_BIN)
297 // SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_BINARY,0,0,at_val->bv_val,0,0);
299 SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,at_val->bv_val,at_val->bv_len,0);
300 Debug(LDAP_DEBUG_TRACE,"backsql_add(): executing '%s'\n",at_rec->add_proc,0,0);
301 rc=SQLExecDirect(sth,at_rec->add_proc,SQL_NTS);
304 Debug(LDAP_DEBUG_TRACE,"backsql_add(): add_proc execution failed\n",0,0,0);
305 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
309 SQLFreeStmt(sth,SQL_RESET_PARAMS);
310 pdn=dn_parent(be,e->e_dn);
311 res=backsql_dn2id(&parent_id,dbh,pdn);
314 Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not lookup parent entry for new record ('%s')\n",
316 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
320 backsql_BindParamStr(sth,1,e->e_dn,BACKSQL_MAX_DN_LEN);
321 SQLBindParameter(sth,2,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&oc->id,0,0);
322 SQLBindParameter(sth,3,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&parent_id.id,0,0);
323 SQLBindParameter(sth,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&new_keyval,0,0);
324 rc=SQLExecDirect(sth,bi->insentry_query,SQL_NTS);
325 if (rc != SQL_SUCCESS)
327 Debug(LDAP_DEBUG_TRACE,"backsql_add(): could not insert ldap_entries record\n",0,0,0);
328 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
329 //execute delete_proc to delete data added !!!
330 SQLFreeStmt(sth,SQL_DROP);
331 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
334 SQLFreeStmt(sth,SQL_DROP);
335 send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
339 int backsql_delete(BackendDB *be,Connection *conn,Operation *op,
342 backsql_info *bi=(backsql_info*)be->be_private;
346 backsql_oc_map_rec *oc=NULL;
347 backsql_entryID e_id,*res;
350 Debug(LDAP_DEBUG_TRACE,"==>backsql_delete(): deleting entry '%s'\n",dn,0,0);
351 dbh=backsql_get_db_conn(be,conn);
354 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not get connection handle - exiting\n",0,0,0);
355 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
358 res=backsql_dn2id(&e_id,dbh,dn);
361 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): could not lookup entry id\n",0,0,0);
362 send_ldap_result(conn,op,LDAP_NO_SUCH_OBJECT,"",NULL,NULL,NULL);
366 oc=backsql_oc_with_id(bi,e_id.oc_id);
369 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): cannot determine objectclass of entry -- aborting\n",0,0,0);
370 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
373 if (oc->delete_proc == NULL)
375 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): delete procedure is not defined for this objectclass - aborting\n",0,0,0);
376 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
380 SQLAllocStmt(dbh, &sth);
381 SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.keyval,0,0);
382 //SQLBindParameter(sth,2,SQL_PARAM_OUTPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&retcode,0,0);
384 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): executing '%s'\n",oc->delete_proc,0,0);
385 rc=SQLExecDirect(sth,oc->delete_proc,SQL_NTS);
386 if (rc != SQL_SUCCESS)
388 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): delete_proc execution failed\n",0,0,0);
389 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
390 SQLFreeStmt(sth,SQL_DROP);
391 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
394 SQLFreeStmt(sth,SQL_RESET_PARAMS);
396 SQLBindParameter(sth,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&e_id.id,0,0);
397 rc=SQLExecDirect(sth,bi->delentry_query,SQL_NTS);
398 if (rc != SQL_SUCCESS)
400 Debug(LDAP_DEBUG_TRACE,"backsql_delete(): failed to delete record from ldap_entries\n",0,0,0);
401 backsql_PrintErrors(bi->db_env,dbh,sth,rc);
402 SQLFreeStmt(sth,SQL_DROP);
403 send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
406 SQLFreeStmt(sth,SQL_DROP);
408 send_ldap_result(conn,op,LDAP_SUCCESS,"",NULL,NULL,NULL);
409 Debug(LDAP_DEBUG_TRACE,"<==backsql_delete()\n",0,0,0);
413 #endif /* SLAPD_SQL */