X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Foverlays%2Funique.c;h=845b24d2e0454e1b2861f1e939e7bc5611f0971e;hb=200af921f4f1de43d89ba587d711ee9fc739e1bb;hp=6852f917d57c919387c8f56966e4ac3609872788;hpb=5a6362c4531d12c1c98f9b88100ed4e3758a9ffa;p=openldap diff --git a/servers/slapd/overlays/unique.c b/servers/slapd/overlays/unique.c index 6852f917d5..845b24d2e0 100644 --- a/servers/slapd/overlays/unique.c +++ b/servers/slapd/overlays/unique.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2004-2007 The OpenLDAP Foundation. + * Copyright 2004-2011 The OpenLDAP Foundation. * Portions Copyright 2004,2006-2007 Symas Corporation. * All rights reserved. * @@ -44,16 +44,17 @@ typedef struct unique_attrs_s { typedef struct unique_domain_uri_s { struct unique_domain_uri_s *next; - struct berval *dn; - struct berval *ndn; - struct berval *filter; + struct berval dn; + struct berval ndn; + struct berval filter; + Filter *f; struct unique_attrs_s *attrs; int scope; } unique_domain_uri; typedef struct unique_domain_s { struct unique_domain_s *next; - struct berval *domain_spec; + struct berval domain_spec; struct unique_domain_uri_s *uri; char ignore; /* polarity of attributes */ char strict; /* null considered unique too */ @@ -138,9 +139,10 @@ unique_free_domain_uri ( unique_domain_uri *uri ) while ( uri ) { next_uri = uri->next; - ber_bvfree ( uri->dn ); - ber_bvfree ( uri->ndn ); - ber_bvfree ( uri->filter ); + ch_free ( uri->dn.bv_val ); + ch_free ( uri->ndn.bv_val ); + ch_free ( uri->filter.bv_val ); + filter_free( uri->f ); attr = uri->attrs; while ( attr ) { next_attr = attr->next; @@ -160,7 +162,7 @@ unique_free_domain ( unique_domain *domain ) while ( domain ) { next_domain = domain->next; - ber_bvfree ( domain->domain_spec ); + ch_free ( domain->domain_spec.bv_val ); unique_free_domain_uri ( domain->uri ); ch_free ( domain ); domain = next_domain; @@ -183,28 +185,44 @@ unique_new_domain_uri ( unique_domain_uri **urip, uri = ch_calloc ( 1, sizeof ( unique_domain_uri ) ); if ( url_desc->lud_dn && url_desc->lud_dn[0] ) { - ber_str2bv( url_desc->lud_dn, 0, 1, &bv ); + ber_str2bv( url_desc->lud_dn, 0, 0, &bv ); rc = dnPrettyNormal( NULL, &bv, - uri->dn, - uri->ndn, + &uri->dn, + &uri->ndn, NULL ); if ( rc != LDAP_SUCCESS ) { - snprintf( c->msg, sizeof( c->msg ), + snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid DN %d (%s)", url_desc->lud_dn, rc, ldap_err2string( rc )); rc = ARG_BAD_CONF; goto exit; } - if ( !dnIsSuffix ( uri->ndn, &be->be_nsuffix[0] ) ) { - sprintf ( c->msg, + if ( be->be_nsuffix == NULL ) { + snprintf( c->cr_msg, sizeof( c->cr_msg ), + "suffix must be set" ); + Debug ( LDAP_DEBUG_CONFIG, "unique config: %s\n", + c->cr_msg, NULL, NULL ); + rc = ARG_BAD_CONF; + goto exit; + } + + if ( !dnIsSuffix ( &uri->ndn, &be->be_nsuffix[0] ) ) { + snprintf( c->cr_msg, sizeof( c->cr_msg ), "dn <%s> is not a suffix of backend base dn <%s>", - uri->dn->bv_val, + uri->dn.bv_val, be->be_nsuffix[0].bv_val ); rc = ARG_BAD_CONF; goto exit; } + + if ( BER_BVISNULL( &be->be_rootndn ) || BER_BVISEMPTY( &be->be_rootndn ) ) { + Debug( LDAP_DEBUG_ANY, + "slapo-unique needs a rootdn; " + "backend <%s> has none, YMMV.\n", + be->be_nsuffix[0].bv_val, 0, 0 ); + } } attr_str = url_desc->lud_attrs; @@ -220,7 +238,7 @@ unique_new_domain_uri ( unique_domain_uri **urip, attr->next = uri->attrs; uri->attrs = attr; } else { - snprintf( c->msg, sizeof( c->msg ), + snprintf( c->cr_msg, sizeof( c->cr_msg ), "unique: attribute: %s: %s", attr_str[i], text ); rc = ARG_BAD_CONF; @@ -231,31 +249,38 @@ unique_new_domain_uri ( unique_domain_uri **urip, uri->scope = url_desc->lud_scope; if ( !uri->scope ) { - snprintf( c->msg, sizeof( c->msg ), + snprintf( c->cr_msg, sizeof( c->cr_msg ), "unique: uri with base scope will always be unique"); rc = ARG_BAD_CONF; goto exit; } if (url_desc->lud_filter) { - Filter * f; - uri->filter = ber_str2bv( url_desc->lud_filter, 0, 1, NULL); - f = str2filter( uri->filter->bv_val ); - if ( !f ) { - snprintf( c->msg, sizeof( c->msg ), + char *ptr; + uri->f = str2filter( url_desc->lud_filter ); + if ( !uri->f ) { + snprintf( c->cr_msg, sizeof( c->cr_msg ), + "unique: bad filter"); + rc = ARG_BAD_CONF; + goto exit; + } + /* make sure the strfilter is in normal form (ITS#5581) */ + filter2bv( uri->f, &uri->filter ); + ptr = strstr( uri->filter.bv_val, "(?=" /*)*/ ); + if ( ptr != NULL && ptr <= ( uri->filter.bv_val - STRLENOF( "(?=" /*)*/ ) + uri->filter.bv_len ) ) + { + snprintf( c->cr_msg, sizeof( c->cr_msg ), "unique: bad filter"); rc = ARG_BAD_CONF; goto exit; } - filter_free( f ); } exit: - if ( bv.bv_val ) ber_memfree ( bv.bv_val ); uri->next = *urip; *urip = uri; if ( rc ) { Debug ( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, - "%s: %s\n", c->log, c->msg, 0 ); + "%s: %s\n", c->log, c->cr_msg, 0 ); unique_free_domain_uri ( uri ); *urip = NULL; } @@ -305,7 +330,7 @@ unique_new_domain ( unique_domain **domainp, domain_spec, 0, 0); domain = ch_calloc ( 1, sizeof (unique_domain) ); - domain->domain_spec = ber_str2bv( domain_spec, 0, 1, NULL ); + ber_str2bv( domain_spec, 0, 1, &domain->domain_spec ); uri_start = domain_spec; if ( strncasecmp ( uri_start, "ignore ", @@ -326,7 +351,7 @@ unique_new_domain ( unique_domain **domainp, } rc = ldap_url_parselist_ext ( &url_descs, uri_start, " ", 0 ); if ( rc ) { - snprintf( c->msg, sizeof( c->msg ), + snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid ldap urilist", uri_start ); rc = ARG_BAD_CONF; @@ -352,7 +377,7 @@ exit: *domainp = domain; if ( rc ) { Debug ( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, - "%s: %s\n", c->log, c->msg, 0 ); + "%s: %s\n", c->log, c->cr_msg, 0 ); unique_free_domain ( domain ); *domainp = NULL; } @@ -372,24 +397,23 @@ unique_cf_base( ConfigArgs *c ) switch ( c->op ) { case SLAP_CONFIG_EMIT: rc = 0; - if ( legacy && legacy->uri && legacy->uri->dn ) { + if ( legacy && legacy->uri && legacy->uri->dn.bv_val ) { rc = value_add_one ( &c->rvalue_vals, - legacy->uri->dn ); + &legacy->uri->dn ); if ( rc ) return rc; rc = value_add_one ( &c->rvalue_nvals, - legacy->uri->ndn ); + &legacy->uri->ndn ); if ( rc ) return rc; } break; case LDAP_MOD_DELETE: - assert ( legacy && legacy->uri && legacy->uri->dn ); + assert ( legacy && legacy->uri && legacy->uri->dn.bv_val ); rc = 0; - ber_bvfree ( legacy->uri->dn ); - ber_bvfree ( legacy->uri->ndn ); - legacy->uri->dn = NULL; - legacy->uri->ndn = NULL; - if ( !legacy->uri->attrs - && !legacy->uri->dn ) { + ch_free ( legacy->uri->dn.bv_val ); + ch_free ( legacy->uri->ndn.bv_val ); + BER_BVZERO( &legacy->uri->dn ); + BER_BVZERO( &legacy->uri->ndn ); + if ( !legacy->uri->attrs ) { unique_free_domain_uri ( legacy->uri ); legacy->uri = NULL; } @@ -401,19 +425,27 @@ unique_cf_base( ConfigArgs *c ) case LDAP_MOD_ADD: case SLAP_CONFIG_ADD: if ( domains ) { - sprintf ( c->msg, + snprintf( c->cr_msg, sizeof( c->cr_msg ), "cannot set legacy attrs when URIs are present" ); Debug ( LDAP_DEBUG_CONFIG, "unique config: %s\n", - c->msg, NULL, NULL ); + c->cr_msg, NULL, NULL ); + rc = ARG_BAD_CONF; + break; + } + if ( be->be_nsuffix == NULL ) { + snprintf( c->cr_msg, sizeof( c->cr_msg ), + "suffix must be set" ); + Debug ( LDAP_DEBUG_CONFIG, "unique config: %s\n", + c->cr_msg, NULL, NULL ); rc = ARG_BAD_CONF; break; } if ( !dnIsSuffix ( &c->value_ndn, &be->be_nsuffix[0] ) ) { - sprintf ( c->msg, + snprintf( c->cr_msg, sizeof( c->cr_msg ), "dn is not a suffix of backend base" ); Debug ( LDAP_DEBUG_CONFIG, "unique config: %s\n", - c->msg, NULL, NULL ); + c->cr_msg, NULL, NULL ); rc = ARG_BAD_CONF; break; } @@ -425,16 +457,23 @@ unique_cf_base( ConfigArgs *c ) } if ( !legacy->uri ) unique_new_domain_uri_basic ( &legacy->uri, c ); - ber_bvfree ( legacy->uri->dn ); - ber_bvfree ( legacy->uri->ndn ); - legacy->uri->dn = ber_bvdup ( &c->value_dn ); - legacy->uri->ndn = ber_bvdup ( &c->value_ndn ); + ch_free ( legacy->uri->dn.bv_val ); + ch_free ( legacy->uri->ndn.bv_val ); + legacy->uri->dn = c->value_dn; + legacy->uri->ndn = c->value_ndn; rc = 0; break; default: abort(); } + if ( rc ) { + ch_free( c->value_dn.bv_val ); + BER_BVZERO( &c->value_dn ); + ch_free( c->value_ndn.bv_val ); + BER_BVZERO( &c->value_ndn ); + } + return rc; } @@ -485,7 +524,7 @@ unique_cf_attrs( ConfigArgs *c ) ch_free (attr); } if ( !legacy->uri->attrs - && !legacy->uri->dn ) { + && !legacy->uri->dn.bv_val ) { unique_free_domain_uri ( legacy->uri ); legacy->uri = NULL; } @@ -499,10 +538,10 @@ unique_cf_attrs( ConfigArgs *c ) case LDAP_MOD_ADD: case SLAP_CONFIG_ADD: if ( domains ) { - sprintf ( c->msg, + snprintf( c->cr_msg, sizeof( c->cr_msg ), "cannot set legacy attrs when URIs are present" ); Debug ( LDAP_DEBUG_CONFIG, "unique config: %s\n", - c->msg, NULL, NULL ); + c->cr_msg, NULL, NULL ); rc = ARG_BAD_CONF; break; } @@ -510,10 +549,10 @@ unique_cf_attrs( ConfigArgs *c ) && legacy->uri && legacy->uri->attrs && (c->type == UNIQUE_IGNORE) != legacy->ignore ) { - sprintf ( c->msg, + snprintf( c->cr_msg, sizeof( c->cr_msg ), "cannot set both attrs and ignore-attrs" ); Debug ( LDAP_DEBUG_CONFIG, "unique config: %s\n", - c->msg, NULL, NULL ); + c->cr_msg, NULL, NULL ); rc = ARG_BAD_CONF; break; } @@ -538,7 +577,7 @@ unique_cf_attrs( ConfigArgs *c ) attr->next = new_attrs; new_attrs = attr; } else { - snprintf( c->msg, sizeof( c->msg ), + snprintf( c->cr_msg, sizeof( c->cr_msg ), "unique: attribute: %s: %s", c->argv[i], text ); for ( attr = new_attrs; @@ -575,7 +614,7 @@ unique_cf_attrs( ConfigArgs *c ) if ( rc ) { Debug ( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, - "%s: %s\n", c->log, c->msg, 0 ); + "%s: %s\n", c->log, c->cr_msg, 0 ); } return rc; } @@ -620,10 +659,10 @@ unique_cf_strict( ConfigArgs *c ) case LDAP_MOD_ADD: case SLAP_CONFIG_ADD: if ( domains ) { - sprintf ( c->msg, + snprintf( c->cr_msg, sizeof( c->cr_msg ), "cannot set legacy attrs when URIs are present" ); Debug ( LDAP_DEBUG_CONFIG, "unique config: %s\n", - c->msg, NULL, NULL ); + c->cr_msg, NULL, NULL ); rc = ARG_BAD_CONF; break; } @@ -663,10 +702,7 @@ unique_cf_uri( ConfigArgs *c ) domain; domain = domain->next ) { rc = value_add_one ( &c->rvalue_vals, - domain->domain_spec ); - if ( rc ) break; - rc = value_add_one ( &c->rvalue_nvals, - domain->domain_spec ); + &domain->domain_spec ); if ( rc ) break; } break; @@ -705,10 +741,10 @@ unique_cf_uri( ConfigArgs *c ) case SLAP_CONFIG_ADD: /* fallthrough */ case LDAP_MOD_ADD: if ( legacy ) { - sprintf ( c->msg, + snprintf( c->cr_msg, sizeof( c->cr_msg ), "cannot set Uri when legacy attrs are present" ); Debug ( LDAP_DEBUG_CONFIG, "unique config: %s\n", - c->msg, NULL, NULL ); + c->cr_msg, NULL, NULL ); rc = ARG_BAD_CONF; break; } @@ -740,7 +776,8 @@ unique_cf_uri( ConfigArgs *c ) static int unique_db_init( - BackendDB *be + BackendDB *be, + ConfigReply *cr ) { slap_overinst *on = (slap_overinst *)be->bd_info; @@ -755,7 +792,8 @@ unique_db_init( static int unique_db_destroy( - BackendDB *be + BackendDB *be, + ConfigReply *cr ) { slap_overinst *on = (slap_overinst *)be->bd_info; @@ -779,7 +817,8 @@ unique_db_destroy( static int unique_open( - BackendDB *be + BackendDB *be, + ConfigReply *cr ) { Debug(LDAP_DEBUG_TRACE, "unique_open: overlay initialized\n", 0, 0, 0); @@ -795,7 +834,8 @@ unique_open( static int unique_close( - BackendDB *be + BackendDB *be, + ConfigReply *cr ) { slap_overinst *on = (slap_overinst *) be->bd_info; @@ -898,6 +938,7 @@ build_filter( AttributeDescription *ad, BerVarray b, char *kp, + int ks, void *ctx ) { @@ -919,15 +960,21 @@ build_filter( if ( b && b[0].bv_val ) { for ( i = 0; b[i].bv_val; i++ ) { struct berval bv; + int len; ldap_bv2escaped_filter_value_x( &b[i], &bv, 1, ctx ); - kp += sprintf( kp, "(%s=%s)", ad->ad_cname.bv_val, bv.bv_val ); + len = snprintf( kp, ks, "(%s=%s)", ad->ad_cname.bv_val, bv.bv_val ); + assert( len >= 0 && len < ks ); + kp += len; if ( bv.bv_val != b[i].bv_val ) { ber_memfree_x( bv.bv_val, ctx ); } } } else if ( domain->strict ) { - kp += sprintf( kp, "(%s=*)", ad->ad_cname.bv_val ); + int len; + len = snprintf( kp, ks, "(%s=*)", ad->ad_cname.bv_val ); + assert( len >= 0 && len < ks ); + kp += len; } break; } @@ -941,7 +988,7 @@ unique_search( struct berval * dn, int scope, SlapReply *rs, - char *key + struct berval *key ) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; @@ -950,10 +997,17 @@ unique_search( unique_counter uq = { NULL, 0 }; int rc; - Debug(LDAP_DEBUG_TRACE, "==> unique_search %s\n", key, 0, 0); + Debug(LDAP_DEBUG_TRACE, "==> unique_search %s\n", key->bv_val, 0, 0); - nop->ors_filter = str2filter_x(nop, key); - ber_str2bv(key, 0, 0, &nop->ors_filterstr); + nop->ors_filter = str2filter_x(nop, key->bv_val); + if(nop->ors_filter == NULL) { + op->o_bd->bd_info = (BackendInfo *) on->on_info; + send_ldap_error(op, rs, LDAP_OTHER, + "unique_search invalid filter"); + return(rs->sr_err); + } + + nop->ors_filterstr = *key; cb.sc_response = (slap_response*)count_attr_cb; cb.sc_private = &uq; @@ -974,8 +1028,8 @@ unique_search( nop->o_bd = on->on_info->oi_origdb; rc = nop->o_bd->be_search(nop, &nrs); - filter_free_x(nop, nop->ors_filter); - op->o_tmpfree( key, op->o_tmpmemctx ); + filter_free_x(nop, nop->ors_filter, 1); + op->o_tmpfree( key->bv_val, op->o_tmpmemctx ); if(rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT) { op->o_bd->bd_info = (BackendInfo *) on->on_info; @@ -1009,6 +1063,7 @@ unique_add( Operation nop = *op; Attribute *a; char *key, *kp; + struct berval bvkey; int rc = SLAP_CB_CONTINUE; Debug(LDAP_DEBUG_TRACE, "==> unique_add <%s>\n", @@ -1016,18 +1071,32 @@ unique_add( for ( domain = legacy ? legacy : domains; domain; - domain = domain->next ) { + domain = domain->next ) + { unique_domain_uri *uri; - int ks = 0; for ( uri = domain->uri; uri; - uri = uri->next ) { + uri = uri->next ) + { + int len; + int ks = 0; - if ( uri->ndn - && !dnIsSuffix( &op->o_req_ndn, uri->ndn )) + if ( uri->ndn.bv_val + && !dnIsSuffix( &op->o_req_ndn, &uri->ndn )) continue; + if ( uri->f ) { + if ( test_filter( NULL, op->ora_e, uri->f ) + == LDAP_COMPARE_FALSE ) + { + Debug( LDAP_DEBUG_TRACE, + "==> unique_add_skip<%s>\n", + op->o_req_dn.bv_val, 0, 0 ); + continue; + } + } + if(!(a = op->ora_e->e_attrs)) { op->o_bd->bd_info = (BackendInfo *) on->on_info; send_ldap_error(op, rs, LDAP_INVALID_SYNTAX, @@ -1047,13 +1116,21 @@ unique_add( /* skip this domain-uri if it isn't involved */ if ( !ks ) continue; - if ( uri->filter && uri->filter->bv_len ) - ks += uri->filter->bv_len + STRLENOF ("(&)"); + /* terminating NUL */ + ks += sizeof("(|)"); + + if ( uri->filter.bv_val && uri->filter.bv_len ) + ks += uri->filter.bv_len + STRLENOF ("(&)"); kp = key = op->o_tmpalloc(ks, op->o_tmpmemctx); - if ( uri->filter && uri->filter->bv_len ) - kp += sprintf (kp, "(&%s", uri->filter->bv_val); - kp += sprintf(kp, "(|"); + if ( uri->filter.bv_val && uri->filter.bv_len ) { + len = snprintf (kp, ks, "(&%s", uri->filter.bv_val); + assert( len >= 0 && len < ks ); + kp += len; + } + len = snprintf(kp, ks - (kp - key), "(|"); + assert( len >= 0 && len < ks - (kp - key) ); + kp += len; for(a = op->ora_e->e_attrs; a; a = a->a_next) kp = build_filter(domain, @@ -1061,20 +1138,28 @@ unique_add( a->a_desc, a->a_vals, kp, + ks - ( kp - key ), op->o_tmpmemctx); - kp += sprintf(kp, ")"); - if ( uri->filter && uri->filter->bv_len ) - kp += sprintf (kp, ")"); + len = snprintf(kp, ks - (kp - key), ")"); + assert( len >= 0 && len < ks - (kp - key) ); + kp += len; + if ( uri->filter.bv_val && uri->filter.bv_len ) { + len = snprintf(kp, ks - (kp - key), ")"); + assert( len >= 0 && len < ks - (kp - key) ); + kp += len; + } + bvkey.bv_val = key; + bvkey.bv_len = kp - key; rc = unique_search ( op, &nop, - uri->ndn ? - uri->ndn : + uri->ndn.bv_val ? + &uri->ndn : &op->o_bd->be_nsuffix[0], uri->scope, rs, - key); + &bvkey); if ( rc != SLAP_CB_CONTINUE ) break; } @@ -1099,6 +1184,7 @@ unique_modify( Operation nop = *op; Modifications *m; char *key, *kp; + struct berval bvkey; int rc = SLAP_CB_CONTINUE; Debug(LDAP_DEBUG_TRACE, "==> unique_modify <%s>\n", @@ -1106,16 +1192,19 @@ unique_modify( for ( domain = legacy ? legacy : domains; domain; - domain = domain->next ) { + domain = domain->next ) + { unique_domain_uri *uri; - int ks = 0; for ( uri = domain->uri; uri; - uri = uri->next ) { + uri = uri->next ) + { + int len; + int ks = 0; - if ( uri->ndn - && !dnIsSuffix( &op->o_req_ndn, uri->ndn )) + if ( uri->ndn.bv_val + && !dnIsSuffix( &op->o_req_ndn, &uri->ndn )) continue; if ( !(m = op->orm_modlist) ) { @@ -1138,13 +1227,21 @@ unique_modify( /* skip this domain-uri if it isn't involved */ if ( !ks ) continue; - if ( uri->filter && uri->filter->bv_len ) - ks += uri->filter->bv_len + STRLENOF ("(&)"); + /* terminating NUL */ + ks += sizeof("(|)"); + + if ( uri->filter.bv_val && uri->filter.bv_len ) + ks += uri->filter.bv_len + STRLENOF ("(&)"); kp = key = op->o_tmpalloc(ks, op->o_tmpmemctx); - if ( uri->filter && uri->filter->bv_len ) - kp += sprintf (kp, "(&%s", uri->filter->bv_val); - kp += sprintf(kp, "(|"); + if ( uri->filter.bv_val && uri->filter.bv_len ) { + len = snprintf(kp, ks, "(&%s", uri->filter.bv_val); + assert( len >= 0 && len < ks ); + kp += len; + } + len = snprintf(kp, ks - (kp - key), "(|"); + assert( len >= 0 && len < ks - (kp - key) ); + kp += len; for(m = op->orm_modlist; m; m = m->sml_next) if ( (m->sml_op & LDAP_MOD_OP) @@ -1154,20 +1251,28 @@ unique_modify( m->sml_desc, m->sml_values, kp, + ks - (kp - key), op->o_tmpmemctx ); - kp += sprintf (kp, ")"); - if ( uri->filter && uri->filter->bv_len ) - kp += sprintf (kp, ")"); + len = snprintf(kp, ks - (kp - key), ")"); + assert( len >= 0 && len < ks - (kp - key) ); + kp += len; + if ( uri->filter.bv_val && uri->filter.bv_len ) { + len = snprintf (kp, ks - (kp - key), ")"); + assert( len >= 0 && len < ks - (kp - key) ); + kp += len; + } + bvkey.bv_val = key; + bvkey.bv_len = kp - key; rc = unique_search ( op, &nop, - uri->ndn ? - uri->ndn : + uri->ndn.bv_val ? + &uri->ndn : &op->o_bd->be_nsuffix[0], uri->scope, rs, - key); + &bvkey); if ( rc != SLAP_CB_CONTINUE ) break; } @@ -1191,6 +1296,7 @@ unique_modrdn( unique_domain *domain; Operation nop = *op; char *key, *kp; + struct berval bvkey; LDAPRDN newrdn; struct berval bv[2]; int rc = SLAP_CB_CONTINUE; @@ -1200,19 +1306,21 @@ unique_modrdn( for ( domain = legacy ? legacy : domains; domain; - domain = domain->next ) { + domain = domain->next ) + { unique_domain_uri *uri; - int ks = 0; for ( uri = domain->uri; uri; - uri = uri->next ) { - int i; + uri = uri->next ) + { + int i, len; + int ks = 0; - if ( uri->ndn - && !dnIsSuffix( &op->o_req_ndn, uri->ndn ) + if ( uri->ndn.bv_val + && !dnIsSuffix( &op->o_req_ndn, &uri->ndn ) && (!op->orr_nnewSup - || !dnIsSuffix( op->orr_nnewSup, uri->ndn ))) + || !dnIsSuffix( op->orr_nnewSup, &uri->ndn ))) continue; if ( ldap_bv2rdn_x ( &op->oq_modrdn.rs_newrdn, @@ -1255,13 +1363,21 @@ unique_modrdn( /* skip this domain if it isn't involved */ if ( !ks ) continue; - if ( uri->filter && uri->filter->bv_len ) - ks += uri->filter->bv_len + STRLENOF ("(&)"); + /* terminating NUL */ + ks += sizeof("(|)"); + + if ( uri->filter.bv_val && uri->filter.bv_len ) + ks += uri->filter.bv_len + STRLENOF ("(&)"); kp = key = op->o_tmpalloc(ks, op->o_tmpmemctx); - if ( uri->filter && uri->filter->bv_len ) - kp += sprintf (kp, "(&%s", uri->filter->bv_val); - kp += sprintf(kp, "(|"); + if ( uri->filter.bv_val && uri->filter.bv_len ) { + len = snprintf(kp, ks, "(&%s", uri->filter.bv_val); + assert( len >= 0 && len < ks ); + kp += len; + } + len = snprintf(kp, ks - (kp - key), "(|"); + assert( len >= 0 && len < ks - (kp - key) ); + kp += len; for ( i=0; newrdn[i]; i++) { bv[0] = newrdn[i]->la_value; @@ -1270,21 +1386,29 @@ unique_modrdn( newrdn[i]->la_private, bv, kp, + ks - (kp - key ), op->o_tmpmemctx); } - kp += sprintf(kp, ")"); - if ( uri->filter && uri->filter->bv_len ) - kp += sprintf (kp, ")"); + len = snprintf(kp, ks - (kp - key), ")"); + assert( len >= 0 && len < ks - (kp - key) ); + kp += len; + if ( uri->filter.bv_val && uri->filter.bv_len ) { + len = snprintf (kp, ks - (kp - key), ")"); + assert( len >= 0 && len < ks - (kp - key) ); + kp += len; + } + bvkey.bv_val = key; + bvkey.bv_len = kp - key; rc = unique_search ( op, &nop, - uri->ndn ? - uri->ndn : + uri->ndn.bv_val ? + &uri->ndn : &op->o_bd->be_nsuffix[0], uri->scope, rs, - key); + &bvkey); if ( rc != SLAP_CB_CONTINUE ) break; }