schema_prep.c 30.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 )",
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
	{ "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
244
			"SINGLE-VALUE NO-USER-MODIFICATION 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
	{ "subschemaSubentry", "( 2.5.18.10 NAME 'subschemaSubentry' "
			"DESC 'RFC2252: name of controlling subschema entry' "
			"EQUALITY distinguishedNameMatch "
Kurt Zeilenga's avatar
Kurt Zeilenga committed
287
288
			"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
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
			"EQUALITY distinguishedNameMatch "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
Kurt Zeilenga's avatar
Kurt Zeilenga committed
295
			"NO-USER-MODIFICATION USAGE directoryOperation )",
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
	{ "supportedControl", "( 1.3.6.1.4.1.1466.101.120.13 "
			"NAME 'supportedControl' "
Kurt Zeilenga's avatar
Kurt Zeilenga committed
334
335
			"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
	char *sssm_name;
	size_t sssm_offset;
} syn_map[] = {
586
587
	{ "1.3.6.1.4.1.1466.115.121.1.40",
		offsetof(struct slap_internal_schema, si_syn_octetString) },
588
589
590
591
592
593
594
	{ "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 }
};

595
int
596
597
slap_schema_load( void )
{
598
	int i;
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
629
630
631

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

632
	for( i=0; ad_map[i].ssam_name; i++ ) {
633
634
		assert( ad_map[i].ssam_defn != NULL );
		{
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
			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 );
		}
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
		{
			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;
			}
		}
693
	}
694
695

	for( i=0; oc_map[i].ssom_name; i++ ) {
696
697
		assert( oc_map[i].ssom_defn != NULL );
		{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
698
699
700
			LDAPObjectClass *oc;
			int		code;
			const char	*err;
701

Kurt Zeilenga's avatar
Kurt Zeilenga committed
702
703
704
705
706
707
708
709
			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;
			}
710

Kurt Zeilenga's avatar
Kurt Zeilenga committed
711
712
713
714
715
716
			if ( oc->oc_oid == NULL ) {
				fprintf( stderr, "slap_schema_load: "
					"%s: objectclass has no OID\n",
					oc_map[i].ssom_name );
				return LDAP_OTHER;
			}
717

Kurt Zeilenga's avatar
Kurt Zeilenga committed
718
719
720
721
722
723
724
725
726
727
			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);
		}
728
729
730
		{
			ObjectClass ** ocp = (ObjectClass **)
				&(((char *) &slap_schema)[oc_map[i].ssom_offset]);
731

732
			assert( *ocp == NULL );
733

734
735
736
737
738
739
740
			*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;
			}
741

742
743
744
745
746
747
			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;
748
749
750
		}
	}

751
	slap_at_undefined.sat_syntax = slap_schema.si_syn_distinguishedName;
752
753
	slap_schema.si_at_undefined = &slap_at_undefined;

754
755
	return LDAP_SUCCESS;
}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
756

757
758
759
760
761
int
slap_schema_check( void )
{
	/* we should only be called once after schema_init() was called */
	assert( schema_init_done == 1 );
762

763
764
765
	++schema_init_done;
	return LDAP_SUCCESS;
}
766

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

Kurt Zeilenga's avatar
Kurt Zeilenga committed
776
777
778
779
780
781
782
783
784
785
786
787
	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;
}

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

797
798
799
800
801
802
	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
803

804
805
806
807
808
809
810
811
812
813
	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
814
815
	*text = textbuf;

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

823
824
825
	return LDAP_SUCCESS;
}

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

835
836
837
838
839
840
841
842
	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
843
844
845
846
847
		snprintf( textbuf, textlen,
			"objectClass \"%s\" only allowed in subentries",
			oc->soc_oid );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
848

Kurt Zeilenga's avatar
Kurt Zeilenga committed
849
850
851
	return LDAP_SUCCESS;
}

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

861
862
863
864
865
866
	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
867

868
869
870
	return LDAP_SUCCESS;
}

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

880
881
	if( e->e_nname.bv_len ) {
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
882
			"attribute \"%s\" only allowed in the root DSE",
883
884
885
886
887
888
889
890
891
			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
892
static int aliasAttribute (
893
	Backend *be,
894
895
896
897
898
899
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
900
901

	if( !SLAP_ALIASES(be) ) {
902
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
903
904
905
906
907
908
909
910
			"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",
911
912
913
914
915
916
917
918
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	return LDAP_SUCCESS;
}

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

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

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

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

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

970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
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
992
993
994
995
996
997
998
999
1000
static int dynamicAttribute (
	Backend *be,
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;