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"
31 #include "proto-sql.h"
33 #ifdef BACKSQL_ARBITRARY_KEY
34 struct berval backsql_baseObject_bv = BER_BVC( BACKSQL_BASEOBJECT_IDSTR );
35 #endif /* BACKSQL_ARBITRARY_KEY */
38 backsql_free_entryID( Operation *op, backsql_entryID *id, int freeit )
40 backsql_entryID *next;
46 if ( !BER_BVISNULL( &id->eid_ndn ) ) {
47 if ( !BER_BVISNULL( &id->eid_dn )
48 && id->eid_dn.bv_val != id->eid_ndn.bv_val )
50 op->o_tmpfree( id->eid_dn.bv_val, op->o_tmpmemctx );
51 BER_BVZERO( &id->eid_dn );
54 op->o_tmpfree( id->eid_ndn.bv_val, op->o_tmpmemctx );
55 BER_BVZERO( &id->eid_ndn );
58 #ifdef BACKSQL_ARBITRARY_KEY
59 if ( !BER_BVISNULL( &id->eid_id ) ) {
60 op->o_tmpfree( id->eid_id.bv_val, op->o_tmpmemctx );
61 BER_BVZERO( &id->eid_id );
64 if ( !BER_BVISNULL( &id->eid_keyval ) ) {
65 op->o_tmpfree( id->eid_keyval.bv_val, op->o_tmpmemctx );
66 BER_BVZERO( &id->eid_keyval );
68 #endif /* BACKSQL_ARBITRARY_KEY */
71 op->o_tmpfree( id, op->o_tmpmemctx );
78 * NOTE: the dn must be normalized
90 backsql_info *bi = op->o_bd->be_private;
91 SQLHSTMT sth = SQL_NULL_HSTMT;
95 struct berval realndn = BER_BVNULL;
98 char upperdn[ BACKSQL_MAX_DN_LEN + 1 ];
103 * NOTE: id can be NULL; in this case, the function
104 * simply checks whether the DN can be successfully
105 * turned into an ID, returning LDAP_SUCCESS for
106 * positive cases, or the most appropriate error
109 Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(\"%s\")%s%s\n",
110 ndn->bv_val, id == NULL ? " (no ID expected)" : "",
111 matched ? " matched expected" : "" );
114 /* NOTE: trap inconsistencies */
115 assert( BER_BVISNULL( &id->eid_ndn ) );
118 if ( ndn->bv_len > BACKSQL_MAX_DN_LEN ) {
119 Debug( LDAP_DEBUG_TRACE,
120 " backsql_dn2id(\"%s\"): DN length=%ld "
121 "exceeds max DN length %d:\n",
122 ndn->bv_val, ndn->bv_len, BACKSQL_MAX_DN_LEN );
126 /* return baseObject if available and matches */
127 /* FIXME: if ndn is already mucked, we cannot check this */
128 if ( bi->sql_baseObject != NULL &&
129 dn_match( ndn, &bi->sql_baseObject->e_nname ) )
132 #ifdef BACKSQL_ARBITRARY_KEY
133 ber_dupbv_x( &id->eid_id, &backsql_baseObject_bv,
135 ber_dupbv_x( &id->eid_keyval, &backsql_baseObject_bv,
137 #else /* ! BACKSQL_ARBITRARY_KEY */
138 id->eid_id = BACKSQL_BASEOBJECT_ID;
139 id->eid_keyval = BACKSQL_BASEOBJECT_KEYVAL;
140 #endif /* ! BACKSQL_ARBITRARY_KEY */
141 id->eid_oc_id = BACKSQL_BASEOBJECT_OC;
143 ber_dupbv_x( &id->eid_ndn, &bi->sql_baseObject->e_nname,
145 ber_dupbv_x( &id->eid_dn, &bi->sql_baseObject->e_name,
155 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): id_query \"%s\"\n",
156 ndn->bv_val, bi->sql_id_query, 0 );
157 assert( bi->sql_id_query != NULL );
158 rc = backsql_Prepare( dbh, &sth, bi->sql_id_query, 0 );
159 if ( rc != SQL_SUCCESS ) {
160 Debug( LDAP_DEBUG_TRACE,
161 " backsql_dn2id(\"%s\"): "
162 "error preparing SQL:\n %s",
163 ndn->bv_val, bi->sql_id_query, 0 );
164 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
171 if ( backsql_api_dn2odbc( op, rs, &realndn ) ) {
172 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
173 "backsql_api_dn2odbc(\"%s\") failed\n",
174 ndn->bv_val, realndn.bv_val, 0 );
180 if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
182 * Prepare an upper cased, byte reversed version
183 * that can be searched using indexes
186 for ( i = 0, j = realndn.bv_len - 1; realndn.bv_val[ i ]; i++, j--)
188 upperdn[ i ] = realndn.bv_val[ j ];
191 ldap_pvt_str2upper( upperdn );
193 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
195 ndn->bv_val, upperdn, 0 );
196 ber_str2bv( upperdn, 0, 0, &tbbDN );
199 if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
200 AC_MEMCPY( upperdn, realndn.bv_val, realndn.bv_len + 1 );
201 ldap_pvt_str2upper( upperdn );
202 Debug( LDAP_DEBUG_TRACE,
203 " backsql_dn2id(\"%s\"): "
205 ndn->bv_val, upperdn, 0 );
206 ber_str2bv( upperdn, 0, 0, &tbbDN );
213 rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &tbbDN );
214 if ( rc != SQL_SUCCESS) {
216 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
217 "error binding dn=\"%s\" parameter:\n",
218 ndn->bv_val, tbbDN.bv_val, 0 );
219 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
224 rc = SQLExecute( sth );
225 if ( rc != SQL_SUCCESS ) {
226 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
227 "error executing query (\"%s\", \"%s\"):\n",
228 ndn->bv_val, bi->sql_id_query, tbbDN.bv_val );
229 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
234 backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx );
235 rc = SQLFetch( sth );
236 if ( BACKSQL_SUCCESS( rc ) ) {
237 char buf[ SLAP_TEXT_BUFLEN ];
240 snprintf( buf, sizeof(buf),
241 "id=%s keyval=%s oc_id=%s dn=%s",
242 row.cols[ 0 ], row.cols[ 1 ],
243 row.cols[ 2 ], row.cols[ 3 ] );
244 Debug( LDAP_DEBUG_TRACE,
245 " backsql_dn2id(\"%s\"): %s\n",
246 ndn->bv_val, buf, 0 );
247 #endif /* LDAP_DEBUG */
253 #ifdef BACKSQL_ARBITRARY_KEY
254 ber_str2bv_x( row.cols[ 0 ], 0, 1, &id->eid_id,
256 ber_str2bv_x( row.cols[ 1 ], 0, 1, &id->eid_keyval,
258 #else /* ! BACKSQL_ARBITRARY_KEY */
259 id->eid_id = strtol( row.cols[ 0 ], NULL, 0 );
260 id->eid_keyval = strtol( row.cols[ 1 ], NULL, 0 );
261 #endif /* ! BACKSQL_ARBITRARY_KEY */
262 id->eid_oc_id = strtol( row.cols[ 2 ], NULL, 0 );
264 ber_str2bv( row.cols[ 3 ], 0, 0, &dn );
266 if ( backsql_api_odbc2dn( op, rs, &dn ) ) {
270 res = dnPrettyNormal( NULL, &dn,
271 &id->eid_dn, &id->eid_ndn,
273 if ( res != LDAP_SUCCESS ) {
274 Debug( LDAP_DEBUG_TRACE,
275 " backsql_dn2id(\"%s\"): "
276 "dnPrettyNormal failed (%d: %s)\n",
278 ldap_err2string( res ) );
281 (void)backsql_free_entryID( op, id, 0 );
284 if ( dn.bv_val != row.cols[ 3 ] ) {
293 res = LDAP_NO_SUCH_OBJECT;
295 struct berval pdn = *ndn;
300 rs->sr_matched = NULL;
301 while ( !be_issuffix( op->o_bd, &pdn ) ) {
302 char *matchedDN = NULL;
304 dnParent( &pdn, &pdn );
307 * Empty DN ("") defaults to LDAP_SUCCESS
309 rs->sr_err = backsql_dn2id( op, rs, dbh, &pdn, id, 0, 1 );
310 switch ( rs->sr_err ) {
311 case LDAP_NO_SUCH_OBJECT:
312 /* try another one */
316 matchedDN = pdn.bv_val;
317 /* fail over to next case */
320 rs->sr_err = LDAP_NO_SUCH_OBJECT;
321 rs->sr_matched = matchedDN;
329 backsql_FreeRow_x( &row, op->o_tmpmemctx );
331 Debug( LDAP_DEBUG_TRACE,
332 "<==backsql_dn2id(\"%s\"): err=%d\n",
333 ndn->bv_val, res, 0 );
334 if ( sth != SQL_NULL_HSTMT ) {
335 SQLFreeStmt( sth, SQL_DROP );
338 if ( !BER_BVISNULL( &realndn ) && realndn.bv_val != ndn->bv_val ) {
339 ch_free( realndn.bv_val );
346 backsql_count_children(
350 unsigned long *nchildren )
352 backsql_info *bi = (backsql_info *)op->o_bd->be_private;
353 SQLHSTMT sth = SQL_NULL_HSTMT;
356 int res = LDAP_SUCCESS;
358 Debug( LDAP_DEBUG_TRACE, "==>backsql_count_children(): dn=\"%s\"\n",
361 if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) {
362 Debug( LDAP_DEBUG_TRACE,
363 "backsql_count_children(): DN \"%s\" (%ld bytes) "
364 "exceeds max DN length (%d):\n",
365 dn->bv_val, dn->bv_len, BACKSQL_MAX_DN_LEN );
370 Debug(LDAP_DEBUG_TRACE, "children id query \"%s\"\n",
371 bi->sql_has_children_query, 0, 0);
372 assert( bi->sql_has_children_query != NULL );
373 rc = backsql_Prepare( dbh, &sth, bi->sql_has_children_query, 0 );
374 if ( rc != SQL_SUCCESS ) {
375 Debug( LDAP_DEBUG_TRACE,
376 "backsql_count_children(): error preparing SQL:\n%s",
377 bi->sql_has_children_query, 0, 0);
378 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
379 SQLFreeStmt( sth, SQL_DROP );
383 rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, dn );
384 if ( rc != SQL_SUCCESS) {
386 Debug( LDAP_DEBUG_TRACE, "backsql_count_children(): "
387 "error binding dn=\"%s\" parameter:\n",
389 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
390 SQLFreeStmt( sth, SQL_DROP );
394 rc = SQLExecute( sth );
395 if ( rc != SQL_SUCCESS ) {
396 Debug( LDAP_DEBUG_TRACE, "backsql_count_children(): "
397 "error executing query (\"%s\", \"%s\"):\n",
398 bi->sql_has_children_query, dn->bv_val, 0 );
399 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
400 SQLFreeStmt( sth, SQL_DROP );
404 backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx );
406 rc = SQLFetch( sth );
407 if ( BACKSQL_SUCCESS( rc ) ) {
410 *nchildren = strtol( row.cols[ 0 ], &end, 0 );
411 if ( end[ 0 ] != '\0' && end[0] != '.' ) {
412 /* FIXME: braindead RDBMSes return
413 * a fractional number from COUNT!
421 backsql_FreeRow_x( &row, op->o_tmpmemctx );
423 SQLFreeStmt( sth, SQL_DROP );
425 Debug( LDAP_DEBUG_TRACE, "<==backsql_count_children(): %lu\n",
432 backsql_has_children(
437 unsigned long nchildren;
440 rc = backsql_count_children( op, dbh, dn, &nchildren );
442 if ( rc == LDAP_SUCCESS ) {
443 return nchildren > 0 ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
450 backsql_get_attr_vals( void *v_at, void *v_bsi )
452 backsql_at_map_rec *at = v_at;
453 backsql_srch_info *bsi = v_bsi;
454 backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;
456 SQLHSTMT sth = SQL_NULL_HSTMT;
462 #ifdef BACKSQL_COUNTQUERY
464 countsize = sizeof( count ),
467 Attribute *attr = NULL;
469 slap_mr_normalize_func *normfunc = NULL;
470 #endif /* BACKSQL_COUNTQUERY */
471 #ifdef BACKSQL_PRETTY_VALIDATE
472 slap_syntax_validate_func *validate = NULL;
473 slap_syntax_transform_func *pretty = NULL;
474 #endif /* BACKSQL_PRETTY_VALIDATE */
476 assert( at != NULL );
477 assert( bsi != NULL );
479 #ifdef BACKSQL_ARBITRARY_KEY
480 Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
481 "oc=\"%s\" attr=\"%s\" keyval=%s\n",
482 BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val,
483 bsi->bsi_c_eid->eid_keyval.bv_val );
484 #else /* ! BACKSQL_ARBITRARY_KEY */
485 Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
486 "oc=\"%s\" attr=\"%s\" keyval=%ld\n",
487 BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val,
488 bsi->bsi_c_eid->eid_keyval );
489 #endif /* ! BACKSQL_ARBITRARY_KEY */
491 #ifdef BACKSQL_PRETTY_VALIDATE
492 validate = at->bam_ad->ad_type->sat_syntax->ssyn_validate;
493 pretty = at->bam_ad->ad_type->sat_syntax->ssyn_pretty;
495 if ( validate == NULL && pretty == NULL ) {
498 #endif /* BACKSQL_PRETTY_VALIDATE */
500 #ifdef BACKSQL_COUNTQUERY
501 if ( at->bam_ad->ad_type->sat_equality ) {
502 normfunc = at->bam_ad->ad_type->sat_equality->smr_normalize;
505 /* Count how many rows will be returned. This avoids memory
506 * fragmentation that can result from loading the values in
507 * one by one and using realloc()
509 rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_countquery, 0 );
510 if ( rc != SQL_SUCCESS ) {
511 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
512 "error preparing count query: %s\n",
513 at->bam_countquery, 0, 0 );
514 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
518 rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
519 &bsi->bsi_c_eid->eid_keyval );
520 if ( rc != SQL_SUCCESS ) {
521 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
522 "error binding key value parameter\n", 0, 0, 0 );
523 SQLFreeStmt( sth, SQL_DROP );
527 rc = SQLExecute( sth );
528 if ( ! BACKSQL_SUCCESS( rc ) ) {
529 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
530 "error executing attribute count query '%s'\n",
531 at->bam_countquery, 0, 0 );
532 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
533 SQLFreeStmt( sth, SQL_DROP );
537 SQLBindCol( sth, (SQLUSMALLINT)1, SQL_C_LONG,
539 (SQLINTEGER)sizeof( count ),
542 rc = SQLFetch( sth );
543 if ( rc != SQL_SUCCESS ) {
544 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
545 "error fetch results of count query: %s\n",
546 at->bam_countquery, 0, 0 );
547 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
548 SQLFreeStmt( sth, SQL_DROP );
552 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
553 "number of values in query: %lu\n", count, 0, 0 );
554 SQLFreeStmt( sth, SQL_DROP );
559 attr = attr_find( bsi->bsi_e->e_attrs, at->bam_ad );
560 if ( attr != NULL ) {
563 if ( attr->a_vals != NULL ) {
564 for ( ; !BER_BVISNULL( &attr->a_vals[ oldcount ] ); oldcount++ )
568 tmp = ch_realloc( attr->a_vals, ( oldcount + count + 1 ) * sizeof( struct berval ) );
573 memset( &attr->a_vals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) );
576 tmp = ch_realloc( attr->a_nvals, ( oldcount + count + 1 ) * sizeof( struct berval ) );
581 memset( &attr->a_nvals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) );
584 attr->a_nvals = attr->a_vals;
590 /* Make space for the array of values */
591 attr = (Attribute *) ch_malloc( sizeof( Attribute ) );
592 attr->a_desc = at->bam_ad;
595 attr->a_vals = ch_calloc( count + 1, sizeof( struct berval ) );
596 if ( attr->a_vals == NULL ) {
597 Debug( LDAP_DEBUG_TRACE, "Out of memory!\n", 0,0,0 );
601 memset( attr->a_vals, 0, ( count + 1 ) * sizeof( struct berval ) );
603 attr->a_nvals = ch_calloc( count + 1, sizeof( struct berval ) );
604 if ( attr->a_nvals == NULL ) {
605 ch_free( attr->a_vals );
610 memset( attr->a_nvals, 0, ( count + 1 ) * sizeof( struct berval ) );
614 attr->a_nvals = attr->a_vals;
617 #endif /* BACKSQL_COUNTQUERY */
619 rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_query, 0 );
620 if ( rc != SQL_SUCCESS ) {
621 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
622 "error preparing query: %s\n", at->bam_query, 0, 0 );
623 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
627 rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
628 &bsi->bsi_c_eid->eid_keyval );
629 if ( rc != SQL_SUCCESS ) {
630 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
631 "error binding key value parameter\n", 0, 0, 0 );
636 #ifdef BACKSQL_ARBITRARY_KEY
637 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
638 "query=\"%s\" keyval=%s\n", at->bam_query,
639 bsi->bsi_c_eid->eid_keyval.bv_val, 0 );
640 #else /* !BACKSQL_ARBITRARY_KEY */
641 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
642 "query=\"%s\" keyval=%d\n", at->bam_query,
643 bsi->bsi_c_eid->eid_keyval, 0 );
644 #endif /* ! BACKSQL_ARBITRARY_KEY */
645 #endif /* BACKSQL_TRACE */
647 rc = SQLExecute( sth );
648 if ( ! BACKSQL_SUCCESS( rc ) ) {
649 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
650 "error executing attribute query \"%s\"\n",
651 at->bam_query, 0, 0 );
652 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
653 SQLFreeStmt( sth, SQL_DROP );
657 backsql_BindRowAsStrings_x( sth, &row, bsi->bsi_op->o_tmpmemctx );
658 #ifdef BACKSQL_COUNTQUERY
660 #endif /* BACKSQL_COUNTQUERY */
661 for ( rc = SQLFetch( sth ), k = 0;
662 BACKSQL_SUCCESS( rc );
663 rc = SQLFetch( sth ), k++ )
665 for ( i = 0; i < (unsigned long)row.ncols; i++ ) {
667 if ( row.value_len[ i ] > 0 ) {
671 AttributeDescription *ad = NULL;
674 retval = slap_bv2ad( &row.col_names[ i ], &ad, &text );
675 if ( retval != LDAP_SUCCESS ) {
676 Debug( LDAP_DEBUG_ANY,
677 "==>backsql_get_attr_vals(\"%s\"): "
678 "unable to find AttributeDescription %s "
680 bsi->bsi_e->e_name.bv_val,
681 row.col_names[ i ].bv_val, retval );
686 if ( ad != at->bam_ad ) {
687 Debug( LDAP_DEBUG_ANY,
688 "==>backsql_get_attr_vals(\"%s\"): "
689 "column name %s differs from "
690 "AttributeDescription %s\n",
691 bsi->bsi_e->e_name.bv_val,
693 at->bam_ad->ad_cname.bv_val );
697 #endif /* BACKSQL_TRACE */
700 * FIXME: what if a binary
703 ber_str2bv( row.cols[ i ], 0, 0, &bv );
705 #ifdef BACKSQL_PRETTY_VALIDATE
709 retval = pretty( at->bam_ad->ad_type->sat_syntax,
710 &bv, &pbv, bsi->bsi_op->o_tmpmemctx );
714 retval = validate( at->bam_ad->ad_type->sat_syntax,
718 if ( retval != LDAP_SUCCESS ) {
719 char buf[ SLAP_TEXT_BUFLEN ];
721 /* FIXME: we're ignoring invalid values,
722 * but we're accepting the attributes;
723 * should we fail at all? */
724 snprintf( buf, sizeof( buf ),
725 "unable to %s value #%lu "
726 "of AttributeDescription %s",
727 pretty ? "prettify" : "validate",
729 at->bam_ad->ad_cname.bv_val );
730 Debug( LDAP_DEBUG_TRACE,
731 "==>backsql_get_attr_vals(\"%s\"): "
733 bsi->bsi_e->e_name.bv_val, buf, retval );
736 #endif /* BACKSQL_PRETTY_VALIDATE */
738 #ifndef BACKSQL_COUNTQUERY
739 (void)backsql_entry_addattr( bsi->bsi_e,
741 bsi->bsi_op->o_tmpmemctx );
743 #else /* BACKSQL_COUNTQUERY */
747 retval = (*normfunc)( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
748 at->bam_ad->ad_type->sat_syntax,
749 at->bam_ad->ad_type->sat_equality,
751 bsi->bsi_op->o_tmpmemctx );
753 if ( retval != LDAP_SUCCESS ) {
754 char buf[ SLAP_TEXT_BUFLEN ];
756 /* FIXME: we're ignoring invalid values,
757 * but we're accepting the attributes;
758 * should we fail at all? */
759 snprintf( buf, sizeof( buf ),
760 "unable to normalize value #%lu "
761 "of AttributeDescription %s",
763 at->bam_ad->ad_cname.bv_val );
764 Debug( LDAP_DEBUG_TRACE,
765 "==>backsql_get_attr_vals(\"%s\"): "
767 bsi->bsi_e->e_name.bv_val, buf, retval );
769 #ifdef BACKSQL_PRETTY_VALIDATE
771 bsi->bsi_op->o_tmpfree( bv.bv_val,
772 bsi->bsi_op->o_tmpmemctx );
774 #endif /* BACKSQL_PRETTY_VALIDATE */
778 ber_dupbv( &attr->a_nvals[ j ], &nbv );
779 bsi->bsi_op->o_tmpfree( nbv.bv_val,
780 bsi->bsi_op->o_tmpmemctx );
783 ber_dupbv( &attr->a_vals[ j ], &bv );
785 assert( j < oldcount + count );
787 #endif /* BACKSQL_COUNTQUERY */
789 #ifdef BACKSQL_PRETTY_VALIDATE
791 bsi->bsi_op->o_tmpfree( bv.bv_val,
792 bsi->bsi_op->o_tmpmemctx );
794 #endif /* BACKSQL_PRETTY_VALIDATE */
797 Debug( LDAP_DEBUG_TRACE, "prec=%d\n",
798 (int)row.col_prec[ i ], 0, 0 );
801 Debug( LDAP_DEBUG_TRACE, "NULL value "
802 "in this row for attribute \"%s\"\n",
803 row.col_names[ i ].bv_val, 0, 0 );
804 #endif /* BACKSQL_TRACE */
809 #ifdef BACKSQL_COUNTQUERY
810 if ( BER_BVISNULL( &attr->a_vals[ 0 ] ) ) {
811 /* don't leave around attributes with no values */
814 } else if ( append ) {
817 for ( ap = &bsi->bsi_e->e_attrs; (*ap) != NULL; ap = &(*ap)->a_next )
821 #endif /* BACKSQL_COUNTQUERY */
823 SQLFreeStmt( sth, SQL_DROP );
824 Debug( LDAP_DEBUG_TRACE, "<==backsql_get_attr_vals()\n", 0, 0, 0 );
826 if ( at->bam_next ) {
827 res = backsql_get_attr_vals( at->bam_next, v_bsi );
834 #endif /* BACKSQL_TRACE */
835 backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx );
841 backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
843 Operation *op = bsi->bsi_op;
844 backsql_info *bi = (backsql_info *)op->o_bd->be_private;
848 Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );
850 assert( bsi->bsi_e != NULL );
852 memset( bsi->bsi_e, 0, sizeof( Entry ) );
854 if ( bi->sql_baseObject && BACKSQL_IS_BASEOBJECT_ID( &eid->eid_id ) ) {
857 e = entry_dup( bi->sql_baseObject );
859 return LDAP_NO_MEMORY;
867 ber_dupbv_x( &bsi->bsi_e->e_name, &eid->eid_dn, op->o_tmpmemctx );
868 ber_dupbv_x( &bsi->bsi_e->e_nname, &eid->eid_ndn, op->o_tmpmemctx );
870 bsi->bsi_e->e_attrs = NULL;
871 bsi->bsi_e->e_private = NULL;
873 bsi->bsi_oc = backsql_id2oc( bsi->bsi_op->o_bd->be_private,
875 bsi->bsi_c_eid = eid;
877 #ifndef BACKSQL_ARBITRARY_KEY
879 bsi->bsi_e->e_id = eid->eid_id;
880 #endif /* ! BACKSQL_ARBITRARY_KEY */
882 rc = attr_merge_normalize_one( bsi->bsi_e,
883 slap_schema.si_ad_objectClass,
884 &bsi->bsi_oc->bom_oc->soc_cname,
885 bsi->bsi_op->o_tmpmemctx );
886 if ( rc != LDAP_SUCCESS ) {
887 backsql_entry_clean( op, bsi->bsi_e );
891 if ( bsi->bsi_attrs == NULL || ( bsi->bsi_flags & BSQL_SF_ALL_USER ) )
893 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
894 "retrieving all attributes\n", 0, 0, 0 );
895 avl_apply( bsi->bsi_oc->bom_attrs, backsql_get_attr_vals,
896 bsi, 0, AVL_INORDER );
899 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
900 "custom attribute list\n", 0, 0, 0 );
901 for ( i = 0; !BER_BVISNULL( &bsi->bsi_attrs[ i ].an_name ); i++ ) {
902 backsql_at_map_rec **vat;
903 AttributeName *an = &bsi->bsi_attrs[ i ];
906 /* if one of the attributes listed here is
907 * a subtype of another, it must be ignored,
908 * because subtypes are already dealt with
909 * by backsql_supad2at()
911 for ( j = 0; !BER_BVISNULL( &bsi->bsi_attrs[ j ].an_name ); j++ ) {
918 if ( is_at_subtype( an->an_desc->ad_type,
919 bsi->bsi_attrs[ j ].an_desc->ad_type ) )
925 rc = backsql_supad2at( bsi->bsi_oc, an->an_desc, &vat );
926 if ( rc != 0 || vat == NULL ) {
927 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
928 "attribute \"%s\" is not defined "
929 "for objectlass \"%s\"\n",
931 BACKSQL_OC_NAME( bsi->bsi_oc ), 0 );
935 for ( j = 0; vat[j]; j++ ) {
936 backsql_get_attr_vals( vat[j], bsi );
945 if ( bsi->bsi_flags & BSQL_SF_RETURN_ENTRYUUID ) {
946 Attribute *a_entryUUID,
949 a_entryUUID = backsql_operational_entryUUID( bi, eid );
950 if ( a_entryUUID != NULL ) {
951 for ( ap = &bsi->bsi_e->e_attrs;
953 ap = &(*ap)->a_next );
959 if ( ( bsi->bsi_flags & BSQL_SF_ALL_OPER )
960 || an_find( bsi->bsi_attrs, &AllOper )
961 || an_find( bsi->bsi_attrs, &slap_schema.si_ad_structuralObjectClass->ad_cname ) )
963 if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
965 const char *text = NULL;
966 char textbuf[ 1024 ];
967 size_t textlen = sizeof( textbuf );
971 int rc = LDAP_SUCCESS;
973 a = attr_find( bsi->bsi_e->e_attrs,
974 slap_schema.si_ad_objectClass );
979 bv[ 0 ] = bsi->bsi_oc->bom_oc->soc_cname;
980 BER_BVZERO( &bv[ 1 ] );
984 rc = structural_class( nvals, &soc, NULL,
985 &text, textbuf, textlen );
986 if ( rc != LDAP_SUCCESS ) {
987 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
988 "structural_class() failed %d (%s)\n",
989 bsi->bsi_e->e_name.bv_val,
990 rc, text ? text : "" );
991 backsql_entry_clean( op, bsi->bsi_e );
995 if ( !bvmatch( &soc, &bsi->bsi_oc->bom_oc->soc_cname ) ) {
996 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
997 "computed structuralObjectClass %s "
998 "does not match objectClass %s associated "
1000 bsi->bsi_e->e_name.bv_val, soc.bv_val,
1001 bsi->bsi_oc->bom_oc->soc_cname.bv_val );
1002 backsql_entry_clean( op, bsi->bsi_e );
1007 rc = attr_merge_normalize_one( bsi->bsi_e,
1008 slap_schema.si_ad_structuralObjectClass,
1009 &bsi->bsi_oc->bom_oc->soc_cname,
1010 bsi->bsi_op->o_tmpmemctx );
1011 if ( rc != LDAP_SUCCESS ) {
1012 backsql_entry_clean( op, bsi->bsi_e );
1018 Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );
1020 return LDAP_SUCCESS;