schema_prep.c 31.7 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 )",
165
166
		0, SLAP_OC_OPERATIONAL,
		offsetof(struct slap_internal_schema, si_oc_extensibleObject) },
167
168
169
170
	{ "alias", "( 2.5.6.1 NAME 'alias' "
			"DESC 'RFC2256: an alias' "
			"SUP top STRUCTURAL "
			"MUST aliasedObjectName )",
171
		aliasObjectClass, SLAP_OC_ALIAS|SLAP_OC_OPERATIONAL,
172
		offsetof(struct slap_internal_schema, si_oc_alias) },
173
174
175
	{ "referral", "( 2.16.840.1.113730.3.2.6 NAME 'referral' "
			"DESC 'namedref: named subordinate referral' "
			"SUP top STRUCTURAL MUST ref )",
176
		referralObjectClass, SLAP_OC_REFERRAL|SLAP_OC_OPERATIONAL,
177
		offsetof(struct slap_internal_schema, si_oc_referral) },
178
179
180
	{ "LDAProotDSE", "( 1.3.6.1.4.1.4203.1.4.1 "
			"NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' ) "
			"DESC 'OpenLDAP Root DSE object' "
181
			"SUP top STRUCTURAL MAY cn )",
182
		rootDseObjectClass, SLAP_OC_OPERATIONAL,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
183
		offsetof(struct slap_internal_schema, si_oc_rootdse) },
184
185
186
	{ "subentry", "( 2.5.20.0 NAME 'subentry' "
			"SUP top STRUCTURAL "
			"MUST ( cn $ subtreeSpecification ) )",
187
		subentryObjectClass, SLAP_OC_SUBENTRY|SLAP_OC_OPERATIONAL,
188
		offsetof(struct slap_internal_schema, si_oc_subentry) },
189
190
	{ "subschema", "( 2.5.20.1 NAME 'subschema' "
		"DESC 'RFC2252: controlling subschema (sub)entry' "
Kurt Zeilenga's avatar
Kurt Zeilenga committed
191
		"AUXILIARY "
192
193
		"MAY ( dITStructureRules $ nameForms $ ditContentRules $ "
			"objectClasses $ attributeTypes $ matchingRules $ "
194
			"matchingRuleUse ) )",
195
		subentryObjectClass, SLAP_OC_OPERATIONAL,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
196
		offsetof(struct slap_internal_schema, si_oc_subschema) },
197
198
199
200
	{ "monitor", "( 1.3.6.1.4.1.4203.666.3.2 NAME 'monitor' "
		"DESC 'OpenLDAP system monitoring' "
		"STRUCTURAL "
		"MUST cn )",
201
202
		0, SLAP_OC_OPERATIONAL,
		offsetof(struct slap_internal_schema, si_oc_monitor) },
203
204
	{ "collectiveAttributeSubentry", "( 2.5.20.2 "
			"NAME 'collectiveAttributeSubentry' "
205
			"AUXILIARY )",
206
207
		subentryObjectClass,
		SLAP_OC_COLLECTIVEATTRIBUTESUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
208
		offsetof(struct slap_internal_schema, si_oc_collectiveAttributeSubentry) },
209
210
211
212
	{ "dynamicObject", "( 1.3.6.1.4.1.1466.101.119.2 "
			"NAME 'dynamicObject' "
			"DESC 'RFC2589: Dynamic Object' "
			"SUP top AUXILIARY )",
213
		dynamicObjectClass, SLAP_OC_DYNAMICOBJECT,
214
		offsetof(struct slap_internal_schema, si_oc_dynamicObject) },
Kurt Zeilenga's avatar
Kurt Zeilenga committed
215
	{ NULL, NULL, NULL, 0, 0 }
216
217
};

218
static AttributeTypeSchemaCheckFN rootDseAttribute;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
219
static AttributeTypeSchemaCheckFN aliasAttribute;
220
static AttributeTypeSchemaCheckFN referralAttribute;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
221
static AttributeTypeSchemaCheckFN subentryAttribute;
222
static AttributeTypeSchemaCheckFN administrativeRoleAttribute;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
223
static AttributeTypeSchemaCheckFN dynamicAttribute;
224

Kurt Zeilenga's avatar
Kurt Zeilenga committed
225
static struct slap_schema_ad_map {
226
	char *ssam_name;
227
228
	char *ssam_defn;
	AttributeTypeSchemaCheckFN *ssam_check;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
229
	slap_mask_t ssam_flags;
230
	slap_mr_match_func *ssam_match;
231
232
	slap_mr_indexer_func *ssam_indexer;
	slap_mr_filter_func *ssam_filter;
233
234
	size_t ssam_offset;
} ad_map[] = {
235
236
237
238
	{ "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 )",
239
		NULL, SLAP_AT_FINAL, objectClassMatch, NULL, NULL,
240
		offsetof(struct slap_internal_schema, si_ad_objectClass) },
241
242

	/* user entry operational attributes */
243
244
245
246
	{ "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 "
Kurt Zeilenga's avatar
Kurt Zeilenga committed
247
			"SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
248
		NULL, 0, structuralObjectClassMatch, NULL, NULL,
249
		offsetof(struct slap_internal_schema, si_ad_structuralObjectClass) },
250
251
252
253
254
255
	{ "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
256
		NULL, 0, NULL, NULL, NULL,
257
		offsetof(struct slap_internal_schema, si_ad_createTimestamp) },
258
259
260
261
262
263
	{ "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
264
		NULL, 0, NULL, NULL, NULL,
265
		offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) },
266
267
268
269
270
	{ "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
271
		NULL, 0, NULL, NULL, NULL,
272
273
274
275
276
277
		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
278
		NULL, 0, NULL, NULL, NULL,
279
280
281
282
283
284
		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
285
		NULL, 0, NULL, NULL, NULL,
286
		offsetof(struct slap_internal_schema, si_ad_hasSubordinates) },
287
288
289
	{ "subschemaSubentry", "( 2.5.18.10 NAME 'subschemaSubentry' "
			"DESC 'RFC2252: name of controlling subschema entry' "
			"EQUALITY distinguishedNameMatch "
Kurt Zeilenga's avatar
Kurt Zeilenga committed
290
291
			"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
292
		NULL, 0, NULL, NULL, NULL,
293
		offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },
294
295
	{ "collectiveAttributeSubentries", "( 2.5.18.12 "
			"NAME 'collectiveAttributeSubentries' "
296
297
			"EQUALITY distinguishedNameMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
Kurt Zeilenga's avatar
Kurt Zeilenga committed
298
			"NO-USER-MODIFICATION USAGE directoryOperation )",
299
		NULL, SLAP_AT_HIDE, NULL, NULL, NULL,
300
		offsetof(struct slap_internal_schema, si_ad_collectiveSubentries) },
301
302
303
304
	{ "collectiveExclusions", "( 2.5.18.7 NAME 'collectiveExclusions' "
			"EQUALITY objectIdentifierMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
			"USAGE directoryOperation )",
305
		NULL, SLAP_AT_HIDE, NULL, NULL, NULL,
306
		offsetof(struct slap_internal_schema, si_ad_collectiveExclusions) },
307

308
309
310
311
312
	{ "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 )",
313
		NULL, SLAP_AT_HIDE, NULL, NULL, NULL,
314
315
316
317
318
319
		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 )",
320
		NULL, SLAP_AT_HIDE, NULL, NULL, NULL,
321
322
		offsetof(struct slap_internal_schema, si_ad_entryCSN) },

323
	/* root DSE attributes */
324
325
326
	{ "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
327
		rootDseAttribute, 0, NULL, NULL, NULL,
328
		offsetof(struct slap_internal_schema, si_ad_altServer) },
329
330
331
332
	{ "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
333
		rootDseAttribute, 0, NULL, NULL, NULL,
334
		offsetof(struct slap_internal_schema, si_ad_namingContexts) },
335
336
	{ "supportedControl", "( 1.3.6.1.4.1.1466.101.120.13 "
			"NAME 'supportedControl' "
Kurt Zeilenga's avatar
Kurt Zeilenga committed
337
338
			"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
339
		rootDseAttribute, 0, NULL, NULL, NULL,
340
		offsetof(struct slap_internal_schema, si_ad_supportedControl) },
341
342
343
344
	{ "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
345
		rootDseAttribute, 0, NULL, NULL, NULL,
346
		offsetof(struct slap_internal_schema, si_ad_supportedExtension) },
347
348
349
350
	{ "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
351
		rootDseAttribute, 0, NULL, NULL, NULL,
352
		offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) },
353
354
355
356
	{ "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
357
		rootDseAttribute, 0, NULL, NULL, NULL,
358
		offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) },
359
360
361
362
363
364
	{ "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
365
		rootDseAttribute, 0, NULL, NULL, NULL,
366
		offsetof(struct slap_internal_schema, si_ad_supportedFeatures) },
367
368
369
370
371
372
	{ "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
373
		rootDseAttribute, 0, NULL, NULL, NULL,
374
375
376
377
378
379
380
		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
381
		rootDseAttribute, 0, NULL, NULL, NULL,
382
383
384
385
386
387
388
		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 )",
389
		administrativeRoleAttribute, SLAP_AT_HIDE, NULL, NULL, NULL,
390
391
392
393
394
		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 )",
395
		subentryAttribute, SLAP_AT_HIDE, NULL, NULL, NULL,
396
		offsetof(struct slap_internal_schema, si_ad_subtreeSpecification) },
397

398
	/* subschema subentry attributes */
399
400
401
402
403
	{ "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 ) ",
404
		subentryAttribute, SLAP_AT_HIDE, NULL, NULL, NULL,
405
406
407
408
409
		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 )",
410
		subentryAttribute, SLAP_AT_HIDE, NULL, NULL, NULL,
411
		offsetof(struct slap_internal_schema, si_ad_ditContentRules) },
412
413
414
415
	{ "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
416
		subentryAttribute, 0, NULL, NULL, NULL,
417
		offsetof(struct slap_internal_schema, si_ad_matchingRules) },
418
419
420
421
	{ "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
422
		subentryAttribute, 0, NULL, NULL, NULL,
423
424
425
426
427
		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
428
		subentryAttribute, 0, NULL, NULL, NULL,
429
		offsetof(struct slap_internal_schema, si_ad_objectClasses) },
430
431
432
433
	{ "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 )",
434
		subentryAttribute, SLAP_AT_HIDE, NULL, NULL, NULL,
435
		offsetof(struct slap_internal_schema, si_ad_nameForms) },
436
	{ "matchingRuleUse", "( 2.5.21.8 NAME 'matchingRuleUse' "
437
438
439
			"DESC 'RFC2252: matching rule uses' "
			"EQUALITY objectIdentifierFirstComponentMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation )",
440
		subentryAttribute, SLAP_AT_HIDE, NULL, NULL, NULL,
441
		offsetof(struct slap_internal_schema, si_ad_matchingRuleUse) },
442

443
444
445
446
	{ "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
447
		subentryAttribute, 0, NULL, NULL, NULL,
448
449
		offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) },

450
	/* knowledge information */
451
452
453
454
455
	{ "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 )",
456
		aliasAttribute, SLAP_AT_FINAL, NULL, NULL, NULL,
457
		offsetof(struct slap_internal_schema, si_ad_aliasedObjectName) },
458
459
460
461
462
	{ "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
463
		referralAttribute, 0, NULL, NULL, NULL,
464
465
		offsetof(struct slap_internal_schema, si_ad_ref) },

Kurt Zeilenga's avatar
Kurt Zeilenga committed
466
	/* access control internals */
467
468
469
470
471
	{ "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 )",
472
		NULL, SLAP_AT_HIDE, NULL, NULL, NULL,
473
		offsetof(struct slap_internal_schema, si_ad_entry) },
474
475
476
477
478
	{ "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 )",
479
		NULL, SLAP_AT_HIDE, NULL, NULL, NULL,
480
		offsetof(struct slap_internal_schema, si_ad_children) },
Howard Chu's avatar
Howard Chu committed
481
	{ "saslAuthzTo", "( 1.3.6.1.4.1.4203.1.3.6 "
482
483
484
485
486
487
488
			"NAME 'saslAuthzTo' "
			"DESC 'SASL proxy authorization targets' "
			"EQUALITY caseExactMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
			"USAGE dSAOperation )",
		NULL, 0, NULL, NULL, NULL,
		offsetof(struct slap_internal_schema, si_ad_saslAuthzTo) },
Howard Chu's avatar
Howard Chu committed
489
	{ "saslAuthzFrom", "( 1.3.6.1.4.1.4203.1.3.7 "
490
491
492
493
494
495
496
			"NAME 'saslAuthzFrom' "
			"DESC 'SASL proxy authorization sources' "
			"EQUALITY caseExactMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
			"USAGE dSAOperation )",
		NULL, 0, NULL, NULL, NULL,
		offsetof(struct slap_internal_schema, si_ad_saslAuthzFrom) },
497
#ifdef SLAPD_ACI_ENABLED
498
499
500
501
502
503
	{ "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
504
		NULL, 0, NULL, NULL, NULL,
505
506
		offsetof(struct slap_internal_schema, si_ad_aci) },
#endif
507

508
509
510
511
	{ "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
512
		dynamicAttribute, 0, NULL, NULL, NULL,
513
514
515
516
517
518
		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
519
		rootDseAttribute, 0, NULL, NULL, NULL,
520
521
		offsetof(struct slap_internal_schema, si_ad_dynamicSubtrees) },

522
	/* userApplication attributes (which system schema depends upon) */
523
524
525
526
	{ "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 )",
527
		NULL, SLAP_AT_ABSTRACT, NULL, NULL, NULL,
528
		offsetof(struct slap_internal_schema, si_ad_distinguishedName) },
529
530
531
532
533
	{ "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} )",
534
		NULL, SLAP_AT_ABSTRACT, NULL, NULL, NULL,
535
536
537
538
		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
539
		NULL, 0, NULL, NULL, NULL,
540
541
542
543
544
		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} )",
545
		NULL, 0, NULL, NULL, NULL,
546
		offsetof(struct slap_internal_schema, si_ad_userPassword) },
547
548

#ifdef SLAPD_AUTHPASSWD
549
550
551
552
553
	{ "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 )",
554
		NULL, 0,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
555
		NULL, NULL, NULL,
556
557
558
559
560
561
562
		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
563
		subschemaAttribute, 0, NULL, NULL, NULL,
564
		offsetof(struct slap_internal_schema, si_ad_authPassword) },
565
#endif
566
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
567
	{ "krbName", NULL,
568
		NULL, 0, NULL, NULL, NULL,
569
570
571
		offsetof(struct slap_internal_schema, si_ad_krbName) },
#endif

Kurt Zeilenga's avatar
Kurt Zeilenga committed
572
	{ NULL, NULL, NULL, 0, NULL, NULL, NULL, 0 }
573
574
};

575
576
577
static AttributeType slap_at_undefined = {
	{ "1.1.1", NULL, NULL, 1, NULL,
		NULL, NULL, NULL, NULL,
578
		0, 0, 0, 1, 3 }, /* LDAPAttributeType */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
579
	{ sizeof("UNDEFINED")-1, "UNDEFINED" }, /* cname */
580
581
582
583
	NULL, /* sup */
	NULL, /* subtypes */
	NULL, NULL, NULL, NULL,	/* matching rules */
	NULL, /* syntax (this may need to be defined) */
584
585
	(AttributeTypeSchemaCheckFN *) 0, /* schema check function */
	SLAP_AT_ABSTRACT|SLAP_AT_FINAL,	/* mask */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
586
587
	NULL, /* next */
	NULL /* attribute description */
588
	/* mutex (don't know how to initialize it :) */
589
};
590

Kurt Zeilenga's avatar
Kurt Zeilenga committed
591
static struct slap_schema_mr_map {
592
593
594
595
596
597
598
599
600
601
	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
602
static struct slap_schema_syn_map {
603
604
605
	char *sssm_name;
	size_t sssm_offset;
} syn_map[] = {
606
607
	{ "1.3.6.1.4.1.1466.115.121.1.40",
		offsetof(struct slap_internal_schema, si_syn_octetString) },
608
609
610
611
612
613
614
	{ "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 }
};

615
int
616
617
slap_schema_load( void )
{
618
	int i;
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651

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

		assert( *synp == NULL );

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

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

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

		assert( *mrp == NULL );

		*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;
		}
	}

652
	for( i=0; ad_map[i].ssam_name; i++ ) {
653
654
		assert( ad_map[i].ssam_defn != NULL );
		{
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
			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 );
		}
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
		{
			int rc;
			const char *text;

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

			assert( *adp == NULL );

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

			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;

			if( ad_map[i].ssam_match ) {
				/* install custom matching routine */
				(*adp)->ad_type->sat_equality->smr_match = ad_map[i].ssam_match;
			}
		}
713
	}
714
715

	for( i=0; oc_map[i].ssom_name; i++ ) {
716
717
		assert( oc_map[i].ssom_defn != NULL );
		{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
718
719
720
			LDAPObjectClass *oc;
			int		code;
			const char	*err;
721

Kurt Zeilenga's avatar
Kurt Zeilenga committed
722
723
724
725
726
727
728
729
			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;
			}
730

Kurt Zeilenga's avatar
Kurt Zeilenga committed
731
732
733
734
735
736
			if ( oc->oc_oid == NULL ) {
				fprintf( stderr, "slap_schema_load: "
					"%s: objectclass has no OID\n",
					oc_map[i].ssom_name );
				return LDAP_OTHER;
			}
737

738
			code = oc_add(oc,0,&err);
Kurt Zeilenga's avatar
Kurt Zeilenga committed
739
740
741
742
743
744
745
746
747
			if ( code ) {
				fprintf( stderr, "slap_schema_load: "
					"%s: %s: \"%s\"\n",
				 	oc_map[i].ssom_name, scherr2str(code), err);
				return code;
			}

			ldap_memfree(oc);
		}
748
749
750
		{
			ObjectClass ** ocp = (ObjectClass **)
				&(((char *) &slap_schema)[oc_map[i].ssom_offset]);
751

752
			assert( *ocp == NULL );
753

754
755
756
757
758
759
760
			*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;
			}
761

762
763
764
765
766
767
			if( oc_map[i].ssom_check ) {
				/* install check routine */
				(*ocp)->soc_check = oc_map[i].ssom_check;
			}
			/* install flags */
			(*ocp)->soc_flags |= oc_map[i].ssom_flags;
768
769
770
		}
	}

771
	slap_at_undefined.sat_syntax = slap_schema.si_syn_distinguishedName;
772
773
	slap_schema.si_at_undefined = &slap_at_undefined;

774
775
	return LDAP_SUCCESS;
}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
776

777
778
779
780
781
int
slap_schema_check( void )
{
	/* we should only be called once after schema_init() was called */
	assert( schema_init_done == 1 );
782

783
784
785
	++schema_init_done;
	return LDAP_SUCCESS;
}
786

Kurt Zeilenga's avatar
Kurt Zeilenga committed
787
static int rootDseObjectClass (
788
	Backend *be,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
789
790
791
792
793
794
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
795

Kurt Zeilenga's avatar
Kurt Zeilenga committed
796
797
798
799
800
801
802
803
804
805
806
807
	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;
}

808
809
810
811
812
813
814
static int aliasObjectClass (
	Backend *be,
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
815
816
	*text = textbuf;

817
818
819
820
821
822
	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
823

824
825
826
827
828
829
830
831
832
833
	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
834
835
	*text = textbuf;

836
837
838
839
840
841
	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
842

843
844
845
	return LDAP_SUCCESS;
}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
846
static int subentryObjectClass (
847
	Backend *be,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
848
849
850
851
852
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
853
854
	*text = textbuf;

855
856
857
858
859
860
861
862
	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
863
864
865
866
867
		snprintf( textbuf, textlen,
			"objectClass \"%s\" only allowed in subentries",
			oc->soc_oid );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
868

Kurt Zeilenga's avatar
Kurt Zeilenga committed
869
870
871
	return LDAP_SUCCESS;
}

872
873
874
875
876
877
878
static int dynamicObjectClass (
	Backend *be,
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
879
880
	*text = textbuf;

881
882
883
884
885
886
	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
887

888
889
890
	return LDAP_SUCCESS;
}

891
static int rootDseAttribute (
892
	Backend *be,
893
894
895
896
897
898
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
899

900
901
	if( e->e_nname.bv_len ) {
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
902
			"attribute \"%s\" only allowed in the root DSE",
903
904
905
906
907
908
909
910
911
			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
912
static int aliasAttribute (
913
	Backend *be,
914
915
916
917
918
919
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
920
921

	if( !SLAP_ALIASES(be) ) {
922
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
923
924
925
926
927
928
929
930
			"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",
931
932
933
934
935
936
937
938
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	return LDAP_SUCCESS;
}

static int referralAttribute (
939
	Backend *be,
940
941
942
943
944
945
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
946
947
948
949
950
951
952
953

	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;
	}

954
955
	if( !is_entry_referral( e ) ) {
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
956
			"attribute \"%s\" only allowed in the referral",
957
958
959
960
961
962
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	return LDAP_SUCCESS;
}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989

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;
}

990
991
992
993
994
995
996
997
998
999
1000
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,