diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 9ea7d39d90..9149adf2ca 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -453,14 +453,53 @@ int config_del_vals(ConfigTable *cf, ConfigArgs *c) { int rc = 0; + void *ptr; - /* If there is no handler, just ignore it */ if ( cf->arg_type & ARG_MAGIC ) { c->argv[0] = cf->ad->ad_cname.bv_val; c->op = LDAP_MOD_DELETE; c->type = cf->arg_type & ARGS_USERLAND; rc = (*((ConfigDriver*)cf->arg_item))(c); + return rc; } + /* If there is no handler, just zero it */ + if ( cf->arg_type & ARG_OFFSET ) { + if ( c->be && c->table == Cft_Database ) + ptr = c->be->be_private; + else if ( c->bi ) + ptr = c->bi->bi_private; + else { + snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> offset is missing base pointer", + c->argv[0] ); + Debug( LDAP_DEBUG_CONFIG, "%s: %s!\n", + c->log, c->cr_msg ); + return ARG_BAD_CONF; + } + ptr = (void *)((char *)ptr + (long)cf->arg_item); + } else if ( cf->arg_type & ARGS_TYPES ) { + ptr = cf->arg_item; + } + if ( cf->arg_type & ARGS_TYPES ) + switch ( cf->arg_type & ARGS_TYPES ) { + case ARG_ON_OFF: + case ARG_INT: *(int *)ptr = 0; break; + case ARG_UINT: *(unsigned *)ptr = 0; break; + case ARG_LONG: *(long *)ptr = 0; break; + case ARG_ULONG: *(size_t *)ptr = 0; break; + case ARG_BER_LEN_T: *(ber_len_t *)ptr = 0; break; + case ARG_STRING: + ch_free( *(char**)ptr ); + *(char **)ptr = NULL; + break; + case ARG_BERVAL: + case ARG_BINARY: + ch_free( ((struct berval *)ptr)->bv_val ); + BER_BVZERO( (struct berval *)ptr ); + break; + case ARG_ATDESC: + *(AttributeDescription **)ptr = NULL; + break; + } return rc; }