add.c revision 1.2 1 1.2 christos /* $NetBSD: add.c,v 1.2 2020/08/11 13:15:42 christos Exp $ */
2 1.2 christos
3 1.2 christos /* $OpenLDAP$ */
4 1.1 lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 1.1 lukem *
6 1.2 christos * Copyright 1999-2020 The OpenLDAP Foundation.
7 1.1 lukem * Portions Copyright 1999 Dmitry Kovalev.
8 1.1 lukem * Portions Copyright 2002 Pierangelo Masarati.
9 1.1 lukem * Portions Copyright 2004 Mark Adamson.
10 1.1 lukem * All rights reserved.
11 1.1 lukem *
12 1.1 lukem * Redistribution and use in source and binary forms, with or without
13 1.1 lukem * modification, are permitted only as authorized by the OpenLDAP
14 1.1 lukem * Public License.
15 1.1 lukem *
16 1.1 lukem * A copy of this license is available in the file LICENSE in the
17 1.1 lukem * top-level directory of the distribution or, alternatively, at
18 1.1 lukem * <http://www.OpenLDAP.org/license.html>.
19 1.1 lukem */
20 1.1 lukem /* ACKNOWLEDGEMENTS:
21 1.1 lukem * This work was initially developed by Dmitry Kovalev for inclusion
22 1.1 lukem * by OpenLDAP Software. Additional significant contributors include
23 1.1 lukem * Pierangelo Masarati and Mark Adamson.
24 1.1 lukem
25 1.1 lukem */
26 1.1 lukem
27 1.2 christos #include <sys/cdefs.h>
28 1.2 christos __RCSID("$NetBSD: add.c,v 1.2 2020/08/11 13:15:42 christos Exp $");
29 1.2 christos
30 1.1 lukem #include "portable.h"
31 1.1 lukem
32 1.1 lukem #include <stdio.h>
33 1.1 lukem #include <sys/types.h>
34 1.1 lukem #include "ac/string.h"
35 1.1 lukem
36 1.1 lukem #include "slap.h"
37 1.1 lukem #include "proto-sql.h"
38 1.1 lukem
39 1.1 lukem #ifdef BACKSQL_SYNCPROV
40 1.1 lukem #include <lutil.h>
41 1.1 lukem #endif /* BACKSQL_SYNCPROV */
42 1.1 lukem
43 1.1 lukem /*
44 1.1 lukem * Skip:
45 1.1 lukem * - null values (e.g. delete modification)
46 1.1 lukem * - single occurrence of objectClass, because it is already used
47 1.1 lukem * to determine how to build the SQL entry
48 1.1 lukem * - operational attributes
49 1.1 lukem * - empty attributes
50 1.1 lukem */
51 1.1 lukem #define backsql_opattr_skip(ad) \
52 1.1 lukem (is_at_operational( (ad)->ad_type ) && (ad) != slap_schema.si_ad_ref )
53 1.1 lukem #define backsql_attr_skip(ad, vals) \
54 1.1 lukem ( \
55 1.1 lukem ( (ad) == slap_schema.si_ad_objectClass \
56 1.1 lukem && (vals) && BER_BVISNULL( &((vals)[ 1 ]) ) ) \
57 1.1 lukem || backsql_opattr_skip( (ad) ) \
58 1.1 lukem || ( (vals) && BER_BVISNULL( &((vals)[ 0 ]) ) ) \
59 1.1 lukem )
60 1.1 lukem
61 1.1 lukem int
62 1.1 lukem backsql_modify_delete_all_values(
63 1.1 lukem Operation *op,
64 1.1 lukem SlapReply *rs,
65 1.1 lukem SQLHDBC dbh,
66 1.1 lukem backsql_entryID *e_id,
67 1.1 lukem backsql_at_map_rec *at )
68 1.1 lukem {
69 1.1 lukem backsql_info *bi = (backsql_info *)op->o_bd->be_private;
70 1.1 lukem RETCODE rc;
71 1.1 lukem SQLHSTMT asth = SQL_NULL_HSTMT;
72 1.1 lukem BACKSQL_ROW_NTS row;
73 1.1 lukem
74 1.1 lukem assert( at != NULL );
75 1.1 lukem if ( at->bam_delete_proc == NULL ) {
76 1.1 lukem Debug( LDAP_DEBUG_TRACE,
77 1.1 lukem " backsql_modify_delete_all_values(): "
78 1.1 lukem "missing attribute value delete procedure "
79 1.1 lukem "for attr \"%s\"\n",
80 1.1 lukem at->bam_ad->ad_cname.bv_val, 0, 0 );
81 1.1 lukem if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
82 1.1 lukem rs->sr_text = "SQL-backend error";
83 1.1 lukem return rs->sr_err = LDAP_OTHER;
84 1.1 lukem }
85 1.1 lukem
86 1.1 lukem return LDAP_SUCCESS;
87 1.1 lukem }
88 1.1 lukem
89 1.1 lukem rc = backsql_Prepare( dbh, &asth, at->bam_query, 0 );
90 1.1 lukem if ( rc != SQL_SUCCESS ) {
91 1.1 lukem Debug( LDAP_DEBUG_TRACE,
92 1.1 lukem " backsql_modify_delete_all_values(): "
93 1.1 lukem "error preparing attribute value select query "
94 1.1 lukem "\"%s\"\n",
95 1.1 lukem at->bam_query, 0, 0 );
96 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
97 1.1 lukem asth, rc );
98 1.1 lukem
99 1.1 lukem rs->sr_text = "SQL-backend error";
100 1.1 lukem return rs->sr_err = LDAP_OTHER;
101 1.1 lukem }
102 1.1 lukem
103 1.1 lukem rc = backsql_BindParamID( asth, 1, SQL_PARAM_INPUT, &e_id->eid_keyval );
104 1.1 lukem if ( rc != SQL_SUCCESS ) {
105 1.1 lukem Debug( LDAP_DEBUG_TRACE,
106 1.1 lukem " backsql_modify_delete_all_values(): "
107 1.1 lukem "error binding key value parameter "
108 1.1 lukem "to attribute value select query\n",
109 1.1 lukem 0, 0, 0 );
110 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
111 1.1 lukem asth, rc );
112 1.1 lukem SQLFreeStmt( asth, SQL_DROP );
113 1.1 lukem
114 1.1 lukem rs->sr_text = "SQL-backend error";
115 1.1 lukem return rs->sr_err = LDAP_OTHER;
116 1.1 lukem }
117 1.1 lukem
118 1.1 lukem rc = SQLExecute( asth );
119 1.1 lukem if ( !BACKSQL_SUCCESS( rc ) ) {
120 1.1 lukem Debug( LDAP_DEBUG_TRACE,
121 1.1 lukem " backsql_modify_delete_all_values(): "
122 1.1 lukem "error executing attribute value select query\n",
123 1.1 lukem 0, 0, 0 );
124 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
125 1.1 lukem asth, rc );
126 1.1 lukem SQLFreeStmt( asth, SQL_DROP );
127 1.1 lukem
128 1.1 lukem rs->sr_text = "SQL-backend error";
129 1.1 lukem return rs->sr_err = LDAP_OTHER;
130 1.1 lukem }
131 1.1 lukem
132 1.1 lukem backsql_BindRowAsStrings_x( asth, &row, op->o_tmpmemctx );
133 1.1 lukem for ( rc = SQLFetch( asth );
134 1.1 lukem BACKSQL_SUCCESS( rc );
135 1.1 lukem rc = SQLFetch( asth ) )
136 1.1 lukem {
137 1.1 lukem int i;
138 1.1 lukem /* first parameter no, parameter order */
139 1.1 lukem SQLUSMALLINT pno = 0,
140 1.1 lukem po = 0;
141 1.1 lukem /* procedure return code */
142 1.1 lukem int prc = LDAP_SUCCESS;
143 1.1 lukem
144 1.1 lukem for ( i = 0; i < row.ncols; i++ ) {
145 1.1 lukem SQLHSTMT sth = SQL_NULL_HSTMT;
146 1.1 lukem ber_len_t col_len;
147 1.1 lukem
148 1.1 lukem rc = backsql_Prepare( dbh, &sth, at->bam_delete_proc, 0 );
149 1.1 lukem if ( rc != SQL_SUCCESS ) {
150 1.1 lukem Debug( LDAP_DEBUG_TRACE,
151 1.1 lukem " backsql_modify_delete_all_values(): "
152 1.1 lukem "error preparing attribute value "
153 1.1 lukem "delete procedure "
154 1.1 lukem "\"%s\"\n",
155 1.1 lukem at->bam_delete_proc, 0, 0 );
156 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
157 1.1 lukem sth, rc );
158 1.1 lukem
159 1.1 lukem rs->sr_text = "SQL-backend error";
160 1.1 lukem rs->sr_err = LDAP_OTHER;
161 1.1 lukem goto done;
162 1.1 lukem }
163 1.1 lukem
164 1.1 lukem if ( BACKSQL_IS_DEL( at->bam_expect_return ) ) {
165 1.1 lukem pno = 1;
166 1.1 lukem rc = backsql_BindParamInt( sth, 1,
167 1.1 lukem SQL_PARAM_OUTPUT, &prc );
168 1.1 lukem if ( rc != SQL_SUCCESS ) {
169 1.1 lukem Debug( LDAP_DEBUG_TRACE,
170 1.1 lukem " backsql_modify_delete_all_values(): "
171 1.1 lukem "error binding output parameter for %s[%d]\n",
172 1.1 lukem at->bam_ad->ad_cname.bv_val, i, 0 );
173 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
174 1.1 lukem sth, rc );
175 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
176 1.1 lukem
177 1.1 lukem rs->sr_text = "SQL-backend error";
178 1.1 lukem rs->sr_err = LDAP_OTHER;
179 1.1 lukem goto done;
180 1.1 lukem }
181 1.1 lukem }
182 1.1 lukem po = ( BACKSQL_IS_DEL( at->bam_param_order ) ) > 0;
183 1.1 lukem rc = backsql_BindParamID( sth, pno + 1 + po,
184 1.1 lukem SQL_PARAM_INPUT, &e_id->eid_keyval );
185 1.1 lukem if ( rc != SQL_SUCCESS ) {
186 1.1 lukem Debug( LDAP_DEBUG_TRACE,
187 1.1 lukem " backsql_modify_delete_all_values(): "
188 1.1 lukem "error binding keyval parameter for %s[%d]\n",
189 1.1 lukem at->bam_ad->ad_cname.bv_val, i, 0 );
190 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
191 1.1 lukem sth, rc );
192 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
193 1.1 lukem
194 1.1 lukem rs->sr_text = "SQL-backend error";
195 1.1 lukem rs->sr_err = LDAP_OTHER;
196 1.1 lukem goto done;
197 1.1 lukem }
198 1.2 christos
199 1.1 lukem Debug( LDAP_DEBUG_TRACE,
200 1.1 lukem " backsql_modify_delete_all_values() "
201 1.2 christos "arg(%d)=" BACKSQL_IDFMT "\n",
202 1.2 christos pno + 1 + po,
203 1.2 christos BACKSQL_IDARG(e_id->eid_keyval), 0 );
204 1.1 lukem
205 1.1 lukem /*
206 1.1 lukem * check for syntax needed here
207 1.1 lukem * maybe need binary bind?
208 1.1 lukem */
209 1.1 lukem col_len = strlen( row.cols[ i ] );
210 1.1 lukem rc = backsql_BindParamStr( sth, pno + 2 - po,
211 1.1 lukem SQL_PARAM_INPUT, row.cols[ i ], col_len );
212 1.1 lukem if ( rc != SQL_SUCCESS ) {
213 1.1 lukem Debug( LDAP_DEBUG_TRACE,
214 1.1 lukem " backsql_modify_delete_all_values(): "
215 1.1 lukem "error binding value parameter for %s[%d]\n",
216 1.1 lukem at->bam_ad->ad_cname.bv_val, i, 0 );
217 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
218 1.1 lukem sth, rc );
219 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
220 1.1 lukem
221 1.1 lukem rs->sr_text = "SQL-backend error";
222 1.1 lukem rs->sr_err = LDAP_OTHER;
223 1.1 lukem goto done;
224 1.1 lukem }
225 1.1 lukem
226 1.1 lukem Debug( LDAP_DEBUG_TRACE,
227 1.1 lukem " backsql_modify_delete_all_values(): "
228 1.1 lukem "arg(%d)=%s; executing \"%s\"\n",
229 1.1 lukem pno + 2 - po, row.cols[ i ],
230 1.1 lukem at->bam_delete_proc );
231 1.1 lukem rc = SQLExecute( sth );
232 1.1 lukem if ( rc == SQL_SUCCESS && prc == LDAP_SUCCESS ) {
233 1.1 lukem rs->sr_err = LDAP_SUCCESS;
234 1.1 lukem
235 1.1 lukem } else {
236 1.1 lukem Debug( LDAP_DEBUG_TRACE,
237 1.1 lukem " backsql_modify_delete_all_values(): "
238 1.1 lukem "delete_proc "
239 1.1 lukem "execution failed (rc=%d, prc=%d)\n",
240 1.1 lukem rc, prc, 0 );
241 1.1 lukem if ( prc != LDAP_SUCCESS ) {
242 1.1 lukem /* SQL procedure executed fine
243 1.1 lukem * but returned an error */
244 1.1 lukem rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
245 1.1 lukem
246 1.1 lukem } else {
247 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
248 1.1 lukem sth, rc );
249 1.1 lukem rs->sr_err = LDAP_OTHER;
250 1.1 lukem }
251 1.1 lukem rs->sr_text = op->o_req_dn.bv_val;
252 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
253 1.1 lukem goto done;
254 1.1 lukem }
255 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
256 1.1 lukem }
257 1.1 lukem }
258 1.1 lukem
259 1.1 lukem rs->sr_err = LDAP_SUCCESS;
260 1.1 lukem
261 1.1 lukem done:;
262 1.1 lukem backsql_FreeRow_x( &row, op->o_tmpmemctx );
263 1.1 lukem SQLFreeStmt( asth, SQL_DROP );
264 1.1 lukem
265 1.1 lukem return rs->sr_err;
266 1.1 lukem }
267 1.1 lukem
268 1.1 lukem int
269 1.1 lukem backsql_modify_internal(
270 1.1 lukem Operation *op,
271 1.1 lukem SlapReply *rs,
272 1.1 lukem SQLHDBC dbh,
273 1.1 lukem backsql_oc_map_rec *oc,
274 1.1 lukem backsql_entryID *e_id,
275 1.1 lukem Modifications *modlist )
276 1.1 lukem {
277 1.1 lukem backsql_info *bi = (backsql_info *)op->o_bd->be_private;
278 1.1 lukem RETCODE rc;
279 1.1 lukem Modifications *ml;
280 1.1 lukem
281 1.1 lukem Debug( LDAP_DEBUG_TRACE, "==>backsql_modify_internal(): "
282 1.1 lukem "traversing modifications list\n", 0, 0, 0 );
283 1.1 lukem
284 1.1 lukem for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
285 1.1 lukem AttributeDescription *ad;
286 1.1 lukem int sm_op;
287 1.1 lukem static char *sm_ops[] = { "add", "delete", "replace", "increment", NULL };
288 1.1 lukem
289 1.1 lukem BerVarray sm_values;
290 1.1 lukem #if 0
291 1.1 lukem /* NOTE: some day we'll have to pass
292 1.1 lukem * the normalized values as well */
293 1.1 lukem BerVarray sm_nvalues;
294 1.1 lukem #endif
295 1.1 lukem backsql_at_map_rec *at = NULL;
296 1.1 lukem struct berval *at_val;
297 1.1 lukem int i;
298 1.1 lukem
299 1.1 lukem ad = ml->sml_mod.sm_desc;
300 1.1 lukem sm_op = ( ml->sml_mod.sm_op & LDAP_MOD_OP );
301 1.1 lukem sm_values = ml->sml_mod.sm_values;
302 1.1 lukem #if 0
303 1.1 lukem sm_nvalues = ml->sml_mod.sm_nvalues;
304 1.1 lukem #endif
305 1.1 lukem
306 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
307 1.1 lukem "modifying attribute \"%s\" (%s) according to "
308 1.1 lukem "mappings for objectClass \"%s\"\n",
309 1.1 lukem ad->ad_cname.bv_val, sm_ops[ sm_op ], BACKSQL_OC_NAME( oc ) );
310 1.1 lukem
311 1.1 lukem if ( backsql_attr_skip( ad, sm_values ) ) {
312 1.1 lukem continue;
313 1.1 lukem }
314 1.1 lukem
315 1.1 lukem at = backsql_ad2at( oc, ad );
316 1.1 lukem if ( at == NULL ) {
317 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
318 1.1 lukem "attribute \"%s\" is not registered "
319 1.1 lukem "in objectClass \"%s\"\n",
320 1.1 lukem ad->ad_cname.bv_val, BACKSQL_OC_NAME( oc ), 0 );
321 1.1 lukem
322 1.1 lukem if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
323 1.1 lukem rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
324 1.1 lukem rs->sr_text = "operation not permitted "
325 1.1 lukem "within namingContext";
326 1.1 lukem goto done;
327 1.1 lukem }
328 1.1 lukem
329 1.1 lukem continue;
330 1.1 lukem }
331 1.1 lukem
332 1.1 lukem switch ( sm_op ) {
333 1.1 lukem case LDAP_MOD_REPLACE: {
334 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
335 1.1 lukem "replacing values for attribute \"%s\"\n",
336 1.1 lukem at->bam_ad->ad_cname.bv_val, 0, 0 );
337 1.1 lukem
338 1.1 lukem if ( at->bam_add_proc == NULL ) {
339 1.1 lukem Debug( LDAP_DEBUG_TRACE,
340 1.1 lukem " backsql_modify_internal(): "
341 1.1 lukem "add procedure is not defined "
342 1.1 lukem "for attribute \"%s\" "
343 1.1 lukem "- unable to perform replacements\n",
344 1.1 lukem at->bam_ad->ad_cname.bv_val, 0, 0 );
345 1.1 lukem
346 1.1 lukem if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
347 1.1 lukem rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
348 1.1 lukem rs->sr_text = "operation not permitted "
349 1.1 lukem "within namingContext";
350 1.1 lukem goto done;
351 1.1 lukem }
352 1.1 lukem
353 1.1 lukem break;
354 1.1 lukem }
355 1.1 lukem
356 1.1 lukem if ( at->bam_delete_proc == NULL ) {
357 1.1 lukem if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
358 1.1 lukem Debug( LDAP_DEBUG_TRACE,
359 1.1 lukem " backsql_modify_internal(): "
360 1.1 lukem "delete procedure is not defined "
361 1.1 lukem "for attribute \"%s\"\n",
362 1.1 lukem at->bam_ad->ad_cname.bv_val, 0, 0 );
363 1.1 lukem
364 1.1 lukem rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
365 1.1 lukem rs->sr_text = "operation not permitted "
366 1.1 lukem "within namingContext";
367 1.1 lukem goto done;
368 1.1 lukem }
369 1.1 lukem
370 1.1 lukem Debug( LDAP_DEBUG_TRACE,
371 1.1 lukem " backsql_modify_internal(): "
372 1.1 lukem "delete procedure is not defined "
373 1.1 lukem "for attribute \"%s\" "
374 1.1 lukem "- adding only\n",
375 1.1 lukem at->bam_ad->ad_cname.bv_val, 0, 0 );
376 1.1 lukem
377 1.1 lukem goto add_only;
378 1.1 lukem }
379 1.1 lukem
380 1.1 lukem del_all:
381 1.1 lukem rs->sr_err = backsql_modify_delete_all_values( op, rs, dbh, e_id, at );
382 1.1 lukem if ( rs->sr_err != LDAP_SUCCESS ) {
383 1.1 lukem goto done;
384 1.1 lukem }
385 1.1 lukem
386 1.1 lukem /* LDAP_MOD_DELETE gets here if all values must be deleted */
387 1.1 lukem if ( sm_op == LDAP_MOD_DELETE ) {
388 1.1 lukem break;
389 1.1 lukem }
390 1.1 lukem }
391 1.1 lukem
392 1.1 lukem /*
393 1.1 lukem * PASSTHROUGH - to add new attributes -- do NOT add break
394 1.1 lukem */
395 1.1 lukem case LDAP_MOD_ADD:
396 1.1 lukem /* case SLAP_MOD_SOFTADD: */
397 1.2 christos /* case SLAP_MOD_ADD_IF_NOT_PRESENT: */
398 1.1 lukem add_only:;
399 1.1 lukem if ( at->bam_add_proc == NULL ) {
400 1.1 lukem Debug( LDAP_DEBUG_TRACE,
401 1.1 lukem " backsql_modify_internal(): "
402 1.1 lukem "add procedure is not defined "
403 1.1 lukem "for attribute \"%s\"\n",
404 1.1 lukem at->bam_ad->ad_cname.bv_val, 0, 0 );
405 1.1 lukem
406 1.1 lukem if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
407 1.1 lukem rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
408 1.1 lukem rs->sr_text = "operation not permitted "
409 1.1 lukem "within namingContext";
410 1.1 lukem goto done;
411 1.1 lukem }
412 1.1 lukem
413 1.1 lukem break;
414 1.1 lukem }
415 1.1 lukem
416 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
417 1.1 lukem "adding new values for attribute \"%s\"\n",
418 1.1 lukem at->bam_ad->ad_cname.bv_val, 0, 0 );
419 1.1 lukem
420 1.1 lukem /* can't add a NULL val array */
421 1.1 lukem assert( sm_values != NULL );
422 1.1 lukem
423 1.1 lukem for ( i = 0, at_val = sm_values;
424 1.1 lukem !BER_BVISNULL( at_val );
425 1.1 lukem i++, at_val++ )
426 1.1 lukem {
427 1.1 lukem SQLHSTMT sth = SQL_NULL_HSTMT;
428 1.1 lukem /* first parameter position, parameter order */
429 1.1 lukem SQLUSMALLINT pno = 0,
430 1.1 lukem po;
431 1.1 lukem /* procedure return code */
432 1.1 lukem int prc = LDAP_SUCCESS;
433 1.1 lukem
434 1.1 lukem rc = backsql_Prepare( dbh, &sth, at->bam_add_proc, 0 );
435 1.1 lukem if ( rc != SQL_SUCCESS ) {
436 1.1 lukem Debug( LDAP_DEBUG_TRACE,
437 1.1 lukem " backsql_modify_internal(): "
438 1.1 lukem "error preparing add query\n",
439 1.1 lukem 0, 0, 0 );
440 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
441 1.1 lukem
442 1.1 lukem rs->sr_err = LDAP_OTHER;
443 1.1 lukem rs->sr_text = "SQL-backend error";
444 1.1 lukem goto done;
445 1.1 lukem }
446 1.1 lukem
447 1.1 lukem if ( BACKSQL_IS_ADD( at->bam_expect_return ) ) {
448 1.1 lukem pno = 1;
449 1.1 lukem rc = backsql_BindParamInt( sth, 1,
450 1.1 lukem SQL_PARAM_OUTPUT, &prc );
451 1.1 lukem if ( rc != SQL_SUCCESS ) {
452 1.1 lukem Debug( LDAP_DEBUG_TRACE,
453 1.1 lukem " backsql_modify_internal(): "
454 1.1 lukem "error binding output parameter for %s[%d]\n",
455 1.1 lukem at->bam_ad->ad_cname.bv_val, i, 0 );
456 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
457 1.1 lukem sth, rc );
458 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
459 1.1 lukem
460 1.1 lukem rs->sr_text = "SQL-backend error";
461 1.1 lukem rs->sr_err = LDAP_OTHER;
462 1.1 lukem goto done;
463 1.1 lukem }
464 1.1 lukem }
465 1.1 lukem po = ( BACKSQL_IS_ADD( at->bam_param_order ) ) > 0;
466 1.1 lukem rc = backsql_BindParamID( sth, pno + 1 + po,
467 1.1 lukem SQL_PARAM_INPUT, &e_id->eid_keyval );
468 1.1 lukem if ( rc != SQL_SUCCESS ) {
469 1.1 lukem Debug( LDAP_DEBUG_TRACE,
470 1.1 lukem " backsql_modify_internal(): "
471 1.1 lukem "error binding keyval parameter for %s[%d]\n",
472 1.1 lukem at->bam_ad->ad_cname.bv_val, i, 0 );
473 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
474 1.1 lukem sth, rc );
475 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
476 1.1 lukem
477 1.1 lukem rs->sr_text = "SQL-backend error";
478 1.1 lukem rs->sr_err = LDAP_OTHER;
479 1.1 lukem goto done;
480 1.1 lukem }
481 1.2 christos
482 1.1 lukem Debug( LDAP_DEBUG_TRACE,
483 1.1 lukem " backsql_modify_internal(): "
484 1.2 christos "arg(%d)=" BACKSQL_IDFMT "\n",
485 1.2 christos pno + 1 + po,
486 1.2 christos BACKSQL_IDARG(e_id->eid_keyval), 0 );
487 1.1 lukem
488 1.1 lukem /*
489 1.1 lukem * check for syntax needed here
490 1.1 lukem * maybe need binary bind?
491 1.1 lukem */
492 1.1 lukem rc = backsql_BindParamBerVal( sth, pno + 2 - po,
493 1.1 lukem SQL_PARAM_INPUT, at_val );
494 1.1 lukem if ( rc != SQL_SUCCESS ) {
495 1.1 lukem Debug( LDAP_DEBUG_TRACE,
496 1.1 lukem " backsql_modify_internal(): "
497 1.1 lukem "error binding value parameter for %s[%d]\n",
498 1.1 lukem at->bam_ad->ad_cname.bv_val, i, 0 );
499 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
500 1.1 lukem sth, rc );
501 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
502 1.1 lukem
503 1.1 lukem rs->sr_text = "SQL-backend error";
504 1.1 lukem rs->sr_err = LDAP_OTHER;
505 1.1 lukem goto done;
506 1.1 lukem }
507 1.1 lukem Debug( LDAP_DEBUG_TRACE,
508 1.1 lukem " backsql_modify_internal(): "
509 1.1 lukem "arg(%d)=\"%s\"; executing \"%s\"\n",
510 1.1 lukem pno + 2 - po, at_val->bv_val,
511 1.1 lukem at->bam_add_proc );
512 1.1 lukem
513 1.1 lukem rc = SQLExecute( sth );
514 1.1 lukem if ( rc == SQL_SUCCESS && prc == LDAP_SUCCESS ) {
515 1.1 lukem rs->sr_err = LDAP_SUCCESS;
516 1.1 lukem
517 1.1 lukem } else {
518 1.1 lukem Debug( LDAP_DEBUG_TRACE,
519 1.1 lukem " backsql_modify_internal(): "
520 1.1 lukem "add_proc execution failed "
521 1.1 lukem "(rc=%d, prc=%d)\n",
522 1.1 lukem rc, prc, 0 );
523 1.1 lukem if ( prc != LDAP_SUCCESS ) {
524 1.1 lukem /* SQL procedure executed fine
525 1.1 lukem * but returned an error */
526 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
527 1.1 lukem
528 1.1 lukem rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
529 1.1 lukem rs->sr_text = at->bam_ad->ad_cname.bv_val;
530 1.1 lukem return rs->sr_err;
531 1.1 lukem
532 1.1 lukem } else {
533 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
534 1.1 lukem sth, rc );
535 1.1 lukem if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) )
536 1.1 lukem {
537 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
538 1.1 lukem
539 1.1 lukem rs->sr_err = LDAP_OTHER;
540 1.1 lukem rs->sr_text = "SQL-backend error";
541 1.1 lukem goto done;
542 1.1 lukem }
543 1.1 lukem }
544 1.1 lukem }
545 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
546 1.1 lukem }
547 1.1 lukem break;
548 1.1 lukem
549 1.1 lukem case LDAP_MOD_DELETE:
550 1.2 christos /* case SLAP_MOD_SOFTDEL: */
551 1.1 lukem if ( at->bam_delete_proc == NULL ) {
552 1.1 lukem Debug( LDAP_DEBUG_TRACE,
553 1.1 lukem " backsql_modify_internal(): "
554 1.1 lukem "delete procedure is not defined "
555 1.1 lukem "for attribute \"%s\"\n",
556 1.1 lukem at->bam_ad->ad_cname.bv_val, 0, 0 );
557 1.1 lukem
558 1.1 lukem if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
559 1.1 lukem rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
560 1.1 lukem rs->sr_text = "operation not permitted "
561 1.1 lukem "within namingContext";
562 1.1 lukem goto done;
563 1.1 lukem }
564 1.1 lukem
565 1.1 lukem break;
566 1.1 lukem }
567 1.1 lukem
568 1.1 lukem if ( sm_values == NULL ) {
569 1.1 lukem Debug( LDAP_DEBUG_TRACE,
570 1.1 lukem " backsql_modify_internal(): "
571 1.1 lukem "no values given to delete "
572 1.1 lukem "for attribute \"%s\" "
573 1.1 lukem "-- deleting all values\n",
574 1.1 lukem at->bam_ad->ad_cname.bv_val, 0, 0 );
575 1.1 lukem goto del_all;
576 1.1 lukem }
577 1.1 lukem
578 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
579 1.1 lukem "deleting values for attribute \"%s\"\n",
580 1.1 lukem at->bam_ad->ad_cname.bv_val, 0, 0 );
581 1.1 lukem
582 1.1 lukem for ( i = 0, at_val = sm_values;
583 1.1 lukem !BER_BVISNULL( at_val );
584 1.1 lukem i++, at_val++ )
585 1.1 lukem {
586 1.1 lukem SQLHSTMT sth = SQL_NULL_HSTMT;
587 1.1 lukem /* first parameter position, parameter order */
588 1.1 lukem SQLUSMALLINT pno = 0,
589 1.1 lukem po;
590 1.1 lukem /* procedure return code */
591 1.1 lukem int prc = LDAP_SUCCESS;
592 1.1 lukem
593 1.1 lukem rc = backsql_Prepare( dbh, &sth, at->bam_delete_proc, 0 );
594 1.1 lukem if ( rc != SQL_SUCCESS ) {
595 1.1 lukem Debug( LDAP_DEBUG_TRACE,
596 1.1 lukem " backsql_modify_internal(): "
597 1.1 lukem "error preparing delete query\n",
598 1.1 lukem 0, 0, 0 );
599 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
600 1.1 lukem
601 1.1 lukem rs->sr_err = LDAP_OTHER;
602 1.1 lukem rs->sr_text = "SQL-backend error";
603 1.1 lukem goto done;
604 1.1 lukem }
605 1.1 lukem
606 1.1 lukem if ( BACKSQL_IS_DEL( at->bam_expect_return ) ) {
607 1.1 lukem pno = 1;
608 1.1 lukem rc = backsql_BindParamInt( sth, 1,
609 1.1 lukem SQL_PARAM_OUTPUT, &prc );
610 1.1 lukem if ( rc != SQL_SUCCESS ) {
611 1.1 lukem Debug( LDAP_DEBUG_TRACE,
612 1.1 lukem " backsql_modify_internal(): "
613 1.1 lukem "error binding output parameter for %s[%d]\n",
614 1.1 lukem at->bam_ad->ad_cname.bv_val, i, 0 );
615 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
616 1.1 lukem sth, rc );
617 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
618 1.1 lukem
619 1.1 lukem rs->sr_text = "SQL-backend error";
620 1.1 lukem rs->sr_err = LDAP_OTHER;
621 1.1 lukem goto done;
622 1.1 lukem }
623 1.1 lukem }
624 1.1 lukem po = ( BACKSQL_IS_DEL( at->bam_param_order ) ) > 0;
625 1.1 lukem rc = backsql_BindParamID( sth, pno + 1 + po,
626 1.1 lukem SQL_PARAM_INPUT, &e_id->eid_keyval );
627 1.1 lukem if ( rc != SQL_SUCCESS ) {
628 1.1 lukem Debug( LDAP_DEBUG_TRACE,
629 1.1 lukem " backsql_modify_internal(): "
630 1.1 lukem "error binding keyval parameter for %s[%d]\n",
631 1.1 lukem at->bam_ad->ad_cname.bv_val, i, 0 );
632 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
633 1.1 lukem sth, rc );
634 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
635 1.1 lukem
636 1.1 lukem rs->sr_text = "SQL-backend error";
637 1.1 lukem rs->sr_err = LDAP_OTHER;
638 1.1 lukem goto done;
639 1.1 lukem }
640 1.2 christos
641 1.1 lukem Debug( LDAP_DEBUG_TRACE,
642 1.1 lukem " backsql_modify_internal(): "
643 1.2 christos "arg(%d)=" BACKSQL_IDFMT "\n",
644 1.2 christos pno + 1 + po,
645 1.2 christos BACKSQL_IDARG(e_id->eid_keyval), 0 );
646 1.1 lukem
647 1.1 lukem /*
648 1.1 lukem * check for syntax needed here
649 1.1 lukem * maybe need binary bind?
650 1.1 lukem */
651 1.1 lukem rc = backsql_BindParamBerVal( sth, pno + 2 - po,
652 1.1 lukem SQL_PARAM_INPUT, at_val );
653 1.1 lukem if ( rc != SQL_SUCCESS ) {
654 1.1 lukem Debug( LDAP_DEBUG_TRACE,
655 1.1 lukem " backsql_modify_internal(): "
656 1.1 lukem "error binding value parameter for %s[%d]\n",
657 1.1 lukem at->bam_ad->ad_cname.bv_val, i, 0 );
658 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
659 1.1 lukem sth, rc );
660 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
661 1.1 lukem
662 1.1 lukem rs->sr_text = "SQL-backend error";
663 1.1 lukem rs->sr_err = LDAP_OTHER;
664 1.1 lukem goto done;
665 1.1 lukem }
666 1.1 lukem
667 1.1 lukem Debug( LDAP_DEBUG_TRACE,
668 1.1 lukem " backsql_modify_internal(): "
669 1.1 lukem "executing \"%s\"\n",
670 1.1 lukem at->bam_delete_proc, 0, 0 );
671 1.1 lukem rc = SQLExecute( sth );
672 1.1 lukem if ( rc == SQL_SUCCESS && prc == LDAP_SUCCESS )
673 1.1 lukem {
674 1.1 lukem rs->sr_err = LDAP_SUCCESS;
675 1.1 lukem
676 1.1 lukem } else {
677 1.1 lukem Debug( LDAP_DEBUG_TRACE,
678 1.1 lukem " backsql_modify_internal(): "
679 1.1 lukem "delete_proc execution "
680 1.1 lukem "failed (rc=%d, prc=%d)\n",
681 1.1 lukem rc, prc, 0 );
682 1.1 lukem
683 1.1 lukem if ( prc != LDAP_SUCCESS ) {
684 1.1 lukem /* SQL procedure executed fine
685 1.1 lukem * but returned an error */
686 1.1 lukem rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
687 1.1 lukem rs->sr_text = at->bam_ad->ad_cname.bv_val;
688 1.1 lukem goto done;
689 1.1 lukem
690 1.1 lukem } else {
691 1.1 lukem backsql_PrintErrors( bi->sql_db_env,
692 1.1 lukem dbh, sth, rc );
693 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
694 1.1 lukem rs->sr_err = LDAP_OTHER;
695 1.1 lukem rs->sr_text = at->bam_ad->ad_cname.bv_val;
696 1.1 lukem goto done;
697 1.1 lukem }
698 1.1 lukem }
699 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
700 1.1 lukem }
701 1.1 lukem break;
702 1.1 lukem
703 1.1 lukem case LDAP_MOD_INCREMENT:
704 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
705 1.1 lukem "increment not supported yet\n", 0, 0, 0 );
706 1.1 lukem if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
707 1.1 lukem rs->sr_err = LDAP_OTHER;
708 1.1 lukem rs->sr_text = "SQL-backend error";
709 1.1 lukem goto done;
710 1.1 lukem }
711 1.1 lukem break;
712 1.1 lukem }
713 1.1 lukem }
714 1.1 lukem
715 1.1 lukem done:;
716 1.1 lukem Debug( LDAP_DEBUG_TRACE, "<==backsql_modify_internal(): %d%s%s\n",
717 1.1 lukem rs->sr_err,
718 1.1 lukem rs->sr_text ? ": " : "",
719 1.1 lukem rs->sr_text ? rs->sr_text : "" );
720 1.1 lukem
721 1.1 lukem /*
722 1.1 lukem * FIXME: should fail in case one change fails?
723 1.1 lukem */
724 1.1 lukem return rs->sr_err;
725 1.1 lukem }
726 1.1 lukem
727 1.1 lukem static int
728 1.1 lukem backsql_add_attr(
729 1.1 lukem Operation *op,
730 1.1 lukem SlapReply *rs,
731 1.1 lukem SQLHDBC dbh,
732 1.1 lukem backsql_oc_map_rec *oc,
733 1.1 lukem Attribute *at,
734 1.2 christos backsql_key_t new_keyval )
735 1.1 lukem {
736 1.1 lukem backsql_info *bi = (backsql_info*)op->o_bd->be_private;
737 1.1 lukem backsql_at_map_rec *at_rec = NULL;
738 1.1 lukem struct berval *at_val;
739 1.1 lukem unsigned long i;
740 1.1 lukem RETCODE rc;
741 1.1 lukem SQLUSMALLINT currpos;
742 1.1 lukem SQLHSTMT sth = SQL_NULL_HSTMT;
743 1.1 lukem
744 1.1 lukem at_rec = backsql_ad2at( oc, at->a_desc );
745 1.1 lukem
746 1.1 lukem if ( at_rec == NULL ) {
747 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add_attr(\"%s\"): "
748 1.1 lukem "attribute \"%s\" is not registered "
749 1.1 lukem "in objectclass \"%s\"\n",
750 1.1 lukem op->ora_e->e_name.bv_val,
751 1.1 lukem at->a_desc->ad_cname.bv_val,
752 1.1 lukem BACKSQL_OC_NAME( oc ) );
753 1.1 lukem
754 1.1 lukem if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
755 1.1 lukem rs->sr_text = "operation not permitted "
756 1.1 lukem "within namingContext";
757 1.1 lukem return rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
758 1.1 lukem }
759 1.1 lukem
760 1.1 lukem return LDAP_SUCCESS;
761 1.1 lukem }
762 1.1 lukem
763 1.1 lukem if ( at_rec->bam_add_proc == NULL ) {
764 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add_attr(\"%s\"): "
765 1.1 lukem "add procedure is not defined "
766 1.1 lukem "for attribute \"%s\" "
767 1.1 lukem "of structuralObjectClass \"%s\"\n",
768 1.1 lukem op->ora_e->e_name.bv_val,
769 1.1 lukem at->a_desc->ad_cname.bv_val,
770 1.1 lukem BACKSQL_OC_NAME( oc ) );
771 1.1 lukem
772 1.1 lukem if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
773 1.1 lukem rs->sr_text = "operation not permitted "
774 1.1 lukem "within namingContext";
775 1.1 lukem return rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
776 1.1 lukem }
777 1.1 lukem
778 1.1 lukem return LDAP_SUCCESS;
779 1.1 lukem }
780 1.1 lukem
781 1.1 lukem for ( i = 0, at_val = &at->a_vals[ i ];
782 1.1 lukem !BER_BVISNULL( at_val );
783 1.1 lukem i++, at_val = &at->a_vals[ i ] )
784 1.1 lukem {
785 1.1 lukem /* procedure return code */
786 1.1 lukem int prc = LDAP_SUCCESS;
787 1.1 lukem /* first parameter #, parameter order */
788 1.1 lukem SQLUSMALLINT pno, po;
789 1.1 lukem char logbuf[ STRLENOF("val[], id=") + 2*LDAP_PVT_INTTYPE_CHARS(unsigned long)];
790 1.1 lukem
791 1.1 lukem /*
792 1.1 lukem * Do not deal with the objectClass that is used
793 1.1 lukem * to build the entry
794 1.1 lukem */
795 1.1 lukem if ( at->a_desc == slap_schema.si_ad_objectClass ) {
796 1.1 lukem if ( dn_match( at_val, &oc->bom_oc->soc_cname ) )
797 1.1 lukem {
798 1.1 lukem continue;
799 1.1 lukem }
800 1.1 lukem }
801 1.1 lukem
802 1.1 lukem rc = backsql_Prepare( dbh, &sth, at_rec->bam_add_proc, 0 );
803 1.1 lukem if ( rc != SQL_SUCCESS ) {
804 1.1 lukem rs->sr_text = "SQL-backend error";
805 1.1 lukem return rs->sr_err = LDAP_OTHER;
806 1.1 lukem }
807 1.1 lukem
808 1.1 lukem if ( BACKSQL_IS_ADD( at_rec->bam_expect_return ) ) {
809 1.1 lukem pno = 1;
810 1.1 lukem rc = backsql_BindParamInt( sth, 1, SQL_PARAM_OUTPUT, &prc );
811 1.1 lukem if ( rc != SQL_SUCCESS ) {
812 1.1 lukem Debug( LDAP_DEBUG_TRACE,
813 1.1 lukem " backsql_add_attr(): "
814 1.1 lukem "error binding output parameter for %s[%lu]\n",
815 1.1 lukem at_rec->bam_ad->ad_cname.bv_val, i, 0 );
816 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
817 1.1 lukem sth, rc );
818 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
819 1.1 lukem
820 1.1 lukem rs->sr_text = "SQL-backend error";
821 1.1 lukem return rs->sr_err = LDAP_OTHER;
822 1.1 lukem }
823 1.1 lukem
824 1.1 lukem } else {
825 1.1 lukem pno = 0;
826 1.1 lukem }
827 1.1 lukem
828 1.1 lukem po = ( BACKSQL_IS_ADD( at_rec->bam_param_order ) ) > 0;
829 1.1 lukem currpos = pno + 1 + po;
830 1.2 christos rc = backsql_BindParamNumID( sth, currpos,
831 1.1 lukem SQL_PARAM_INPUT, &new_keyval );
832 1.1 lukem if ( rc != SQL_SUCCESS ) {
833 1.1 lukem Debug( LDAP_DEBUG_TRACE,
834 1.1 lukem " backsql_add_attr(): "
835 1.1 lukem "error binding keyval parameter for %s[%lu]\n",
836 1.1 lukem at_rec->bam_ad->ad_cname.bv_val, i, 0 );
837 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
838 1.1 lukem sth, rc );
839 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
840 1.1 lukem
841 1.1 lukem rs->sr_text = "SQL-backend error";
842 1.1 lukem return rs->sr_err = LDAP_OTHER;
843 1.1 lukem }
844 1.1 lukem
845 1.1 lukem currpos = pno + 2 - po;
846 1.1 lukem
847 1.1 lukem /*
848 1.1 lukem * check for syntax needed here
849 1.1 lukem * maybe need binary bind?
850 1.1 lukem */
851 1.1 lukem
852 1.1 lukem rc = backsql_BindParamBerVal( sth, currpos, SQL_PARAM_INPUT, at_val );
853 1.1 lukem if ( rc != SQL_SUCCESS ) {
854 1.1 lukem Debug( LDAP_DEBUG_TRACE,
855 1.1 lukem " backsql_add_attr(): "
856 1.1 lukem "error binding value parameter for %s[%lu]\n",
857 1.1 lukem at_rec->bam_ad->ad_cname.bv_val, i, 0 );
858 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
859 1.1 lukem sth, rc );
860 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
861 1.1 lukem
862 1.1 lukem rs->sr_text = "SQL-backend error";
863 1.1 lukem return rs->sr_err = LDAP_OTHER;
864 1.1 lukem }
865 1.1 lukem
866 1.1 lukem #ifdef LDAP_DEBUG
867 1.2 christos if ( LogTest( LDAP_DEBUG_TRACE ) ) {
868 1.2 christos snprintf( logbuf, sizeof( logbuf ), "val[%lu], id=" BACKSQL_IDNUMFMT,
869 1.2 christos i, new_keyval );
870 1.2 christos Debug( LDAP_DEBUG_TRACE, " backsql_add_attr(\"%s\"): "
871 1.2 christos "executing \"%s\" %s\n",
872 1.2 christos op->ora_e->e_name.bv_val,
873 1.2 christos at_rec->bam_add_proc, logbuf );
874 1.2 christos }
875 1.1 lukem #endif
876 1.1 lukem rc = SQLExecute( sth );
877 1.1 lukem if ( rc == SQL_SUCCESS && prc == LDAP_SUCCESS ) {
878 1.1 lukem rs->sr_err = LDAP_SUCCESS;
879 1.1 lukem
880 1.1 lukem } else {
881 1.1 lukem Debug( LDAP_DEBUG_TRACE,
882 1.1 lukem " backsql_add_attr(\"%s\"): "
883 1.1 lukem "add_proc execution failed (rc=%d, prc=%d)\n",
884 1.1 lukem op->ora_e->e_name.bv_val, rc, prc );
885 1.1 lukem if ( prc != LDAP_SUCCESS ) {
886 1.1 lukem /* SQL procedure executed fine
887 1.1 lukem * but returned an error */
888 1.1 lukem rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
889 1.1 lukem rs->sr_text = op->ora_e->e_name.bv_val;
890 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
891 1.1 lukem return rs->sr_err;
892 1.1 lukem
893 1.1 lukem } else {
894 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
895 1.1 lukem sth, rc );
896 1.1 lukem rs->sr_err = LDAP_OTHER;
897 1.1 lukem rs->sr_text = op->ora_e->e_name.bv_val;
898 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
899 1.1 lukem return rs->sr_err;
900 1.1 lukem }
901 1.1 lukem }
902 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
903 1.1 lukem }
904 1.1 lukem
905 1.1 lukem return LDAP_SUCCESS;
906 1.1 lukem }
907 1.1 lukem
908 1.1 lukem int
909 1.1 lukem backsql_add( Operation *op, SlapReply *rs )
910 1.1 lukem {
911 1.1 lukem backsql_info *bi = (backsql_info*)op->o_bd->be_private;
912 1.1 lukem SQLHDBC dbh = SQL_NULL_HDBC;
913 1.1 lukem SQLHSTMT sth = SQL_NULL_HSTMT;
914 1.2 christos backsql_key_t new_keyval = 0;
915 1.1 lukem RETCODE rc;
916 1.1 lukem backsql_oc_map_rec *oc = NULL;
917 1.1 lukem backsql_srch_info bsi = { 0 };
918 1.1 lukem Entry p = { 0 }, *e = NULL;
919 1.1 lukem Attribute *at,
920 1.1 lukem *at_objectClass = NULL;
921 1.1 lukem ObjectClass *soc = NULL;
922 1.1 lukem struct berval scname = BER_BVNULL;
923 1.1 lukem struct berval pdn;
924 1.1 lukem struct berval realdn = BER_BVNULL;
925 1.1 lukem int colnum;
926 1.1 lukem slap_mask_t mask;
927 1.1 lukem
928 1.1 lukem char textbuf[ SLAP_TEXT_BUFLEN ];
929 1.1 lukem size_t textlen = sizeof( textbuf );
930 1.1 lukem
931 1.1 lukem #ifdef BACKSQL_SYNCPROV
932 1.1 lukem /*
933 1.1 lukem * NOTE: fake successful result to force contextCSN to be bumped up
934 1.1 lukem */
935 1.1 lukem if ( op->o_sync ) {
936 1.2 christos char buf[ LDAP_PVT_CSNSTR_BUFSIZE ];
937 1.1 lukem struct berval csn;
938 1.1 lukem
939 1.1 lukem csn.bv_val = buf;
940 1.1 lukem csn.bv_len = sizeof( buf );
941 1.1 lukem slap_get_csn( op, &csn, 1 );
942 1.1 lukem
943 1.1 lukem rs->sr_err = LDAP_SUCCESS;
944 1.1 lukem send_ldap_result( op, rs );
945 1.1 lukem
946 1.1 lukem slap_graduate_commit_csn( op );
947 1.1 lukem
948 1.1 lukem return 0;
949 1.1 lukem }
950 1.1 lukem #endif /* BACKSQL_SYNCPROV */
951 1.1 lukem
952 1.1 lukem Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n",
953 1.1 lukem op->ora_e->e_name.bv_val, 0, 0 );
954 1.1 lukem
955 1.1 lukem /* check schema */
956 1.1 lukem if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
957 1.1 lukem char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' };
958 1.1 lukem
959 1.2 christos rs->sr_err = entry_schema_check( op, op->ora_e, NULL, 0, 1, NULL,
960 1.1 lukem &rs->sr_text, textbuf, sizeof( textbuf ) );
961 1.1 lukem if ( rs->sr_err != LDAP_SUCCESS ) {
962 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
963 1.1 lukem "entry failed schema check -- aborting\n",
964 1.1 lukem op->ora_e->e_name.bv_val, 0, 0 );
965 1.1 lukem e = NULL;
966 1.1 lukem goto done;
967 1.1 lukem }
968 1.1 lukem }
969 1.1 lukem
970 1.1 lukem slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
971 1.1 lukem
972 1.2 christos if ( get_assert( op ) &&
973 1.2 christos ( test_filter( op, op->ora_e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
974 1.2 christos {
975 1.2 christos Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
976 1.2 christos "assertion control failed -- aborting\n",
977 1.2 christos op->ora_e->e_name.bv_val, 0, 0 );
978 1.2 christos e = NULL;
979 1.2 christos rs->sr_err = LDAP_ASSERTION_FAILED;
980 1.2 christos goto done;
981 1.2 christos }
982 1.2 christos
983 1.1 lukem /* search structuralObjectClass */
984 1.1 lukem for ( at = op->ora_e->e_attrs; at != NULL; at = at->a_next ) {
985 1.1 lukem if ( at->a_desc == slap_schema.si_ad_structuralObjectClass ) {
986 1.1 lukem break;
987 1.1 lukem }
988 1.1 lukem }
989 1.1 lukem
990 1.1 lukem /* there must exist */
991 1.1 lukem if ( at == NULL ) {
992 1.1 lukem char buf[ SLAP_TEXT_BUFLEN ];
993 1.1 lukem const char *text;
994 1.1 lukem
995 1.1 lukem /* search structuralObjectClass */
996 1.1 lukem for ( at = op->ora_e->e_attrs; at != NULL; at = at->a_next ) {
997 1.1 lukem if ( at->a_desc == slap_schema.si_ad_objectClass ) {
998 1.1 lukem break;
999 1.1 lukem }
1000 1.1 lukem }
1001 1.1 lukem
1002 1.1 lukem if ( at == NULL ) {
1003 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1004 1.1 lukem "no objectClass\n",
1005 1.1 lukem op->ora_e->e_name.bv_val, 0, 0 );
1006 1.1 lukem rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION;
1007 1.1 lukem e = NULL;
1008 1.1 lukem goto done;
1009 1.1 lukem }
1010 1.1 lukem
1011 1.1 lukem rs->sr_err = structural_class( at->a_vals, &soc, NULL,
1012 1.1 lukem &text, buf, sizeof( buf ), op->o_tmpmemctx );
1013 1.1 lukem if ( rs->sr_err != LDAP_SUCCESS ) {
1014 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1015 1.1 lukem "%s (%d)\n",
1016 1.1 lukem op->ora_e->e_name.bv_val, text, rs->sr_err );
1017 1.1 lukem e = NULL;
1018 1.1 lukem goto done;
1019 1.1 lukem }
1020 1.1 lukem scname = soc->soc_cname;
1021 1.1 lukem
1022 1.1 lukem } else {
1023 1.1 lukem scname = at->a_vals[0];
1024 1.1 lukem }
1025 1.1 lukem
1026 1.1 lukem /* I guess we should play with sub/supertypes to find a suitable oc */
1027 1.1 lukem oc = backsql_name2oc( bi, &scname );
1028 1.1 lukem
1029 1.1 lukem if ( oc == NULL ) {
1030 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1031 1.1 lukem "cannot map structuralObjectClass \"%s\" -- aborting\n",
1032 1.1 lukem op->ora_e->e_name.bv_val,
1033 1.1 lukem scname.bv_val, 0 );
1034 1.1 lukem rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
1035 1.1 lukem rs->sr_text = "operation not permitted within namingContext";
1036 1.1 lukem e = NULL;
1037 1.1 lukem goto done;
1038 1.1 lukem }
1039 1.1 lukem
1040 1.1 lukem if ( oc->bom_create_proc == NULL ) {
1041 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1042 1.1 lukem "create procedure is not defined "
1043 1.1 lukem "for structuralObjectClass \"%s\" - aborting\n",
1044 1.1 lukem op->ora_e->e_name.bv_val,
1045 1.1 lukem scname.bv_val, 0 );
1046 1.1 lukem rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
1047 1.1 lukem rs->sr_text = "operation not permitted within namingContext";
1048 1.1 lukem e = NULL;
1049 1.1 lukem goto done;
1050 1.1 lukem
1051 1.1 lukem } else if ( BACKSQL_CREATE_NEEDS_SELECT( bi )
1052 1.1 lukem && oc->bom_create_keyval == NULL ) {
1053 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1054 1.1 lukem "create procedure needs select procedure, "
1055 1.1 lukem "but none is defined for structuralObjectClass \"%s\" "
1056 1.1 lukem "- aborting\n",
1057 1.1 lukem op->ora_e->e_name.bv_val,
1058 1.1 lukem scname.bv_val, 0 );
1059 1.1 lukem rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
1060 1.1 lukem rs->sr_text = "operation not permitted within namingContext";
1061 1.1 lukem e = NULL;
1062 1.1 lukem goto done;
1063 1.1 lukem }
1064 1.1 lukem
1065 1.1 lukem /* check write access */
1066 1.1 lukem if ( !access_allowed_mask( op, op->ora_e,
1067 1.1 lukem slap_schema.si_ad_entry,
1068 1.1 lukem NULL, ACL_WADD, NULL, &mask ) )
1069 1.1 lukem {
1070 1.1 lukem rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
1071 1.1 lukem e = op->ora_e;
1072 1.1 lukem goto done;
1073 1.1 lukem }
1074 1.1 lukem
1075 1.1 lukem rs->sr_err = backsql_get_db_conn( op, &dbh );
1076 1.1 lukem if ( rs->sr_err != LDAP_SUCCESS ) {
1077 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1078 1.1 lukem "could not get connection handle - exiting\n",
1079 1.1 lukem op->ora_e->e_name.bv_val, 0, 0 );
1080 1.1 lukem rs->sr_text = ( rs->sr_err == LDAP_OTHER )
1081 1.1 lukem ? "SQL-backend error" : NULL;
1082 1.1 lukem e = NULL;
1083 1.1 lukem goto done;
1084 1.1 lukem }
1085 1.1 lukem
1086 1.1 lukem /*
1087 1.1 lukem * Check if entry exists
1088 1.1 lukem *
1089 1.1 lukem * NOTE: backsql_api_dn2odbc() is called explicitly because
1090 1.1 lukem * we need the mucked DN to pass it to the create procedure.
1091 1.1 lukem */
1092 1.1 lukem realdn = op->ora_e->e_name;
1093 1.1 lukem if ( backsql_api_dn2odbc( op, rs, &realdn ) ) {
1094 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1095 1.1 lukem "backsql_api_dn2odbc(\"%s\") failed\n",
1096 1.1 lukem op->ora_e->e_name.bv_val, realdn.bv_val, 0 );
1097 1.1 lukem rs->sr_err = LDAP_OTHER;
1098 1.1 lukem rs->sr_text = "SQL-backend error";
1099 1.1 lukem e = NULL;
1100 1.1 lukem goto done;
1101 1.1 lukem }
1102 1.1 lukem
1103 1.1 lukem rs->sr_err = backsql_dn2id( op, rs, dbh, &realdn, NULL, 0, 0 );
1104 1.1 lukem if ( rs->sr_err == LDAP_SUCCESS ) {
1105 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1106 1.1 lukem "entry exists\n",
1107 1.1 lukem op->ora_e->e_name.bv_val, 0, 0 );
1108 1.1 lukem rs->sr_err = LDAP_ALREADY_EXISTS;
1109 1.1 lukem e = op->ora_e;
1110 1.1 lukem goto done;
1111 1.1 lukem }
1112 1.1 lukem
1113 1.1 lukem /*
1114 1.1 lukem * Get the parent dn and see if the corresponding entry exists.
1115 1.1 lukem */
1116 1.1 lukem if ( be_issuffix( op->o_bd, &op->ora_e->e_nname ) ) {
1117 1.1 lukem pdn = slap_empty_bv;
1118 1.1 lukem
1119 1.1 lukem } else {
1120 1.1 lukem dnParent( &op->ora_e->e_nname, &pdn );
1121 1.1 lukem
1122 1.1 lukem /*
1123 1.1 lukem * Get the parent
1124 1.1 lukem */
1125 1.1 lukem bsi.bsi_e = &p;
1126 1.1 lukem rs->sr_err = backsql_init_search( &bsi, &pdn,
1127 1.1 lukem LDAP_SCOPE_BASE,
1128 1.1 lukem (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs,
1129 1.1 lukem ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
1130 1.1 lukem if ( rs->sr_err != LDAP_SUCCESS ) {
1131 1.1 lukem Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
1132 1.1 lukem "could not retrieve addDN parent "
1133 1.1 lukem "\"%s\" ID - %s matched=\"%s\"\n",
1134 1.1 lukem pdn.bv_val,
1135 1.1 lukem rs->sr_err == LDAP_REFERRAL ? "referral" : "no such entry",
1136 1.1 lukem rs->sr_matched ? rs->sr_matched : "(null)" );
1137 1.1 lukem e = &p;
1138 1.1 lukem goto done;
1139 1.1 lukem }
1140 1.1 lukem
1141 1.1 lukem /* check "children" pseudo-attribute access to parent */
1142 1.1 lukem if ( !access_allowed( op, &p, slap_schema.si_ad_children,
1143 1.1 lukem NULL, ACL_WADD, NULL ) )
1144 1.1 lukem {
1145 1.1 lukem rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
1146 1.1 lukem e = &p;
1147 1.1 lukem goto done;
1148 1.1 lukem }
1149 1.1 lukem }
1150 1.1 lukem
1151 1.1 lukem /*
1152 1.1 lukem * create_proc is executed; if expect_return is set, then
1153 1.1 lukem * an output parameter is bound, which should contain
1154 1.1 lukem * the id of the added row; otherwise the procedure
1155 1.1 lukem * is expected to return the id as the first column of a select
1156 1.1 lukem */
1157 1.1 lukem rc = backsql_Prepare( dbh, &sth, oc->bom_create_proc, 0 );
1158 1.1 lukem if ( rc != SQL_SUCCESS ) {
1159 1.1 lukem rs->sr_err = LDAP_OTHER;
1160 1.1 lukem rs->sr_text = "SQL-backend error";
1161 1.1 lukem e = NULL;
1162 1.1 lukem goto done;
1163 1.1 lukem }
1164 1.1 lukem
1165 1.1 lukem colnum = 1;
1166 1.1 lukem if ( BACKSQL_IS_ADD( oc->bom_expect_return ) ) {
1167 1.2 christos rc = backsql_BindParamNumID( sth, 1, SQL_PARAM_OUTPUT, &new_keyval );
1168 1.1 lukem if ( rc != SQL_SUCCESS ) {
1169 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1170 1.1 lukem "error binding keyval parameter "
1171 1.1 lukem "for objectClass %s\n",
1172 1.1 lukem op->ora_e->e_name.bv_val,
1173 1.1 lukem oc->bom_oc->soc_cname.bv_val, 0 );
1174 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
1175 1.1 lukem sth, rc );
1176 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1177 1.1 lukem
1178 1.1 lukem rs->sr_text = "SQL-backend error";
1179 1.1 lukem rs->sr_err = LDAP_OTHER;
1180 1.1 lukem e = NULL;
1181 1.1 lukem goto done;
1182 1.1 lukem }
1183 1.1 lukem colnum++;
1184 1.1 lukem }
1185 1.1 lukem
1186 1.1 lukem if ( oc->bom_create_hint ) {
1187 1.1 lukem at = attr_find( op->ora_e->e_attrs, oc->bom_create_hint );
1188 1.1 lukem if ( at && at->a_vals ) {
1189 1.1 lukem backsql_BindParamStr( sth, colnum, SQL_PARAM_INPUT,
1190 1.1 lukem at->a_vals[0].bv_val,
1191 1.1 lukem at->a_vals[0].bv_len );
1192 1.1 lukem Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
1193 1.1 lukem "create_proc hint: param = '%s'\n",
1194 1.1 lukem at->a_vals[0].bv_val, 0, 0 );
1195 1.1 lukem
1196 1.1 lukem } else {
1197 1.1 lukem backsql_BindParamStr( sth, colnum, SQL_PARAM_INPUT,
1198 1.1 lukem "", 0 );
1199 1.1 lukem Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
1200 1.1 lukem "create_proc hint (%s) not avalable\n",
1201 1.1 lukem oc->bom_create_hint->ad_cname.bv_val,
1202 1.1 lukem 0, 0 );
1203 1.1 lukem }
1204 1.1 lukem colnum++;
1205 1.1 lukem }
1206 1.1 lukem
1207 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): executing \"%s\"\n",
1208 1.1 lukem op->ora_e->e_name.bv_val, oc->bom_create_proc, 0 );
1209 1.1 lukem rc = SQLExecute( sth );
1210 1.1 lukem if ( rc != SQL_SUCCESS ) {
1211 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1212 1.1 lukem "create_proc execution failed\n",
1213 1.1 lukem op->ora_e->e_name.bv_val, 0, 0 );
1214 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
1215 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1216 1.1 lukem rs->sr_err = LDAP_OTHER;
1217 1.1 lukem rs->sr_text = "SQL-backend error";
1218 1.1 lukem e = NULL;
1219 1.1 lukem goto done;
1220 1.1 lukem }
1221 1.1 lukem
1222 1.1 lukem /* FIXME: after SQLExecute(), the row is already inserted
1223 1.1 lukem * (at least with PostgreSQL and unixODBC); needs investigation */
1224 1.1 lukem
1225 1.1 lukem if ( !BACKSQL_IS_ADD( oc->bom_expect_return ) ) {
1226 1.1 lukem SWORD ncols;
1227 1.2 christos SQLLEN value_len;
1228 1.1 lukem
1229 1.1 lukem if ( BACKSQL_CREATE_NEEDS_SELECT( bi ) ) {
1230 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1231 1.1 lukem
1232 1.1 lukem rc = backsql_Prepare( dbh, &sth, oc->bom_create_keyval, 0 );
1233 1.1 lukem if ( rc != SQL_SUCCESS ) {
1234 1.1 lukem rs->sr_err = LDAP_OTHER;
1235 1.1 lukem rs->sr_text = "SQL-backend error";
1236 1.1 lukem e = NULL;
1237 1.1 lukem goto done;
1238 1.1 lukem }
1239 1.1 lukem
1240 1.1 lukem rc = SQLExecute( sth );
1241 1.1 lukem if ( rc != SQL_SUCCESS ) {
1242 1.1 lukem rs->sr_err = LDAP_OTHER;
1243 1.1 lukem rs->sr_text = "SQL-backend error";
1244 1.1 lukem e = NULL;
1245 1.1 lukem goto done;
1246 1.1 lukem }
1247 1.1 lukem }
1248 1.1 lukem
1249 1.1 lukem /*
1250 1.1 lukem * the query to know the id of the inserted entry
1251 1.1 lukem * must be embedded in the create procedure
1252 1.1 lukem */
1253 1.1 lukem rc = SQLNumResultCols( sth, &ncols );
1254 1.1 lukem if ( rc != SQL_SUCCESS ) {
1255 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1256 1.1 lukem "create_proc result evaluation failed\n",
1257 1.1 lukem op->ora_e->e_name.bv_val, 0, 0 );
1258 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
1259 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1260 1.1 lukem rs->sr_err = LDAP_OTHER;
1261 1.1 lukem rs->sr_text = "SQL-backend error";
1262 1.1 lukem e = NULL;
1263 1.1 lukem goto done;
1264 1.1 lukem
1265 1.1 lukem } else if ( ncols != 1 ) {
1266 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1267 1.1 lukem "create_proc result is bogus (ncols=%d)\n",
1268 1.1 lukem op->ora_e->e_name.bv_val, ncols, 0 );
1269 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
1270 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1271 1.1 lukem rs->sr_err = LDAP_OTHER;
1272 1.1 lukem rs->sr_text = "SQL-backend error";
1273 1.1 lukem e = NULL;
1274 1.1 lukem goto done;
1275 1.1 lukem }
1276 1.1 lukem
1277 1.1 lukem #if 0
1278 1.1 lukem {
1279 1.1 lukem SQLCHAR colname[ 64 ];
1280 1.1 lukem SQLSMALLINT name_len, col_type, col_scale, col_null;
1281 1.1 lukem UDWORD col_prec;
1282 1.1 lukem
1283 1.1 lukem /*
1284 1.1 lukem * FIXME: check whether col_type is compatible,
1285 1.1 lukem * if it can be null and so on ...
1286 1.1 lukem */
1287 1.1 lukem rc = SQLDescribeCol( sth, (SQLUSMALLINT)1,
1288 1.1 lukem &colname[ 0 ],
1289 1.1 lukem (SQLUINTEGER)( sizeof( colname ) - 1 ),
1290 1.1 lukem &name_len, &col_type,
1291 1.1 lukem &col_prec, &col_scale, &col_null );
1292 1.1 lukem }
1293 1.1 lukem #endif
1294 1.1 lukem
1295 1.1 lukem rc = SQLBindCol( sth, (SQLUSMALLINT)1, SQL_C_ULONG,
1296 1.1 lukem (SQLPOINTER)&new_keyval,
1297 1.1 lukem (SQLINTEGER)sizeof( new_keyval ),
1298 1.1 lukem &value_len );
1299 1.1 lukem
1300 1.1 lukem rc = SQLFetch( sth );
1301 1.1 lukem
1302 1.1 lukem if ( value_len <= 0 ) {
1303 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1304 1.1 lukem "create_proc result is empty?\n",
1305 1.1 lukem op->ora_e->e_name.bv_val, 0, 0 );
1306 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
1307 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1308 1.1 lukem rs->sr_err = LDAP_OTHER;
1309 1.1 lukem rs->sr_text = "SQL-backend error";
1310 1.1 lukem e = NULL;
1311 1.1 lukem goto done;
1312 1.1 lukem }
1313 1.1 lukem }
1314 1.1 lukem
1315 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1316 1.1 lukem
1317 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1318 1.2 christos "create_proc returned keyval=" BACKSQL_IDNUMFMT "\n",
1319 1.1 lukem op->ora_e->e_name.bv_val, new_keyval, 0 );
1320 1.1 lukem
1321 1.1 lukem rc = backsql_Prepare( dbh, &sth, bi->sql_insentry_stmt, 0 );
1322 1.1 lukem if ( rc != SQL_SUCCESS ) {
1323 1.1 lukem rs->sr_err = LDAP_OTHER;
1324 1.1 lukem rs->sr_text = "SQL-backend error";
1325 1.1 lukem e = NULL;
1326 1.1 lukem goto done;
1327 1.1 lukem }
1328 1.1 lukem
1329 1.1 lukem rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &realdn );
1330 1.1 lukem if ( rc != SQL_SUCCESS ) {
1331 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1332 1.1 lukem "error binding DN parameter for objectClass %s\n",
1333 1.1 lukem op->ora_e->e_name.bv_val,
1334 1.1 lukem oc->bom_oc->soc_cname.bv_val, 0 );
1335 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
1336 1.1 lukem sth, rc );
1337 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1338 1.1 lukem
1339 1.1 lukem rs->sr_text = "SQL-backend error";
1340 1.1 lukem rs->sr_err = LDAP_OTHER;
1341 1.1 lukem e = NULL;
1342 1.1 lukem goto done;
1343 1.1 lukem }
1344 1.1 lukem
1345 1.2 christos rc = backsql_BindParamNumID( sth, 2, SQL_PARAM_INPUT, &oc->bom_id );
1346 1.1 lukem if ( rc != SQL_SUCCESS ) {
1347 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1348 1.1 lukem "error binding objectClass ID parameter "
1349 1.1 lukem "for objectClass %s\n",
1350 1.1 lukem op->ora_e->e_name.bv_val,
1351 1.1 lukem oc->bom_oc->soc_cname.bv_val, 0 );
1352 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
1353 1.1 lukem sth, rc );
1354 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1355 1.1 lukem
1356 1.1 lukem rs->sr_text = "SQL-backend error";
1357 1.1 lukem rs->sr_err = LDAP_OTHER;
1358 1.1 lukem e = NULL;
1359 1.1 lukem goto done;
1360 1.1 lukem }
1361 1.1 lukem
1362 1.1 lukem rc = backsql_BindParamID( sth, 3, SQL_PARAM_INPUT, &bsi.bsi_base_id.eid_id );
1363 1.1 lukem if ( rc != SQL_SUCCESS ) {
1364 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1365 1.1 lukem "error binding parent ID parameter "
1366 1.1 lukem "for objectClass %s\n",
1367 1.1 lukem op->ora_e->e_name.bv_val,
1368 1.1 lukem oc->bom_oc->soc_cname.bv_val, 0 );
1369 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
1370 1.1 lukem sth, rc );
1371 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1372 1.1 lukem
1373 1.1 lukem rs->sr_text = "SQL-backend error";
1374 1.1 lukem rs->sr_err = LDAP_OTHER;
1375 1.1 lukem e = NULL;
1376 1.1 lukem goto done;
1377 1.1 lukem }
1378 1.1 lukem
1379 1.2 christos rc = backsql_BindParamNumID( sth, 4, SQL_PARAM_INPUT, &new_keyval );
1380 1.1 lukem if ( rc != SQL_SUCCESS ) {
1381 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1382 1.1 lukem "error binding entry ID parameter "
1383 1.1 lukem "for objectClass %s\n",
1384 1.1 lukem op->ora_e->e_name.bv_val,
1385 1.1 lukem oc->bom_oc->soc_cname.bv_val, 0 );
1386 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh,
1387 1.1 lukem sth, rc );
1388 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1389 1.1 lukem
1390 1.1 lukem rs->sr_text = "SQL-backend error";
1391 1.1 lukem rs->sr_err = LDAP_OTHER;
1392 1.1 lukem e = NULL;
1393 1.1 lukem goto done;
1394 1.1 lukem }
1395 1.1 lukem
1396 1.2 christos if ( LogTest( LDAP_DEBUG_TRACE ) ) {
1397 1.2 christos char buf[ SLAP_TEXT_BUFLEN ];
1398 1.2 christos
1399 1.2 christos snprintf( buf, sizeof(buf),
1400 1.2 christos "executing \"%s\" for dn=\"%s\" oc_map_id=" BACKSQL_IDNUMFMT " p_id=" BACKSQL_IDFMT " keyval=" BACKSQL_IDNUMFMT,
1401 1.2 christos bi->sql_insentry_stmt, op->ora_e->e_name.bv_val,
1402 1.2 christos oc->bom_id, BACKSQL_IDARG(bsi.bsi_base_id.eid_id),
1403 1.2 christos new_keyval );
1404 1.2 christos Debug( LDAP_DEBUG_TRACE, " backsql_add(): %s\n", buf, 0, 0 );
1405 1.2 christos }
1406 1.2 christos
1407 1.1 lukem rc = SQLExecute( sth );
1408 1.1 lukem if ( rc != SQL_SUCCESS ) {
1409 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1410 1.1 lukem "could not insert ldap_entries record\n",
1411 1.1 lukem op->ora_e->e_name.bv_val, 0, 0 );
1412 1.1 lukem backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
1413 1.1 lukem
1414 1.1 lukem /*
1415 1.1 lukem * execute delete_proc to delete data added !!!
1416 1.1 lukem */
1417 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1418 1.1 lukem rs->sr_err = LDAP_OTHER;
1419 1.1 lukem rs->sr_text = "SQL-backend error";
1420 1.1 lukem e = NULL;
1421 1.1 lukem goto done;
1422 1.1 lukem }
1423 1.1 lukem
1424 1.1 lukem SQLFreeStmt( sth, SQL_DROP );
1425 1.1 lukem
1426 1.1 lukem for ( at = op->ora_e->e_attrs; at != NULL; at = at->a_next ) {
1427 1.1 lukem Debug( LDAP_DEBUG_TRACE, " backsql_add(): "
1428 1.1 lukem "adding attribute \"%s\"\n",
1429 1.1 lukem at->a_desc->ad_cname.bv_val, 0, 0 );
1430 1.1 lukem
1431 1.1 lukem /*
1432 1.1 lukem * Skip:
1433 1.1 lukem * - the first occurrence of objectClass, which is used
1434 1.1 lukem * to determine how to build the SQL entry (FIXME ?!?)
1435 1.1 lukem * - operational attributes
1436 1.1 lukem * - empty attributes (FIXME ?!?)
1437 1.1 lukem */
1438 1.1 lukem if ( backsql_attr_skip( at->a_desc, at->a_vals ) ) {
1439 1.1 lukem continue;
1440 1.1 lukem }
1441 1.1 lukem
1442 1.1 lukem if ( at->a_desc == slap_schema.si_ad_objectClass ) {
1443 1.1 lukem at_objectClass = at;
1444 1.1 lukem continue;
1445 1.1 lukem }
1446 1.1 lukem
1447 1.1 lukem rs->sr_err = backsql_add_attr( op, rs, dbh, oc, at, new_keyval );
1448 1.1 lukem if ( rs->sr_err != LDAP_SUCCESS ) {
1449 1.1 lukem e = op->ora_e;
1450 1.1 lukem goto done;
1451 1.1 lukem }
1452 1.1 lukem }
1453 1.1 lukem
1454 1.1 lukem if ( at_objectClass ) {
1455 1.1 lukem rs->sr_err = backsql_add_attr( op, rs, dbh, oc,
1456 1.1 lukem at_objectClass, new_keyval );
1457 1.1 lukem if ( rs->sr_err != LDAP_SUCCESS ) {
1458 1.1 lukem e = op->ora_e;
1459 1.1 lukem goto done;
1460 1.1 lukem }
1461 1.1 lukem }
1462 1.1 lukem
1463 1.1 lukem done:;
1464 1.1 lukem /*
1465 1.1 lukem * Commit only if all operations succeed
1466 1.1 lukem */
1467 1.1 lukem if ( sth != SQL_NULL_HSTMT ) {
1468 1.1 lukem SQLUSMALLINT CompletionType = SQL_ROLLBACK;
1469 1.1 lukem
1470 1.1 lukem if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
1471 1.1 lukem assert( e == NULL );
1472 1.1 lukem CompletionType = SQL_COMMIT;
1473 1.1 lukem }
1474 1.1 lukem
1475 1.1 lukem SQLTransact( SQL_NULL_HENV, dbh, CompletionType );
1476 1.1 lukem }
1477 1.1 lukem
1478 1.1 lukem /*
1479 1.1 lukem * FIXME: NOOP does not work for add -- it works for all
1480 1.1 lukem * the other operations, and I don't get the reason :(
1481 1.1 lukem *
1482 1.1 lukem * hint: there might be some autocommit in Postgres
1483 1.1 lukem * so that when the unique id of the key table is
1484 1.1 lukem * automatically increased, there's no rollback.
1485 1.1 lukem * We might implement a "rollback" procedure consisting
1486 1.1 lukem * in deleting that row.
1487 1.1 lukem */
1488 1.1 lukem
1489 1.1 lukem if ( e != NULL ) {
1490 1.1 lukem int disclose = 1;
1491 1.1 lukem
1492 1.1 lukem if ( e == op->ora_e && !ACL_GRANT( mask, ACL_DISCLOSE ) ) {
1493 1.1 lukem /* mask already collected */
1494 1.1 lukem disclose = 0;
1495 1.1 lukem
1496 1.1 lukem } else if ( e == &p && !access_allowed( op, &p,
1497 1.1 lukem slap_schema.si_ad_entry, NULL,
1498 1.1 lukem ACL_DISCLOSE, NULL ) )
1499 1.1 lukem {
1500 1.1 lukem disclose = 0;
1501 1.1 lukem }
1502 1.1 lukem
1503 1.1 lukem if ( disclose == 0 ) {
1504 1.1 lukem rs->sr_err = LDAP_NO_SUCH_OBJECT;
1505 1.1 lukem rs->sr_text = NULL;
1506 1.1 lukem rs->sr_matched = NULL;
1507 1.1 lukem if ( rs->sr_ref ) {
1508 1.1 lukem ber_bvarray_free( rs->sr_ref );
1509 1.1 lukem rs->sr_ref = NULL;
1510 1.1 lukem }
1511 1.1 lukem }
1512 1.1 lukem }
1513 1.1 lukem
1514 1.1 lukem if ( op->o_noop && rs->sr_err == LDAP_SUCCESS ) {
1515 1.1 lukem rs->sr_err = LDAP_X_NO_OPERATION;
1516 1.1 lukem }
1517 1.1 lukem
1518 1.1 lukem send_ldap_result( op, rs );
1519 1.1 lukem slap_graduate_commit_csn( op );
1520 1.1 lukem
1521 1.1 lukem if ( !BER_BVISNULL( &realdn )
1522 1.1 lukem && realdn.bv_val != op->ora_e->e_name.bv_val )
1523 1.1 lukem {
1524 1.1 lukem ch_free( realdn.bv_val );
1525 1.1 lukem }
1526 1.1 lukem
1527 1.1 lukem if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
1528 1.1 lukem (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
1529 1.1 lukem }
1530 1.1 lukem
1531 1.1 lukem if ( !BER_BVISNULL( &p.e_nname ) ) {
1532 1.1 lukem backsql_entry_clean( op, &p );
1533 1.1 lukem }
1534 1.1 lukem
1535 1.1 lukem Debug( LDAP_DEBUG_TRACE, "<==backsql_add(\"%s\"): %d \"%s\"\n",
1536 1.1 lukem op->ora_e->e_name.bv_val,
1537 1.1 lukem rs->sr_err,
1538 1.1 lukem rs->sr_text ? rs->sr_text : "" );
1539 1.1 lukem
1540 1.1 lukem rs->sr_text = NULL;
1541 1.1 lukem rs->sr_matched = NULL;
1542 1.1 lukem if ( rs->sr_ref ) {
1543 1.1 lukem ber_bvarray_free( rs->sr_ref );
1544 1.1 lukem rs->sr_ref = NULL;
1545 1.1 lukem }
1546 1.1 lukem
1547 1.1 lukem return rs->sr_err;
1548 1.1 lukem }
1549 1.1 lukem
1550