schema_prep.c 32.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
38
#if 1
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
39
40
	LDAP_LOG( CONFIG, ENTRY, 
		"> objectClassMatch(%s, %s)\n", value->bv_val, a->bv_val, 0 );
41
42
43
44
45
46
#else
	Debug( LDAP_DEBUG_TRACE, "> objectClassMatch(%s,%s)\n",
		value->bv_val, a->bv_val, 0 );
#endif
#endif

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

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

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

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

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

80
81
82
	return LDAP_SUCCESS;
}

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

99
100
#if 1
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
101
102
	LDAP_LOG( CONFIG, ENTRY, 
		"> structuralObjectClassMatch(%s, %s)\n", value->bv_val, a->bv_val, 0 );
103
104
105
106
107
108
#else
	Debug( LDAP_DEBUG_TRACE, "> structuralObjectClassMatch(%s,%s)\n",
		value->bv_val, a->bv_val, 0 );
#endif
#endif

109
110
111
112
113
114
115
116
117
118
	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;
	}
119

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

	*matchp = ( asserted != oc );

127
#if 1
128
#ifdef NEW_LOGGING
Julius Enarusai's avatar
   
Julius Enarusai committed
129
130
131
	LDAP_LOG( CONFIG, ENTRY, 
		"< structuralObjectClassMatch( %s, %s ) = %d\n",
		value->bv_val, a->bv_val, *matchp );
132
#else
133
	Debug( LDAP_DEBUG_TRACE, "< structuralObjectClassMatch(%s,%s) = %d\n",
134
		value->bv_val, a->bv_val, *matchp );
135
#endif
136
#endif
137
138
139

	return LDAP_SUCCESS;
}
140
#endif
141

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

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

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

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

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

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

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

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

450
451
452
453
	{ "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
454
		subentryAttribute, 0, NULL, NULL, NULL,
455
456
		offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) },

457
	/* knowledge information */
458
459
460
461
462
	{ "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 )",
463
		aliasAttribute, SLAP_AT_FINAL, NULL, NULL, NULL,
464
		offsetof(struct slap_internal_schema, si_ad_aliasedObjectName) },
465
466
467
468
469
	{ "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
470
		referralAttribute, 0, NULL, NULL, NULL,
471
472
		offsetof(struct slap_internal_schema, si_ad_ref) },

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

515
516
517
518
	{ "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
519
		dynamicAttribute, 0, NULL, NULL, NULL,
520
521
522
523
524
525
		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
526
		rootDseAttribute, 0, NULL, NULL, NULL,
527
528
		offsetof(struct slap_internal_schema, si_ad_dynamicSubtrees) },

529
	/* userApplication attributes (which system schema depends upon) */
530
531
532
533
	{ "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 )",
534
		NULL, SLAP_AT_ABSTRACT, NULL, NULL, NULL,
535
		offsetof(struct slap_internal_schema, si_ad_distinguishedName) },
536
537
538
539
540
	{ "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} )",
541
		NULL, SLAP_AT_ABSTRACT, NULL, NULL, NULL,
542
543
544
545
		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
546
		NULL, 0, NULL, NULL, NULL,
547
548
549
550
551
		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} )",
552
		NULL, 0, NULL, NULL, NULL,
553
		offsetof(struct slap_internal_schema, si_ad_userPassword) },
554
555

#ifdef SLAPD_AUTHPASSWD
556
557
558
559
560
	{ "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 )",
561
		NULL, 0,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
562
		NULL, NULL, NULL,
563
564
565
566
567
568
569
		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
570
		subschemaAttribute, 0, NULL, NULL, NULL,
571
		offsetof(struct slap_internal_schema, si_ad_authPassword) },
572
#endif
573
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
574
575
576
577
578
579
	{ "krbName", "( 1.3.6.1.4.1.250.1.32 "
			"NAME ( 'krbName' 'kerberosName' ) "
			"DESC 'Kerberos principal associated with object' "
			"EQUALITY caseIgnoreIA5Match "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 "
			"SINGLE-VALUE )",
580
		NULL, 0, NULL, NULL, NULL,
581
582
583
		offsetof(struct slap_internal_schema, si_ad_krbName) },
#endif

Kurt Zeilenga's avatar
Kurt Zeilenga committed
584
	{ NULL, NULL, NULL, 0, NULL, NULL, NULL, 0 }
585
586
};

587
588
589
static AttributeType slap_at_undefined = {
	{ "1.1.1", NULL, NULL, 1, NULL,
		NULL, NULL, NULL, NULL,
590
		0, 0, 0, 1, 3 }, /* LDAPAttributeType */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
591
	{ sizeof("UNDEFINED")-1, "UNDEFINED" }, /* cname */
592
593
594
595
	NULL, /* sup */
	NULL, /* subtypes */
	NULL, NULL, NULL, NULL,	/* matching rules */
	NULL, /* syntax (this may need to be defined) */
596
597
	(AttributeTypeSchemaCheckFN *) 0, /* schema check function */
	SLAP_AT_ABSTRACT|SLAP_AT_FINAL,	/* mask */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
598
599
	NULL, /* next */
	NULL /* attribute description */
600
	/* mutex (don't know how to initialize it :) */
601
};
602

Kurt Zeilenga's avatar
Kurt Zeilenga committed
603
static struct slap_schema_mr_map {
604
605
606
607
608
609
610
611
612
613
	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
614
static struct slap_schema_syn_map {
615
616
617
	char *sssm_name;
	size_t sssm_offset;
} syn_map[] = {
618
619
	{ "1.3.6.1.4.1.1466.115.121.1.40",
		offsetof(struct slap_internal_schema, si_syn_octetString) },
620
621
622
623
624
625
626
	{ "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 }
};

627
int
628
629
slap_schema_load( void )
{
630
	int i;
631
632
633
634
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

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

664
	for( i=0; ad_map[i].ssam_name; i++ ) {
665
666
		assert( ad_map[i].ssam_defn != NULL );
		{
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
693
694
695
			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 );
		}
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
		{
			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;
			}
		}
725
	}
726
727

	for( i=0; oc_map[i].ssom_name; i++ ) {
728
729
		assert( oc_map[i].ssom_defn != NULL );
		{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
730
731
732
			LDAPObjectClass *oc;
			int		code;
			const char	*err;
733

Kurt Zeilenga's avatar
Kurt Zeilenga committed
734
735
736
737
738
739
740
741
			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;
			}
742

Kurt Zeilenga's avatar
Kurt Zeilenga committed
743
744
745
746
747
748
			if ( oc->oc_oid == NULL ) {
				fprintf( stderr, "slap_schema_load: "
					"%s: objectclass has no OID\n",
					oc_map[i].ssom_name );
				return LDAP_OTHER;
			}
749

750
			code = oc_add(oc,0,&err);
Kurt Zeilenga's avatar
Kurt Zeilenga committed
751
752
753
754
755
756
757
758
759
			if ( code ) {
				fprintf( stderr, "slap_schema_load: "
					"%s: %s: \"%s\"\n",
				 	oc_map[i].ssom_name, scherr2str(code), err);
				return code;
			}

			ldap_memfree(oc);
		}
760
761
762
		{
			ObjectClass ** ocp = (ObjectClass **)
				&(((char *) &slap_schema)[oc_map[i].ssom_offset]);
763

764
			assert( *ocp == NULL );
765

766
767
768
769
770
771
772
			*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;
			}
773

774
775
776
777
778
779
			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;
780
781
782
		}
	}

783
	slap_at_undefined.sat_syntax = slap_schema.si_syn_distinguishedName;
784
785
	slap_schema.si_at_undefined = &slap_at_undefined;

786
787
	return LDAP_SUCCESS;
}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
788

789
790
791
792
793
int
slap_schema_check( void )
{
	/* we should only be called once after schema_init() was called */
	assert( schema_init_done == 1 );
794

795
796
797
	++schema_init_done;
	return LDAP_SUCCESS;
}
798

Kurt Zeilenga's avatar
Kurt Zeilenga committed
799
static int rootDseObjectClass (
800
	Backend *be,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
801
802
803
804
805
806
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
807

Kurt Zeilenga's avatar
Kurt Zeilenga committed
808
809
810
811
812
813
814
815
816
817
818
819
	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;
}

820
821
822
823
824
825
826
static int aliasObjectClass (
	Backend *be,
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
827
828
	*text = textbuf;

829
830
831
832
833
834
	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
835

836
837
838
839
840
841
842
843
844
845
	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
846
847
	*text = textbuf;

848
849
850
851
852
853
	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
854

855
856
857
	return LDAP_SUCCESS;
}

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

867
868
869
870
871
872
873
874
	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
875
876
877
878
879
		snprintf( textbuf, textlen,
			"objectClass \"%s\" only allowed in subentries",
			oc->soc_oid );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
880

Kurt Zeilenga's avatar
Kurt Zeilenga committed
881
882
883
	return LDAP_SUCCESS;
}

884
885
886
887
888
889
890
static int dynamicObjectClass (
	Backend *be,
	Entry *e,
	ObjectClass *oc,
	const char** text,
	char *textbuf, size_t textlen )
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
891
892
	*text = textbuf;

893
894
895
896
897
898
	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
899

900
901
902
	return LDAP_SUCCESS;
}

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

912
913
	if( e->e_nname.bv_len ) {
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
914
			"attribute \"%s\" only allowed in the root DSE",
915
916
917
918
919
920
921
922
923
			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
924
static int aliasAttribute (
925
	Backend *be,
926
927
928
929
930
931
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
932
933

	if( !SLAP_ALIASES(be) ) {
934
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
935
936
937
938
939
940
941
942
			"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",
943
944
945
946
947
948
949
950
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	return LDAP_SUCCESS;
}

static int referralAttribute (
951
	Backend *be,
952
953
954
955
956
957
	Entry *e,
	Attribute *attr,
	const char** text,
	char *textbuf, size_t textlen )
{
	*text = textbuf;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
958
959
960
961
962
963
964
965

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

966
967
	if( !is_entry_referral( e ) ) {
		snprintf( textbuf, textlen,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
968
			"attribute \"%s\" only allowed in the referral",
969
970
971
972
973
974
			attr->a_desc->ad_cname.bv_val );
		return LDAP_OBJECT_CLASS_VIOLATION;
	}

	return LDAP_SUCCESS;
}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000

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