X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-sql%2Fentry-id.c;h=b864e803d4ab7b28e4bccfb1a201548086ae608c;hb=9647ccd9456b8781066dbba5a063bf6c6c9dab6d;hp=eab33bbc140462d3fe4b2635781479331353603f;hpb=115408986c62fea339b99f93dafc820bd8c94062;p=openldap diff --git a/servers/slapd/back-sql/entry-id.c b/servers/slapd/back-sql/entry-id.c index eab33bbc14..b864e803d4 100644 --- a/servers/slapd/back-sql/entry-id.c +++ b/servers/slapd/back-sql/entry-id.c @@ -1,10 +1,21 @@ -/* - * Copyright 1999, Dmitry Kovalev , All rights reserved. +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . * - * Redistribution and use in source and binary forms are permitted only - * as authorized by the OpenLDAP Public License. A copy of this - * license is available at http://www.OpenLDAP.org/license.html or - * in file LICENSE in the top-level directory of the distribution. + * Copyright 1999-2003 The OpenLDAP Foundation. + * Portions Copyright 1999 Dmitry Kovalev. + * 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 + * . + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Dmitry Kovalev for inclusion + * by OpenLDAP Software. */ #include "portable.h" @@ -14,6 +25,7 @@ #include #include #include "ac/string.h" +#include "lber_pvt.h" #include "ldap_pvt.h" #include "slap.h" #include "back-sql.h" @@ -42,11 +54,6 @@ backsql_free_entryID( backsql_entryID *id, int freeit ) return next; } -/* - * FIXME: need to change API to pass backsql_entryID **id - * and return an error code, to distinguish LDAP_OTHER from - * LDAP_NO_SUCH_OBJECT - */ int backsql_dn2id( backsql_info *bi, @@ -56,9 +63,6 @@ backsql_dn2id( { SQLHSTMT sth; BACKSQL_ROW_NTS row; -#if 0 - SQLINTEGER nrows = 0; -#endif RETCODE rc; int res; @@ -93,7 +97,7 @@ backsql_dn2id( return LDAP_OTHER; } - if ( bi->has_ldapinfo_dn_ru ) { + if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) { /* * Prepare an upper cased, byte reversed version * that can be searched using indexes @@ -109,7 +113,7 @@ backsql_dn2id( upperdn, 0, 0 ); toBind = upperdn; } else { - if ( bi->isTimesTen ) { + if ( BACKSQL_USE_REVERSE_DN( bi ) ) { AC_MEMCPY( upperdn, dn->bv_val, dn->bv_len + 1 ); ldap_pvt_str2upper( upperdn ); Debug( LDAP_DEBUG_TRACE, @@ -126,7 +130,8 @@ backsql_dn2id( if ( rc != SQL_SUCCESS) { /* end TimesTen */ Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): " - "error binding dn=\"%s\" parameter:\n", toBind, 0, 0 ); + "error binding dn=\"%s\" parameter:\n", + toBind, 0, 0 ); backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); return LDAP_OTHER; @@ -145,9 +150,9 @@ backsql_dn2id( backsql_BindRowAsStrings( sth, &row ); rc = SQLFetch( sth ); if ( BACKSQL_SUCCESS( rc ) ) { - id->id = atoi( row.cols[ 0 ] ); - id->keyval = atoi( row.cols[ 1 ] ); - id->oc_id = atoi( row.cols[ 2 ] ); + id->id = strtol( row.cols[ 0 ], NULL, 0 ); + id->keyval = strtol( row.cols[ 1 ], NULL, 0 ); + id->oc_id = strtol( row.cols[ 2 ], NULL, 0 ); ber_dupbv( &id->dn, dn ); id->next = NULL; @@ -170,25 +175,129 @@ backsql_dn2id( } int -backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi ) +backsql_count_children( + backsql_info *bi, + SQLHDBC dbh, + struct berval *dn, + unsigned long *nchildren ) { - RETCODE rc; - SQLHSTMT sth; - BACKSQL_ROW_NTS row; - int i; + SQLHSTMT sth; + 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->has_children_query, 0, 0); + assert( bi->has_children_query ); + rc = backsql_Prepare( dbh, &sth, bi->has_children_query, 0 ); + if ( rc != SQL_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, + "backsql_count_children(): error preparing SQL:\n%s", + bi->has_children_query, 0, 0); + backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc ); + SQLFreeStmt( sth, SQL_DROP ); + return LDAP_OTHER; + } + + rc = backsql_BindParamStr( sth, 1, dn->bv_val, BACKSQL_MAX_DN_LEN ); + 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( SQL_NULL_HENV, 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->has_children_query, dn->bv_val, 0 ); + backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc ); + SQLFreeStmt( sth, SQL_DROP ); + return LDAP_OTHER; + } + + backsql_BindRowAsStrings( sth, &row ); + + rc = SQLFetch( sth ); + if ( BACKSQL_SUCCESS( rc ) ) { + char *end; + + *nchildren = strtol( row.cols[ 0 ], &end, 0 ); + if ( end[ 0 ] != '\0' ) { + res = LDAP_OTHER; + } + + } else { + res = LDAP_OTHER; + } + backsql_FreeRow( &row ); + + SQLFreeStmt( sth, SQL_DROP ); + + Debug( LDAP_DEBUG_TRACE, "<==backsql_count_children(): %lu\n", + *nchildren, 0, 0 ); + + return res; +} + +int +backsql_has_children( + backsql_info *bi, + SQLHDBC dbh, + struct berval *dn ) +{ + unsigned long nchildren; + int rc; + + rc = backsql_count_children( bi, dbh, dn, &nchildren ); + + if ( rc == LDAP_SUCCESS ) { + return nchildren > 0 ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE; + } + + return rc; +} + +static int +backsql_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->op->o_bd->be_private; + RETCODE rc; + SQLHSTMT sth; + BACKSQL_ROW_NTS row; + int i; assert( at ); assert( bsi ); Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): " "oc='%s' attr='%s' keyval=%ld\n", - bsi->oc->name, at->name, bsi->c_eid->keyval ); + BACKSQL_OC_NAME( bsi->oc ), at->ad->ad_cname.bv_val, + bsi->c_eid->keyval ); rc = backsql_Prepare( bsi->dbh, &sth, at->query, 0 ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): " "error preparing query: %s\n", at->query, 0, 0 ); - backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc ); + backsql_PrintErrors( bi->db_env, bsi->dbh, sth, rc ); return 1; } @@ -204,7 +313,7 @@ backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi ) Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): " "error executing attribute query '%s'\n", at->query, 0, 0 ); - backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc ); + backsql_PrintErrors( bi->db_env, bsi->dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); return 1; } @@ -214,28 +323,31 @@ backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi ) rc = SQLFetch( sth ); for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) { for ( i = 0; i < row.ncols; i++ ) { - if ( row.is_null[ i ] > 0 ) { - backsql_entry_addattr( bsi->e, - row.col_names[ i ], - row.cols[ i ], + if ( row.value_len[ i ] > 0 ) { + struct berval bv; + + bv.bv_val = row.cols[ i ]; #if 0 - row.col_prec[ i ] + bv.bv_len = row.col_prec[ i ]; #else - /* - * FIXME: what if a binary - * is fetched? - */ - strlen( row.cols[ i ] ) + /* + * FIXME: what if a binary + * is fetched? + */ + bv.bv_len = strlen( row.cols[ i ] ); #endif - ); -#if 0 + backsql_entry_addattr( bsi->e, + &row.col_names[ i ], &bv, + bsi->op->o_tmpmemctx ); + +#ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "prec=%d\n", (int)row.col_prec[ i ], 0, 0 ); } else { Debug( LDAP_DEBUG_TRACE, "NULL value " "in this row for attribute '%s'\n", - row.col_names[ i ], 0, 0 ); -#endif + row.col_names[ i ].bv_val, 0, 0 ); +#endif /* BACKSQL_TRACE */ } } } @@ -250,59 +362,91 @@ backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi ) Entry * backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid ) { - char **c_at_name; + int i; backsql_at_map_rec *at; int rc; + AttributeDescription *ad_oc = slap_schema.si_ad_objectClass; Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 ); - rc = dnPrettyNormal( NULL, &eid->dn, &e->e_name, &e->e_nname ); + rc = dnPrettyNormal( NULL, &eid->dn, &e->e_name, &e->e_nname, + bsi->op->o_tmpmemctx ); if ( rc != LDAP_SUCCESS ) { return NULL; } - bsi->oc = backsql_oc_with_id( bsi->bi, eid->oc_id ); + bsi->oc = backsql_id2oc( bsi->op->o_bd->be_private, eid->oc_id ); bsi->e = e; bsi->c_eid = eid; e->e_attrs = NULL; e->e_private = NULL; - /* if ( bsi->base_dn != NULL)??? */ - e->e_id = eid->id; if ( bsi->attrs != NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): " "custom attribute list\n", 0, 0, 0 ); - for ( c_at_name = bsi->attrs; *c_at_name != NULL; c_at_name++ ) { - if ( !strcasecmp( *c_at_name, "objectclass" ) - || !strcasecmp( *c_at_name, "0.10" ) ) { -#if 0 - backsql_entry_addattr( bsi->e, "objectclass", - bsi->oc->name, - strlen( bsi->oc->name ) ); -#endif + for ( i = 0; bsi->attrs[ i ].an_name.bv_val; i++ ) { + AttributeName *attr = &bsi->attrs[ i ]; + + if ( attr->an_desc == ad_oc ) { continue; } - at = backsql_at_with_name( bsi->oc, *c_at_name ); + + at = backsql_ad2at( bsi->oc, attr->an_desc ); if ( at != NULL ) { backsql_get_attr_vals( at, bsi ); } else { Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): " "attribute '%s' is not defined " "for objectlass '%s'\n", - *c_at_name, bsi->oc->name, 0 ); + attr->an_name.bv_val, + BACKSQL_OC_NAME( bsi->oc ), 0 ); } } + } else { Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): " "retrieving all attributes\n", 0, 0, 0 ); - avl_apply( bsi->oc->attrs, (AVL_APPLY)backsql_get_attr_vals, + avl_apply( bsi->oc->attrs, backsql_get_attr_vals, bsi, 0, AVL_INORDER ); } - backsql_entry_addattr( bsi->e, "objectclass", bsi->oc->name, - strlen( bsi->oc->name ) ); + if ( attr_merge_normalize_one( bsi->e, ad_oc, &bsi->oc->oc->soc_cname, + bsi->op->o_tmpmemctx ) ) { + entry_free( e ); + return NULL; + } + + if ( global_schemacheck ) { + const char *text = NULL; + char textbuf[ 1024 ]; + size_t textlen = sizeof( textbuf ); + struct berval bv[ 2 ]; + struct berval soc; + int rc; + + bv[ 0 ] = bsi->oc->oc->soc_cname; + bv[ 1 ].bv_val = NULL; + + rc = structural_class( bv, &soc, NULL, + &text, textbuf, textlen ); + if ( rc != LDAP_SUCCESS ) { + entry_free( e ); + return NULL; + } + + if ( ( bsi->bsi_flags | BSQL_SF_ALL_OPER ) + || an_find( bsi->attrs, &AllOper ) ) { + rc = attr_merge_normalize_one( bsi->e, + slap_schema.si_ad_structuralObjectClass, + &soc, bsi->op->o_tmpmemctx ); + if ( rc != LDAP_SUCCESS ) { + entry_free( e ); + return NULL; + } + } + } Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );