2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2005 The OpenLDAP Foundation.
5 * Portions Copyright 1999 Dmitry Kovalev.
6 * Portions Copyright 2002 Pierangelo Masarati.
7 * Portions Copyright 2004 Mark Adamson.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
14 * A copy of this license is available in the file LICENSE in the
15 * top-level directory of the distribution or, alternatively, at
16 * <http://www.OpenLDAP.org/license.html>.
19 * This work was initially developed by Dmitry Kovalev for inclusion
20 * by OpenLDAP Software. Additional significant contributors include
21 * Pierangelo Masarati and Mark Adamson.
28 #include <sys/types.h>
29 #include "ac/string.h"
32 #include "proto-sql.h"
34 #ifdef BACKSQL_SYNCPROV
36 #endif /* BACKSQL_SYNCPROV */
40 * - null values (e.g. delete modification)
41 * - single occurrence of objectClass, because it is already used
42 * to determine how to build the SQL entry
43 * - operational attributes
46 #define backsql_opattr_skip(ad) \
47 (is_at_operational( (ad)->ad_type ) && (ad) != slap_schema.si_ad_ref )
48 #define backsql_attr_skip(ad, vals) \
50 ( (ad) == slap_schema.si_ad_objectClass \
51 && (vals) && BER_BVISNULL( &((vals)[ 1 ]) ) ) \
52 || backsql_opattr_skip( (ad) ) \
53 || ( (vals) && BER_BVISNULL( &((vals)[ 0 ]) ) ) \
57 backsql_modify_delete_all_values(
61 backsql_entryID *e_id,
62 backsql_at_map_rec *at )
64 backsql_info *bi = (backsql_info *)op->o_bd->be_private;
66 SQLHSTMT asth = SQL_NULL_HSTMT;
70 if ( at->bam_delete_proc == NULL ) {
71 Debug( LDAP_DEBUG_TRACE,
72 " backsql_modify_delete_all_values(): "
73 "missing attribute value delete procedure "
75 at->bam_ad->ad_cname.bv_val, 0, 0 );
76 if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
77 rs->sr_text = "SQL-backend error";
78 return rs->sr_err = LDAP_OTHER;
84 rc = backsql_Prepare( dbh, &asth, at->bam_query, 0 );
85 if ( rc != SQL_SUCCESS ) {
86 Debug( LDAP_DEBUG_TRACE,
87 " backsql_modify_delete_all_values(): "
88 "error preparing attribute value select query "
90 at->bam_query, 0, 0 );
91 backsql_PrintErrors( bi->sql_db_env, dbh,
94 rs->sr_text = "SQL-backend error";
95 return rs->sr_err = LDAP_OTHER;
98 rc = backsql_BindParamID( asth, 1, SQL_PARAM_INPUT, &e_id->eid_keyval );
99 if ( rc != SQL_SUCCESS ) {
100 Debug( LDAP_DEBUG_TRACE,
101 " backsql_modify_delete_all_values(): "
102 "error binding key value parameter "
103 "to attribute value select query\n",
105 backsql_PrintErrors( bi->sql_db_env, dbh,
107 SQLFreeStmt( asth, SQL_DROP );
109 rs->sr_text = "SQL-backend error";
110 return rs->sr_err = LDAP_OTHER;
113 rc = SQLExecute( asth );
114 if ( !BACKSQL_SUCCESS( rc ) ) {
115 Debug( LDAP_DEBUG_TRACE,
116 " backsql_modify_delete_all_values(): "
117 "error executing attribute value select query\n",
119 backsql_PrintErrors( bi->sql_db_env, dbh,
121 SQLFreeStmt( asth, SQL_DROP );
123 rs->sr_text = "SQL-backend error";
124 return rs->sr_err = LDAP_OTHER;
127 backsql_BindRowAsStrings( asth, &row );
128 for ( rc = SQLFetch( asth );
129 BACKSQL_SUCCESS( rc );
130 rc = SQLFetch( asth ) )
133 /* first parameter no, parameter order */
134 SQLUSMALLINT pno, po;
135 /* procedure return code */
136 int prc = LDAP_SUCCESS;
138 for ( i = 0; i < row.ncols; i++ ) {
139 SQLHSTMT sth = SQL_NULL_HSTMT;
142 rc = backsql_Prepare( dbh, &sth, at->bam_delete_proc, 0 );
143 if ( rc != SQL_SUCCESS ) {
144 Debug( LDAP_DEBUG_TRACE,
145 " backsql_modify_delete_all_values(): "
146 "error preparing attribute value "
149 at->bam_delete_proc, 0, 0 );
150 backsql_PrintErrors( bi->sql_db_env, dbh,
153 rs->sr_text = "SQL-backend error";
154 return rs->sr_err = LDAP_OTHER;
157 if ( BACKSQL_IS_DEL( at->bam_expect_return ) ) {
159 rc = backsql_BindParamInt( sth, 1,
160 SQL_PARAM_OUTPUT, &prc );
161 if ( rc != SQL_SUCCESS ) {
162 Debug( LDAP_DEBUG_TRACE,
163 " backsql_modify_delete_all_values(): "
164 "error binding output parameter for %s[%d]\n",
165 at->bam_ad->ad_cname.bv_val, i, 0 );
166 backsql_PrintErrors( bi->sql_db_env, dbh,
168 SQLFreeStmt( sth, SQL_DROP );
170 rs->sr_text = "SQL-backend error";
171 return rs->sr_err = LDAP_OTHER;
177 po = ( BACKSQL_IS_DEL( at->bam_param_order ) ) > 0;
178 rc = backsql_BindParamID( sth, pno + 1 + po,
179 SQL_PARAM_INPUT, &e_id->eid_keyval );
180 if ( rc != SQL_SUCCESS ) {
181 Debug( LDAP_DEBUG_TRACE,
182 " backsql_modify_delete_all_values(): "
183 "error binding keyval parameter for %s[%d]\n",
184 at->bam_ad->ad_cname.bv_val, i, 0 );
185 backsql_PrintErrors( bi->sql_db_env, dbh,
187 SQLFreeStmt( sth, SQL_DROP );
189 rs->sr_text = "SQL-backend error";
190 return rs->sr_err = LDAP_OTHER;
192 #ifdef BACKSQL_ARBITRARY_KEY
193 Debug( LDAP_DEBUG_TRACE,
194 " backsql_modify_delete_all_values() "
196 pno + 1 + po, e_id->eid_keyval.bv_val, 0 );
197 #else /* ! BACKSQL_ARBITRARY_KEY */
198 Debug( LDAP_DEBUG_TRACE,
199 " backsql_modify_delete_all_values() "
201 pno + 1 + po, e_id->eid_keyval, 0 );
202 #endif /* ! BACKSQL_ARBITRARY_KEY */
205 * check for syntax needed here
206 * maybe need binary bind?
208 col_len = strlen( row.cols[ i ] );
209 rc = backsql_BindParamStr( sth, pno + 2 - po,
210 SQL_PARAM_INPUT, row.cols[ i ], col_len );
211 if ( rc != SQL_SUCCESS ) {
212 Debug( LDAP_DEBUG_TRACE,
213 " backsql_modify_delete_all_values(): "
214 "error binding value parameter for %s[%d]\n",
215 at->bam_ad->ad_cname.bv_val, i, 0 );
216 backsql_PrintErrors( bi->sql_db_env, dbh,
218 SQLFreeStmt( sth, SQL_DROP );
220 rs->sr_text = "SQL-backend error";
221 return rs->sr_err = LDAP_OTHER;
224 Debug( LDAP_DEBUG_TRACE,
225 " backsql_modify_delete_all_values(): "
226 "arg%d=%s; executing \"%s\"\n",
227 pno + 2 - po, row.cols[ i ],
228 at->bam_delete_proc );
229 rc = SQLExecute( sth );
230 if ( rc == SQL_SUCCESS && prc == LDAP_SUCCESS ) {
231 rs->sr_err = LDAP_SUCCESS;
234 Debug( LDAP_DEBUG_TRACE,
235 " backsql_modify_delete_all_values(): "
237 "execution failed (rc=%d, prc=%d)\n",
239 if ( prc != LDAP_SUCCESS ) {
240 /* SQL procedure executed fine
241 * but returned an error */
242 rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
245 backsql_PrintErrors( bi->sql_db_env, dbh,
247 rs->sr_err = LDAP_OTHER;
249 rs->sr_text = op->o_req_dn.bv_val;
250 SQLFreeStmt( sth, SQL_DROP );
253 SQLFreeStmt( sth, SQL_DROP );
256 backsql_FreeRow( &row );
257 SQLFreeStmt( asth, SQL_DROP );
263 backsql_modify_internal(
267 backsql_oc_map_rec *oc,
268 backsql_entryID *e_id,
269 Modifications *modlist )
271 backsql_info *bi = (backsql_info*)op->o_bd->be_private;
273 SQLHSTMT sth = SQL_NULL_HSTMT;
276 Debug( LDAP_DEBUG_TRACE, "==>backsql_modify_internal(): "
277 "traversing modifications list\n", 0, 0, 0 );
279 for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
280 AttributeDescription *ad;
282 static char *sm_ops[] = { "add", "delete", "replace", "increment", NULL };
286 /* NOTE: some day we'll have to pass
287 * the normalized values as well */
288 BerVarray sm_nvalues;
290 backsql_at_map_rec *at = NULL;
291 struct berval *at_val;
293 /* first parameter position, parameter order */
294 SQLUSMALLINT pno, po;
295 /* procedure return code */
296 int prc = LDAP_SUCCESS;
298 ad = ml->sml_mod.sm_desc;
299 sm_op = ( ml->sml_mod.sm_op & LDAP_MOD_OP );
300 sm_values = ml->sml_mod.sm_values;
302 sm_nvalues = ml->sml_mod.sm_nvalues;
305 Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
306 "modifying attribute \"%s\" (%s) according to "
307 "mappings for objectClass \"%s\"\n",
308 ad->ad_cname.bv_val, sm_ops[ sm_op ], BACKSQL_OC_NAME( oc ) );
310 if ( backsql_attr_skip( ad, sm_values ) ) {
314 at = backsql_ad2at( oc, ad );
316 Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
317 "attribute \"%s\" is not registered "
318 "in objectClass \"%s\"\n",
319 ad->ad_cname.bv_val, BACKSQL_OC_NAME( oc ), 0 );
321 if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
322 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
323 rs->sr_text = "operation not permitted "
324 "within namingContext";
332 case LDAP_MOD_REPLACE: {
333 Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
334 "replacing values for attribute \"%s\"\n",
335 at->bam_ad->ad_cname.bv_val, 0, 0 );
337 if ( at->bam_add_proc == NULL ) {
338 Debug( LDAP_DEBUG_TRACE,
339 " backsql_modify_internal(): "
340 "add procedure is not defined "
341 "for attribute \"%s\" "
342 "- unable to perform replacements\n",
343 at->bam_ad->ad_cname.bv_val, 0, 0 );
345 if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
346 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
347 rs->sr_text = "operation not permitted "
348 "within namingContext";
355 if ( at->bam_delete_proc == NULL ) {
356 if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
357 Debug( LDAP_DEBUG_TRACE,
358 " backsql_modify_internal(): "
359 "delete procedure is not defined "
360 "for attribute \"%s\"\n",
361 at->bam_ad->ad_cname.bv_val, 0, 0 );
363 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
364 rs->sr_text = "operation not permitted "
365 "within namingContext";
369 Debug( LDAP_DEBUG_TRACE,
370 " backsql_modify_internal(): "
371 "delete procedure is not defined "
372 "for attribute \"%s\" "
374 at->bam_ad->ad_cname.bv_val, 0, 0 );
380 rs->sr_err = backsql_modify_delete_all_values( op, rs, dbh, e_id, at );
381 if ( rs->sr_err != LDAP_SUCCESS ) {
385 /* LDAP_MOD_DELETE gets here if all values must be deleted */
386 if ( sm_op == LDAP_MOD_DELETE ) {
392 * PASSTHROUGH - to add new attributes -- do NOT add break
395 /* case SLAP_MOD_SOFTADD: */
397 if ( at->bam_add_proc == NULL ) {
398 Debug( LDAP_DEBUG_TRACE,
399 " backsql_modify_internal(): "
400 "add procedure is not defined "
401 "for attribute \"%s\"\n",
402 at->bam_ad->ad_cname.bv_val, 0, 0 );
404 if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
405 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
406 rs->sr_text = "operation not permitted "
407 "within namingContext";
414 Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
415 "adding new values for attribute \"%s\"\n",
416 at->bam_ad->ad_cname.bv_val, 0, 0 );
418 /* can't add a NULL val array */
419 assert( sm_values != NULL );
421 for ( i = 0, at_val = sm_values;
422 !BER_BVISNULL( at_val );
425 rc = backsql_Prepare( dbh, &sth, at->bam_add_proc, 0 );
426 if ( rc != SQL_SUCCESS ) {
427 Debug( LDAP_DEBUG_TRACE,
428 " backsql_modify_internal(): "
429 "error preparing add query\n",
431 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
433 rs->sr_err = LDAP_OTHER;
434 rs->sr_text = "SQL-backend error";
438 if ( BACKSQL_IS_ADD( at->bam_expect_return ) ) {
440 rc = backsql_BindParamInt( sth, 1,
441 SQL_PARAM_OUTPUT, &prc );
442 if ( rc != SQL_SUCCESS ) {
443 Debug( LDAP_DEBUG_TRACE,
444 " backsql_modify_internal(): "
445 "error binding output parameter for %s[%d]\n",
446 at->bam_ad->ad_cname.bv_val, i, 0 );
447 backsql_PrintErrors( bi->sql_db_env, dbh,
449 SQLFreeStmt( sth, SQL_DROP );
451 rs->sr_text = "SQL-backend error";
452 rs->sr_err = LDAP_OTHER;
459 po = ( BACKSQL_IS_ADD( at->bam_param_order ) ) > 0;
460 rc = backsql_BindParamID( sth, pno + 1 + po,
461 SQL_PARAM_INPUT, &e_id->eid_keyval );
462 if ( rc != SQL_SUCCESS ) {
463 Debug( LDAP_DEBUG_TRACE,
464 " backsql_modify_internal(): "
465 "error binding keyval parameter for %s[%d]\n",
466 at->bam_ad->ad_cname.bv_val, i, 0 );
467 backsql_PrintErrors( bi->sql_db_env, dbh,
469 SQLFreeStmt( sth, SQL_DROP );
471 rs->sr_text = "SQL-backend error";
472 rs->sr_err = LDAP_OTHER;
475 #ifdef BACKSQL_ARBITRARY_KEY
476 Debug( LDAP_DEBUG_TRACE,
477 " backsql_modify_internal(): "
479 pno + 1 + po, e_id->eid_keyval.bv_val, 0 );
480 #else /* ! BACKSQL_ARBITRARY_KEY */
481 Debug( LDAP_DEBUG_TRACE,
482 " backsql_modify_internal(): "
484 pno + 1 + po, e_id->eid_keyval, 0 );
485 #endif /* ! BACKSQL_ARBITRARY_KEY */
488 * check for syntax needed here
489 * maybe need binary bind?
491 rc = backsql_BindParamBerVal( sth, pno + 2 - po,
492 SQL_PARAM_INPUT, at_val );
493 if ( rc != SQL_SUCCESS ) {
494 Debug( LDAP_DEBUG_TRACE,
495 " backsql_modify_internal(): "
496 "error binding value parameter for %s[%d]\n",
497 at->bam_ad->ad_cname.bv_val, i, 0 );
498 backsql_PrintErrors( bi->sql_db_env, dbh,
500 SQLFreeStmt( sth, SQL_DROP );
502 rs->sr_text = "SQL-backend error";
503 rs->sr_err = LDAP_OTHER;
506 Debug( LDAP_DEBUG_TRACE,
507 " backsql_modify_internal(): "
508 "arg%d=\"%s\"; executing \"%s\"\n",
509 pno + 2 - po, at_val->bv_val,
512 rc = SQLExecute( sth );
513 if ( rc != SQL_SUCCESS ) {
514 Debug( LDAP_DEBUG_TRACE,
515 " backsql_modify_internal(): "
516 "add_proc execution failed\n",
518 backsql_PrintErrors( bi->sql_db_env,
521 SQLFreeStmt( sth, SQL_DROP );
522 rs->sr_err = LDAP_OTHER;
523 rs->sr_text = "SQL-backend error";
526 SQLFreeStmt( sth, SQL_DROP );
530 case LDAP_MOD_DELETE:
531 if ( at->bam_delete_proc == NULL ) {
532 Debug( LDAP_DEBUG_TRACE,
533 " backsql_modify_internal(): "
534 "delete procedure is not defined "
535 "for attribute \"%s\"\n",
536 at->bam_ad->ad_cname.bv_val, 0, 0 );
538 if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
539 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
540 rs->sr_text = "operation not permitted "
541 "within namingContext";
548 if ( sm_values == NULL ) {
549 Debug( LDAP_DEBUG_TRACE,
550 " backsql_modify_internal(): "
551 "no values given to delete "
552 "for attribute \"%s\" "
553 "-- deleting all values\n",
554 at->bam_ad->ad_cname.bv_val, 0, 0 );
558 Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
559 "deleting values for attribute \"%s\"\n",
560 at->bam_ad->ad_cname.bv_val, 0, 0 );
562 for ( i = 0, at_val = sm_values;
563 !BER_BVISNULL( at_val );
567 rc = backsql_Prepare( dbh, &sth, at->bam_delete_proc, 0 );
568 if ( rc != SQL_SUCCESS ) {
569 Debug( LDAP_DEBUG_TRACE,
570 " backsql_modify_internal(): "
571 "error preparing delete query\n",
573 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
575 rs->sr_err = LDAP_OTHER;
576 rs->sr_text = "SQL-backend error";
580 if ( BACKSQL_IS_DEL( at->bam_expect_return ) ) {
582 rc = backsql_BindParamInt( sth, 1,
583 SQL_PARAM_OUTPUT, &prc );
584 if ( rc != SQL_SUCCESS ) {
585 Debug( LDAP_DEBUG_TRACE,
586 " backsql_modify_internal(): "
587 "error binding output parameter for %s[%d]\n",
588 at->bam_ad->ad_cname.bv_val, i, 0 );
589 backsql_PrintErrors( bi->sql_db_env, dbh,
591 SQLFreeStmt( sth, SQL_DROP );
593 rs->sr_text = "SQL-backend error";
594 rs->sr_err = LDAP_OTHER;
601 po = ( BACKSQL_IS_DEL( at->bam_param_order ) ) > 0;
602 rc = backsql_BindParamID( sth, pno + 1 + po,
603 SQL_PARAM_INPUT, &e_id->eid_keyval );
604 if ( rc != SQL_SUCCESS ) {
605 Debug( LDAP_DEBUG_TRACE,
606 " backsql_modify_internal(): "
607 "error binding keyval parameter for %s[%d]\n",
608 at->bam_ad->ad_cname.bv_val, i, 0 );
609 backsql_PrintErrors( bi->sql_db_env, dbh,
611 SQLFreeStmt( sth, SQL_DROP );
613 rs->sr_text = "SQL-backend error";
614 rs->sr_err = LDAP_OTHER;
617 #ifdef BACKSQL_ARBITRARY_KEY
618 Debug( LDAP_DEBUG_TRACE,
619 " backsql_modify_internal(): "
621 pno + 1 + po, e_id->eid_keyval.bv_val, 0 );
622 #else /* ! BACKSQL_ARBITRARY_KEY */
623 Debug( LDAP_DEBUG_TRACE,
624 " backsql_modify_internal(): "
626 pno + 1 + po, e_id->eid_keyval, 0 );
627 #endif /* ! BACKSQL_ARBITRARY_KEY */
630 * check for syntax needed here
631 * maybe need binary bind?
633 rc = backsql_BindParamBerVal( sth, pno + 2 - po,
634 SQL_PARAM_INPUT, at_val );
635 if ( rc != SQL_SUCCESS ) {
636 Debug( LDAP_DEBUG_TRACE,
637 " backsql_modify_internal(): "
638 "error binding value parameter for %s[%d]\n",
639 at->bam_ad->ad_cname.bv_val, i, 0 );
640 backsql_PrintErrors( bi->sql_db_env, dbh,
642 SQLFreeStmt( sth, SQL_DROP );
644 rs->sr_text = "SQL-backend error";
645 rs->sr_err = LDAP_OTHER;
649 Debug( LDAP_DEBUG_TRACE,
650 " backsql_modify_internal(): "
651 "executing \"%s\"\n",
652 at->bam_delete_proc, 0, 0 );
653 rc = SQLExecute( sth );
654 if ( rc == SQL_SUCCESS && prc == LDAP_SUCCESS )
656 rs->sr_err = LDAP_SUCCESS;
659 Debug( LDAP_DEBUG_TRACE,
660 " backsql_modify_internal(): "
661 "delete_proc execution "
662 "failed (rc=%d, prc=%d)\n",
665 if ( prc != LDAP_SUCCESS ) {
666 /* SQL procedure executed fine
667 * but returned an error */
668 rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
669 rs->sr_text = at->bam_ad->ad_cname.bv_val;
673 backsql_PrintErrors( bi->sql_db_env,
675 SQLFreeStmt( sth, SQL_DROP );
676 rs->sr_err = LDAP_OTHER;
677 rs->sr_text = at->bam_ad->ad_cname.bv_val;
681 SQLFreeStmt( sth, SQL_DROP );
685 case LDAP_MOD_INCREMENT:
686 Debug( LDAP_DEBUG_TRACE, " backsql_modify_internal(): "
687 "increment not supported yet\n", 0, 0, 0 );
688 if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
689 rs->sr_err = LDAP_OTHER;
690 rs->sr_text = "SQL-backend error";
698 Debug( LDAP_DEBUG_TRACE, "<==backsql_modify_internal(): %d%s%s\n",
700 rs->sr_text ? ": " : "",
701 rs->sr_text ? rs->sr_text : "" );
704 * FIXME: should fail in case one change fails?
714 backsql_oc_map_rec *oc,
716 unsigned long new_keyval )
718 backsql_info *bi = (backsql_info*)op->o_bd->be_private;
719 backsql_at_map_rec *at_rec = NULL;
720 struct berval *at_val;
723 SQLUSMALLINT currpos;
724 SQLHSTMT sth = SQL_NULL_HSTMT;
726 at_rec = backsql_ad2at( oc, at->a_desc );
728 if ( at_rec == NULL ) {
729 Debug( LDAP_DEBUG_TRACE, " backsql_add_attr(\"%s\"): "
730 "attribute \"%s\" is not registered "
731 "in objectclass \"%s\"\n",
732 op->ora_e->e_name.bv_val,
733 at->a_desc->ad_cname.bv_val,
734 BACKSQL_OC_NAME( oc ) );
736 if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
737 rs->sr_text = "operation not permitted "
738 "within namingContext";
739 return rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
745 if ( at_rec->bam_add_proc == NULL ) {
746 Debug( LDAP_DEBUG_TRACE, " backsql_add_attr(\"%s\"): "
747 "add procedure is not defined "
748 "for attribute \"%s\" "
749 "of structuralObjectClass \"%s\"\n",
750 op->ora_e->e_name.bv_val,
751 at->a_desc->ad_cname.bv_val,
752 BACKSQL_OC_NAME( oc ) );
754 if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
755 rs->sr_text = "operation not permitted "
756 "within namingContext";
757 return rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
763 for ( i = 0, at_val = &at->a_vals[ i ];
764 !BER_BVISNULL( at_val );
765 i++, at_val = &at->a_vals[ i ] )
767 /* procedure return code */
768 int prc = LDAP_SUCCESS;
769 /* first parameter #, parameter order */
770 SQLUSMALLINT pno, po;
771 char logbuf[] = "val[18446744073709551615UL], id=18446744073709551615UL";
774 * Do not deal with the objectClass that is used
777 if ( at->a_desc == slap_schema.si_ad_objectClass ) {
778 if ( dn_match( at_val, &oc->bom_oc->soc_cname ) )
784 rc = backsql_Prepare( dbh, &sth, at_rec->bam_add_proc, 0 );
785 if ( rc != SQL_SUCCESS ) {
786 rs->sr_text = "SQL-backend error";
787 return rs->sr_err = LDAP_OTHER;
790 if ( BACKSQL_IS_ADD( at_rec->bam_expect_return ) ) {
792 rc = backsql_BindParamInt( sth, 1, SQL_PARAM_OUTPUT, &prc );
793 if ( rc != SQL_SUCCESS ) {
794 Debug( LDAP_DEBUG_TRACE,
795 " backsql_add_attr(): "
796 "error binding output parameter for %s[%d]\n",
797 at_rec->bam_ad->ad_cname.bv_val, i, 0 );
798 backsql_PrintErrors( bi->sql_db_env, dbh,
800 SQLFreeStmt( sth, SQL_DROP );
802 rs->sr_text = "SQL-backend error";
803 return rs->sr_err = LDAP_OTHER;
810 po = ( BACKSQL_IS_ADD( at_rec->bam_param_order ) ) > 0;
811 currpos = pno + 1 + po;
812 rc = backsql_BindParamInt( sth, currpos,
813 SQL_PARAM_INPUT, &new_keyval );
814 if ( rc != SQL_SUCCESS ) {
815 Debug( LDAP_DEBUG_TRACE,
816 " backsql_add_attr(): "
817 "error binding keyval parameter for %s[%d]\n",
818 at_rec->bam_ad->ad_cname.bv_val, i, 0 );
819 backsql_PrintErrors( bi->sql_db_env, dbh,
821 SQLFreeStmt( sth, SQL_DROP );
823 rs->sr_text = "SQL-backend error";
824 return rs->sr_err = LDAP_OTHER;
827 currpos = pno + 2 - po;
830 * check for syntax needed here
831 * maybe need binary bind?
834 rc = backsql_BindParamBerVal( sth, currpos, SQL_PARAM_INPUT, at_val );
835 if ( rc != SQL_SUCCESS ) {
836 Debug( LDAP_DEBUG_TRACE,
837 " backsql_add_attr(): "
838 "error binding value parameter for %s[%d]\n",
839 at_rec->bam_ad->ad_cname.bv_val, i, 0 );
840 backsql_PrintErrors( bi->sql_db_env, dbh,
842 SQLFreeStmt( sth, SQL_DROP );
844 rs->sr_text = "SQL-backend error";
845 return rs->sr_err = LDAP_OTHER;
849 snprintf( logbuf, sizeof( logbuf ), "val[%lu], id=%lu",
851 Debug( LDAP_DEBUG_TRACE, " backsql_add_attr(\"%s\"): "
852 "executing \"%s\" %s\n",
853 op->ora_e->e_name.bv_val,
854 at_rec->bam_add_proc, logbuf );
856 rc = SQLExecute( sth );
857 if ( rc == SQL_SUCCESS && prc == LDAP_SUCCESS ) {
858 rs->sr_err = LDAP_SUCCESS;
861 Debug( LDAP_DEBUG_TRACE,
862 " backsql_add_attr(\"%s\"): "
863 "add_proc execution failed (rc=%d, prc=%d)\n",
864 op->ora_e->e_name.bv_val, rc, prc );
865 if ( prc != LDAP_SUCCESS ) {
866 /* SQL procedure executed fine
867 * but returned an error */
868 rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
869 rs->sr_text = op->ora_e->e_name.bv_val;
870 SQLFreeStmt( sth, SQL_DROP );
874 backsql_PrintErrors( bi->sql_db_env, dbh,
876 rs->sr_err = LDAP_OTHER;
877 rs->sr_text = op->ora_e->e_name.bv_val;
878 SQLFreeStmt( sth, SQL_DROP );
882 SQLFreeStmt( sth, SQL_DROP );
889 backsql_add( Operation *op, SlapReply *rs )
891 backsql_info *bi = (backsql_info*)op->o_bd->be_private;
892 SQLHDBC dbh = SQL_NULL_HDBC;
893 SQLHSTMT sth = SQL_NULL_HSTMT;
894 unsigned long new_keyval = 0;
896 backsql_oc_map_rec *oc = NULL;
897 backsql_srch_info bsi = { 0 };
898 Entry p = { 0 }, *e = NULL;
900 *at_objectClass = NULL;
901 struct berval scname = BER_BVNULL;
903 struct berval realdn = BER_BVNULL;
907 #ifdef BACKSQL_SYNCPROV
909 * NOTE: fake successful result to force contextCSN to be bumped up
912 char buf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
913 struct berval csn = BER_BVNULL;
915 slap_get_csn( op, buf, sizeof( buf ), &csn, 1 );
917 rs->sr_err = LDAP_SUCCESS;
918 send_ldap_result( op, rs );
920 slap_graduate_commit_csn( op );
924 #endif /* BACKSQL_SYNCPROV */
926 Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n",
927 op->ora_e->e_name.bv_val, 0, 0 );
930 if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
931 char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' };
933 rs->sr_err = entry_schema_check( op->o_bd, op->ora_e, NULL, 0,
934 &rs->sr_text, textbuf, sizeof( textbuf ) );
935 if ( rs->sr_err != LDAP_SUCCESS ) {
936 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
937 "entry failed schema check -- aborting\n",
938 op->ora_e->e_name.bv_val, 0, 0 );
944 /* search structuralObjectClass */
945 for ( at = op->ora_e->e_attrs; at != NULL; at = at->a_next ) {
946 if ( at->a_desc == slap_schema.si_ad_structuralObjectClass ) {
951 /* there must exist */
953 char buf[ SLAP_TEXT_BUFLEN ];
956 /* search structuralObjectClass */
957 for ( at = op->ora_e->e_attrs; at != NULL; at = at->a_next ) {
958 if ( at->a_desc == slap_schema.si_ad_objectClass ) {
964 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
966 op->ora_e->e_name.bv_val, 0, 0 );
967 rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION;
972 rs->sr_err = structural_class( at->a_vals, &scname, NULL,
973 &text, buf, sizeof( buf ) );
974 if ( rs->sr_err != LDAP_SUCCESS ) {
975 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
977 op->ora_e->e_name.bv_val, text, rs->sr_err );
983 scname = at->a_vals[0];
986 /* I guess we should play with sub/supertypes to find a suitable oc */
987 oc = backsql_name2oc( bi, &scname );
990 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
991 "cannot map structuralObjectClass \"%s\" -- aborting\n",
992 op->ora_e->e_name.bv_val,
994 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
995 rs->sr_text = "operation not permitted within namingContext";
1000 if ( oc->bom_create_proc == NULL ) {
1001 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1002 "create procedure is not defined "
1003 "for structuralObjectClass \"%s\" - aborting\n",
1004 op->ora_e->e_name.bv_val,
1006 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
1007 rs->sr_text = "operation not permitted within namingContext";
1011 } else if ( BACKSQL_CREATE_NEEDS_SELECT( bi )
1012 && oc->bom_create_keyval == NULL ) {
1013 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1014 "create procedure needs select procedure, "
1015 "but none is defined for structuralObjectClass \"%s\" "
1017 op->ora_e->e_name.bv_val,
1019 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
1020 rs->sr_text = "operation not permitted within namingContext";
1025 rs->sr_err = backsql_get_db_conn( op, &dbh );
1026 if ( rs->sr_err != LDAP_SUCCESS ) {
1027 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1028 "could not get connection handle - exiting\n",
1029 op->ora_e->e_name.bv_val, 0, 0 );
1030 rs->sr_text = ( rs->sr_err == LDAP_OTHER )
1031 ? "SQL-backend error" : NULL;
1037 * Check if entry exists
1039 * NOTE: backsql_api_dn2odbc() is called explicitly because
1040 * we need the mucked DN to pass it to the create procedure.
1042 realdn = op->ora_e->e_name;
1043 if ( backsql_api_dn2odbc( op, rs, &realdn ) ) {
1044 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1045 "backsql_api_dn2odbc(\"%s\") failed\n",
1046 op->ora_e->e_name.bv_val, realdn.bv_val, 0 );
1047 rs->sr_err = LDAP_OTHER;
1048 rs->sr_text = "SQL-backend error";
1053 rs->sr_err = backsql_dn2id( op, rs, dbh, &realdn, NULL, 0, 0 );
1054 if ( rs->sr_err == LDAP_SUCCESS ) {
1055 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1057 op->ora_e->e_name.bv_val, 0, 0 );
1058 rs->sr_err = LDAP_ALREADY_EXISTS;
1064 * Get the parent dn and see if the corresponding entry exists.
1066 if ( be_issuffix( op->o_bd, &op->ora_e->e_nname ) ) {
1067 pdn = slap_empty_bv;
1070 dnParent( &op->ora_e->e_nname, &pdn );
1077 rs->sr_err = backsql_init_search( &bsi, &pdn,
1079 SLAP_NO_LIMIT, SLAP_NO_LIMIT,
1080 (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs,
1081 ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
1082 if ( rs->sr_err != LDAP_SUCCESS ) {
1083 Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
1084 "could not retrieve addDN parent "
1085 "\"%s\" ID - %s matched=\"%s\"\n",
1087 rs->sr_err == LDAP_REFERRAL ? "referral" : "no such entry",
1088 rs->sr_matched ? rs->sr_matched : "(null)" );
1093 /* check "children" pseudo-attribute access to parent */
1094 if ( !access_allowed( op, &p, slap_schema.si_ad_children,
1095 NULL, ACL_WADD, NULL ) )
1097 rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
1102 if ( get_assert( op ) &&
1103 ( test_filter( op, op->oq_add.rs_e, get_assertion( op ) )
1104 != LDAP_COMPARE_TRUE ) )
1106 rs->sr_err = LDAP_ASSERTION_FAILED;
1111 if ( !access_allowed_mask( op, op->ora_e,
1112 slap_schema.si_ad_entry,
1113 NULL, ACL_WADD, NULL, &mask ) )
1115 rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
1121 * create_proc is executed; if expect_return is set, then
1122 * an output parameter is bound, which should contain
1123 * the id of the added row; otherwise the procedure
1124 * is expected to return the id as the first column of a select
1126 rc = backsql_Prepare( dbh, &sth, oc->bom_create_proc, 0 );
1127 if ( rc != SQL_SUCCESS ) {
1128 rs->sr_err = LDAP_OTHER;
1129 rs->sr_text = "SQL-backend error";
1135 if ( BACKSQL_IS_ADD( oc->bom_expect_return ) ) {
1136 rc = backsql_BindParamInt( sth, 1, SQL_PARAM_OUTPUT, &new_keyval );
1137 if ( rc != SQL_SUCCESS ) {
1138 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1139 "error binding keyval parameter "
1140 "for objectClass %s\n",
1141 op->ora_e->e_name.bv_val,
1142 oc->bom_oc->soc_cname.bv_val, 0 );
1143 backsql_PrintErrors( bi->sql_db_env, dbh,
1145 SQLFreeStmt( sth, SQL_DROP );
1147 rs->sr_text = "SQL-backend error";
1148 rs->sr_err = LDAP_OTHER;
1155 if ( oc->bom_create_hint ) {
1156 at = attr_find( op->ora_e->e_attrs, oc->bom_create_hint );
1157 if ( at && at->a_vals ) {
1158 backsql_BindParamStr( sth, colnum, SQL_PARAM_INPUT,
1159 at->a_vals[0].bv_val,
1160 at->a_vals[0].bv_len );
1161 Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
1162 "create_proc hint: param = '%s'\n",
1163 at->a_vals[0].bv_val, 0, 0 );
1166 backsql_BindParamStr( sth, colnum, SQL_PARAM_INPUT,
1168 Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
1169 "create_proc hint (%s) not avalable\n",
1170 oc->bom_create_hint->ad_cname.bv_val,
1176 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): executing \"%s\"\n",
1177 op->ora_e->e_name.bv_val, oc->bom_create_proc, 0 );
1178 rc = SQLExecute( sth );
1179 if ( rc != SQL_SUCCESS ) {
1180 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1181 "create_proc execution failed\n",
1182 op->ora_e->e_name.bv_val, 0, 0 );
1183 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
1184 SQLFreeStmt( sth, SQL_DROP );
1185 rs->sr_err = LDAP_OTHER;
1186 rs->sr_text = "SQL-backend error";
1191 /* FIXME: after SQLExecute(), the row is already inserted
1192 * (at least with PostgreSQL and unixODBC); needs investigation */
1194 if ( !BACKSQL_IS_ADD( oc->bom_expect_return ) ) {
1196 SQLINTEGER value_len;
1198 if ( BACKSQL_CREATE_NEEDS_SELECT( bi ) ) {
1199 SQLFreeStmt( sth, SQL_DROP );
1201 rc = backsql_Prepare( dbh, &sth, oc->bom_create_keyval, 0 );
1202 if ( rc != SQL_SUCCESS ) {
1203 rs->sr_err = LDAP_OTHER;
1204 rs->sr_text = "SQL-backend error";
1209 rc = SQLExecute( sth );
1210 if ( rc != SQL_SUCCESS ) {
1211 rs->sr_err = LDAP_OTHER;
1212 rs->sr_text = "SQL-backend error";
1219 * the query to know the id of the inserted entry
1220 * must be embedded in the create procedure
1222 rc = SQLNumResultCols( sth, &ncols );
1223 if ( rc != SQL_SUCCESS ) {
1224 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1225 "create_proc result evaluation failed\n",
1226 op->ora_e->e_name.bv_val, 0, 0 );
1227 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
1228 SQLFreeStmt( sth, SQL_DROP );
1229 rs->sr_err = LDAP_OTHER;
1230 rs->sr_text = "SQL-backend error";
1234 } else if ( ncols != 1 ) {
1235 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1236 "create_proc result is bogus (ncols=%d)\n",
1237 op->ora_e->e_name.bv_val, ncols, 0 );
1238 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
1239 SQLFreeStmt( sth, SQL_DROP );
1240 rs->sr_err = LDAP_OTHER;
1241 rs->sr_text = "SQL-backend error";
1248 SQLCHAR colname[ 64 ];
1249 SQLSMALLINT name_len, col_type, col_scale, col_null;
1253 * FIXME: check whether col_type is compatible,
1254 * if it can be null and so on ...
1256 rc = SQLDescribeCol( sth, (SQLUSMALLINT)1,
1258 (SQLUINTEGER)( sizeof( colname ) - 1 ),
1259 &name_len, &col_type,
1260 &col_prec, &col_scale, &col_null );
1264 rc = SQLBindCol( sth, (SQLUSMALLINT)1, SQL_C_ULONG,
1265 (SQLPOINTER)&new_keyval,
1266 (SQLINTEGER)sizeof( new_keyval ),
1269 rc = SQLFetch( sth );
1271 if ( value_len <= 0 ) {
1272 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1273 "create_proc result is empty?\n",
1274 op->ora_e->e_name.bv_val, 0, 0 );
1275 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc);
1276 SQLFreeStmt( sth, SQL_DROP );
1277 rs->sr_err = LDAP_OTHER;
1278 rs->sr_text = "SQL-backend error";
1284 SQLFreeStmt( sth, SQL_DROP );
1286 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1287 "create_proc returned keyval=%ld\n",
1288 op->ora_e->e_name.bv_val, new_keyval, 0 );
1290 rc = backsql_Prepare( dbh, &sth, bi->sql_insentry_stmt, 0 );
1291 if ( rc != SQL_SUCCESS ) {
1292 rs->sr_err = LDAP_OTHER;
1293 rs->sr_text = "SQL-backend error";
1298 rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &realdn );
1299 if ( rc != SQL_SUCCESS ) {
1300 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1301 "error binding DN parameter for objectClass %s\n",
1302 op->ora_e->e_name.bv_val,
1303 oc->bom_oc->soc_cname.bv_val, 0 );
1304 backsql_PrintErrors( bi->sql_db_env, dbh,
1306 SQLFreeStmt( sth, SQL_DROP );
1308 rs->sr_text = "SQL-backend error";
1309 rs->sr_err = LDAP_OTHER;
1314 rc = backsql_BindParamInt( sth, 2, SQL_PARAM_INPUT, &oc->bom_id );
1315 if ( rc != SQL_SUCCESS ) {
1316 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1317 "error binding objectClass ID parameter "
1318 "for objectClass %s\n",
1319 op->ora_e->e_name.bv_val,
1320 oc->bom_oc->soc_cname.bv_val, 0 );
1321 backsql_PrintErrors( bi->sql_db_env, dbh,
1323 SQLFreeStmt( sth, SQL_DROP );
1325 rs->sr_text = "SQL-backend error";
1326 rs->sr_err = LDAP_OTHER;
1331 rc = backsql_BindParamID( sth, 3, SQL_PARAM_INPUT, &bsi.bsi_base_id.eid_id );
1332 if ( rc != SQL_SUCCESS ) {
1333 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1334 "error binding parent ID parameter "
1335 "for objectClass %s\n",
1336 op->ora_e->e_name.bv_val,
1337 oc->bom_oc->soc_cname.bv_val, 0 );
1338 backsql_PrintErrors( bi->sql_db_env, dbh,
1340 SQLFreeStmt( sth, SQL_DROP );
1342 rs->sr_text = "SQL-backend error";
1343 rs->sr_err = LDAP_OTHER;
1348 rc = backsql_BindParamInt( sth, 4, SQL_PARAM_INPUT, &new_keyval );
1349 if ( rc != SQL_SUCCESS ) {
1350 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1351 "error binding entry ID parameter "
1352 "for objectClass %s\n",
1353 op->ora_e->e_name.bv_val,
1354 oc->bom_oc->soc_cname.bv_val, 0 );
1355 backsql_PrintErrors( bi->sql_db_env, dbh,
1357 SQLFreeStmt( sth, SQL_DROP );
1359 rs->sr_text = "SQL-backend error";
1360 rs->sr_err = LDAP_OTHER;
1365 Debug( LDAP_DEBUG_TRACE, " backsql_add(): executing \"%s\" for dn \"%s\"\n",
1366 bi->sql_insentry_stmt, op->ora_e->e_name.bv_val, 0 );
1367 #ifdef BACKSQL_ARBITRARY_KEY
1368 Debug( LDAP_DEBUG_TRACE, " for oc_map_id=%ld, "
1369 "p_id=%s, keyval=%ld\n",
1370 oc->bom_id, bsi.bsi_base_id.eid_id.bv_val, new_keyval );
1371 #else /* ! BACKSQL_ARBITRARY_KEY */
1372 Debug( LDAP_DEBUG_TRACE, " for oc_map_id=%ld, "
1373 "p_id=%ld, keyval=%ld\n",
1374 oc->bom_id, bsi.bsi_base_id.eid_id, new_keyval );
1375 #endif /* ! BACKSQL_ARBITRARY_KEY */
1376 rc = SQLExecute( sth );
1377 if ( rc != SQL_SUCCESS ) {
1378 Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
1379 "could not insert ldap_entries record\n",
1380 op->ora_e->e_name.bv_val, 0, 0 );
1381 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
1384 * execute delete_proc to delete data added !!!
1386 SQLFreeStmt( sth, SQL_DROP );
1387 rs->sr_err = LDAP_OTHER;
1388 rs->sr_text = "SQL-backend error";
1393 SQLFreeStmt( sth, SQL_DROP );
1395 for ( at = op->ora_e->e_attrs; at != NULL; at = at->a_next ) {
1396 Debug( LDAP_DEBUG_TRACE, " backsql_add(): "
1397 "adding attribute \"%s\"\n",
1398 at->a_desc->ad_cname.bv_val, 0, 0 );
1402 * - the first occurrence of objectClass, which is used
1403 * to determine how to build the SQL entry (FIXME ?!?)
1404 * - operational attributes
1405 * - empty attributes (FIXME ?!?)
1407 if ( backsql_attr_skip( at->a_desc, at->a_vals ) ) {
1411 if ( at->a_desc == slap_schema.si_ad_objectClass ) {
1412 at_objectClass = at;
1416 rs->sr_err = backsql_add_attr( op, rs, dbh, oc, at, new_keyval );
1417 if ( rs->sr_err != LDAP_SUCCESS ) {
1423 if ( at_objectClass ) {
1424 rs->sr_err = backsql_add_attr( op, rs, dbh, oc,
1425 at_objectClass, new_keyval );
1426 if ( rs->sr_err != LDAP_SUCCESS ) {
1434 * Commit only if all operations succeed
1436 if ( sth != SQL_NULL_HSTMT ) {
1437 SQLUSMALLINT CompletionType = SQL_ROLLBACK;
1439 if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
1440 CompletionType = SQL_COMMIT;
1443 SQLTransact( SQL_NULL_HENV, dbh, CompletionType );
1447 * FIXME: NOOP does not work for add -- it works for all
1448 * the other operations, and I don't get the reason :(
1450 * hint: there might be some autocommit in Postgres
1451 * so that when the unique id of the key table is
1452 * automatically increased, there's no rollback.
1453 * We might implement a "rollback" procedure consisting
1454 * in deleting that row.
1457 #ifdef SLAP_ACL_HONOR_DISCLOSE
1461 if ( e == op->ora_e && !ACL_GRANT( mask, ACL_DISCLOSE ) ) {
1462 /* mask already collected */
1465 } else if ( e == &p && !access_allowed( op, &p,
1466 slap_schema.si_ad_entry, NULL,
1467 ACL_DISCLOSE, NULL ) )
1472 if ( disclose == 0 ) {
1473 rs->sr_err = LDAP_NO_SUCH_OBJECT;
1475 rs->sr_matched = NULL;
1477 ber_bvarray_free( rs->sr_ref );
1482 #endif /* SLAP_ACL_HONOR_DISCLOSE */
1484 send_ldap_result( op, rs );
1486 if ( !BER_BVISNULL( &realdn )
1487 && realdn.bv_val != op->ora_e->e_name.bv_val )
1489 ch_free( realdn.bv_val );
1492 if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
1493 (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
1496 if ( !BER_BVISNULL( &p.e_nname ) ) {
1497 backsql_entry_clean( op, &p );
1500 Debug( LDAP_DEBUG_TRACE, "<==backsql_add(\"%s\"): %d \"%s\"\n",
1501 op->ora_e->e_name.bv_val,
1503 rs->sr_text ? rs->sr_text : "" );
1506 rs->sr_matched = NULL;
1508 ber_bvarray_free( rs->sr_ref );