/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2004 The OpenLDAP Foundation.
+ * Copyright 2004-2006 The OpenLDAP Foundation.
* Portions Copyright 2004 Symas Corporation.
* All rights reserved.
*
} unique_data;
typedef struct unique_counter_s {
+ struct berval *ndn;
int count;
} unique_counter;
for(up = ud->attrs; up; up = up->next)
if(!strcmp(argv[i], up->attr->ad_cname.bv_val)) {
Debug(LDAP_DEBUG_ANY,
- "%s: line %d: duplicate attribute <s>, ignored\n",
+ "%s: line %d: duplicate attribute <%s>, ignored\n",
fname, lineno, argv[i]);
continue;
}
up->next = ud->attrs;
ud->attrs = up;
}
- Debug(LDAP_DEBUG_ANY, "%s: line %d: new attribute <%s>\n",
+ Debug(LDAP_DEBUG_CONFIG, "%s: line %d: new attribute <%s>\n",
fname, lineno, argv[i]);
}
} else if(!strcasecmp(*argv, "unique_strict")) {
ber_str2bv( argv[1], 0, 0, &bv );
ch_free(ud->dn.bv_val);
dnNormalize(0, NULL, NULL, &bv, &ud->dn, NULL);
- Debug(LDAP_DEBUG_ANY, "%s: line %d: new base dn <%s>\n",
+ Debug(LDAP_DEBUG_CONFIG, "%s: line %d: new base dn <%s>\n",
fname, lineno, argv[1]);
} else {
return(SLAP_CONF_UNKNOWN);
SlapReply *rs
)
{
+ unique_counter *uc;
+
/* because you never know */
if(!op || !rs) return(0);
/* Only search entries are interesting */
if(rs->sr_type != REP_SEARCH) return(0);
+ uc = op->o_callback->sc_private;
+
+ /* Ignore the current entry */
+ if ( dn_match( uc->ndn, &rs->sr_entry->e_nname )) return(0);
+
Debug(LDAP_DEBUG_TRACE, "==> count_attr_cb <%s>\n",
rs->sr_entry ? rs->sr_entry->e_name.bv_val : "UNKNOWN_DN", 0, 0);
- ((unique_counter*)op->o_callback->sc_private)->count++;
+ uc->count++;
return(0);
}
unique_attrs *up;
int i;
- while(!is_at_operational(ad->ad_type)) {
- if(ud->ignore) {
- for(up = ud->ignore; up; up = up->next)
- if(ad == up->attr) break;
- if(up) break;
+ while ( !is_at_operational( ad->ad_type ) ) {
+ if ( ud->ignore ) {
+ for ( up = ud->ignore; up; up = up->next ) {
+ if (ad == up->attr ) {
+ break;
+ }
+ }
+ if ( up ) {
+ break;
+ }
}
- if(ud->attrs) {
- for(up = ud->attrs; up; up = up->next)
- if(ad == up->attr) break;
- if(!up) break;
+ if ( ud->attrs ) {
+ for ( up = ud->attrs; up; up = up->next ) {
+ if ( ad == up->attr ) {
+ break;
+ }
+ }
+ if ( !up ) {
+ break;
+ }
}
- if(b && b[0].bv_val) for(i = 0; b[i].bv_val; i++)
- ks += b[i].bv_len + ad->ad_cname.bv_len + STRLENOF( "(=)" );
- else if(ud->strict)
+ if ( b && b[0].bv_val ) {
+ for (i = 0; b[i].bv_val; i++ ) {
+ /* note: make room for filter escaping... */
+ ks += ( 3 * b[i].bv_len ) + ad->ad_cname.bv_len + STRLENOF( "(=)" );
+ }
+ } else if ( ud->strict ) {
ks += ad->ad_cname.bv_len + STRLENOF( "(=*)" ); /* (attr=*) */
+ }
break;
}
return ks;
unique_data *ud,
AttributeDescription *ad,
BerVarray b,
- char *kp
+ char *kp,
+ void *ctx
)
{
unique_attrs *up;
int i;
- while(!is_at_operational(ad->ad_type)) {
- if(ud->ignore) {
- for(up = ud->ignore; up; up = up->next)
- if(ad == up->attr) break;
- if(up) break;
+ while ( !is_at_operational( ad->ad_type ) ) {
+ if ( ud->ignore ) {
+ for ( up = ud->ignore; up; up = up->next ) {
+ if ( ad == up->attr ) {
+ break;
+ }
+ }
+ if ( up ) {
+ break;
+ }
}
- if(ud->attrs) {
- for(up = ud->attrs; up; up = up->next)
- if(ad == up->attr) break;
- if(!up) break;
+ if ( ud->attrs ) {
+ for ( up = ud->attrs; up; up = up->next ) {
+ if ( ad == up->attr ) {
+ break;
+ }
+ }
+ if ( !up ) {
+ break;
+ }
+ }
+ if ( b && b[0].bv_val ) {
+ for ( i = 0; b[i].bv_val; i++ ) {
+ struct berval bv;
+
+ ldap_bv2escaped_filter_value_x( &b[i], &bv, 1, ctx );
+ kp += sprintf( kp, "(%s=%s)", ad->ad_cname.bv_val, bv.bv_val );
+ if ( bv.bv_val != b[i].bv_val ) {
+ ber_memfree_x( bv.bv_val, ctx );
+ }
+ }
+ } else if ( ud->strict ) {
+ kp += sprintf( kp, "(%s=*)", ad->ad_cname.bv_val );
}
- if(b && b[0].bv_val) for(i = 0; b[i].bv_val; i++)
- kp += sprintf(kp, "(%s=%s)", ad->ad_cname.bv_val, b[i].bv_val);
- else if(ud->strict)
- kp += sprintf(kp, "(%s=*)", ad->ad_cname.bv_val);
break;
}
return kp;
unique_data *ud = on->on_bi.bi_private;
SlapReply nrs = { REP_RESULT };
slap_callback cb = { NULL, NULL, NULL, NULL }; /* XXX */
- unique_counter uq = { 0 };
+ unique_counter uq = { NULL, 0 };
int rc;
nop->ors_filter = str2filter_x(nop, key);
nop->o_tag = LDAP_REQ_SEARCH;
nop->ors_scope = LDAP_SCOPE_SUBTREE;
nop->ors_deref = LDAP_DEREF_NEVER;
+ nop->ors_limit = NULL;
nop->ors_slimit = SLAP_NO_LIMIT;
nop->ors_tlimit = SLAP_NO_LIMIT;
nop->ors_attrs = slap_anlist_no_attrs;
nop->ors_attrsonly = 1;
- nop->o_sync_slog_size = -1;
+
+ uq.ndn = &op->o_req_ndn;
nop->o_req_ndn = ud->dn;
nop->o_ndn = op->o_bd->be_rootndn;
+ nop->o_bd = on->on_info->oi_origdb;
rc = nop->o_bd->be_search(nop, &nrs);
filter_free_x(nop, nop->ors_filter);
- ch_free( key );
+ op->o_tmpfree( key, op->o_tmpmemctx );
if(rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT) {
op->o_bd->bd_info = (BackendInfo *) on->on_info;
return(SLAP_CB_CONTINUE);
}
+#define ALLOC_EXTRA 16 /* extra slop */
+
static int unique_add(
Operation *op,
SlapReply *rs
Attribute *a;
char *key, *kp;
- int ks = 16;
+ int ks = 0;
Debug(LDAP_DEBUG_TRACE, "==> unique_add <%s>\n", op->o_req_dn.bv_val, 0, 0);
- /* validate backend. Should have already been done, but whatever */
- nop.o_bd = select_backend(&ud->dn, 0, 1);
- if(nop.o_bd) {
- if (!nop.o_bd->be_search) {
- op->o_bd->bd_info = (BackendInfo *) on->on_info;
- send_ldap_error(op, rs, LDAP_UNWILLING_TO_PERFORM,
- "backend missing search function");
- return(rs->sr_err);
- }
- } else {
- op->o_bd->bd_info = (BackendInfo *) on->on_info;
- send_ldap_error(op, rs, LDAP_OTHER,
- "no known backend? this shouldn't be happening!");
- return(rs->sr_err);
- }
+ if ( !dnIsSuffix( &op->o_req_ndn, &ud->dn ))
+ return SLAP_CB_CONTINUE;
/*
** count everything first;
ks = count_filter_len(ud, a->a_desc, a->a_vals, ks);
}
- key = ch_malloc(ks);
+ if ( !ks )
+ return SLAP_CB_CONTINUE;
+
+ ks += ALLOC_EXTRA;
+ key = op->o_tmpalloc(ks, op->o_tmpmemctx);
kp = key + sprintf(key, "(|");
for(a = op->ora_e->e_attrs; a; a = a->a_next) {
- kp = build_filter(ud, a->a_desc, a->a_vals, kp);
+ kp = build_filter(ud, a->a_desc, a->a_vals, kp, op->o_tmpmemctx);
}
sprintf(kp, ")");
Modifications *m;
char *key, *kp;
- int ks = 16; /* a handful of extra bytes */
+ int ks = 0;
Debug(LDAP_DEBUG_TRACE, "==> unique_modify <%s>\n", op->o_req_dn.bv_val, 0, 0);
- nop.o_bd = select_backend(&ud->dn, 0, 1);
- if(nop.o_bd) {
- if (!nop.o_bd->be_search) {
- op->o_bd->bd_info = (BackendInfo *) on->on_info;
- send_ldap_error(op, rs, LDAP_UNWILLING_TO_PERFORM,
- "backend missing search function");
- return(rs->sr_err);
- }
- } else {
- op->o_bd->bd_info = (BackendInfo *) on->on_info;
- send_ldap_error(op, rs, LDAP_OTHER,
- "no known backend? this shouldn't be happening!");
- return(rs->sr_err);
- }
+ if ( !dnIsSuffix( &op->o_req_ndn, &ud->dn ))
+ return SLAP_CB_CONTINUE;
/*
** count everything first;
ks = count_filter_len(ud, m->sml_desc, m->sml_values, ks);
}
- key = ch_malloc(ks);
+ if ( !ks )
+ return SLAP_CB_CONTINUE;
+
+ ks += ALLOC_EXTRA;
+ key = op->o_tmpalloc(ks, op->o_tmpmemctx);
kp = key + sprintf(key, "(|");
for(m = op->orm_modlist; m; m = m->sml_next) {
if ((m->sml_op & LDAP_MOD_OP) == LDAP_MOD_DELETE) continue;
- kp = build_filter(ud, m->sml_desc, m->sml_values, kp);
+ kp = build_filter(ud, m->sml_desc, m->sml_values, kp, op->o_tmpmemctx);
}
sprintf(kp, ")");
Operation nop = *op;
char *key, *kp;
- int i, rc, ks = 16; /* a handful of extra bytes */
+ int i, ks = 0;
LDAPRDN newrdn;
struct berval bv[2];
Debug(LDAP_DEBUG_TRACE, "==> unique_modrdn <%s> <%s>\n",
op->o_req_dn.bv_val, op->orr_newrdn.bv_val, 0);
- nop.o_bd = select_backend(&ud->dn, 0, 1);
- if(nop.o_bd) {
- if (!nop.o_bd->be_search) {
- op->o_bd->bd_info = (BackendInfo *) on->on_info;
- send_ldap_error(op, rs, LDAP_UNWILLING_TO_PERFORM,
- "backend missing search function");
- return(rs->sr_err);
- }
- } else {
- op->o_bd->bd_info = (BackendInfo *) on->on_info;
- send_ldap_error(op, rs, LDAP_OTHER,
- "no known backend? this shouldn't be happening!");
- return(rs->sr_err);
- }
+ if ( !dnIsSuffix( &op->o_req_ndn, &ud->dn ) &&
+ (!op->orr_nnewSup || !dnIsSuffix( op->orr_nnewSup, &ud->dn )))
+ return SLAP_CB_CONTINUE;
if(ldap_bv2rdn_x(&op->oq_modrdn.rs_newrdn, &newrdn,
(char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx )) {
ks = count_filter_len(ud, newrdn[i]->la_private, bv, ks);
}
- key = ch_malloc(ks);
+ if ( !ks )
+ return SLAP_CB_CONTINUE;
+
+ ks += ALLOC_EXTRA;
+ key = op->o_tmpalloc(ks, op->o_tmpmemctx);
kp = key + sprintf(key, "(|");
for(i = 0; newrdn[i]; i++) {
bv[0] = newrdn[i]->la_value;
- kp = build_filter(ud, newrdn[i]->la_private, bv, kp);
+ kp = build_filter(ud, newrdn[i]->la_private, bv, kp, op->o_tmpmemctx);
}
sprintf(kp, ")");
** it expects to be called automagically during dynamic module initialization
*/
-int unique_init() {
+int unique_initialize() {
/* statically declared just after the #includes at top */
unique.on_bi.bi_type = "unique";
#if SLAPD_OVER_UNIQUE == SLAPD_MOD_DYNAMIC && defined(PIC)
int init_module(int argc, char *argv[]) {
- return unique_init();
+ return unique_initialize();
}
#endif