Commit adf3744d authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

fix backsql new API; use berbuf instead of berval

parent 8563681f
......@@ -299,7 +299,6 @@ do_add( Operation *op, SlapReply *rs )
#ifndef SLAPD_MULTIMASTER
} else {
BerVarray defref;
BerVarray ref;
#ifdef LDAP_SLAPI
/*
* SLAPI_ADD_ENTRY will be empty, but this may be acceptable
......@@ -457,7 +456,7 @@ slap_mods2entry(
}
} else {
int rc;
int rc = LDAP_SUCCESS;
int match;
for ( i = 0; mods->sml_nvalues[i].bv_val != NULL; i++ ) {
......
......@@ -266,12 +266,13 @@ backsql_has_children(
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;
RETCODE rc;
SQLHSTMT sth;
BACKSQL_ROW_NTS row;
int i;
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 );
......@@ -285,7 +286,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
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;
}
......@@ -301,7 +302,7 @@ backsql_get_attr_vals( void *v_at, void *v_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;
}
......@@ -363,7 +364,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
return NULL;
}
bsi->oc = backsql_id2oc( 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;
......
......@@ -163,7 +163,7 @@ backsql_db_open(
backsql_info *si = (backsql_info*)bd->be_private;
SQLHDBC dbh;
ber_len_t idq_len;
struct berval bv;
struct berbuf bb = BB_NULL;
Operation otmp;
......@@ -228,12 +228,12 @@ backsql_db_open(
* Prepare concat function for subtree search condition
*/
struct berval concat;
ber_len_t len = 0;
struct berval values[] = {
{ sizeof( "'%'" ) - 1, "'%'" },
{ sizeof( "?" ) - 1, "?" },
{ 0, NULL }
};
struct berbuf bb = BB_NULL;
if ( backsql_prepare_pattern( si->concat_func, values,
&concat ) ) {
......@@ -247,16 +247,13 @@ backsql_db_open(
"(use \"subtree_cond\" directive in slapd.conf)\n",
0, 0, 0);
si->subtree_cond.bv_val = NULL;
si->subtree_cond.bv_len = 0;
if ( si->upper_func.bv_val ) {
/*
* UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%',?))
*/
backsql_strfcat( &si->subtree_cond, &len, "blbbb",
backsql_strfcat( &bb, "blbbb",
&si->upper_func,
(ber_len_t)sizeof( "(ldap_entries.dn) LIKE " ) - 1,
"(ldap_entries.dn) LIKE ",
......@@ -270,11 +267,13 @@ backsql_db_open(
* ldap_entries.dn LIKE CONCAT('%',?)
*/
backsql_strfcat( &si->subtree_cond, &len, "lb",
backsql_strfcat( &bb, "lb",
(ber_len_t)sizeof( "ldap_entries.dn LIKE " ) - 1,
"ldap_entries.dn LIKE ",
&concat );
}
si->subtree_cond = bb.bb_val;
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"setting '%s' as default\n",
......@@ -282,7 +281,7 @@ backsql_db_open(
}
if ( si->children_cond.bv_val == NULL ) {
ber_len_t len = 0;
struct berbuf bb = BB_NULL;
if ( si->upper_func.bv_val ) {
......@@ -290,7 +289,7 @@ backsql_db_open(
* UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%,',?))
*/
backsql_strfcat( &si->children_cond, &len, "blbl",
backsql_strfcat( &bb, "blbl",
&si->upper_func,
(ber_len_t)sizeof( "(ldap_entries.dn)=" ) - 1,
"(ldap_entries.dn)=",
......@@ -303,10 +302,12 @@ backsql_db_open(
* ldap_entries.dn LIKE CONCAT('%,',?)
*/
backsql_strfcat( &si->children_cond, &len, "l",
backsql_strfcat( &bb, "l",
(ber_len_t)sizeof( "ldap_entries.dn=?" ) - 1,
"ldap_entries.dn=?");
}
si->children_cond = bb.bb_val;
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"setting '%s' as default\n",
......@@ -377,23 +378,20 @@ backsql_db_open(
si->id_query = NULL;
idq_len = 0;
bv.bv_val = NULL;
bv.bv_len = 0;
if ( si->upper_func.bv_val == NULL ) {
backsql_strcat( &bv, &idq_len, backsql_id_query,
"dn=?", NULL );
backsql_strcat( &bb, backsql_id_query, "dn=?", NULL );
} else {
if ( BACKSQL_HAS_LDAPINFO_DN_RU( si ) ) {
backsql_strcat( &bv, &idq_len, backsql_id_query,
backsql_strcat( &bb, backsql_id_query,
"dn_ru=?", NULL );
} else {
if ( BACKSQL_USE_REVERSE_DN( si ) ) {
backsql_strfcat( &bv, &idq_len, "sbl",
backsql_strfcat( &bb, "sbl",
backsql_id_query,
&si->upper_func,
(ber_len_t)sizeof( "(dn)=?" ) - 1, "(dn)=?" );
} else {
backsql_strfcat( &bv, &idq_len, "sblbcb",
backsql_strfcat( &bb, "sblbcb",
backsql_id_query,
&si->upper_func,
(ber_len_t)sizeof( "(dn)=" ) - 1, "(dn)=",
......@@ -403,21 +401,21 @@ backsql_db_open(
}
}
}
si->id_query = bv.bv_val;
si->id_query = bb.bb_val.bv_val;
/*
* Prepare children ID selection query
*/
si->has_children_query = NULL;
idq_len = 0;
bv.bv_val = NULL;
bv.bv_len = 0;
backsql_strfcat( &bv, &idq_len, "sb",
bb.bb_val.bv_val = NULL;
bb.bb_val.bv_len = 0;
bb.bb_len = 0;
backsql_strfcat( &bb, "sb",
"SELECT COUNT(distinct subordinates.id) FROM ldap_entries,ldap_entries AS subordinates WHERE subordinates.parent=ldap_entries.id AND ",
&si->children_cond );
si->has_children_query = bv.bv_val;
si->has_children_query = bb.bb_val.bv_val;
backsql_free_db_conn( &otmp );
if ( !BACKSQL_SCHEMA_LOADED( si ) ) {
......
......@@ -54,10 +54,9 @@ backsql_make_attr_query(
backsql_oc_map_rec *oc_map,
backsql_at_map_rec *at_map )
{
struct berval tmps = BER_BVNULL;
ber_len_t tmpslen = 0;
struct berbuf bb = BB_NULL;
backsql_strfcat( &tmps, &tmpslen, "lblblblbcbl",
backsql_strfcat( &bb, "lblblblbcbl",
(ber_len_t)sizeof( "SELECT " ) - 1, "SELECT ",
&at_map->sel_expr,
(ber_len_t)sizeof( " AS " ) - 1, " AS ",
......@@ -71,12 +70,12 @@ backsql_make_attr_query(
(ber_len_t)sizeof( "=?" ) - 1, "=?" );
if ( at_map->join_where.bv_val != NULL ) {
backsql_strfcat( &tmps, &tmpslen, "lb",
backsql_strfcat( &bb, "lb",
(ber_len_t)sizeof( " AND ") - 1, " AND ",
&at_map->join_where );
}
at_map->query = tmps.bv_val;
at_map->query = bb.bb_val.bv_val;
return 0;
}
......@@ -85,8 +84,9 @@ static int
backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
{
backsql_at_map_rec *at_map;
char s[ 30 ];
ber_len_t len, slen;
char s[] = "+9223372036854775807L";
ber_len_t slen;
struct berbuf bb;
snprintf( s, sizeof( s ), "%ld", oc_map->id );
......@@ -98,13 +98,16 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
ber_str2bv( "ldap_entry_objclasses.oc_name", 0, 1, &at_map->sel_expr );
ber_str2bv( "ldap_entry_objclasses,ldap_entries", 0, 1,
&at_map->from_tbls );
len = at_map->from_tbls.bv_len + 1;
backsql_merge_from_clause( &at_map->from_tbls, &len, &oc_map->keytbl );
len = 0;
at_map->join_where.bv_val = NULL;
at_map->join_where.bv_len = 0;
backsql_strfcat( &at_map->join_where, &len, "lbcbll",
bb.bb_len = at_map->from_tbls.bv_len + 1;
bb.bb_val = at_map->from_tbls;
backsql_merge_from_clause( &bb, &oc_map->keytbl );
at_map->from_tbls = bb.bb_val;
bb.bb_val.bv_val = NULL;
bb.bb_val.bv_len = 0;
bb.bb_len = 0;
backsql_strfcat( &bb, "lbcbll",
(ber_len_t)sizeof( "ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entries.keyval=" ) - 1,
"ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entries.keyval=",
&oc_map->keytbl,
......@@ -114,10 +117,12 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
" and ldap_entries.oc_map_id=",
slen, s );
at_map->join_where = bb.bb_val;
at_map->add_proc = NULL;
at_map->delete_proc = NULL;
at_map->param_order = 0;
at_map->expect_return = 0;
backsql_make_attr_query( oc_map, at_map );
avl_insert( &oc_map->attrs, at_map, backsql_cmp_attr, NULL );
......@@ -126,13 +131,17 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
at_map->ad = slap_schema.si_ad_ref;
ber_str2bv( "ldap_referrals.url", 0, 1, &at_map->sel_expr );
ber_str2bv( "ldap_referrals,ldap_entries", 0, 1, &at_map->from_tbls );
len = at_map->from_tbls.bv_len + 1;
backsql_merge_from_clause( &at_map->from_tbls, &len, &oc_map->keytbl );
len = 0;
at_map->join_where.bv_val = NULL;
at_map->join_where.bv_len = 0;
backsql_strfcat( &at_map->join_where, &len, "lbcbll",
bb.bb_val.bv_val = NULL;
bb.bb_val.bv_len = 0;
bb.bb_len = at_map->from_tbls.bv_len + 1;
backsql_merge_from_clause( &bb, &oc_map->keytbl );
at_map->from_tbls = bb.bb_val;
bb.bb_val.bv_val = NULL;
bb.bb_val.bv_len = 0;
bb.bb_len = 0;
backsql_strfcat( &bb, "lbcbll",
(ber_len_t)sizeof( "ldap_entries.id=ldap_referrals.entry_id and ldap_entries.keyval=" ) - 1,
"ldap_entries.id=ldap_referrals.entry_id and ldap_entries.keyval=",
&oc_map->keytbl,
......@@ -142,10 +151,12 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
" and ldap_entries.oc_map_id=",
slen, s );
at_map->join_where = bb.bb_val;
at_map->add_proc = NULL;
at_map->delete_proc = NULL;
at_map->param_order = 0;
at_map->expect_return = 0;
backsql_make_attr_query( oc_map, at_map );
avl_insert( &oc_map->attrs, at_map, backsql_cmp_attr, NULL );
......@@ -301,7 +312,7 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
for ( ; BACKSQL_SUCCESS(rc); rc = SQLFetch( at_sth ) ) {
const char *text = NULL;
struct berval bv;
ber_len_t tmpslen;
struct berbuf bb = BB_NULL;
Debug( LDAP_DEBUG_TRACE, "********'%s'\n",
at_row.cols[ 0 ], 0, 0 );
......@@ -338,10 +349,10 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
ber_str2bv( at_row.cols[ 8 ], 0, 1,
&at_map->sel_expr_u );
}
tmpslen = 0;
ber_str2bv( at_row.cols[ 2 ], 0, 0, &bv );
backsql_merge_from_clause( &at_map->from_tbls,
&tmpslen, &bv );
backsql_merge_from_clause( &bb, &bv );
at_map->from_tbls = bb.bb_val;
if ( at_row.value_len[ 3 ] < 0 ) {
at_map->join_where.bv_val = NULL;
at_map->join_where.bv_len = 0;
......
This diff is collapsed.
......@@ -51,59 +51,59 @@ char backsql_def_concat_func[] = "CONCAT(?,?)";
/* TimesTen */
char backsql_check_dn_ru_query[] = "SELECT dn_ru from ldap_entries";
struct berval *
backsql_strcat( struct berval *dest, ber_len_t *buflen, ... )
struct berbuf *
backsql_strcat( struct berbuf *dest, ... )
{
va_list strs;
ber_len_t cdlen, cslen, grow;
char *cstr;
assert( dest );
assert( dest->bv_val == NULL
|| dest->bv_len == strlen( dest->bv_val ) );
assert( dest->bb_val.bv_val == NULL
|| dest->bb_val.bv_len == strlen( dest->bb_val.bv_val ) );
#ifdef BACKSQL_TRACE
Debug( LDAP_DEBUG_TRACE, "==>backsql_strcat()\n" );
#endif /* BACKSQL_TRACE */
va_start( strs, buflen );
if ( dest->bv_val == NULL || *buflen == 0 ) {
dest->bv_val = (char *)ch_calloc( BACKSQL_STR_GROW,
va_start( strs, dest );
if ( dest->bb_val.bv_val == NULL || dest->bb_len == 0 ) {
dest->bb_val.bv_val = (char *)ch_calloc( BACKSQL_STR_GROW,
sizeof( char ) );
dest->bv_len = 0;
*buflen = BACKSQL_STR_GROW;
dest->bb_val.bv_len = 0;
dest->bb_len = BACKSQL_STR_GROW;
}
cdlen = dest->bv_len;
cdlen = dest->bb_val.bv_len;
while ( ( cstr = va_arg( strs, char * ) ) != NULL ) {
cslen = strlen( cstr );
grow = BACKSQL_MAX( BACKSQL_STR_GROW, cslen );
if ( *buflen - cdlen <= cslen ) {
if ( dest->bb_len - cdlen <= cslen ) {
char *tmp_dest;
#ifdef BACKSQL_TRACE
Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
"buflen=%d, cdlen=%d, cslen=%d "
"-- reallocating dest\n",
*buflen, cdlen + 1, cslen );
dest->bb_len, cdlen + 1, cslen );
#endif /* BACKSQL_TRACE */
tmp_dest = (char *)ch_realloc( dest->bv_val,
( *buflen ) + grow * sizeof( char ) );
tmp_dest = (char *)ch_realloc( dest->bb_val.bv_val,
( dest->bb_len ) + grow * sizeof( char ) );
if ( tmp_dest == NULL ) {
Debug( LDAP_DEBUG_ANY, "backsql_strcat(): "
"could not reallocate string buffer.\n",
0, 0, 0 );
return NULL;
}
dest->bv_val = tmp_dest;
*buflen += grow;
dest->bb_val.bv_val = tmp_dest;
dest->bb_len += grow;
#ifdef BACKSQL_TRACE
Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
"new buflen=%d, dest=%p\n", *buflen, dest, 0 );
"new buflen=%d, dest=%p\n", dest->bb_len, dest, 0 );
#endif /* BACKSQL_TRACE */
}
AC_MEMCPY( dest->bv_val + cdlen, cstr, cslen + 1 );
AC_MEMCPY( dest->bb_val.bv_val + cdlen, cstr, cslen + 1 );
cdlen += cslen;
}
va_end( strs );
......@@ -113,37 +113,36 @@ backsql_strcat( struct berval *dest, ber_len_t *buflen, ... )
dest, 0, 0 );
#endif /* BACKSQL_TRACE */
dest->bv_len = cdlen;
dest->bb_val.bv_len = cdlen;
return dest;
}
struct berval *
backsql_strfcat( struct berval *dest, ber_len_t *buflen, const char *fmt, ... )
struct berbuf *
backsql_strfcat( struct berbuf *dest, const char *fmt, ... )
{
va_list strs;
ber_len_t cdlen;
assert( dest );
assert( buflen );
assert( fmt );
assert( *buflen == 0 || *buflen > dest->bv_len );
assert( dest->bv_val == NULL
|| dest->bv_len == strlen( dest->bv_val ) );
assert( dest->bb_len == 0 || dest->bb_len > dest->bb_val.bv_len );
assert( dest->bb_val.bv_val == NULL
|| dest->bb_val.bv_len == strlen( dest->bb_val.bv_val ) );
#ifdef BACKSQL_TRACE
Debug( LDAP_DEBUG_TRACE, "==>backsql_strfcat()\n" );
#endif /* BACKSQL_TRACE */
va_start( strs, fmt );
if ( dest->bv_val == NULL || *buflen == 0 ) {
dest->bv_val = (char *)ch_calloc( BACKSQL_STR_GROW,
if ( dest->bb_val.bv_val == NULL || dest->bb_len == 0 ) {
dest->bb_val.bv_val = (char *)ch_calloc( BACKSQL_STR_GROW,
sizeof( char ) );
dest->bv_len = 0;
*buflen = BACKSQL_STR_GROW;
dest->bb_val.bv_len = 0;
dest->bb_len = BACKSQL_STR_GROW;
}
cdlen = dest->bv_len;
cdlen = dest->bb_val.bv_len;
for ( ; fmt[0]; fmt++ ) {
ber_len_t cslen, grow;
char *cstr, cc[ 2 ] = { '\0', '\0' };
......@@ -185,36 +184,36 @@ backsql_strfcat( struct berval *dest, ber_len_t *buflen, const char *fmt, ... )
}
grow = BACKSQL_MAX( BACKSQL_STR_GROW, cslen );
if ( *buflen - cdlen <= cslen ) {
if ( dest->bb_len - cdlen <= cslen ) {
char *tmp_dest;
#ifdef BACKSQL_TRACE
Debug( LDAP_DEBUG_TRACE, "backsql_strfcat(): "
"buflen=%d, cdlen=%d, cslen=%d "
"-- reallocating dest\n",
*buflen, cdlen + 1, cslen );
dest->bb_len, cdlen + 1, cslen );
#endif /* BACKSQL_TRACE */
tmp_dest = (char *)ch_realloc( dest->bv_val,
( *buflen ) + grow * sizeof( char ) );
tmp_dest = (char *)ch_realloc( dest->bb_val.bv_val,
( dest->bb_len ) + grow * sizeof( char ) );
if ( tmp_dest == NULL ) {
Debug( LDAP_DEBUG_ANY, "backsql_strfcat(): "
"could not reallocate string buffer.\n",
0, 0, 0 );
return NULL;
}
dest->bv_val = tmp_dest;
*buflen += grow * sizeof( char );
dest->bb_val.bv_val = tmp_dest;
dest->bb_len += grow * sizeof( char );
#ifdef BACKSQL_TRACE
Debug( LDAP_DEBUG_TRACE, "backsql_strfcat(): "
"new buflen=%d, dest=%p\n", *buflen, dest, 0 );
"new buflen=%d, dest=%p\n", dest->bb_len, dest, 0 );
#endif /* BACKSQL_TRACE */
}
assert( cstr );
AC_MEMCPY( dest->bv_val + cdlen, cstr, cslen + 1 );
AC_MEMCPY( dest->bb_val.bv_val + cdlen, cstr, cslen + 1 );
cdlen += cslen;
}
......@@ -225,7 +224,7 @@ backsql_strfcat( struct berval *dest, ber_len_t *buflen, const char *fmt, ... )
dest, 0, 0 );
#endif /* BACKSQL_TRACE */
dest->bv_len = cdlen;
dest->bb_val.bv_len = cdlen;
return dest;
}
......@@ -276,8 +275,7 @@ char *
backsql_get_table_spec( char **p )
{
char *s, *q;
struct berval res = BER_BVNULL;
ber_len_t res_len = 0;
struct berbuf res = BB_NULL;
assert( p );
assert( *p );
......@@ -293,7 +291,7 @@ backsql_get_table_spec( char **p )
#define BACKSQL_NEXT_WORD { \
while ( *s && isspace( (unsigned char)*s ) ) s++; \
if ( !*s ) return res.bv_val; \
if ( !*s ) return res.bb_val.bv_val; \
q = s; \
while ( *q && !isspace( (unsigned char)*q ) ) q++; \
if ( *q ) *q++='\0'; \
......@@ -301,7 +299,7 @@ backsql_get_table_spec( char **p )
BACKSQL_NEXT_WORD;
/* table name */
backsql_strcat( &res, &res_len, s, NULL );
backsql_strcat( &res, s, NULL );
s = q;
BACKSQL_NEXT_WORD;
......@@ -311,29 +309,28 @@ backsql_get_table_spec( char **p )
}
#if 0
backsql_strcat( &res, &res_len, " AS ", s, NULL );
backsql_strcat( &res, " AS ", s, NULL );
/* oracle doesn't understand AS :( */
#endif
/* table alias */
backsql_strfcat( &res, &res_len, "cs", ' ', s );
backsql_strfcat( &res, "cs", ' ', s );
return res.bv_val;
return res.bb_val.bv_val;
}
int
backsql_merge_from_clause(
struct berval *dest_from,
ber_len_t *dest_len,
struct berbuf *dest_from,
struct berval *src_from )
{
char *s, *p, *srcc, *pos, e;
struct berval res = { 0 , NULL };
struct berbuf res = BB_NULL;
#ifdef BACKSQL_TRACE
Debug( LDAP_DEBUG_TRACE, "==>backsql_merge_from_clause(): "
"dest_from='%s',src_from='%s'\n",
dest_from ? dest_from->bv_val : "<NULL>", src_from, 0 );
dest_from ? dest_from->bb_val.bv_val : "<NULL>", src_from, 0 );
#endif /* BACKSQL_TRACE */
srcc = ch_strdup( src_from->bv_val );
......@@ -351,15 +348,13 @@ backsql_merge_from_clause(
"p='%s' s='%s'\n", p, s, 0 );
#endif /* BACKSQL_TRACE */
if ( res.bv_val == NULL ) {
backsql_strcat( &res, dest_len, s, NULL );
if ( res.bb_val.bv_val == NULL ) {
backsql_strcat( &res, s, NULL );
} else {
pos = strstr( res.bv_val, s );
if ( pos == NULL ) {
backsql_strfcat( &res, dest_len, "cs", ',', s );
} else if ( ( e = pos[ strlen( s ) ] ) != '\0' && e != ',' ) {
backsql_strfcat( &res, dest_len, "cs", ',', s );
pos = strstr( res.bb_val.bv_val, s );
if ( pos == NULL || ( ( e = pos[ strlen( s ) ] ) != '\0' && e != ',' ) ) {
backsql_strfcat( &res, "cs", ',', s );
}
}
......@@ -454,25 +449,28 @@ backsql_prepare_pattern(
BerVarray values,
struct berval *res )
{