schema_prep.c 9.25 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 struct slap_schema_oc_map {
119
120
121
	char *ssom_name;
	size_t ssom_offset;
} oc_map[] = {
122
	{ "top", offsetof(struct slap_internal_schema, si_oc_top) },
Kurt Zeilenga's avatar
Kurt Zeilenga committed
123
	{ "extensibleObject", offsetof(struct slap_internal_schema, si_oc_extensibleObject) },
124
125
	{ "alias", offsetof(struct slap_internal_schema, si_oc_alias) },
	{ "referral", offsetof(struct slap_internal_schema, si_oc_referral) },
126
127
128
	{ "LDAProotDSE", offsetof(struct slap_internal_schema, si_oc_rootdse) },
	{ "LDAPsubentry", offsetof(struct slap_internal_schema, si_oc_subentry) },
	{ "subschema", offsetof(struct slap_internal_schema, si_oc_subschema) },
129
130
131
	{ NULL, 0 }
};

Kurt Zeilenga's avatar
Kurt Zeilenga committed
132
static struct slap_schema_ad_map {
133
134
	char *ssam_name;
	slap_mr_match_func *ssam_match;
135
136
	slap_mr_indexer_func *ssam_indexer;
	slap_mr_filter_func *ssam_filter;
137
138
	size_t ssam_offset;
} ad_map[] = {
139
	{ "objectClass",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
140
		objectClassMatch, NULL, NULL,
141
		offsetof(struct slap_internal_schema, si_ad_objectClass) },
142
	{ "structuralObjectClass",
Kurt Zeilenga's avatar
Kurt Zeilenga committed
143
		structuralObjectClassMatch, NULL, NULL,
144
		offsetof(struct slap_internal_schema, si_ad_structuralObjectClass) },
145

146
	/* user entry operational attributes */
147
148
149
150
	{ "entryUUID", NULL, NULL, NULL,
		offsetof(struct slap_internal_schema, si_ad_entryUUID) },
	{ "entryCSN", NULL, NULL, NULL,
		offsetof(struct slap_internal_schema, si_ad_entryCSN) },
151
	{ "creatorsName", NULL, NULL, NULL,
152
		offsetof(struct slap_internal_schema, si_ad_creatorsName) },
153
	{ "createTimestamp", NULL, NULL, NULL,
154
		offsetof(struct slap_internal_schema, si_ad_createTimestamp) },
155
	{ "modifiersName", NULL, NULL, NULL,
156
		offsetof(struct slap_internal_schema, si_ad_modifiersName) },
157
	{ "modifyTimestamp", NULL, NULL, NULL,
158
		offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) },
159
160
	{ "hasSubordinates", NULL, NULL, NULL,
		offsetof(struct slap_internal_schema, si_ad_hasSubordinates) },
161
	{ "subschemaSubentry", NULL, NULL, NULL,
162
163
		offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },

164
	/* root DSE attributes */
165
	{ "namingContexts", NULL, NULL, NULL,
166
		offsetof(struct slap_internal_schema, si_ad_namingContexts) },
167
	{ "supportedControl", NULL, NULL, NULL,
168
		offsetof(struct slap_internal_schema, si_ad_supportedControl) },
169
	{ "supportedExtension", NULL, NULL, NULL,
170
		offsetof(struct slap_internal_schema, si_ad_supportedExtension) },
171
	{ "supportedLDAPVersion", NULL, NULL, NULL,
172
		offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) },
173
	{ "supportedSASLMechanisms", NULL, NULL, NULL,
174
		offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) },
175
176
	{ "supportedFeatures", NULL, NULL, NULL,
		offsetof(struct slap_internal_schema, si_ad_supportedFeatures) },
177

178
	/* subschema subentry attributes */
179
	{ "attributeTypes", NULL, NULL, NULL,
180
		offsetof(struct slap_internal_schema, si_ad_attributeTypes) },
181
	{ "ldapSyntaxes", NULL, NULL, NULL,
182
		offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) },
183
	{ "matchingRules", NULL, NULL, NULL,
184
		offsetof(struct slap_internal_schema, si_ad_matchingRules) },
185
	{ "objectClasses", NULL, NULL, NULL,
186
187
		offsetof(struct slap_internal_schema, si_ad_objectClasses) },

188
	/* knowledge information */
189
	{ "aliasedObjectName", NULL, NULL, NULL,
190
		offsetof(struct slap_internal_schema, si_ad_aliasedObjectName) },
191
	{ "ref", NULL, NULL, NULL,
192
193
		offsetof(struct slap_internal_schema, si_ad_ref) },

Kurt Zeilenga's avatar
Kurt Zeilenga committed
194
	/* access control internals */
195
	{ "entry", NULL, NULL, NULL,
196
		offsetof(struct slap_internal_schema, si_ad_entry) },
197
	{ "children", NULL, NULL, NULL,
198
		offsetof(struct slap_internal_schema, si_ad_children) },
199
#ifdef SLAPD_ACI_ENABLED
200
	{ "OpenLDAPaci", NULL, NULL, NULL,
201
202
		offsetof(struct slap_internal_schema, si_ad_aci) },
#endif
203

204
	{ "userPassword", NULL, NULL, NULL,
205
		offsetof(struct slap_internal_schema, si_ad_userPassword) },
206
	{ "authPassword", NULL, NULL, NULL,
207
208
		offsetof(struct slap_internal_schema, si_ad_authPassword) },
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
209
	{ "krbName", NULL, NULL, NULL,
210
211
212
		offsetof(struct slap_internal_schema, si_ad_krbName) },
#endif

213
	{ NULL, NULL, NULL, NULL, 0 }
214
215
};

216
217
218
static AttributeType slap_at_undefined = {
	{ "1.1.1", NULL, NULL, 1, NULL,
		NULL, NULL, NULL, NULL,
219
		0, 0, 0, 1, 3 }, /* LDAPAttributeType */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
220
	{ sizeof("UNDEFINED")-1, "UNDEFINED" }, /* cname */
221
222
223
224
	NULL, /* sup */
	NULL, /* subtypes */
	NULL, NULL, NULL, NULL,	/* matching rules */
	NULL, /* syntax (this may need to be defined) */
225
	NULL, /* attribute description */
226
	NULL  /* next */
227
	/* mutex (don't know how to initialize it :) */
228
};
229

Kurt Zeilenga's avatar
Kurt Zeilenga committed
230
static struct slap_schema_mr_map {
231
232
233
234
235
236
237
238
239
240
	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
241
static struct slap_schema_syn_map {
242
243
244
245
246
247
248
249
250
251
	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 }
};

252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
int
schema_prep( void )
{
	int i;
	/* we should only be called once after schema_init() was called */
	assert( schema_init_done == 1 );

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

		*ocp = oc_find( oc_map[i].ssom_name );

		if( *ocp == NULL ) {
			fprintf( stderr,
				"No objectClass \"%s\" defined in schema\n",
				oc_map[i].ssom_name );
			return LDAP_OBJECT_CLASS_VIOLATION;
		}
	}

	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]);

		*adp = NULL;

		rc = slap_str2ad( ad_map[i].ssam_name, adp, &text );

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

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

297
298
299
300
301
302
	slap_at_undefined.sat_syntax = syn_find( SLAPD_OCTETSTRING_SYNTAX );
	if( slap_at_undefined.sat_syntax == NULL ) {
		fprintf( stderr,
			"No octetString syntax \"" SLAPD_OCTETSTRING_SYNTAX "\"\n" );
		return LDAP_INVALID_SYNTAX;
	}
303
304
	slap_schema.si_at_undefined = &slap_at_undefined;

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
	for( i=0; mr_map[i].ssmm_name; i++ ) {
		MatchingRule ** mrp = (MatchingRule **)
			&(((char *) &slap_schema)[mr_map[i].ssmm_offset]);

		*mrp = mr_find( mr_map[i].ssmm_name );

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

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

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

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

333
334
335
	++schema_init_done;
	return LDAP_SUCCESS;
}