#include "portable.h"
#include <stdio.h>
#include <limits.h>
#include <ac/ctype.h>
#include <ac/errno.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"
#include "ldap_pvt.h"
#include "lber_pvt.h"
#include "ldap_utf8.h"
#ifdef HAVE_TLS
#include <openssl/x509.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/crypto.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/asn1.h>
#include <openssl/x509v3.h>
#include <openssl/ssl.h>
#endif
#include "lutil_hash.h"
#define HASH_BYTES LUTIL_HASH_BYTES
#define HASH_CONTEXT lutil_HASH_CTX
#define HASH_Init(c) lutil_HASHInit(c)
#define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
#define HASH_Final(d,c) lutil_HASHFinal(d,c)
#define OpenLDAPaciMatch NULL
#define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
#define directoryStringApproxMatch approxMatch
#define directoryStringApproxIndexer approxIndexer
#define directoryStringApproxFilter approxFilter
#define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
#define IA5StringApproxMatch approxMatch
#define IA5StringApproxIndexer approxIndexer
#define IA5StringApproxFilter approxFilter
static int
inValidate(
Syntax *syntax,
struct berval *in )
{
return LDAP_INVALID_SYNTAX;
}
static int
blobValidate(
Syntax *syntax,
struct berval *in )
{
return LDAP_SUCCESS;
}
#define berValidate blobValidate
static int
sequenceValidate(
Syntax *syntax,
struct berval *in )
{
if ( in->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
if ( in->bv_val[0] != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
return LDAP_SUCCESS;
}
#ifdef HAVE_TLS
static int certificateValidate( Syntax *syntax, struct berval *in )
{
X509 *xcert=NULL;
unsigned char *p = (unsigned char *)in->bv_val;
xcert = d2i_X509(NULL, &p, in->bv_len);
if ( !xcert ) return LDAP_INVALID_SYNTAX;
X509_free(xcert);
return LDAP_SUCCESS;
}
#else
#define certificateValidate sequenceValidate
#endif
static int
octetStringMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
struct berval *asserted = (struct berval *) assertedValue;
int match = value->bv_len - asserted->bv_len;
if( match == 0 ) {
match = memcmp( value->bv_val, asserted->bv_val, value->bv_len );
}
*matchp = match;
return LDAP_SUCCESS;
}
static int
octetStringOrderingMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
struct berval *asserted = (struct berval *) assertedValue;
ber_len_t v_len = value->bv_len;
ber_len_t av_len = asserted->bv_len;
int match = memcmp( value->bv_val, asserted->bv_val,
(v_len < av_len ? v_len : av_len) );
if( match == 0 ) match = v_len - av_len;
*matchp = match;
return LDAP_SUCCESS;
}
int octetStringIndexer(
slap_mask_t use,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *prefix,
BerVarray values,
BerVarray *keysp,
void *ctx )
{
int i;
size_t slen, mlen;
BerVarray keys;
HASH_CONTEXT HASHcontext;
unsigned char HASHdigest[HASH_BYTES];
struct berval digest;
digest.bv_val = (char *)HASHdigest;
digest.bv_len = sizeof(HASHdigest);
for( i=0; values[i].bv_val != NULL; i++ ) {
}
assert( i > 0 );
keys = sl_malloc( sizeof( struct berval ) * (i+1), ctx );
slen = syntax->ssyn_oidlen;
mlen = mr->smr_oidlen;
for( i=0; values[i].bv_val != NULL; i++ ) {
HASH_Init( &HASHcontext );
if( prefix != NULL && prefix->bv_len > 0 ) {
HASH_Update( &HASHcontext,
(unsigned char *)prefix->bv_val,
prefix->bv_len );
}
HASH_Update( &HASHcontext,
(unsigned char *)syntax->ssyn_oid, slen );
HASH_Update( &HASHcontext,
(unsigned char *)mr->smr_oid, mlen );
HASH_Update( &HASHcontext,
(unsigned char *)values[i].bv_val, values[i].bv_len );
HASH_Final( HASHdigest, &HASHcontext );
ber_dupbv_x( &keys[i], &digest, ctx );
}
keys[i].bv_val = NULL;
keys[i].bv_len = 0;
*keysp = keys;
return LDAP_SUCCESS;
}
int octetStringFilter(
slap_mask_t use,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *prefix,
void * assertedValue,
BerVarray *keysp,
void *ctx )
{
size_t slen, mlen;
BerVarray keys;
HASH_CONTEXT HASHcontext;
unsigned char HASHdigest[HASH_BYTES];
struct berval *value = (struct berval *) assertedValue;
struct berval digest;
digest.bv_val = (char *)HASHdigest;
digest.bv_len = sizeof(HASHdigest);
slen = syntax->ssyn_oidlen;
mlen = mr->smr_oidlen;
keys = sl_malloc( sizeof( struct berval ) * 2, ctx );
HASH_Init( &HASHcontext );
if( prefix != NULL && prefix->bv_len > 0 ) {
HASH_Update( &HASHcontext,
(unsigned char *)prefix->bv_val, prefix->bv_len );
}
HASH_Update( &HASHcontext,
(unsigned char *)syntax->ssyn_oid, slen );
HASH_Update( &HASHcontext,
(unsigned char *)mr->smr_oid, mlen );
HASH_Update( &HASHcontext,
(unsigned char *)value->bv_val, value->bv_len );
HASH_Final( HASHdigest, &HASHcontext );
ber_dupbv_x( keys, &digest, ctx );
keys[1].bv_val = NULL;
keys[1].bv_len = 0;
*keysp = keys;
return LDAP_SUCCESS;
}
static int
octetStringSubstringsMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
int match = 0;
SubstringsAssertion *sub = assertedValue;
struct berval left = *value;
int i;
ber_len_t inlen = 0;
if( sub->sa_initial.bv_val ) {
inlen += sub->sa_initial.bv_len;
}
if( sub->sa_any ) {
for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
inlen += sub->sa_any[i].bv_len;
}
}
if( sub->sa_final.bv_val ) {
inlen += sub->sa_final.bv_len;
}
if( sub->sa_initial.bv_val ) {
if( inlen > left.bv_len ) {
match = 1;
goto done;
}
match = memcmp( sub->sa_initial.bv_val, left.bv_val,
sub->sa_initial.bv_len );
if( match != 0 ) {
goto done;
}
left.bv_val += sub->sa_initial.bv_len;
left.bv_len -= sub->sa_initial.bv_len;
inlen -= sub->sa_initial.bv_len;
}
if( sub->sa_final.bv_val ) {
if( inlen > left.bv_len ) {
match = 1;
goto done;
}
match = memcmp( sub->sa_final.bv_val,
&left.bv_val[left.bv_len - sub->sa_final.bv_len],
sub->sa_final.bv_len );
if( match != 0 ) {
goto done;
}
left.bv_len -= sub->sa_final.bv_len;
inlen -= sub->sa_final.bv_len;
}
if( sub->sa_any ) {
for(i=0; sub->sa_any[i].bv_val; i++) {
ber_len_t idx;
char *p;
retry:
if( inlen > left.bv_len ) {
match = 1;
goto done;
}
if( sub->sa_any[i].bv_len == 0 ) {
continue;
}
p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
if( p == NULL ) {
match = 1;
goto done;
}
idx = p - left.bv_val;
if( idx >= left.bv_len ) {
return LDAP_OTHER;
}
left.bv_val = p;
left.bv_len -= idx;
if( sub->sa_any[i].bv_len > left.bv_len ) {
match = 1;
goto done;
}
match = memcmp( left.bv_val,
sub->sa_any[i].bv_val,
sub->sa_any[i].bv_len );
if( match != 0 ) {
left.bv_val++;
left.bv_len--;
goto retry;
}
left.bv_val += sub->sa_any[i].bv_len;
left.bv_len -= sub->sa_any[i].bv_len;
inlen -= sub->sa_any[i].bv_len;
}
}
done:
*matchp = match;
return LDAP_SUCCESS;
}
static int
octetStringSubstringsIndexer(
slap_mask_t use,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *prefix,
BerVarray values,
BerVarray *keysp,
void *ctx )
{
ber_len_t i, nkeys;
size_t slen, mlen;
BerVarray keys;
HASH_CONTEXT HASHcontext;
unsigned char HASHdigest[HASH_BYTES];
struct berval digest;
digest.bv_val = (char *)HASHdigest;
digest.bv_len = sizeof(HASHdigest);
nkeys=0;
for( i=0; values[i].bv_val != NULL; i++ ) {
if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
continue;
}
if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
(SLAP_INDEX_SUBSTR_MINLEN - 1);
} else {
nkeys += values[i].bv_len - (SLAP_INDEX_SUBSTR_MINLEN - 1);
}
}
if( flags & SLAP_INDEX_SUBSTR_ANY ) {
if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
nkeys += values[i].bv_len - (SLAP_INDEX_SUBSTR_MAXLEN - 1);
}
}
if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
( SLAP_INDEX_SUBSTR_MINLEN - 1);
} else {
nkeys += values[i].bv_len - (SLAP_INDEX_SUBSTR_MINLEN - 1);
}
}
}
if( nkeys == 0 ) {
*keysp = NULL;
return LDAP_SUCCESS;
}
keys = sl_malloc( sizeof( struct berval ) * (nkeys+1), ctx );
slen = syntax->ssyn_oidlen;
mlen = mr->smr_oidlen;
nkeys=0;
for( i=0; values[i].bv_val != NULL; i++ ) {
ber_len_t j,max;
if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
{
char pre = SLAP_INDEX_SUBSTR_PREFIX;
max = values[i].bv_len - (SLAP_INDEX_SUBSTR_MAXLEN - 1);
for( j=0; j<max; j++ ) {
HASH_Init( &HASHcontext );
if( prefix != NULL && prefix->bv_len > 0 ) {
HASH_Update( &HASHcontext,
(unsigned char *)prefix->bv_val, prefix->bv_len );
}
HASH_Update( &HASHcontext,
(unsigned char *)&pre, sizeof( pre ) );
HASH_Update( &HASHcontext,
(unsigned char *)syntax->ssyn_oid, slen );
HASH_Update( &HASHcontext,
(unsigned char *)mr->smr_oid, mlen );
HASH_Update( &HASHcontext,
(unsigned char *)&values[i].bv_val[j],
SLAP_INDEX_SUBSTR_MAXLEN );
HASH_Final( HASHdigest, &HASHcontext );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
}
max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
char pre;
if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
HASH_Init( &HASHcontext );
if( prefix != NULL && prefix->bv_len > 0 ) {
HASH_Update( &HASHcontext,
(unsigned char *)prefix->bv_val, prefix->bv_len );
}
HASH_Update( &HASHcontext,
(unsigned char *)&pre, sizeof( pre ) );
HASH_Update( &HASHcontext,
(unsigned char *)syntax->ssyn_oid, slen );
HASH_Update( &HASHcontext,
(unsigned char *)mr->smr_oid, mlen );
HASH_Update( &HASHcontext,
(unsigned char *)values[i].bv_val, j );
HASH_Final( HASHdigest, &HASHcontext );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
HASH_Init( &HASHcontext );
if( prefix != NULL && prefix->bv_len > 0 ) {
HASH_Update( &HASHcontext,
(unsigned char *)prefix->bv_val, prefix->bv_len );
}
HASH_Update( &HASHcontext,
(unsigned char *)&pre, sizeof( pre ) );
HASH_Update( &HASHcontext,
(unsigned char *)syntax->ssyn_oid, slen );
HASH_Update( &HASHcontext,
(unsigned char *)mr->smr_oid, mlen );
HASH_Update( &HASHcontext,
(unsigned char *)&values[i].bv_val[values[i].bv_len-j], j );
HASH_Final( HASHdigest, &HASHcontext );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
}
}
if( nkeys > 0 ) {
keys[nkeys].bv_val = NULL;
*keysp = keys;
} else {
ch_free( keys );
*keysp = NULL;
}
return LDAP_SUCCESS;
}
static int
octetStringSubstringsFilter (
slap_mask_t use,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *prefix,
void * assertedValue,
BerVarray *keysp,
void *ctx)
{
SubstringsAssertion *sa;
char pre;
ber_len_t nkeys = 0;
size_t slen, mlen, klen;
BerVarray keys;
HASH_CONTEXT HASHcontext;
unsigned char HASHdigest[HASH_BYTES];
struct berval *value;
struct berval digest;
sa = (SubstringsAssertion *) assertedValue;
if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL
&& sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
{
nkeys++;
}
if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
ber_len_t i;
for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
nkeys += sa->sa_any[i].bv_len -
( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
}
}
}
if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
{
nkeys++;
}
if( nkeys == 0 ) {
*keysp = NULL;
return LDAP_SUCCESS;
}
digest.bv_val = (char *)HASHdigest;
digest.bv_len = sizeof(HASHdigest);
slen = syntax->ssyn_oidlen;
mlen = mr->smr_oidlen;
keys = sl_malloc( sizeof( struct berval ) * (nkeys+1), ctx );
nkeys = 0;
if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
{
pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
value = &sa->sa_initial;
klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
HASH_Init( &HASHcontext );
if( prefix != NULL && prefix->bv_len > 0 ) {
HASH_Update( &HASHcontext,
(unsigned char *)prefix->bv_val, prefix->bv_len );
}
HASH_Update( &HASHcontext,
(unsigned char *)&pre, sizeof( pre ) );
HASH_Update( &HASHcontext,
(unsigned char *)syntax->ssyn_oid, slen );
HASH_Update( &HASHcontext,
(unsigned char *)mr->smr_oid, mlen );
HASH_Update( &HASHcontext,
(unsigned char *)value->bv_val, klen );
HASH_Final( HASHdigest, &HASHcontext );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
ber_len_t i, j;
pre = SLAP_INDEX_SUBSTR_PREFIX;
klen = SLAP_INDEX_SUBSTR_MAXLEN;
for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
continue;
}
value = &sa->sa_any[i];
for(j=0;
j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
j += SLAP_INDEX_SUBSTR_STEP )
{
HASH_Init( &HASHcontext );
if( prefix != NULL && prefix->bv_len > 0 ) {
HASH_Update( &HASHcontext,
(unsigned char *)prefix->bv_val, prefix->bv_len );
}
HASH_Update( &HASHcontext,
(unsigned char *)&pre, sizeof( pre ) );
HASH_Update( &HASHcontext,
(unsigned char *)syntax->ssyn_oid, slen );
HASH_Update( &HASHcontext,
(unsigned char *)mr->smr_oid, mlen );
HASH_Update( &HASHcontext,
(unsigned char *)&value->bv_val[j], klen );
HASH_Final( HASHdigest, &HASHcontext );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
}
}
if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
{
pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
value = &sa->sa_final;
klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
HASH_Init( &HASHcontext );
if( prefix != NULL && prefix->bv_len > 0 ) {
HASH_Update( &HASHcontext,
(unsigned char *)prefix->bv_val, prefix->bv_len );
}
HASH_Update( &HASHcontext,
(unsigned char *)&pre, sizeof( pre ) );
HASH_Update( &HASHcontext,
(unsigned char *)syntax->ssyn_oid, slen );
HASH_Update( &HASHcontext,
(unsigned char *)mr->smr_oid, mlen );
HASH_Update( &HASHcontext,
(unsigned char *)&value->bv_val[value->bv_len-klen], klen );
HASH_Final( HASHdigest, &HASHcontext );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
if( nkeys > 0 ) {
keys[nkeys].bv_val = NULL;
*keysp = keys;
} else {
ch_free( keys );
*keysp = NULL;
}
return LDAP_SUCCESS;
}
static int
bitStringValidate(
Syntax *syntax,
struct berval *in )
{
ber_len_t i;
if( in->bv_len < 3 ) {
return LDAP_INVALID_SYNTAX;
}
if( in->bv_val[0] != '\'' ||
in->bv_val[in->bv_len-2] != '\'' ||
in->bv_val[in->bv_len-1] != 'B' )
{
return LDAP_INVALID_SYNTAX;
}
for( i=in->bv_len-3; i>0; i-- ) {
if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
return LDAP_INVALID_SYNTAX;
}
}
return LDAP_SUCCESS;
}
static int
nameUIDValidate(
Syntax *syntax,
struct berval *in )
{
int rc;
struct berval dn, uid;
if( in->bv_len == 0 ) return LDAP_SUCCESS;
ber_dupbv( &dn, in );
if( !dn.bv_val ) return LDAP_OTHER;
uid.bv_val = strrchr( dn.bv_val, '#' );
if ( uid.bv_val ) {
uid.bv_val++;
uid.bv_len = dn.bv_len - ( uid.bv_val - dn.bv_val );
rc = bitStringValidate( NULL, &uid );
if ( rc == LDAP_SUCCESS ) {
dn.bv_len -= uid.bv_len + 1;
uid.bv_val[-1] = '\0';
}
}
rc = dnValidate( NULL, &dn );
ber_memfree( dn.bv_val );
return rc;
}
int
nameUIDPretty(
Syntax *syntax,
struct berval *val,
struct berval *out,
void *ctx )
{
assert( val );
assert( out );
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ARGS, ">>> nameUIDPretty: <%s>\n", val->bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, ">>> nameUIDPretty: <%s>\n", val->bv_val, 0, 0 );
#endif
if( val->bv_len == 0 ) {
ber_dupbv_x( out, val, ctx );
} else if ( val->bv_len > SLAP_LDAPDN_MAXLEN ) {
return LDAP_INVALID_SYNTAX;
} else {
int rc;
struct berval dnval = *val;
struct berval uidval = BER_BVNULL;
uidval.bv_val = strrchr( val->bv_val, '#' );
if ( uidval.bv_val ) {
uidval.bv_val++;
uidval.bv_len = val->bv_len - ( uidval.bv_val - val->bv_val );
rc = bitStringValidate( NULL, &uidval );
if ( rc == LDAP_SUCCESS ) {
ber_dupbv_x( &dnval, val, ctx );
dnval.bv_len -= uidval.bv_len + 1;
dnval.bv_val[dnval.bv_len] = '\0';
} else {
uidval.bv_val = NULL;
}
}
rc = dnPretty( syntax, &dnval, out, ctx );
if ( dnval.bv_val != val->bv_val ) {
slap_sl_free( dnval.bv_val, ctx );
}
if( rc != LDAP_SUCCESS ) {
return rc;
}
if( uidval.bv_val ) {
int i, c, got1;
char *tmp;
tmp = sl_realloc( out->bv_val, out->bv_len
+ STRLENOF( "#" ) + uidval.bv_len + 1,
ctx );
if( tmp == NULL ) {
ber_memfree_x( out->bv_val, ctx );
return LDAP_OTHER;
}
out->bv_val = tmp;
out->bv_val[out->bv_len++] = '#';
out->bv_val[out->bv_len++] = '\'';
got1 = uidval.bv_len < sizeof("'0'B");
for( i = 1; i < uidval.bv_len - 2; i++ ) {
c = uidval.bv_val[i];
switch(c) {
case '0':
if( got1 ) out->bv_val[out->bv_len++] = c;
break;
case '1':
got1 = 1;
out->bv_val[out->bv_len++] = c;
break;
}
}
out->bv_val[out->bv_len++] = '\'';
out->bv_val[out->bv_len++] = 'B';
out->bv_val[out->bv_len] = '\0';
}
}
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ARGS, "<<< nameUIDPretty: <%s>\n", out->bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "<<< nameUIDPretty: <%s>\n", out->bv_val, 0, 0 );
#endif
return LDAP_SUCCESS;
}
static int
uniqueMemberNormalize(
slap_mask_t usage,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized,
void *ctx )
{
struct berval out;
int rc;
assert( SLAP_MR_IS_VALUE_OF_SYNTAX( usage ));
ber_dupbv_x( &out, val, ctx );
if( BER_BVISEMPTY( &out ) ) {
*normalized = out;
} else {
struct berval uid = BER_BVNULL;
uid.bv_val = strrchr( out.bv_val, '#' );
if ( uid.bv_val ) {
uid.bv_val++;
uid.bv_len = out.bv_len - ( uid.bv_val - out.bv_val );
rc = bitStringValidate( NULL, &uid );
if ( rc == LDAP_SUCCESS ) {
uid.bv_val[-1] = '\0';
out.bv_len -= uid.bv_len + 1;
} else {
uid.bv_val = NULL;
}
}
rc = dnNormalize( 0, NULL, NULL, &out, normalized, ctx );
if( rc != LDAP_SUCCESS ) {
sl_free( out.bv_val, ctx );
return LDAP_INVALID_SYNTAX;
}
if( uid.bv_val ) {
char *tmp;
tmp = ch_realloc( normalized->bv_val,
normalized->bv_len + uid.bv_len
+ STRLENOF("#") + 1 );
if ( tmp == NULL ) {
ber_memfree_x( normalized->bv_val, ctx );
return LDAP_OTHER;
}
normalized->bv_val = tmp;
normalized->bv_val[normalized->bv_len++] = '#';
AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
uid.bv_val, uid.bv_len );
normalized->bv_len += uid.bv_len;
normalized->bv_val[normalized->bv_len] = '\0';
}
sl_free( out.bv_val, ctx );
}
return LDAP_SUCCESS;
}
static int
uniqueMemberMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
int match;
struct berval *asserted = (struct berval *) assertedValue;
struct berval assertedDN = *asserted;
struct berval assertedUID = BER_BVNULL;
struct berval valueDN = BER_BVNULL;
struct berval valueUID = BER_BVNULL;
if ( !BER_BVISEMPTY( asserted ) ) {
assertedUID.bv_val = strrchr( assertedDN.bv_val, '#' );
if ( !BER_BVISNULL( &assertedUID ) ) {
assertedUID.bv_val++;
assertedUID.bv_len = assertedDN.bv_len
- ( assertedUID.bv_val - assertedDN.bv_val );
if ( bitStringValidate( NULL, &assertedUID ) == LDAP_SUCCESS ) {
assertedDN.bv_len -= assertedUID.bv_len + 1;
} else {
BER_BVZERO( &assertedUID );
}
}
}
if ( !BER_BVISEMPTY( value ) ) {
valueDN = *value;
valueUID.bv_val = strrchr( valueDN.bv_val, '#' );
if ( !BER_BVISNULL( &valueUID ) ) {
valueUID.bv_val++;
valueUID.bv_len = valueDN.bv_len
- ( valueUID.bv_val - valueDN.bv_val );
if ( bitStringValidate( NULL, &valueUID ) == LDAP_SUCCESS ) {
valueDN.bv_len -= valueUID.bv_len + 1;
} else {
BER_BVZERO( &valueUID );
}
}
}
if( valueUID.bv_len && assertedUID.bv_len ) {
match = valueUID.bv_len - assertedUID.bv_len;
if ( match ) {
*matchp = match;
return LDAP_SUCCESS;
}
match = memcmp( valueUID.bv_val, assertedUID.bv_val, valueUID.bv_len );
if( match ) {
*matchp = match;
return LDAP_SUCCESS;
}
}
return dnMatch( matchp, flags, syntax, mr, &valueDN, &assertedDN );
}
static int
booleanValidate(
Syntax *syntax,
struct berval *in )
{
if( in->bv_len == 4 ) {
if( bvmatch( in, &slap_true_bv ) ) {
return LDAP_SUCCESS;
}
} else if( in->bv_len == 5 ) {
if( bvmatch( in, &slap_false_bv ) ) {
return LDAP_SUCCESS;
}
}
return LDAP_INVALID_SYNTAX;
}
static int
booleanMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
struct berval *asserted = (struct berval *) assertedValue;
*matchp = value->bv_len != asserted->bv_len;
return LDAP_SUCCESS;
}
static int
UTF8StringValidate(
Syntax *syntax,
struct berval *in )
{
ber_len_t count;
int len;
unsigned char *u = (unsigned char *)in->bv_val;
if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
return LDAP_INVALID_SYNTAX;
}
for( count = in->bv_len; count > 0; count-=len, u+=len ) {
len = LDAP_UTF8_CHARLEN2( u, len );
switch( len ) {
case 6:
if( (u[5] & 0xC0) != 0x80 ) {
return LDAP_INVALID_SYNTAX;
}
case 5:
if( (u[4] & 0xC0) != 0x80 ) {
return LDAP_INVALID_SYNTAX;
}
case 4:
if( (u[3] & 0xC0) != 0x80 ) {
return LDAP_INVALID_SYNTAX;
}
case 3:
if( (u[2] & 0xC0 )!= 0x80 ) {
return LDAP_INVALID_SYNTAX;
}
case 2:
if( (u[1] & 0xC0) != 0x80 ) {
return LDAP_INVALID_SYNTAX;
}
case 1:
break;
default:
return LDAP_INVALID_SYNTAX;
}
if( LDAP_UTF8_OFFSET( (char *)u ) != len ) return LDAP_INVALID_SYNTAX;
}
if( count != 0 ) {
return LDAP_INVALID_SYNTAX;
}
return LDAP_SUCCESS;
}
static int
UTF8StringNormalize(
slap_mask_t use,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized,
void *ctx )
{
struct berval tmp, nvalue;
int flags;
int i, wasspace;
assert( SLAP_MR_IS_VALUE_OF_SYNTAX( use ));
if( val->bv_val == NULL ) {
normalized->bv_len = 0;
normalized->bv_val = NULL;
return LDAP_SUCCESS;
}
flags = SLAP_MR_ASSOCIATED( mr, slap_schema.si_mr_caseExactMatch )
? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
flags |= ( ( use & SLAP_MR_EQUALITY_APPROX ) == SLAP_MR_EQUALITY_APPROX )
? LDAP_UTF8_APPROX : 0;
val = UTF8bvnormalize( val, &tmp, flags, ctx );
if( val == NULL ) {
return LDAP_OTHER;
}
nvalue.bv_len = 0;
nvalue.bv_val = tmp.bv_val;
wasspace=1;
for( i=0; i<tmp.bv_len; i++) {
if ( ASCII_SPACE( tmp.bv_val[i] )) {
if( wasspace++ == 0 ) {
nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
}
} else {
wasspace = 0;
nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
}
}
if( nvalue.bv_len ) {
if( wasspace ) {
--nvalue.bv_len;
}
nvalue.bv_val[nvalue.bv_len] = '\0';
} else {
nvalue.bv_val[0] = ' ';
nvalue.bv_val[1] = '\0';
nvalue.bv_len = 1;
}
*normalized = nvalue;
return LDAP_SUCCESS;
}
#if defined(SLAPD_APPROX_INITIALS)
# define SLAPD_APPROX_DELIMITER "._ "
# define SLAPD_APPROX_WORDLEN 2
#else
# define SLAPD_APPROX_DELIMITER " "
# define SLAPD_APPROX_WORDLEN 1
#endif
static int
approxMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
struct berval *nval, *assertv;
char *val, **values, **words, *c;
int i, count, len, nextchunk=0, nextavail=0;
nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX, NULL );
if( nval == NULL ) {
*matchp = 1;
return LDAP_SUCCESS;
}
assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
NULL, LDAP_UTF8_APPROX, NULL );
if( assertv == NULL ) {
ber_bvfree( nval );
*matchp = 1;
return LDAP_SUCCESS;
}
for ( c = nval->bv_val, count = 1; *c; c++ ) {
c = strpbrk( c, SLAPD_APPROX_DELIMITER );
if ( c == NULL ) break;
*c = '\0';
count++;
}
words = (char **)ch_malloc( count * sizeof(char *) );
values = (char **)ch_malloc( count * sizeof(char *) );
for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
words[i] = c;
values[i] = phonetic(c);
}
len = 0;
while ( (ber_len_t) nextchunk < assertv->bv_len ) {
len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
if( len == 0 ) {
nextchunk++;
continue;
}
#if defined(SLAPD_APPROX_INITIALS)
else if( len == 1 ) {
for( i=nextavail; i<count; i++ )
if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
nextavail=i+1;
break;
}
}
#endif
else {
assertv->bv_val[nextchunk+len] = '\0';
val = phonetic( assertv->bv_val + nextchunk );
for( i=nextavail; i<count; i++ ){
if( !strcmp( val, values[i] ) ){
nextavail = i+1;
break;
}
}
ch_free( val );
}
if( i >= count ) {
nextavail=-1;
break;
}
nextchunk += len+1;
}
if( nextavail > 0 ) {
*matchp = 0;
}
else {
*matchp = 1;
}
ber_bvfree( assertv );
for( i=0; i<count; i++ ) {
ch_free( values[i] );
}
ch_free( values );
ch_free( words );
ber_bvfree( nval );
return LDAP_SUCCESS;
}
static int
approxIndexer(
slap_mask_t use,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *prefix,
BerVarray values,
BerVarray *keysp,
void *ctx )
{
char *c;
int i,j, len, wordcount, keycount=0;
struct berval *newkeys;
BerVarray keys=NULL;
for( j=0; values[j].bv_val != NULL; j++ ) {
struct berval val = BER_BVNULL;
UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX, NULL );
assert( val.bv_val != NULL );
for( wordcount = 0, c = val.bv_val; *c; c++) {
len = strcspn(c, SLAPD_APPROX_DELIMITER);
if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
c+= len;
if (*c == '\0') break;
*c = '\0';
}
newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
* sizeof(struct berval) );
AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
if( keys ) ch_free( keys );
keys = newkeys;
for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
len = strlen( c );
if( len < SLAPD_APPROX_WORDLEN ) continue;
ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
keycount++;
i++;
}
ber_memfree( val.bv_val );
}
keys[keycount].bv_val = NULL;
*keysp = keys;
return LDAP_SUCCESS;
}
static int
approxFilter(
slap_mask_t use,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *prefix,
void * assertedValue,
BerVarray *keysp,
void *ctx )
{
char *c;
int i, count, len;
struct berval *val;
BerVarray keys;
val = UTF8bvnormalize( ((struct berval *)assertedValue),
NULL, LDAP_UTF8_APPROX, NULL );
if( val == NULL || val->bv_val == NULL ) {
keys = (struct berval *)ch_malloc( sizeof(struct berval) );
keys[0].bv_val = NULL;
*keysp = keys;
ber_bvfree( val );
return LDAP_SUCCESS;
}
for( count = 0,c = val->bv_val; *c; c++) {
len = strcspn(c, SLAPD_APPROX_DELIMITER);
if( len >= SLAPD_APPROX_WORDLEN ) count++;
c+= len;
if (*c == '\0') break;
*c = '\0';
}
keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
len = strlen(c);
if( len < SLAPD_APPROX_WORDLEN ) continue;
ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
i++;
}
ber_bvfree( val );
keys[count].bv_val = NULL;
*keysp = keys;
return LDAP_SUCCESS;
}
static int
telephoneNumberNormalize(
slap_mask_t usage,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized,
void *ctx )
{
char *p, *q;
assert( SLAP_MR_IS_VALUE_OF_SYNTAX( usage ));
assert( val->bv_len );
q = normalized->bv_val = sl_malloc( val->bv_len + 1, ctx );
for( p = val->bv_val; *p; p++ ) {
if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
*q++ = *p;
}
}
*q = '\0';
normalized->bv_len = q - normalized->bv_val;
if( normalized->bv_len == 0 ) {
sl_free( normalized->bv_val, ctx );
normalized->bv_val = NULL;
return LDAP_INVALID_SYNTAX;
}
return LDAP_SUCCESS;
}
static int
numericoidValidate(
Syntax *syntax,
struct berval *in )
{
struct berval val = *in;
if( val.bv_len == 0 ) {
return LDAP_INVALID_SYNTAX;
}
while( OID_LEADCHAR( val.bv_val[0] ) ) {
if ( val.bv_len == 1 ) {
return LDAP_SUCCESS;
}
if ( val.bv_val[0] == '0' ) {
break;
}
val.bv_val++;
val.bv_len--;
while ( OID_LEADCHAR( val.bv_val[0] )) {
val.bv_val++;
val.bv_len--;
if ( val.bv_len == 0 ) {
return LDAP_SUCCESS;
}
}
if( !OID_SEPARATOR( val.bv_val[0] )) {
break;
}
val.bv_val++;
val.bv_len--;
}
return LDAP_INVALID_SYNTAX;
}
static int
integerValidate(
Syntax *syntax,
struct berval *in )
{
ber_len_t i;
struct berval val = *in;
if( val.bv_len == 0 ) return LDAP_INVALID_SYNTAX;
if ( val.bv_val[0] == '-' ) {
val.bv_len--;
val.bv_val++;
if( val.bv_len == 0 ) {
return LDAP_INVALID_SYNTAX;
}
if( val.bv_val[0] == '0' ) {
return LDAP_INVALID_SYNTAX;
}
} else if ( val.bv_val[0] == '0' ) {
if( val.bv_len > 1 ) {
return LDAP_INVALID_SYNTAX;
}
return LDAP_SUCCESS;
}
for( i=0; i < val.bv_len; i++ ) {
if( !ASCII_DIGIT(val.bv_val[i]) ) {
return LDAP_INVALID_SYNTAX;
}
}
return LDAP_SUCCESS;
}
static int
integerMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
struct berval *asserted = (struct berval *) assertedValue;
int vsign = 1, asign = 1;
struct berval v, a;
int match;
v = *value;
if( v.bv_val[0] == '-' ) {
vsign = -1;
v.bv_val++;
v.bv_len--;
}
if( v.bv_len == 0 ) vsign = 0;
a = *asserted;
if( a.bv_val[0] == '-' ) {
asign = -1;
a.bv_val++;
a.bv_len--;
}
if( a.bv_len == 0 ) vsign = 0;
match = vsign - asign;
if( match == 0 ) {
match = ( v.bv_len != a.bv_len
? ( v.bv_len < a.bv_len ? -1 : 1 )
: memcmp( v.bv_val, a.bv_val, v.bv_len ));
if( vsign < 0 ) match = -match;
}
*matchp = match;
return LDAP_SUCCESS;
}
static int
countryStringValidate(
Syntax *syntax,
struct berval *val )
{
if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
return LDAP_INVALID_SYNTAX;
}
if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
return LDAP_INVALID_SYNTAX;
}
return LDAP_SUCCESS;
}
static int
printableStringValidate(
Syntax *syntax,
struct berval *val )
{
ber_len_t i;
if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
for(i=0; i < val->bv_len; i++) {
if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
return LDAP_INVALID_SYNTAX;
}
}
return LDAP_SUCCESS;
}
static int
printablesStringValidate(
Syntax *syntax,
struct berval *val )
{
ber_len_t i, len;
if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
for(i=0,len=0; i < val->bv_len; i++) {
int c = val->bv_val[i];
if( c == '$' ) {
if( len == 0 ) {
return LDAP_INVALID_SYNTAX;
}
len = 0;
} else if ( SLAP_PRINTABLE(c) ) {
len++;
} else {
return LDAP_INVALID_SYNTAX;
}
}
if( len == 0 ) {
return LDAP_INVALID_SYNTAX;
}
return LDAP_SUCCESS;
}
static int
IA5StringValidate(
Syntax *syntax,
struct berval *val )
{
ber_len_t i;
if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
for(i=0; i < val->bv_len; i++) {
if( !LDAP_ASCII(val->bv_val[i]) ) {
return LDAP_INVALID_SYNTAX;
}
}
return LDAP_SUCCESS;
}
static int
IA5StringNormalize(
slap_mask_t use,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized,
void *ctx )
{
char *p, *q;
int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
assert( val->bv_len );
assert( SLAP_MR_IS_VALUE_OF_SYNTAX( use ));
p = val->bv_val;
while ( ASCII_SPACE( *p ) ) p++;
normalized->bv_val = ber_strdup_x( p, ctx );
p = q = normalized->bv_val;
while ( *p ) {
if ( ASCII_SPACE( *p ) ) {
*q++ = *p++;
while ( ASCII_SPACE( *p ) ) {
p++;
}
} else if ( casefold ) {
*q++ = TOLOWER(*p); p++;
} else {
*q++ = *p++;
}
}
assert( normalized->bv_val <= p );
assert( q <= p );
if ( ASCII_SPACE( q[-1] ) ) --q;
*q = '\0';
normalized->bv_len = q - normalized->bv_val;
if( normalized->bv_len == 0 ) {
normalized->bv_val = sl_realloc( normalized->bv_val, 2, ctx );
normalized->bv_val[0] = ' ';
normalized->bv_val[1] = '\0';
normalized->bv_len = 1;
}
return LDAP_SUCCESS;
}
static int
UUIDValidate(
Syntax *syntax,
struct berval *in )
{
int i;
if( in->bv_len != 36 ) {
return LDAP_INVALID_SYNTAX;
}
for( i=0; i<36; i++ ) {
switch(i) {
case 8:
case 13:
case 18:
case 23:
if( in->bv_val[i] != '-' ) {
return LDAP_INVALID_SYNTAX;
}
break;
default:
if( !ASCII_HEX( in->bv_val[i]) ) {
return LDAP_INVALID_SYNTAX;
}
}
}
return LDAP_SUCCESS;
}
static int
UUIDNormalize(
slap_mask_t usage,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized,
void *ctx )
{
unsigned char octet = '\0';
int i;
int j;
normalized->bv_len = 16;
normalized->bv_val = sl_malloc( normalized->bv_len+1, ctx );
for( i=0, j=0; i<36; i++ ) {
unsigned char nibble;
if( val->bv_val[i] == '-' ) {
continue;
} else if( ASCII_DIGIT( val->bv_val[i] ) ) {
nibble = val->bv_val[i] - '0';
} else if( ASCII_HEXLOWER( val->bv_val[i] ) ) {
nibble = val->bv_val[i] - ('a'-10);
} else if( ASCII_HEXUPPER( val->bv_val[i] ) ) {
nibble = val->bv_val[i] - ('A'-10);
} else {
sl_free( normalized->bv_val, ctx );
return LDAP_INVALID_SYNTAX;
}
if( j & 1 ) {
octet |= nibble;
normalized->bv_val[j>>1] = octet;
} else {
octet = nibble << 4;
}
j++;
}
normalized->bv_val[normalized->bv_len] = 0;
return LDAP_SUCCESS;
}
static int
numericStringValidate(
Syntax *syntax,
struct berval *in )
{
ber_len_t i;
if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
for(i=0; i < in->bv_len; i++) {
if( !SLAP_NUMERIC(in->bv_val[i]) ) {
return LDAP_INVALID_SYNTAX;
}
}
return LDAP_SUCCESS;
}
static int
numericStringNormalize(
slap_mask_t usage,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized,
void *ctx )
{
char *p, *q;
assert( val->bv_len );
normalized->bv_val = sl_malloc( val->bv_len + 1, ctx );
p = val->bv_val;
q = normalized->bv_val;
while ( *p ) {
if ( ASCII_SPACE( *p ) ) {
p++;
} else {
*q++ = *p++;
}
}
assert( (q - normalized->bv_val) <= (p - val->bv_val) );
*q = '\0';
normalized->bv_len = q - normalized->bv_val;
if( normalized->bv_len == 0 ) {
normalized->bv_val = sl_realloc( normalized->bv_val, 2, ctx );
normalized->bv_val[0] = ' ';
normalized->bv_val[1] = '\0';
normalized->bv_len = 1;
}
return LDAP_SUCCESS;
}
#if defined(HAVE_STRTOLL) && defined(LLONG_MAX) \
&& defined(LLONG_MIN) && defined(HAVE_LONG_LONG)
# define SLAP_STRTOL(n,e,b) strtoll(n,e,b)
# define SLAP_LONG_MAX LLONG_MAX
# define SLAP_LONG_MIN LLONG_MIN
# define SLAP_LONG long long
#else
# define SLAP_STRTOL(n,e,b) strtol(n,e,b)
# define SLAP_LONG_MAX LONG_MAX
# define SLAP_LONG_MIN LONG_MIN
# define SLAP_LONG long
#endif
static int
integerBitAndMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
SLAP_LONG lValue, lAssertedValue;
lValue = SLAP_STRTOL(value->bv_val, NULL, 10);
if(( lValue == SLAP_LONG_MIN || lValue == SLAP_LONG_MAX) &&
errno == ERANGE )
{
return LDAP_CONSTRAINT_VIOLATION;
}
lAssertedValue = SLAP_STRTOL(((struct berval *)assertedValue)->bv_val,
NULL, 10);
if(( lAssertedValue == SLAP_LONG_MIN || lAssertedValue == SLAP_LONG_MAX ) &&
errno == ERANGE )
{
return LDAP_CONSTRAINT_VIOLATION;
}
*matchp = (lValue & lAssertedValue) ? 0 : 1;
return LDAP_SUCCESS;
}
static int
integerBitOrMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
SLAP_LONG lValue, lAssertedValue;
lValue = SLAP_STRTOL(value->bv_val, NULL, 10);
if(( lValue == SLAP_LONG_MIN || lValue == SLAP_LONG_MAX ) &&
errno == ERANGE )
{
return LDAP_CONSTRAINT_VIOLATION;
}
lAssertedValue = SLAP_STRTOL( ((struct berval *)assertedValue)->bv_val,
NULL, 10);
if(( lAssertedValue == SLAP_LONG_MIN || lAssertedValue == SLAP_LONG_MAX ) &&
errno == ERANGE )
{
return LDAP_CONSTRAINT_VIOLATION;
}
*matchp = (lValue | lAssertedValue) ? 0 : -1;
return LDAP_SUCCESS;
}
static int
serialNumberAndIssuerValidate(
Syntax *syntax,
struct berval *in )
{
int rc;
ber_len_t n;
struct berval sn, i;
if( in->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
i.bv_val = strchr( in->bv_val, '$' );
if( i.bv_val == NULL ) return LDAP_INVALID_SYNTAX;
sn.bv_val = in->bv_val;
sn.bv_len = i.bv_val - in->bv_val;
i.bv_val++;
i.bv_len = in->bv_len - (sn.bv_len + 1);
for( n=0; n < sn.bv_len; n++ ) {
if( !ASCII_DIGIT(sn.bv_val[n]) ) return LDAP_INVALID_SYNTAX;
}
rc = dnValidate( NULL, &i );
if( rc ) return LDAP_INVALID_SYNTAX;
return LDAP_SUCCESS;
}
int
serialNumberAndIssuerPretty(
Syntax *syntax,
struct berval *val,
struct berval *out,
void *ctx )
{
int rc;
ber_len_t n;
struct berval sn, i, newi;
assert( val );
assert( out );
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ARGS, ">>> serialNumberAndIssuerPretty: <%s>\n",
val->bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, ">>> serialNumberAndIssuerPretty: <%s>\n",
val->bv_val, 0, 0 );
#endif
if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
i.bv_val = strchr( val->bv_val, '$' );
if( i.bv_val == NULL ) return LDAP_INVALID_SYNTAX;
sn.bv_val = val->bv_val;
sn.bv_len = i.bv_val - val->bv_val;
i.bv_val++;
i.bv_len = val->bv_len - (sn.bv_len + 1);
for( n=0; n < (sn.bv_len-1); n++ ) {
if( sn.bv_val[n] != '0' ) break;
}
sn.bv_val += n;
sn.bv_len -= n;
for( n=0; n < sn.bv_len; n++ ) {
if( !ASCII_DIGIT(sn.bv_val[n]) ) return LDAP_INVALID_SYNTAX;
}
rc = dnPretty( syntax, &i, &newi, ctx );
if( rc ) return LDAP_INVALID_SYNTAX;
out->bv_len = sn.bv_len + newi.bv_len + 1;
out->bv_val = sl_realloc( newi.bv_val, out->bv_len + 1, ctx );
if( out->bv_val == NULL ) {
sl_free( newi.bv_val, ctx );
return LDAP_OTHER;
}
AC_MEMCPY( &out->bv_val[sn.bv_len+1], newi.bv_val, newi.bv_len );
AC_MEMCPY( out->bv_val, sn.bv_val, sn.bv_len );
out->bv_val[sn.bv_len] = '$';
out->bv_val[out->bv_len] = '\0';
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ARGS, "<<< serialNumberAndIssuerPretty: <%s>\n",
out->bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "<<< serialNumberAndIssuerPretty: <%s>\n",
out->bv_val, 0, 0 );
#endif
return LDAP_SUCCESS;
}
static int
serialNumberAndIssuerNormalize(
slap_mask_t usage,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *out,
void *ctx )
{
int rc;
ber_len_t n;
struct berval sn, i, newi;
assert( val );
assert( out );
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ARGS, ">>> serialNumberAndIssuerNormalize: <%s>\n",
val->bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, ">>> serialNumberAndIssuerNormalize: <%s>\n",
val->bv_val, 0, 0 );
#endif
if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
i.bv_val = strchr( val->bv_val, '$' );
if( i.bv_val == NULL ) return LDAP_INVALID_SYNTAX;
sn.bv_val = val->bv_val;
sn.bv_len = i.bv_val - val->bv_val;
i.bv_val++;
i.bv_len = val->bv_len - (sn.bv_len + 1);
for( n=0; n < (sn.bv_len-1); n++ ) {
if( sn.bv_val[n] != '0' ) break;
}
sn.bv_val += n;
sn.bv_len -= n;
for( n=0; n < sn.bv_len; n++ ) {
if( !ASCII_DIGIT(sn.bv_val[n]) ) {
return LDAP_INVALID_SYNTAX;
}
}
rc = dnNormalize( usage, syntax, mr, &i, &newi, ctx );
if( rc ) return LDAP_INVALID_SYNTAX;
out->bv_len = sn.bv_len + newi.bv_len + 1;
out->bv_val = sl_realloc( newi.bv_val, out->bv_len + 1, ctx );
if( out->bv_val == NULL ) {
sl_free( newi.bv_val, ctx );
return LDAP_OTHER;
}
AC_MEMCPY( &out->bv_val[sn.bv_len+1], newi.bv_val, newi.bv_len );
AC_MEMCPY( out->bv_val, sn.bv_val, sn.bv_len );
out->bv_val[sn.bv_len] = '$';
out->bv_val[out->bv_len] = '\0';
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ARGS, "<<< serialNumberAndIssuerNormalize: <%s>\n",
out->bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "<<< serialNumberAndIssuerNormalize: <%s>\n",
out->bv_val, 0, 0 );
#endif
return rc;
}
#ifdef HAVE_TLS
static int
certificateExactNormalize(
slap_mask_t usage,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized,
void *ctx )
{
int rc = LDAP_INVALID_SYNTAX;
unsigned char *p;
char *serial = NULL;
ber_len_t seriallen;
struct berval issuer_dn = BER_BVNULL;
X509_NAME *name = NULL;
ASN1_INTEGER *sn = NULL;
X509 *xcert = NULL;
if( val->bv_len == 0 ) goto done;
if( SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX(usage) ) {
return serialNumberAndIssuerNormalize(0,NULL,NULL,val,normalized,ctx);
}
assert( SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX(usage) );
p = (unsigned char *)val->bv_val;
xcert = d2i_X509( NULL, &p, val->bv_len);
if( xcert == NULL ) goto done;
sn=X509_get_serialNumber(xcert);
if ( sn == NULL ) goto done;
serial=i2s_ASN1_INTEGER(0, sn );
if( serial == NULL ) goto done;
seriallen=strlen(serial);
name=X509_get_issuer_name(xcert);
if( name == NULL ) goto done;
rc = dnX509normalize( name, &issuer_dn );
if( rc != LDAP_SUCCESS ) goto done;
normalized->bv_len = seriallen + issuer_dn.bv_len + 1;
normalized->bv_val = ch_malloc(normalized->bv_len+1);
p = (unsigned char *)normalized->bv_val;
AC_MEMCPY(p, serial, seriallen);
p += seriallen;
*p++ = '$';
AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
p += issuer_dn.bv_len;
*p = '\0';
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, ARGS, "certificateExactNormalize: %s\n",
normalized->bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "certificateExactNormalize: %s\n",
normalized->bv_val, NULL, NULL );
#endif
done:
if (xcert) X509_free(xcert);
if (serial) ch_free(serial);
if (issuer_dn.bv_val) ber_memfree(issuer_dn.bv_val);
return rc;
}
#endif
#ifndef SUPPORT_OBSOLETE_UTC_SYNTAX
#define check_time_syntax(v, start, p, f) (check_time_syntax)(v, p, f)
enum { start = 0 };
#endif
static int
check_time_syntax (struct berval *val,
int start,
int *parts,
struct berval *fraction)
{
static const int ceiling[9] = { 100, 100, 12, 31, 24, 60, 60, 24, 60 };
static const int mdays[2][12] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
char *p, *e;
int part, c, c1, c2, tzoffset, leapyear = 0;
p = val->bv_val;
e = p + val->bv_len;
#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
parts[0] = 20;
#endif
for (part = start; part < 7 && p < e; part++) {
c1 = *p;
if (!ASCII_DIGIT(c1)) {
break;
}
p++;
if (p == e) {
return LDAP_INVALID_SYNTAX;
}
c = *p++;
if (!ASCII_DIGIT(c)) {
return LDAP_INVALID_SYNTAX;
}
c += c1 * 10 - '0' * 11;
if ((part | 1) == 3) {
--c;
if (c < 0) {
return LDAP_INVALID_SYNTAX;
}
}
if (c >= ceiling[part]) {
if (! (c == 60 && part == 6 && start == 0))
return LDAP_INVALID_SYNTAX;
}
parts[part] = c;
}
if (part < 5 + start) {
return LDAP_INVALID_SYNTAX;
}
for (; part < 9; part++) {
parts[part] = 0;
}
if (parts[parts[1] == 0 ? 0 : 1] % 4 == 0)
{
leapyear = 1;
}
if (parts[3] >= mdays[leapyear][parts[2]]) {
return LDAP_INVALID_SYNTAX;
}
if (start == 0) {
fraction->bv_val = p;
fraction->bv_len = 0;
if (p < e && (*p == '.' || *p == ',')) {
char *end_num;
while (++p < e && ASCII_DIGIT(*p))
;
if (p - fraction->bv_val == 1) {
return LDAP_INVALID_SYNTAX;
}
for (end_num = p; end_num[-1] == '0'; --end_num)
;
c = end_num - fraction->bv_val;
if (c != 1)
fraction->bv_len = c;
}
}
if (p == e) {
return start == 0 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
}
tzoffset = *p++;
switch (tzoffset) {
default:
return LDAP_INVALID_SYNTAX;
case 'Z':
break;
case '+':
case '-':
for (part = 7; part < 9 && p < e; part++) {
c1 = *p;
if (!ASCII_DIGIT(c1)) {
break;
}
p++;
if (p == e) {
return LDAP_INVALID_SYNTAX;
}
c2 = *p++;
if (!ASCII_DIGIT(c2)) {
return LDAP_INVALID_SYNTAX;
}
parts[part] = c1 * 10 + c2 - '0' * 11;
if (parts[part] >= ceiling[part]) {
return LDAP_INVALID_SYNTAX;
}
}
if (part < 8 + start) {
return LDAP_INVALID_SYNTAX;
}
if (tzoffset == '-') {
parts[4] += parts[7];
parts[5] += parts[8];
for (part = 6; --part >= 0; ) {
if (part != 3) {
c = ceiling[part];
} else {
c = mdays[leapyear][parts[2]];
}
if (parts[part] >= c) {
if (part == 0) {
return LDAP_INVALID_SYNTAX;
}
parts[part] -= c;
parts[part - 1]++;
continue;
} else if (part != 5) {
break;
}
}
} else {
parts[4] -= parts[7];
parts[5] -= parts[8];
for (part = 6; --part >= 0; ) {
if (parts[part] < 0) {
if (part == 0) {
return LDAP_INVALID_SYNTAX;
}
if (part != 3) {
c = ceiling[part];
} else {
c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
}
parts[part] += c;
parts[part - 1]--;
continue;
} else if (part != 5) {
break;
}
}
}
}
return p != e ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
}
#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
#if 0
static int
xutcTimeNormalize(
Syntax *syntax,
struct berval *val,
struct berval *normalized )
{
int parts[9], rc;
rc = check_time_syntax(val, 1, parts, NULL);
if (rc != LDAP_SUCCESS) {
return rc;
}
normalized->bv_val = ch_malloc( 14 );
if ( normalized->bv_val == NULL ) {
return LBER_ERROR_MEMORY;
}
sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
parts[1], parts[2] + 1, parts[3] + 1,
parts[4], parts[5], parts[6] );
normalized->bv_len = 13;
return LDAP_SUCCESS;
}
#endif
static int
utcTimeValidate(
Syntax *syntax,
struct berval *in )
{
int parts[9];
return check_time_syntax(in, 1, parts, NULL);
}
#endif
static int
generalizedTimeValidate(
Syntax *syntax,
struct berval *in )
{
int parts[9];
struct berval fraction;
return check_time_syntax(in, 0, parts, &fraction);
}
static int
generalizedTimeNormalize(
slap_mask_t usage,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized,
void *ctx )
{
int parts[9], rc;
unsigned int len;
struct berval fraction;
rc = check_time_syntax(val, 0, parts, &fraction);
if (rc != LDAP_SUCCESS) {
return rc;
}
len = sizeof("YYYYmmddHHMMSSZ")-1 + fraction.bv_len;
normalized->bv_val = sl_malloc( len + 1, ctx );
if ( normalized->bv_val == NULL ) {
return LBER_ERROR_MEMORY;
}
sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02d",
parts[0], parts[1], parts[2] + 1, parts[3] + 1,
parts[4], parts[5], parts[6] );
if ( fraction.bv_len ) {
memcpy( normalized->bv_val + sizeof("YYYYmmddHHMMSSZ")-2,
fraction.bv_val, fraction.bv_len );
normalized->bv_val[sizeof("YYYYmmddHHMMSSZ")-2] = '.';
}
strcpy( normalized->bv_val + len-1, "Z" );
normalized->bv_len = len;
return LDAP_SUCCESS;
}
static int
generalizedTimeOrderingMatch(
int *matchp,
slap_mask_t flags,
Syntax *syntax,
MatchingRule *mr,
struct berval *value,
void *assertedValue )
{
struct berval *asserted = (struct berval *) assertedValue;
ber_len_t v_len = value->bv_len;
ber_len_t av_len = asserted->bv_len;
int match = memcmp( value->bv_val, asserted->bv_val,
(v_len < av_len ? v_len : av_len) - 1 );
if ( match == 0 ) match = v_len - av_len;
*matchp = match;
return LDAP_SUCCESS;
}
static int
deliveryMethodValidate(
Syntax *syntax,
struct berval *val )
{
#undef LENOF
#define LENOF(s) (sizeof(s)-1)
struct berval tmp = *val;
again:
if( tmp.bv_len < 3 ) return LDAP_INVALID_SYNTAX;
switch( tmp.bv_val[0] ) {
case 'a':
case 'A':
if(( tmp.bv_len >= LENOF("any") ) &&
( strncasecmp(tmp.bv_val, "any", LENOF("any")) == 0 ))
{
tmp.bv_len -= LENOF("any");
tmp.bv_val += LENOF("any");
break;
}
return LDAP_INVALID_SYNTAX;
case 'm':
case 'M':
if(( tmp.bv_len >= LENOF("mhs") ) &&
( strncasecmp(tmp.bv_val, "mhs", LENOF("mhs")) == 0 ))
{
tmp.bv_len -= LENOF("mhs");
tmp.bv_val += LENOF("mhs");
break;
}
return LDAP_INVALID_SYNTAX;
case 'p':
case 'P':
if(( tmp.bv_len >= LENOF("physical") ) &&
( strncasecmp(tmp.bv_val, "physical", LENOF("physical")) == 0 ))
{
tmp.bv_len -= LENOF("physical");
tmp.bv_val += LENOF("physical");
break;
}
return LDAP_INVALID_SYNTAX;
case 't':
case 'T':
if(( tmp.bv_len >= LENOF("telex") ) &&
( strncasecmp(tmp.bv_val, "telex", LENOF("telex")) == 0 ))
{
tmp.bv_len -= LENOF("telex");
tmp.bv_val += LENOF("telex");
break;
}
if(( tmp.bv_len >= LENOF("teletex") ) &&
( strncasecmp(tmp.bv_val, "teletex", LENOF("teletex")) == 0 ))
{
tmp.bv_len -= LENOF("teletex");
tmp.bv_val += LENOF("teletex");
break;
}
if(( tmp.bv_len >= LENOF("telephone") ) &&
( strncasecmp(tmp.bv_val, "telephone", LENOF("telephone")) == 0 ))
{
tmp.bv_len -= LENOF("telephone");
tmp.bv_val += LENOF("telephone");
break;
}
return LDAP_INVALID_SYNTAX;
case 'g':
case 'G':
if(( tmp.bv_len >= LENOF("g3fax") ) && (
( strncasecmp(tmp.bv_val, "g3fax", LENOF("g3fax")) == 0 ) ||
( strncasecmp(tmp.bv_val, "g4fax", LENOF("g4fax")) == 0 )))
{
tmp.bv_len -= LENOF("g3fax");
tmp.bv_val += LENOF("g3fax");
break;
}
return LDAP_INVALID_SYNTAX;
case 'i':
case 'I':
if(( tmp.bv_len >= LENOF("ia5") ) &&
( strncasecmp(tmp.bv_val, "ia5", LENOF("ia5")) == 0 ))
{
tmp.bv_len -= LENOF("ia5");
tmp.bv_val += LENOF("ia5");
break;
}
return LDAP_INVALID_SYNTAX;
case 'v':
case 'V':
if(( tmp.bv_len >= LENOF("videotex") ) &&
( strncasecmp(tmp.bv_val, "videotex", LENOF("videotex")) == 0 ))
{
tmp.bv_len -= LENOF("videotex");
tmp.bv_val += LENOF("videotex");
break;
}
return LDAP_INVALID_SYNTAX;
default:
return LDAP_INVALID_SYNTAX;
}
if( tmp.bv_len == 0 ) return LDAP_SUCCESS;
while( tmp.bv_len && ( tmp.bv_val[0] == ' ' )) {
tmp.bv_len++;
tmp.bv_val--;
}
if( tmp.bv_len && ( tmp.bv_val[0] == '$' )) {
tmp.bv_len++;
tmp.bv_val--;
} else {
return LDAP_INVALID_SYNTAX;
}
while( tmp.bv_len && ( tmp.bv_val[0] == ' ' )) {
tmp.bv_len++;
tmp.bv_val--;
}
goto again;
}
static int
nisNetgroupTripleValidate(
Syntax *syntax,
struct berval *val )
{
char *p, *e;
int commas = 0;
if ( val->bv_len == 0 ) {
return LDAP_INVALID_SYNTAX;
}
p = (char *)val->bv_val;
e = p + val->bv_len;
if ( *p != '(' ) {
return LDAP_INVALID_SYNTAX;
}
for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
if ( *p == ',' ) {
commas++;
if ( commas > 2 ) {
return LDAP_INVALID_SYNTAX;
}
} else if ( !AD_CHAR( *p ) ) {
return LDAP_INVALID_SYNTAX;
}
}
if ( ( commas != 2 ) || ( *p != ')' ) ) {
return LDAP_INVALID_SYNTAX;
}
p++;
if (p != e) {
return LDAP_INVALID_SYNTAX;
}
return LDAP_SUCCESS;
}
static int
bootParameterValidate(
Syntax *syntax,
struct berval *val )
{
char *p, *e;
if ( val->bv_len == 0 ) {
return LDAP_INVALID_SYNTAX;
}
p = (char *)val->bv_val;
e = p + val->bv_len;
for (; ( p < e ) && ( *p != '=' ); p++ ) {
if ( !AD_CHAR( *p ) ) {
return LDAP_INVALID_SYNTAX;
}
}
if ( *p != '=' ) {
return LDAP_INVALID_SYNTAX;
}
for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
if ( !AD_CHAR( *p ) ) {
return LDAP_INVALID_SYNTAX;
}
}
if ( *p != ':' ) {
return LDAP_INVALID_SYNTAX;
}
for ( p++; p < e; p++ ) {
if ( !SLAP_PRINTABLE( *p ) ) {
return LDAP_INVALID_SYNTAX;
}
}
return LDAP_SUCCESS;
}
static int
firstComponentNormalize(
slap_mask_t usage,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized,
void *ctx )
{
int rc;
struct berval comp;
ber_len_t len;
if( SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX( usage )) {
ber_dupbv_x( normalized, val, ctx );
return LDAP_SUCCESS;
}
if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
if( val->bv_val[0] != '(' &&
val->bv_val[0] != '{' )
{
return LDAP_INVALID_SYNTAX;
}
for( len=1;
len < val->bv_len && ASCII_SPACE(val->bv_val[len]);
len++ )
{
}
comp.bv_val = &val->bv_val[len];
len = val->bv_len - len;
for( comp.bv_len=0;
!ASCII_SPACE(comp.bv_val[comp.bv_len]) && comp.bv_len < len;
comp.bv_len++ )
{
}
if( mr == slap_schema.si_mr_objectIdentifierFirstComponentMatch ) {
rc = numericoidValidate( NULL, &comp );
} else if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
rc = integerValidate( NULL, &comp );
} else {
rc = LDAP_INVALID_SYNTAX;
}
if( rc == LDAP_SUCCESS ) {
ber_dupbv_x( normalized, &comp, ctx );
}
return rc;
}
#define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
#define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
static slap_syntax_defs_rec syntax_defs[] = {
{"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
X_BINARY X_NOT_H_R ")",
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
X_NOT_H_R ")",
SLAP_SYNTAX_BLOB, blobValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
X_NOT_H_R ")",
SLAP_SYNTAX_BER, berValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
0, bitStringValidate, NULL },
{"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
0, booleanValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
X_BINARY X_NOT_H_R ")",
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, certificateValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
X_BINARY X_NOT_H_R ")",
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, sequenceValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
X_BINARY X_NOT_H_R ")",
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, sequenceValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
0, countryStringValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
0, dnValidate, dnPretty},
{"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
0, deliveryMethodValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
0, UTF8StringValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
0, printablesStringValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
SLAP_SYNTAX_BLOB, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
0, generalizedTimeValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
0, IA5StringValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
0, integerValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
SLAP_SYNTAX_BLOB, blobValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
0, nameUIDValidate, nameUIDPretty },
{"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
0, numericStringValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
0, numericoidValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
0, IA5StringValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
0, blobValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
0, UTF8StringValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
0, printableStringValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' )",
#define subtreeSpecificationValidate UTF8StringValidate
0, subtreeSpecificationValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
X_BINARY X_NOT_H_R ")",
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
0, printableStringValidate, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
0, printablesStringValidate, NULL},
#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
{"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
0, utcTimeValidate, NULL},
#endif
{"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
0, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
0, NULL, NULL},
{"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
0, nisNetgroupTripleValidate, NULL},
{"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
0, bootParameterValidate, NULL},
{"( 1.2.826.0.1.3344810.7.1 DESC 'Certificate Serial Number and Issuer' )",
SLAP_SYNTAX_HIDE,
serialNumberAndIssuerValidate,
serialNumberAndIssuerPretty},
#ifdef SLAPD_ACI_ENABLED
{"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
SLAP_SYNTAX_HIDE,
UTF8StringValidate ,
NULL},
#endif
#ifdef SLAPD_AUTHPASSWD
{"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
SLAP_SYNTAX_HIDE, NULL, NULL},
#endif
{"( 1.3.6.1.4.1.4203.666.2.6 DESC 'UUID' )",
SLAP_SYNTAX_HIDE, UUIDValidate, NULL},
{"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
SLAP_SYNTAX_HIDE, inValidate, NULL},
{NULL, 0, NULL, NULL}
};
char *certificateExactMatchSyntaxes[] = {
"1.3.6.1.4.1.1466.115.121.1.8" ,
NULL
};
char *directoryStringSyntaxes[] = {
"1.3.6.1.4.1.1466.115.121.1.44" ,
NULL
};
char *integerFirstComponentMatchSyntaxes[] = {
"1.3.6.1.4.1.1466.115.121.1.27" ,
"1.3.6.1.4.1.1466.115.121.1.17" ,
NULL
};
char *objectIdentifierFirstComponentMatchSyntaxes[] = {
"1.3.6.1.4.1.1466.115.121.1.38" ,
"1.3.6.1.4.1.1466.115.121.1.3" ,
"1.3.6.1.4.1.1466.115.121.1.16" ,
"1.3.6.1.4.1.1466.115.121.1.54" ,
"1.3.6.1.4.1.1466.115.121.1.30" ,
"1.3.6.1.4.1.1466.115.121.1.31" ,
"1.3.6.1.4.1.1466.115.121.1.35" ,
"1.3.6.1.4.1.1466.115.121.1.37" ,
NULL
};
static slap_mrule_defs_rec mrule_defs[] = {
{"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
NULL, NULL, directoryStringApproxMatch,
directoryStringApproxIndexer, directoryStringApproxFilter,
NULL},
{"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
NULL, NULL, IA5StringApproxMatch,
IA5StringApproxIndexer, IA5StringApproxFilter,
NULL},
{"( 2.5.13.0 NAME 'objectIdentifierMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, NULL, octetStringMatch,
octetStringIndexer, octetStringFilter,
NULL },
{"( 2.5.13.1 NAME 'distinguishedNameMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, dnNormalize, dnMatch,
octetStringIndexer, octetStringFilter,
NULL },
{"( 2.5.13.2 NAME 'caseIgnoreMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
NULL, UTF8StringNormalize, octetStringMatch,
octetStringIndexer, octetStringFilter,
directoryStringApproxMatchOID },
{"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
SLAP_MR_ORDERING, directoryStringSyntaxes,
NULL, UTF8StringNormalize, octetStringOrderingMatch,
NULL, NULL,
"caseIgnoreMatch" },
{"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
SLAP_MR_SUBSTR, directoryStringSyntaxes,
NULL, UTF8StringNormalize, octetStringSubstringsMatch,
octetStringSubstringsIndexer, octetStringSubstringsFilter,
"caseIgnoreMatch" },
{"( 2.5.13.5 NAME 'caseExactMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
NULL, UTF8StringNormalize, octetStringMatch,
octetStringIndexer, octetStringFilter,
directoryStringApproxMatchOID },
{"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
SLAP_MR_ORDERING, directoryStringSyntaxes,
NULL, UTF8StringNormalize, octetStringOrderingMatch,
NULL, NULL,
"caseExactMatch" },
{"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
SLAP_MR_SUBSTR, directoryStringSyntaxes,
NULL, UTF8StringNormalize, octetStringSubstringsMatch,
octetStringSubstringsIndexer, octetStringSubstringsFilter,
"caseExactMatch" },
{"( 2.5.13.8 NAME 'numericStringMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, numericStringNormalize, octetStringMatch,
octetStringIndexer, octetStringFilter,
NULL },
{"( 2.5.13.9 NAME 'numericStringOrderingMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
SLAP_MR_ORDERING, NULL,
NULL, numericStringNormalize, octetStringOrderingMatch,
NULL, NULL,
"numericStringMatch" },
{"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
SLAP_MR_SUBSTR, NULL,
NULL, numericStringNormalize, octetStringSubstringsMatch,
octetStringSubstringsIndexer, octetStringSubstringsFilter,
"numericStringMatch" },
{"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, NULL, NULL, NULL, NULL, NULL },
{"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
SLAP_MR_SUBSTR, NULL,
NULL, NULL, NULL, NULL, NULL,
"caseIgnoreListMatch" },
{"( 2.5.13.13 NAME 'booleanMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, NULL, booleanMatch,
octetStringIndexer, octetStringFilter,
NULL },
{"( 2.5.13.14 NAME 'integerMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, NULL, integerMatch,
octetStringIndexer, octetStringFilter,
NULL },
{"( 2.5.13.15 NAME 'integerOrderingMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
SLAP_MR_ORDERING, NULL,
NULL, NULL, integerMatch,
NULL, NULL,
"integerMatch" },
{"( 2.5.13.16 NAME 'bitStringMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, NULL, octetStringMatch,
octetStringIndexer, octetStringFilter,
NULL },
{"( 2.5.13.17 NAME 'octetStringMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, NULL, octetStringMatch,
octetStringIndexer, octetStringFilter,
NULL },
{"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
SLAP_MR_ORDERING, NULL,
NULL, NULL, octetStringOrderingMatch,
NULL, NULL,
"octetStringMatch" },
{"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
SLAP_MR_SUBSTR, NULL,
NULL, NULL, octetStringSubstringsMatch,
octetStringSubstringsIndexer, octetStringSubstringsFilter,
"octetStringMatch" },
{"( 2.5.13.20 NAME 'telephoneNumberMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL,
telephoneNumberNormalize, octetStringMatch,
octetStringIndexer, octetStringFilter,
NULL },
{"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
SLAP_MR_SUBSTR, NULL,
NULL, telephoneNumberNormalize, octetStringSubstringsMatch,
octetStringSubstringsIndexer, octetStringSubstringsFilter,
"telephoneNumberMatch" },
{"( 2.5.13.22 NAME 'presentationAddressMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, NULL, NULL, NULL, NULL, NULL },
{"( 2.5.13.23 NAME 'uniqueMemberMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, uniqueMemberNormalize, uniqueMemberMatch,
NULL, NULL,
NULL },
{"( 2.5.13.24 NAME 'protocolInformationMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, NULL, NULL, NULL, NULL, NULL },
{"( 2.5.13.27 NAME 'generalizedTimeMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, generalizedTimeNormalize, octetStringMatch,
NULL, NULL,
NULL },
{"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
SLAP_MR_ORDERING, NULL,
NULL, generalizedTimeNormalize, generalizedTimeOrderingMatch,
NULL, NULL,
"generalizedTimeMatch" },
{"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT,
integerFirstComponentMatchSyntaxes,
NULL, firstComponentNormalize, integerMatch,
octetStringIndexer, octetStringFilter,
NULL },
{"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT,
objectIdentifierFirstComponentMatchSyntaxes,
NULL, firstComponentNormalize, octetStringMatch,
octetStringIndexer, octetStringFilter,
NULL },
{"( 2.5.13.34 NAME 'certificateExactMatch' "
"SYNTAX 1.2.826.0.1.3344810.7.1 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
#ifdef HAVE_TLS
NULL, certificateExactNormalize, octetStringMatch,
octetStringIndexer, octetStringFilter,
#else
NULL, NULL, NULL, NULL, NULL,
#endif
NULL },
{"( 2.5.13.35 NAME 'certificateMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
#ifdef HAVE_TLS
NULL, NULL, octetStringMatch,
octetStringIndexer, octetStringFilter,
#else
NULL, NULL, NULL, NULL, NULL,
#endif
NULL },
{"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, IA5StringNormalize, octetStringMatch,
octetStringIndexer, octetStringFilter,
IA5StringApproxMatchOID },
{"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
NULL, IA5StringNormalize, octetStringMatch,
octetStringIndexer, octetStringFilter,
IA5StringApproxMatchOID },
{"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
SLAP_MR_SUBSTR, NULL,
NULL, IA5StringNormalize, octetStringSubstringsMatch,
octetStringSubstringsIndexer, octetStringSubstringsFilter,
"caseIgnoreIA5Match" },
{"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
SLAP_MR_SUBSTR, NULL,
NULL, IA5StringNormalize, octetStringSubstringsMatch,
octetStringSubstringsIndexer, octetStringSubstringsFilter,
"caseExactIA5Match" },
#ifdef SLAPD_AUTHPASSWD
{"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL,
NULL, NULL, authPasswordMatch,
NULL, NULL,
NULL},
#endif
#ifdef SLAPD_ACI_ENABLED
{"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
"SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL,
NULL, NULL, OpenLDAPaciMatch,
NULL, NULL,
NULL},
#endif
{"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
SLAP_MR_EXT, NULL,
NULL, NULL, integerBitAndMatch,
NULL, NULL,
"integerMatch" },
{"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
SLAP_MR_EXT, NULL,
NULL, NULL, integerBitOrMatch,
NULL, NULL,
"integerMatch" },
{"( 1.3.6.1.4.1.4203.666.4.6 NAME 'UUIDMatch' "
"SYNTAX 1.3.6.1.4.1.4203.666.2.6 )",
SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL,
NULL, UUIDNormalize, octetStringMatch,
octetStringIndexer, octetStringFilter,
NULL},
{"( 1.3.6.1.4.1.4203.666.4.7 NAME 'UUIDOrderingMatch' "
"SYNTAX 1.3.6.1.4.1.4203.666.2.6 )",
SLAP_MR_HIDE | SLAP_MR_ORDERING, NULL,
NULL, UUIDNormalize, octetStringOrderingMatch,
octetStringIndexer, octetStringFilter,
"UUIDMatch"},
{NULL, SLAP_MR_NONE, NULL,
NULL, NULL, NULL, NULL, NULL,
NULL }
};
int
slap_schema_init( void )
{
int res;
int i;
assert( schema_init_done == 0 );
ldap_pvt_thread_mutex_init( &oc_mutex );
ldap_pvt_thread_mutex_init( &at_mutex );
for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
res = register_syntax( &syntax_defs[i] );
if ( res ) {
fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
syntax_defs[i].sd_desc );
return LDAP_OTHER;
}
}
for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
mrule_defs[i].mrd_compat_syntaxes == NULL )
{
fprintf( stderr,
"slap_schema_init: Ignoring unusable matching rule %s\n",
mrule_defs[i].mrd_desc );
continue;
}
res = register_matching_rule( &mrule_defs[i] );
if ( res ) {
fprintf( stderr,
"slap_schema_init: Error registering matching rule %s\n",
mrule_defs[i].mrd_desc );
return LDAP_OTHER;
}
}
res = slap_schema_load();
schema_init_done = 1;
return res;
}
void
schema_destroy( void )
{
oidm_destroy();
oc_destroy();
at_destroy();
mr_destroy();
mru_destroy();
syn_destroy();
}