📄 entry-id.c
字号:
/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/entry-id.c,v 1.46.2.13 2007/08/11 07:39:30 ando Exp $ *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 1999-2007 The OpenLDAP Foundation. * Portions Copyright 1999 Dmitry Kovalev. * Portions Copyright 2002 Pierangelo Masarati. * Portions Copyright 2004 Mark Adamson. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * <http://www.OpenLDAP.org/license.html>. *//* ACKNOWLEDGEMENTS: * This work was initially developed by Dmitry Kovalev for inclusion * by OpenLDAP Software. Additional significant contributors include * Pierangelo Masarati and Mark Adamson. */#include "portable.h"#include <stdio.h>#include <sys/types.h>#include "ac/string.h"#include "lutil.h"#include "slap.h"#include "proto-sql.h"#ifdef BACKSQL_ARBITRARY_KEYstruct berval backsql_baseObject_bv = BER_BVC( BACKSQL_BASEOBJECT_IDSTR );#endif /* BACKSQL_ARBITRARY_KEY */backsql_entryID *backsql_free_entryID( Operation *op, backsql_entryID *id, int freeit ){ backsql_entryID *next; assert( id != NULL ); next = id->eid_next; if ( !BER_BVISNULL( &id->eid_ndn ) ) { if ( !BER_BVISNULL( &id->eid_dn ) && id->eid_dn.bv_val != id->eid_ndn.bv_val ) { op->o_tmpfree( id->eid_dn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &id->eid_dn ); } op->o_tmpfree( id->eid_ndn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &id->eid_ndn ); }#ifdef BACKSQL_ARBITRARY_KEY if ( !BER_BVISNULL( &id->eid_id ) ) { op->o_tmpfree( id->eid_id.bv_val, op->o_tmpmemctx ); BER_BVZERO( &id->eid_id ); } if ( !BER_BVISNULL( &id->eid_keyval ) ) { op->o_tmpfree( id->eid_keyval.bv_val, op->o_tmpmemctx ); BER_BVZERO( &id->eid_keyval ); }#endif /* BACKSQL_ARBITRARY_KEY */ if ( freeit ) { op->o_tmpfree( id, op->o_tmpmemctx ); } return next;}/* * NOTE: the dn must be normalized */intbacksql_dn2id( Operation *op, SlapReply *rs, SQLHDBC dbh, struct berval *ndn, backsql_entryID *id, int matched, int muck ){ backsql_info *bi = op->o_bd->be_private; SQLHSTMT sth = SQL_NULL_HSTMT; BACKSQL_ROW_NTS row = { 0 }; RETCODE rc; int res; struct berval realndn = BER_BVNULL; /* TimesTen */ char upperdn[ BACKSQL_MAX_DN_LEN + 1 ]; struct berval tbbDN; int i, j; /* * NOTE: id can be NULL; in this case, the function * simply checks whether the DN can be successfully * turned into an ID, returning LDAP_SUCCESS for * positive cases, or the most appropriate error */ Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(\"%s\")%s%s\n", ndn->bv_val, id == NULL ? " (no ID expected)" : "", matched ? " matched expected" : "" ); if ( id ) { /* NOTE: trap inconsistencies */ assert( BER_BVISNULL( &id->eid_ndn ) ); } if ( ndn->bv_len > BACKSQL_MAX_DN_LEN ) { Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): DN length=%ld " "exceeds max DN length %d:\n", ndn->bv_val, ndn->bv_len, BACKSQL_MAX_DN_LEN ); return LDAP_OTHER; } /* return baseObject if available and matches */ /* FIXME: if ndn is already mucked, we cannot check this */ if ( bi->sql_baseObject != NULL && dn_match( ndn, &bi->sql_baseObject->e_nname ) ) { if ( id != NULL ) {#ifdef BACKSQL_ARBITRARY_KEY ber_dupbv_x( &id->eid_id, &backsql_baseObject_bv, op->o_tmpmemctx ); ber_dupbv_x( &id->eid_keyval, &backsql_baseObject_bv, op->o_tmpmemctx );#else /* ! BACKSQL_ARBITRARY_KEY */ id->eid_id = BACKSQL_BASEOBJECT_ID; id->eid_keyval = BACKSQL_BASEOBJECT_KEYVAL;#endif /* ! BACKSQL_ARBITRARY_KEY */ id->eid_oc_id = BACKSQL_BASEOBJECT_OC; ber_dupbv_x( &id->eid_ndn, &bi->sql_baseObject->e_nname, op->o_tmpmemctx ); ber_dupbv_x( &id->eid_dn, &bi->sql_baseObject->e_name, op->o_tmpmemctx ); id->eid_next = NULL; } return LDAP_SUCCESS; } /* begin TimesTen */ Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): id_query \"%s\"\n", ndn->bv_val, bi->sql_id_query, 0 ); assert( bi->sql_id_query != NULL ); rc = backsql_Prepare( dbh, &sth, bi->sql_id_query, 0 ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "error preparing SQL:\n %s", ndn->bv_val, bi->sql_id_query, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); res = LDAP_OTHER; goto done; } realndn = *ndn; if ( muck ) { if ( backsql_api_dn2odbc( op, rs, &realndn ) ) { Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "backsql_api_dn2odbc(\"%s\") failed\n", ndn->bv_val, realndn.bv_val, 0 ); res = LDAP_OTHER; goto done; } } if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) { /* * Prepare an upper cased, byte reversed version * that can be searched using indexes */ for ( i = 0, j = realndn.bv_len - 1; realndn.bv_val[ i ]; i++, j--) { upperdn[ i ] = realndn.bv_val[ j ]; } upperdn[ i ] = '\0'; ldap_pvt_str2upper( upperdn ); Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "upperdn=\"%s\"\n", ndn->bv_val, upperdn, 0 ); ber_str2bv( upperdn, 0, 0, &tbbDN ); } else { if ( BACKSQL_USE_REVERSE_DN( bi ) ) { AC_MEMCPY( upperdn, realndn.bv_val, realndn.bv_len + 1 ); ldap_pvt_str2upper( upperdn ); Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "upperdn=\"%s\"\n", ndn->bv_val, upperdn, 0 ); ber_str2bv( upperdn, 0, 0, &tbbDN ); } else { tbbDN = realndn; } } rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &tbbDN ); if ( rc != SQL_SUCCESS) { /* end TimesTen */ Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "error binding dn=\"%s\" parameter:\n", ndn->bv_val, tbbDN.bv_val, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); res = LDAP_OTHER; goto done; } rc = SQLExecute( sth ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "error executing query (\"%s\", \"%s\"):\n", ndn->bv_val, bi->sql_id_query, tbbDN.bv_val ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); res = LDAP_OTHER; goto done; } backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx ); rc = SQLFetch( sth ); if ( BACKSQL_SUCCESS( rc ) ) { char buf[ SLAP_TEXT_BUFLEN ];#ifdef LDAP_DEBUG snprintf( buf, sizeof(buf), "id=%s keyval=%s oc_id=%s dn=%s", row.cols[ 0 ], row.cols[ 1 ], row.cols[ 2 ], row.cols[ 3 ] ); Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): %s\n", ndn->bv_val, buf, 0 );#endif /* LDAP_DEBUG */ res = LDAP_SUCCESS; if ( id != NULL ) { struct berval dn; id->eid_next = NULL;#ifdef BACKSQL_ARBITRARY_KEY ber_str2bv_x( row.cols[ 0 ], 0, 1, &id->eid_id, op->o_tmpmemctx ); ber_str2bv_x( row.cols[ 1 ], 0, 1, &id->eid_keyval, op->o_tmpmemctx );#else /* ! BACKSQL_ARBITRARY_KEY */ if ( lutil_atoulx( &id->eid_id, row.cols[ 0 ], 0 ) != 0 ) { res = LDAP_OTHER; goto done; } if ( lutil_atoulx( &id->eid_keyval, row.cols[ 1 ], 0 ) != 0 ) { res = LDAP_OTHER; goto done; }#endif /* ! BACKSQL_ARBITRARY_KEY */ if ( lutil_atoulx( &id->eid_oc_id, row.cols[ 2 ], 0 ) != 0 ) { res = LDAP_OTHER; goto done; } ber_str2bv( row.cols[ 3 ], 0, 0, &dn ); if ( backsql_api_odbc2dn( op, rs, &dn ) ) { res = LDAP_OTHER; goto done; } res = dnPrettyNormal( NULL, &dn, &id->eid_dn, &id->eid_ndn, op->o_tmpmemctx ); if ( res != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "dnPrettyNormal failed (%d: %s)\n", realndn.bv_val, res, ldap_err2string( res ) ); /* cleanup... */ (void)backsql_free_entryID( op, id, 0 ); } if ( dn.bv_val != row.cols[ 3 ] ) { free( dn.bv_val ); } } } else { res = LDAP_NO_SUCH_OBJECT; if ( matched ) { struct berval pdn = *ndn; /* * Look for matched */ rs->sr_matched = NULL; while ( !be_issuffix( op->o_bd, &pdn ) ) { char *matchedDN = NULL; dnParent( &pdn, &pdn ); /* * Empty DN ("") defaults to LDAP_SUCCESS */ rs->sr_err = backsql_dn2id( op, rs, dbh, &pdn, id, 0, 1 ); switch ( rs->sr_err ) { case LDAP_NO_SUCH_OBJECT: /* try another one */ break; case LDAP_SUCCESS: matchedDN = pdn.bv_val; /* fail over to next case */ default: rs->sr_err = LDAP_NO_SUCH_OBJECT; rs->sr_matched = matchedDN; goto done; } } } }done:; backsql_FreeRow_x( &row, op->o_tmpmemctx ); Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(\"%s\"): err=%d\n", ndn->bv_val, res, 0 ); if ( sth != SQL_NULL_HSTMT ) { SQLFreeStmt( sth, SQL_DROP ); } if ( !BER_BVISNULL( &realndn ) && realndn.bv_val != ndn->bv_val ) { ch_free( realndn.bv_val ); } return res;}intbacksql_count_children( Operation *op, SQLHDBC dbh, struct berval *dn, unsigned long *nchildren ){ backsql_info *bi = (backsql_info *)op->o_bd->be_private; SQLHSTMT sth = SQL_NULL_HSTMT; BACKSQL_ROW_NTS row; RETCODE rc; int res = LDAP_SUCCESS; Debug( LDAP_DEBUG_TRACE, "==>backsql_count_children(): dn=\"%s\"\n", dn->bv_val, 0, 0 ); if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) { Debug( LDAP_DEBUG_TRACE, "backsql_count_children(): DN \"%s\" (%ld bytes) " "exceeds max DN length (%d):\n", dn->bv_val, dn->bv_len, BACKSQL_MAX_DN_LEN ); return LDAP_OTHER; } /* begin TimesTen */ Debug(LDAP_DEBUG_TRACE, "children id query \"%s\"\n", bi->sql_has_children_query, 0, 0); assert( bi->sql_has_children_query != NULL ); rc = backsql_Prepare( dbh, &sth, bi->sql_has_children_query, 0 ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_count_children(): error preparing SQL:\n%s", bi->sql_has_children_query, 0, 0); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); return LDAP_OTHER; } rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, dn ); if ( rc != SQL_SUCCESS) { /* end TimesTen */ Debug( LDAP_DEBUG_TRACE, "backsql_count_children(): " "error binding dn=\"%s\" parameter:\n", dn->bv_val, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); return LDAP_OTHER; } rc = SQLExecute( sth ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_count_children(): " "error executing query (\"%s\", \"%s\"):\n", bi->sql_has_children_query, dn->bv_val, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); return LDAP_OTHER; } backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx ); rc = SQLFetch( sth ); if ( BACKSQL_SUCCESS( rc ) ) { char *end; *nchildren = strtol( row.cols[ 0 ], &end, 0 ); if ( end == row.cols[ 0 ] ) { res = LDAP_OTHER; } else { switch ( end[ 0 ] ) { case '\0': break; case '.': { unsigned long ul; /* FIXME: braindead RDBMSes return * a fractional number from COUNT! */ if ( lutil_atoul( &ul, end + 1 ) != 0 || ul != 0 ) { res = LDAP_OTHER; } } break; default: res = LDAP_OTHER; } } } else { res = LDAP_OTHER; } backsql_FreeRow_x( &row, op->o_tmpmemctx ); SQLFreeStmt( sth, SQL_DROP ); Debug( LDAP_DEBUG_TRACE, "<==backsql_count_children(): %lu\n", *nchildren, 0, 0 ); return res;}intbacksql_has_children( Operation *op, SQLHDBC dbh, struct berval *dn ){ unsigned long nchildren; int rc; rc = backsql_count_children( op, dbh, dn, &nchildren ); if ( rc == LDAP_SUCCESS ) { return nchildren > 0 ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE; } return rc;}static intbacksql_get_attr_vals( void *v_at, void *v_bsi ){ backsql_at_map_rec *at = v_at; backsql_srch_info *bsi = v_bsi; backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private; RETCODE rc; SQLHSTMT sth = SQL_NULL_HSTMT; BACKSQL_ROW_NTS row; unsigned long i, k = 0, oldcount = 0, res = 0;#ifdef BACKSQL_COUNTQUERY unsigned count, j, append = 0; SQLLEN countsize = sizeof( count ); Attribute *attr = NULL; slap_mr_normalize_func *normfunc = NULL;#endif /* BACKSQL_COUNTQUERY */#ifdef BACKSQL_PRETTY_VALIDATE slap_syntax_validate_func *validate = NULL; slap_syntax_transform_func *pretty = NULL;#endif /* BACKSQL_PRETTY_VALIDATE */ assert( at != NULL ); assert( bsi != NULL );#ifdef BACKSQL_ARBITRARY_KEY Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): " "oc=\"%s\" attr=\"%s\" keyval=%s\n", BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val, bsi->bsi_c_eid->eid_keyval.bv_val );#else /* ! BACKSQL_ARBITRARY_KEY */ Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): " "oc=\"%s\" attr=\"%s\" keyval=%ld\n", BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val, bsi->bsi_c_eid->eid_keyval );#endif /* ! BACKSQL_ARBITRARY_KEY */#ifdef BACKSQL_PRETTY_VALIDATE validate = at->bam_ad->ad_type->sat_syntax->ssyn_validate; pretty = at->bam_ad->ad_type->sat_syntax->ssyn_pretty; if ( validate == NULL && pretty == NULL ) { return 1; }#endif /* BACKSQL_PRETTY_VALIDATE */#ifdef BACKSQL_COUNTQUERY if ( at->bam_ad->ad_type->sat_equality ) { normfunc = at->bam_ad->ad_type->sat_equality->smr_normalize; } /* Count how many rows will be returned. This avoids memory * fragmentation that can result from loading the values in * one by one and using realloc() */ rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_countquery, 0 ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): " "error preparing count query: %s\n", at->bam_countquery, 0, 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -