2000-01-30 03:43:19 +08:00
|
|
|
/* schema_init.c - init builtin schema */
|
|
|
|
/* $OpenLDAP$ */
|
|
|
|
/*
|
2003-01-04 04:20:47 +08:00
|
|
|
* Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
|
2000-01-30 03:43:19 +08:00
|
|
|
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "portable.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2001-09-07 10:08:32 +08:00
|
|
|
#include <limits.h>
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
#include <ac/ctype.h>
|
2001-09-02 01:10:43 +08:00
|
|
|
#include <ac/errno.h>
|
2000-01-30 03:43:19 +08:00
|
|
|
#include <ac/string.h>
|
|
|
|
#include <ac/socket.h>
|
|
|
|
|
|
|
|
#include "slap.h"
|
|
|
|
#include "ldap_pvt.h"
|
2002-02-15 05:10:13 +08:00
|
|
|
#include "lber_pvt.h"
|
2000-06-05 06:59:38 +08:00
|
|
|
|
2001-07-22 07:13:04 +08:00
|
|
|
#include "ldap_utf8.h"
|
|
|
|
|
2000-09-23 06:19:46 +08:00
|
|
|
#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)
|
2000-09-23 04:47:46 +08:00
|
|
|
|
2003-04-05 11:35:16 +08:00
|
|
|
#define SLAP_NVALUES 1
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* not yet implemented */
|
2003-04-24 13:16:06 +08:00
|
|
|
#define uniqueMemberMatch NULL
|
2000-06-21 09:12:29 +08:00
|
|
|
|
2003-04-07 16:54:12 +08:00
|
|
|
#define OpenLDAPaciMatch NULL
|
|
|
|
|
2000-07-25 05:29:30 +08:00
|
|
|
/* approx matching rules */
|
2003-02-27 14:51:53 +08:00
|
|
|
#ifdef SLAP_NVALUES
|
|
|
|
#define directoryStringApproxMatchOID NULL
|
|
|
|
#define IA5StringApproxMatchOID NULL
|
|
|
|
#else
|
2000-07-25 05:29:30 +08:00
|
|
|
#define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
|
2001-01-18 00:35:53 +08:00
|
|
|
#define directoryStringApproxMatch approxMatch
|
|
|
|
#define directoryStringApproxIndexer approxIndexer
|
|
|
|
#define directoryStringApproxFilter approxFilter
|
2000-07-25 05:29:30 +08:00
|
|
|
#define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
|
2001-01-18 00:35:53 +08:00
|
|
|
#define IA5StringApproxMatch approxMatch
|
2000-10-25 04:25:37 +08:00
|
|
|
#define IA5StringApproxIndexer approxIndexer
|
2001-01-18 00:35:53 +08:00
|
|
|
#define IA5StringApproxFilter approxFilter
|
2003-02-27 14:51:53 +08:00
|
|
|
#endif
|
2000-07-25 05:29:30 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
static int
|
|
|
|
inValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
2000-09-04 02:04:08 +08:00
|
|
|
{
|
2003-04-07 09:06:46 +08:00
|
|
|
/* no value allowed */
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2002-01-17 08:18:57 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
static int
|
|
|
|
blobValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
/* any value allowed */
|
|
|
|
return LDAP_SUCCESS;
|
2000-09-04 02:04:08 +08:00
|
|
|
}
|
2000-07-25 05:29:30 +08:00
|
|
|
|
2003-04-07 11:46:22 +08:00
|
|
|
#define berValidate blobValidate
|
|
|
|
|
2000-06-05 06:59:38 +08:00
|
|
|
static int
|
|
|
|
octetStringMatch(
|
|
|
|
int *matchp,
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t flags,
|
2000-06-05 06:59:38 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
2003-04-07 11:46:22 +08:00
|
|
|
struct berval *asserted = (struct berval *) assertedValue;
|
|
|
|
int match = value->bv_len - asserted->bv_len;
|
2000-06-05 06:59:38 +08:00
|
|
|
|
|
|
|
if( match == 0 ) {
|
2003-04-07 11:46:22 +08:00
|
|
|
match = memcmp( value->bv_val, asserted->bv_val, value->bv_len );
|
2000-06-05 06:59:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
*matchp = match;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-01-04 01:06:01 +08:00
|
|
|
static int
|
|
|
|
octetStringOrderingMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
2003-04-07 11:46:22 +08:00
|
|
|
struct berval *asserted = (struct berval *) assertedValue;
|
2003-01-04 01:06:01 +08:00
|
|
|
ber_len_t v_len = value->bv_len;
|
2003-04-07 11:46:22 +08:00
|
|
|
ber_len_t av_len = asserted->bv_len;
|
2003-02-27 14:51:53 +08:00
|
|
|
|
2003-04-07 11:46:22 +08:00
|
|
|
int match = memcmp( value->bv_val, asserted->bv_val,
|
2003-01-04 01:06:01 +08:00
|
|
|
(v_len < av_len ? v_len : av_len) );
|
2003-02-27 14:51:53 +08:00
|
|
|
|
|
|
|
if( match == 0 ) match = v_len - av_len;
|
|
|
|
|
2003-01-04 01:06:01 +08:00
|
|
|
*matchp = match;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-06-05 06:59:38 +08:00
|
|
|
/* Index generation function */
|
2002-08-29 09:12:59 +08:00
|
|
|
int octetStringIndexer(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-06-05 06:59:38 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
2002-01-14 09:43:17 +08:00
|
|
|
BerVarray values,
|
2003-04-11 09:29:28 +08:00
|
|
|
BerVarray *keysp,
|
|
|
|
void *ctx )
|
2000-06-05 06:59:38 +08:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
size_t slen, mlen;
|
2002-01-14 09:43:17 +08:00
|
|
|
BerVarray keys;
|
2003-04-07 11:46:22 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-06-05 06:59:38 +08:00
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-06-05 06:59:38 +08:00
|
|
|
|
2002-01-02 19:00:36 +08:00
|
|
|
for( i=0; values[i].bv_val != NULL; i++ ) {
|
2000-06-05 06:59:38 +08:00
|
|
|
/* just count them */
|
|
|
|
}
|
|
|
|
|
2001-07-26 09:08:00 +08:00
|
|
|
/* we should have at least one value at this point */
|
|
|
|
assert( i > 0 );
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
keys = sl_malloc( sizeof( struct berval ) * (i+1), ctx );
|
2000-06-05 06:59:38 +08:00
|
|
|
|
2001-12-26 22:36:02 +08:00
|
|
|
slen = syntax->ssyn_oidlen;
|
|
|
|
mlen = mr->smr_oidlen;
|
2000-06-05 06:59:38 +08:00
|
|
|
|
2002-01-02 19:00:36 +08:00
|
|
|
for( i=0; values[i].bv_val != NULL; i++ ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2002-01-02 19:00:36 +08:00
|
|
|
values[i].bv_val, values[i].bv_len );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
ber_dupbv_x( &keys[i], &digest, ctx );
|
2000-06-05 06:59:38 +08:00
|
|
|
}
|
|
|
|
|
2001-12-29 23:01:10 +08:00
|
|
|
keys[i].bv_val = NULL;
|
2002-08-29 09:12:59 +08:00
|
|
|
keys[i].bv_len = 0;
|
2000-06-05 06:59:38 +08:00
|
|
|
|
|
|
|
*keysp = keys;
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Index generation function */
|
2002-08-29 09:12:59 +08:00
|
|
|
int octetStringFilter(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-06-05 06:59:38 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
2002-08-29 10:27:15 +08:00
|
|
|
void * assertedValue,
|
2003-04-11 09:29:28 +08:00
|
|
|
BerVarray *keysp,
|
|
|
|
void *ctx )
|
2000-06-05 06:59:38 +08:00
|
|
|
{
|
|
|
|
size_t slen, mlen;
|
2002-01-14 09:43:17 +08:00
|
|
|
BerVarray keys;
|
2003-04-07 11:46:22 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2002-08-29 10:27:15 +08:00
|
|
|
struct berval *value = (struct berval *) assertedValue;
|
2000-06-05 06:59:38 +08:00
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-06-05 06:59:38 +08:00
|
|
|
|
2001-12-26 22:36:02 +08:00
|
|
|
slen = syntax->ssyn_oidlen;
|
|
|
|
mlen = mr->smr_oidlen;
|
2000-06-05 06:59:38 +08:00
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
keys = sl_malloc( sizeof( struct berval ) * 2, ctx );
|
2000-06-05 06:59:38 +08:00
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
value->bv_val, value->bv_len );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
ber_dupbv_x( keys, &digest, ctx );
|
2001-12-29 23:01:10 +08:00
|
|
|
keys[1].bv_val = NULL;
|
2002-08-29 09:12:59 +08:00
|
|
|
keys[1].bv_len = 0;
|
2000-06-05 06:59:38 +08:00
|
|
|
|
|
|
|
*keysp = keys;
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-05-28 03:33:08 +08:00
|
|
|
static int
|
2003-04-07 11:46:22 +08:00
|
|
|
octetStringSubstringsMatch(
|
2003-04-07 09:06:46 +08:00
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
2000-09-12 08:32:08 +08:00
|
|
|
Syntax *syntax,
|
2003-04-07 09:06:46 +08:00
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
2000-09-12 08:32:08 +08:00
|
|
|
{
|
2003-04-07 09:06:46 +08:00
|
|
|
int match = 0;
|
|
|
|
SubstringsAssertion *sub = assertedValue;
|
|
|
|
struct berval left = *value;
|
|
|
|
int i;
|
2003-04-07 11:46:22 +08:00
|
|
|
ber_len_t inlen = 0;
|
2000-09-12 08:32:08 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Add up asserted input length */
|
|
|
|
if( sub->sa_initial.bv_val ) {
|
|
|
|
inlen += sub->sa_initial.bv_len;
|
2000-09-12 08:32:08 +08:00
|
|
|
}
|
2003-04-07 09:06:46 +08:00
|
|
|
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;
|
2000-09-12 08:32:08 +08:00
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
if( sub->sa_initial.bv_val ) {
|
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
2000-09-12 08:32:08 +08:00
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
match = memcmp( sub->sa_initial.bv_val, left.bv_val,
|
|
|
|
sub->sa_initial.bv_len );
|
2000-09-12 08:32:08 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
if( match != 0 ) {
|
|
|
|
goto done;
|
|
|
|
}
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
left.bv_val += sub->sa_initial.bv_len;
|
|
|
|
left.bv_len -= sub->sa_initial.bv_len;
|
|
|
|
inlen -= sub->sa_initial.bv_len;
|
|
|
|
}
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
if( sub->sa_final.bv_val ) {
|
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
match = memcmp( sub->sa_final.bv_val,
|
|
|
|
&left.bv_val[left.bv_len - sub->sa_final.bv_len],
|
|
|
|
sub->sa_final.bv_len );
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
if( match != 0 ) {
|
|
|
|
goto done;
|
2002-08-06 11:18:02 +08:00
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
left.bv_len -= sub->sa_final.bv_len;
|
|
|
|
inlen -= sub->sa_final.bv_len;
|
2002-08-06 11:18:02 +08:00
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
if( sub->sa_any ) {
|
|
|
|
for(i=0; sub->sa_any[i].bv_val; i++) {
|
|
|
|
ber_len_t idx;
|
|
|
|
char *p;
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
retry:
|
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
/* not enough length */
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
if( sub->sa_any[i].bv_len == 0 ) {
|
|
|
|
continue;
|
|
|
|
}
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
if( p == NULL ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
2002-08-06 11:18:02 +08:00
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
idx = p - left.bv_val;
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
if( idx >= left.bv_len ) {
|
|
|
|
/* this shouldn't happen */
|
|
|
|
return LDAP_OTHER;
|
|
|
|
}
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
left.bv_val = p;
|
|
|
|
left.bv_len -= idx;
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
if( sub->sa_any[i].bv_len > left.bv_len ) {
|
|
|
|
/* not enough left */
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
match = memcmp( left.bv_val,
|
|
|
|
sub->sa_any[i].bv_val,
|
|
|
|
sub->sa_any[i].bv_len );
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
if( match != 0 ) {
|
|
|
|
left.bv_val++;
|
|
|
|
left.bv_len--;
|
|
|
|
goto retry;
|
|
|
|
}
|
2002-08-06 11:18:02 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
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;
|
2002-08-06 11:18:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
done:
|
|
|
|
*matchp = match;
|
2002-08-06 11:18:02 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Substrings Index generation function */
|
|
|
|
static int
|
2003-04-07 11:46:22 +08:00
|
|
|
octetStringSubstringsIndexer(
|
2003-04-07 09:06:46 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
BerVarray values,
|
2003-04-11 09:29:28 +08:00
|
|
|
BerVarray *keysp,
|
|
|
|
void *ctx )
|
2003-04-07 09:06:46 +08:00
|
|
|
{
|
|
|
|
ber_len_t i, j, nkeys;
|
|
|
|
size_t slen, mlen;
|
|
|
|
BerVarray keys;
|
|
|
|
|
2003-04-07 11:46:22 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2003-04-07 09:06:46 +08:00
|
|
|
struct berval digest;
|
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
|
|
|
|
|
|
|
nkeys=0;
|
|
|
|
|
|
|
|
for( i=0; values[i].bv_val != NULL; i++ ) {
|
|
|
|
/* count number of indices to generate */
|
|
|
|
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 -
|
2003-04-07 11:46:22 +08:00
|
|
|
(SLAP_INDEX_SUBSTR_MINLEN - 1);
|
2003-04-07 09:06:46 +08:00
|
|
|
} else {
|
2003-04-07 11:46:22 +08:00
|
|
|
nkeys += values[i].bv_len - (SLAP_INDEX_SUBSTR_MINLEN - 1);
|
2003-04-07 09:06:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_ANY ) {
|
|
|
|
if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
2003-04-07 11:46:22 +08:00
|
|
|
nkeys += values[i].bv_len - (SLAP_INDEX_SUBSTR_MAXLEN - 1);
|
2003-04-07 09:06:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2003-04-07 11:46:22 +08:00
|
|
|
nkeys += values[i].bv_len - (SLAP_INDEX_SUBSTR_MINLEN - 1);
|
2003-04-07 09:06:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nkeys == 0 ) {
|
|
|
|
/* no keys to generate */
|
|
|
|
*keysp = NULL;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
keys = sl_malloc( sizeof( struct berval ) * (nkeys+1), ctx );
|
2003-04-07 09:06:46 +08:00
|
|
|
|
|
|
|
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;
|
2003-04-07 11:46:22 +08:00
|
|
|
max = values[i].bv_len - (SLAP_INDEX_SUBSTR_MAXLEN - 1);
|
2003-04-07 09:06:46 +08:00
|
|
|
|
|
|
|
for( j=0; j<max; j++ ) {
|
|
|
|
HASH_Init( &HASHcontext );
|
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
|
|
|
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
&pre, sizeof( pre ) );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
syntax->ssyn_oid, slen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
mr->smr_oid, mlen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
&values[i].bv_val[j],
|
|
|
|
SLAP_INDEX_SUBSTR_MAXLEN );
|
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
|
2003-04-07 09:06:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
&pre, sizeof( pre ) );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
syntax->ssyn_oid, slen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
mr->smr_oid, mlen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
values[i].bv_val, j );
|
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
|
2003-04-07 09:06:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
&pre, sizeof( pre ) );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
syntax->ssyn_oid, slen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
mr->smr_oid, mlen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
&values[i].bv_val[values[i].bv_len-j], j );
|
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
|
2003-04-07 09:06:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
2003-04-11 09:29:28 +08:00
|
|
|
BerVarray *keysp,
|
|
|
|
void *ctx)
|
2003-04-07 09:06:46 +08:00
|
|
|
{
|
|
|
|
SubstringsAssertion *sa;
|
|
|
|
char pre;
|
|
|
|
ber_len_t nkeys = 0;
|
|
|
|
size_t slen, mlen, klen;
|
|
|
|
BerVarray keys;
|
2003-04-07 11:46:22 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2003-04-07 09:06:46 +08:00
|
|
|
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 ) {
|
|
|
|
/* don't bother accounting for stepping */
|
|
|
|
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 = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
|
|
|
|
|
|
|
slen = syntax->ssyn_oidlen;
|
|
|
|
mlen = mr->smr_oidlen;
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
keys = sl_malloc( sizeof( struct berval ) * (nkeys+1), ctx );
|
2003-04-07 09:06:46 +08:00
|
|
|
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,
|
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
&pre, sizeof( pre ) );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
syntax->ssyn_oid, slen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
mr->smr_oid, mlen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
value->bv_val, klen );
|
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
|
2003-04-07 09:06:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
&pre, sizeof( pre ) );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
syntax->ssyn_oid, slen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
mr->smr_oid, mlen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
&value->bv_val[j], klen );
|
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
|
2003-04-07 09:06:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
&pre, sizeof( pre ) );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
syntax->ssyn_oid, slen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
mr->smr_oid, mlen );
|
|
|
|
HASH_Update( &HASHcontext,
|
|
|
|
&value->bv_val[value->bv_len-klen], klen );
|
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
|
2003-04-07 09:06:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
/* very unforgiving validation, requires no normalization
|
|
|
|
* before simplistic matching
|
|
|
|
*/
|
|
|
|
if( in->bv_len < 3 ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2003-04-07 11:46:22 +08:00
|
|
|
* RFC 2252 section 6.3 Bit String
|
|
|
|
* bitstring = "'" *binary-digit "'B"
|
|
|
|
* binary-digit = "0" / "1"
|
2003-04-07 09:06:46 +08:00
|
|
|
* example: '0101111101'B
|
|
|
|
*/
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
if( in->bv_len == 0 ) return LDAP_SUCCESS;
|
|
|
|
|
|
|
|
ber_dupbv( &dn, in );
|
|
|
|
if( !dn.bv_val ) return LDAP_OTHER;
|
|
|
|
|
|
|
|
if( dn.bv_val[dn.bv_len-1] == 'B'
|
|
|
|
&& dn.bv_val[dn.bv_len-2] == '\'' )
|
|
|
|
{
|
|
|
|
/* assume presence of optional UID */
|
|
|
|
ber_len_t i;
|
|
|
|
|
|
|
|
for(i=dn.bv_len-3; i>1; i--) {
|
2003-04-07 11:46:22 +08:00
|
|
|
if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
|
2003-04-07 09:06:46 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
|
|
|
|
ber_memfree( dn.bv_val );
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* trim the UID to allow use of dnValidate */
|
|
|
|
dn.bv_val[i-1] = '\0';
|
|
|
|
dn.bv_len = i-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = dnValidate( NULL, &dn );
|
|
|
|
|
|
|
|
ber_memfree( dn.bv_val );
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
uniqueMemberNormalize(
|
|
|
|
slap_mask_t usage,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *val,
|
2003-04-11 09:29:28 +08:00
|
|
|
struct berval *normalized,
|
|
|
|
void *ctx )
|
2003-04-07 09:06:46 +08:00
|
|
|
{
|
|
|
|
struct berval out;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
ber_dupbv( &out, val );
|
|
|
|
if( out.bv_len != 0 ) {
|
|
|
|
struct berval uid = { 0, NULL };
|
|
|
|
|
|
|
|
if( out.bv_val[out.bv_len-1] == 'B'
|
|
|
|
&& out.bv_val[out.bv_len-2] == '\'' )
|
|
|
|
{
|
|
|
|
/* assume presence of optional UID */
|
|
|
|
uid.bv_val = strrchr( out.bv_val, '#' );
|
|
|
|
|
|
|
|
if( uid.bv_val == NULL ) {
|
|
|
|
free( out.bv_val );
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
|
|
|
|
out.bv_len -= uid.bv_len--;
|
|
|
|
|
|
|
|
/* temporarily trim the UID */
|
|
|
|
*(uid.bv_val++) = '\0';
|
|
|
|
}
|
|
|
|
|
2003-04-30 02:28:14 +08:00
|
|
|
rc = dnNormalize( 0, NULL, NULL, &out, normalized, ctx );
|
2003-04-07 09:06:46 +08:00
|
|
|
|
|
|
|
if( rc != LDAP_SUCCESS ) {
|
|
|
|
free( out.bv_val );
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( uid.bv_len ) {
|
|
|
|
normalized->bv_val = ch_realloc( normalized->bv_val,
|
|
|
|
normalized->bv_len + uid.bv_len + sizeof("#") );
|
|
|
|
|
|
|
|
/* insert the separator */
|
|
|
|
normalized->bv_val[normalized->bv_len++] = '#';
|
|
|
|
|
|
|
|
/* append the UID */
|
|
|
|
AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
|
|
|
|
uid.bv_val, uid.bv_len );
|
|
|
|
normalized->bv_len += uid.bv_len;
|
|
|
|
|
|
|
|
/* terminate */
|
|
|
|
normalized->bv_val[normalized->bv_len] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
free( out.bv_val );
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Handling boolean syntax and matching is quite rigid.
|
|
|
|
* A more flexible approach would be to allow a variety
|
|
|
|
* of strings to be normalized and prettied into TRUE
|
|
|
|
* and FALSE.
|
|
|
|
*/
|
2000-06-30 03:00:17 +08:00
|
|
|
static int
|
|
|
|
booleanValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
/* very unforgiving validation, requires no normalization
|
|
|
|
* before simplistic matching
|
|
|
|
*/
|
|
|
|
|
|
|
|
if( in->bv_len == 4 ) {
|
2003-04-17 03:49:00 +08:00
|
|
|
if( bvmatch( in, &slap_true_bv ) ) {
|
2000-06-30 03:00:17 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
} else if( in->bv_len == 5 ) {
|
2003-04-17 03:49:00 +08:00
|
|
|
if( bvmatch( in, &slap_false_bv ) ) {
|
2000-06-30 03:00:17 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
booleanMatch(
|
|
|
|
int *matchp,
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t flags,
|
2000-06-30 03:00:17 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
/* simplistic matching allowed by rigid validation */
|
|
|
|
struct berval *asserted = (struct berval *) assertedValue;
|
|
|
|
*matchp = value->bv_len != asserted->bv_len;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2002-08-07 16:19:11 +08:00
|
|
|
/*-------------------------------------------------------------------
|
|
|
|
LDAP/X.500 string syntax / matching rules have a few oddities. This
|
|
|
|
comment attempts to detail how slapd(8) treats them.
|
|
|
|
|
|
|
|
Summary:
|
2003-02-28 13:13:29 +08:00
|
|
|
StringSyntax X.500 LDAP Matching/Comments
|
2002-08-07 16:19:11 +08:00
|
|
|
DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
|
|
|
|
PrintableString subset subset i/e + ignore insignificant spaces
|
2003-02-28 13:13:29 +08:00
|
|
|
PrintableString subset subset i/e + ignore insignificant spaces
|
2003-04-07 11:46:22 +08:00
|
|
|
NumericString subset subset ignore all spaces
|
2002-08-07 16:19:11 +08:00
|
|
|
IA5String ASCII ASCII i/e + ignore insignificant spaces
|
|
|
|
TeletexString T.61 T.61 i/e + ignore insignificant spaces
|
|
|
|
|
2003-04-07 11:46:22 +08:00
|
|
|
TelephoneNumber subset subset i + ignore all spaces and "-"
|
2002-08-07 16:19:11 +08:00
|
|
|
|
|
|
|
See draft-ietf-ldapbis-strpro for details (once published).
|
|
|
|
|
|
|
|
|
|
|
|
Directory String -
|
|
|
|
In X.500(93), a directory string can be either a PrintableString,
|
|
|
|
a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
|
|
|
|
In later versions, more CHOICEs were added. In all cases the string
|
|
|
|
must be non-empty.
|
|
|
|
|
2002-08-31 18:45:22 +08:00
|
|
|
In LDAPv3, a directory string is a UTF-8 encoded UCS string.
|
2003-02-28 13:13:29 +08:00
|
|
|
A directory string cannot be zero length.
|
2002-08-07 16:19:11 +08:00
|
|
|
|
|
|
|
For matching, there are both case ignore and exact rules. Both
|
|
|
|
also require that "insignificant" spaces be ignored.
|
|
|
|
spaces before the first non-space are ignored;
|
|
|
|
spaces after the last non-space are ignored;
|
|
|
|
spaces after a space are ignored.
|
|
|
|
Note: by these rules (and as clarified in X.520), a string of only
|
|
|
|
spaces is to be treated as if held one space, not empty (which
|
|
|
|
would be a syntax error).
|
|
|
|
|
|
|
|
NumericString
|
|
|
|
In ASN.1, numeric string is just a string of digits and spaces
|
|
|
|
and could be empty. However, in X.500, all attribute values of
|
|
|
|
numeric string carry a non-empty constraint. For example:
|
|
|
|
|
|
|
|
internationalISDNNumber ATTRIBUTE ::= {
|
|
|
|
WITH SYNTAX InternationalISDNNumber
|
|
|
|
EQUALITY MATCHING RULE numericStringMatch
|
|
|
|
SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
|
|
|
|
ID id-at-internationalISDNNumber }
|
|
|
|
InternationalISDNNumber ::=
|
|
|
|
NumericString (SIZE(1..ub-international-isdn-number))
|
|
|
|
|
|
|
|
Unforunately, some assertion values are don't carry the same
|
|
|
|
constraint (but its unclear how such an assertion could ever
|
|
|
|
be true). In LDAP, there is one syntax (numericString) not two
|
|
|
|
(numericString with constraint, numericString without constraint).
|
|
|
|
This should be treated as numericString with non-empty constraint.
|
|
|
|
Note that while someone may have no ISDN number, there are no ISDN
|
|
|
|
numbers which are zero length.
|
|
|
|
|
|
|
|
In matching, spaces are ignored.
|
|
|
|
|
|
|
|
PrintableString
|
|
|
|
In ASN.1, Printable string is just a string of printable characters
|
|
|
|
and can be empty. In X.500, semantics much like NumericString (see
|
|
|
|
serialNumber for a like example) excepting uses insignificant space
|
|
|
|
handling instead of ignore all spaces.
|
|
|
|
|
|
|
|
IA5String
|
|
|
|
Basically same as PrintableString. There are no examples in X.500,
|
|
|
|
but same logic applies. So we require them to be non-empty as
|
|
|
|
well.
|
|
|
|
|
|
|
|
-------------------------------------------------------------------*/
|
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
static int
|
|
|
|
UTF8StringValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
ber_len_t count;
|
|
|
|
int len;
|
|
|
|
unsigned char *u = in->bv_val;
|
|
|
|
|
2003-02-28 13:13:29 +08:00
|
|
|
if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
|
|
|
|
/* directory strings cannot be empty */
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-06-24 07:57:53 +08:00
|
|
|
|
2000-05-23 10:33:56 +08:00
|
|
|
for( count = in->bv_len; count > 0; count-=len, u+=len ) {
|
2000-01-30 03:43:19 +08:00
|
|
|
/* get the length indicated by the first byte */
|
2002-01-15 16:27:19 +08:00
|
|
|
len = LDAP_UTF8_CHARLEN2( u, len );
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2002-01-15 12:38:05 +08:00
|
|
|
/* very basic checks */
|
|
|
|
switch( len ) {
|
|
|
|
case 6:
|
2002-01-15 16:27:19 +08:00
|
|
|
if( (u[5] & 0xC0) != 0x80 ) {
|
2002-01-15 12:38:05 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
case 5:
|
2002-01-15 16:27:19 +08:00
|
|
|
if( (u[4] & 0xC0) != 0x80 ) {
|
2002-01-15 12:38:05 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
case 4:
|
2002-01-15 16:27:19 +08:00
|
|
|
if( (u[3] & 0xC0) != 0x80 ) {
|
2002-01-15 12:38:05 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
case 3:
|
2002-01-15 16:27:19 +08:00
|
|
|
if( (u[2] & 0xC0 )!= 0x80 ) {
|
2002-01-15 12:38:05 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
case 2:
|
2002-01-15 16:27:19 +08:00
|
|
|
if( (u[1] & 0xC0) != 0x80 ) {
|
2002-01-15 12:38:05 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
case 1:
|
2002-01-18 12:49:55 +08:00
|
|
|
/* CHARLEN already validated it */
|
2002-01-15 12:38:05 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
/* make sure len corresponds with the offset
|
|
|
|
to the next character */
|
2000-05-25 07:27:33 +08:00
|
|
|
if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
|
|
|
|
2003-02-28 13:13:29 +08:00
|
|
|
if( count != 0 ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-05-25 07:27:33 +08:00
|
|
|
return LDAP_SUCCESS;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
|
|
|
|
2003-02-28 13:13:29 +08:00
|
|
|
static int
|
|
|
|
UTF8StringNormalize(
|
|
|
|
slap_mask_t use,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *val,
|
2003-04-11 09:29:28 +08:00
|
|
|
struct berval *normalized,
|
|
|
|
void *ctx )
|
2003-02-28 13:13:29 +08:00
|
|
|
{
|
|
|
|
struct berval tmp, nvalue;
|
|
|
|
int flags;
|
|
|
|
int i, wasspace;
|
|
|
|
|
|
|
|
if( val->bv_val == NULL ) {
|
|
|
|
/* assume we're dealing with a syntax (e.g., UTF8String)
|
|
|
|
* which allows empty strings
|
|
|
|
*/
|
|
|
|
normalized->bv_len = 0;
|
|
|
|
normalized->bv_val = NULL;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-04-16 18:22:33 +08:00
|
|
|
flags = SLAP_MR_ASSOCIATED( mr, slap_schema.si_mr_caseExactMatch )
|
2003-03-01 04:00:54 +08:00
|
|
|
? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
|
2003-04-04 06:18:17 +08:00
|
|
|
flags |= ( ( use & SLAP_MR_EQUALITY_APPROX ) == SLAP_MR_EQUALITY_APPROX )
|
2003-02-28 13:13:29 +08:00
|
|
|
? LDAP_UTF8_APPROX : 0;
|
|
|
|
|
2003-04-11 11:57:10 +08:00
|
|
|
val = UTF8bvnormalize( val, &tmp, flags, ctx );
|
2003-02-28 13:13:29 +08:00
|
|
|
if( val == NULL ) {
|
|
|
|
return LDAP_OTHER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* collapse spaces (in place) */
|
|
|
|
nvalue.bv_len = 0;
|
|
|
|
nvalue.bv_val = tmp.bv_val;
|
|
|
|
|
|
|
|
wasspace=1; /* trim leading spaces */
|
|
|
|
for( i=0; i<tmp.bv_len; i++) {
|
|
|
|
if ( ASCII_SPACE( tmp.bv_val[i] )) {
|
|
|
|
if( wasspace++ == 0 ) {
|
|
|
|
/* trim repeated spaces */
|
|
|
|
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 ) {
|
|
|
|
/* last character was a space, trim it */
|
|
|
|
--nvalue.bv_len;
|
2003-04-07 09:06:46 +08:00
|
|
|
}
|
|
|
|
nvalue.bv_val[nvalue.bv_len] = '\0';
|
2000-10-25 04:25:37 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
} else {
|
|
|
|
/* string of all spaces is treated as one space */
|
|
|
|
nvalue.bv_val[0] = ' ';
|
|
|
|
nvalue.bv_val[1] = '\0';
|
|
|
|
nvalue.bv_len = 1;
|
|
|
|
}
|
2000-10-25 04:25:37 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
*normalized = nvalue;
|
2000-10-25 04:25:37 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
#ifndef SLAP_NVALUES
|
|
|
|
|
|
|
|
#ifndef SLAPD_APPROX_OLDSINGLESTRING
|
|
|
|
#if defined(SLAPD_APPROX_INITIALS)
|
|
|
|
#define SLAPD_APPROX_DELIMITER "._ "
|
|
|
|
#define SLAPD_APPROX_WORDLEN 2
|
2000-10-25 04:25:37 +08:00
|
|
|
#else
|
2003-04-07 09:06:46 +08:00
|
|
|
#define SLAPD_APPROX_DELIMITER " "
|
|
|
|
#define SLAPD_APPROX_WORDLEN 1
|
|
|
|
#endif
|
2000-10-25 04:25:37 +08:00
|
|
|
|
|
|
|
static int
|
|
|
|
approxMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
2003-04-07 09:06:46 +08:00
|
|
|
struct berval *nval, *assertv;
|
|
|
|
char *val, **values, **words, *c;
|
|
|
|
int i, count, len, nextchunk=0, nextavail=0;
|
2000-10-25 04:25:37 +08:00
|
|
|
|
2001-07-26 05:22:55 +08:00
|
|
|
/* Yes, this is necessary */
|
2003-04-07 09:06:46 +08:00
|
|
|
nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
|
|
|
|
if( nval == NULL ) {
|
2001-07-26 05:22:55 +08:00
|
|
|
*matchp = 1;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Yes, this is necessary */
|
2003-04-07 09:06:46 +08:00
|
|
|
assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
|
|
|
|
NULL, LDAP_UTF8_APPROX );
|
|
|
|
if( assertv == NULL ) {
|
|
|
|
ber_bvfree( nval );
|
|
|
|
*matchp = 1;
|
2001-07-26 05:22:55 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Isolate how many words there are */
|
|
|
|
for ( c = nval->bv_val, count = 1; *c; c++ ) {
|
|
|
|
c = strpbrk( c, SLAPD_APPROX_DELIMITER );
|
|
|
|
if ( c == NULL ) break;
|
|
|
|
*c = '\0';
|
|
|
|
count++;
|
2000-10-25 04:25:37 +08:00
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Get a phonetic copy of each word */
|
|
|
|
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);
|
2001-07-26 05:22:55 +08:00
|
|
|
}
|
2000-10-25 04:25:37 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Work through the asserted value's words, to see if at least some
|
|
|
|
of the words are there, in the same order. */
|
|
|
|
len = 0;
|
|
|
|
while ( (ber_len_t) nextchunk < assertv->bv_len ) {
|
|
|
|
len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
|
|
|
|
if( len == 0 ) {
|
|
|
|
nextchunk++;
|
2003-04-07 02:57:17 +08:00
|
|
|
continue;
|
2000-06-16 03:56:51 +08:00
|
|
|
}
|
2003-04-07 09:06:46 +08:00
|
|
|
#if defined(SLAPD_APPROX_INITIALS)
|
|
|
|
else if( len == 1 ) {
|
|
|
|
/* Single letter words need to at least match one word's initial */
|
|
|
|
for( i=nextavail; i<count; i++ )
|
|
|
|
if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
|
|
|
|
nextavail=i+1;
|
|
|
|
break;
|
|
|
|
}
|
2000-05-28 07:08:28 +08:00
|
|
|
}
|
2003-04-07 09:06:46 +08:00
|
|
|
#endif
|
|
|
|
else {
|
|
|
|
/* Isolate the next word in the asserted value and phonetic it */
|
|
|
|
assertv->bv_val[nextchunk+len] = '\0';
|
|
|
|
val = phonetic( assertv->bv_val + nextchunk );
|
2000-05-28 07:08:28 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* See if this phonetic chunk is in the remaining words of *value */
|
|
|
|
for( i=nextavail; i<count; i++ ){
|
|
|
|
if( !strcmp( val, values[i] ) ){
|
|
|
|
nextavail = i+1;
|
|
|
|
break;
|
|
|
|
}
|
2003-04-07 02:57:17 +08:00
|
|
|
}
|
2003-04-07 09:06:46 +08:00
|
|
|
ch_free( val );
|
2000-06-16 03:32:24 +08:00
|
|
|
}
|
2000-05-28 07:08:28 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* This chunk in the asserted value was NOT within the *value. */
|
|
|
|
if( i >= count ) {
|
|
|
|
nextavail=-1;
|
|
|
|
break;
|
2000-05-28 07:08:28 +08:00
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Go on to the next word in the asserted value */
|
|
|
|
nextchunk += len+1;
|
2003-04-07 02:57:17 +08:00
|
|
|
}
|
2000-06-16 03:56:51 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* If some of the words were seen, call it a match */
|
|
|
|
if( nextavail > 0 ) {
|
|
|
|
*matchp = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*matchp = 1;
|
|
|
|
}
|
2000-08-22 10:23:52 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Cleanup allocs */
|
|
|
|
ber_bvfree( assertv );
|
|
|
|
for( i=0; i<count; i++ ) {
|
|
|
|
ch_free( values[i] );
|
|
|
|
}
|
|
|
|
ch_free( values );
|
|
|
|
ch_free( words );
|
|
|
|
ber_bvfree( nval );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
static int
|
|
|
|
approxIndexer(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
BerVarray values,
|
|
|
|
BerVarray *keysp )
|
|
|
|
{
|
|
|
|
char *c;
|
|
|
|
int i,j, len, wordcount, keycount=0;
|
|
|
|
struct berval *newkeys;
|
|
|
|
BerVarray keys=NULL;
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
for( j=0; values[j].bv_val != NULL; j++ ) {
|
|
|
|
struct berval val = { 0, NULL };
|
|
|
|
/* Yes, this is necessary */
|
|
|
|
UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
|
|
|
|
assert( val.bv_val != NULL );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Isolate how many words there are. There will be a key for each */
|
|
|
|
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';
|
|
|
|
}
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Allocate/increase storage to account for new keys */
|
|
|
|
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;
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Get a phonetic copy of each word */
|
|
|
|
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++;
|
2000-07-19 01:46:34 +08:00
|
|
|
}
|
2001-01-26 23:56:29 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
ber_memfree( val.bv_val );
|
2000-07-19 01:46:34 +08:00
|
|
|
}
|
2003-04-07 09:06:46 +08:00
|
|
|
keys[keycount].bv_val = NULL;
|
|
|
|
*keysp = keys;
|
2000-08-23 05:26:25 +08:00
|
|
|
|
2000-07-19 01:46:34 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-06-21 09:12:29 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
static int
|
|
|
|
approxFilter(
|
2003-04-07 02:57:17 +08:00
|
|
|
slap_mask_t use,
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t flags,
|
2000-07-19 01:46:34 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
2002-08-29 10:27:15 +08:00
|
|
|
void * assertedValue,
|
2002-01-14 09:43:17 +08:00
|
|
|
BerVarray *keysp )
|
2000-07-19 01:46:34 +08:00
|
|
|
{
|
2003-04-07 09:06:46 +08:00
|
|
|
char *c;
|
|
|
|
int i, count, len;
|
|
|
|
struct berval *val;
|
2002-01-14 09:43:17 +08:00
|
|
|
BerVarray keys;
|
2001-07-17 06:48:52 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Yes, this is necessary */
|
|
|
|
val = UTF8bvnormalize( ((struct berval *)assertedValue),
|
|
|
|
NULL, LDAP_UTF8_APPROX );
|
|
|
|
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;
|
2000-07-19 01:46:34 +08:00
|
|
|
}
|
2000-08-22 10:23:52 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Isolate how many words there are. There will be a key for each */
|
|
|
|
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';
|
2000-08-22 10:23:52 +08:00
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Allocate storage for new keys */
|
|
|
|
keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Get a phonetic copy of each word */
|
|
|
|
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++;
|
2000-07-19 01:46:34 +08:00
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
ber_bvfree( val );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
keys[count].bv_val = NULL;
|
|
|
|
*keysp = keys;
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
#else
|
|
|
|
/* No other form of Approximate Matching is defined */
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
static int
|
|
|
|
approxMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
char *vapprox, *avapprox;
|
|
|
|
char *s, *t;
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Yes, this is necessary */
|
|
|
|
s = UTF8normalize( value, UTF8_NOCASEFOLD );
|
|
|
|
if( s == NULL ) {
|
|
|
|
*matchp = 1;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Yes, this is necessary */
|
|
|
|
t = UTF8normalize( ((struct berval *)assertedValue),
|
|
|
|
UTF8_NOCASEFOLD );
|
|
|
|
if( t == NULL ) {
|
|
|
|
free( s );
|
|
|
|
*matchp = -1;
|
|
|
|
return LDAP_SUCCESS;
|
2000-07-19 01:46:34 +08:00
|
|
|
}
|
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
vapprox = phonetic( strip8bitChars( s ) );
|
|
|
|
avapprox = phonetic( strip8bitChars( t ) );
|
|
|
|
|
|
|
|
free( s );
|
|
|
|
free( t );
|
|
|
|
|
|
|
|
*matchp = strcmp( vapprox, avapprox );
|
|
|
|
|
|
|
|
ch_free( vapprox );
|
|
|
|
ch_free( avapprox );
|
|
|
|
|
|
|
|
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 )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
BerVarray *keys;
|
|
|
|
char *s;
|
2000-08-22 10:23:52 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
for( i=0; values[i].bv_val != NULL; i++ ) {
|
|
|
|
/* empty - just count them */
|
|
|
|
}
|
2000-08-22 10:23:52 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* we should have at least one value at this point */
|
|
|
|
assert( i > 0 );
|
2000-08-22 10:23:52 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
|
2000-08-22 10:23:52 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Copy each value and run it through phonetic() */
|
|
|
|
for( i=0; values[i].bv_val != NULL; i++ ) {
|
|
|
|
/* Yes, this is necessary */
|
|
|
|
s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
|
2001-01-26 23:56:29 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* strip 8-bit chars and run through phonetic() */
|
|
|
|
ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
|
|
|
|
free( s );
|
2000-08-22 10:23:52 +08:00
|
|
|
}
|
2003-04-07 09:06:46 +08:00
|
|
|
keys[i].bv_val = NULL;
|
2000-08-22 10:23:52 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
static int
|
|
|
|
approxFilter(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertedValue,
|
|
|
|
BerVarray *keysp )
|
|
|
|
{
|
|
|
|
BerVarray keys;
|
|
|
|
char *s;
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
/* Yes, this is necessary */
|
|
|
|
s = UTF8normalize( ((struct berval *)assertedValue),
|
|
|
|
UTF8_NOCASEFOLD );
|
|
|
|
if( s == NULL ) {
|
|
|
|
keys[0] = NULL;
|
2000-08-23 05:26:25 +08:00
|
|
|
} else {
|
2003-04-07 09:06:46 +08:00
|
|
|
/* strip 8-bit chars and run through phonetic() */
|
|
|
|
keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
|
|
|
|
free( s );
|
|
|
|
keys[1] = NULL;
|
2000-08-23 05:26:25 +08:00
|
|
|
}
|
2003-03-17 07:54:22 +08:00
|
|
|
|
2003-04-07 09:06:46 +08:00
|
|
|
*keysp = keys;
|
2000-07-19 01:46:34 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2003-04-07 09:06:46 +08:00
|
|
|
#endif
|
|
|
|
#endif /* !SLAP_NVALUES */
|
2003-03-02 04:21:39 +08:00
|
|
|
|
2002-03-26 01:08:38 +08:00
|
|
|
/* Remove all spaces and '-' characters */
|
|
|
|
static int
|
2003-03-24 10:16:10 +08:00
|
|
|
telephoneNumberNormalize(
|
|
|
|
slap_mask_t usage,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *val,
|
2003-04-11 09:29:28 +08:00
|
|
|
struct berval *normalized,
|
|
|
|
void *ctx )
|
2002-03-26 01:08:38 +08:00
|
|
|
{
|
|
|
|
char *p, *q;
|
|
|
|
|
2002-08-06 13:35:59 +08:00
|
|
|
/* validator should have refused an empty string */
|
|
|
|
assert( val->bv_len );
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
q = normalized->bv_val = sl_malloc( val->bv_len + 1, ctx );
|
2002-03-26 01:08:38 +08:00
|
|
|
|
2002-08-06 13:35:59 +08:00
|
|
|
for( p = val->bv_val; *p; p++ ) {
|
|
|
|
if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
|
2002-03-26 01:08:38 +08:00
|
|
|
*q++ = *p;
|
2002-08-06 13:35:59 +08:00
|
|
|
}
|
|
|
|
}
|
2002-03-26 01:08:38 +08:00
|
|
|
*q = '\0';
|
|
|
|
|
|
|
|
normalized->bv_len = q - normalized->bv_val;
|
|
|
|
|
2002-08-06 13:35:59 +08:00
|
|
|
if( normalized->bv_len == 0 ) {
|
2003-04-11 09:29:28 +08:00
|
|
|
sl_free( normalized->bv_val, ctx );
|
2002-08-06 13:35:59 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
2002-03-26 01:08:38 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
static int
|
2003-04-25 10:28:06 +08:00
|
|
|
numericoidValidate(
|
2000-09-04 02:04:08 +08:00
|
|
|
Syntax *syntax,
|
2003-04-25 10:28:06 +08:00
|
|
|
struct berval *in )
|
2000-09-04 02:04:08 +08:00
|
|
|
{
|
2003-04-25 10:28:06 +08:00
|
|
|
struct berval val = *in;
|
2000-09-04 02:04:08 +08:00
|
|
|
|
2003-04-25 10:28:06 +08:00
|
|
|
if( val.bv_len == 0 ) {
|
2000-11-11 07:07:20 +08:00
|
|
|
/* disallow empty strings */
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-09-04 02:04:08 +08:00
|
|
|
|
2003-04-25 10:28:06 +08:00
|
|
|
while( OID_LEADCHAR( val.bv_val[0] ) ) {
|
|
|
|
if ( val.bv_len == 1 ) {
|
|
|
|
return LDAP_SUCCESS;
|
2003-04-25 07:40:55 +08:00
|
|
|
}
|
2000-09-04 02:04:08 +08:00
|
|
|
|
2003-04-25 10:28:06 +08:00
|
|
|
if ( val.bv_val[0] == '0' ) {
|
|
|
|
break;
|
|
|
|
}
|
2003-04-25 07:40:55 +08:00
|
|
|
|
2003-04-25 10:28:06 +08:00
|
|
|
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;
|
2000-09-04 02:04:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-04-25 10:28:06 +08:00
|
|
|
if( !OID_SEPARATOR( val.bv_val[0] )) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
val.bv_val++;
|
|
|
|
val.bv_len--;
|
2000-09-04 02:04:08 +08:00
|
|
|
}
|
2003-04-25 10:28:06 +08:00
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
2001-09-20 23:50:49 +08:00
|
|
|
static int
|
2003-04-24 13:16:06 +08:00
|
|
|
integerValidate(
|
2001-09-20 23:50:49 +08:00
|
|
|
Syntax *syntax,
|
2003-04-24 13:16:06 +08:00
|
|
|
struct berval *in )
|
2001-09-20 23:50:49 +08:00
|
|
|
{
|
2003-04-24 13:16:06 +08:00
|
|
|
ber_len_t i;
|
|
|
|
struct berval val = *in;
|
2001-09-20 23:50:49 +08:00
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
if( val.bv_len == 0 ) return LDAP_INVALID_SYNTAX;
|
2001-09-20 23:50:49 +08:00
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
if ( val.bv_val[0] == '-' ) {
|
|
|
|
val.bv_len--;
|
|
|
|
val.bv_val++;
|
2001-09-20 23:50:49 +08:00
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
if( val.bv_len == 0 ) { /* bare "-" */
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-09-04 02:04:08 +08:00
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
if( val.bv_val[0] == '0' ) { /* "-0" */
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-09-04 02:04:08 +08:00
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
} else if ( val.bv_val[0] == '0' ) {
|
2003-04-24 20:43:30 +08:00
|
|
|
if( val.bv_len > 1 ) { /* "0<more>" */
|
2003-04-24 13:16:06 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2003-03-24 14:49:55 +08:00
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
return LDAP_SUCCESS;
|
2000-09-12 08:00:25 +08:00
|
|
|
}
|
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
for( i=0; i < val.bv_len; i++ ) {
|
|
|
|
if( !ASCII_DIGIT(val.bv_val[i]) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-09-04 02:04:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-12 02:34:14 +08:00
|
|
|
static int
|
2003-04-24 13:16:06 +08:00
|
|
|
integerMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
2003-03-24 14:49:55 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
2003-04-24 13:16:06 +08:00
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
2000-09-12 02:34:14 +08:00
|
|
|
{
|
2003-04-24 13:16:06 +08:00
|
|
|
struct berval *asserted = (struct berval *) assertedValue;
|
|
|
|
int vsign = 1, asign = 1; /* default sign = '+' */
|
|
|
|
struct berval v, a;
|
|
|
|
int match;
|
2001-09-20 23:50:49 +08:00
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
v = *value;
|
|
|
|
if( v.bv_val[0] == '-' ) {
|
|
|
|
vsign = -1;
|
|
|
|
v.bv_val++;
|
|
|
|
v.bv_len--;
|
2001-09-20 23:50:49 +08:00
|
|
|
}
|
2000-09-12 02:34:14 +08:00
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
if( v.bv_len == 0 ) vsign = 0;
|
2000-09-12 02:34:14 +08:00
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
a = *asserted;
|
|
|
|
if( a.bv_val[0] == '-' ) {
|
|
|
|
asign = -1;
|
|
|
|
a.bv_val++;
|
|
|
|
a.bv_len--;
|
2001-09-20 23:50:49 +08:00
|
|
|
}
|
2000-09-12 02:34:14 +08:00
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
if( a.bv_len == 0 ) vsign = 0;
|
2003-03-24 14:49:55 +08:00
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
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;
|
2000-09-12 02:34:14 +08:00
|
|
|
}
|
|
|
|
|
2003-04-24 13:16:06 +08:00
|
|
|
*matchp = match;
|
2001-09-20 23:50:49 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2003-04-24 13:16:06 +08:00
|
|
|
|
2000-11-05 05:09:23 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
static int
|
|
|
|
printableStringValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val )
|
|
|
|
{
|
|
|
|
ber_len_t i;
|
|
|
|
|
2002-08-06 13:35:59 +08:00
|
|
|
if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
for(i=0; i < val->bv_len; i++) {
|
2000-11-05 04:31:50 +08:00
|
|
|
if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-09-04 02:04:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-11-05 05:09:23 +08:00
|
|
|
static int
|
|
|
|
printablesStringValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val )
|
|
|
|
{
|
2002-08-06 13:35:59 +08:00
|
|
|
ber_len_t i, len;
|
2000-11-05 05:09:23 +08:00
|
|
|
|
2002-08-06 13:35:59 +08:00
|
|
|
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 {
|
2000-11-05 05:09:23 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-08-17 00:32:42 +08:00
|
|
|
if( len == 0 ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2002-08-06 13:35:59 +08:00
|
|
|
|
2000-11-05 05:09:23 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
static int
|
|
|
|
IA5StringValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val )
|
|
|
|
{
|
|
|
|
ber_len_t i;
|
|
|
|
|
2002-08-06 13:35:59 +08:00
|
|
|
if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
for(i=0; i < val->bv_len; i++) {
|
2002-01-04 04:03:27 +08:00
|
|
|
if( !LDAP_ASCII(val->bv_val[i]) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-09-04 02:04:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-02-28 13:13:29 +08:00
|
|
|
static int
|
|
|
|
IA5StringNormalize(
|
|
|
|
slap_mask_t use,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *val,
|
2003-04-11 09:29:28 +08:00
|
|
|
struct berval *normalized,
|
|
|
|
void *ctx )
|
2000-09-04 02:04:08 +08:00
|
|
|
{
|
|
|
|
char *p, *q;
|
2003-04-28 12:41:47 +08:00
|
|
|
int casefold = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
|
2000-09-04 02:04:08 +08:00
|
|
|
|
2002-08-06 13:35:59 +08:00
|
|
|
assert( val->bv_len );
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
p = val->bv_val;
|
|
|
|
|
|
|
|
/* Ignore initial whitespace */
|
2003-04-28 12:41:47 +08:00
|
|
|
while ( ASCII_SPACE( *p ) ) p++;
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
normalized->bv_val = ber_strdup_x( p, ctx );
|
2003-04-07 02:57:17 +08:00
|
|
|
p = q = normalized->bv_val;
|
|
|
|
|
|
|
|
while ( *p ) {
|
|
|
|
if ( ASCII_SPACE( *p ) ) {
|
|
|
|
*q++ = *p++;
|
|
|
|
|
|
|
|
/* Ignore the extra whitespace */
|
|
|
|
while ( ASCII_SPACE( *p ) ) {
|
|
|
|
p++;
|
2000-07-19 01:46:34 +08:00
|
|
|
}
|
|
|
|
|
2003-04-07 02:57:17 +08:00
|
|
|
} else if ( casefold ) {
|
|
|
|
/* Most IA5 rules require casefolding */
|
|
|
|
*q++ = TOLOWER(*p++);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
*q++ = *p++;
|
2000-07-19 01:46:34 +08:00
|
|
|
}
|
2003-04-07 02:57:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
assert( normalized->bv_val <= p );
|
|
|
|
assert( q <= p );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the string ended in space, backup the pointer one
|
|
|
|
* position. One is enough because the above loop collapsed
|
|
|
|
* all whitespace to a single space.
|
|
|
|
*/
|
2003-04-28 12:41:47 +08:00
|
|
|
if ( ASCII_SPACE( q[-1] ) ) --q;
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2003-04-07 02:57:17 +08:00
|
|
|
/* null terminate */
|
|
|
|
*q = '\0';
|
|
|
|
|
|
|
|
normalized->bv_len = q - normalized->bv_val;
|
|
|
|
if( normalized->bv_len == 0 ) {
|
2003-04-11 09:29:28 +08:00
|
|
|
normalized->bv_val = sl_realloc( normalized->bv_val, 2, ctx );
|
2003-04-07 02:57:17 +08:00
|
|
|
normalized->bv_val[0] = ' ';
|
|
|
|
normalized->bv_val[1] = '\0';
|
|
|
|
normalized->bv_len = 1;
|
2000-08-23 05:26:25 +08:00
|
|
|
}
|
|
|
|
|
2000-07-19 01:46:34 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-01-18 05:02:11 +08:00
|
|
|
static int
|
|
|
|
numericStringValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
ber_len_t i;
|
|
|
|
|
2002-08-06 13:35:59 +08:00
|
|
|
if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
|
|
|
|
|
2001-01-18 05:02:11 +08:00
|
|
|
for(i=0; i < in->bv_len; i++) {
|
|
|
|
if( !SLAP_NUMERIC(in->bv_val[i]) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-05-29 12:58:40 +08:00
|
|
|
static int
|
2003-03-24 10:11:41 +08:00
|
|
|
numericStringNormalize(
|
|
|
|
slap_mask_t usage,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *val,
|
2003-04-11 09:29:28 +08:00
|
|
|
struct berval *normalized,
|
|
|
|
void *ctx )
|
2000-05-29 12:58:40 +08:00
|
|
|
{
|
2001-01-18 05:02:11 +08:00
|
|
|
/* removal all spaces */
|
2000-05-29 12:58:40 +08:00
|
|
|
char *p, *q;
|
|
|
|
|
2002-08-06 13:35:59 +08:00
|
|
|
assert( val->bv_len );
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
normalized->bv_val = sl_malloc( val->bv_len + 1, ctx );
|
2000-05-29 12:58:40 +08:00
|
|
|
|
|
|
|
p = val->bv_val;
|
2001-12-29 23:01:10 +08:00
|
|
|
q = normalized->bv_val;
|
2000-05-29 12:58:40 +08:00
|
|
|
|
|
|
|
while ( *p ) {
|
2000-06-21 01:05:15 +08:00
|
|
|
if ( ASCII_SPACE( *p ) ) {
|
2000-05-29 12:58:40 +08:00
|
|
|
/* Ignore whitespace */
|
|
|
|
p++;
|
|
|
|
} else {
|
|
|
|
*q++ = *p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-07-25 03:54:04 +08:00
|
|
|
/* we should have copied no more then is in val */
|
2001-12-29 23:01:10 +08:00
|
|
|
assert( (q - normalized->bv_val) <= (p - val->bv_val) );
|
2000-05-29 12:58:40 +08:00
|
|
|
|
|
|
|
/* null terminate */
|
|
|
|
*q = '\0';
|
|
|
|
|
2001-12-29 23:01:10 +08:00
|
|
|
normalized->bv_len = q - normalized->bv_val;
|
2000-05-29 12:58:40 +08:00
|
|
|
|
2002-08-06 13:35:59 +08:00
|
|
|
if( normalized->bv_len == 0 ) {
|
2003-04-11 09:29:28 +08:00
|
|
|
normalized->bv_val = sl_realloc( normalized->bv_val, 2, ctx );
|
2002-08-06 13:35:59 +08:00
|
|
|
normalized->bv_val[0] = ' ';
|
|
|
|
normalized->bv_val[1] = '\0';
|
|
|
|
normalized->bv_len = 1;
|
|
|
|
}
|
|
|
|
|
2000-05-29 12:58:40 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-09-02 01:10:43 +08:00
|
|
|
static int
|
|
|
|
integerBitAndMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
long lValue, lAssertedValue;
|
|
|
|
|
|
|
|
/* safe to assume integers are NUL terminated? */
|
2003-01-19 23:20:09 +08:00
|
|
|
lValue = strtol(value->bv_val, NULL, 10);
|
2002-12-12 04:39:05 +08:00
|
|
|
if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
|
2001-09-02 01:10:43 +08:00
|
|
|
return LDAP_CONSTRAINT_VIOLATION;
|
2002-12-12 04:39:05 +08:00
|
|
|
}
|
2001-09-02 01:10:43 +08:00
|
|
|
|
|
|
|
lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
|
2002-12-12 04:39:05 +08:00
|
|
|
if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
|
|
|
|
&& errno == ERANGE )
|
|
|
|
{
|
2001-09-02 01:10:43 +08:00
|
|
|
return LDAP_CONSTRAINT_VIOLATION;
|
2002-12-12 04:39:05 +08:00
|
|
|
}
|
2001-09-02 01:10:43 +08:00
|
|
|
|
2002-08-31 18:56:27 +08:00
|
|
|
*matchp = (lValue & lAssertedValue) ? 0 : 1;
|
2001-09-02 01:10:43 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
integerBitOrMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
long lValue, lAssertedValue;
|
|
|
|
|
|
|
|
/* safe to assume integers are NUL terminated? */
|
2003-01-19 23:20:09 +08:00
|
|
|
lValue = strtol(value->bv_val, NULL, 10);
|
2002-12-12 04:39:05 +08:00
|
|
|
if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
|
2001-09-02 01:10:43 +08:00
|
|
|
return LDAP_CONSTRAINT_VIOLATION;
|
2002-12-12 04:39:05 +08:00
|
|
|
}
|
2001-09-02 01:10:43 +08:00
|
|
|
|
|
|
|
lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
|
2002-12-12 04:39:05 +08:00
|
|
|
if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
|
|
|
|
&& errno == ERANGE )
|
|
|
|
{
|
2001-09-02 01:10:43 +08:00
|
|
|
return LDAP_CONSTRAINT_VIOLATION;
|
2002-12-12 04:39:05 +08:00
|
|
|
}
|
2001-09-02 01:10:43 +08:00
|
|
|
|
2002-08-31 18:56:27 +08:00
|
|
|
*matchp = (lValue | lAssertedValue) ? 0 : -1;
|
2001-09-02 01:10:43 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-02-28 01:35:23 +08:00
|
|
|
#ifndef SLAP_NVALUES
|
2001-10-20 18:15:09 +08:00
|
|
|
#ifdef HAVE_TLS
|
|
|
|
#include <openssl/x509.h>
|
|
|
|
#include <openssl/err.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Next function returns a string representation of a ASN1_INTEGER.
|
|
|
|
* It works for unlimited lengths.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static struct berval *
|
2002-04-16 16:46:25 +08:00
|
|
|
asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
|
2001-10-20 18:15:09 +08:00
|
|
|
{
|
|
|
|
char buf[256];
|
|
|
|
char *p;
|
2002-12-11 00:44:02 +08:00
|
|
|
static char digit[] = "0123456789";
|
2001-10-20 18:15:09 +08:00
|
|
|
|
|
|
|
/* We work backwards, make it fill from the end of buf */
|
|
|
|
p = buf + sizeof(buf) - 1;
|
|
|
|
*p = '\0';
|
|
|
|
|
|
|
|
if ( a == NULL || a->length == 0 ) {
|
|
|
|
*--p = '0';
|
|
|
|
} else {
|
|
|
|
int i;
|
|
|
|
int n = a->length;
|
|
|
|
int base = 0;
|
|
|
|
unsigned int *copy;
|
|
|
|
|
|
|
|
/* We want to preserve the original */
|
|
|
|
copy = ch_malloc(n*sizeof(unsigned int));
|
|
|
|
for (i = 0; i<n; i++) {
|
|
|
|
copy[i] = a->data[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* base indicates the index of the most significant
|
|
|
|
* byte that might be nonzero. When it goes off the
|
|
|
|
* end, we now there is nothing left to do.
|
|
|
|
*/
|
|
|
|
while (base < n) {
|
|
|
|
unsigned int carry;
|
|
|
|
|
|
|
|
carry = 0;
|
|
|
|
for (i = base; i<n; i++ ) {
|
|
|
|
copy[i] += carry*256;
|
|
|
|
carry = copy[i] % 10;
|
|
|
|
copy[i] /= 10;
|
|
|
|
}
|
|
|
|
if (p <= buf+1) {
|
|
|
|
/*
|
|
|
|
* Way too large, we need to leave
|
|
|
|
* room for sign if negative
|
|
|
|
*/
|
2001-11-07 06:36:28 +08:00
|
|
|
free(copy);
|
|
|
|
return NULL;
|
2001-10-20 18:15:09 +08:00
|
|
|
}
|
|
|
|
*--p = digit[carry];
|
2002-12-12 04:39:05 +08:00
|
|
|
|
|
|
|
if (copy[base] == 0) base++;
|
2001-10-20 18:15:09 +08:00
|
|
|
}
|
|
|
|
free(copy);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( a->type == V_ASN1_NEG_INTEGER ) {
|
|
|
|
*--p = '-';
|
|
|
|
}
|
|
|
|
|
2002-04-16 16:46:25 +08:00
|
|
|
return ber_str2bv( p, 0, 1, bv );
|
2001-10-20 18:15:09 +08:00
|
|
|
}
|
|
|
|
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
/*
|
|
|
|
* Given a certificate in DER format, extract the corresponding
|
|
|
|
* assertion value for certificateExactMatch
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
certificateExactConvert(
|
|
|
|
struct berval * in,
|
2001-12-29 23:01:10 +08:00
|
|
|
struct berval * out )
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
{
|
|
|
|
X509 *xcert;
|
|
|
|
unsigned char *p = in->bv_val;
|
2002-04-16 16:46:25 +08:00
|
|
|
struct berval serial;
|
|
|
|
struct berval issuer_dn;
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
|
|
|
|
xcert = d2i_X509(NULL, &p, in->bv_len);
|
|
|
|
if ( !xcert ) {
|
2001-10-23 03:55:21 +08:00
|
|
|
#ifdef NEW_LOGGING
|
2002-07-12 04:33:24 +08:00
|
|
|
LDAP_LOG( CONFIG, ENTRY,
|
|
|
|
"certificateExactConvert: error parsing cert: %s\n",
|
|
|
|
ERR_error_string(ERR_get_error(),NULL), 0, 0 );
|
2001-10-23 03:55:21 +08:00
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
|
|
|
|
"error parsing cert: %s\n",
|
|
|
|
ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
|
|
|
|
#endif
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
2002-04-16 16:46:25 +08:00
|
|
|
if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
|
2001-10-23 17:05:04 +08:00
|
|
|
X509_free(xcert);
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2002-12-12 04:39:05 +08:00
|
|
|
if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
|
|
|
|
!= LDAP_SUCCESS )
|
|
|
|
{
|
2001-10-23 17:05:04 +08:00
|
|
|
X509_free(xcert);
|
2002-04-16 16:46:25 +08:00
|
|
|
ber_memfree(serial.bv_val);
|
2001-10-23 17:05:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
|
|
|
|
X509_free(xcert);
|
|
|
|
|
2002-04-16 16:46:25 +08:00
|
|
|
out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
|
2001-12-29 23:01:10 +08:00
|
|
|
out->bv_val = ch_malloc(out->bv_len);
|
|
|
|
p = out->bv_val;
|
2002-04-16 16:46:25 +08:00
|
|
|
AC_MEMCPY(p, serial.bv_val, serial.bv_len);
|
|
|
|
p += serial.bv_len;
|
2002-01-03 01:06:56 +08:00
|
|
|
AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
p += 3;
|
2002-04-16 16:46:25 +08:00
|
|
|
AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
|
|
|
|
p += issuer_dn.bv_len;
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
*p++ = '\0';
|
|
|
|
|
|
|
|
#ifdef NEW_LOGGING
|
2002-07-12 04:33:24 +08:00
|
|
|
LDAP_LOG( CONFIG, ARGS,
|
|
|
|
"certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
|
|
|
|
"\n\t\"%s\"\n",
|
2001-12-29 23:01:10 +08:00
|
|
|
out->bv_val, NULL, NULL );
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
#endif
|
|
|
|
|
2002-04-16 16:46:25 +08:00
|
|
|
ber_memfree(serial.bv_val);
|
|
|
|
ber_memfree(issuer_dn.bv_val);
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-10-20 18:15:09 +08:00
|
|
|
static int
|
|
|
|
serial_and_issuer_parse(
|
|
|
|
struct berval *assertion,
|
2002-04-16 16:46:25 +08:00
|
|
|
struct berval *serial,
|
2003-04-07 11:46:22 +08:00
|
|
|
struct berval *issuer_dn )
|
2001-10-20 18:15:09 +08:00
|
|
|
{
|
|
|
|
char *begin;
|
|
|
|
char *end;
|
|
|
|
char *p;
|
2001-12-26 14:21:23 +08:00
|
|
|
struct berval bv;
|
2001-10-20 18:15:09 +08:00
|
|
|
|
|
|
|
begin = assertion->bv_val;
|
|
|
|
end = assertion->bv_val+assertion->bv_len-1;
|
2002-12-12 04:39:05 +08:00
|
|
|
for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
|
|
|
|
if ( p > end ) return LDAP_INVALID_SYNTAX;
|
2001-10-20 18:15:09 +08:00
|
|
|
|
2002-12-22 06:54:51 +08:00
|
|
|
/* p now points at the $ sign, now use
|
|
|
|
* begin and end to delimit the serial number
|
|
|
|
*/
|
2002-12-12 04:39:05 +08:00
|
|
|
while (ASCII_SPACE(*begin)) begin++;
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
end = p-1;
|
2002-12-12 04:39:05 +08:00
|
|
|
while (ASCII_SPACE(*end)) end--;
|
2001-10-20 18:15:09 +08:00
|
|
|
|
2002-12-22 06:54:51 +08:00
|
|
|
if( end <= begin ) return LDAP_INVALID_SYNTAX;
|
|
|
|
|
2001-12-26 14:21:23 +08:00
|
|
|
bv.bv_len = end-begin+1;
|
|
|
|
bv.bv_val = begin;
|
2002-04-16 16:46:25 +08:00
|
|
|
ber_dupbv(serial, &bv);
|
2001-10-20 18:15:09 +08:00
|
|
|
|
|
|
|
/* now extract the issuer, remember p was at the dollar sign */
|
2002-12-22 06:54:51 +08:00
|
|
|
begin = p+1;
|
|
|
|
end = assertion->bv_val+assertion->bv_len-1;
|
|
|
|
while (ASCII_SPACE(*begin)) begin++;
|
|
|
|
/* should we trim spaces at the end too? is it safe always? no, no */
|
|
|
|
|
|
|
|
if( end <= begin ) return LDAP_INVALID_SYNTAX;
|
2001-10-20 18:15:09 +08:00
|
|
|
|
2002-12-22 06:54:51 +08:00
|
|
|
if ( issuer_dn ) {
|
2002-04-16 16:46:25 +08:00
|
|
|
bv.bv_len = end-begin+1;
|
|
|
|
bv.bv_val = begin;
|
2002-12-22 06:54:51 +08:00
|
|
|
|
2003-04-30 02:28:14 +08:00
|
|
|
return dnNormalize( 0, NULL, NULL, &bv, issuer_dn );
|
2002-04-16 16:46:25 +08:00
|
|
|
}
|
2001-10-20 18:15:09 +08:00
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
certificateExactMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
X509 *xcert;
|
|
|
|
unsigned char *p = value->bv_val;
|
2002-04-16 16:46:25 +08:00
|
|
|
struct berval serial;
|
|
|
|
struct berval issuer_dn;
|
|
|
|
struct berval asserted_serial;
|
|
|
|
struct berval asserted_issuer_dn;
|
2001-10-20 18:15:09 +08:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
xcert = d2i_X509(NULL, &p, value->bv_len);
|
|
|
|
if ( !xcert ) {
|
2001-10-23 03:55:21 +08:00
|
|
|
#ifdef NEW_LOGGING
|
2002-07-12 04:33:24 +08:00
|
|
|
LDAP_LOG( CONFIG, ENTRY,
|
|
|
|
"certificateExactMatch: error parsing cert: %s\n",
|
|
|
|
ERR_error_string(ERR_get_error(),NULL), 0, 0 );
|
2001-10-23 03:55:21 +08:00
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
|
|
|
|
"error parsing cert: %s\n",
|
|
|
|
ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
|
|
|
|
#endif
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2001-10-20 18:15:09 +08:00
|
|
|
}
|
|
|
|
|
2002-04-16 16:46:25 +08:00
|
|
|
asn1_integer2str(xcert->cert_info->serialNumber, &serial);
|
2002-04-18 20:26:36 +08:00
|
|
|
dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
|
2001-10-20 18:15:09 +08:00
|
|
|
|
|
|
|
X509_free(xcert);
|
|
|
|
|
|
|
|
serial_and_issuer_parse(assertedValue,
|
2002-12-12 04:39:05 +08:00
|
|
|
&asserted_serial, &asserted_issuer_dn);
|
2001-10-20 18:15:09 +08:00
|
|
|
|
|
|
|
ret = integerMatch(
|
|
|
|
matchp,
|
|
|
|
flags,
|
|
|
|
slap_schema.si_syn_integer,
|
|
|
|
slap_schema.si_mr_integerMatch,
|
2002-04-16 16:46:25 +08:00
|
|
|
&serial,
|
|
|
|
&asserted_serial);
|
2001-10-20 18:15:09 +08:00
|
|
|
if ( ret == LDAP_SUCCESS ) {
|
|
|
|
if ( *matchp == 0 ) {
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
/* We need to normalize everything for dnMatch */
|
2001-10-20 18:15:09 +08:00
|
|
|
ret = dnMatch(
|
|
|
|
matchp,
|
|
|
|
flags,
|
|
|
|
slap_schema.si_syn_distinguishedName,
|
|
|
|
slap_schema.si_mr_distinguishedNameMatch,
|
2002-04-16 16:46:25 +08:00
|
|
|
&issuer_dn,
|
|
|
|
&asserted_issuer_dn);
|
2001-10-20 18:15:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
#ifdef NEW_LOGGING
|
2002-07-12 04:33:24 +08:00
|
|
|
LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
|
|
|
|
"%d\n\t\"%s $ %s\"\n",
|
|
|
|
*matchp, serial.bv_val, issuer_dn.bv_val );
|
|
|
|
LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
|
|
|
|
asserted_serial.bv_val, asserted_issuer_dn.bv_val,
|
|
|
|
0 );
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
|
|
|
|
"%d\n\t\"%s $ %s\"\n",
|
2002-04-16 16:46:25 +08:00
|
|
|
*matchp, serial.bv_val, issuer_dn.bv_val );
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
|
2002-04-16 16:46:25 +08:00
|
|
|
asserted_serial.bv_val, asserted_issuer_dn.bv_val,
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
NULL );
|
|
|
|
#endif
|
|
|
|
|
2002-04-16 16:46:25 +08:00
|
|
|
ber_memfree(serial.bv_val);
|
|
|
|
ber_memfree(issuer_dn.bv_val);
|
|
|
|
ber_memfree(asserted_serial.bv_val);
|
|
|
|
ber_memfree(asserted_issuer_dn.bv_val);
|
2001-10-20 18:15:09 +08:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2001-10-23 21:39:07 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Index generation function
|
|
|
|
* We just index the serials, in most scenarios the issuer DN is one of
|
|
|
|
* a very small set of values.
|
|
|
|
*/
|
2001-12-23 09:19:46 +08:00
|
|
|
static int certificateExactIndexer(
|
2001-10-23 21:39:07 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
2002-01-14 09:43:17 +08:00
|
|
|
BerVarray values,
|
|
|
|
BerVarray *keysp )
|
2001-10-23 21:39:07 +08:00
|
|
|
{
|
|
|
|
int i;
|
2002-01-14 09:43:17 +08:00
|
|
|
BerVarray keys;
|
2001-10-23 21:39:07 +08:00
|
|
|
X509 *xcert;
|
|
|
|
unsigned char *p;
|
2002-04-16 16:46:25 +08:00
|
|
|
struct berval serial;
|
2001-10-23 21:39:07 +08:00
|
|
|
|
|
|
|
/* we should have at least one value at this point */
|
2002-01-02 19:00:36 +08:00
|
|
|
assert( values != NULL && values[0].bv_val != NULL );
|
2001-10-23 21:39:07 +08:00
|
|
|
|
2002-01-02 19:00:36 +08:00
|
|
|
for( i=0; values[i].bv_val != NULL; i++ ) {
|
2001-10-23 21:39:07 +08:00
|
|
|
/* empty -- just count them */
|
|
|
|
}
|
|
|
|
|
2001-12-29 23:01:10 +08:00
|
|
|
keys = ch_malloc( sizeof( struct berval ) * (i+1) );
|
2001-10-23 21:39:07 +08:00
|
|
|
|
2002-01-02 19:00:36 +08:00
|
|
|
for( i=0; values[i].bv_val != NULL; i++ ) {
|
|
|
|
p = values[i].bv_val;
|
|
|
|
xcert = d2i_X509(NULL, &p, values[i].bv_len);
|
2001-10-23 21:39:07 +08:00
|
|
|
if ( !xcert ) {
|
|
|
|
#ifdef NEW_LOGGING
|
2002-07-12 04:33:24 +08:00
|
|
|
LDAP_LOG( CONFIG, ENTRY,
|
|
|
|
"certificateExactIndexer: error parsing cert: %s\n",
|
|
|
|
ERR_error_string(ERR_get_error(),NULL), 0, 0);
|
2001-10-23 21:39:07 +08:00
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
|
|
|
|
"error parsing cert: %s\n",
|
|
|
|
ERR_error_string(ERR_get_error(),NULL),
|
|
|
|
NULL, NULL );
|
|
|
|
#endif
|
|
|
|
/* Do we leak keys on error? */
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
2002-04-16 16:46:25 +08:00
|
|
|
asn1_integer2str(xcert->cert_info->serialNumber, &serial);
|
2001-10-23 21:39:07 +08:00
|
|
|
X509_free(xcert);
|
2003-02-27 14:51:53 +08:00
|
|
|
xintegerNormalize( slap_schema.si_syn_integer,
|
2002-12-12 04:39:05 +08:00
|
|
|
&serial, &keys[i] );
|
2002-04-16 16:46:25 +08:00
|
|
|
ber_memfree(serial.bv_val);
|
2001-10-23 21:39:07 +08:00
|
|
|
#ifdef NEW_LOGGING
|
2002-07-12 04:33:24 +08:00
|
|
|
LDAP_LOG( CONFIG, ENTRY,
|
|
|
|
"certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
|
2001-10-23 21:39:07 +08:00
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
|
|
|
|
"returning: %s\n",
|
2001-12-29 23:01:10 +08:00
|
|
|
keys[i].bv_val,
|
2001-10-23 21:39:07 +08:00
|
|
|
NULL, NULL );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2001-12-29 23:01:10 +08:00
|
|
|
keys[i].bv_val = NULL;
|
2001-10-23 21:39:07 +08:00
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Index generation function */
|
|
|
|
/* We think this is always called with a value in matching rule syntax */
|
2001-12-23 09:19:46 +08:00
|
|
|
static int certificateExactFilter(
|
2001-10-23 21:39:07 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
2002-08-29 10:27:15 +08:00
|
|
|
void * assertedValue,
|
2002-01-14 09:43:17 +08:00
|
|
|
BerVarray *keysp )
|
2001-10-23 21:39:07 +08:00
|
|
|
{
|
2002-01-14 09:43:17 +08:00
|
|
|
BerVarray keys;
|
2002-04-16 16:46:25 +08:00
|
|
|
struct berval asserted_serial;
|
2002-12-22 06:54:51 +08:00
|
|
|
int ret;
|
2001-10-23 21:39:07 +08:00
|
|
|
|
2002-12-22 06:54:51 +08:00
|
|
|
ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
|
|
|
|
if( ret != LDAP_SUCCESS ) return ret;
|
2001-10-23 21:39:07 +08:00
|
|
|
|
2001-12-29 23:01:10 +08:00
|
|
|
keys = ch_malloc( sizeof( struct berval ) * 2 );
|
2003-02-27 14:51:53 +08:00
|
|
|
xintegerNormalize( syntax, &asserted_serial, &keys[0] );
|
2001-12-29 23:01:10 +08:00
|
|
|
keys[1].bv_val = NULL;
|
2001-10-23 21:39:07 +08:00
|
|
|
*keysp = keys;
|
|
|
|
|
2002-04-16 16:46:25 +08:00
|
|
|
ber_memfree(asserted_serial.bv_val);
|
2001-10-23 21:39:07 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2001-10-20 18:15:09 +08:00
|
|
|
#endif
|
2003-02-28 01:35:23 +08:00
|
|
|
#endif
|
2001-10-20 18:15:09 +08:00
|
|
|
|
2000-06-15 15:58:04 +08:00
|
|
|
static int
|
|
|
|
check_time_syntax (struct berval *val,
|
|
|
|
int start,
|
|
|
|
int *parts)
|
|
|
|
{
|
|
|
|
static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
|
2000-09-07 03:17:33 +08:00
|
|
|
static int mdays[2][12] = {
|
|
|
|
/* non-leap years */
|
|
|
|
{ 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
|
|
|
|
/* leap years */
|
|
|
|
{ 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
|
|
|
|
};
|
2000-06-15 15:58:04 +08:00
|
|
|
char *p, *e;
|
2000-09-07 03:17:33 +08:00
|
|
|
int part, c, tzoffset, leapyear = 0 ;
|
2000-06-15 15:58:04 +08:00
|
|
|
|
2000-09-07 03:17:33 +08:00
|
|
|
if( val->bv_len == 0 ) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
|
|
|
|
p = (char *)val->bv_val;
|
|
|
|
e = p + val->bv_len;
|
|
|
|
|
|
|
|
/* Ignore initial whitespace */
|
2000-06-21 01:05:15 +08:00
|
|
|
while ( ( p < e ) && ASCII_SPACE( *p ) ) {
|
2000-06-15 15:58:04 +08:00
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
2000-09-07 03:17:33 +08:00
|
|
|
if (e - p < 13 - (2 * start)) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
|
2000-09-07 03:17:33 +08:00
|
|
|
for (part = 0; part < 9; part++) {
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part] = 0;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
|
|
|
|
for (part = start; part < 7; part++) {
|
|
|
|
c = *p;
|
2000-09-07 03:17:33 +08:00
|
|
|
if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
|
2000-06-15 15:58:04 +08:00
|
|
|
part++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
c -= '0';
|
2000-09-07 03:17:33 +08:00
|
|
|
if (p == e) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
|
|
|
if (c < 0 || c > 9) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part] = c;
|
|
|
|
|
|
|
|
c = *p++ - '0';
|
2000-09-07 03:17:33 +08:00
|
|
|
if (p == e) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
|
|
|
if (c < 0 || c > 9) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part] *= 10;
|
|
|
|
parts[part] += c;
|
|
|
|
|
2000-09-07 03:17:33 +08:00
|
|
|
if (part == 2 || part == 3) {
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part]--;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
|
|
|
if (parts[part] < 0) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
|
|
|
if (parts[part] > ceiling[part]) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
2000-09-07 03:17:33 +08:00
|
|
|
|
|
|
|
/* leapyear check for the Gregorian calendar (year>1581) */
|
|
|
|
if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
|
|
|
|
((parts[0] % 4 == 0) && (parts[1] == 0)))
|
|
|
|
{
|
|
|
|
leapyear = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parts[3] > mdays[leapyear][parts[2]]) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
2000-06-15 15:58:04 +08:00
|
|
|
c = *p++;
|
|
|
|
if (c == 'Z') {
|
2000-09-07 03:17:33 +08:00
|
|
|
tzoffset = 0; /* UTC */
|
2000-06-15 15:58:04 +08:00
|
|
|
} else if (c != '+' && c != '-') {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
} else {
|
2000-09-07 03:17:33 +08:00
|
|
|
if (c == '-') {
|
|
|
|
tzoffset = -1;
|
|
|
|
} else /* c == '+' */ {
|
|
|
|
tzoffset = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p > e - 4) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
|
|
|
|
2000-06-15 15:58:04 +08:00
|
|
|
for (part = 7; part < 9; part++) {
|
|
|
|
c = *p++ - '0';
|
2000-09-07 03:17:33 +08:00
|
|
|
if (c < 0 || c > 9) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part] = c;
|
|
|
|
|
|
|
|
c = *p++ - '0';
|
2000-09-07 03:17:33 +08:00
|
|
|
if (c < 0 || c > 9) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part] *= 10;
|
|
|
|
parts[part] += c;
|
2000-09-07 03:17:33 +08:00
|
|
|
if (parts[part] < 0 || parts[part] > ceiling[part]) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ignore trailing whitespace */
|
2000-06-21 01:05:15 +08:00
|
|
|
while ( ( p < e ) && ASCII_SPACE( *p ) ) {
|
2000-06-15 15:58:04 +08:00
|
|
|
p++;
|
|
|
|
}
|
2000-09-07 03:17:33 +08:00
|
|
|
if (p != e) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
|
2000-09-07 03:17:33 +08:00
|
|
|
switch ( tzoffset ) {
|
2001-01-18 00:35:53 +08:00
|
|
|
case -1: /* negativ offset to UTC, ie west of Greenwich */
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[4] += parts[7];
|
|
|
|
parts[5] += parts[8];
|
2000-09-07 03:17:33 +08:00
|
|
|
for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
|
|
|
|
if (part != 3) {
|
2000-06-15 15:58:04 +08:00
|
|
|
c = ceiling[part];
|
2000-09-07 03:17:33 +08:00
|
|
|
} else {
|
|
|
|
c = mdays[leapyear][parts[2]];
|
2000-06-15 15:58:04 +08:00
|
|
|
}
|
|
|
|
if (parts[part] > c) {
|
|
|
|
parts[part] -= c + 1;
|
|
|
|
parts[part - 1]++;
|
|
|
|
}
|
|
|
|
}
|
2000-09-07 03:17:33 +08:00
|
|
|
break;
|
|
|
|
case 1: /* positive offset to UTC, ie east of Greenwich */
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[4] -= parts[7];
|
|
|
|
parts[5] -= parts[8];
|
2000-09-07 03:17:33 +08:00
|
|
|
for (part = 6; --part > 0; ) {
|
|
|
|
if (part != 3) {
|
2000-06-15 15:58:04 +08:00
|
|
|
c = ceiling[part];
|
2000-09-07 03:17:33 +08:00
|
|
|
} else {
|
|
|
|
/* first arg to % needs to be non negativ */
|
|
|
|
c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
|
2000-06-15 15:58:04 +08:00
|
|
|
}
|
|
|
|
if (parts[part] < 0) {
|
|
|
|
parts[part] += c + 1;
|
|
|
|
parts[part - 1]--;
|
|
|
|
}
|
|
|
|
}
|
2000-09-07 03:17:33 +08:00
|
|
|
break;
|
|
|
|
case 0: /* already UTC */
|
|
|
|
break;
|
2000-06-15 15:58:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2002-03-24 10:17:21 +08:00
|
|
|
#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
|
2000-06-15 15:58:04 +08:00
|
|
|
static int
|
2003-02-27 14:51:53 +08:00
|
|
|
xutcTimeNormalize(
|
2000-06-15 15:58:04 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val,
|
2001-12-29 23:01:10 +08:00
|
|
|
struct berval *normalized )
|
2000-06-15 15:58:04 +08:00
|
|
|
{
|
|
|
|
int parts[9], rc;
|
|
|
|
|
|
|
|
rc = check_time_syntax(val, 1, parts);
|
|
|
|
if (rc != LDAP_SUCCESS) {
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2001-12-29 23:01:10 +08:00
|
|
|
normalized->bv_val = ch_malloc( 14 );
|
|
|
|
if ( normalized->bv_val == NULL ) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LBER_ERROR_MEMORY;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
|
2001-12-29 23:01:10 +08:00
|
|
|
sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
|
2000-09-07 03:17:33 +08:00
|
|
|
parts[1], parts[2] + 1, parts[3] + 1,
|
|
|
|
parts[4], parts[5], parts[6] );
|
2001-12-29 23:01:10 +08:00
|
|
|
normalized->bv_len = 13;
|
2000-06-15 15:58:04 +08:00
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
utcTimeValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
int parts[9];
|
|
|
|
return check_time_syntax(in, 1, parts);
|
|
|
|
}
|
2002-03-24 10:17:21 +08:00
|
|
|
#endif
|
2000-06-15 15:58:04 +08:00
|
|
|
|
2000-06-30 10:18:58 +08:00
|
|
|
static int
|
|
|
|
generalizedTimeValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
int parts[9];
|
|
|
|
return check_time_syntax(in, 0, parts);
|
|
|
|
}
|
|
|
|
|
2000-06-15 15:58:04 +08:00
|
|
|
static int
|
2003-03-24 14:49:55 +08:00
|
|
|
generalizedTimeNormalize(
|
|
|
|
slap_mask_t usage,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *val,
|
2003-04-11 09:29:28 +08:00
|
|
|
struct berval *normalized,
|
|
|
|
void *ctx )
|
2000-06-15 15:58:04 +08:00
|
|
|
{
|
|
|
|
int parts[9], rc;
|
|
|
|
|
|
|
|
rc = check_time_syntax(val, 0, parts);
|
|
|
|
if (rc != LDAP_SUCCESS) {
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2003-04-11 09:29:28 +08:00
|
|
|
normalized->bv_val = sl_malloc( 16, ctx );
|
2001-12-29 23:01:10 +08:00
|
|
|
if ( normalized->bv_val == NULL ) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LBER_ERROR_MEMORY;
|
|
|
|
}
|
|
|
|
|
2001-12-29 23:01:10 +08:00
|
|
|
sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
|
2000-09-07 03:17:33 +08:00
|
|
|
parts[0], parts[1], parts[2] + 1, parts[3] + 1,
|
|
|
|
parts[4], parts[5], parts[6] );
|
2001-12-29 23:01:10 +08:00
|
|
|
normalized->bv_len = 15;
|
2000-06-15 15:58:04 +08:00
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-04 01:35:39 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2002-01-03 01:06:56 +08:00
|
|
|
for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
|
2000-09-04 01:35:39 +08:00
|
|
|
if ( *p == ',' ) {
|
|
|
|
commas++;
|
|
|
|
if ( commas > 2 ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
2002-07-24 23:19:40 +08:00
|
|
|
} else if ( !AD_CHAR( *p ) ) {
|
2000-09-04 01:35:39 +08:00
|
|
|
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;
|
|
|
|
|
|
|
|
/* key */
|
|
|
|
for (; ( p < e ) && ( *p != '=' ); p++ ) {
|
2002-07-24 23:19:40 +08:00
|
|
|
if ( !AD_CHAR( *p ) ) {
|
2000-09-04 01:35:39 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( *p != '=' ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* server */
|
|
|
|
for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
|
2002-07-24 23:19:40 +08:00
|
|
|
if ( !AD_CHAR( *p ) ) {
|
2000-09-04 01:35:39 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( *p != ':' ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* path */
|
|
|
|
for ( p++; p < e; p++ ) {
|
2002-07-24 23:29:22 +08:00
|
|
|
if ( !SLAP_PRINTABLE( *p ) ) {
|
2000-09-04 01:35:39 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-04-28 12:41:47 +08:00
|
|
|
static int
|
|
|
|
firstComponentNormalize(
|
|
|
|
slap_mask_t usage,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *val,
|
|
|
|
struct berval *normalized,
|
|
|
|
void *ctx )
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct berval oid;
|
|
|
|
ber_len_t len;
|
|
|
|
|
|
|
|
if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
|
|
|
|
|
|
|
|
if( val->bv_val[0] != '(' /*')'*/ &&
|
|
|
|
val->bv_val[0] != '{' /*'}'*/ )
|
|
|
|
{
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* trim leading white space */
|
|
|
|
for( len=1;
|
|
|
|
len < val->bv_len && ASCII_SPACE(val->bv_val[len]);
|
|
|
|
len++ )
|
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* grab next word */
|
|
|
|
oid.bv_val = &val->bv_val[len];
|
|
|
|
len = val->bv_len - len;
|
|
|
|
for( oid.bv_len=0;
|
|
|
|
!ASCII_SPACE(oid.bv_val[oid.bv_len]) && oid.bv_len < len;
|
|
|
|
oid.bv_len++ )
|
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
|
|
|
if( mr == slap_schema.si_mr_objectIdentifierFirstComponentMatch ) {
|
|
|
|
rc = numericoidValidate( NULL, &oid );
|
|
|
|
} else if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
|
|
|
|
rc = integerValidate( NULL, &oid );
|
|
|
|
} else {
|
|
|
|
rc = LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( rc == LDAP_SUCCESS ) {
|
|
|
|
ber_dupbv_x( normalized, &oid, ctx );
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2001-12-23 09:19:46 +08:00
|
|
|
#define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
|
|
|
|
#define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
|
2002-08-17 09:29:18 +08:00
|
|
|
|
|
|
|
static slap_syntax_defs_rec syntax_defs[] = {
|
2002-01-06 12:59:26 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
|
|
|
|
X_BINARY X_NOT_H_R ")",
|
2003-04-07 03:16:49 +08:00
|
|
|
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL},
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2002-01-06 12:59:26 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
|
|
|
|
X_NOT_H_R ")",
|
2003-04-07 03:16:49 +08:00
|
|
|
SLAP_SYNTAX_BLOB, blobValidate, NULL},
|
2002-01-06 12:59:26 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
|
|
|
|
X_NOT_H_R ")",
|
2003-04-07 03:16:49 +08:00
|
|
|
SLAP_SYNTAX_BER, berValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, bitStringValidate, NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, booleanValidate, NULL},
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
|
|
|
|
X_BINARY X_NOT_H_R ")",
|
2003-04-07 03:16:49 +08:00
|
|
|
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL},
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
|
|
|
|
X_BINARY X_NOT_H_R ")",
|
2003-04-07 03:16:49 +08:00
|
|
|
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL},
|
2000-05-19 08:33:09 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
|
|
|
|
X_BINARY X_NOT_H_R ")",
|
2003-04-07 03:16:49 +08:00
|
|
|
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, countryStringValidate, NULL},
|
2000-05-29 08:27:49 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
|
2003-04-30 02:13:10 +08:00
|
|
|
0, dnValidate, dnPretty},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, UTF8StringValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, printablesStringValidate, NULL},
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
|
2003-04-07 03:16:49 +08:00
|
|
|
SLAP_SYNTAX_BLOB, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, generalizedTimeValidate, NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, IA5StringValidate, NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, integerValidate, NULL},
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
|
2003-04-07 03:16:49 +08:00
|
|
|
SLAP_SYNTAX_BLOB, blobValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, nameUIDValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, numericStringValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
|
2003-04-25 10:28:06 +08:00
|
|
|
0, numericoidValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, IA5StringValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, blobValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, UTF8StringValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, printableStringValidate, NULL},
|
2003-04-23 04:33:08 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' )",
|
2003-04-23 04:35:41 +08:00
|
|
|
#define subtreeSpecificationValidate UTF8StringValidate /* FIXME */
|
2003-04-23 04:33:08 +08:00
|
|
|
0, subtreeSpecificationValidate, NULL},
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
|
|
|
|
X_BINARY X_NOT_H_R ")",
|
2003-04-07 03:16:49 +08:00
|
|
|
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, printableStringValidate, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, printablesStringValidate, NULL},
|
2002-03-24 10:17:21 +08:00
|
|
|
#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, utcTimeValidate, NULL},
|
2002-03-24 10:17:21 +08:00
|
|
|
#endif
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, NULL, NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-08-25 03:54:16 +08:00
|
|
|
/* RFC 2307 NIS Syntaxes */
|
2000-09-12 08:32:08 +08:00
|
|
|
{"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, nisNetgroupTripleValidate, NULL},
|
2000-08-25 03:54:16 +08:00
|
|
|
{"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, bootParameterValidate, NULL},
|
2000-08-25 03:54:16 +08:00
|
|
|
|
2001-10-20 18:15:09 +08:00
|
|
|
#ifdef HAVE_TLS
|
|
|
|
/* From PKIX */
|
2001-10-21 01:31:52 +08:00
|
|
|
/* These OIDs are not published yet, but will be in the next
|
|
|
|
* I-D for PKIX LDAPv3 schema as have been advanced by David
|
|
|
|
* Chadwick in private mail.
|
|
|
|
*/
|
|
|
|
{"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
0, UTF8StringValidate, NULL},
|
2001-10-20 18:15:09 +08:00
|
|
|
#endif
|
|
|
|
|
2000-02-02 02:05:49 +08:00
|
|
|
/* OpenLDAP Experimental Syntaxes */
|
2002-02-19 04:06:50 +08:00
|
|
|
#ifdef SLAPD_ACI_ENABLED
|
2000-05-28 03:33:08 +08:00
|
|
|
{"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
|
2001-12-02 12:48:06 +08:00
|
|
|
SLAP_SYNTAX_HIDE,
|
|
|
|
UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
|
2003-04-07 03:16:49 +08:00
|
|
|
NULL},
|
2002-02-19 04:06:50 +08:00
|
|
|
#endif
|
2001-12-02 12:48:06 +08:00
|
|
|
|
2002-01-10 08:17:21 +08:00
|
|
|
#ifdef SLAPD_AUTHPASSWD
|
2001-12-02 12:48:06 +08:00
|
|
|
/* needs updating */
|
2000-05-31 05:34:55 +08:00
|
|
|
{"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
|
2003-04-07 03:16:49 +08:00
|
|
|
SLAP_SYNTAX_HIDE, NULL, NULL},
|
2002-01-10 08:17:21 +08:00
|
|
|
#endif
|
2000-02-02 02:05:49 +08:00
|
|
|
|
2000-08-27 03:52:21 +08:00
|
|
|
/* OpenLDAP Void Syntax */
|
2000-10-17 07:47:46 +08:00
|
|
|
{"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
|
2003-04-07 03:16:49 +08:00
|
|
|
SLAP_SYNTAX_HIDE, inValidate, NULL},
|
|
|
|
{NULL, 0, NULL, NULL}
|
2000-01-30 03:43:19 +08:00
|
|
|
};
|
|
|
|
|
2002-09-01 04:42:25 +08:00
|
|
|
#ifdef HAVE_TLS
|
|
|
|
char *certificateExactMatchSyntaxes[] = {
|
2002-09-03 15:01:09 +08:00
|
|
|
"1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
|
|
|
|
NULL
|
|
|
|
};
|
2002-09-01 04:42:25 +08:00
|
|
|
#endif
|
2002-09-03 15:01:09 +08:00
|
|
|
char *directoryStringSyntaxes[] = {
|
|
|
|
"1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
char *integerFirstComponentMatchSyntaxes[] = {
|
|
|
|
"1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
|
|
|
|
"1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
char *objectIdentifierFirstComponentMatchSyntaxes[] = {
|
|
|
|
"1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
|
|
|
|
"1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
|
|
|
|
"1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
|
|
|
|
"1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
|
|
|
|
"1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
|
|
|
|
"1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
|
|
|
|
"1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
|
|
|
|
"1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
|
|
|
|
NULL
|
|
|
|
};
|
2002-09-01 04:42:25 +08:00
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
/*
|
2000-07-03 00:36:21 +08:00
|
|
|
* Other matching rules in X.520 that we do not use (yet):
|
2000-01-30 03:43:19 +08:00
|
|
|
*
|
|
|
|
* 2.5.13.9 numericStringOrderingMatch
|
|
|
|
* 2.5.13.25 uTCTimeMatch
|
|
|
|
* 2.5.13.26 uTCTimeOrderingMatch
|
|
|
|
* 2.5.13.31 directoryStringFirstComponentMatch
|
|
|
|
* 2.5.13.32 wordMatch
|
|
|
|
* 2.5.13.33 keywordMatch
|
|
|
|
* 2.5.13.35 certificateMatch
|
|
|
|
* 2.5.13.36 certificatePairExactMatch
|
|
|
|
* 2.5.13.37 certificatePairMatch
|
|
|
|
* 2.5.13.38 certificateListExactMatch
|
|
|
|
* 2.5.13.39 certificateListMatch
|
|
|
|
* 2.5.13.40 algorithmIdentifierMatch
|
|
|
|
* 2.5.13.41 storedPrefixMatch
|
|
|
|
* 2.5.13.42 attributeCertificateMatch
|
|
|
|
* 2.5.13.43 readerAndKeyIDMatch
|
|
|
|
* 2.5.13.44 attributeIntegrityMatch
|
|
|
|
*/
|
2002-08-17 09:29:18 +08:00
|
|
|
static slap_mrule_defs_rec mrule_defs[] = {
|
2000-07-25 05:29:30 +08:00
|
|
|
/*
|
|
|
|
* EQUALITY matching rules must be listed after associated APPROX
|
|
|
|
* matching rules. So, we list all APPROX matching rules first.
|
|
|
|
*/
|
2003-02-27 14:51:53 +08:00
|
|
|
#ifndef SLAP_NVALUES
|
2000-07-25 05:29:30 +08:00
|
|
|
{"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
|
2003-02-27 14:51:53 +08:00
|
|
|
NULL, NULL, directoryStringApproxMatch,
|
|
|
|
directoryStringApproxIndexer, directoryStringApproxFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
|
|
|
|
|
|
|
{"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
|
2003-02-27 14:51:53 +08:00
|
|
|
NULL, NULL, IA5StringApproxMatch,
|
|
|
|
IA5StringApproxIndexer, IA5StringApproxFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
2003-02-27 14:51:53 +08:00
|
|
|
#endif
|
2000-07-25 05:29:30 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Other matching rules
|
|
|
|
*/
|
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 2.5.13.0 NAME 'objectIdentifierMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-25 10:28:06 +08:00
|
|
|
NULL, NULL, octetStringMatch,
|
2003-04-07 09:06:46 +08:00
|
|
|
octetStringIndexer, octetStringFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.1 NAME 'distinguishedNameMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-07 09:19:47 +08:00
|
|
|
NULL, dnNormalize, dnMatch,
|
2003-04-07 09:06:46 +08:00
|
|
|
octetStringIndexer, octetStringFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.2 NAME 'caseIgnoreMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
|
2003-04-07 09:19:47 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
|
|
|
|
NULL, UTF8StringNormalize, octetStringMatch,
|
2003-04-07 09:06:46 +08:00
|
|
|
octetStringIndexer, octetStringFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
directoryStringApproxMatchOID },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
|
2002-09-03 15:01:09 +08:00
|
|
|
SLAP_MR_ORDERING, directoryStringSyntaxes,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, UTF8StringNormalize, octetStringOrderingMatch,
|
|
|
|
NULL, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
"caseIgnoreMatch" },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_SUBSTR, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, UTF8StringNormalize, octetStringSubstringsMatch,
|
|
|
|
octetStringSubstringsIndexer, octetStringSubstringsFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
"caseIgnoreMatch" },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.5 NAME 'caseExactMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
|
2002-09-03 15:01:09 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, UTF8StringNormalize, octetStringMatch,
|
|
|
|
octetStringIndexer, octetStringFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
directoryStringApproxMatchOID },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
|
2002-09-03 15:01:09 +08:00
|
|
|
SLAP_MR_ORDERING, directoryStringSyntaxes,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, UTF8StringNormalize, octetStringOrderingMatch,
|
|
|
|
NULL, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
"caseExactMatch" },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
|
2002-09-03 15:01:09 +08:00
|
|
|
SLAP_MR_SUBSTR, directoryStringSyntaxes,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, UTF8StringNormalize, octetStringSubstringsMatch,
|
|
|
|
octetStringSubstringsIndexer, octetStringSubstringsFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
"caseExactMatch" },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.8 NAME 'numericStringMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
|
2003-04-07 02:57:17 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, numericStringNormalize, octetStringSubstringsMatch,
|
|
|
|
octetStringSubstringsIndexer, octetStringSubstringsFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_SUBSTR, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, numericStringNormalize, octetStringSubstringsMatch,
|
|
|
|
octetStringSubstringsIndexer, octetStringSubstringsFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
"numericStringMatch" },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
|
2003-04-07 02:57:17 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL, NULL, NULL, NULL, NULL, NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-05-17 02:11:50 +08:00
|
|
|
{"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_SUBSTR, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL, NULL, NULL, NULL, NULL,
|
|
|
|
"caseIgnoreListMatch" },
|
2000-05-17 02:11:50 +08:00
|
|
|
|
2000-06-30 03:00:17 +08:00
|
|
|
{"( 2.5.13.13 NAME 'booleanMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, NULL, booleanMatch,
|
|
|
|
octetStringIndexer, octetStringFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-06-30 03:00:17 +08:00
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 2.5.13.14 NAME 'integerMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-24 13:16:06 +08:00
|
|
|
NULL, NULL, integerMatch,
|
2003-04-07 09:06:46 +08:00
|
|
|
octetStringIndexer, octetStringFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2002-03-26 01:08:38 +08:00
|
|
|
{"( 2.5.13.15 NAME 'integerOrderingMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
|
2003-04-07 09:06:46 +08:00
|
|
|
SLAP_MR_ORDERING, NULL,
|
2003-04-24 13:16:06 +08:00
|
|
|
NULL, NULL, integerMatch,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
"integerMatch" },
|
2002-03-26 01:08:38 +08:00
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 2.5.13.16 NAME 'bitStringMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, NULL, octetStringMatch,
|
|
|
|
octetStringIndexer, octetStringFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.17 NAME 'octetStringMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, NULL, octetStringMatch,
|
|
|
|
octetStringIndexer, octetStringFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2002-09-04 10:00:42 +08:00
|
|
|
{"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
|
|
|
|
SLAP_MR_ORDERING, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, NULL, octetStringOrderingMatch,
|
2002-09-04 10:00:42 +08:00
|
|
|
NULL, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
"octetStringMatch" },
|
2002-09-04 10:00:42 +08:00
|
|
|
|
2003-03-01 09:27:09 +08:00
|
|
|
{"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
|
|
|
|
SLAP_MR_SUBSTR, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, NULL, octetStringSubstringsMatch,
|
|
|
|
octetStringSubstringsIndexer, octetStringSubstringsFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
"octetStringMatch" },
|
2003-03-01 09:27:09 +08:00
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 2.5.13.20 NAME 'telephoneNumberMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
|
2003-04-07 02:57:17 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-02-27 14:51:53 +08:00
|
|
|
NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
telephoneNumberNormalize, octetStringMatch,
|
|
|
|
octetStringIndexer, octetStringFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_SUBSTR, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, telephoneNumberNormalize, octetStringSubstringsMatch,
|
|
|
|
octetStringSubstringsIndexer, octetStringSubstringsFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
"telephoneNumberMatch" },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.22 NAME 'presentationAddressMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL, NULL, NULL, NULL, NULL, NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.23 NAME 'uniqueMemberMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, uniqueMemberNormalize, uniqueMemberMatch,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.24 NAME 'protocolInformationMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL, NULL, NULL, NULL, NULL, NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.27 NAME 'generalizedTimeMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, generalizedTimeNormalize, octetStringMatch,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_ORDERING, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, generalizedTimeNormalize, octetStringOrderingMatch,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
"generalizedTimeMatch" },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
|
2003-04-24 13:16:06 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
|
|
|
integerFirstComponentMatchSyntaxes,
|
2003-04-28 12:41:47 +08:00
|
|
|
NULL, firstComponentNormalize, integerMatch,
|
2003-04-24 13:16:06 +08:00
|
|
|
octetStringIndexer, octetStringFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
|
2002-09-03 15:01:09 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
|
|
|
objectIdentifierFirstComponentMatchSyntaxes,
|
2003-04-28 12:41:47 +08:00
|
|
|
NULL, firstComponentNormalize, octetStringMatch,
|
2003-04-07 09:06:46 +08:00
|
|
|
octetStringIndexer, octetStringFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2003-02-28 01:35:23 +08:00
|
|
|
#ifndef SLAP_NVALUES
|
2001-10-20 18:15:09 +08:00
|
|
|
#ifdef HAVE_TLS
|
|
|
|
{"( 2.5.13.34 NAME 'certificateExactMatch' "
|
2001-10-21 01:31:52 +08:00
|
|
|
"SYNTAX 1.2.826.0.1.3344810.7.1 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
|
2003-04-07 09:06:46 +08:00
|
|
|
certificateExactConvert, NULL, certificateExactMatch,
|
2001-10-23 21:39:07 +08:00
|
|
|
certificateExactIndexer, certificateExactFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
NULL },
|
2003-02-27 14:51:53 +08:00
|
|
|
#endif
|
2001-10-20 18:15:09 +08:00
|
|
|
#endif
|
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, IA5StringNormalize, octetStringMatch,
|
|
|
|
octetStringIndexer, octetStringFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
IA5StringApproxMatchOID },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
|
2003-04-07 02:57:17 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, IA5StringNormalize, octetStringMatch,
|
|
|
|
octetStringIndexer, octetStringFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
IA5StringApproxMatchOID },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_SUBSTR, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, IA5StringNormalize, octetStringSubstringsMatch,
|
|
|
|
octetStringSubstringsIndexer, octetStringSubstringsFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
"caseIgnoreIA5Match" },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-08-27 02:49:50 +08:00
|
|
|
{"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
|
2000-07-03 00:36:21 +08:00
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_SUBSTR, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, IA5StringNormalize, octetStringSubstringsMatch,
|
|
|
|
octetStringSubstringsIndexer, octetStringSubstringsFilter,
|
2003-04-16 13:56:28 +08:00
|
|
|
"caseExactIA5Match" },
|
2000-07-03 00:36:21 +08:00
|
|
|
|
2002-01-10 08:17:21 +08:00
|
|
|
#ifdef SLAPD_AUTHPASSWD
|
2001-12-02 12:48:06 +08:00
|
|
|
/* needs updating */
|
2000-05-31 05:34:55 +08:00
|
|
|
{"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, NULL, authPasswordMatch,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
NULL},
|
2002-01-10 08:17:21 +08:00
|
|
|
#endif
|
2000-05-31 05:34:55 +08:00
|
|
|
|
2002-02-19 04:06:50 +08:00
|
|
|
#ifdef SLAPD_ACI_ENABLED
|
2000-05-31 05:34:55 +08:00
|
|
|
{"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EQUALITY, NULL,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, NULL, OpenLDAPaciMatch,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
NULL},
|
2002-02-19 04:06:50 +08:00
|
|
|
#endif
|
2000-05-31 05:34:55 +08:00
|
|
|
|
2001-09-02 01:10:43 +08:00
|
|
|
{"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EXT, NULL,
|
2003-04-24 13:16:06 +08:00
|
|
|
NULL, NULL, integerBitAndMatch,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
"integerMatch" },
|
2001-09-02 01:10:43 +08:00
|
|
|
|
|
|
|
{"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
|
2002-09-01 04:42:25 +08:00
|
|
|
SLAP_MR_EXT, NULL,
|
2003-04-24 13:16:06 +08:00
|
|
|
NULL, NULL, integerBitOrMatch,
|
2003-04-07 09:06:46 +08:00
|
|
|
NULL, NULL,
|
2003-04-16 13:56:28 +08:00
|
|
|
"integerMatch" },
|
2001-09-02 01:10:43 +08:00
|
|
|
|
2002-09-01 04:42:25 +08:00
|
|
|
{NULL, SLAP_MR_NONE, NULL,
|
|
|
|
NULL, NULL, NULL, NULL, NULL,
|
|
|
|
NULL }
|
2000-01-30 03:43:19 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
int
|
2002-01-10 08:17:21 +08:00
|
|
|
slap_schema_init( void )
|
2000-01-30 03:43:19 +08:00
|
|
|
{
|
|
|
|
int res;
|
2003-04-07 11:46:22 +08:00
|
|
|
int i;
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-05-16 04:04:36 +08:00
|
|
|
/* we should only be called once (from main) */
|
|
|
|
assert( schema_init_done == 0 );
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
|
2002-08-17 09:29:18 +08:00
|
|
|
res = register_syntax( &syntax_defs[i] );
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
if ( res ) {
|
2002-01-10 08:17:21 +08:00
|
|
|
fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
|
2000-01-30 03:43:19 +08:00
|
|
|
syntax_defs[i].sd_desc );
|
2000-05-25 07:27:33 +08:00
|
|
|
return LDAP_OTHER;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
|
2002-09-01 04:42:25 +08:00
|
|
|
if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
|
|
|
|
mrule_defs[i].mrd_compat_syntaxes == NULL )
|
|
|
|
{
|
2000-02-15 04:57:34 +08:00
|
|
|
fprintf( stderr,
|
2003-02-27 11:29:07 +08:00
|
|
|
"slap_schema_init: Ignoring unusable matching rule %s\n",
|
2000-02-15 04:57:34 +08:00
|
|
|
mrule_defs[i].mrd_desc );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2002-08-17 09:29:18 +08:00
|
|
|
res = register_matching_rule( &mrule_defs[i] );
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
if ( res ) {
|
|
|
|
fprintf( stderr,
|
2002-01-10 08:17:21 +08:00
|
|
|
"slap_schema_init: Error registering matching rule %s\n",
|
2000-01-30 03:43:19 +08:00
|
|
|
mrule_defs[i].mrd_desc );
|
2000-05-25 07:27:33 +08:00
|
|
|
return LDAP_OTHER;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
|
|
|
}
|
2002-01-10 08:17:21 +08:00
|
|
|
|
|
|
|
res = slap_schema_load();
|
2000-01-30 03:43:19 +08:00
|
|
|
schema_init_done = 1;
|
2002-01-10 08:17:21 +08:00
|
|
|
return res;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
2001-11-07 09:03:49 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
schema_destroy( void )
|
|
|
|
{
|
2001-12-31 12:35:02 +08:00
|
|
|
oidm_destroy();
|
2001-11-07 09:03:49 +08:00
|
|
|
oc_destroy();
|
|
|
|
at_destroy();
|
|
|
|
mr_destroy();
|
2002-08-31 18:45:22 +08:00
|
|
|
mru_destroy();
|
2001-11-07 09:03:49 +08:00
|
|
|
syn_destroy();
|
|
|
|
}
|