schema_prep.c 30.8 KB
Newer Older
1
2
3
/* schema_init.c - init builtin schema */
/* $OpenLDAP$ */
/*
Kurt Zeilenga's avatar
Kurt Zeilenga committed
4
 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5
6
7
8
9
10
11
12
13
14
15
16
17
 * 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"
Kurt Zeilenga's avatar
Kurt Zeilenga committed
18
#include "ldap_pvt_uc.h"
19
20
21
22
23
24
25

int schema_init_done = 0;

struct slap_internal_schema slap_schema;

static int
objectClassMatch(
26
	int *matchp,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
27
	slap_mask_t flags,
28
29
30
31
32
	Syntax *syntax,
	MatchingRule *mr,
	struct berval *value,
	void *assertedValue )
{
33
	struct berval *a = (struct berval *) assertedValue;
Howard Chu's avatar
Howard Chu committed
34
35
	ObjectClass *oc = oc_bvfind( value );
	ObjectClass *asserted = oc_bvfind( a );
36

37
38
39
40
41
42
43
44
45
46
47
#if 1
#ifdef NEW_LOGGING
	LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
		   "> objectClassMatch(%s, %s)\n",
		   value->bv_val, a->bv_val ));
#else
	Debug( LDAP_DEBUG_TRACE, "> objectClassMatch(%s,%s)\n",
		value->bv_val, a->bv_val, 0 );
#endif
#endif

48
	if( asserted == NULL ) {
49
		if( OID_LEADCHAR( *a->bv_val ) ) {
50
51
52
53
54
55
			/* OID form, return FALSE */
			*matchp = 1;
			return LDAP_SUCCESS;
		}

		/* desc form, return undefined */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
56
		return SLAPD_COMPARE_UNDEFINED;
57
58
59
	}

	if ( oc == NULL ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
60
61
		/* unrecognized stored value */
		return SLAPD_COMPARE_UNDEFINED;
62
63
	}

64
	if( SLAP_IS_MR_VALUE_SYNTAX_MATCH( flags ) ) {
65
66
67
68
69
		*matchp = ( asserted != oc );
	} else {
		*matchp = !is_object_subclass( asserted, oc );
	}

70
#if 1
71
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
72
	LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
73
		   "< objectClassMatch(%s, %s) = %d\n",
Gary Williams's avatar
Gary Williams committed
74
		   value->bv_val, a->bv_val, *matchp ));
75
#else
76
	Debug( LDAP_DEBUG_TRACE, "< objectClassMatch(%s,%s) = %d\n",
77
		value->bv_val, a->bv_val, *matchp );
78
#endif
79
80
#endif

81
82
83
	return LDAP_SUCCESS;
}

84
85
86
#if 1
#define structuralObjectClassMatch objectClassMatch
#else
87
88
89
static int
structuralObjectClassMatch(
	int *matchp,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
90
	slap_mask_t flags,
91
92
93
94
95
96
	Syntax *syntax,
	MatchingRule *mr,
	struct berval *value,
	void *assertedValue )
{
	struct berval *a = (struct berval *) assertedValue;
Howard Chu's avatar
Howard Chu committed
97
98
	ObjectClass *oc = oc_bvfind( value );
	ObjectClass *asserted = oc_bvfind( a );
99

100
101
102
103
104
105
106
107
108
109
110
#if 1
#ifdef NEW_LOGGING
	LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
		   "> structuralObjectClassMatch(%s, %s)\n",
		   value->bv_val, a->bv_val ));
#else
	Debug( LDAP_DEBUG_TRACE, "> structuralObjectClassMatch(%s,%s)\n",
		value->bv_val, a->bv_val, 0 );
#endif
#endif

111
112
113
114
115
116
117
118
119
120
	if( asserted == NULL ) {
		if( OID_LEADCHAR( *a->bv_val ) ) {
			/* OID form, return FALSE */
			*matchp = 1;
			return LDAP_SUCCESS;
		}

		/* desc form, return undefined */
		return SLAPD_COMPARE_UNDEFINED;
	}
121

122
123
124
125
126
127
128
	if ( oc == NULL ) {
		/* unrecognized stored value */
		return SLAPD_COMPARE_UNDEFINED;
	}

	*matchp = ( asserted != oc );

129
#if 1
130
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
131
	LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
132
		   "< structuralObjectClassMatch( %s, %s ) = %d\n",
Gary Williams's avatar
Gary Williams committed
133
		   value->bv_val, a->bv_val, *matchp ));
134
#else
135
	Debug( LDAP_DEBUG_TRACE, "< structuralObjectClassMatch(%s,%s) = %d\n",
136
		value->bv_val, a->bv_val, *matchp );
137
#endif
138
#endif
139
140
141

	return LDAP_SUCCESS;
}
142
#endif
143

Kurt Zeilenga's avatar
Kurt Zeilenga committed
144
static ObjectClassSchemaCheckFN rootDseObjectClass;
145
146
static ObjectClassSchemaCheckFN aliasObjectClass;
static ObjectClassSchemaCheckFN referralObjectClass;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
147
static ObjectClassSchemaCheckFN subentryObjectClass;
148
static ObjectClassSchemaCheckFN dynamicObjectClass;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
149

Kurt Zeilenga's avatar
Kurt Zeilenga committed
150
static struct slap_schema_oc_map {
151
	char *ssom_name;
152
153
	char *ssom_defn;
	ObjectClassSchemaCheckFN *ssom_check;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
154
	slap_mask_t ssom_flags;
155
156
	size_t ssom_offset;
} oc_map[] = {
157
158
159
	{ "top", "( 2.5.6.0 NAME 'top' "
			"DESC 'top of the superclass chain' "
			"ABSTRACT MUST objectClass )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
160
		0, 0, offsetof(struct slap_internal_schema, si_oc_top) },
161
162
163
164
	{ "extensibleObject", "( 1.3.6.1.4.1.1466.101.120.111 "
			"NAME 'extensibleObject' "
			"DESC 'RFC2252: extensible object' "
			"SUP top AUXILIARY )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
165
		0, 0, offsetof(struct slap_internal_schema, si_oc_extensibleObject) },
166
167
168
169
	{ "alias", "( 2.5.6.1 NAME 'alias' "
			"DESC 'RFC2256: an alias' "
			"SUP top STRUCTURAL "
			"MUST aliasedObjectName )",
170
		aliasObjectClass, SLAP_OC_ALIAS,
171
		offsetof(struct slap_internal_schema, si_oc_alias) },
172
173
174
	{ "referral", "( 2.16.840.1.113730.3.2.6 NAME 'referral' "
			"DESC 'namedref: named subordinate referral' "
			"SUP top STRUCTURAL MUST ref )",
175
		referralObjectClass, SLAP_OC_REFERRAL,
176
		offsetof(struct slap_internal_schema, si_oc_referral) },
177
178
179
	{ "LDAProotDSE", "( 1.3.6.1.4.1.4203.1.4.1 "
			"NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' ) "
			"DESC 'OpenLDAP Root DSE object' "
180
			"SUP top STRUCTURAL MAY cn )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
181
		rootDseObjectClass, 0,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
182
		offsetof(struct slap_internal_schema, si_oc_rootdse) },
183
184
185
	{ "subentry", "( 2.5.20.0 NAME 'subentry' "
			"SUP top STRUCTURAL "
			"MUST ( cn $ subtreeSpecification ) )",
Howard Chu's avatar
Howard Chu committed
186
		subentryObjectClass, SLAP_OC_SUBENTRY,
187
		offsetof(struct slap_internal_schema, si_oc_subentry) },
188
189
	{ "subschema", "( 2.5.20.1 NAME 'subschema' "
		"DESC 'RFC2252: controlling subschema (sub)entry' "
Kurt Zeilenga's avatar
Kurt Zeilenga committed
190
		"AUXILIARY "
191
192
		"MAY ( dITStructureRules $ nameForms $ ditContentRules $ "
			"objectClasses $ attributeTypes $ matchingRules $ "
193
			"matchingRuleUse ) )",
Howard Chu's avatar
Howard Chu committed
194
		subentryObjectClass, 0,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
195
		offsetof(struct slap_internal_schema, si_oc_subschema) },
196
197
198
199
	{ "monitor", "( 1.3.6.1.4.1.4203.666.3.2 NAME 'monitor' "
		"DESC 'OpenLDAP system monitoring' "
		"STRUCTURAL "
		"MUST cn )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
200
		0, 0, offsetof(struct slap_internal_schema, si_oc_monitor) },
201
202
	{ "collectiveAttributeSubentry", "( 2.5.20.2 "
			"NAME 'collectiveAttributeSubentry' "
203
			"AUXILIARY )",
204
205
		subentryObjectClass, SLAP_OC_COLLECTIVEATTRIBUTESUBENTRY,
		offsetof(struct slap_internal_schema, si_oc_collectiveAttributeSubentry) },
206
207
208
209
	{ "dynamicObject", "( 1.3.6.1.4.1.1466.101.119.2 "
			"NAME 'dynamicObject' "
			"DESC 'RFC2589: Dynamic Object' "
			"SUP top AUXILIARY )",
210
		dynamicObjectClass, SLAP_OC_DYNAMICOBJECT,
211
		offsetof(struct slap_internal_schema, si_oc_dynamicObject) },
Kurt Zeilenga's avatar
Kurt Zeilenga committed
212
	{ NULL, NULL, NULL, 0, 0 }
213
214
};

215
static AttributeTypeSchemaCheckFN rootDseAttribute;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
216
static AttributeTypeSchemaCheckFN aliasAttribute;
217
static AttributeTypeSchemaCheckFN referralAttribute;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
218
static AttributeTypeSchemaCheckFN subentryAttribute;
219
static AttributeTypeSchemaCheckFN administrativeRoleAttribute;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
220
static AttributeTypeSchemaCheckFN dynamicAttribute;
221

Kurt Zeilenga's avatar
Kurt Zeilenga committed
222
static struct slap_schema_ad_map {
223
	char *ssam_name;
224
225
	char *ssam_defn;
	AttributeTypeSchemaCheckFN *ssam_check;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
226
	slap_mask_t ssam_flags;
227
	slap_mr_match_func *ssam_match;
228
229
	slap_mr_indexer_func *ssam_indexer;
	slap_mr_filter_func *ssam_filter;
230
231
	size_t ssam_offset;
} ad_map[] = {
232
233
234
235
	{ "objectClass", "( 2.5.4.0 NAME 'objectClass' "
			"DESC 'RFC2256: object classes of the entity' "
			"EQUALITY objectIdentifierMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
236
		NULL, 0, objectClassMatch, NULL, NULL,
237
		offsetof(struct slap_internal_schema, si_ad_objectClass) },
238
239

	/* user entry operational attributes */
240
241
242
243
244
	{ "structuralObjectClass", "( 2.5.21.9 NAME 'structuralObjectClass' "
			"DESC 'X.500(93): structural object class of entry' "
			"EQUALITY objectIdentifierMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
			"NO-USER-MODIFICATION SINGLE-VALUE USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
245
		NULL, 0, structuralObjectClassMatch, NULL, NULL,
246
		offsetof(struct slap_internal_schema, si_ad_structuralObjectClass) },
247
248
249
250
251
252
	{ "createTimestamp", "( 2.5.18.1 NAME 'createTimestamp' "
			"DESC 'RFC2252: time which object was created' "
			"EQUALITY generalizedTimeMatch "
			"ORDERING generalizedTimeOrderingMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
			"SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
253
		NULL, 0, NULL, NULL, NULL,
254
		offsetof(struct slap_internal_schema, si_ad_createTimestamp) },
255
256
257
258
259
260
	{ "modifyTimestamp", "( 2.5.18.2 NAME 'modifyTimestamp' "
			"DESC 'RFC2252: time which object was last modified' "
			"EQUALITY generalizedTimeMatch "
			"ORDERING generalizedTimeOrderingMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
			"SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
261
		NULL, 0, NULL, NULL, NULL,
262
		offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) },
263
264
265
266
267
	{ "creatorsName", "( 2.5.18.3 NAME 'creatorsName' "
			"DESC 'RFC2252: name of creator' "
			"EQUALITY distinguishedNameMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
			"SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
268
		NULL, 0, NULL, NULL, NULL,
269
270
271
272
273
274
		offsetof(struct slap_internal_schema, si_ad_creatorsName) },
	{ "modifiersName", "( 2.5.18.4 NAME 'modifiersName' "
			"DESC 'RFC2252: name of last modifier' "
			"EQUALITY distinguishedNameMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
			"SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
275
		NULL, 0, NULL, NULL, NULL,
276
277
278
279
280
281
		offsetof(struct slap_internal_schema, si_ad_modifiersName) },
	{ "hasSubordinates", "( 2.5.18.9 NAME 'hasSubordinates' "
			"DESC 'X.501: entry has children' "
			"EQUALITY booleanMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
			"SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
282
		NULL, 0, NULL, NULL, NULL,
283
		offsetof(struct slap_internal_schema, si_ad_hasSubordinates) },
284
285
286
287
288
	{ "subschemaSubentry", "( 2.5.18.10 NAME 'subschemaSubentry' "
			"DESC 'RFC2252: name of controlling subschema entry' "
			"EQUALITY distinguishedNameMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION "
			"SINGLE-VALUE USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
289
		NULL, 0, NULL, NULL, NULL,
290
		offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },
291
292
	{ "collectiveAttributeSubentries", "( 2.5.18.12 "
			"NAME 'collectiveAttributeSubentries' "
293
294
295
			"EQUALITY distinguishedNameMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
			"USAGE directoryOperation NO-USER-MODIFICATION )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
296
		NULL, 0, NULL, NULL, NULL,
297
		offsetof(struct slap_internal_schema, si_ad_collectiveSubentries) },
298
299
300
301
	{ "collectiveExclusions", "( 2.5.18.7 NAME 'collectiveExclusions' "
			"EQUALITY objectIdentifierMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
			"USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
302
		NULL, 0, NULL, NULL, NULL,
303
		offsetof(struct slap_internal_schema, si_ad_collectiveExclusions) },
304

305
306
307
308
309
	{ "entryUUID", "( 1.3.6.1.4.1.4203.666.1.6 NAME 'entryUUID' "   
			"DESC 'LCUP/LDUP: universally unique identifier' "
			"EQUALITY octetStringMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64} "
			"SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
310
		NULL, 0, NULL, NULL, NULL,
311
312
313
314
315
316
		offsetof(struct slap_internal_schema, si_ad_entryUUID) },
	{ "entryCSN", "( 1.3.6.1.4.1.4203.666.1.7 NAME 'entryCSN' "
			"DESC 'LCUP/LDUP: change sequence number' "
			"EQUALITY octetStringMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64} "
			"SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
317
		NULL, 0, NULL, NULL, NULL,
318
319
		offsetof(struct slap_internal_schema, si_ad_entryCSN) },

320
	/* root DSE attributes */
321
322
323
	{ "altServer", "( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer' "
			"DESC 'RFC2252: alternative servers' "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
324
		rootDseAttribute, 0, NULL, NULL, NULL,
325
		offsetof(struct slap_internal_schema, si_ad_altServer) },
326
327
328
329
	{ "namingContexts", "( 1.3.6.1.4.1.1466.101.120.5 "
			"NAME 'namingContexts' "
			"DESC 'RFC2252: naming contexts' "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
330
		rootDseAttribute, 0, NULL, NULL, NULL,
331
		offsetof(struct slap_internal_schema, si_ad_namingContexts) },
332
333
334
335
	{ "supportedControl", "( 1.3.6.1.4.1.1466.101.120.13 "
			"NAME 'supportedControl' "
		   "DESC 'RFC2252: supported controls' "
		   "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
336
		rootDseAttribute, 0, NULL, NULL, NULL,
337
		offsetof(struct slap_internal_schema, si_ad_supportedControl) },
338
339
340
341
	{ "supportedExtension", "( 1.3.6.1.4.1.1466.101.120.7 "
			"NAME 'supportedExtension' "
			"DESC 'RFC2252: supported extended operations' "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
342
		rootDseAttribute, 0, NULL, NULL, NULL,
343
		offsetof(struct slap_internal_schema, si_ad_supportedExtension) },
344
345
346
347
	{ "supportedLDAPVersion", "( 1.3.6.1.4.1.1466.101.120.15 "
			"NAME 'supportedLDAPVersion' "
			"DESC 'RFC2252: supported LDAP versions' "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
348
		rootDseAttribute, 0, NULL, NULL, NULL,
349
		offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) },
350
351
352
353
	{ "supportedSASLMechanisms", "( 1.3.6.1.4.1.1466.101.120.14 "
			"NAME 'supportedSASLMechanisms' "
			"DESC 'RFC2252: supported SASL mechanisms'"
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
354
		rootDseAttribute, 0, NULL, NULL, NULL,
355
		offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) },
356
357
358
359
360
361
	{ "supportedFeatures", "( 1.3.6.1.4.1.4203.1.3.5 "
			"NAME 'supportedFeatures' "
			"DESC 'features supported by the server' "
			"EQUALITY objectIdentifierMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
			"USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
362
		rootDseAttribute, 0, NULL, NULL, NULL,
363
		offsetof(struct slap_internal_schema, si_ad_supportedFeatures) },
364
365
366
367
368
369
	{ "vendorName", "( 1.3.6.1.1.4 NAME 'vendorName' "
			"DESC 'RFC3045: name of implementation vendor' "
			"EQUALITY 1.3.6.1.4.1.1466.109.114.1 "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
			"SINGLE-VALUE NO-USER-MODIFICATION "
			"USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
370
		rootDseAttribute, 0, NULL, NULL, NULL,
371
372
373
374
375
376
377
		offsetof(struct slap_internal_schema, si_ad_vendorName) },
	{ "vendorVersion", "( 1.3.6.1.1.5 NAME 'vendorVersion' "
			"DESC 'RFC3045: version of implementation' "
			"EQUALITY 1.3.6.1.4.1.1466.109.114.1 "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
			"SINGLE-VALUE NO-USER-MODIFICATION "
			"USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
378
		rootDseAttribute, 0, NULL, NULL, NULL,
379
380
381
382
383
384
385
		offsetof(struct slap_internal_schema, si_ad_vendorVersion) },

	/* subentry attributes */
	{ "administrativeRole", "( 2.5.18.5 NAME 'administrativeRole' "
			"EQUALITY objectIdentifierMatch "
			"USAGE directoryOperation "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
386
		administrativeRoleAttribute, 0, NULL, NULL, NULL,
387
388
389
390
391
		offsetof(struct slap_internal_schema, si_ad_administrativeRole) },
	{ "subtreeSpecification", "( 2.5.18.6 NAME 'subtreeSpecification' "
			"SINGLE-VALUE "
			"USAGE directoryOperation "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.45 )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
392
		subentryAttribute, 0, NULL, NULL, NULL,
393
		offsetof(struct slap_internal_schema, si_ad_subtreeSpecification) },
394

395
	/* subschema subentry attributes */
396
397
398
399
400
	{ "ditStructureRules", "( 2.5.21.1 NAME 'dITStructureRules' "
			"DESC 'RFC2252: DIT structure rules' "
			"EQUALITY integerFirstComponentMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.17 "
			"USAGE directoryOperation ) ",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
401
		subentryAttribute, 0, NULL, NULL, NULL,
402
403
404
405
406
		offsetof(struct slap_internal_schema, si_ad_ditStructureRules) },
	{ "ditContentRules", "( 2.5.21.2 NAME 'dITContentRules' "
			"DESC 'RFC2252: DIT content rules' "
			"EQUALITY objectIdentifierFirstComponentMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.16 USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
407
		subentryAttribute, 0, NULL, NULL, NULL,
408
		offsetof(struct slap_internal_schema, si_ad_ditContentRules) },
409
410
411
412
	{ "matchingRules", "( 2.5.21.4 NAME 'matchingRules' "
			"DESC 'RFC2252: matching rules' "
			"EQUALITY objectIdentifierFirstComponentMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.30 USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
413
		subentryAttribute, 0, NULL, NULL, NULL,
414
		offsetof(struct slap_internal_schema, si_ad_matchingRules) },
415
416
417
418
	{ "attributeTypes", "( 2.5.21.5 NAME 'attributeTypes' "
			"DESC 'RFC2252: attribute types' "
			"EQUALITY objectIdentifierFirstComponentMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
419
		subentryAttribute, 0, NULL, NULL, NULL,
420
421
422
423
424
		offsetof(struct slap_internal_schema, si_ad_attributeTypes) },
	{ "objectClasses", "( 2.5.21.6 NAME 'objectClasses' "
			"DESC 'RFC2252: object classes' "
			"EQUALITY objectIdentifierFirstComponentMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
425
		subentryAttribute, 0, NULL, NULL, NULL,
426
		offsetof(struct slap_internal_schema, si_ad_objectClasses) },
427
428
429
430
	{ "nameForms", "( 2.5.21.7 NAME 'nameForms' "
			"DESC 'RFC2252: name forms ' "
			"EQUALITY objectIdentifierFirstComponentMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.35 USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
431
		subentryAttribute, 0, NULL, NULL, NULL,
432
		offsetof(struct slap_internal_schema, si_ad_nameForms) },
433
	{ "matchingRuleUse", "( 2.5.21.8 NAME 'matchingRuleUse' "
434
435
436
			"DESC 'RFC2252: matching rule uses' "
			"EQUALITY objectIdentifierFirstComponentMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
437
		subentryAttribute, 0, NULL, NULL, NULL,
438
		offsetof(struct slap_internal_schema, si_ad_matchingRuleUse) },
439

440
441
442
443
	{ "ldapSyntaxes", "( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes' "
			"DESC 'RFC2252: LDAP syntaxes' "
			"EQUALITY objectIdentifierFirstComponentMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.54 USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
444
		subentryAttribute, 0, NULL, NULL, NULL,
445
446
		offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) },

447
	/* knowledge information */
448
449
450
451
452
	{ "aliasedObjectName", "( 2.5.4.1 "
			"NAME ( 'aliasedObjectName' 'aliasedEntryName' ) "
			"DESC 'RFC2256: name of aliased object' "
			"EQUALITY distinguishedNameMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
453
		aliasAttribute, 0, NULL, NULL, NULL,
454
		offsetof(struct slap_internal_schema, si_ad_aliasedObjectName) },
455
456
457
458
459
	{ "ref", "( 2.16.840.1.113730.3.1.34 NAME 'ref' "
			"DESC 'namedref: subordinate referral URL' "
			"EQUALITY caseExactMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
			"USAGE distributedOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
460
		referralAttribute, 0, NULL, NULL, NULL,
461
462
		offsetof(struct slap_internal_schema, si_ad_ref) },

Kurt Zeilenga's avatar
Kurt Zeilenga committed
463
	/* access control internals */
464
465
466
467
468
	{ "entry", "( 1.3.6.1.4.1.4203.1.3.1 "
			"NAME 'entry' "
			"DESC 'OpenLDAP ACL entry pseudo-attribute' "
			"SYNTAX 1.3.6.1.4.1.4203.1.1.1 "
			"SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
469
		NULL, 0, NULL, NULL, NULL,
470
		offsetof(struct slap_internal_schema, si_ad_entry) },
471
472
473
474
475
	{ "children", "( 1.3.6.1.4.1.4203.1.3.2 "
			"NAME 'children' "
			"DESC 'OpenLDAP ACL children pseudo-attribute' "
			"SYNTAX 1.3.6.1.4.1.4203.1.1.1 "
			"SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
476
		NULL, 0, NULL, NULL, NULL,
477
		offsetof(struct slap_internal_schema, si_ad_children) },
478
#ifdef SLAPD_ACI_ENABLED
479
480
481
482
483
484
	{ "OpenLDAPaci", "( 1.3.6.1.4.1.4203.666.1.5 "
			"NAME 'OpenLDAPaci' "
			"DESC 'OpenLDAP access control information (experimental)' "
			"EQUALITY OpenLDAPaciMatch "
			"SYNTAX 1.3.6.1.4.1.4203.666.2.1 "
			"USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
485
		NULL, 0, NULL, NULL, NULL,
486
487
		offsetof(struct slap_internal_schema, si_ad_aci) },
#endif
488

489
490
491
492
	{ "entryTtl", "( 1.3.6.1.4.1.1466.101.119.3 NAME 'entryTtl' "
			"DESC 'RFC2589: entry time-to-live' "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE "
			"NO-USER-MODIFICATION USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
493
		dynamicAttribute, 0, NULL, NULL, NULL,
494
495
496
497
498
499
		offsetof(struct slap_internal_schema, si_ad_entryTtl) },
	{ "dynamicSubtrees", "( 1.3.6.1.4.1.1466.101.119.4 "
			"NAME 'dynamicSubtrees' "
			"DESC 'RFC2589: dynamic subtrees' "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION "
			"USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
500
		rootDseAttribute, 0, NULL, NULL, NULL,
501
502
		offsetof(struct slap_internal_schema, si_ad_dynamicSubtrees) },

503
	/* userApplication attributes (which system schema depends upon) */
504
505
506
507
	{ "distinguishedName", "( 2.5.4.49 NAME 'distinguishedName' "
			"DESC 'RFC2256: common supertype of DN attributes' "
			"EQUALITY distinguishedNameMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
508
		NULL, 0, NULL, NULL, NULL,
509
		offsetof(struct slap_internal_schema, si_ad_distinguishedName) },
510
511
512
513
514
	{ "name", "( 2.5.4.41 NAME 'name' "
			"DESC 'RFC2256: common supertype of name attributes' "
			"EQUALITY caseIgnoreMatch "
			"SUBSTR caseIgnoreSubstringsMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
515
		NULL, 0, NULL, NULL, NULL,
516
517
518
519
		offsetof(struct slap_internal_schema, si_ad_name) },
	{ "cn", "( 2.5.4.3 NAME ( 'cn' 'commonName' ) "
			"DESC 'RFC2256: common name(s) for which the entity is known by' "
			"SUP name )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
520
		NULL, 0, NULL, NULL, NULL,
521
522
523
524
525
		offsetof(struct slap_internal_schema, si_ad_cn) },
	{ "userPassword", "( 2.5.4.35 NAME 'userPassword' "
			"DESC 'RFC2256/2307: password of user' "
			"EQUALITY octetStringMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
526
		NULL, 0, NULL, NULL, NULL,
527
		offsetof(struct slap_internal_schema, si_ad_userPassword) },
528
529

#ifdef SLAPD_AUTHPASSWD
530
531
532
533
534
	{ "authPassword", "( 1.3.6.1.4.1.4203.1.3.4 "
			"NAME 'authPassword' "
			"DESC 'RFC3112: authentication password attribute' "
			"EQUALITY 1.3.6.1.4.1.4203.1.2.2 "
			"SYNTAX 1.3.6.1.4.1.4203.1.1.2 )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
535
536
		NULL, 0,
		NULL, NULL, NULL,
537
538
539
540
541
542
543
		offsetof(struct slap_internal_schema, si_ad_authPassword) },
	{ "supportedAuthPasswordSchemes", "( 1.3.6.1.4.1.4203.1.3.3 "
			"NAME 'supportedAuthPasswordSchemes' "
			"DESC 'RFC3112: supported authPassword schemes' "
			"EQUALITY caseExactIA5Match "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} "
			"USAGE dSAOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
544
		subschemaAttribute, 0, NULL, NULL, NULL,
545
		offsetof(struct slap_internal_schema, si_ad_authPassword) },
546
#endif
547
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
548
	{ "krbName", NULL,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
549
		NULL, 0, NULL, NULL, NULL,
550
551
552
		offsetof(struct slap_internal_schema, si_ad_krbName) },
#endif

Kurt Zeilenga's avatar
Kurt Zeilenga committed
553
	{ NULL, NULL, NULL, 0, NULL, NULL, NULL, 0 }
554
555
};

556
557
558
static AttributeType slap_at_undefined = {
	{ "1.1.1", NULL, NULL, 1, NULL,
		NULL, NULL, NULL, NULL,
559
		0, 0, 0, 1, 3 }, /* LDAPAttributeType */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
560
	{ sizeof("UNDEFINED")-1, "UNDEFINED" }, /* cname */
561
562
563
564
	NULL, /* sup */
	NULL, /* subtypes */
	NULL, NULL, NULL, NULL,	/* matching rules */
	NULL, /* syntax (this may need to be defined) */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
565
	(AttributeTypeSchemaCheckFN *) 0, 0, /* schema check function/mask */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
566
567
	NULL, /* next */
	NULL /* attribute description */
568
	/* mutex (don't know how to initialize it :) */
569
};
570

Kurt Zeilenga's avatar
Kurt Zeilenga committed
571
static struct slap_schema_mr_map {
572
573
574
575
576
577
578
579
580
581
	char *ssmm_name;
	size_t ssmm_offset;
} mr_map[] = {
	{ "distinguishedNameMatch",
		offsetof(struct slap_internal_schema, si_mr_distinguishedNameMatch) },
	{ "integerMatch",
		offsetof(struct slap_internal_schema, si_mr_integerMatch) },
	{ NULL, 0 }
};

Kurt Zeilenga's avatar
Kurt Zeilenga committed
582
static struct slap_schema_syn_map {
583
584
585
586
587
588
589
590
591
592
	char *sssm_name;
	size_t sssm_offset;
} syn_map[] = {
	{ "1.3.6.1.4.1.1466.115.121.1.12",
		offsetof(struct slap_internal_schema, si_syn_distinguishedName) },
	{ "1.3.6.1.4.1.1466.115.121.1.27",
		offsetof(struct slap_internal_schema, si_syn_integer) },
	{ NULL, 0 }
};

593
int
594
595
slap_schema_load( void )
{
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
	int i;
	for( i=0; ad_map[i].ssam_name; i++ ) {
		if( ad_map[i].ssam_defn != NULL ) {
			LDAPAttributeType *at;
			int		code;
			const char	*err;

			at = ldap_str2attributetype( ad_map[i].ssam_defn,
				&code, &err, LDAP_SCHEMA_ALLOW_ALL );
			if ( !at ) {
				fprintf( stderr,
					"slap_schema_load: %s: %s before %s\n",
					 ad_map[i].ssam_name, ldap_scherr2str(code), err );
				return code;
			}

			if ( at->at_oid == NULL ) {
				fprintf( stderr, "slap_schema_load: "
					"attributeType \"%s\" has no OID\n",
					ad_map[i].ssam_name );
				return LDAP_OTHER;
			}

			code = at_add( at, &err );
			if ( code ) {
				fprintf( stderr, "slap_schema_load: "
					"%s: %s: \"%s\"\n",
					 ad_map[i].ssam_name, scherr2str(code), err );
				return code;
			}
			ldap_memfree( at );
		}
	}
629
630

	for( i=0; oc_map[i].ssom_name; i++ ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
631
632
633
634
		if( oc_map[i].ssom_defn != NULL ) {
			LDAPObjectClass *oc;
			int		code;
			const char	*err;
635

Kurt Zeilenga's avatar
Kurt Zeilenga committed
636
637
638
639
640
641
642
643
			oc = ldap_str2objectclass( oc_map[i].ssom_defn, &code, &err,
				LDAP_SCHEMA_ALLOW_ALL );
			if ( !oc ) {
				fprintf( stderr, "slap_schema_load: "
					"%s: %s before %s\n",
				 	oc_map[i].ssom_name, ldap_scherr2str(code), err );
				return code;
			}
644

Kurt Zeilenga's avatar
Kurt Zeilenga committed
645
646
647
648
649
650
			if ( oc->oc_oid == NULL ) {
				fprintf( stderr, "slap_schema_load: "
					"%s: objectclass has no OID\n",
					oc_map[i].ssom_name );
				return LDAP_OTHER;
			}
651

Kurt Zeilenga's avatar
Kurt Zeilenga committed
652
653
654
655
656
657
658
659
660
661
			code = oc_add(oc,&err);
			if ( code ) {
				fprintf( stderr, "slap_schema_load: "
					"%s: %s: \"%s\"\n",
				 	oc_map[i].ssom_name, scherr2str(code), err);
				return code;
			}

			ldap_memfree(oc);
		}
662
663
	}

664
665
666
667
668
	return LDAP_SUCCESS;
}

int
slap_schema_check( void )
669
670
671
672
673
{
	int i;
	/* we should only be called once after schema_init() was called */
	assert( schema_init_done == 1 );

674
675
676
	for( i=0; syn_map[i].sssm_name; i++ ) {
		Syntax ** synp = (Syntax **)
			&(((char *) &slap_schema)[syn_map[i].sssm_offset]);
677

678
679
		assert( *synp == NULL );

680
		*synp = syn_find( syn_map[i].sssm_name );
681

682
683
684
685
686
		if( *synp == NULL ) {
			fprintf( stderr, "slap_schema_check: "
				"No syntax \"%s\" defined in schema\n",
				syn_map[i].sssm_name );
			return LDAP_INVALID_SYNTAX;
687
688
689
		}
	}

690
691
692
693
	for( i=0; mr_map[i].ssmm_name; i++ ) {
		MatchingRule ** mrp = (MatchingRule **)
			&(((char *) &slap_schema)[mr_map[i].ssmm_offset]);

694
695
		assert( *mrp == NULL );

696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
		*mrp = mr_find( mr_map[i].ssmm_name );

		if( *mrp == NULL ) {
			fprintf( stderr, "slap_schema_check: "
				"No matching rule \"%s\" defined in schema\n",
				mr_map[i].ssmm_name );
			return LDAP_INAPPROPRIATE_MATCHING;
		}
	}

	slap_at_undefined.sat_syntax = syn_find( SLAPD_OCTETSTRING_SYNTAX );
	if( slap_at_undefined.sat_syntax == NULL ) {
		fprintf( stderr, "slap_schema_check: "
			"No octetString syntax \"" SLAPD_OCTETSTRING_SYNTAX "\"\n" );
		return LDAP_INVALID_SYNTAX;
	}
	slap_schema.si_at_undefined = &slap_at_undefined;

714
715
716
717
718
719
720
	for( i=0; ad_map[i].ssam_name; i++ ) {
		int rc;
		const char *text;

		AttributeDescription ** adp = (AttributeDescription **)
			&(((char *) &slap_schema)[ad_map[i].ssam_offset]);

721
		assert( *adp == NULL );
722
723
724

		rc = slap_str2ad( ad_map[i].ssam_name, adp, &text );
		if( rc != LDAP_SUCCESS ) {
725
			fprintf( stderr, "slap_schema_check: "
726
727
728
729
730
				"No attribute \"%s\" defined in schema\n",
				ad_map[i].ssam_name );
			return rc;
		}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
731
732
733
734
735
736
737
		if( ad_map[i].ssam_check ) {
			/* install check routine */
			(*adp)->ad_type->sat_check = ad_map[i].ssam_check;
		}
		/* install flags */
		(*adp)->ad_type->sat_flags |= ad_map[i].ssam_flags;

738
739
740
741
742
743
		if( ad_map[i].ssam_match ) {
			/* install custom matching routine */
			(*adp)->ad_type->sat_equality->smr_match = ad_map[i].ssam_match;
		}
	}

744
745
746
	for( i=0; oc_map[i].ssom_name; i++ ) {
		ObjectClass ** ocp = (ObjectClass **)
			&(((char *) &slap_schema)[oc_map[i].ssom_offset]);
747

748
749
		assert( *ocp == NULL );

750
751
752
753
754
755
		*ocp = oc_find( oc_map[i].ssom_name );
		if( *ocp == NULL ) {
			fprintf( stderr, "slap_schema_check: "
				"No objectClass \"%s\" defined in schema\n",
				oc_map[i].ssom_name );
			return LDAP_OBJECT_CLASS_VIOLATION;
756
		}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
757
758
759

		if( oc_map[i].ssom_check ) {
			/* install check routine */
760
			(*ocp)->soc_check = oc_map[i].ssom_check;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
761
762
		}
		/* install flags */
763
		(*ocp)->soc_flags |= oc_map[i].ssom_flags;
764
765
	}

766
767
768
	++schema_init_done;
	return LDAP_SUCCESS;
}
769

Kurt Zeilenga's avatar
Kurt Zeilenga committed
770
static int rootDseObjectClass (
771
	Backend *be,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
772
773
774
775
776
777
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
778

Kurt Zeilenga's avatar
Kurt Zeilenga committed
779
780
781
782
783
784
785
786
787
788
789
790
	if( e->e_nname.bv_len ) {
		snprintf( textbuf, textlen,
			"objectClass \"%s\" only allowed in the root DSE",
			oc->soc_oid );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	/* we should not be called for the root DSE */
	assert( 0 );
	return LDAP_SUCCESS;
}

791
792
793
794
795
796
797
static int aliasObjectClass (
	Backend *be,
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
798
799
	*text = textbuf;

800
801
802
803
804
805
	if( !SLAP_ALIASES(be) ) {
		snprintf( textbuf, textlen,
			"objectClass \"%s\" not supported in context",
			oc->soc_oid );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
806

807
808
809
810
811
812
813
814
815
816
	return LDAP_SUCCESS;
}

static int referralObjectClass (
	Backend *be,
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
817
818
	*text = textbuf;

819
820
821
822
823
824
	if( !SLAP_REFERRALS(be) ) {
		snprintf( textbuf, textlen,
			"objectClass \"%s\" not supported in context",
			oc->soc_oid );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
825

826
827
828
	return LDAP_SUCCESS;
}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
829
static int subentryObjectClass (
830
	Backend *be,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
831
832
833
834
835
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
836
837
	*text = textbuf;

838
839
840
841
842
843
844
845
	if( !SLAP_SUBENTRIES(be) ) {
		snprintf( textbuf, textlen,
			"objectClass \"%s\" not supported in context",
			oc->soc_oid );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	if( oc != slap_schema.si_oc_subentry && !is_entry_subentry( e ) ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
846
847
848
849
850
		snprintf( textbuf, textlen,
			"objectClass \"%s\" only allowed in subentries",
			oc->soc_oid );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
851

Kurt Zeilenga's avatar
Kurt Zeilenga committed
852
853
854
	return LDAP_SUCCESS;
}

855
856
857
858
859
860
861
static int dynamicObjectClass (
	Backend *be,
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
862
863
	*text = textbuf;

864
865
866
867
868
869
	if( !SLAP_DYNAMIC(be) ) {
		snprintf( textbuf, textlen,
			"objectClass \"%s\" not supported in context",
			oc->soc_oid );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
870

871
872
873
	return LDAP_SUCCESS;
}

874
static int rootDseAttribute (
875
	Backend *be,
876
877
878
879
880
881
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
882

883
884
	if( e->e_nname.bv_len ) {
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
885
			"attribute \"%s\" only allowed in the root DSE",
886
887
888
889
890
891
892
893
894
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	/* we should not be called for the root DSE */
	assert( 0 );
	return LDAP_SUCCESS;
}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
895
static int aliasAttribute (
896
	Backend *be,
897
898
899
900
901
902
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
903
904

	if( !SLAP_ALIASES(be) ) {
905
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
906
907
908
909
910
911
912
913
			"attribute \"%s\" not supported in context",
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	if( !is_entry_alias( e ) ) {
		snprintf( textbuf, textlen,
			"attribute \"%s\" only allowed in the alias",
914
915
916
917
918
919
920
921
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	return LDAP_SUCCESS;
}

static int referralAttribute (
922
	Backend *be,
923
924
925
926
927
928
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
929
930
931
932
933
934
935
936

	if( !SLAP_REFERRALS(be) ) {
		snprintf( textbuf, textlen,
			"attribute \"%s\" not supported in context",
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

937
938
	if( !is_entry_referral( e ) ) {
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
939
			"attribute \"%s\" only allowed in the referral",
940
941
942
943
944
945
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	return LDAP_SUCCESS;
}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972

static int subentryAttribute (
	Backend *be,
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;

	if( !SLAP_SUBENTRIES(be) ) {
		snprintf( textbuf, textlen,
			"attribute \"%s\" not supported in context",
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	if( !is_entry_subentry( e ) ) {
		snprintf( textbuf, textlen,
			"attribute \"%s\" only allowed in the subentry",
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	return LDAP_SUCCESS;
}

973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
static int administrativeRoleAttribute (
	Backend *be,
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;

	if( !SLAP_SUBENTRIES(be) ) {
		snprintf( textbuf, textlen,
			"attribute \"%s\" not supported in context",
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	snprintf( textbuf, textlen,
		"attribute \"%s\" not supported!",
		attr->a_desc->ad_cname.bv_val );
	return LDAP_OBJECT_CLASS_VIOLATION;
}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
995
996
997
998
999
1000
static int dynamicAttribute (
	Backend *be,
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )