schema_init.c 21.7 KB
Newer Older
1
2
3
/* schema_init.c - init builtin schema */
/* $OpenLDAP$ */
/*
Kurt Zeilenga's avatar
Kurt Zeilenga committed
4
 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 */

#include "portable.h"

#include <stdio.h>

#include <ac/ctype.h>
#include <ac/string.h>
#include <ac/socket.h>

#include "slap.h"
#include "ldap_pvt.h"

19
#define berValidate blobValidate
20
static int
21
blobValidate(
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
	Syntax *syntax,
	struct berval *in )
{
	/* any value allowed */
	return 0;
}

static int
UTF8StringValidate(
	Syntax *syntax,
	struct berval *in )
{
	ber_len_t count;
	int len;
	unsigned char *u = in->bv_val;

38
	for( count = in->bv_len; count > 0; count-=len, u+=len ) {
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
		/* get the length indicated by the first byte */
		len = LDAP_UTF8_CHARLEN( u );

		/* should not be zero */
		if( len == 0 ) return -1;

		/* make sure len corresponds with the offset
			to the next character */
		if( LDAP_UTF8_OFFSET( u ) != len ) return -1;
	}

	if( count != 0 ) return -1;

	return 0;
}

static int
UTF8StringNormalize(
57
	unsigned use,
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
	Syntax *syntax,
	MatchingRule *mr,
	struct berval *val,
	struct berval **normalized )
{
	struct berval *newval;
	char *p, *q, *s;

	newval = ch_malloc( sizeof( struct berval ) );

	p = val->bv_val;

	/* Ignore initial whitespace */
	while ( ldap_utf8_isspace( p ) ) {
		LDAP_UTF8_INCR( p );
	}

	if( *p ) {
		ch_free( newval );
		return 1;
	}

	newval->bv_val = ch_strdup( p );
	p = q = newval->bv_val;
	s = NULL;

	while ( *p ) {
		int len;

		if ( ldap_utf8_isspace( p ) ) {
			len = LDAP_UTF8_COPY(q,p);
			s=q;
			p+=len;
			q+=len;

			/* Ignore the extra whitespace */
			while ( ldap_utf8_isspace( p ) ) {
				LDAP_UTF8_INCR( p );
			}
		} else {
			len = LDAP_UTF8_COPY(q,p);
			s=NULL;
			p+=len;
			q+=len;
		}
	}

	assert( *newval->bv_val );
	assert( newval->bv_val < p );
	assert( p <= q );

	/* cannot start with a space */
	assert( !ldap_utf8_isspace(newval->bv_val) );

	/*
	 * 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.
	 */

	if ( s != NULL ) {
		q = s;
	}

	/* cannot end with a space */
	assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );

	/* null terminate */
	*q = '\0';

	newval->bv_len = q - newval->bv_val;
	normalized = &newval;

	return 0;
}

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
static int
oidValidate(
	Syntax *syntax,
	struct berval *val )
{
	ber_len_t i;

	if( val->bv_len == 0 ) return 0;

	if( isdigit(val->bv_val[0]) ) {
		int dot = 0;
		for(i=1; i < val->bv_len; i++) {
			if( val->bv_val[i] == '.' ) {
				if( dot++ ) return 1;
			} else if ( isdigit(val->bv_val[i]) ) {
				dot = 0;
			} else {
				return 1;
			}
		}

		return !dot ? 0 : 1;

	} else if( isalpha(val->bv_val[0]) ) {
		for(i=1; i < val->bv_len; i++) {
			if( !isalpha(val->bv_val[i] ) ) {
				return 1;
			}
		}

		return 0;
	}
	
	return 1;
}

170
static int
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
IA5StringValidate(
	Syntax *syntax,
	struct berval *val )
{
	ber_len_t i;

	for(i=0; i < val->bv_len; i++) {
		if( !isascii(val->bv_val[i]) ) return -1;
	}

	return 0;
}

static int
IA5StringConvert(
	Syntax *syntax,
	struct berval *in,
	struct berval **out )
{
190
191
	ldap_unicode_t *u;
	ber_len_t i, len = in->bv_len;
192
193
	struct berval *bv = ch_malloc( sizeof(struct berval) );

194
195
196
197
	bv->bv_len = len * sizeof( ldap_unicode_t );
	bv->bv_val = (char *) u = ch_malloc( bv->bv_len + sizeof( ldap_unicode_t ) );;

	for(i=0; i < len; i++ ) {
198
199
200
201
		/*
		 * IA5StringValidate should have been called to ensure
		 * input is limited to IA5.
		 */
202
		u[i] = in->bv_val[i];
203
	}
204
	u[i] = 0;
205
206
207
208
209
210
211

	*out = bv;
	return 0;
}

static int
IA5StringNormalize(
212
	unsigned use,
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
	Syntax *syntax,
	MatchingRule *mr,
	struct berval *val,
	struct berval **normalized )
{
	struct berval *newval;
	char *p, *q;

	newval = ch_malloc( sizeof( struct berval ) );

	p = val->bv_val;

	/* Ignore initial whitespace */
	while ( isspace( *p++ ) ) {
		/* EMPTY */  ;
	}

	if( *p ) {
		ch_free( newval );
		return 1;
	}

	newval->bv_val = ch_strdup( p );
	p = q = newval->bv_val;

	while ( *p ) {
		if ( isspace( *p ) ) {
			*q++ = *p++;

			/* Ignore the extra whitespace */
			while ( isspace( *p++ ) ) {
				/* EMPTY */  ;
			}
		} else {
			*q++ = *p++;
		}
	}

	assert( *newval->bv_val );
	assert( newval->bv_val < p );
	assert( p <= q );

	/* cannot start with a space */
	assert( !isspace(*newval->bv_val) );

	/*
	 * 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.
	 */

	if ( isspace( q[-1] ) ) {
		--q;
	}

	/* cannot end with a space */
	assert( !isspace( q[-1] ) );

	/* null terminate */
	*q = '\0';

	newval->bv_len = q - newval->bv_val;
	normalized = &newval;

	return 0;
}

static int
caseExactIA5Match(
282
	unsigned use,
283
284
285
	Syntax *syntax,
	MatchingRule *mr,
	struct berval *value,
286
	void *assertedValue )
287
{
288
289
	return strcmp( value->bv_val,
		((struct berval *) assertedValue)->bv_val );
290
291
292
293
}

static int
caseIgnoreIA5Match(
294
	unsigned use,
295
296
297
	Syntax *syntax,
	MatchingRule *mr,
	struct berval *value,
298
	void *assertedValue )
299
{
300
301
	return strcasecmp( value->bv_val,
		((struct berval *) assertedValue)->bv_val );
302
303
304
305
}

struct syntax_defs_rec {
	char *sd_desc;
306
	int sd_flags;
307
308
309
310
311
	slap_syntax_validate_func *sd_validate;
	slap_syntax_transform_func *sd_ber2str;
	slap_syntax_transform_func *sd_str2ber;
};

312
313
#define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
#define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
314

315
struct syntax_defs_rec syntax_defs[] = {
316
317
318
319
	{"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
		SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
	{"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
		0, NULL, NULL, NULL},
320
	{"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
321
		0, NULL, NULL, NULL},
322
323
324
325
	{"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
		SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
	{"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_BINARY X_NOT_H_R ")",
		SLAP_SYNTAX_BER, berValidate, NULL, NULL},
326
	{"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
327
		0, NULL, NULL, NULL},
328
	{"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
329
		0, NULL, NULL, NULL},
330
331
332
333
334
335
	{"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
		X_BINARY X_NOT_H_R ")",
		SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
	{"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
		X_BINARY X_NOT_H_R ")",
		SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
Kurt Zeilenga's avatar
Kurt Zeilenga committed
336
337
	{"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
		X_BINARY X_NOT_H_R ")",
338
		SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
339
340
	{"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
		0, NULL, NULL, NULL},
341
	{"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )",
342
		0, blobValidate, NULL, NULL},
343
	{"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
344
		0, NULL, NULL, NULL},
345
	{"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
346
		0, NULL, NULL, NULL},
347
	{"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
348
		0, UTF8StringValidate, NULL, NULL},
349
	{"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
350
		0, NULL, NULL, NULL},
351
	{"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
352
		0, NULL, NULL, NULL},
353
	{"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
354
		0, NULL, NULL, NULL},
355
	{"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
356
		0, NULL, NULL, NULL},
357
	{"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
358
		0, NULL, NULL, NULL},
359
	{"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
360
		0, NULL, NULL, NULL},
361
362
	{"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
		SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
363
	{"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
364
		0, NULL, NULL, NULL},
365
	{"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
366
		0, NULL, NULL, NULL},
367
	{"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
368
		0, IA5StringValidate, NULL, NULL},
369
	{"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
370
		0, NULL, NULL, NULL},
371
372
	{"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
		SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
373
	{"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
374
		0, NULL, NULL, NULL},
375
	{"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
376
		0, NULL, NULL, NULL},
377
	{"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
378
		0, NULL, NULL, NULL},
379
	{"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
380
		0, NULL, NULL, NULL},
381
	{"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
382
		0, NULL, NULL, NULL},
383
	{"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
384
		0, NULL, NULL, NULL},
385
	{"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
386
		0, NULL, NULL, NULL},
387
388
389
	{"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
		0, NULL, NULL, NULL},
	{"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
390
		0, NULL, NULL, NULL},
391
	{"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
392
		0, oidValidate, NULL, NULL},
393
	{"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
394
		0, NULL, NULL, NULL},
395
	{"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
396
		0, blobValidate, NULL, NULL},
397
	{"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
398
		0, blobValidate, NULL, NULL},
399
	{"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
400
		0, NULL, NULL, NULL},
401
	{"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
402
		0, NULL, NULL, NULL},
403
	{"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
404
		0, NULL, NULL, NULL},
405
406
407
	{"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
		X_BINARY X_NOT_H_R ")",
		SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
408
	{"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
409
		0, blobValidate, NULL, NULL},
410
411
412
413
414
	{"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
		0, NULL, NULL, NULL},
	{"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
		0, NULL, NULL, NULL},
	{"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
415
		0, NULL, NULL, NULL},
416
	{"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
417
		0, NULL, NULL, NULL},
418
	{"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
419
		0, NULL, NULL, NULL},
420
	{"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
421
		0, NULL, NULL, NULL},
422
	{"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
423
		0, NULL, NULL, NULL},
424
	{"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
425
		0, NULL, NULL, NULL},
426

427
	/* OpenLDAP Experimental Syntaxes */
428
	{"( " SLAPD_OID_ACI_SYNTAX " DESC 'OpenLDAP Experimental ACI' )",
429
430
		0, NULL, NULL, NULL},

431
	{NULL, 0, NULL, NULL, NULL}
432
433
434
};

struct mrule_defs_rec {
435
	char *						mrd_desc;
436
	unsigned					mrd_usage;
437
438
439
440
441
	slap_mr_convert_func *		mrd_convert;
	slap_mr_normalize_func *	mrd_normalize;
	slap_mr_match_func *		mrd_match;
	slap_mr_indexer_func *		mrd_indexer;
	slap_mr_filter_func *		mrd_filter;
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
};

/*
 * Other matching rules in X.520 that we do not use:
 *
 * 2.5.13.9		numericStringOrderingMatch
 * 2.5.13.13	booleanMatch
 * 2.5.13.15	integerOrderingMatch
 * 2.5.13.18	octetStringOrderingMatch
 * 2.5.13.19	octetStringSubstringsMatch
 * 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.34	certificateExactMatch
 * 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
 */

/* recycled matching functions */
#define caseIgnoreMatch caseIgnoreIA5Match
#define caseExactMatch caseExactIA5Match

/* unimplemented matching functions */
#define objectIdentifierMatch NULL
#define distinguishedNameMatch NULL
#define caseIgnoreOrderingMatch NULL
#define caseIgnoreSubstringsMatch NULL
#define caseExactOrderingMatch NULL
#define caseExactSubstringsMatch NULL
#define numericStringMatch NULL
#define numericStringSubstringsMatch NULL
#define caseIgnoreListMatch NULL
Kurt Zeilenga's avatar
Kurt Zeilenga committed
484
#define caseIgnoreListSubstringsMatch NULL
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
#define integerMatch NULL
#define bitStringMatch NULL
#define octetStringMatch NULL
#define telephoneNumberMatch NULL
#define telephoneNumberSubstringsMatch NULL
#define presentationAddressMatch NULL
#define uniqueMemberMatch NULL
#define protocolInformationMatch NULL
#define generalizedTimeMatch NULL
#define generalizedTimeOrderingMatch NULL
#define integerFirstComponentMatch NULL
#define objectIdentifierFirstComponentMatch NULL
#define caseIgnoreIA5SubstringsMatch NULL

struct mrule_defs_rec mrule_defs[] = {
	{"( 2.5.13.0 NAME 'objectIdentifierMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
502
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
503
		NULL, NULL, objectIdentifierMatch, NULL, NULL},
504
505
506

	{"( 2.5.13.1 NAME 'distinguishedNameMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
507
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
508
		NULL, NULL, distinguishedNameMatch, NULL, NULL},
509
510
511

	{"( 2.5.13.2 NAME 'caseIgnoreMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
512
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
513
		NULL, UTF8StringNormalize, caseIgnoreMatch, NULL, NULL},
514
515
516

	{"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
517
		SLAP_MR_ORDERING,
518
		NULL, UTF8StringNormalize, caseIgnoreOrderingMatch, NULL, NULL},
519
520
521

	{"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
522
		SLAP_MR_SUBSTR | SLAP_MR_EXT,
523
		NULL, UTF8StringNormalize, caseIgnoreSubstringsMatch, NULL, NULL},
524
525
526
527

	/* Next three are not in the RFC's, but are needed for compatibility */
	{"( 2.5.13.5 NAME 'caseExactMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
528
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
529
		NULL, UTF8StringNormalize, caseExactMatch, NULL, NULL},
530
531
532

	{"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
533
		SLAP_MR_ORDERING,
534
		NULL, UTF8StringNormalize, caseExactOrderingMatch, NULL, NULL},
535
536
537

	{"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
538
		SLAP_MR_SUBSTR | SLAP_MR_EXT,
539
		NULL, UTF8StringNormalize, caseExactSubstringsMatch, NULL, NULL},
540
541
542

	{"( 2.5.13.8 NAME 'numericStringMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
543
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
544
		NULL, NULL, numericStringMatch, NULL, NULL},
545
546
547

	{"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
548
		SLAP_MR_SUBSTR | SLAP_MR_EXT,
549
		NULL, NULL, numericStringSubstringsMatch, NULL, NULL},
550
551
552

	{"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
553
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
554
		NULL, NULL, caseIgnoreListMatch, NULL, NULL},
555

Kurt Zeilenga's avatar
Kurt Zeilenga committed
556
557
558
559
560
	{"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
		SLAP_MR_SUBSTR | SLAP_MR_EXT,
		NULL, NULL, caseIgnoreListSubstringsMatch, NULL, NULL},

561
562
	{"( 2.5.13.14 NAME 'integerMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
563
		SLAP_MR_NONE | SLAP_MR_EXT,
564
		NULL, NULL, integerMatch, NULL, NULL},
565
566
567

	{"( 2.5.13.16 NAME 'bitStringMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
568
		SLAP_MR_NONE | SLAP_MR_EXT,
569
		NULL, NULL, bitStringMatch, NULL, NULL},
570
571
572

	{"( 2.5.13.17 NAME 'octetStringMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
573
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
574
		NULL, NULL, octetStringMatch, NULL, NULL},
575
576
577

	{"( 2.5.13.20 NAME 'telephoneNumberMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
578
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
579
		NULL, NULL, telephoneNumberMatch, NULL, NULL},
580
581
582

	{"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
583
		SLAP_MR_SUBSTR | SLAP_MR_EXT,
584
		NULL, NULL, telephoneNumberSubstringsMatch, NULL, NULL},
585
586
587

	{"( 2.5.13.22 NAME 'presentationAddressMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
588
		SLAP_MR_NONE | SLAP_MR_EXT,
589
		NULL, NULL, presentationAddressMatch, NULL, NULL},
590
591
592

	{"( 2.5.13.23 NAME 'uniqueMemberMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
593
		SLAP_MR_NONE | SLAP_MR_EXT,
594
		NULL, NULL, uniqueMemberMatch, NULL, NULL},
595
596
597

	{"( 2.5.13.24 NAME 'protocolInformationMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
598
		SLAP_MR_NONE | SLAP_MR_EXT,
599
		NULL, NULL, protocolInformationMatch, NULL, NULL},
600
601
602

	{"( 2.5.13.27 NAME 'generalizedTimeMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
603
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
604
		NULL, NULL, generalizedTimeMatch, NULL, NULL},
605
606
607

	{"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
608
		SLAP_MR_ORDERING,
609
		NULL, NULL, generalizedTimeOrderingMatch, NULL, NULL},
610
611
612

	{"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
613
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
614
		NULL, NULL, integerFirstComponentMatch, NULL, NULL},
615
616
617

	{"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
618
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
619
		NULL, NULL, objectIdentifierFirstComponentMatch, NULL, NULL},
620
621
622

	{"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
623
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
624
		NULL, IA5StringNormalize, caseExactIA5Match, NULL, NULL},
625
626
627

	{"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
628
		SLAP_MR_EQUALITY | SLAP_MR_EXT,
629
		NULL, IA5StringNormalize, caseIgnoreIA5Match, NULL, NULL},
630
631
632

	{"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
633
		SLAP_MR_SUBSTR,
634
		NULL, IA5StringNormalize, caseIgnoreIA5SubstringsMatch, NULL, NULL},
635

636
	{NULL, SLAP_MR_NONE, NULL, NULL, NULL}
637
638
};

639
640
static int schema_init_done = 0;

641
642
643
644
645
646
int
schema_init( void )
{
	int		res;
	int		i;

647
648
	/* we should only be called once (from main) */
	assert( schema_init_done == 0 );
649
650
651

	for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
		res = register_syntax( syntax_defs[i].sd_desc,
652
		    syntax_defs[i].sd_flags,
653
654
655
656
657
658
659
		    syntax_defs[i].sd_validate,
		    syntax_defs[i].sd_ber2str,
			syntax_defs[i].sd_str2ber );

		if ( res ) {
			fprintf( stderr, "schema_init: Error registering syntax %s\n",
				 syntax_defs[i].sd_desc );
660
			return -1;
661
662
663
664
		}
	}

	for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
665
666
667
668
669
670
671
		if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
			fprintf( stderr,
				"schema_init: Ingoring unusable matching rule %s\n",
				 mrule_defs[i].mrd_desc );
			continue;
		}

672
673
		res = register_matching_rule(
			mrule_defs[i].mrd_desc,
674
			mrule_defs[i].mrd_usage,
675
676
			mrule_defs[i].mrd_convert,
			mrule_defs[i].mrd_normalize,
677
678
679
		    mrule_defs[i].mrd_match,
			mrule_defs[i].mrd_indexer,
			mrule_defs[i].mrd_filter );
680
681
682
683
684

		if ( res ) {
			fprintf( stderr,
				"schema_init: Error registering matching rule %s\n",
				 mrule_defs[i].mrd_desc );
685
			return -1;
686
687
688
689
690
		}
	}
	schema_init_done = 1;
	return( 0 );
}
691
692

#ifdef SLAPD_SCHEMA_NOT_COMPAT
693
694
struct slap_internal_schema slap_schema;

695
696
697
698
699
700
701
702
703
struct slap_schema_oc_map {
	char *ssom_name;
	size_t ssom_offset;
} oc_map[] = {
	{ "alias", offsetof(struct slap_internal_schema, si_oc_alias) },
	{ "referral", offsetof(struct slap_internal_schema, si_oc_referral) },
	{ NULL, 0 }
};

704
struct slap_schema_ad_map {
705
706
707
	char *ssam_name;
	size_t ssam_offset;
} ad_map[] = {
708
709
710
711
712
713
714
715
716
717
718
	{ "objectClass",
		offsetof(struct slap_internal_schema, si_ad_objectClass) },

	{ "creatorsName",
		offsetof(struct slap_internal_schema, si_ad_creatorsName) },
	{ "createTimestamp",
		offsetof(struct slap_internal_schema, si_ad_createTimestamp) },
	{ "modifiersName",
		offsetof(struct slap_internal_schema, si_ad_modifiersName) },
	{ "modifyTimestamp",
		offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) },
719
720
721
722

	{ "subschemaSubentry",
		offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },

723
724
725
726
727
728
729
730
731
732
733
	{ "namingContexts",
		offsetof(struct slap_internal_schema, si_ad_namingContexts) },
	{ "supportedControl",
		offsetof(struct slap_internal_schema, si_ad_supportedControl) },
	{ "supportedExtension",
		offsetof(struct slap_internal_schema, si_ad_supportedExtension) },
	{ "supportedLDAPVersion",
		offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) },
	{ "supportedSASLMechanisms",
		offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) },

734
735
736
737
738
739
740
741
742
	{ "attributeTypes",
		offsetof(struct slap_internal_schema, si_ad_attributeTypes) },
	{ "ldapSyntaxes",
		offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) },
	{ "matchingRules",
		offsetof(struct slap_internal_schema, si_ad_matchingRules) },
	{ "objectClasses",
		offsetof(struct slap_internal_schema, si_ad_objectClasses) },

743
744
745
746
747
748
749
	{ "ref",
		offsetof(struct slap_internal_schema, si_ad_ref) },

	{ "entry",
		offsetof(struct slap_internal_schema, si_ad_entry) },
	{ "children",
		offsetof(struct slap_internal_schema, si_ad_children) },
750
751
752
753
754
755
756
757
758
759

	{ "userPassword",
		offsetof(struct slap_internal_schema, si_ad_userPassword) },
	{ "authPassword",
		offsetof(struct slap_internal_schema, si_ad_authPassword) },
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
	{ "krbName",
		offsetof(struct slap_internal_schema, si_ad_krbName) },
#endif

760
	{ NULL, 0 }
761
762
};

763
764
765
766
767
768
#endif

int
schema_prep( void )
{
#ifdef SLAPD_SCHEMA_NOT_COMPAT
769
	int i;
770
771
772
773
774
#endif
	/* we should only be called once after schema_init() was called */
	assert( schema_init_done == 1 );

#ifdef SLAPD_SCHEMA_NOT_COMPAT
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
	for( i=0; oc_map[i].ssom_name; i++ ) {
		ObjectClass ** ocp = (ObjectClass **)
			&(((char *) &slap_schema)[oc_map[i].ssom_offset]);

		*ocp = oc_find( oc_map[i].ssom_name );

		if( *ocp == NULL ) {
			fprintf( stderr,
				"No objectClass \"%s\" defined in schema\n",
				oc_map[i].ssom_name );
			return LDAP_OBJECT_CLASS_VIOLATION;
		}
	}

	for( i=0; ad_map[i].ssam_name; i++ ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
790
		int rc;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
791
		const char *text;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
792
793

		AttributeDescription ** adp = (AttributeDescription **)
794
			&(((char *) &slap_schema)[ad_map[i].ssam_offset]);
Kurt Zeilenga's avatar
Kurt Zeilenga committed
795
796
797

		*adp = NULL;

798
		rc = slap_str2ad( ad_map[i].ssam_name, adp, &text );
799

800
801
802
		if( rc != LDAP_SUCCESS ) {
			fprintf( stderr,
				"No attribute \"%s\" defined in schema\n",
803
				ad_map[i].ssam_name );
804
805
			return rc;
		}
806
807
808
809
810
811
	}
#endif

	++schema_init_done;
	return 0;
}