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_entryID_dup( backsql_entryID *src, void *ctx )
43 if ( src == NULL ) return NULL;
45 dst = slap_sl_calloc( 1, sizeof( backsql_entryID ), ctx );
46 ber_dupbv_x( &dst->eid_ndn, &src->eid_ndn, ctx );
47 if ( src->eid_dn.bv_val == src->eid_ndn.bv_val ) {
48 dst->eid_dn = dst->eid_ndn;
50 ber_dupbv_x( &dst->eid_dn, &src->eid_dn, ctx );
53 #ifdef BACKSQL_ARBITRARY_KEY
54 ber_dupbv_x( &dst->eid_id, &src->eid_id, ctx );
55 ber_dupbv_x( &dst->eid_keyval, &src->eid_keyval, ctx );
56 #else /* ! BACKSQL_ARBITRARY_KEY */
57 dst->eid_id = src->eid_id;
58 dst->eid_keyval = src->eid_keyval;
59 #endif /* ! BACKSQL_ARBITRARY_KEY */
61 dst->eid_oc_id = src->eid_oc_id;
67 backsql_free_entryID( backsql_entryID *id, int freeit, void *ctx )
69 backsql_entryID *next;
75 if ( !BER_BVISNULL( &id->eid_ndn ) ) {
76 if ( !BER_BVISNULL( &id->eid_dn )
77 && id->eid_dn.bv_val != id->eid_ndn.bv_val )
79 slap_sl_free( id->eid_dn.bv_val, ctx );
80 BER_BVZERO( &id->eid_dn );
83 slap_sl_free( id->eid_ndn.bv_val, ctx );
84 BER_BVZERO( &id->eid_ndn );
87 #ifdef BACKSQL_ARBITRARY_KEY
88 if ( !BER_BVISNULL( &id->eid_id ) ) {
89 slap_sl_free( id->eid_id.bv_val, ctx );
90 BER_BVZERO( &id->eid_id );
93 if ( !BER_BVISNULL( &id->eid_keyval ) ) {
94 slap_sl_free( id->eid_keyval.bv_val, ctx );
95 BER_BVZERO( &id->eid_keyval );
97 #endif /* BACKSQL_ARBITRARY_KEY */
100 slap_sl_free( id, ctx );
107 * NOTE: the dn must be normalized
119 backsql_info *bi = op->o_bd->be_private;
120 SQLHSTMT sth = SQL_NULL_HSTMT;
121 BACKSQL_ROW_NTS row = { 0 };
124 struct berval realndn = BER_BVNULL;
127 char upperdn[ BACKSQL_MAX_DN_LEN + 1 ];
132 * NOTE: id can be NULL; in this case, the function
133 * simply checks whether the DN can be successfully
134 * turned into an ID, returning LDAP_SUCCESS for
135 * positive cases, or the most appropriate error
138 Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(\"%s\")%s%s\n",
139 ndn->bv_val, id == NULL ? " (no ID expected)" : "",
140 matched ? " matched expected" : "" );
143 /* NOTE: trap inconsistencies */
144 assert( BER_BVISNULL( &id->eid_ndn ) );
147 if ( ndn->bv_len > BACKSQL_MAX_DN_LEN ) {
148 Debug( LDAP_DEBUG_TRACE,
149 " backsql_dn2id(\"%s\"): DN length=%ld "
150 "exceeds max DN length %d:\n",
151 ndn->bv_val, ndn->bv_len, BACKSQL_MAX_DN_LEN );
155 /* return baseObject if available and matches */
156 /* FIXME: if ndn is already mucked, we cannot check this */
157 if ( bi->sql_baseObject != NULL &&
158 dn_match( ndn, &bi->sql_baseObject->e_nname ) )
161 #ifdef BACKSQL_ARBITRARY_KEY
162 ber_dupbv_x( &id->eid_id, &backsql_baseObject_bv,
164 ber_dupbv_x( &id->eid_keyval, &backsql_baseObject_bv,
166 #else /* ! BACKSQL_ARBITRARY_KEY */
167 id->eid_id = BACKSQL_BASEOBJECT_ID;
168 id->eid_keyval = BACKSQL_BASEOBJECT_KEYVAL;
169 #endif /* ! BACKSQL_ARBITRARY_KEY */
170 id->eid_oc_id = BACKSQL_BASEOBJECT_OC;
172 ber_dupbv_x( &id->eid_ndn, &bi->sql_baseObject->e_nname,
174 ber_dupbv_x( &id->eid_dn, &bi->sql_baseObject->e_name,
184 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): id_query \"%s\"\n",
185 ndn->bv_val, bi->sql_id_query, 0 );
186 assert( bi->sql_id_query != NULL );
187 rc = backsql_Prepare( dbh, &sth, bi->sql_id_query, 0 );
188 if ( rc != SQL_SUCCESS ) {
189 Debug( LDAP_DEBUG_TRACE,
190 " backsql_dn2id(\"%s\"): "
191 "error preparing SQL:\n %s",
192 ndn->bv_val, bi->sql_id_query, 0 );
193 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
200 if ( backsql_api_dn2odbc( op, rs, &realndn ) ) {
201 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
202 "backsql_api_dn2odbc(\"%s\") failed\n",
203 ndn->bv_val, realndn.bv_val, 0 );
209 if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
211 * Prepare an upper cased, byte reversed version
212 * that can be searched using indexes
215 for ( i = 0, j = realndn.bv_len - 1; realndn.bv_val[ i ]; i++, j--)
217 upperdn[ i ] = realndn.bv_val[ j ];
220 ldap_pvt_str2upper( upperdn );
222 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
224 ndn->bv_val, upperdn, 0 );
225 ber_str2bv( upperdn, 0, 0, &tbbDN );
228 if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
229 AC_MEMCPY( upperdn, realndn.bv_val, realndn.bv_len + 1 );
230 ldap_pvt_str2upper( upperdn );
231 Debug( LDAP_DEBUG_TRACE,
232 " backsql_dn2id(\"%s\"): "
234 ndn->bv_val, upperdn, 0 );
235 ber_str2bv( upperdn, 0, 0, &tbbDN );
242 rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &tbbDN );
243 if ( rc != SQL_SUCCESS) {
245 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
246 "error binding dn=\"%s\" parameter:\n",
247 ndn->bv_val, tbbDN.bv_val, 0 );
248 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
253 rc = SQLExecute( sth );
254 if ( rc != SQL_SUCCESS ) {
255 Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): "
256 "error executing query (\"%s\", \"%s\"):\n",
257 ndn->bv_val, bi->sql_id_query, tbbDN.bv_val );
258 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
263 backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx );
264 rc = SQLFetch( sth );
265 if ( BACKSQL_SUCCESS( rc ) ) {
266 char buf[ SLAP_TEXT_BUFLEN ];
269 snprintf( buf, sizeof(buf),
270 "id=%s keyval=%s oc_id=%s dn=%s",
271 row.cols[ 0 ], row.cols[ 1 ],
272 row.cols[ 2 ], row.cols[ 3 ] );
273 Debug( LDAP_DEBUG_TRACE,
274 " backsql_dn2id(\"%s\"): %s\n",
275 ndn->bv_val, buf, 0 );
276 #endif /* LDAP_DEBUG */
284 #ifdef BACKSQL_ARBITRARY_KEY
285 ber_str2bv_x( row.cols[ 0 ], 0, 1, &id->eid_id,
287 ber_str2bv_x( row.cols[ 1 ], 0, 1, &id->eid_keyval,
289 #else /* ! BACKSQL_ARBITRARY_KEY */
290 if ( lutil_atoulx( &id->eid_id, row.cols[ 0 ], 0 ) != 0 ) {
294 if ( lutil_atoulx( &id->eid_keyval, row.cols[ 1 ], 0 ) != 0 ) {
298 #endif /* ! BACKSQL_ARBITRARY_KEY */
299 if ( lutil_atoulx( &id->eid_oc_id, row.cols[ 2 ], 0 ) != 0 ) {
304 ber_str2bv( row.cols[ 3 ], 0, 0, &dn );
306 if ( backsql_api_odbc2dn( op, rs, &dn ) ) {
311 res = dnPrettyNormal( NULL, &dn,
312 &id->eid_dn, &id->eid_ndn,
314 if ( res != LDAP_SUCCESS ) {
315 Debug( LDAP_DEBUG_TRACE,
316 " backsql_dn2id(\"%s\"): "
317 "dnPrettyNormal failed (%d: %s)\n",
319 ldap_err2string( res ) );
322 (void)backsql_free_entryID( id, 0, op->o_tmpmemctx );
325 if ( dn.bv_val != row.cols[ 3 ] ) {
331 res = LDAP_NO_SUCH_OBJECT;
333 struct berval pdn = *ndn;
338 rs->sr_matched = NULL;
339 while ( !be_issuffix( op->o_bd, &pdn ) ) {
340 char *matchedDN = NULL;
342 dnParent( &pdn, &pdn );
345 * Empty DN ("") defaults to LDAP_SUCCESS
347 rs->sr_err = backsql_dn2id( op, rs, dbh, &pdn, id, 0, 1 );
348 switch ( rs->sr_err ) {
349 case LDAP_NO_SUCH_OBJECT:
350 /* try another one */
354 matchedDN = pdn.bv_val;
355 /* fail over to next case */
358 rs->sr_err = LDAP_NO_SUCH_OBJECT;
359 rs->sr_matched = matchedDN;
367 backsql_FreeRow_x( &row, op->o_tmpmemctx );
369 Debug( LDAP_DEBUG_TRACE,
370 "<==backsql_dn2id(\"%s\"): err=%d\n",
371 ndn->bv_val, res, 0 );
372 if ( sth != SQL_NULL_HSTMT ) {
373 SQLFreeStmt( sth, SQL_DROP );
376 if ( !BER_BVISNULL( &realndn ) && realndn.bv_val != ndn->bv_val ) {
377 ch_free( realndn.bv_val );
384 backsql_count_children(
388 unsigned long *nchildren )
390 backsql_info *bi = (backsql_info *)op->o_bd->be_private;
391 SQLHSTMT sth = SQL_NULL_HSTMT;
394 int res = LDAP_SUCCESS;
396 Debug( LDAP_DEBUG_TRACE, "==>backsql_count_children(): dn=\"%s\"\n",
399 if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) {
400 Debug( LDAP_DEBUG_TRACE,
401 "backsql_count_children(): DN \"%s\" (%ld bytes) "
402 "exceeds max DN length (%d):\n",
403 dn->bv_val, dn->bv_len, BACKSQL_MAX_DN_LEN );
408 Debug(LDAP_DEBUG_TRACE, "children id query \"%s\"\n",
409 bi->sql_has_children_query, 0, 0);
410 assert( bi->sql_has_children_query != NULL );
411 rc = backsql_Prepare( dbh, &sth, bi->sql_has_children_query, 0 );
412 if ( rc != SQL_SUCCESS ) {
413 Debug( LDAP_DEBUG_TRACE,
414 "backsql_count_children(): error preparing SQL:\n%s",
415 bi->sql_has_children_query, 0, 0);
416 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
417 SQLFreeStmt( sth, SQL_DROP );
421 rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, dn );
422 if ( rc != SQL_SUCCESS) {
424 Debug( LDAP_DEBUG_TRACE, "backsql_count_children(): "
425 "error binding dn=\"%s\" parameter:\n",
427 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
428 SQLFreeStmt( sth, SQL_DROP );
432 rc = SQLExecute( sth );
433 if ( rc != SQL_SUCCESS ) {
434 Debug( LDAP_DEBUG_TRACE, "backsql_count_children(): "
435 "error executing query (\"%s\", \"%s\"):\n",
436 bi->sql_has_children_query, dn->bv_val, 0 );
437 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
438 SQLFreeStmt( sth, SQL_DROP );
442 backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx );
444 rc = SQLFetch( sth );
445 if ( BACKSQL_SUCCESS( rc ) ) {
448 *nchildren = strtol( row.cols[ 0 ], &end, 0 );
449 if ( end == row.cols[ 0 ] ) {
453 switch ( end[ 0 ] ) {
460 /* FIXME: braindead RDBMSes return
461 * a fractional number from COUNT!
463 if ( lutil_atoul( &ul, end + 1 ) != 0 || ul != 0 ) {
476 backsql_FreeRow_x( &row, op->o_tmpmemctx );
478 SQLFreeStmt( sth, SQL_DROP );
480 Debug( LDAP_DEBUG_TRACE, "<==backsql_count_children(): %lu\n",
487 backsql_has_children(
492 unsigned long nchildren;
495 rc = backsql_count_children( op, dbh, dn, &nchildren );
497 if ( rc == LDAP_SUCCESS ) {
498 return nchildren > 0 ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
505 backsql_get_attr_vals( void *v_at, void *v_bsi )
507 backsql_at_map_rec *at = v_at;
508 backsql_srch_info *bsi = v_bsi;
509 backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;
511 SQLHSTMT sth = SQL_NULL_HSTMT;
517 #ifdef BACKSQL_COUNTQUERY
521 SQLLEN countsize = sizeof( count );
522 Attribute *attr = NULL;
524 slap_mr_normalize_func *normfunc = NULL;
525 #endif /* BACKSQL_COUNTQUERY */
526 #ifdef BACKSQL_PRETTY_VALIDATE
527 slap_syntax_validate_func *validate = NULL;
528 slap_syntax_transform_func *pretty = NULL;
529 #endif /* BACKSQL_PRETTY_VALIDATE */
531 assert( at != NULL );
532 assert( bsi != NULL );
534 #ifdef BACKSQL_ARBITRARY_KEY
535 Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
536 "oc=\"%s\" attr=\"%s\" keyval=%s\n",
537 BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val,
538 bsi->bsi_c_eid->eid_keyval.bv_val );
539 #else /* ! BACKSQL_ARBITRARY_KEY */
540 Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
541 "oc=\"%s\" attr=\"%s\" keyval=%ld\n",
542 BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val,
543 bsi->bsi_c_eid->eid_keyval );
544 #endif /* ! BACKSQL_ARBITRARY_KEY */
546 #ifdef BACKSQL_PRETTY_VALIDATE
547 validate = at->bam_true_ad->ad_type->sat_syntax->ssyn_validate;
548 pretty = at->bam_true_ad->ad_type->sat_syntax->ssyn_pretty;
550 if ( validate == NULL && pretty == NULL ) {
553 #endif /* BACKSQL_PRETTY_VALIDATE */
555 #ifdef BACKSQL_COUNTQUERY
556 if ( at->bam_true_ad->ad_type->sat_equality ) {
557 normfunc = at->bam_true_ad->ad_type->sat_equality->smr_normalize;
560 /* Count how many rows will be returned. This avoids memory
561 * fragmentation that can result from loading the values in
562 * one by one and using realloc()
564 rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_countquery, 0 );
565 if ( rc != SQL_SUCCESS ) {
566 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
567 "error preparing count query: %s\n",
568 at->bam_countquery, 0, 0 );
569 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
573 rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
574 &bsi->bsi_c_eid->eid_keyval );
575 if ( rc != SQL_SUCCESS ) {
576 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
577 "error binding key value parameter\n", 0, 0, 0 );
578 SQLFreeStmt( sth, SQL_DROP );
582 rc = SQLExecute( sth );
583 if ( ! BACKSQL_SUCCESS( rc ) ) {
584 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
585 "error executing attribute count query '%s'\n",
586 at->bam_countquery, 0, 0 );
587 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
588 SQLFreeStmt( sth, SQL_DROP );
592 SQLBindCol( sth, (SQLUSMALLINT)1, SQL_C_LONG,
594 (SQLINTEGER)sizeof( count ),
597 rc = SQLFetch( sth );
598 if ( rc != SQL_SUCCESS ) {
599 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
600 "error fetch results of count query: %s\n",
601 at->bam_countquery, 0, 0 );
602 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
603 SQLFreeStmt( sth, SQL_DROP );
607 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
608 "number of values in query: %u\n", count, 0, 0 );
609 SQLFreeStmt( sth, SQL_DROP );
614 attr = attr_find( bsi->bsi_e->e_attrs, at->bam_true_ad );
615 if ( attr != NULL ) {
618 if ( attr->a_vals != NULL ) {
619 for ( ; !BER_BVISNULL( &attr->a_vals[ oldcount ] ); oldcount++ )
623 tmp = ch_realloc( attr->a_vals, ( oldcount + count + 1 ) * sizeof( struct berval ) );
628 memset( &attr->a_vals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) );
631 tmp = ch_realloc( attr->a_nvals, ( oldcount + count + 1 ) * sizeof( struct berval ) );
636 memset( &attr->a_nvals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) );
639 attr->a_nvals = attr->a_vals;
645 /* Make space for the array of values */
646 attr = attr_alloc( at->bam_true_ad );
647 attr->a_vals = ch_calloc( count + 1, sizeof( struct berval ) );
648 if ( attr->a_vals == NULL ) {
649 Debug( LDAP_DEBUG_TRACE, "Out of memory!\n", 0,0,0 );
653 memset( attr->a_vals, 0, ( count + 1 ) * sizeof( struct berval ) );
655 attr->a_nvals = ch_calloc( count + 1, sizeof( struct berval ) );
656 if ( attr->a_nvals == NULL ) {
657 ch_free( attr->a_vals );
662 memset( attr->a_nvals, 0, ( count + 1 ) * sizeof( struct berval ) );
666 attr->a_nvals = attr->a_vals;
669 #endif /* BACKSQL_COUNTQUERY */
671 rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_query, 0 );
672 if ( rc != SQL_SUCCESS ) {
673 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
674 "error preparing query: %s\n", at->bam_query, 0, 0 );
675 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
676 #ifdef BACKSQL_COUNTQUERY
680 #endif /* BACKSQL_COUNTQUERY */
684 rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
685 &bsi->bsi_c_eid->eid_keyval );
686 if ( rc != SQL_SUCCESS ) {
687 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
688 "error binding key value parameter\n", 0, 0, 0 );
689 #ifdef BACKSQL_COUNTQUERY
693 #endif /* BACKSQL_COUNTQUERY */
698 #ifdef BACKSQL_ARBITRARY_KEY
699 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
700 "query=\"%s\" keyval=%s\n", at->bam_query,
701 bsi->bsi_c_eid->eid_keyval.bv_val, 0 );
702 #else /* !BACKSQL_ARBITRARY_KEY */
703 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
704 "query=\"%s\" keyval=%d\n", at->bam_query,
705 bsi->bsi_c_eid->eid_keyval, 0 );
706 #endif /* ! BACKSQL_ARBITRARY_KEY */
707 #endif /* BACKSQL_TRACE */
709 rc = SQLExecute( sth );
710 if ( ! BACKSQL_SUCCESS( rc ) ) {
711 Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
712 "error executing attribute query \"%s\"\n",
713 at->bam_query, 0, 0 );
714 backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
715 SQLFreeStmt( sth, SQL_DROP );
716 #ifdef BACKSQL_COUNTQUERY
720 #endif /* BACKSQL_COUNTQUERY */
724 backsql_BindRowAsStrings_x( sth, &row, bsi->bsi_op->o_tmpmemctx );
725 #ifdef BACKSQL_COUNTQUERY
727 #endif /* BACKSQL_COUNTQUERY */
728 for ( rc = SQLFetch( sth ), k = 0;
729 BACKSQL_SUCCESS( rc );
730 rc = SQLFetch( sth ), k++ )
732 for ( i = 0; i < (unsigned long)row.ncols; i++ ) {
734 if ( row.value_len[ i ] > 0 ) {
738 AttributeDescription *ad = NULL;
741 retval = slap_bv2ad( &row.col_names[ i ], &ad, &text );
742 if ( retval != LDAP_SUCCESS ) {
743 Debug( LDAP_DEBUG_ANY,
744 "==>backsql_get_attr_vals(\"%s\"): "
745 "unable to find AttributeDescription %s "
747 bsi->bsi_e->e_name.bv_val,
748 row.col_names[ i ].bv_val, retval );
753 if ( ad != at->bam_ad ) {
754 Debug( LDAP_DEBUG_ANY,
755 "==>backsql_get_attr_vals(\"%s\"): "
756 "column name %s differs from "
757 "AttributeDescription %s\n",
758 bsi->bsi_e->e_name.bv_val,
760 at->bam_ad->ad_cname.bv_val );
764 #endif /* BACKSQL_TRACE */
766 /* ITS#3386, ITS#3113 - 20070308
767 * If a binary is fetched?
768 * must use the actual size read
771 if ( BACKSQL_IS_BINARY( row.col_type[ i ] ) ) {
773 Debug( LDAP_DEBUG_ANY,
774 "==>backsql_get_attr_vals(\"%s\"): "
775 "column name %s: data is binary; "
776 "using database size %ld\n",
777 bsi->bsi_e->e_name.bv_val,
779 row.value_len[ i ] );
780 #endif /* BACKSQL_TRACE */
781 bv.bv_val = row.cols[ i ];
782 bv.bv_len = row.value_len[ i ];
785 ber_str2bv( row.cols[ i ], 0, 0, &bv );
788 #ifdef BACKSQL_PRETTY_VALIDATE
792 retval = pretty( at->bam_true_ad->ad_type->sat_syntax,
793 &bv, &pbv, bsi->bsi_op->o_tmpmemctx );
797 retval = validate( at->bam_true_ad->ad_type->sat_syntax,
801 if ( retval != LDAP_SUCCESS ) {
802 char buf[ SLAP_TEXT_BUFLEN ];
804 /* FIXME: we're ignoring invalid values,
805 * but we're accepting the attributes;
806 * should we fail at all? */
807 snprintf( buf, sizeof( buf ),
808 "unable to %s value #%lu "
809 "of AttributeDescription %s",
810 pretty ? "prettify" : "validate",
812 at->bam_ad->ad_cname.bv_val );
813 Debug( LDAP_DEBUG_TRACE,
814 "==>backsql_get_attr_vals(\"%s\"): "
816 bsi->bsi_e->e_name.bv_val, buf, retval );
819 #endif /* BACKSQL_PRETTY_VALIDATE */
821 #ifndef BACKSQL_COUNTQUERY
822 (void)backsql_entry_addattr( bsi->bsi_e,
823 at->bam_true_ad, &bv,
824 bsi->bsi_op->o_tmpmemctx );
826 #else /* BACKSQL_COUNTQUERY */
830 retval = (*normfunc)( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
831 at->bam_true_ad->ad_type->sat_syntax,
832 at->bam_true_ad->ad_type->sat_equality,
834 bsi->bsi_op->o_tmpmemctx );
836 if ( retval != LDAP_SUCCESS ) {
837 char buf[ SLAP_TEXT_BUFLEN ];
839 /* FIXME: we're ignoring invalid values,
840 * but we're accepting the attributes;
841 * should we fail at all? */
842 snprintf( buf, sizeof( buf ),
843 "unable to normalize value #%lu "
844 "of AttributeDescription %s",
846 at->bam_ad->ad_cname.bv_val );
847 Debug( LDAP_DEBUG_TRACE,
848 "==>backsql_get_attr_vals(\"%s\"): "
850 bsi->bsi_e->e_name.bv_val, buf, retval );
852 #ifdef BACKSQL_PRETTY_VALIDATE
854 bsi->bsi_op->o_tmpfree( bv.bv_val,
855 bsi->bsi_op->o_tmpmemctx );
857 #endif /* BACKSQL_PRETTY_VALIDATE */
861 ber_dupbv( &attr->a_nvals[ j ], &nbv );
862 bsi->bsi_op->o_tmpfree( nbv.bv_val,
863 bsi->bsi_op->o_tmpmemctx );
866 ber_dupbv( &attr->a_vals[ j ], &bv );
868 assert( j < oldcount + count );
870 #endif /* BACKSQL_COUNTQUERY */
872 #ifdef BACKSQL_PRETTY_VALIDATE
874 bsi->bsi_op->o_tmpfree( bv.bv_val,
875 bsi->bsi_op->o_tmpmemctx );
877 #endif /* BACKSQL_PRETTY_VALIDATE */
880 Debug( LDAP_DEBUG_TRACE, "prec=%d\n",
881 (int)row.col_prec[ i ], 0, 0 );
884 Debug( LDAP_DEBUG_TRACE, "NULL value "
885 "in this row for attribute \"%s\"\n",
886 row.col_names[ i ].bv_val, 0, 0 );
887 #endif /* BACKSQL_TRACE */
892 #ifdef BACKSQL_COUNTQUERY
893 if ( BER_BVISNULL( &attr->a_vals[ 0 ] ) ) {
894 /* don't leave around attributes with no values */
897 } else if ( append ) {
900 for ( ap = &bsi->bsi_e->e_attrs; (*ap) != NULL; ap = &(*ap)->a_next )
904 #endif /* BACKSQL_COUNTQUERY */
906 SQLFreeStmt( sth, SQL_DROP );
907 Debug( LDAP_DEBUG_TRACE, "<==backsql_get_attr_vals()\n", 0, 0, 0 );
909 if ( at->bam_next ) {
910 res = backsql_get_attr_vals( at->bam_next, v_bsi );
917 #endif /* BACKSQL_TRACE */
918 backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx );
924 backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
926 Operation *op = bsi->bsi_op;
927 backsql_info *bi = (backsql_info *)op->o_bd->be_private;
931 Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );
933 assert( bsi->bsi_e != NULL );
935 memset( bsi->bsi_e, 0, sizeof( Entry ) );
937 if ( bi->sql_baseObject && BACKSQL_IS_BASEOBJECT_ID( &eid->eid_id ) ) {
940 e = entry_dup( bi->sql_baseObject );
942 return LDAP_NO_MEMORY;
950 ber_dupbv_x( &bsi->bsi_e->e_name, &eid->eid_dn, op->o_tmpmemctx );
951 ber_dupbv_x( &bsi->bsi_e->e_nname, &eid->eid_ndn, op->o_tmpmemctx );
953 bsi->bsi_e->e_attrs = NULL;
954 bsi->bsi_e->e_private = NULL;
956 bsi->bsi_oc = backsql_id2oc( bsi->bsi_op->o_bd->be_private,
958 bsi->bsi_c_eid = eid;
960 #ifndef BACKSQL_ARBITRARY_KEY
962 bsi->bsi_e->e_id = eid->eid_id;
963 #endif /* ! BACKSQL_ARBITRARY_KEY */
965 rc = attr_merge_normalize_one( bsi->bsi_e,
966 slap_schema.si_ad_objectClass,
967 &bsi->bsi_oc->bom_oc->soc_cname,
968 bsi->bsi_op->o_tmpmemctx );
969 if ( rc != LDAP_SUCCESS ) {
970 backsql_entry_clean( op, bsi->bsi_e );
974 if ( bsi->bsi_attrs == NULL || ( bsi->bsi_flags & BSQL_SF_ALL_USER ) )
976 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
977 "retrieving all attributes\n", 0, 0, 0 );
978 avl_apply( bsi->bsi_oc->bom_attrs, backsql_get_attr_vals,
979 bsi, 0, AVL_INORDER );
982 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
983 "custom attribute list\n", 0, 0, 0 );
984 for ( i = 0; !BER_BVISNULL( &bsi->bsi_attrs[ i ].an_name ); i++ ) {
985 backsql_at_map_rec **vat;
986 AttributeName *an = &bsi->bsi_attrs[ i ];
989 /* if one of the attributes listed here is
990 * a subtype of another, it must be ignored,
991 * because subtypes are already dealt with
992 * by backsql_supad2at()
994 for ( j = 0; !BER_BVISNULL( &bsi->bsi_attrs[ j ].an_name ); j++ ) {
1001 if ( is_at_subtype( an->an_desc->ad_type,
1002 bsi->bsi_attrs[ j ].an_desc->ad_type ) )
1008 rc = backsql_supad2at( bsi->bsi_oc, an->an_desc, &vat );
1009 if ( rc != 0 || vat == NULL ) {
1010 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
1011 "attribute \"%s\" is not defined "
1012 "for objectlass \"%s\"\n",
1014 BACKSQL_OC_NAME( bsi->bsi_oc ), 0 );
1018 for ( j = 0; vat[j]; j++ ) {
1019 backsql_get_attr_vals( vat[j], bsi );
1028 if ( bsi->bsi_flags & BSQL_SF_RETURN_ENTRYUUID ) {
1029 Attribute *a_entryUUID,
1032 a_entryUUID = backsql_operational_entryUUID( bi, eid );
1033 if ( a_entryUUID != NULL ) {
1034 for ( ap = &bsi->bsi_e->e_attrs;
1036 ap = &(*ap)->a_next );
1042 if ( ( bsi->bsi_flags & BSQL_SF_ALL_OPER )
1043 || an_find( bsi->bsi_attrs, &AllOper )
1044 || an_find( bsi->bsi_attrs, &slap_schema.si_ad_structuralObjectClass->ad_cname ) )
1046 ObjectClass *soc = NULL;
1048 if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
1050 const char *text = NULL;
1051 char textbuf[ 1024 ];
1052 size_t textlen = sizeof( textbuf );
1053 struct berval bv[ 2 ],
1055 int rc = LDAP_SUCCESS;
1057 a = attr_find( bsi->bsi_e->e_attrs,
1058 slap_schema.si_ad_objectClass );
1063 bv[ 0 ] = bsi->bsi_oc->bom_oc->soc_cname;
1064 BER_BVZERO( &bv[ 1 ] );
1068 rc = structural_class( nvals, &soc, NULL,
1069 &text, textbuf, textlen, op->o_tmpmemctx );
1070 if ( rc != LDAP_SUCCESS ) {
1071 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
1072 "structural_class() failed %d (%s)\n",
1073 bsi->bsi_e->e_name.bv_val,
1074 rc, text ? text : "" );
1075 backsql_entry_clean( op, bsi->bsi_e );
1079 if ( !bvmatch( &soc->soc_cname, &bsi->bsi_oc->bom_oc->soc_cname ) ) {
1080 if ( !is_object_subclass( bsi->bsi_oc->bom_oc, soc ) ) {
1081 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
1082 "computed structuralObjectClass %s "
1083 "does not match objectClass %s associated "
1085 bsi->bsi_e->e_name.bv_val, soc->soc_cname.bv_val,
1086 bsi->bsi_oc->bom_oc->soc_cname.bv_val );
1087 backsql_entry_clean( op, bsi->bsi_e );
1091 Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
1092 "computed structuralObjectClass %s "
1093 "is subclass of objectClass %s associated "
1095 bsi->bsi_e->e_name.bv_val, soc->soc_cname.bv_val,
1096 bsi->bsi_oc->bom_oc->soc_cname.bv_val );
1100 soc = bsi->bsi_oc->bom_oc;
1103 rc = attr_merge_normalize_one( bsi->bsi_e,
1104 slap_schema.si_ad_structuralObjectClass,
1106 bsi->bsi_op->o_tmpmemctx );
1107 if ( rc != LDAP_SUCCESS ) {
1108 backsql_entry_clean( op, bsi->bsi_e );
1114 Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );
1116 return LDAP_SUCCESS;