1 /* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/entry-id.c,v 1.67.2.6 2008/02/11 23:26:48 kurt Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2008 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
= src
->eid_oc
;
62 dst
->eid_oc_id
= src
->eid_oc_id
;
68 backsql_free_entryID( backsql_entryID
*id
, int freeit
, void *ctx
)
70 backsql_entryID
*next
;
76 if ( !BER_BVISNULL( &id
->eid_ndn
) ) {
77 if ( !BER_BVISNULL( &id
->eid_dn
)
78 && id
->eid_dn
.bv_val
!= id
->eid_ndn
.bv_val
)
80 slap_sl_free( id
->eid_dn
.bv_val
, ctx
);
81 BER_BVZERO( &id
->eid_dn
);
84 slap_sl_free( id
->eid_ndn
.bv_val
, ctx
);
85 BER_BVZERO( &id
->eid_ndn
);
88 #ifdef BACKSQL_ARBITRARY_KEY
89 if ( !BER_BVISNULL( &id
->eid_id
) ) {
90 slap_sl_free( id
->eid_id
.bv_val
, ctx
);
91 BER_BVZERO( &id
->eid_id
);
94 if ( !BER_BVISNULL( &id
->eid_keyval
) ) {
95 slap_sl_free( id
->eid_keyval
.bv_val
, ctx
);
96 BER_BVZERO( &id
->eid_keyval
);
98 #endif /* BACKSQL_ARBITRARY_KEY */
101 slap_sl_free( id
, ctx
);
108 * NOTE: the dn must be normalized
120 backsql_info
*bi
= op
->o_bd
->be_private
;
121 SQLHSTMT sth
= SQL_NULL_HSTMT
;
122 BACKSQL_ROW_NTS row
= { 0 };
125 struct berval realndn
= BER_BVNULL
;
128 char upperdn
[ BACKSQL_MAX_DN_LEN
+ 1 ];
133 * NOTE: id can be NULL; in this case, the function
134 * simply checks whether the DN can be successfully
135 * turned into an ID, returning LDAP_SUCCESS for
136 * positive cases, or the most appropriate error
139 Debug( LDAP_DEBUG_TRACE
, "==>backsql_dn2id(\"%s\")%s%s\n",
140 ndn
->bv_val
, id
== NULL
? " (no ID expected)" : "",
141 matched
? " matched expected" : "" );
144 /* NOTE: trap inconsistencies */
145 assert( BER_BVISNULL( &id
->eid_ndn
) );
148 if ( ndn
->bv_len
> BACKSQL_MAX_DN_LEN
) {
149 Debug( LDAP_DEBUG_TRACE
,
150 " backsql_dn2id(\"%s\"): DN length=%ld "
151 "exceeds max DN length %d:\n",
152 ndn
->bv_val
, ndn
->bv_len
, BACKSQL_MAX_DN_LEN
);
156 /* return baseObject if available and matches */
157 /* FIXME: if ndn is already mucked, we cannot check this */
158 if ( bi
->sql_baseObject
!= NULL
&&
159 dn_match( ndn
, &bi
->sql_baseObject
->e_nname
) )
162 #ifdef BACKSQL_ARBITRARY_KEY
163 ber_dupbv_x( &id
->eid_id
, &backsql_baseObject_bv
,
165 ber_dupbv_x( &id
->eid_keyval
, &backsql_baseObject_bv
,
167 #else /* ! BACKSQL_ARBITRARY_KEY */
168 id
->eid_id
= BACKSQL_BASEOBJECT_ID
;
169 id
->eid_keyval
= BACKSQL_BASEOBJECT_KEYVAL
;
170 #endif /* ! BACKSQL_ARBITRARY_KEY */
171 id
->eid_oc_id
= BACKSQL_BASEOBJECT_OC
;
173 ber_dupbv_x( &id
->eid_ndn
, &bi
->sql_baseObject
->e_nname
,
175 ber_dupbv_x( &id
->eid_dn
, &bi
->sql_baseObject
->e_name
,
185 Debug( LDAP_DEBUG_TRACE
, " backsql_dn2id(\"%s\"): id_query \"%s\"\n",
186 ndn
->bv_val
, bi
->sql_id_query
, 0 );
187 assert( bi
->sql_id_query
!= NULL
);
188 rc
= backsql_Prepare( dbh
, &sth
, bi
->sql_id_query
, 0 );
189 if ( rc
!= SQL_SUCCESS
) {
190 Debug( LDAP_DEBUG_TRACE
,
191 " backsql_dn2id(\"%s\"): "
192 "error preparing SQL:\n %s",
193 ndn
->bv_val
, bi
->sql_id_query
, 0 );
194 backsql_PrintErrors( bi
->sql_db_env
, dbh
, sth
, rc
);
201 if ( backsql_api_dn2odbc( op
, rs
, &realndn
) ) {
202 Debug( LDAP_DEBUG_TRACE
, " backsql_dn2id(\"%s\"): "
203 "backsql_api_dn2odbc(\"%s\") failed\n",
204 ndn
->bv_val
, realndn
.bv_val
, 0 );
210 if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi
) ) {
212 * Prepare an upper cased, byte reversed version
213 * that can be searched using indexes
216 for ( i
= 0, j
= realndn
.bv_len
- 1; realndn
.bv_val
[ i
]; i
++, j
--)
218 upperdn
[ i
] = realndn
.bv_val
[ j
];
221 ldap_pvt_str2upper( upperdn
);
223 Debug( LDAP_DEBUG_TRACE
, " backsql_dn2id(\"%s\"): "
225 ndn
->bv_val
, upperdn
, 0 );
226 ber_str2bv( upperdn
, 0, 0, &tbbDN
);
229 if ( BACKSQL_USE_REVERSE_DN( bi
) ) {
230 AC_MEMCPY( upperdn
, realndn
.bv_val
, realndn
.bv_len
+ 1 );
231 ldap_pvt_str2upper( upperdn
);
232 Debug( LDAP_DEBUG_TRACE
,
233 " backsql_dn2id(\"%s\"): "
235 ndn
->bv_val
, upperdn
, 0 );
236 ber_str2bv( upperdn
, 0, 0, &tbbDN
);
243 rc
= backsql_BindParamBerVal( sth
, 1, SQL_PARAM_INPUT
, &tbbDN
);
244 if ( rc
!= SQL_SUCCESS
) {
246 Debug( LDAP_DEBUG_TRACE
, " backsql_dn2id(\"%s\"): "
247 "error binding dn=\"%s\" parameter:\n",
248 ndn
->bv_val
, tbbDN
.bv_val
, 0 );
249 backsql_PrintErrors( bi
->sql_db_env
, dbh
, sth
, rc
);
254 rc
= SQLExecute( sth
);
255 if ( rc
!= SQL_SUCCESS
) {
256 Debug( LDAP_DEBUG_TRACE
, " backsql_dn2id(\"%s\"): "
257 "error executing query (\"%s\", \"%s\"):\n",
258 ndn
->bv_val
, bi
->sql_id_query
, tbbDN
.bv_val
);
259 backsql_PrintErrors( bi
->sql_db_env
, dbh
, sth
, rc
);
264 backsql_BindRowAsStrings_x( sth
, &row
, op
->o_tmpmemctx
);
265 rc
= SQLFetch( sth
);
266 if ( BACKSQL_SUCCESS( rc
) ) {
267 char buf
[ SLAP_TEXT_BUFLEN
];
270 snprintf( buf
, sizeof(buf
),
271 "id=%s keyval=%s oc_id=%s dn=%s",
272 row
.cols
[ 0 ], row
.cols
[ 1 ],
273 row
.cols
[ 2 ], row
.cols
[ 3 ] );
274 Debug( LDAP_DEBUG_TRACE
,
275 " backsql_dn2id(\"%s\"): %s\n",
276 ndn
->bv_val
, buf
, 0 );
277 #endif /* LDAP_DEBUG */
285 #ifdef BACKSQL_ARBITRARY_KEY
286 ber_str2bv_x( row
.cols
[ 0 ], 0, 1, &id
->eid_id
,
288 ber_str2bv_x( row
.cols
[ 1 ], 0, 1, &id
->eid_keyval
,
290 #else /* ! BACKSQL_ARBITRARY_KEY */
291 if ( lutil_atoulx( &id
->eid_id
, row
.cols
[ 0 ], 0 ) != 0 ) {
295 if ( lutil_atoulx( &id
->eid_keyval
, row
.cols
[ 1 ], 0 ) != 0 ) {
299 #endif /* ! BACKSQL_ARBITRARY_KEY */
300 if ( lutil_atoulx( &id
->eid_oc_id
, row
.cols
[ 2 ], 0 ) != 0 ) {
305 ber_str2bv( row
.cols
[ 3 ], 0, 0, &dn
);
307 if ( backsql_api_odbc2dn( op
, rs
, &dn
) ) {
312 res
= dnPrettyNormal( NULL
, &dn
,
313 &id
->eid_dn
, &id
->eid_ndn
,
315 if ( res
!= LDAP_SUCCESS
) {
316 Debug( LDAP_DEBUG_TRACE
,
317 " backsql_dn2id(\"%s\"): "
318 "dnPrettyNormal failed (%d: %s)\n",
320 ldap_err2string( res
) );
323 (void)backsql_free_entryID( id
, 0, op
->o_tmpmemctx
);
326 if ( dn
.bv_val
!= row
.cols
[ 3 ] ) {
332 res
= LDAP_NO_SUCH_OBJECT
;
334 struct berval pdn
= *ndn
;
339 rs
->sr_matched
= NULL
;
340 while ( !be_issuffix( op
->o_bd
, &pdn
) ) {
341 char *matchedDN
= NULL
;
343 dnParent( &pdn
, &pdn
);
346 * Empty DN ("") defaults to LDAP_SUCCESS
348 rs
->sr_err
= backsql_dn2id( op
, rs
, dbh
, &pdn
, id
, 0, 1 );
349 switch ( rs
->sr_err
) {
350 case LDAP_NO_SUCH_OBJECT
:
351 /* try another one */
355 matchedDN
= pdn
.bv_val
;
356 /* fail over to next case */
359 rs
->sr_err
= LDAP_NO_SUCH_OBJECT
;
360 rs
->sr_matched
= matchedDN
;
368 backsql_FreeRow_x( &row
, op
->o_tmpmemctx
);
370 Debug( LDAP_DEBUG_TRACE
,
371 "<==backsql_dn2id(\"%s\"): err=%d\n",
372 ndn
->bv_val
, res
, 0 );
373 if ( sth
!= SQL_NULL_HSTMT
) {
374 SQLFreeStmt( sth
, SQL_DROP
);
377 if ( !BER_BVISNULL( &realndn
) && realndn
.bv_val
!= ndn
->bv_val
) {
378 ch_free( realndn
.bv_val
);
385 backsql_count_children(
389 unsigned long *nchildren
)
391 backsql_info
*bi
= (backsql_info
*)op
->o_bd
->be_private
;
392 SQLHSTMT sth
= SQL_NULL_HSTMT
;
395 int res
= LDAP_SUCCESS
;
397 Debug( LDAP_DEBUG_TRACE
, "==>backsql_count_children(): dn=\"%s\"\n",
400 if ( dn
->bv_len
> BACKSQL_MAX_DN_LEN
) {
401 Debug( LDAP_DEBUG_TRACE
,
402 "backsql_count_children(): DN \"%s\" (%ld bytes) "
403 "exceeds max DN length (%d):\n",
404 dn
->bv_val
, dn
->bv_len
, BACKSQL_MAX_DN_LEN
);
409 Debug(LDAP_DEBUG_TRACE
, "children id query \"%s\"\n",
410 bi
->sql_has_children_query
, 0, 0);
411 assert( bi
->sql_has_children_query
!= NULL
);
412 rc
= backsql_Prepare( dbh
, &sth
, bi
->sql_has_children_query
, 0 );
413 if ( rc
!= SQL_SUCCESS
) {
414 Debug( LDAP_DEBUG_TRACE
,
415 "backsql_count_children(): error preparing SQL:\n%s",
416 bi
->sql_has_children_query
, 0, 0);
417 backsql_PrintErrors( bi
->sql_db_env
, dbh
, sth
, rc
);
418 SQLFreeStmt( sth
, SQL_DROP
);
422 rc
= backsql_BindParamBerVal( sth
, 1, SQL_PARAM_INPUT
, dn
);
423 if ( rc
!= SQL_SUCCESS
) {
425 Debug( LDAP_DEBUG_TRACE
, "backsql_count_children(): "
426 "error binding dn=\"%s\" parameter:\n",
428 backsql_PrintErrors( bi
->sql_db_env
, dbh
, sth
, rc
);
429 SQLFreeStmt( sth
, SQL_DROP
);
433 rc
= SQLExecute( sth
);
434 if ( rc
!= SQL_SUCCESS
) {
435 Debug( LDAP_DEBUG_TRACE
, "backsql_count_children(): "
436 "error executing query (\"%s\", \"%s\"):\n",
437 bi
->sql_has_children_query
, dn
->bv_val
, 0 );
438 backsql_PrintErrors( bi
->sql_db_env
, dbh
, sth
, rc
);
439 SQLFreeStmt( sth
, SQL_DROP
);
443 backsql_BindRowAsStrings_x( sth
, &row
, op
->o_tmpmemctx
);
445 rc
= SQLFetch( sth
);
446 if ( BACKSQL_SUCCESS( rc
) ) {
449 *nchildren
= strtol( row
.cols
[ 0 ], &end
, 0 );
450 if ( end
== row
.cols
[ 0 ] ) {
454 switch ( end
[ 0 ] ) {
461 /* FIXME: braindead RDBMSes return
462 * a fractional number from COUNT!
464 if ( lutil_atoul( &ul
, end
+ 1 ) != 0 || ul
!= 0 ) {
477 backsql_FreeRow_x( &row
, op
->o_tmpmemctx
);
479 SQLFreeStmt( sth
, SQL_DROP
);
481 Debug( LDAP_DEBUG_TRACE
, "<==backsql_count_children(): %lu\n",
488 backsql_has_children(
493 unsigned long nchildren
;
496 rc
= backsql_count_children( op
, dbh
, dn
, &nchildren
);
498 if ( rc
== LDAP_SUCCESS
) {
499 return nchildren
> 0 ? LDAP_COMPARE_TRUE
: LDAP_COMPARE_FALSE
;
506 backsql_get_attr_vals( void *v_at
, void *v_bsi
)
508 backsql_at_map_rec
*at
= v_at
;
509 backsql_srch_info
*bsi
= v_bsi
;
510 backsql_info
*bi
= (backsql_info
*)bsi
->bsi_op
->o_bd
->be_private
;
512 SQLHSTMT sth
= SQL_NULL_HSTMT
;
518 #ifdef BACKSQL_COUNTQUERY
522 SQLLEN countsize
= sizeof( count
);
523 Attribute
*attr
= NULL
;
525 slap_mr_normalize_func
*normfunc
= NULL
;
526 #endif /* BACKSQL_COUNTQUERY */
527 #ifdef BACKSQL_PRETTY_VALIDATE
528 slap_syntax_validate_func
*validate
= NULL
;
529 slap_syntax_transform_func
*pretty
= NULL
;
530 #endif /* BACKSQL_PRETTY_VALIDATE */
532 assert( at
!= NULL
);
533 assert( bsi
!= NULL
);
535 #ifdef BACKSQL_ARBITRARY_KEY
536 Debug( LDAP_DEBUG_TRACE
, "==>backsql_get_attr_vals(): "
537 "oc=\"%s\" attr=\"%s\" keyval=%s\n",
538 BACKSQL_OC_NAME( bsi
->bsi_oc
), at
->bam_ad
->ad_cname
.bv_val
,
539 bsi
->bsi_c_eid
->eid_keyval
.bv_val
);
540 #else /* ! BACKSQL_ARBITRARY_KEY */
541 Debug( LDAP_DEBUG_TRACE
, "==>backsql_get_attr_vals(): "
542 "oc=\"%s\" attr=\"%s\" keyval=%ld\n",
543 BACKSQL_OC_NAME( bsi
->bsi_oc
), at
->bam_ad
->ad_cname
.bv_val
,
544 bsi
->bsi_c_eid
->eid_keyval
);
545 #endif /* ! BACKSQL_ARBITRARY_KEY */
547 #ifdef BACKSQL_PRETTY_VALIDATE
548 validate
= at
->bam_true_ad
->ad_type
->sat_syntax
->ssyn_validate
;
549 pretty
= at
->bam_true_ad
->ad_type
->sat_syntax
->ssyn_pretty
;
551 if ( validate
== NULL
&& pretty
== NULL
) {
554 #endif /* BACKSQL_PRETTY_VALIDATE */
556 #ifdef BACKSQL_COUNTQUERY
557 if ( at
->bam_true_ad
->ad_type
->sat_equality
) {
558 normfunc
= at
->bam_true_ad
->ad_type
->sat_equality
->smr_normalize
;
561 /* Count how many rows will be returned. This avoids memory
562 * fragmentation that can result from loading the values in
563 * one by one and using realloc()
565 rc
= backsql_Prepare( bsi
->bsi_dbh
, &sth
, at
->bam_countquery
, 0 );
566 if ( rc
!= SQL_SUCCESS
) {
567 Debug( LDAP_DEBUG_TRACE
, "backsql_get_attr_vals(): "
568 "error preparing count query: %s\n",
569 at
->bam_countquery
, 0, 0 );
570 backsql_PrintErrors( bi
->sql_db_env
, bsi
->bsi_dbh
, sth
, rc
);
574 rc
= backsql_BindParamID( sth
, 1, SQL_PARAM_INPUT
,
575 &bsi
->bsi_c_eid
->eid_keyval
);
576 if ( rc
!= SQL_SUCCESS
) {
577 Debug( LDAP_DEBUG_TRACE
, "backsql_get_attr_vals(): "
578 "error binding key value parameter\n", 0, 0, 0 );
579 SQLFreeStmt( sth
, SQL_DROP
);
583 rc
= SQLExecute( sth
);
584 if ( ! BACKSQL_SUCCESS( rc
) ) {
585 Debug( LDAP_DEBUG_TRACE
, "backsql_get_attr_vals(): "
586 "error executing attribute count query '%s'\n",
587 at
->bam_countquery
, 0, 0 );
588 backsql_PrintErrors( bi
->sql_db_env
, bsi
->bsi_dbh
, sth
, rc
);
589 SQLFreeStmt( sth
, SQL_DROP
);
593 SQLBindCol( sth
, (SQLUSMALLINT
)1, SQL_C_LONG
,
595 (SQLINTEGER
)sizeof( count
),
598 rc
= SQLFetch( sth
);
599 if ( rc
!= SQL_SUCCESS
) {
600 Debug( LDAP_DEBUG_TRACE
, "backsql_get_attr_vals(): "
601 "error fetch results of count query: %s\n",
602 at
->bam_countquery
, 0, 0 );
603 backsql_PrintErrors( bi
->sql_db_env
, bsi
->bsi_dbh
, sth
, rc
);
604 SQLFreeStmt( sth
, SQL_DROP
);
608 Debug( LDAP_DEBUG_TRACE
, "backsql_get_attr_vals(): "
609 "number of values in query: %u\n", count
, 0, 0 );
610 SQLFreeStmt( sth
, SQL_DROP
);
615 attr
= attr_find( bsi
->bsi_e
->e_attrs
, at
->bam_true_ad
);
616 if ( attr
!= NULL
) {
619 if ( attr
->a_vals
!= NULL
) {
620 oldcount
= attr
->a_numvals
;
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
;
641 attr
->a_numvals
+= count
;
646 /* Make space for the array of values */
647 attr
= attr_alloc( at
->bam_true_ad
);
648 attr
->a_numvals
= count
;
649 attr
->a_vals
= ch_calloc( count
+ 1, sizeof( struct berval
) );
650 if ( attr
->a_vals
== NULL
) {
651 Debug( LDAP_DEBUG_TRACE
, "Out of memory!\n", 0,0,0 );
656 attr
->a_nvals
= ch_calloc( count
+ 1, sizeof( struct berval
) );
657 if ( attr
->a_nvals
== NULL
) {
658 ch_free( attr
->a_vals
);
665 attr
->a_nvals
= attr
->a_vals
;
668 #endif /* BACKSQL_COUNTQUERY */
670 rc
= backsql_Prepare( bsi
->bsi_dbh
, &sth
, at
->bam_query
, 0 );
671 if ( rc
!= SQL_SUCCESS
) {
672 Debug( LDAP_DEBUG_TRACE
, "backsql_get_attr_vals(): "
673 "error preparing query: %s\n", at
->bam_query
, 0, 0 );
674 backsql_PrintErrors( bi
->sql_db_env
, bsi
->bsi_dbh
, sth
, rc
);
675 #ifdef BACKSQL_COUNTQUERY
679 #endif /* BACKSQL_COUNTQUERY */
683 rc
= backsql_BindParamID( sth
, 1, SQL_PARAM_INPUT
,
684 &bsi
->bsi_c_eid
->eid_keyval
);
685 if ( rc
!= SQL_SUCCESS
) {
686 Debug( LDAP_DEBUG_TRACE
, "backsql_get_attr_vals(): "
687 "error binding key value parameter\n", 0, 0, 0 );
688 #ifdef BACKSQL_COUNTQUERY
692 #endif /* BACKSQL_COUNTQUERY */
697 #ifdef BACKSQL_ARBITRARY_KEY
698 Debug( LDAP_DEBUG_TRACE
, "backsql_get_attr_vals(): "
699 "query=\"%s\" keyval=%s\n", at
->bam_query
,
700 bsi
->bsi_c_eid
->eid_keyval
.bv_val
, 0 );
701 #else /* !BACKSQL_ARBITRARY_KEY */
702 Debug( LDAP_DEBUG_TRACE
, "backsql_get_attr_vals(): "
703 "query=\"%s\" keyval=%d\n", at
->bam_query
,
704 bsi
->bsi_c_eid
->eid_keyval
, 0 );
705 #endif /* ! BACKSQL_ARBITRARY_KEY */
706 #endif /* BACKSQL_TRACE */
708 rc
= SQLExecute( sth
);
709 if ( ! BACKSQL_SUCCESS( rc
) ) {
710 Debug( LDAP_DEBUG_TRACE
, "backsql_get_attr_vals(): "
711 "error executing attribute query \"%s\"\n",
712 at
->bam_query
, 0, 0 );
713 backsql_PrintErrors( bi
->sql_db_env
, bsi
->bsi_dbh
, sth
, rc
);
714 SQLFreeStmt( sth
, SQL_DROP
);
715 #ifdef BACKSQL_COUNTQUERY
719 #endif /* BACKSQL_COUNTQUERY */
723 backsql_BindRowAsStrings_x( sth
, &row
, bsi
->bsi_op
->o_tmpmemctx
);
724 #ifdef BACKSQL_COUNTQUERY
726 #endif /* BACKSQL_COUNTQUERY */
727 for ( rc
= SQLFetch( sth
), k
= 0;
728 BACKSQL_SUCCESS( rc
);
729 rc
= SQLFetch( sth
), k
++ )
731 for ( i
= 0; i
< (unsigned long)row
.ncols
; i
++ ) {
733 if ( row
.value_len
[ i
] > 0 ) {
737 AttributeDescription
*ad
= NULL
;
740 retval
= slap_bv2ad( &row
.col_names
[ i
], &ad
, &text
);
741 if ( retval
!= LDAP_SUCCESS
) {
742 Debug( LDAP_DEBUG_ANY
,
743 "==>backsql_get_attr_vals(\"%s\"): "
744 "unable to find AttributeDescription %s "
746 bsi
->bsi_e
->e_name
.bv_val
,
747 row
.col_names
[ i
].bv_val
, retval
);
752 if ( ad
!= at
->bam_ad
) {
753 Debug( LDAP_DEBUG_ANY
,
754 "==>backsql_get_attr_vals(\"%s\"): "
755 "column name %s differs from "
756 "AttributeDescription %s\n",
757 bsi
->bsi_e
->e_name
.bv_val
,
759 at
->bam_ad
->ad_cname
.bv_val
);
763 #endif /* BACKSQL_TRACE */
765 /* ITS#3386, ITS#3113 - 20070308
766 * If a binary is fetched?
767 * must use the actual size read
770 if ( BACKSQL_IS_BINARY( row
.col_type
[ i
] ) ) {
772 Debug( LDAP_DEBUG_ANY
,
773 "==>backsql_get_attr_vals(\"%s\"): "
774 "column name %s: data is binary; "
775 "using database size %ld\n",
776 bsi
->bsi_e
->e_name
.bv_val
,
778 row
.value_len
[ i
] );
779 #endif /* BACKSQL_TRACE */
780 bv
.bv_val
= row
.cols
[ i
];
781 bv
.bv_len
= row
.value_len
[ i
];
784 ber_str2bv( row
.cols
[ i
], 0, 0, &bv
);
787 #ifdef BACKSQL_PRETTY_VALIDATE
791 retval
= pretty( at
->bam_true_ad
->ad_type
->sat_syntax
,
792 &bv
, &pbv
, bsi
->bsi_op
->o_tmpmemctx
);
796 retval
= validate( at
->bam_true_ad
->ad_type
->sat_syntax
,
800 if ( retval
!= LDAP_SUCCESS
) {
801 char buf
[ SLAP_TEXT_BUFLEN
];
803 /* FIXME: we're ignoring invalid values,
804 * but we're accepting the attributes;
805 * should we fail at all? */
806 snprintf( buf
, sizeof( buf
),
807 "unable to %s value #%lu "
808 "of AttributeDescription %s",
809 pretty
? "prettify" : "validate",
811 at
->bam_ad
->ad_cname
.bv_val
);
812 Debug( LDAP_DEBUG_TRACE
,
813 "==>backsql_get_attr_vals(\"%s\"): "
815 bsi
->bsi_e
->e_name
.bv_val
, buf
, retval
);
818 #endif /* BACKSQL_PRETTY_VALIDATE */
820 #ifndef BACKSQL_COUNTQUERY
821 (void)backsql_entry_addattr( bsi
->bsi_e
,
822 at
->bam_true_ad
, &bv
,
823 bsi
->bsi_op
->o_tmpmemctx
);
825 #else /* BACKSQL_COUNTQUERY */
829 retval
= (*normfunc
)( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX
,
830 at
->bam_true_ad
->ad_type
->sat_syntax
,
831 at
->bam_true_ad
->ad_type
->sat_equality
,
833 bsi
->bsi_op
->o_tmpmemctx
);
835 if ( retval
!= LDAP_SUCCESS
) {
836 char buf
[ SLAP_TEXT_BUFLEN
];
838 /* FIXME: we're ignoring invalid values,
839 * but we're accepting the attributes;
840 * should we fail at all? */
841 snprintf( buf
, sizeof( buf
),
842 "unable to normalize value #%lu "
843 "of AttributeDescription %s",
845 at
->bam_ad
->ad_cname
.bv_val
);
846 Debug( LDAP_DEBUG_TRACE
,
847 "==>backsql_get_attr_vals(\"%s\"): "
849 bsi
->bsi_e
->e_name
.bv_val
, buf
, retval
);
851 #ifdef BACKSQL_PRETTY_VALIDATE
853 bsi
->bsi_op
->o_tmpfree( bv
.bv_val
,
854 bsi
->bsi_op
->o_tmpmemctx
);
856 #endif /* BACKSQL_PRETTY_VALIDATE */
860 ber_dupbv( &attr
->a_nvals
[ j
], &nbv
);
861 bsi
->bsi_op
->o_tmpfree( nbv
.bv_val
,
862 bsi
->bsi_op
->o_tmpmemctx
);
865 ber_dupbv( &attr
->a_vals
[ j
], &bv
);
867 assert( j
< oldcount
+ count
);
869 #endif /* BACKSQL_COUNTQUERY */
871 #ifdef BACKSQL_PRETTY_VALIDATE
873 bsi
->bsi_op
->o_tmpfree( bv
.bv_val
,
874 bsi
->bsi_op
->o_tmpmemctx
);
876 #endif /* BACKSQL_PRETTY_VALIDATE */
879 Debug( LDAP_DEBUG_TRACE
, "prec=%d\n",
880 (int)row
.col_prec
[ i
], 0, 0 );
883 Debug( LDAP_DEBUG_TRACE
, "NULL value "
884 "in this row for attribute \"%s\"\n",
885 row
.col_names
[ i
].bv_val
, 0, 0 );
886 #endif /* BACKSQL_TRACE */
891 #ifdef BACKSQL_COUNTQUERY
892 if ( BER_BVISNULL( &attr
->a_vals
[ 0 ] ) ) {
893 /* don't leave around attributes with no values */
896 } else if ( append
) {
899 for ( ap
= &bsi
->bsi_e
->e_attrs
; (*ap
) != NULL
; ap
= &(*ap
)->a_next
)
903 #endif /* BACKSQL_COUNTQUERY */
905 SQLFreeStmt( sth
, SQL_DROP
);
906 Debug( LDAP_DEBUG_TRACE
, "<==backsql_get_attr_vals()\n", 0, 0, 0 );
908 if ( at
->bam_next
) {
909 res
= backsql_get_attr_vals( at
->bam_next
, v_bsi
);
916 #endif /* BACKSQL_TRACE */
917 backsql_FreeRow_x( &row
, bsi
->bsi_op
->o_tmpmemctx
);
923 backsql_id2entry( backsql_srch_info
*bsi
, backsql_entryID
*eid
)
925 Operation
*op
= bsi
->bsi_op
;
926 backsql_info
*bi
= (backsql_info
*)op
->o_bd
->be_private
;
930 Debug( LDAP_DEBUG_TRACE
, "==>backsql_id2entry()\n", 0, 0, 0 );
932 assert( bsi
->bsi_e
!= NULL
);
934 memset( bsi
->bsi_e
, 0, sizeof( Entry
) );
936 if ( bi
->sql_baseObject
&& BACKSQL_IS_BASEOBJECT_ID( &eid
->eid_id
) ) {
939 e
= entry_dup( bi
->sql_baseObject
);
941 return LDAP_NO_MEMORY
;
949 ber_dupbv_x( &bsi
->bsi_e
->e_name
, &eid
->eid_dn
, op
->o_tmpmemctx
);
950 ber_dupbv_x( &bsi
->bsi_e
->e_nname
, &eid
->eid_ndn
, op
->o_tmpmemctx
);
952 bsi
->bsi_e
->e_attrs
= NULL
;
953 bsi
->bsi_e
->e_private
= NULL
;
955 if ( eid
->eid_oc
== NULL
) {
956 eid
->eid_oc
= backsql_id2oc( bsi
->bsi_op
->o_bd
->be_private
,
959 bsi
->bsi_oc
= eid
->eid_oc
;
960 bsi
->bsi_c_eid
= eid
;
962 #ifndef BACKSQL_ARBITRARY_KEY
964 bsi
->bsi_e
->e_id
= eid
->eid_id
;
965 #endif /* ! BACKSQL_ARBITRARY_KEY */
967 rc
= attr_merge_normalize_one( bsi
->bsi_e
,
968 slap_schema
.si_ad_objectClass
,
969 &bsi
->bsi_oc
->bom_oc
->soc_cname
,
970 bsi
->bsi_op
->o_tmpmemctx
);
971 if ( rc
!= LDAP_SUCCESS
) {
972 backsql_entry_clean( op
, bsi
->bsi_e
);
976 if ( bsi
->bsi_attrs
== NULL
|| ( bsi
->bsi_flags
& BSQL_SF_ALL_USER
) )
978 Debug( LDAP_DEBUG_TRACE
, "backsql_id2entry(): "
979 "retrieving all attributes\n", 0, 0, 0 );
980 avl_apply( bsi
->bsi_oc
->bom_attrs
, backsql_get_attr_vals
,
981 bsi
, 0, AVL_INORDER
);
984 Debug( LDAP_DEBUG_TRACE
, "backsql_id2entry(): "
985 "custom attribute list\n", 0, 0, 0 );
986 for ( i
= 0; !BER_BVISNULL( &bsi
->bsi_attrs
[ i
].an_name
); i
++ ) {
987 backsql_at_map_rec
**vat
;
988 AttributeName
*an
= &bsi
->bsi_attrs
[ i
];
991 /* if one of the attributes listed here is
992 * a subtype of another, it must be ignored,
993 * because subtypes are already dealt with
994 * by backsql_supad2at()
996 for ( j
= 0; !BER_BVISNULL( &bsi
->bsi_attrs
[ j
].an_name
); j
++ ) {
1003 if ( is_at_subtype( an
->an_desc
->ad_type
,
1004 bsi
->bsi_attrs
[ j
].an_desc
->ad_type
) )
1010 rc
= backsql_supad2at( bsi
->bsi_oc
, an
->an_desc
, &vat
);
1011 if ( rc
!= 0 || vat
== NULL
) {
1012 Debug( LDAP_DEBUG_TRACE
, "backsql_id2entry(): "
1013 "attribute \"%s\" is not defined "
1014 "for objectlass \"%s\"\n",
1016 BACKSQL_OC_NAME( bsi
->bsi_oc
), 0 );
1020 for ( j
= 0; vat
[j
]; j
++ ) {
1021 backsql_get_attr_vals( vat
[j
], bsi
);
1030 if ( bsi
->bsi_flags
& BSQL_SF_RETURN_ENTRYUUID
) {
1031 Attribute
*a_entryUUID
,
1034 a_entryUUID
= backsql_operational_entryUUID( bi
, eid
);
1035 if ( a_entryUUID
!= NULL
) {
1036 for ( ap
= &bsi
->bsi_e
->e_attrs
;
1038 ap
= &(*ap
)->a_next
);
1044 if ( ( bsi
->bsi_flags
& BSQL_SF_ALL_OPER
)
1045 || an_find( bsi
->bsi_attrs
, &AllOper
)
1046 || an_find( bsi
->bsi_attrs
, &slap_schema
.si_ad_structuralObjectClass
->ad_cname
) )
1048 ObjectClass
*soc
= NULL
;
1050 if ( BACKSQL_CHECK_SCHEMA( bi
) ) {
1052 const char *text
= NULL
;
1053 char textbuf
[ 1024 ];
1054 size_t textlen
= sizeof( textbuf
);
1055 struct berval bv
[ 2 ],
1057 int rc
= LDAP_SUCCESS
;
1059 a
= attr_find( bsi
->bsi_e
->e_attrs
,
1060 slap_schema
.si_ad_objectClass
);
1065 bv
[ 0 ] = bsi
->bsi_oc
->bom_oc
->soc_cname
;
1066 BER_BVZERO( &bv
[ 1 ] );
1070 rc
= structural_class( nvals
, &soc
, NULL
,
1071 &text
, textbuf
, textlen
, op
->o_tmpmemctx
);
1072 if ( rc
!= LDAP_SUCCESS
) {
1073 Debug( LDAP_DEBUG_TRACE
, "backsql_id2entry(%s): "
1074 "structural_class() failed %d (%s)\n",
1075 bsi
->bsi_e
->e_name
.bv_val
,
1076 rc
, text
? text
: "" );
1077 backsql_entry_clean( op
, bsi
->bsi_e
);
1081 if ( !bvmatch( &soc
->soc_cname
, &bsi
->bsi_oc
->bom_oc
->soc_cname
) ) {
1082 if ( !is_object_subclass( bsi
->bsi_oc
->bom_oc
, soc
) ) {
1083 Debug( LDAP_DEBUG_TRACE
, "backsql_id2entry(%s): "
1084 "computed structuralObjectClass %s "
1085 "does not match objectClass %s associated "
1087 bsi
->bsi_e
->e_name
.bv_val
, soc
->soc_cname
.bv_val
,
1088 bsi
->bsi_oc
->bom_oc
->soc_cname
.bv_val
);
1089 backsql_entry_clean( op
, bsi
->bsi_e
);
1093 Debug( LDAP_DEBUG_TRACE
, "backsql_id2entry(%s): "
1094 "computed structuralObjectClass %s "
1095 "is subclass of objectClass %s associated "
1097 bsi
->bsi_e
->e_name
.bv_val
, soc
->soc_cname
.bv_val
,
1098 bsi
->bsi_oc
->bom_oc
->soc_cname
.bv_val
);
1102 soc
= bsi
->bsi_oc
->bom_oc
;
1105 rc
= attr_merge_normalize_one( bsi
->bsi_e
,
1106 slap_schema
.si_ad_structuralObjectClass
,
1108 bsi
->bsi_op
->o_tmpmemctx
);
1109 if ( rc
!= LDAP_SUCCESS
) {
1110 backsql_entry_clean( op
, bsi
->bsi_e
);
1116 Debug( LDAP_DEBUG_TRACE
, "<==backsql_id2entry()\n", 0, 0, 0 );
1118 return LDAP_SUCCESS
;