2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2006 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 );
651 #ifdef BACKSQL_COUNTQUERY
655 #endif /* BACKSQL_COUNTQUERY */
659 rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
660 &bsi->bsi_c_eid->eid_keyval );
661 if ( rc != SQL_SUCCESS ) {
662 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
663 "error binding key value parameter\n", 0, 0, 0 );
664 #ifdef BACKSQL_COUNTQUERY
668 #endif /* BACKSQL_COUNTQUERY */
673 #ifdef BACKSQL_ARBITRARY_KEY
674 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
675 "query=\"%s\" keyval=%s\n", at->bam_query,
676 bsi->bsi_c_eid->eid_keyval.bv_val, 0 );
677 #else /* !BACKSQL_ARBITRARY_KEY */
678 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
679 "query=\"%s\" keyval=%d\n", at->bam_query,
680 bsi->bsi_c_eid->eid_keyval, 0 );
681 #endif /* ! BACKSQL_ARBITRARY_KEY */
682 #endif /* BACKSQL_TRACE */
684 rc = SQLExecute( sth );
685 if ( ! BACKSQL_SUCCESS( rc ) ) {
686 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
687 "error executing attribute query \"%s\"\n",
688 at->bam_query, 0, 0 );
689 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
690 SQLFreeStmt( sth, SQL_DROP );
691 #ifdef BACKSQL_COUNTQUERY
695 #endif /* BACKSQL_COUNTQUERY */
699 backsql_BindRowAsStrings_x( sth, &row, bsi->bsi_op->o_tmpmemctx );
700 #ifdef BACKSQL_COUNTQUERY
702 #endif /* BACKSQL_COUNTQUERY */
703 for ( rc = SQLFetch( sth ), k = 0;
704 BACKSQL_SUCCESS( rc );
705 rc = SQLFetch( sth ), k++ )
707 for ( i = 0; i < (unsigned long)row.ncols; i++ ) {
709 if ( row.value_len[ i ] > 0 ) {
713 AttributeDescription *ad = NULL;
716 retval = slap_bv2ad( &row.col_names[ i ], &ad, &text );
717 if ( retval != LDAP_SUCCESS ) {
718 Debug( LDAP_DEBUG_ANY,
719 "==>backsql_get_attr_vals(\"%s\"): "
720 "unable to find AttributeDescription %s "
722 bsi->bsi_e->e_name.bv_val,
723 row.col_names[ i ].bv_val, retval );
728 if ( ad != at->bam_ad ) {
729 Debug( LDAP_DEBUG_ANY,
730 "==>backsql_get_attr_vals(\"%s\"): "
731 "column name %s differs from "
732 "AttributeDescription %s\n",
733 bsi->bsi_e->e_name.bv_val,
735 at->bam_ad->ad_cname.bv_val );
739 #endif /* BACKSQL_TRACE */
742 * FIXME: what if a binary
745 ber_str2bv( row.cols[ i ], 0, 0, &bv );
747 #ifdef BACKSQL_PRETTY_VALIDATE
751 retval = pretty( at->bam_ad->ad_type->sat_syntax,
752 &bv, &pbv, bsi->bsi_op->o_tmpmemctx );
756 retval = validate( at->bam_ad->ad_type->sat_syntax,
760 if ( retval != LDAP_SUCCESS ) {
761 char buf[ SLAP_TEXT_BUFLEN ];
763 /* FIXME: we're ignoring invalid values,
764 * but we're accepting the attributes;
765 * should we fail at all? */
766 snprintf( buf, sizeof( buf ),
767 "unable to %s value #%lu "
768 "of AttributeDescription %s",
769 pretty ? "prettify" : "validate",
771 at->bam_ad->ad_cname.bv_val );
772 Debug( LDAP_DEBUG_TRACE,
773 "==>backsql_get_attr_vals(\"%s\"): "
775 bsi->bsi_e->e_name.bv_val, buf, retval );
778 #endif /* BACKSQL_PRETTY_VALIDATE */
780 #ifndef BACKSQL_COUNTQUERY
781 (void)backsql_entry_addattr( bsi->bsi_e,
783 bsi->bsi_op->o_tmpmemctx );
785 #else /* BACKSQL_COUNTQUERY */
789 retval = (*normfunc)( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
790 at->bam_ad->ad_type->sat_syntax,
791 at->bam_ad->ad_type->sat_equality,
793 bsi->bsi_op->o_tmpmemctx );
795 if ( retval != LDAP_SUCCESS ) {
796 char buf[ SLAP_TEXT_BUFLEN ];
798 /* FIXME: we're ignoring invalid values,
799 * but we're accepting the attributes;
800 * should we fail at all? */
801 snprintf( buf, sizeof( buf ),
802 "unable to normalize value #%lu "
803 "of AttributeDescription %s",
805 at->bam_ad->ad_cname.bv_val );
806 Debug( LDAP_DEBUG_TRACE,
807 "==>backsql_get_attr_vals(\"%s\"): "
809 bsi->bsi_e->e_name.bv_val, buf, retval );
811 #ifdef BACKSQL_PRETTY_VALIDATE
813 bsi->bsi_op->o_tmpfree( bv.bv_val,
814 bsi->bsi_op->o_tmpmemctx );
816 #endif /* BACKSQL_PRETTY_VALIDATE */
820 ber_dupbv( &attr->a_nvals[ j ], &nbv );
821 bsi->bsi_op->o_tmpfree( nbv.bv_val,
822 bsi->bsi_op->o_tmpmemctx );
825 ber_dupbv( &attr->a_vals[ j ], &bv );
827 assert( j < oldcount + count );
829 #endif /* BACKSQL_COUNTQUERY */
831 #ifdef BACKSQL_PRETTY_VALIDATE
833 bsi->bsi_op->o_tmpfree( bv.bv_val,
834 bsi->bsi_op->o_tmpmemctx );
836 #endif /* BACKSQL_PRETTY_VALIDATE */
839 Debug( LDAP_DEBUG_TRACE, "prec=%d\n",
840 (int)row.col_prec[ i ], 0, 0 );
843 Debug( LDAP_DEBUG_TRACE, "NULL value "
844 "in this row for attribute \"%s\"\n",
845 row.col_names[ i ].bv_val, 0, 0 );
846 #endif /* BACKSQL_TRACE */
851 #ifdef BACKSQL_COUNTQUERY
852 if ( BER_BVISNULL( &attr->a_vals[ 0 ] ) ) {
853 /* don't leave around attributes with no values */
856 } else if ( append ) {
859 for ( ap = &bsi->bsi_e->e_attrs; (*ap) != NULL; ap = &(*ap)->a_next )
863 #endif /* BACKSQL_COUNTQUERY */
865 SQLFreeStmt( sth, SQL_DROP );
866 Debug( LDAP_DEBUG_TRACE, "<==backsql_get_attr_vals()\n", 0, 0, 0 );
868 if ( at->bam_next ) {
869 res = backsql_get_attr_vals( at->bam_next, v_bsi );
876 #endif /* BACKSQL_TRACE */
877 backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx );
883 backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
885 Operation *op = bsi->bsi_op;
886 backsql_info *bi = (backsql_info *)op->o_bd->be_private;
890 Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );
892 assert( bsi->bsi_e != NULL );
894 memset( bsi->bsi_e, 0, sizeof( Entry ) );
896 if ( bi->sql_baseObject && BACKSQL_IS_BASEOBJECT_ID( &eid->eid_id ) ) {
899 e = entry_dup( bi->sql_baseObject );
901 return LDAP_NO_MEMORY;
909 ber_dupbv_x( &bsi->bsi_e->e_name, &eid->eid_dn, op->o_tmpmemctx );
910 ber_dupbv_x( &bsi->bsi_e->e_nname, &eid->eid_ndn, op->o_tmpmemctx );
912 bsi->bsi_e->e_attrs = NULL;
913 bsi->bsi_e->e_private = NULL;
915 bsi->bsi_oc = backsql_id2oc( bsi->bsi_op->o_bd->be_private,
917 bsi->bsi_c_eid = eid;
919 #ifndef BACKSQL_ARBITRARY_KEY
921 bsi->bsi_e->e_id = eid->eid_id;
922 #endif /* ! BACKSQL_ARBITRARY_KEY */
924 rc = attr_merge_normalize_one( bsi->bsi_e,
925 slap_schema.si_ad_objectClass,
926 &bsi->bsi_oc->bom_oc->soc_cname,
927 bsi->bsi_op->o_tmpmemctx );
928 if ( rc != LDAP_SUCCESS ) {
929 backsql_entry_clean( op, bsi->bsi_e );
933 if ( bsi->bsi_attrs == NULL || ( bsi->bsi_flags & BSQL_SF_ALL_USER ) )
935 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
936 "retrieving all attributes\n", 0, 0, 0 );
937 avl_apply( bsi->bsi_oc->bom_attrs, backsql_get_attr_vals,
938 bsi, 0, AVL_INORDER );
941 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
942 "custom attribute list\n", 0, 0, 0 );
943 for ( i = 0; !BER_BVISNULL( &bsi->bsi_attrs[ i ].an_name ); i++ ) {
944 backsql_at_map_rec **vat;
945 AttributeName *an = &bsi->bsi_attrs[ i ];
948 /* if one of the attributes listed here is
949 * a subtype of another, it must be ignored,
950 * because subtypes are already dealt with
951 * by backsql_supad2at()
953 for ( j = 0; !BER_BVISNULL( &bsi->bsi_attrs[ j ].an_name ); j++ ) {
960 if ( is_at_subtype( an->an_desc->ad_type,
961 bsi->bsi_attrs[ j ].an_desc->ad_type ) )
967 rc = backsql_supad2at( bsi->bsi_oc, an->an_desc, &vat );
968 if ( rc != 0 || vat == NULL ) {
969 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
970 "attribute \"%s\" is not defined "
971 "for objectlass \"%s\"\n",
973 BACKSQL_OC_NAME( bsi->bsi_oc ), 0 );
977 for ( j = 0; vat[j]; j++ ) {
978 backsql_get_attr_vals( vat[j], bsi );
987 if ( bsi->bsi_flags & BSQL_SF_RETURN_ENTRYUUID ) {
988 Attribute *a_entryUUID,
991 a_entryUUID = backsql_operational_entryUUID( bi, eid );
992 if ( a_entryUUID != NULL ) {
993 for ( ap = &bsi->bsi_e->e_attrs;
995 ap = &(*ap)->a_next );
1001 if ( ( bsi->bsi_flags & BSQL_SF_ALL_OPER )
1002 || an_find( bsi->bsi_attrs, &AllOper )
1003 || an_find( bsi->bsi_attrs, &slap_schema.si_ad_structuralObjectClass->ad_cname ) )
1005 if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
1007 const char *text = NULL;
1008 char textbuf[ 1024 ];
1009 size_t textlen = sizeof( textbuf );
1013 int rc = LDAP_SUCCESS;
1015 a = attr_find( bsi->bsi_e->e_attrs,
1016 slap_schema.si_ad_objectClass );
1021 bv[ 0 ] = bsi->bsi_oc->bom_oc->soc_cname;
1022 BER_BVZERO( &bv[ 1 ] );
1026 rc = structural_class( nvals, &soc, NULL,
1027 &text, textbuf, textlen );
1028 if ( rc != LDAP_SUCCESS ) {
1029 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
1030 "structural_class() failed %d (%s)\n",
1031 bsi->bsi_e->e_name.bv_val,
1032 rc, text ? text : "" );
1033 backsql_entry_clean( op, bsi->bsi_e );
1037 if ( !bvmatch( &soc, &bsi->bsi_oc->bom_oc->soc_cname ) ) {
1038 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
1039 "computed structuralObjectClass %s "
1040 "does not match objectClass %s associated "
1042 bsi->bsi_e->e_name.bv_val, soc.bv_val,
1043 bsi->bsi_oc->bom_oc->soc_cname.bv_val );
1044 backsql_entry_clean( op, bsi->bsi_e );
1049 rc = attr_merge_normalize_one( bsi->bsi_e,
1050 slap_schema.si_ad_structuralObjectClass,
1051 &bsi->bsi_oc->bom_oc->soc_cname,
1052 bsi->bsi_op->o_tmpmemctx );
1053 if ( rc != LDAP_SUCCESS ) {
1054 backsql_entry_clean( op, bsi->bsi_e );
1060 Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );
1062 return LDAP_SUCCESS;