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.
27 #include <sys/types.h>
28 #include "ac/string.h"
32 #include "proto-sql.h"
34 #ifdef BACKSQL_ARBITRARY_KEY
35 struct berval backsql_baseObject_bv = BER_BVC( BACKSQL_BASEOBJECT_IDSTR );
36 #endif /* BACKSQL_ARBITRARY_KEY */
39 backsql_free_entryID( Operation *op, backsql_entryID *id, int freeit )
41 backsql_entryID *next;
47 if ( !BER_BVISNULL( &id->eid_ndn ) ) {
48 if ( !BER_BVISNULL( &id->eid_dn )
49 && id->eid_dn.bv_val != id->eid_ndn.bv_val )
51 op->o_tmpfree( id->eid_dn.bv_val, op->o_tmpmemctx );
52 BER_BVZERO( &id->eid_dn );
55 op->o_tmpfree( id->eid_ndn.bv_val, op->o_tmpmemctx );
56 BER_BVZERO( &id->eid_ndn );
59 #ifdef BACKSQL_ARBITRARY_KEY
60 if ( !BER_BVISNULL( &id->eid_id ) ) {
61 op->o_tmpfree( id->eid_id.bv_val, op->o_tmpmemctx );
62 BER_BVZERO( &id->eid_id );
65 if ( !BER_BVISNULL( &id->eid_keyval ) ) {
66 op->o_tmpfree( id->eid_keyval.bv_val, op->o_tmpmemctx );
67 BER_BVZERO( &id->eid_keyval );
69 #endif /* BACKSQL_ARBITRARY_KEY */
72 op->o_tmpfree( id, op->o_tmpmemctx );
79 * NOTE: the dn must be normalized
91 backsql_info *bi = op->o_bd->be_private;
92 SQLHSTMT sth = SQL_NULL_HSTMT;
96 struct berval realndn = BER_BVNULL;
99 char upperdn[ BACKSQL_MAX_DN_LEN + 1 ];
104 * NOTE: id can be NULL; in this case, the function
105 * simply checks whether the DN can be successfully
106 * turned into an ID, returning LDAP_SUCCESS for
107 * positive cases, or the most appropriate error
110 Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(\"%s\")%s%s\n",
111 ndn->bv_val, id == NULL ? " (no ID expected)" : "",
112 matched ? " matched expected" : "" );
115 /* NOTE: trap inconsistencies */
116 assert( BER_BVISNULL( &id->eid_ndn ) );
119 if ( ndn->bv_len > BACKSQL_MAX_DN_LEN ) {
120 Debug( LDAP_DEBUG_TRACE,
121 " backsql_dn2id(\"%s\"): DN length=%ld "
122 "exceeds max DN length %d:\n",
123 ndn->bv_val, ndn->bv_len, BACKSQL_MAX_DN_LEN );
127 /* return baseObject if available and matches */
128 /* FIXME: if ndn is already mucked, we cannot check this */
129 if ( bi->sql_baseObject != NULL &&
130 dn_match( ndn, &bi->sql_baseObject->e_nname ) )
133 #ifdef BACKSQL_ARBITRARY_KEY
134 ber_dupbv_x( &id->eid_id, &backsql_baseObject_bv,
136 ber_dupbv_x( &id->eid_keyval, &backsql_baseObject_bv,
138 #else /* ! BACKSQL_ARBITRARY_KEY */
139 id->eid_id = BACKSQL_BASEOBJECT_ID;
140 id->eid_keyval = BACKSQL_BASEOBJECT_KEYVAL;
141 #endif /* ! BACKSQL_ARBITRARY_KEY */
142 id->eid_oc_id = BACKSQL_BASEOBJECT_OC;
144 ber_dupbv_x( &id->eid_ndn, &bi->sql_baseObject->e_nname,
146 ber_dupbv_x( &id->eid_dn, &bi->sql_baseObject->e_name,
156 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): id_query \"%s\"\n",
157 ndn->bv_val, bi->sql_id_query, 0 );
158 assert( bi->sql_id_query != NULL );
159 rc = backsql_Prepare( dbh, &sth, bi->sql_id_query, 0 );
160 if ( rc != SQL_SUCCESS ) {
161 Debug( LDAP_DEBUG_TRACE,
162 " backsql_dn2id(\"%s\"): "
163 "error preparing SQL:\n %s",
164 ndn->bv_val, bi->sql_id_query, 0 );
165 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
172 if ( backsql_api_dn2odbc( op, rs, &realndn ) ) {
173 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
174 "backsql_api_dn2odbc(\"%s\") failed\n",
175 ndn->bv_val, realndn.bv_val, 0 );
181 if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
183 * Prepare an upper cased, byte reversed version
184 * that can be searched using indexes
187 for ( i = 0, j = realndn.bv_len - 1; realndn.bv_val[ i ]; i++, j--)
189 upperdn[ i ] = realndn.bv_val[ j ];
192 ldap_pvt_str2upper( upperdn );
194 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
196 ndn->bv_val, upperdn, 0 );
197 ber_str2bv( upperdn, 0, 0, &tbbDN );
200 if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
201 AC_MEMCPY( upperdn, realndn.bv_val, realndn.bv_len + 1 );
202 ldap_pvt_str2upper( upperdn );
203 Debug( LDAP_DEBUG_TRACE,
204 " backsql_dn2id(\"%s\"): "
206 ndn->bv_val, upperdn, 0 );
207 ber_str2bv( upperdn, 0, 0, &tbbDN );
214 rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &tbbDN );
215 if ( rc != SQL_SUCCESS) {
217 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
218 "error binding dn=\"%s\" parameter:\n",
219 ndn->bv_val, tbbDN.bv_val, 0 );
220 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
225 rc = SQLExecute( sth );
226 if ( rc != SQL_SUCCESS ) {
227 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
228 "error executing query (\"%s\", \"%s\"):\n",
229 ndn->bv_val, bi->sql_id_query, tbbDN.bv_val );
230 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
235 backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx );
236 rc = SQLFetch( sth );
237 if ( BACKSQL_SUCCESS( rc ) ) {
238 char buf[ SLAP_TEXT_BUFLEN ];
241 snprintf( buf, sizeof(buf),
242 "id=%s keyval=%s oc_id=%s dn=%s",
243 row.cols[ 0 ], row.cols[ 1 ],
244 row.cols[ 2 ], row.cols[ 3 ] );
245 Debug( LDAP_DEBUG_TRACE,
246 " backsql_dn2id(\"%s\"): %s\n",
247 ndn->bv_val, buf, 0 );
248 #endif /* LDAP_DEBUG */
256 #ifdef BACKSQL_ARBITRARY_KEY
257 ber_str2bv_x( row.cols[ 0 ], 0, 1, &id->eid_id,
259 ber_str2bv_x( row.cols[ 1 ], 0, 1, &id->eid_keyval,
261 #else /* ! BACKSQL_ARBITRARY_KEY */
262 if ( lutil_atoulx( &id->eid_id, row.cols[ 0 ], 0 ) != 0 ) {
266 if ( lutil_atoulx( &id->eid_keyval, row.cols[ 1 ], 0 ) != 0 ) {
270 #endif /* ! BACKSQL_ARBITRARY_KEY */
271 if ( lutil_atoulx( &id->eid_oc_id, row.cols[ 2 ], 0 ) != 0 ) {
276 ber_str2bv( row.cols[ 3 ], 0, 0, &dn );
278 if ( backsql_api_odbc2dn( op, rs, &dn ) ) {
283 res = dnPrettyNormal( NULL, &dn,
284 &id->eid_dn, &id->eid_ndn,
286 if ( res != LDAP_SUCCESS ) {
287 Debug( LDAP_DEBUG_TRACE,
288 " backsql_dn2id(\"%s\"): "
289 "dnPrettyNormal failed (%d: %s)\n",
291 ldap_err2string( res ) );
294 (void)backsql_free_entryID( op, id, 0 );
297 if ( dn.bv_val != row.cols[ 3 ] ) {
303 res = LDAP_NO_SUCH_OBJECT;
305 struct berval pdn = *ndn;
310 rs->sr_matched = NULL;
311 while ( !be_issuffix( op->o_bd, &pdn ) ) {
312 char *matchedDN = NULL;
314 dnParent( &pdn, &pdn );
317 * Empty DN ("") defaults to LDAP_SUCCESS
319 rs->sr_err = backsql_dn2id( op, rs, dbh, &pdn, id, 0, 1 );
320 switch ( rs->sr_err ) {
321 case LDAP_NO_SUCH_OBJECT:
322 /* try another one */
326 matchedDN = pdn.bv_val;
327 /* fail over to next case */
330 rs->sr_err = LDAP_NO_SUCH_OBJECT;
331 rs->sr_matched = matchedDN;
339 backsql_FreeRow_x( &row, op->o_tmpmemctx );
341 Debug( LDAP_DEBUG_TRACE,
342 "<==backsql_dn2id(\"%s\"): err=%d\n",
343 ndn->bv_val, res, 0 );
344 if ( sth != SQL_NULL_HSTMT ) {
345 SQLFreeStmt( sth, SQL_DROP );
348 if ( !BER_BVISNULL( &realndn ) && realndn.bv_val != ndn->bv_val ) {
349 ch_free( realndn.bv_val );
356 backsql_count_children(
360 unsigned long *nchildren )
362 backsql_info *bi = (backsql_info *)op->o_bd->be_private;
363 SQLHSTMT sth = SQL_NULL_HSTMT;
366 int res = LDAP_SUCCESS;
368 Debug( LDAP_DEBUG_TRACE, "==>backsql_count_children(): dn=\"%s\"\n",
371 if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) {
372 Debug( LDAP_DEBUG_TRACE,
373 "backsql_count_children(): DN \"%s\" (%ld bytes) "
374 "exceeds max DN length (%d):\n",
375 dn->bv_val, dn->bv_len, BACKSQL_MAX_DN_LEN );
380 Debug(LDAP_DEBUG_TRACE, "children id query \"%s\"\n",
381 bi->sql_has_children_query, 0, 0);
382 assert( bi->sql_has_children_query != NULL );
383 rc = backsql_Prepare( dbh, &sth, bi->sql_has_children_query, 0 );
384 if ( rc != SQL_SUCCESS ) {
385 Debug( LDAP_DEBUG_TRACE,
386 "backsql_count_children(): error preparing SQL:\n%s",
387 bi->sql_has_children_query, 0, 0);
388 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
389 SQLFreeStmt( sth, SQL_DROP );
393 rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, dn );
394 if ( rc != SQL_SUCCESS) {
396 Debug( LDAP_DEBUG_TRACE, "backsql_count_children(): "
397 "error binding dn=\"%s\" parameter:\n",
399 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
400 SQLFreeStmt( sth, SQL_DROP );
404 rc = SQLExecute( sth );
405 if ( rc != SQL_SUCCESS ) {
406 Debug( LDAP_DEBUG_TRACE, "backsql_count_children(): "
407 "error executing query (\"%s\", \"%s\"):\n",
408 bi->sql_has_children_query, dn->bv_val, 0 );
409 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
410 SQLFreeStmt( sth, SQL_DROP );
414 backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx );
416 rc = SQLFetch( sth );
417 if ( BACKSQL_SUCCESS( rc ) ) {
420 *nchildren = strtol( row.cols[ 0 ], &end, 0 );
421 if ( end == row.cols[ 0 ] ) {
425 switch ( end[ 0 ] ) {
432 /* FIXME: braindead RDBMSes return
433 * a fractional number from COUNT!
435 if ( lutil_atoul( &ul, end + 1 ) != 0 || ul != 0 ) {
448 backsql_FreeRow_x( &row, op->o_tmpmemctx );
450 SQLFreeStmt( sth, SQL_DROP );
452 Debug( LDAP_DEBUG_TRACE, "<==backsql_count_children(): %lu\n",
459 backsql_has_children(
464 unsigned long nchildren;
467 rc = backsql_count_children( op, dbh, dn, &nchildren );
469 if ( rc == LDAP_SUCCESS ) {
470 return nchildren > 0 ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
477 backsql_get_attr_vals( void *v_at, void *v_bsi )
479 backsql_at_map_rec *at = v_at;
480 backsql_srch_info *bsi = v_bsi;
481 backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;
483 SQLHSTMT sth = SQL_NULL_HSTMT;
489 #ifdef BACKSQL_COUNTQUERY
493 SQLLEN countsize = sizeof( count );
494 Attribute *attr = NULL;
496 slap_mr_normalize_func *normfunc = NULL;
497 #endif /* BACKSQL_COUNTQUERY */
498 #ifdef BACKSQL_PRETTY_VALIDATE
499 slap_syntax_validate_func *validate = NULL;
500 slap_syntax_transform_func *pretty = NULL;
501 #endif /* BACKSQL_PRETTY_VALIDATE */
503 assert( at != NULL );
504 assert( bsi != NULL );
506 #ifdef BACKSQL_ARBITRARY_KEY
507 Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
508 "oc=\"%s\" attr=\"%s\" keyval=%s\n",
509 BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val,
510 bsi->bsi_c_eid->eid_keyval.bv_val );
511 #else /* ! BACKSQL_ARBITRARY_KEY */
512 Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
513 "oc=\"%s\" attr=\"%s\" keyval=%ld\n",
514 BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val,
515 bsi->bsi_c_eid->eid_keyval );
516 #endif /* ! BACKSQL_ARBITRARY_KEY */
518 #ifdef BACKSQL_PRETTY_VALIDATE
519 validate = at->bam_ad->ad_type->sat_syntax->ssyn_validate;
520 pretty = at->bam_ad->ad_type->sat_syntax->ssyn_pretty;
522 if ( validate == NULL && pretty == NULL ) {
525 #endif /* BACKSQL_PRETTY_VALIDATE */
527 #ifdef BACKSQL_COUNTQUERY
528 if ( at->bam_ad->ad_type->sat_equality ) {
529 normfunc = at->bam_ad->ad_type->sat_equality->smr_normalize;
532 /* Count how many rows will be returned. This avoids memory
533 * fragmentation that can result from loading the values in
534 * one by one and using realloc()
536 rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_countquery, 0 );
537 if ( rc != SQL_SUCCESS ) {
538 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
539 "error preparing count query: %s\n",
540 at->bam_countquery, 0, 0 );
541 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
545 rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
546 &bsi->bsi_c_eid->eid_keyval );
547 if ( rc != SQL_SUCCESS ) {
548 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
549 "error binding key value parameter\n", 0, 0, 0 );
550 SQLFreeStmt( sth, SQL_DROP );
554 rc = SQLExecute( sth );
555 if ( ! BACKSQL_SUCCESS( rc ) ) {
556 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
557 "error executing attribute count query '%s'\n",
558 at->bam_countquery, 0, 0 );
559 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
560 SQLFreeStmt( sth, SQL_DROP );
564 SQLBindCol( sth, (SQLUSMALLINT)1, SQL_C_LONG,
566 (SQLINTEGER)sizeof( count ),
569 rc = SQLFetch( sth );
570 if ( rc != SQL_SUCCESS ) {
571 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
572 "error fetch results of count query: %s\n",
573 at->bam_countquery, 0, 0 );
574 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
575 SQLFreeStmt( sth, SQL_DROP );
579 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
580 "number of values in query: %u\n", count, 0, 0 );
581 SQLFreeStmt( sth, SQL_DROP );
586 attr = attr_find( bsi->bsi_e->e_attrs, at->bam_ad );
587 if ( attr != NULL ) {
590 if ( attr->a_vals != NULL ) {
591 for ( ; !BER_BVISNULL( &attr->a_vals[ oldcount ] ); oldcount++ )
595 tmp = ch_realloc( attr->a_vals, ( oldcount + count + 1 ) * sizeof( struct berval ) );
600 memset( &attr->a_vals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) );
603 tmp = ch_realloc( attr->a_nvals, ( oldcount + count + 1 ) * sizeof( struct berval ) );
608 memset( &attr->a_nvals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) );
611 attr->a_nvals = attr->a_vals;
617 /* Make space for the array of values */
618 attr = (Attribute *) ch_malloc( sizeof( Attribute ) );
619 attr->a_desc = at->bam_ad;
622 attr->a_vals = ch_calloc( count + 1, sizeof( struct berval ) );
623 if ( attr->a_vals == NULL ) {
624 Debug( LDAP_DEBUG_TRACE, "Out of memory!\n", 0,0,0 );
628 memset( attr->a_vals, 0, ( count + 1 ) * sizeof( struct berval ) );
630 attr->a_nvals = ch_calloc( count + 1, sizeof( struct berval ) );
631 if ( attr->a_nvals == NULL ) {
632 ch_free( attr->a_vals );
637 memset( attr->a_nvals, 0, ( count + 1 ) * sizeof( struct berval ) );
641 attr->a_nvals = attr->a_vals;
644 #endif /* BACKSQL_COUNTQUERY */
646 rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_query, 0 );
647 if ( rc != SQL_SUCCESS ) {
648 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
649 "error preparing query: %s\n", at->bam_query, 0, 0 );
650 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
654 rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
655 &bsi->bsi_c_eid->eid_keyval );
656 if ( rc != SQL_SUCCESS ) {
657 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
658 "error binding key value parameter\n", 0, 0, 0 );
663 #ifdef BACKSQL_ARBITRARY_KEY
664 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
665 "query=\"%s\" keyval=%s\n", at->bam_query,
666 bsi->bsi_c_eid->eid_keyval.bv_val, 0 );
667 #else /* !BACKSQL_ARBITRARY_KEY */
668 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
669 "query=\"%s\" keyval=%d\n", at->bam_query,
670 bsi->bsi_c_eid->eid_keyval, 0 );
671 #endif /* ! BACKSQL_ARBITRARY_KEY */
672 #endif /* BACKSQL_TRACE */
674 rc = SQLExecute( sth );
675 if ( ! BACKSQL_SUCCESS( rc ) ) {
676 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
677 "error executing attribute query \"%s\"\n",
678 at->bam_query, 0, 0 );
679 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
680 SQLFreeStmt( sth, SQL_DROP );
684 backsql_BindRowAsStrings_x( sth, &row, bsi->bsi_op->o_tmpmemctx );
685 #ifdef BACKSQL_COUNTQUERY
687 #endif /* BACKSQL_COUNTQUERY */
688 for ( rc = SQLFetch( sth ), k = 0;
689 BACKSQL_SUCCESS( rc );
690 rc = SQLFetch( sth ), k++ )
692 for ( i = 0; i < (unsigned long)row.ncols; i++ ) {
694 if ( row.value_len[ i ] > 0 ) {
698 AttributeDescription *ad = NULL;
701 retval = slap_bv2ad( &row.col_names[ i ], &ad, &text );
702 if ( retval != LDAP_SUCCESS ) {
703 Debug( LDAP_DEBUG_ANY,
704 "==>backsql_get_attr_vals(\"%s\"): "
705 "unable to find AttributeDescription %s "
707 bsi->bsi_e->e_name.bv_val,
708 row.col_names[ i ].bv_val, retval );
713 if ( ad != at->bam_ad ) {
714 Debug( LDAP_DEBUG_ANY,
715 "==>backsql_get_attr_vals(\"%s\"): "
716 "column name %s differs from "
717 "AttributeDescription %s\n",
718 bsi->bsi_e->e_name.bv_val,
720 at->bam_ad->ad_cname.bv_val );
724 #endif /* BACKSQL_TRACE */
727 * FIXME: what if a binary
730 ber_str2bv( row.cols[ i ], 0, 0, &bv );
732 #ifdef BACKSQL_PRETTY_VALIDATE
736 retval = pretty( at->bam_ad->ad_type->sat_syntax,
737 &bv, &pbv, bsi->bsi_op->o_tmpmemctx );
741 retval = validate( at->bam_ad->ad_type->sat_syntax,
745 if ( retval != LDAP_SUCCESS ) {
746 char buf[ SLAP_TEXT_BUFLEN ];
748 /* FIXME: we're ignoring invalid values,
749 * but we're accepting the attributes;
750 * should we fail at all? */
751 snprintf( buf, sizeof( buf ),
752 "unable to %s value #%lu "
753 "of AttributeDescription %s",
754 pretty ? "prettify" : "validate",
756 at->bam_ad->ad_cname.bv_val );
757 Debug( LDAP_DEBUG_TRACE,
758 "==>backsql_get_attr_vals(\"%s\"): "
760 bsi->bsi_e->e_name.bv_val, buf, retval );
763 #endif /* BACKSQL_PRETTY_VALIDATE */
765 #ifndef BACKSQL_COUNTQUERY
766 (void)backsql_entry_addattr( bsi->bsi_e,
768 bsi->bsi_op->o_tmpmemctx );
770 #else /* BACKSQL_COUNTQUERY */
774 retval = (*normfunc)( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
775 at->bam_ad->ad_type->sat_syntax,
776 at->bam_ad->ad_type->sat_equality,
778 bsi->bsi_op->o_tmpmemctx );
780 if ( retval != LDAP_SUCCESS ) {
781 char buf[ SLAP_TEXT_BUFLEN ];
783 /* FIXME: we're ignoring invalid values,
784 * but we're accepting the attributes;
785 * should we fail at all? */
786 snprintf( buf, sizeof( buf ),
787 "unable to normalize value #%lu "
788 "of AttributeDescription %s",
790 at->bam_ad->ad_cname.bv_val );
791 Debug( LDAP_DEBUG_TRACE,
792 "==>backsql_get_attr_vals(\"%s\"): "
794 bsi->bsi_e->e_name.bv_val, buf, retval );
796 #ifdef BACKSQL_PRETTY_VALIDATE
798 bsi->bsi_op->o_tmpfree( bv.bv_val,
799 bsi->bsi_op->o_tmpmemctx );
801 #endif /* BACKSQL_PRETTY_VALIDATE */
805 ber_dupbv( &attr->a_nvals[ j ], &nbv );
806 bsi->bsi_op->o_tmpfree( nbv.bv_val,
807 bsi->bsi_op->o_tmpmemctx );
810 ber_dupbv( &attr->a_vals[ j ], &bv );
812 assert( j < oldcount + count );
814 #endif /* BACKSQL_COUNTQUERY */
816 #ifdef BACKSQL_PRETTY_VALIDATE
818 bsi->bsi_op->o_tmpfree( bv.bv_val,
819 bsi->bsi_op->o_tmpmemctx );
821 #endif /* BACKSQL_PRETTY_VALIDATE */
824 Debug( LDAP_DEBUG_TRACE, "prec=%d\n",
825 (int)row.col_prec[ i ], 0, 0 );
828 Debug( LDAP_DEBUG_TRACE, "NULL value "
829 "in this row for attribute \"%s\"\n",
830 row.col_names[ i ].bv_val, 0, 0 );
831 #endif /* BACKSQL_TRACE */
836 #ifdef BACKSQL_COUNTQUERY
837 if ( BER_BVISNULL( &attr->a_vals[ 0 ] ) ) {
838 /* don't leave around attributes with no values */
841 } else if ( append ) {
844 for ( ap = &bsi->bsi_e->e_attrs; (*ap) != NULL; ap = &(*ap)->a_next )
848 #endif /* BACKSQL_COUNTQUERY */
850 SQLFreeStmt( sth, SQL_DROP );
851 Debug( LDAP_DEBUG_TRACE, "<==backsql_get_attr_vals()\n", 0, 0, 0 );
853 if ( at->bam_next ) {
854 res = backsql_get_attr_vals( at->bam_next, v_bsi );
861 #endif /* BACKSQL_TRACE */
862 backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx );
868 backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
870 Operation *op = bsi->bsi_op;
871 backsql_info *bi = (backsql_info *)op->o_bd->be_private;
875 Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );
877 assert( bsi->bsi_e != NULL );
879 memset( bsi->bsi_e, 0, sizeof( Entry ) );
881 if ( bi->sql_baseObject && BACKSQL_IS_BASEOBJECT_ID( &eid->eid_id ) ) {
884 e = entry_dup( bi->sql_baseObject );
886 return LDAP_NO_MEMORY;
894 ber_dupbv_x( &bsi->bsi_e->e_name, &eid->eid_dn, op->o_tmpmemctx );
895 ber_dupbv_x( &bsi->bsi_e->e_nname, &eid->eid_ndn, op->o_tmpmemctx );
897 bsi->bsi_e->e_attrs = NULL;
898 bsi->bsi_e->e_private = NULL;
900 bsi->bsi_oc = backsql_id2oc( bsi->bsi_op->o_bd->be_private,
902 bsi->bsi_c_eid = eid;
904 #ifndef BACKSQL_ARBITRARY_KEY
906 bsi->bsi_e->e_id = eid->eid_id;
907 #endif /* ! BACKSQL_ARBITRARY_KEY */
909 rc = attr_merge_normalize_one( bsi->bsi_e,
910 slap_schema.si_ad_objectClass,
911 &bsi->bsi_oc->bom_oc->soc_cname,
912 bsi->bsi_op->o_tmpmemctx );
913 if ( rc != LDAP_SUCCESS ) {
914 backsql_entry_clean( op, bsi->bsi_e );
918 if ( bsi->bsi_attrs == NULL || ( bsi->bsi_flags & BSQL_SF_ALL_USER ) )
920 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
921 "retrieving all attributes\n", 0, 0, 0 );
922 avl_apply( bsi->bsi_oc->bom_attrs, backsql_get_attr_vals,
923 bsi, 0, AVL_INORDER );
926 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
927 "custom attribute list\n", 0, 0, 0 );
928 for ( i = 0; !BER_BVISNULL( &bsi->bsi_attrs[ i ].an_name ); i++ ) {
929 backsql_at_map_rec **vat;
930 AttributeName *an = &bsi->bsi_attrs[ i ];
933 /* if one of the attributes listed here is
934 * a subtype of another, it must be ignored,
935 * because subtypes are already dealt with
936 * by backsql_supad2at()
938 for ( j = 0; !BER_BVISNULL( &bsi->bsi_attrs[ j ].an_name ); j++ ) {
945 if ( is_at_subtype( an->an_desc->ad_type,
946 bsi->bsi_attrs[ j ].an_desc->ad_type ) )
952 rc = backsql_supad2at( bsi->bsi_oc, an->an_desc, &vat );
953 if ( rc != 0 || vat == NULL ) {
954 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
955 "attribute \"%s\" is not defined "
956 "for objectlass \"%s\"\n",
958 BACKSQL_OC_NAME( bsi->bsi_oc ), 0 );
962 for ( j = 0; vat[j]; j++ ) {
963 backsql_get_attr_vals( vat[j], bsi );
972 if ( bsi->bsi_flags & BSQL_SF_RETURN_ENTRYUUID ) {
973 Attribute *a_entryUUID,
976 a_entryUUID = backsql_operational_entryUUID( bi, eid );
977 if ( a_entryUUID != NULL ) {
978 for ( ap = &bsi->bsi_e->e_attrs;
980 ap = &(*ap)->a_next );
986 if ( ( bsi->bsi_flags & BSQL_SF_ALL_OPER )
987 || an_find( bsi->bsi_attrs, &AllOper )
988 || an_find( bsi->bsi_attrs, &slap_schema.si_ad_structuralObjectClass->ad_cname ) )
990 if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
992 const char *text = NULL;
993 char textbuf[ 1024 ];
994 size_t textlen = sizeof( textbuf );
998 int rc = LDAP_SUCCESS;
1000 a = attr_find( bsi->bsi_e->e_attrs,
1001 slap_schema.si_ad_objectClass );
1006 bv[ 0 ] = bsi->bsi_oc->bom_oc->soc_cname;
1007 BER_BVZERO( &bv[ 1 ] );
1011 rc = structural_class( nvals, &soc, NULL,
1012 &text, textbuf, textlen );
1013 if ( rc != LDAP_SUCCESS ) {
1014 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
1015 "structural_class() failed %d (%s)\n",
1016 bsi->bsi_e->e_name.bv_val,
1017 rc, text ? text : "" );
1018 backsql_entry_clean( op, bsi->bsi_e );
1022 if ( !bvmatch( &soc, &bsi->bsi_oc->bom_oc->soc_cname ) ) {
1023 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
1024 "computed structuralObjectClass %s "
1025 "does not match objectClass %s associated "
1027 bsi->bsi_e->e_name.bv_val, soc.bv_val,
1028 bsi->bsi_oc->bom_oc->soc_cname.bv_val );
1029 backsql_entry_clean( op, bsi->bsi_e );
1034 rc = attr_merge_normalize_one( bsi->bsi_e,
1035 slap_schema.si_ad_structuralObjectClass,
1036 &bsi->bsi_oc->bom_oc->soc_cname,
1037 bsi->bsi_op->o_tmpmemctx );
1038 if ( rc != LDAP_SUCCESS ) {
1039 backsql_entry_clean( op, bsi->bsi_e );
1045 Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );
1047 return LDAP_SUCCESS;