2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2007 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;
93 BACKSQL_ROW_NTS row = { 0 };
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 = attr_alloc( at->bam_ad );
619 attr->a_vals = ch_calloc( count + 1, sizeof( struct berval ) );
620 if ( attr->a_vals == NULL ) {
621 Debug( LDAP_DEBUG_TRACE, "Out of memory!\n", 0,0,0 );
625 memset( attr->a_vals, 0, ( count + 1 ) * sizeof( struct berval ) );
627 attr->a_nvals = ch_calloc( count + 1, sizeof( struct berval ) );
628 if ( attr->a_nvals == NULL ) {
629 ch_free( attr->a_vals );
634 memset( attr->a_nvals, 0, ( count + 1 ) * sizeof( struct berval ) );
638 attr->a_nvals = attr->a_vals;
641 #endif /* BACKSQL_COUNTQUERY */
643 rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_query, 0 );
644 if ( rc != SQL_SUCCESS ) {
645 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
646 "error preparing query: %s\n", at->bam_query, 0, 0 );
647 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
648 #ifdef BACKSQL_COUNTQUERY
652 #endif /* BACKSQL_COUNTQUERY */
656 rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
657 &bsi->bsi_c_eid->eid_keyval );
658 if ( rc != SQL_SUCCESS ) {
659 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
660 "error binding key value parameter\n", 0, 0, 0 );
661 #ifdef BACKSQL_COUNTQUERY
665 #endif /* BACKSQL_COUNTQUERY */
670 #ifdef BACKSQL_ARBITRARY_KEY
671 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
672 "query=\"%s\" keyval=%s\n", at->bam_query,
673 bsi->bsi_c_eid->eid_keyval.bv_val, 0 );
674 #else /* !BACKSQL_ARBITRARY_KEY */
675 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
676 "query=\"%s\" keyval=%d\n", at->bam_query,
677 bsi->bsi_c_eid->eid_keyval, 0 );
678 #endif /* ! BACKSQL_ARBITRARY_KEY */
679 #endif /* BACKSQL_TRACE */
681 rc = SQLExecute( sth );
682 if ( ! BACKSQL_SUCCESS( rc ) ) {
683 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
684 "error executing attribute query \"%s\"\n",
685 at->bam_query, 0, 0 );
686 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
687 SQLFreeStmt( sth, SQL_DROP );
688 #ifdef BACKSQL_COUNTQUERY
692 #endif /* BACKSQL_COUNTQUERY */
696 backsql_BindRowAsStrings_x( sth, &row, bsi->bsi_op->o_tmpmemctx );
697 #ifdef BACKSQL_COUNTQUERY
699 #endif /* BACKSQL_COUNTQUERY */
700 for ( rc = SQLFetch( sth ), k = 0;
701 BACKSQL_SUCCESS( rc );
702 rc = SQLFetch( sth ), k++ )
704 for ( i = 0; i < (unsigned long)row.ncols; i++ ) {
706 if ( row.value_len[ i ] > 0 ) {
710 AttributeDescription *ad = NULL;
713 retval = slap_bv2ad( &row.col_names[ i ], &ad, &text );
714 if ( retval != LDAP_SUCCESS ) {
715 Debug( LDAP_DEBUG_ANY,
716 "==>backsql_get_attr_vals(\"%s\"): "
717 "unable to find AttributeDescription %s "
719 bsi->bsi_e->e_name.bv_val,
720 row.col_names[ i ].bv_val, retval );
725 if ( ad != at->bam_ad ) {
726 Debug( LDAP_DEBUG_ANY,
727 "==>backsql_get_attr_vals(\"%s\"): "
728 "column name %s differs from "
729 "AttributeDescription %s\n",
730 bsi->bsi_e->e_name.bv_val,
732 at->bam_ad->ad_cname.bv_val );
736 #endif /* BACKSQL_TRACE */
739 * FIXME: what if a binary
742 ber_str2bv( row.cols[ i ], 0, 0, &bv );
744 #ifdef BACKSQL_PRETTY_VALIDATE
748 retval = pretty( at->bam_ad->ad_type->sat_syntax,
749 &bv, &pbv, bsi->bsi_op->o_tmpmemctx );
753 retval = validate( at->bam_ad->ad_type->sat_syntax,
757 if ( retval != LDAP_SUCCESS ) {
758 char buf[ SLAP_TEXT_BUFLEN ];
760 /* FIXME: we're ignoring invalid values,
761 * but we're accepting the attributes;
762 * should we fail at all? */
763 snprintf( buf, sizeof( buf ),
764 "unable to %s value #%lu "
765 "of AttributeDescription %s",
766 pretty ? "prettify" : "validate",
768 at->bam_ad->ad_cname.bv_val );
769 Debug( LDAP_DEBUG_TRACE,
770 "==>backsql_get_attr_vals(\"%s\"): "
772 bsi->bsi_e->e_name.bv_val, buf, retval );
775 #endif /* BACKSQL_PRETTY_VALIDATE */
777 #ifndef BACKSQL_COUNTQUERY
778 (void)backsql_entry_addattr( bsi->bsi_e,
780 bsi->bsi_op->o_tmpmemctx );
782 #else /* BACKSQL_COUNTQUERY */
786 retval = (*normfunc)( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
787 at->bam_ad->ad_type->sat_syntax,
788 at->bam_ad->ad_type->sat_equality,
790 bsi->bsi_op->o_tmpmemctx );
792 if ( retval != LDAP_SUCCESS ) {
793 char buf[ SLAP_TEXT_BUFLEN ];
795 /* FIXME: we're ignoring invalid values,
796 * but we're accepting the attributes;
797 * should we fail at all? */
798 snprintf( buf, sizeof( buf ),
799 "unable to normalize value #%lu "
800 "of AttributeDescription %s",
802 at->bam_ad->ad_cname.bv_val );
803 Debug( LDAP_DEBUG_TRACE,
804 "==>backsql_get_attr_vals(\"%s\"): "
806 bsi->bsi_e->e_name.bv_val, buf, retval );
808 #ifdef BACKSQL_PRETTY_VALIDATE
810 bsi->bsi_op->o_tmpfree( bv.bv_val,
811 bsi->bsi_op->o_tmpmemctx );
813 #endif /* BACKSQL_PRETTY_VALIDATE */
817 ber_dupbv( &attr->a_nvals[ j ], &nbv );
818 bsi->bsi_op->o_tmpfree( nbv.bv_val,
819 bsi->bsi_op->o_tmpmemctx );
822 ber_dupbv( &attr->a_vals[ j ], &bv );
824 assert( j < oldcount + count );
826 #endif /* BACKSQL_COUNTQUERY */
828 #ifdef BACKSQL_PRETTY_VALIDATE
830 bsi->bsi_op->o_tmpfree( bv.bv_val,
831 bsi->bsi_op->o_tmpmemctx );
833 #endif /* BACKSQL_PRETTY_VALIDATE */
836 Debug( LDAP_DEBUG_TRACE, "prec=%d\n",
837 (int)row.col_prec[ i ], 0, 0 );
840 Debug( LDAP_DEBUG_TRACE, "NULL value "
841 "in this row for attribute \"%s\"\n",
842 row.col_names[ i ].bv_val, 0, 0 );
843 #endif /* BACKSQL_TRACE */
848 #ifdef BACKSQL_COUNTQUERY
849 if ( BER_BVISNULL( &attr->a_vals[ 0 ] ) ) {
850 /* don't leave around attributes with no values */
853 } else if ( append ) {
856 for ( ap = &bsi->bsi_e->e_attrs; (*ap) != NULL; ap = &(*ap)->a_next )
860 #endif /* BACKSQL_COUNTQUERY */
862 SQLFreeStmt( sth, SQL_DROP );
863 Debug( LDAP_DEBUG_TRACE, "<==backsql_get_attr_vals()\n", 0, 0, 0 );
865 if ( at->bam_next ) {
866 res = backsql_get_attr_vals( at->bam_next, v_bsi );
873 #endif /* BACKSQL_TRACE */
874 backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx );
880 backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
882 Operation *op = bsi->bsi_op;
883 backsql_info *bi = (backsql_info *)op->o_bd->be_private;
887 Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );
889 assert( bsi->bsi_e != NULL );
891 memset( bsi->bsi_e, 0, sizeof( Entry ) );
893 if ( bi->sql_baseObject && BACKSQL_IS_BASEOBJECT_ID( &eid->eid_id ) ) {
896 e = entry_dup( bi->sql_baseObject );
898 return LDAP_NO_MEMORY;
906 ber_dupbv_x( &bsi->bsi_e->e_name, &eid->eid_dn, op->o_tmpmemctx );
907 ber_dupbv_x( &bsi->bsi_e->e_nname, &eid->eid_ndn, op->o_tmpmemctx );
909 bsi->bsi_e->e_attrs = NULL;
910 bsi->bsi_e->e_private = NULL;
912 bsi->bsi_oc = backsql_id2oc( bsi->bsi_op->o_bd->be_private,
914 bsi->bsi_c_eid = eid;
916 #ifndef BACKSQL_ARBITRARY_KEY
918 bsi->bsi_e->e_id = eid->eid_id;
919 #endif /* ! BACKSQL_ARBITRARY_KEY */
921 rc = attr_merge_normalize_one( bsi->bsi_e,
922 slap_schema.si_ad_objectClass,
923 &bsi->bsi_oc->bom_oc->soc_cname,
924 bsi->bsi_op->o_tmpmemctx );
925 if ( rc != LDAP_SUCCESS ) {
926 backsql_entry_clean( op, bsi->bsi_e );
930 if ( bsi->bsi_attrs == NULL || ( bsi->bsi_flags & BSQL_SF_ALL_USER ) )
932 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
933 "retrieving all attributes\n", 0, 0, 0 );
934 avl_apply( bsi->bsi_oc->bom_attrs, backsql_get_attr_vals,
935 bsi, 0, AVL_INORDER );
938 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
939 "custom attribute list\n", 0, 0, 0 );
940 for ( i = 0; !BER_BVISNULL( &bsi->bsi_attrs[ i ].an_name ); i++ ) {
941 backsql_at_map_rec **vat;
942 AttributeName *an = &bsi->bsi_attrs[ i ];
945 /* if one of the attributes listed here is
946 * a subtype of another, it must be ignored,
947 * because subtypes are already dealt with
948 * by backsql_supad2at()
950 for ( j = 0; !BER_BVISNULL( &bsi->bsi_attrs[ j ].an_name ); j++ ) {
957 if ( is_at_subtype( an->an_desc->ad_type,
958 bsi->bsi_attrs[ j ].an_desc->ad_type ) )
964 rc = backsql_supad2at( bsi->bsi_oc, an->an_desc, &vat );
965 if ( rc != 0 || vat == NULL ) {
966 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
967 "attribute \"%s\" is not defined "
968 "for objectlass \"%s\"\n",
970 BACKSQL_OC_NAME( bsi->bsi_oc ), 0 );
974 for ( j = 0; vat[j]; j++ ) {
975 backsql_get_attr_vals( vat[j], bsi );
984 if ( bsi->bsi_flags & BSQL_SF_RETURN_ENTRYUUID ) {
985 Attribute *a_entryUUID,
988 a_entryUUID = backsql_operational_entryUUID( bi, eid );
989 if ( a_entryUUID != NULL ) {
990 for ( ap = &bsi->bsi_e->e_attrs;
992 ap = &(*ap)->a_next );
998 if ( ( bsi->bsi_flags & BSQL_SF_ALL_OPER )
999 || an_find( bsi->bsi_attrs, &AllOper )
1000 || an_find( bsi->bsi_attrs, &slap_schema.si_ad_structuralObjectClass->ad_cname ) )
1002 if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
1004 const char *text = NULL;
1005 char textbuf[ 1024 ];
1006 size_t textlen = sizeof( textbuf );
1007 ObjectClass *soc = NULL;
1008 struct berval bv[ 2 ],
1010 int rc = LDAP_SUCCESS;
1012 a = attr_find( bsi->bsi_e->e_attrs,
1013 slap_schema.si_ad_objectClass );
1018 bv[ 0 ] = bsi->bsi_oc->bom_oc->soc_cname;
1019 BER_BVZERO( &bv[ 1 ] );
1023 rc = structural_class( nvals, &soc, NULL,
1024 &text, textbuf, textlen, op->o_tmpmemctx );
1025 if ( rc != LDAP_SUCCESS ) {
1026 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
1027 "structural_class() failed %d (%s)\n",
1028 bsi->bsi_e->e_name.bv_val,
1029 rc, text ? text : "" );
1030 backsql_entry_clean( op, bsi->bsi_e );
1034 if ( !bvmatch( &soc->soc_cname, &bsi->bsi_oc->bom_oc->soc_cname ) ) {
1035 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
1036 "computed structuralObjectClass %s "
1037 "does not match objectClass %s associated "
1039 bsi->bsi_e->e_name.bv_val, soc->soc_cname.bv_val,
1040 bsi->bsi_oc->bom_oc->soc_cname.bv_val );
1041 backsql_entry_clean( op, bsi->bsi_e );
1046 rc = attr_merge_normalize_one( bsi->bsi_e,
1047 slap_schema.si_ad_structuralObjectClass,
1048 &bsi->bsi_oc->bom_oc->soc_cname,
1049 bsi->bsi_op->o_tmpmemctx );
1050 if ( rc != LDAP_SUCCESS ) {
1051 backsql_entry_clean( op, bsi->bsi_e );
1057 Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );
1059 return LDAP_SUCCESS;