schema_prep.c 30.2 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
	if( asserted == NULL ) {
38
		if( OID_LEADCHAR( *a->bv_val ) ) {
39
40
41
42
43
44
			/* OID form, return FALSE */
			*matchp = 1;
			return LDAP_SUCCESS;
		}

		/* desc form, return undefined */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
45
		return SLAPD_COMPARE_UNDEFINED;
46
47
48
	}

	if ( oc == NULL ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
49
50
		/* unrecognized stored value */
		return SLAPD_COMPARE_UNDEFINED;
51
52
	}

53
	if( SLAP_IS_MR_VALUE_SYNTAX_MATCH( flags ) ) {
54
55
56
57
58
		*matchp = ( asserted != oc );
	} else {
		*matchp = !is_object_subclass( asserted, oc );
	}

59
#if 0
60
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
61
62
63
	LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
		   "objectClassMatch(%s, %s) = %d\n",
		   value->bv_val, a->bv_val, *matchp ));
64
#else
65
66
	Debug( LDAP_DEBUG_TRACE, "objectClassMatch(%s,%s) = %d\n",
		value->bv_val, a->bv_val, *matchp );
67
#endif
68
69
#endif

70
71
72
73
74
75
	return LDAP_SUCCESS;
}

static int
structuralObjectClassMatch(
	int *matchp,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
76
	slap_mask_t flags,
77
78
79
80
81
82
	Syntax *syntax,
	MatchingRule *mr,
	struct berval *value,
	void *assertedValue )
{
	struct berval *a = (struct berval *) assertedValue;
Howard Chu's avatar
Howard Chu committed
83
84
	ObjectClass *oc = oc_bvfind( value );
	ObjectClass *asserted = oc_bvfind( a );
85
86
87
88
89
90
91
92
93
94
95

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

97
98
99
100
101
102
103
104
	if ( oc == NULL ) {
		/* unrecognized stored value */
		return SLAPD_COMPARE_UNDEFINED;
	}

	*matchp = ( asserted != oc );

#if 0
105
#ifdef NEW_LOGGING
Gary Williams's avatar
Gary Williams committed
106
107
108
	LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
		   "structuralObjectClassMatch( %s, %s ) = %d\n",
		   value->bv_val, a->bv_val, *matchp ));
109
#else
110
111
	Debug( LDAP_DEBUG_TRACE, "structuralObjectClassMatch(%s,%s) = %d\n",
		value->bv_val, a->bv_val, *matchp );
112
#endif
113
#endif
114
115
116
117

	return LDAP_SUCCESS;
}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
118
static ObjectClassSchemaCheckFN rootDseObjectClass;
119
120
static ObjectClassSchemaCheckFN aliasObjectClass;
static ObjectClassSchemaCheckFN referralObjectClass;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
121
static ObjectClassSchemaCheckFN subentryObjectClass;
122
static ObjectClassSchemaCheckFN dynamicObjectClass;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
123

Kurt Zeilenga's avatar
Kurt Zeilenga committed
124
static struct slap_schema_oc_map {
125
	char *ssom_name;
126
127
	char *ssom_defn;
	ObjectClassSchemaCheckFN *ssom_check;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
128
	slap_mask_t ssom_flags;
129
130
	size_t ssom_offset;
} oc_map[] = {
131
132
133
	{ "top", "( 2.5.6.0 NAME 'top' "
			"DESC 'top of the superclass chain' "
			"ABSTRACT MUST objectClass )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
134
		0, 0, offsetof(struct slap_internal_schema, si_oc_top) },
135
136
137
138
	{ "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
139
		0, 0, offsetof(struct slap_internal_schema, si_oc_extensibleObject) },
140
141
142
143
	{ "alias", "( 2.5.6.1 NAME 'alias' "
			"DESC 'RFC2256: an alias' "
			"SUP top STRUCTURAL "
			"MUST aliasedObjectName )",
144
		aliasObjectClass, SLAP_OC_ALIAS,
145
		offsetof(struct slap_internal_schema, si_oc_alias) },
146
147
148
	{ "referral", "( 2.16.840.1.113730.3.2.6 NAME 'referral' "
			"DESC 'namedref: named subordinate referral' "
			"SUP top STRUCTURAL MUST ref )",
149
		referralObjectClass, SLAP_OC_REFERRAL,
150
		offsetof(struct slap_internal_schema, si_oc_referral) },
151
152
153
	{ "LDAProotDSE", "( 1.3.6.1.4.1.4203.1.4.1 "
			"NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' ) "
			"DESC 'OpenLDAP Root DSE object' "
154
			"SUP top STRUCTURAL MAY cn )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
155
		rootDseObjectClass, 0,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
156
		offsetof(struct slap_internal_schema, si_oc_rootdse) },
157
158
159
	{ "subentry", "( 2.5.20.0 NAME 'subentry' "
			"SUP top STRUCTURAL "
			"MUST ( cn $ subtreeSpecification ) )",
Howard Chu's avatar
Howard Chu committed
160
		subentryObjectClass, SLAP_OC_SUBENTRY,
161
		offsetof(struct slap_internal_schema, si_oc_subentry) },
162
163
	{ "subschema", "( 2.5.20.1 NAME 'subschema' "
		"DESC 'RFC2252: controlling subschema (sub)entry' "
Kurt Zeilenga's avatar
Kurt Zeilenga committed
164
		"AUXILIARY "
165
166
		"MAY ( dITStructureRules $ nameForms $ ditContentRules $ "
			"objectClasses $ attributeTypes $ matchingRules $ "
167
			"matchingRuleUse ) )",
Howard Chu's avatar
Howard Chu committed
168
		subentryObjectClass, 0,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
169
		offsetof(struct slap_internal_schema, si_oc_subschema) },
170
171
172
173
	{ "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
174
		0, 0, offsetof(struct slap_internal_schema, si_oc_monitor) },
175
176
	{ "collectiveAttributes", "( 2.5.20.2 "
			"NAME 'collectiveAttributes' "
177
			"AUXILIARY )",
178
		subentryObjectClass, SLAP_OC_COLLECTIVEATTRIBUTES,
179
		offsetof(struct slap_internal_schema, si_oc_collectiveAttributes) },
180
181
182
183
	{ "dynamicObject", "( 1.3.6.1.4.1.1466.101.119.2 "
			"NAME 'dynamicObject' "
			"DESC 'RFC2589: Dynamic Object' "
			"SUP top AUXILIARY )",
184
		dynamicObjectClass, SLAP_OC_DYNAMICOBJECT,
185
		offsetof(struct slap_internal_schema, si_oc_dynamicObject) },
Kurt Zeilenga's avatar
Kurt Zeilenga committed
186
	{ NULL, NULL, NULL, 0, 0 }
187
188
};

189
static AttributeTypeSchemaCheckFN rootDseAttribute;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
190
static AttributeTypeSchemaCheckFN aliasAttribute;
191
static AttributeTypeSchemaCheckFN referralAttribute;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
192
static AttributeTypeSchemaCheckFN subentryAttribute;
193
static AttributeTypeSchemaCheckFN administrativeRoleAttribute;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
194
static AttributeTypeSchemaCheckFN dynamicAttribute;
195

Kurt Zeilenga's avatar
Kurt Zeilenga committed
196
static struct slap_schema_ad_map {
197
	char *ssam_name;
198
199
	char *ssam_defn;
	AttributeTypeSchemaCheckFN *ssam_check;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
200
	slap_mask_t ssam_flags;
201
	slap_mr_match_func *ssam_match;
202
203
	slap_mr_indexer_func *ssam_indexer;
	slap_mr_filter_func *ssam_filter;
204
205
	size_t ssam_offset;
} ad_map[] = {
206
207
208
209
	{ "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 )",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
210
		NULL, 0,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
211
		objectClassMatch, NULL, NULL,
212
		offsetof(struct slap_internal_schema, si_ad_objectClass) },
213
214

	/* user entry operational attributes */
215
216
217
218
219
	{ "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
220
		NULL, 0, structuralObjectClassMatch, NULL, NULL,
221
		offsetof(struct slap_internal_schema, si_ad_structuralObjectClass) },
222
223
224
225
226
227
	{ "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
228
		NULL, 0, NULL, NULL, NULL,
229
		offsetof(struct slap_internal_schema, si_ad_createTimestamp) },
230
231
232
233
234
235
	{ "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
236
		NULL, 0, NULL, NULL, NULL,
237
		offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) },
238
239
240
241
242
	{ "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
243
		NULL, 0, NULL, NULL, NULL,
244
245
246
247
248
249
		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
250
		NULL, 0, NULL, NULL, NULL,
251
252
253
254
255
256
		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
257
		NULL, 0, NULL, NULL, NULL,
258
		offsetof(struct slap_internal_schema, si_ad_hasSubordinates) },
259
260
261
262
263
	{ "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
264
		NULL, 0, NULL, NULL, NULL,
265
		offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },
266
267
	{ "collectiveAttributeSubentry", "( 2.5.18.12 "
			"NAME 'collectiveAttributeSubentry' "
268
269
270
			"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
271
		NULL, 0, NULL, NULL, NULL,
272
273
274
275
276
		offsetof(struct slap_internal_schema, si_ad_collectiveSubentry) },
	{ "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
277
		NULL, 0, NULL, NULL, NULL,
278
		offsetof(struct slap_internal_schema, si_ad_collectiveExclusions) },
279

280
281
282
283
284
	{ "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
285
		NULL, 0, NULL, NULL, NULL,
286
287
288
289
290
291
		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
292
		NULL, 0, NULL, NULL, NULL,
293
294
		offsetof(struct slap_internal_schema, si_ad_entryCSN) },

295
	/* root DSE attributes */
296
297
298
	{ "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
299
		rootDseAttribute, 0, NULL, NULL, NULL,
300
		offsetof(struct slap_internal_schema, si_ad_altServer) },
301
302
303
304
	{ "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
305
		rootDseAttribute, 0, NULL, NULL, NULL,
306
		offsetof(struct slap_internal_schema, si_ad_namingContexts) },
307
308
309
310
	{ "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
311
		rootDseAttribute, 0, NULL, NULL, NULL,
312
		offsetof(struct slap_internal_schema, si_ad_supportedControl) },
313
314
315
316
	{ "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
317
		rootDseAttribute, 0, NULL, NULL, NULL,
318
		offsetof(struct slap_internal_schema, si_ad_supportedExtension) },
319
320
321
322
	{ "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
323
		rootDseAttribute, 0, NULL, NULL, NULL,
324
		offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) },
325
326
327
328
	{ "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
329
		rootDseAttribute, 0, NULL, NULL, NULL,
330
		offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) },
331
332
333
334
335
336
	{ "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
337
		rootDseAttribute, 0, NULL, NULL, NULL,
338
		offsetof(struct slap_internal_schema, si_ad_supportedFeatures) },
339
340
341
342
343
344
	{ "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
345
		rootDseAttribute, 0, NULL, NULL, NULL,
346
347
348
349
350
351
352
		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
353
		rootDseAttribute, 0, NULL, NULL, NULL,
354
355
356
357
358
359
360
		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 )",
361
		administrativeRoleAttribute, 0, NULL, NULL, NULL,
362
363
364
365
366
		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
367
		subentryAttribute, 0, NULL, NULL, NULL,
368
		offsetof(struct slap_internal_schema, si_ad_subtreeSpecification) },
369

370
	/* subschema subentry attributes */
371
372
373
374
375
	{ "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
376
		subentryAttribute, 0, NULL, NULL, NULL,
377
378
379
380
381
		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
382
		subentryAttribute, 0, NULL, NULL, NULL,
383
		offsetof(struct slap_internal_schema, si_ad_ditContentRules) },
384
385
386
387
	{ "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
388
		subentryAttribute, 0, NULL, NULL, NULL,
389
		offsetof(struct slap_internal_schema, si_ad_matchingRules) },
390
391
392
393
	{ "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
394
		subentryAttribute, 0, NULL, NULL, NULL,
395
396
397
398
399
		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
400
		subentryAttribute, 0, NULL, NULL, NULL,
401
		offsetof(struct slap_internal_schema, si_ad_objectClasses) },
402
403
404
405
	{ "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
406
		subentryAttribute, 0, NULL, NULL, NULL,
407
		offsetof(struct slap_internal_schema, si_ad_nameForms) },
408
	{ "matchingRuleUse", "( 2.5.21.8 NAME 'matchingRuleUse' "
409
410
411
			"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
412
		subentryAttribute, 0, NULL, NULL, NULL,
413
		offsetof(struct slap_internal_schema, si_ad_matchingRuleUse) },
414

415
416
417
418
	{ "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
419
		subentryAttribute, 0, NULL, NULL, NULL,
420
421
		offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) },

422
	/* knowledge information */
423
424
425
426
427
	{ "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
428
		aliasAttribute, 0, NULL, NULL, NULL,
429
		offsetof(struct slap_internal_schema, si_ad_aliasedObjectName) },
430
431
432
433
434
	{ "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
435
		referralAttribute, 0, NULL, NULL, NULL,
436
437
		offsetof(struct slap_internal_schema, si_ad_ref) },

Kurt Zeilenga's avatar
Kurt Zeilenga committed
438
	/* access control internals */
439
440
441
442
443
	{ "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
444
		NULL, 0, NULL, NULL, NULL,
445
		offsetof(struct slap_internal_schema, si_ad_entry) },
446
447
448
449
450
	{ "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
451
		NULL, 0, NULL, NULL, NULL,
452
		offsetof(struct slap_internal_schema, si_ad_children) },
453
#ifdef SLAPD_ACI_ENABLED
454
455
456
457
458
459
	{ "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
460
		NULL, 0, NULL, NULL, NULL,
461
462
		offsetof(struct slap_internal_schema, si_ad_aci) },
#endif
463

464
465
466
467
	{ "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
468
		dynamicAttribute, 0, NULL, NULL, NULL,
469
470
471
472
473
474
		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
475
		rootDseAttribute, 0, NULL, NULL, NULL,
476
477
		offsetof(struct slap_internal_schema, si_ad_dynamicSubtrees) },

478
	/* userApplication attributes (which system schema depends upon) */
479
480
481
482
	{ "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
483
		NULL, 0, NULL, NULL, NULL,
484
		offsetof(struct slap_internal_schema, si_ad_distinguishedName) },
485
486
487
488
489
	{ "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
490
		NULL, 0, NULL, NULL, NULL,
491
492
493
494
		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
495
		NULL, 0, NULL, NULL, NULL,
496
497
498
499
500
		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
501
		NULL, 0, NULL, NULL, NULL,
502
		offsetof(struct slap_internal_schema, si_ad_userPassword) },
503
504

#ifdef SLAPD_AUTHPASSWD
505
506
507
508
509
	{ "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
510
511
		NULL, 0,
		NULL, NULL, NULL,
512
513
514
515
516
517
518
		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
519
		subschemaAttribute, 0, NULL, NULL, NULL,
520
		offsetof(struct slap_internal_schema, si_ad_authPassword) },
521
#endif
522
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
523
	{ "krbName", NULL,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
524
		NULL, 0, NULL, NULL, NULL,
525
526
527
		offsetof(struct slap_internal_schema, si_ad_krbName) },
#endif

Kurt Zeilenga's avatar
Kurt Zeilenga committed
528
	{ NULL, NULL, NULL, 0, NULL, NULL, NULL, 0 }
529
530
};

531
532
533
static AttributeType slap_at_undefined = {
	{ "1.1.1", NULL, NULL, 1, NULL,
		NULL, NULL, NULL, NULL,
534
		0, 0, 0, 1, 3 }, /* LDAPAttributeType */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
535
	{ sizeof("UNDEFINED")-1, "UNDEFINED" }, /* cname */
536
537
538
539
	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
540
	(AttributeTypeSchemaCheckFN *) 0, 0, /* schema check function/mask */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
541
542
	NULL, /* next */
	NULL /* attribute description */
543
	/* mutex (don't know how to initialize it :) */
544
};
545

Kurt Zeilenga's avatar
Kurt Zeilenga committed
546
static struct slap_schema_mr_map {
547
548
549
550
551
552
553
554
555
556
	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
557
static struct slap_schema_syn_map {
558
559
560
561
562
563
564
565
566
567
	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 }
};

568
int
569
570
slap_schema_load( void )
{
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
	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 );
		}
	}
604
605

	for( i=0; oc_map[i].ssom_name; i++ ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
606
607
608
609
		if( oc_map[i].ssom_defn != NULL ) {
			LDAPObjectClass *oc;
			int		code;
			const char	*err;
610

Kurt Zeilenga's avatar
Kurt Zeilenga committed
611
612
613
614
615
616
617
618
			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;
			}
619

Kurt Zeilenga's avatar
Kurt Zeilenga committed
620
621
622
623
624
625
			if ( oc->oc_oid == NULL ) {
				fprintf( stderr, "slap_schema_load: "
					"%s: objectclass has no OID\n",
					oc_map[i].ssom_name );
				return LDAP_OTHER;
			}
626

Kurt Zeilenga's avatar
Kurt Zeilenga committed
627
628
629
630
631
632
633
634
635
636
			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);
		}
637
638
	}

639
640
641
642
643
	return LDAP_SUCCESS;
}

int
slap_schema_check( void )
644
645
646
647
648
{
	int i;
	/* we should only be called once after schema_init() was called */
	assert( schema_init_done == 1 );

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

653
654
		assert( *synp == NULL );

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

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

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

669
670
		assert( *mrp == NULL );

671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
		*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;

689
690
691
692
693
694
695
	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]);

696
		assert( *adp == NULL );
697
698
699

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

Kurt Zeilenga's avatar
Kurt Zeilenga committed
706
707
708
709
710
711
712
		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;

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

719
720
721
	for( i=0; oc_map[i].ssom_name; i++ ) {
		ObjectClass ** ocp = (ObjectClass **)
			&(((char *) &slap_schema)[oc_map[i].ssom_offset]);
722

723
724
		assert( *ocp == NULL );

725
726
727
728
729
730
		*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;
731
		}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
732
733
734

		if( oc_map[i].ssom_check ) {
			/* install check routine */
735
			(*ocp)->soc_check = oc_map[i].ssom_check;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
736
737
		}
		/* install flags */
738
		(*ocp)->soc_flags |= oc_map[i].ssom_flags;
739
740
	}

741
742
743
	++schema_init_done;
	return LDAP_SUCCESS;
}
744

Kurt Zeilenga's avatar
Kurt Zeilenga committed
745
static int rootDseObjectClass (
746
	Backend *be,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
747
748
749
750
751
752
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
753

Kurt Zeilenga's avatar
Kurt Zeilenga committed
754
755
756
757
758
759
760
761
762
763
764
765
	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;
}

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

775
776
777
778
779
780
	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
781

782
783
784
785
786
787
788
789
790
791
	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
792
793
	*text = textbuf;

794
795
796
797
798
799
	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
800

801
802
803
	return LDAP_SUCCESS;
}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
804
static int subentryObjectClass (
805
	Backend *be,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
806
807
808
809
810
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
811
812
	*text = textbuf;

813
814
815
816
817
818
819
820
	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
821
822
823
824
825
		snprintf( textbuf, textlen,
			"objectClass \"%s\" only allowed in subentries",
			oc->soc_oid );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
826

Kurt Zeilenga's avatar
Kurt Zeilenga committed
827
828
829
	return LDAP_SUCCESS;
}

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

839
840
841
842
843
844
	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
845

846
847
848
	return LDAP_SUCCESS;
}

849
static int rootDseAttribute (
850
	Backend *be,
851
852
853
854
855
856
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
857

858
859
	if( e->e_nname.bv_len ) {
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
860
			"attribute \"%s\" only allowed in the root DSE",
861
862
863
864
865
866
867
868
869
			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
870
static int aliasAttribute (
871
	Backend *be,
872
873
874
875
876
877
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
878
879

	if( !SLAP_ALIASES(be) ) {
880
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
881
882
883
884
885
886
887
888
			"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",
889
890
891
892
893
894
895
896
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	return LDAP_SUCCESS;
}

static int referralAttribute (
897
	Backend *be,
898
899
900
901
902
903
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
904
905
906
907
908
909
910
911

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

912
913
	if( !is_entry_referral( e ) ) {
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
914
			"attribute \"%s\" only allowed in the referral",
915
916
917
918
919
920
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	return LDAP_SUCCESS;
}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947

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

948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
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
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
static int dynamicAttribute (
	Backend *be,
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;

	if( !SLAP_DYNAMIC(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_dynamicObject( e ) ) {
		snprintf( textbuf, textlen,
			"attribute \"%s\" only allowed in dynamic object",
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	return LDAP_SUCCESS;
}