mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-20 22:59:34 -05:00
ITS#9715 Deduplicate verbmasks implementation from slapd/lloadd
This commit is contained in:
parent
f50cca2e12
commit
90fc349654
6 changed files with 303 additions and 366 deletions
|
|
@ -23,7 +23,7 @@ NT_OBJS = ../slapd/nt_svc.o ../../libraries/liblutil/slapdmsg.res
|
|||
|
||||
SRCS += main.c value.c \
|
||||
../slapd/ch_malloc.c ../slapd/logging.c ../slapd/proxyp.c \
|
||||
../slapd/sl_malloc.c ../slapd/user.c
|
||||
../slapd/sl_malloc.c ../slapd/user.c ../slapd/verbs.c
|
||||
|
||||
OBJS = $(patsubst %.c,%.o,$(SRCS)) $(@PLAT@_OBJS)
|
||||
|
||||
|
|
|
|||
|
|
@ -2894,99 +2894,6 @@ lload_read_config( const char *fname, const char *dir )
|
|||
return lload_read_config_file( fname, 0, NULL, config_back_cf_table );
|
||||
}
|
||||
|
||||
/* restrictops, allows, disallows, requires, loglevel */
|
||||
|
||||
int
|
||||
bverb_to_mask( struct berval *bword, slap_verbmasks *v )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; !BER_BVISNULL( &v[i].word ); i++ ) {
|
||||
if ( !ber_bvstrcasecmp( bword, &v[i].word ) ) break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
verb_to_mask( const char *word, slap_verbmasks *v )
|
||||
{
|
||||
struct berval bword;
|
||||
ber_str2bv( word, 0, 0, &bword );
|
||||
return bverb_to_mask( &bword, v );
|
||||
}
|
||||
|
||||
int
|
||||
verbs_to_mask( int argc, char *argv[], slap_verbmasks *v, slap_mask_t *m )
|
||||
{
|
||||
int i, j;
|
||||
for ( i = 1; i < argc; i++ ) {
|
||||
j = verb_to_mask( argv[i], v );
|
||||
if ( BER_BVISNULL( &v[j].word ) ) return i;
|
||||
while ( !v[j].mask )
|
||||
j--;
|
||||
*m |= v[j].mask;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Mask keywords that represent multiple bits should occur before single
|
||||
* bit keywords in the verbmasks array.
|
||||
*/
|
||||
int
|
||||
mask_to_verbs( slap_verbmasks *v, slap_mask_t m, BerVarray *bva )
|
||||
{
|
||||
int i, rc = 1;
|
||||
|
||||
if ( m ) {
|
||||
for ( i = 0; !BER_BVISNULL( &v[i].word ); i++ ) {
|
||||
if ( !v[i].mask ) continue;
|
||||
if ( (m & v[i].mask) == v[i].mask ) {
|
||||
value_add_one( bva, &v[i].word );
|
||||
rc = 0;
|
||||
m ^= v[i].mask;
|
||||
if ( !m ) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
slap_verbmasks_init( slap_verbmasks **vp, slap_verbmasks *v )
|
||||
{
|
||||
int i;
|
||||
|
||||
assert( *vp == NULL );
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &v[i].word ); i++ ) /* EMPTY */;
|
||||
|
||||
*vp = ch_calloc( i + 1, sizeof(slap_verbmasks) );
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &v[i].word ); i++ ) {
|
||||
ber_dupbv( &(*vp)[i].word, &v[i].word );
|
||||
*( (slap_mask_t *)&(*vp)[i].mask ) = v[i].mask;
|
||||
}
|
||||
|
||||
BER_BVZERO( &(*vp)[i].word );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
slap_verbmasks_destroy( slap_verbmasks *v )
|
||||
{
|
||||
int i;
|
||||
|
||||
assert( v != NULL );
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &v[i].word ); i++ ) {
|
||||
ch_free( v[i].word.bv_val );
|
||||
}
|
||||
|
||||
ch_free( v );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef BALANCER_MODULE
|
||||
int
|
||||
config_push_cleanup( ConfigArgs *ca, ConfigDriver *cleanup )
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ SRCS = main.c globals.c bconfig.c config.c daemon.c \
|
|||
connection.c search.c filter.c add.c cr.c \
|
||||
attr.c entry.c backend.c result.c operation.c \
|
||||
dn.c compare.c modify.c delete.c modrdn.c ch_malloc.c \
|
||||
value.c ava.c bind.c unbind.c abandon.c filterentry.c \
|
||||
value.c verbs.c ava.c bind.c unbind.c abandon.c filterentry.c \
|
||||
phonetic.c acl.c str2filter.c aclparse.c init.c user.c \
|
||||
lock.c logging.c controls.c extended.c passwd.c proxyp.c \
|
||||
schema.c schema_check.c schema_init.c schema_prep.c \
|
||||
|
|
@ -45,7 +45,7 @@ OBJS = main.o globals.o bconfig.o config.o daemon.o \
|
|||
connection.o search.o filter.o add.o cr.o \
|
||||
attr.o entry.o backend.o backends.o result.o operation.o \
|
||||
dn.o compare.o modify.o delete.o modrdn.o ch_malloc.o \
|
||||
value.o ava.o bind.o unbind.o abandon.o filterentry.o \
|
||||
value.o verbs.o ava.o bind.o unbind.o abandon.o filterentry.o \
|
||||
phonetic.o acl.o str2filter.o aclparse.o init.o user.o \
|
||||
lock.o logging.o controls.o extended.o passwd.o proxyp.o \
|
||||
schema.o schema_check.o schema_init.o schema_prep.o \
|
||||
|
|
|
|||
|
|
@ -1022,258 +1022,6 @@ done:
|
|||
|
||||
/* restrictops, allows, disallows, requires, loglevel */
|
||||
|
||||
int
|
||||
bverb_to_mask(struct berval *bword, slap_verbmasks *v) {
|
||||
int i;
|
||||
for(i = 0; !BER_BVISNULL(&v[i].word); i++) {
|
||||
if(!ber_bvstrcasecmp(bword, &v[i].word)) break;
|
||||
}
|
||||
return(i);
|
||||
}
|
||||
|
||||
int
|
||||
verb_to_mask(const char *word, slap_verbmasks *v) {
|
||||
struct berval bword;
|
||||
ber_str2bv( word, 0, 0, &bword );
|
||||
return bverb_to_mask( &bword, v );
|
||||
}
|
||||
|
||||
int
|
||||
verbs_to_mask(int argc, char *argv[], slap_verbmasks *v, slap_mask_t *m) {
|
||||
int i, j;
|
||||
for(i = 1; i < argc; i++) {
|
||||
j = verb_to_mask(argv[i], v);
|
||||
if(BER_BVISNULL(&v[j].word)) return i;
|
||||
while (!v[j].mask) j--;
|
||||
*m |= v[j].mask;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Mask keywords that represent multiple bits should occur before single
|
||||
* bit keywords in the verbmasks array.
|
||||
*/
|
||||
int
|
||||
mask_to_verbs(slap_verbmasks *v, slap_mask_t m, BerVarray *bva) {
|
||||
int i, rc = 1;
|
||||
|
||||
if (m) {
|
||||
for (i=0; !BER_BVISNULL(&v[i].word); i++) {
|
||||
if (!v[i].mask) continue;
|
||||
if (( m & v[i].mask ) == v[i].mask ) {
|
||||
value_add_one( bva, &v[i].word );
|
||||
rc = 0;
|
||||
m ^= v[i].mask;
|
||||
if ( !m ) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Return the verbs as a single string, separated by delim */
|
||||
int
|
||||
mask_to_verbstring(slap_verbmasks *v, slap_mask_t m0, char delim, struct berval *bv)
|
||||
{
|
||||
int i, rc = 1;
|
||||
|
||||
BER_BVZERO( bv );
|
||||
if (m0) {
|
||||
slap_mask_t m = m0;
|
||||
char *ptr;
|
||||
for (i=0; !BER_BVISNULL(&v[i].word); i++) {
|
||||
if (!v[i].mask) continue;
|
||||
if (( m & v[i].mask ) == v[i].mask ) {
|
||||
bv->bv_len += v[i].word.bv_len + 1;
|
||||
rc = 0;
|
||||
m ^= v[i].mask;
|
||||
if ( !m ) break;
|
||||
}
|
||||
}
|
||||
bv->bv_val = ch_malloc(bv->bv_len);
|
||||
bv->bv_len--;
|
||||
ptr = bv->bv_val;
|
||||
m = m0;
|
||||
for (i=0; !BER_BVISNULL(&v[i].word); i++) {
|
||||
if (!v[i].mask) continue;
|
||||
if (( m & v[i].mask ) == v[i].mask ) {
|
||||
ptr = lutil_strcopy(ptr, v[i].word.bv_val);
|
||||
*ptr++ = delim;
|
||||
m ^= v[i].mask;
|
||||
if ( !m ) break;
|
||||
}
|
||||
}
|
||||
ptr[-1] = '\0';
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Parse a verbstring */
|
||||
int
|
||||
verbstring_to_mask(slap_verbmasks *v, char *str, char delim, slap_mask_t *m) {
|
||||
int j;
|
||||
char *d;
|
||||
struct berval bv;
|
||||
|
||||
do {
|
||||
bv.bv_val = str;
|
||||
d = strchr( str, delim );
|
||||
if ( d )
|
||||
bv.bv_len = d - str;
|
||||
else
|
||||
bv.bv_len = strlen( str );
|
||||
j = bverb_to_mask( &bv, v );
|
||||
if(BER_BVISNULL(&v[j].word)) return 1;
|
||||
while (!v[j].mask) j--;
|
||||
*m |= v[j].mask;
|
||||
str += bv.bv_len + 1;
|
||||
} while ( d );
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
slap_verbmasks_init( slap_verbmasks **vp, slap_verbmasks *v )
|
||||
{
|
||||
int i;
|
||||
|
||||
assert( *vp == NULL );
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &v[ i ].word ); i++ ) /* EMPTY */;
|
||||
|
||||
*vp = ch_calloc( i + 1, sizeof( slap_verbmasks ) );
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &v[ i ].word ); i++ ) {
|
||||
ber_dupbv( &(*vp)[ i ].word, &v[ i ].word );
|
||||
*((slap_mask_t *)&(*vp)[ i ].mask) = v[ i ].mask;
|
||||
}
|
||||
|
||||
BER_BVZERO( &(*vp)[ i ].word );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
slap_verbmasks_destroy( slap_verbmasks *v )
|
||||
{
|
||||
int i;
|
||||
|
||||
assert( v != NULL );
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &v[ i ].word ); i++ ) {
|
||||
ch_free( v[ i ].word.bv_val );
|
||||
}
|
||||
|
||||
ch_free( v );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
slap_verbmasks_append(
|
||||
slap_verbmasks **vp,
|
||||
slap_mask_t m,
|
||||
struct berval *v,
|
||||
slap_mask_t *ignore )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !m ) {
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &(*vp)[ i ].word ); i++ ) {
|
||||
if ( !(*vp)[ i ].mask ) continue;
|
||||
|
||||
if ( ignore != NULL ) {
|
||||
int j;
|
||||
|
||||
for ( j = 0; ignore[ j ] != 0; j++ ) {
|
||||
if ( (*vp)[ i ].mask == ignore[ j ] ) {
|
||||
goto check_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( m & (*vp)[ i ].mask ) == (*vp)[ i ].mask ) {
|
||||
if ( ber_bvstrcasecmp( v, &(*vp)[ i ].word ) == 0 ) {
|
||||
/* already set; ignore */
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
/* conflicts */
|
||||
return LDAP_TYPE_OR_VALUE_EXISTS;
|
||||
}
|
||||
|
||||
if ( m & (*vp)[ i ].mask ) {
|
||||
/* conflicts */
|
||||
return LDAP_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
check_next:;
|
||||
}
|
||||
|
||||
*vp = ch_realloc( *vp, sizeof( slap_verbmasks ) * ( i + 2 ) );
|
||||
ber_dupbv( &(*vp)[ i ].word, v );
|
||||
*((slap_mask_t *)&(*vp)[ i ].mask) = m;
|
||||
BER_BVZERO( &(*vp)[ i + 1 ].word );
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
enum_to_verb(slap_verbmasks *v, slap_mask_t m, struct berval *bv) {
|
||||
int i;
|
||||
|
||||
for (i=0; !BER_BVISNULL(&v[i].word); i++) {
|
||||
if ( m == v[i].mask ) {
|
||||
if ( bv != NULL ) {
|
||||
*bv = v[i].word;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* register a new verbmask */
|
||||
static int
|
||||
slap_verbmask_register( slap_verbmasks *vm_, slap_verbmasks **vmp, struct berval *bv, int mask )
|
||||
{
|
||||
slap_verbmasks *vm = *vmp;
|
||||
int i;
|
||||
|
||||
/* check for duplicate word */
|
||||
/* NOTE: we accept duplicate codes; the first occurrence will be used
|
||||
* when mapping from mask to verb */
|
||||
i = verb_to_mask( bv->bv_val, vm );
|
||||
if ( !BER_BVISNULL( &vm[ i ].word ) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &vm[ i ].word ); i++ )
|
||||
;
|
||||
|
||||
if ( vm == vm_ ) {
|
||||
/* first time: duplicate array */
|
||||
vm = ch_calloc( i + 2, sizeof( slap_verbmasks ) );
|
||||
for ( i = 0; !BER_BVISNULL( &vm_[ i ].word ); i++ )
|
||||
{
|
||||
ber_dupbv( &vm[ i ].word, &vm_[ i ].word );
|
||||
*((slap_mask_t*)&vm[ i ].mask) = vm_[ i ].mask;
|
||||
}
|
||||
|
||||
} else {
|
||||
vm = ch_realloc( vm, (i + 2) * sizeof( slap_verbmasks ) );
|
||||
}
|
||||
|
||||
ber_dupbv( &vm[ i ].word, bv );
|
||||
*((slap_mask_t*)&vm[ i ].mask) = mask;
|
||||
|
||||
BER_BVZERO( &vm[ i+1 ].word );
|
||||
|
||||
*vmp = vm;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static slap_verbmasks slap_ldap_response_code_[] = {
|
||||
{ BER_BVC("success"), LDAP_SUCCESS },
|
||||
|
||||
|
|
|
|||
|
|
@ -723,24 +723,6 @@ LDAP_SLAPD_F (int) read_config LDAP_P(( const char *fname, const char *dir ));
|
|||
LDAP_SLAPD_F (void) config_destroy LDAP_P ((void));
|
||||
LDAP_SLAPD_F (char **) slap_str2clist LDAP_P((
|
||||
char ***, char *, const char * ));
|
||||
LDAP_SLAPD_F (int) bverb_to_mask LDAP_P((
|
||||
struct berval *bword, slap_verbmasks *v ));
|
||||
LDAP_SLAPD_F (int) verb_to_mask LDAP_P((
|
||||
const char *word, slap_verbmasks *v ));
|
||||
LDAP_SLAPD_F (int) verbs_to_mask LDAP_P((
|
||||
int argc, char *argv[], slap_verbmasks *v, slap_mask_t *m ));
|
||||
LDAP_SLAPD_F (int) mask_to_verbs LDAP_P((
|
||||
slap_verbmasks *v, slap_mask_t m, BerVarray *bva ));
|
||||
LDAP_SLAPD_F (int) mask_to_verbstring LDAP_P((
|
||||
slap_verbmasks *v, slap_mask_t m, char delim, struct berval *bv ));
|
||||
LDAP_SLAPD_F (int) verbstring_to_mask LDAP_P((
|
||||
slap_verbmasks *v, char *str, char delim, slap_mask_t *m ));
|
||||
LDAP_SLAPD_F (int) enum_to_verb LDAP_P((
|
||||
slap_verbmasks *v, slap_mask_t m, struct berval *bv ));
|
||||
LDAP_SLAPD_F (int) slap_verbmasks_init LDAP_P(( slap_verbmasks **vp, slap_verbmasks *v ));
|
||||
LDAP_SLAPD_F (int) slap_verbmasks_destroy LDAP_P(( slap_verbmasks *v ));
|
||||
LDAP_SLAPD_F (int) slap_verbmasks_append LDAP_P(( slap_verbmasks **vp,
|
||||
slap_mask_t m, struct berval *v, slap_mask_t *ignore ));
|
||||
LDAP_SLAPD_F (int) slap_tls_get_config LDAP_P((
|
||||
LDAP *ld, int opt, char **val ));
|
||||
LDAP_SLAPD_F (void) bindconf_tls_defaults LDAP_P(( slap_bindconf *bc ));
|
||||
|
|
@ -2042,6 +2024,30 @@ LDAP_SLAPD_F (int) value_add_one LDAP_P((
|
|||
/* assumes (x) > (y) returns 1 if true, 0 otherwise */
|
||||
#define SLAP_PTRCMP(x, y) ((x) < (y) ? -1 : (x) > (y))
|
||||
|
||||
/*
|
||||
* verbs.c
|
||||
*/
|
||||
LDAP_SLAPD_F (int) bverb_to_mask LDAP_P((
|
||||
struct berval *bword, slap_verbmasks *v ));
|
||||
LDAP_SLAPD_F (int) verb_to_mask LDAP_P((
|
||||
const char *word, slap_verbmasks *v ));
|
||||
LDAP_SLAPD_F (int) verbs_to_mask LDAP_P((
|
||||
int argc, char *argv[], slap_verbmasks *v, slap_mask_t *m ));
|
||||
LDAP_SLAPD_F (int) mask_to_verbs LDAP_P((
|
||||
slap_verbmasks *v, slap_mask_t m, BerVarray *bva ));
|
||||
LDAP_SLAPD_F (int) mask_to_verbstring LDAP_P((
|
||||
slap_verbmasks *v, slap_mask_t m, char delim, struct berval *bv ));
|
||||
LDAP_SLAPD_F (int) verbstring_to_mask LDAP_P((
|
||||
slap_verbmasks *v, char *str, char delim, slap_mask_t *m ));
|
||||
LDAP_SLAPD_F (int) enum_to_verb LDAP_P((
|
||||
slap_verbmasks *v, slap_mask_t m, struct berval *bv ));
|
||||
LDAP_SLAPD_F (int) slap_verbmasks_init LDAP_P(( slap_verbmasks **vp, slap_verbmasks *v ));
|
||||
LDAP_SLAPD_F (int) slap_verbmasks_destroy LDAP_P(( slap_verbmasks *v ));
|
||||
LDAP_SLAPD_F (int) slap_verbmasks_append LDAP_P(( slap_verbmasks **vp,
|
||||
slap_mask_t m, struct berval *v, slap_mask_t *ignore ));
|
||||
LDAP_SLAPD_F (int) slap_verbmask_register LDAP_P(( slap_verbmasks *vm_,
|
||||
slap_verbmasks **vmp, struct berval *bv, int mask ));
|
||||
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
/*
|
||||
* zn_malloc.c
|
||||
|
|
|
|||
276
servers/slapd/verbs.c
Normal file
276
servers/slapd/verbs.c
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 1998-2021 The OpenLDAP Foundation.
|
||||
* 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
|
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "slap.h"
|
||||
#include "slap-config.h"
|
||||
|
||||
int
|
||||
bverb_to_mask( struct berval *bword, slap_verbmasks *v ) {
|
||||
int i;
|
||||
for ( i = 0; !BER_BVISNULL(&v[i].word); i++ ) {
|
||||
if ( !ber_bvstrcasecmp( bword, &v[i].word) ) break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
verb_to_mask( const char *word, slap_verbmasks *v ) {
|
||||
struct berval bword;
|
||||
ber_str2bv( word, 0, 0, &bword );
|
||||
return bverb_to_mask( &bword, v );
|
||||
}
|
||||
|
||||
int
|
||||
verbs_to_mask( int argc, char *argv[], slap_verbmasks *v, slap_mask_t *m ) {
|
||||
int i, j;
|
||||
for (i = 1; i < argc; i++ ) {
|
||||
j = verb_to_mask( argv[i], v );
|
||||
if ( BER_BVISNULL(&v[j].word) ) return i;
|
||||
while ( !v[j].mask ) j--;
|
||||
*m |= v[j].mask;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mask keywords that represent multiple bits should occur before single
|
||||
* bit keywords in the verbmasks array.
|
||||
*/
|
||||
int
|
||||
mask_to_verbs( slap_verbmasks *v, slap_mask_t m, BerVarray *bva ) {
|
||||
int i, rc = 1;
|
||||
|
||||
if ( m ) {
|
||||
for ( i=0; !BER_BVISNULL(&v[i].word); i++ ) {
|
||||
if (!v[i].mask) continue;
|
||||
if ( ( m & v[i].mask ) == v[i].mask ) {
|
||||
value_add_one( bva, &v[i].word );
|
||||
rc = 0;
|
||||
m ^= v[i].mask;
|
||||
if ( !m ) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Return the verbs as a single string, separated by delim */
|
||||
int
|
||||
mask_to_verbstring( slap_verbmasks *v, slap_mask_t m0, char delim, struct berval *bv )
|
||||
{
|
||||
int i, rc = 1;
|
||||
|
||||
BER_BVZERO( bv );
|
||||
if ( m0 ) {
|
||||
slap_mask_t m = m0;
|
||||
char *ptr;
|
||||
for ( i=0; !BER_BVISNULL(&v[i].word); i++ ) {
|
||||
if ( !v[i].mask ) continue;
|
||||
if ( ( m & v[i].mask ) == v[i].mask ) {
|
||||
bv->bv_len += v[i].word.bv_len + 1;
|
||||
rc = 0;
|
||||
m ^= v[i].mask;
|
||||
if ( !m ) break;
|
||||
}
|
||||
}
|
||||
bv->bv_val = ch_malloc(bv->bv_len);
|
||||
bv->bv_len--;
|
||||
ptr = bv->bv_val;
|
||||
m = m0;
|
||||
for ( i=0; !BER_BVISNULL(&v[i].word); i++ ) {
|
||||
if ( !v[i].mask ) continue;
|
||||
if ( ( m & v[i].mask ) == v[i].mask ) {
|
||||
ptr = lutil_strcopy( ptr, v[i].word.bv_val );
|
||||
*ptr++ = delim;
|
||||
m ^= v[i].mask;
|
||||
if ( !m ) break;
|
||||
}
|
||||
}
|
||||
ptr[-1] = '\0';
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Parse a verbstring */
|
||||
int
|
||||
verbstring_to_mask( slap_verbmasks *v, char *str, char delim, slap_mask_t *m ) {
|
||||
int j;
|
||||
char *d;
|
||||
struct berval bv;
|
||||
|
||||
do {
|
||||
bv.bv_val = str;
|
||||
d = strchr( str, delim );
|
||||
if ( d )
|
||||
bv.bv_len = d - str;
|
||||
else
|
||||
bv.bv_len = strlen( str );
|
||||
j = bverb_to_mask( &bv, v );
|
||||
if ( BER_BVISNULL(&v[j].word) ) return 1;
|
||||
while ( !v[j].mask ) j--;
|
||||
*m |= v[j].mask;
|
||||
str += bv.bv_len + 1;
|
||||
} while ( d );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
slap_verbmasks_init( slap_verbmasks **vp, slap_verbmasks *v )
|
||||
{
|
||||
int i;
|
||||
|
||||
assert( *vp == NULL );
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &v[ i ].word ); i++ ) /* EMPTY */;
|
||||
|
||||
*vp = ch_calloc( i + 1, sizeof( slap_verbmasks ) );
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &v[ i ].word ); i++ ) {
|
||||
ber_dupbv( &(*vp)[ i ].word, &v[ i ].word );
|
||||
*((slap_mask_t *)&(*vp)[ i ].mask) = v[ i ].mask;
|
||||
}
|
||||
|
||||
BER_BVZERO( &(*vp)[ i ].word );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
slap_verbmasks_destroy( slap_verbmasks *v )
|
||||
{
|
||||
int i;
|
||||
|
||||
assert( v != NULL );
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &v[ i ].word ); i++ ) {
|
||||
ch_free( v[ i ].word.bv_val );
|
||||
}
|
||||
|
||||
ch_free( v );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
slap_verbmasks_append(
|
||||
slap_verbmasks **vp,
|
||||
slap_mask_t m,
|
||||
struct berval *v,
|
||||
slap_mask_t *ignore )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !m ) {
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &(*vp)[ i ].word ); i++ ) {
|
||||
if ( !(*vp)[ i ].mask ) continue;
|
||||
|
||||
if ( ignore != NULL ) {
|
||||
int j;
|
||||
|
||||
for ( j = 0; ignore[ j ] != 0; j++ ) {
|
||||
if ( (*vp)[ i ].mask == ignore[ j ] ) {
|
||||
goto check_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( m & (*vp)[ i ].mask ) == (*vp)[ i ].mask ) {
|
||||
if ( ber_bvstrcasecmp( v, &(*vp)[ i ].word ) == 0 ) {
|
||||
/* already set; ignore */
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
/* conflicts */
|
||||
return LDAP_TYPE_OR_VALUE_EXISTS;
|
||||
}
|
||||
|
||||
if ( m & (*vp)[ i ].mask ) {
|
||||
/* conflicts */
|
||||
return LDAP_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
check_next:;
|
||||
}
|
||||
|
||||
*vp = ch_realloc( *vp, sizeof( slap_verbmasks ) * ( i + 2 ) );
|
||||
ber_dupbv( &(*vp)[ i ].word, v );
|
||||
*((slap_mask_t *)&(*vp)[ i ].mask) = m;
|
||||
BER_BVZERO( &(*vp)[ i + 1 ].word );
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
enum_to_verb(slap_verbmasks *v, slap_mask_t m, struct berval *bv) {
|
||||
int i;
|
||||
|
||||
for (i=0; !BER_BVISNULL(&v[i].word); i++) {
|
||||
if ( m == v[i].mask ) {
|
||||
if ( bv != NULL ) {
|
||||
*bv = v[i].word;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* register a new verbmask */
|
||||
int
|
||||
slap_verbmask_register(
|
||||
slap_verbmasks *vm_,
|
||||
slap_verbmasks **vmp,
|
||||
struct berval *bv,
|
||||
int mask )
|
||||
{
|
||||
slap_verbmasks *vm = *vmp;
|
||||
int i;
|
||||
|
||||
/* check for duplicate word */
|
||||
/* NOTE: we accept duplicate codes; the first occurrence will be used
|
||||
* when mapping from mask to verb */
|
||||
i = verb_to_mask( bv->bv_val, vm );
|
||||
if ( !BER_BVISNULL( &vm[ i ].word ) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &vm[ i ].word ); i++ )
|
||||
;
|
||||
|
||||
if ( vm == vm_ ) {
|
||||
/* first time: duplicate array */
|
||||
vm = ch_calloc( i + 2, sizeof( slap_verbmasks ) );
|
||||
for ( i = 0; !BER_BVISNULL( &vm_[ i ].word ); i++ )
|
||||
{
|
||||
ber_dupbv( &vm[ i ].word, &vm_[ i ].word );
|
||||
*((slap_mask_t*)&vm[ i ].mask) = vm_[ i ].mask;
|
||||
}
|
||||
|
||||
} else {
|
||||
vm = ch_realloc( vm, (i + 2) * sizeof( slap_verbmasks ) );
|
||||
}
|
||||
|
||||
ber_dupbv( &vm[ i ].word, bv );
|
||||
*((slap_mask_t*)&vm[ i ].mask) = mask;
|
||||
|
||||
BER_BVZERO( &vm[ i+1 ].word );
|
||||
|
||||
*vmp = vm;
|
||||
|
||||
return i;
|
||||
}
|
||||
Loading…
Reference in a new issue