~ttx/openldap/lucid-gssapi-495418

« back to all changes in this revision

Viewing changes to servers/slapd/schema_prep.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug
  • Date: 2008-07-10 14:45:49 UTC
  • Revision ID: james.westby@ubuntu.com-20080710144549-wck73med0e72gfyo
Tags: upstream-2.4.10
ImportĀ upstreamĀ versionĀ 2.4.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* schema_prep.c - load builtin schema */
 
2
/* $OpenLDAP: pkg/ldap/servers/slapd/schema_prep.c,v 1.169.2.6 2008/02/11 23:26:44 kurt Exp $ */
 
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 
4
 *
 
5
 * Copyright 1998-2008 The OpenLDAP Foundation.
 
6
 * All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted only as authorized by the OpenLDAP
 
10
 * Public License.
 
11
 *
 
12
 * A copy of this license is available in the file LICENSE in the
 
13
 * top-level directory of the distribution or, alternatively, at
 
14
 * <http://www.OpenLDAP.org/license.html>.
 
15
 */
 
16
 
 
17
#include "portable.h"
 
18
 
 
19
#include <stdio.h>
 
20
 
 
21
#include <ac/ctype.h>
 
22
#include <ac/string.h>
 
23
#include <ac/socket.h>
 
24
 
 
25
#include "slap.h"
 
26
 
 
27
#define OCDEBUG 0
 
28
 
 
29
int schema_init_done = 0;
 
30
 
 
31
struct slap_internal_schema slap_schema;
 
32
 
 
33
static int
 
34
oidValidate(
 
35
        Syntax *syntax,
 
36
        struct berval *in )
 
37
{
 
38
        struct berval val = *in;
 
39
 
 
40
        if( val.bv_len == 0 ) {
 
41
                /* disallow empty strings */
 
42
                return LDAP_INVALID_SYNTAX;
 
43
        }
 
44
 
 
45
        if( DESC_LEADCHAR( val.bv_val[0] ) ) {
 
46
                val.bv_val++;
 
47
                val.bv_len--;
 
48
                if ( val.bv_len == 0 ) return LDAP_SUCCESS;
 
49
 
 
50
                while( DESC_CHAR( val.bv_val[0] ) ) {
 
51
                        val.bv_val++;
 
52
                        val.bv_len--;
 
53
 
 
54
                        if ( val.bv_len == 0 ) return LDAP_SUCCESS;
 
55
                }
 
56
 
 
57
        } else {
 
58
                int sep = 0;
 
59
                while( OID_LEADCHAR( val.bv_val[0] ) ) {
 
60
                        val.bv_val++;
 
61
                        val.bv_len--;
 
62
 
 
63
                        if ( val.bv_val[-1] != '0' ) {
 
64
                                while ( OID_LEADCHAR( val.bv_val[0] )) {
 
65
                                        val.bv_val++;
 
66
                                        val.bv_len--;
 
67
                                }
 
68
                        }
 
69
 
 
70
                        if( val.bv_len == 0 ) {
 
71
                                if( sep == 0 ) break;
 
72
                                return LDAP_SUCCESS;
 
73
                        }
 
74
 
 
75
                        if( !OID_SEPARATOR( val.bv_val[0] )) break;
 
76
 
 
77
                        sep++;
 
78
                        val.bv_val++;
 
79
                        val.bv_len--;
 
80
                }
 
81
        }
 
82
 
 
83
        return LDAP_INVALID_SYNTAX;
 
84
}
 
85
 
 
86
 
 
87
static int objectClassPretty(
 
88
        Syntax *syntax,
 
89
        struct berval *in,
 
90
        struct berval *out,
 
91
        void *ctx )
 
92
{
 
93
        ObjectClass *oc;
 
94
 
 
95
        if( oidValidate( NULL, in )) return LDAP_INVALID_SYNTAX;
 
96
 
 
97
        oc = oc_bvfind( in );
 
98
        if( oc == NULL ) return LDAP_INVALID_SYNTAX;
 
99
 
 
100
        ber_dupbv_x( out, &oc->soc_cname, ctx );
 
101
        return LDAP_SUCCESS;
 
102
}
 
103
 
 
104
static int
 
105
attributeTypeMatch(
 
106
        int *matchp,
 
107
        slap_mask_t flags,
 
108
        Syntax *syntax,
 
109
        MatchingRule *mr,
 
110
        struct berval *value,
 
111
        void *assertedValue )
 
112
{
 
113
        struct berval *a = (struct berval *) assertedValue;
 
114
        AttributeType *at = at_bvfind( value );
 
115
        AttributeType *asserted = at_bvfind( a );
 
116
 
 
117
        if( asserted == NULL ) {
 
118
                if( OID_LEADCHAR( *a->bv_val ) ) {
 
119
                        /* OID form, return FALSE */
 
120
                        *matchp = 1;
 
121
                        return LDAP_SUCCESS;
 
122
                }
 
123
 
 
124
                /* desc form, return undefined */
 
125
                return LDAP_INVALID_SYNTAX;
 
126
        }
 
127
 
 
128
        if ( at == NULL ) {
 
129
                /* unrecognized stored value */
 
130
                return LDAP_INVALID_SYNTAX;
 
131
        }
 
132
 
 
133
        *matchp = ( asserted != at );
 
134
        return LDAP_SUCCESS;
 
135
}
 
136
 
 
137
static int
 
138
matchingRuleMatch(
 
139
        int *matchp,
 
140
        slap_mask_t flags,
 
141
        Syntax *syntax,
 
142
        MatchingRule *mr,
 
143
        struct berval *value,
 
144
        void *assertedValue )
 
145
{
 
146
        struct berval *a = (struct berval *) assertedValue;
 
147
        MatchingRule *mrv = mr_bvfind( value );
 
148
        MatchingRule *asserted = mr_bvfind( a );
 
149
 
 
150
        if( asserted == NULL ) {
 
151
                if( OID_LEADCHAR( *a->bv_val ) ) {
 
152
                        /* OID form, return FALSE */
 
153
                        *matchp = 1;
 
154
                        return LDAP_SUCCESS;
 
155
                }
 
156
 
 
157
                /* desc form, return undefined */
 
158
                return LDAP_INVALID_SYNTAX;
 
159
        }
 
160
 
 
161
        if ( mrv == NULL ) {
 
162
                /* unrecognized stored value */
 
163
                return LDAP_INVALID_SYNTAX;
 
164
        }
 
165
 
 
166
        *matchp = ( asserted != mrv );
 
167
        return LDAP_SUCCESS;
 
168
}
 
169
 
 
170
static int
 
171
objectClassMatch(
 
172
        int *matchp,
 
173
        slap_mask_t flags,
 
174
        Syntax *syntax,
 
175
        MatchingRule *mr,
 
176
        struct berval *value,
 
177
        void *assertedValue )
 
178
{
 
179
        struct berval *a = (struct berval *) assertedValue;
 
180
        ObjectClass *oc = oc_bvfind( value );
 
181
        ObjectClass *asserted = oc_bvfind( a );
 
182
 
 
183
        if( asserted == NULL ) {
 
184
                if( OID_LEADCHAR( *a->bv_val ) ) {
 
185
                        /* OID form, return FALSE */
 
186
                        *matchp = 1;
 
187
                        return LDAP_SUCCESS;
 
188
                }
 
189
 
 
190
                /* desc form, return undefined */
 
191
                return LDAP_INVALID_SYNTAX;
 
192
        }
 
193
 
 
194
        if ( oc == NULL ) {
 
195
                /* unrecognized stored value */
 
196
                return LDAP_INVALID_SYNTAX;
 
197
        }
 
198
 
 
199
        *matchp = ( asserted != oc );
 
200
        return LDAP_SUCCESS;
 
201
}
 
202
 
 
203
static int
 
204
objectSubClassMatch(
 
205
        int *matchp,
 
206
        slap_mask_t flags,
 
207
        Syntax *syntax,
 
208
        MatchingRule *mr,
 
209
        struct berval *value,
 
210
        void *assertedValue )
 
211
{
 
212
        struct berval *a = (struct berval *) assertedValue;
 
213
        ObjectClass *oc = oc_bvfind( value );
 
214
        ObjectClass *asserted = oc_bvfind( a );
 
215
 
 
216
        if( asserted == NULL ) {
 
217
                if( OID_LEADCHAR( *a->bv_val ) ) {
 
218
                        /* OID form, return FALSE */
 
219
                        *matchp = 1;
 
220
                        return LDAP_SUCCESS;
 
221
                }
 
222
 
 
223
                /* desc form, return undefined */
 
224
                return LDAP_INVALID_SYNTAX;
 
225
        }
 
226
 
 
227
        if ( oc == NULL ) {
 
228
                /* unrecognized stored value */
 
229
                return LDAP_INVALID_SYNTAX;
 
230
        }
 
231
 
 
232
        if( SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX( flags ) ) {
 
233
                *matchp = ( asserted != oc );
 
234
        } else {
 
235
                *matchp = !is_object_subclass( asserted, oc );
 
236
        }
 
237
 
 
238
        return LDAP_SUCCESS;
 
239
}
 
240
 
 
241
static int objectSubClassIndexer( 
 
242
        slap_mask_t use,
 
243
        slap_mask_t mask,
 
244
        Syntax *syntax,
 
245
        MatchingRule *mr,
 
246
        struct berval *prefix,
 
247
        BerVarray values,
 
248
        BerVarray *keysp,
 
249
        void *ctx )
 
250
{
 
251
        int rc, noc, i;
 
252
        BerVarray ocvalues;
 
253
        ObjectClass **socs;
 
254
        
 
255
        for( noc=0; values[noc].bv_val != NULL; noc++ ) {
 
256
                /* just count em */;
 
257
        }
 
258
 
 
259
        /* over allocate */
 
260
        socs = slap_sl_malloc( (noc+16) * sizeof( ObjectClass * ), ctx );
 
261
 
 
262
        /* initialize */
 
263
        for( i=0; i<noc; i++ ) {
 
264
                socs[i] = oc_bvfind( &values[i] );
 
265
        }
 
266
 
 
267
        /* expand values */
 
268
        for( i=0; i<noc; i++ ) {
 
269
                int j;
 
270
                ObjectClass *oc = socs[i];
 
271
                if( oc == NULL || oc->soc_sups == NULL ) continue;
 
272
                
 
273
                for( j=0; oc->soc_sups[j] != NULL; j++ ) {
 
274
                        int found = 0;
 
275
                        ObjectClass *sup = oc->soc_sups[j];
 
276
                        int k;
 
277
 
 
278
                        for( k=0; k<noc; k++ ) {
 
279
                                if( sup == socs[k] ) {
 
280
                                        found++;
 
281
                                        break;
 
282
                                }
 
283
                        }
 
284
 
 
285
                        if( !found ) {
 
286
                                socs = slap_sl_realloc( socs,
 
287
                                        sizeof( ObjectClass * ) * (noc+2), ctx );
 
288
 
 
289
                                assert( k == noc );
 
290
                                socs[noc++] = sup;
 
291
                        }
 
292
                }
 
293
        }
 
294
 
 
295
        ocvalues = slap_sl_malloc( sizeof( struct berval ) * (noc+1), ctx );
 
296
        /* copy values */
 
297
        for( i=0; i<noc; i++ ) {
 
298
                if ( socs[i] )
 
299
                        ocvalues[i] = socs[i]->soc_cname;
 
300
                else
 
301
                        ocvalues[i] = values[i];
 
302
        }
 
303
        BER_BVZERO( &ocvalues[i] );
 
304
 
 
305
        rc = octetStringIndexer( use, mask, syntax, mr,
 
306
                prefix, ocvalues, keysp, ctx );
 
307
 
 
308
        slap_sl_free( ocvalues, ctx );
 
309
        slap_sl_free( socs, ctx );
 
310
        return rc;
 
311
}
 
312
 
 
313
#define objectSubClassFilter octetStringFilter
 
314
 
 
315
static ObjectClassSchemaCheckFN rootDseObjectClass;
 
316
static ObjectClassSchemaCheckFN aliasObjectClass;
 
317
static ObjectClassSchemaCheckFN referralObjectClass;
 
318
static ObjectClassSchemaCheckFN subentryObjectClass;
 
319
#ifdef LDAP_DYNAMIC_OBJECTS
 
320
static ObjectClassSchemaCheckFN dynamicObjectClass;
 
321
#endif
 
322
 
 
323
static struct slap_schema_oc_map {
 
324
        char *ssom_name;
 
325
        char *ssom_defn;
 
326
        ObjectClassSchemaCheckFN *ssom_check;
 
327
        slap_mask_t ssom_flags;
 
328
        size_t ssom_offset;
 
329
} oc_map[] = {
 
330
        { "top", "( 2.5.6.0 NAME 'top' "
 
331
                        "DESC 'top of the superclass chain' "
 
332
                        "ABSTRACT MUST objectClass )",
 
333
                0, 0, offsetof(struct slap_internal_schema, si_oc_top) },
 
334
        { "extensibleObject", "( 1.3.6.1.4.1.1466.101.120.111 "
 
335
                        "NAME 'extensibleObject' "
 
336
                        "DESC 'RFC4512: extensible object' "
 
337
                        "SUP top AUXILIARY )",
 
338
                0, SLAP_OC_OPERATIONAL,
 
339
                offsetof(struct slap_internal_schema, si_oc_extensibleObject) },
 
340
        { "alias", "( 2.5.6.1 NAME 'alias' "
 
341
                        "DESC 'RFC4512: an alias' "
 
342
                        "SUP top STRUCTURAL "
 
343
                        "MUST aliasedObjectName )",
 
344
                aliasObjectClass, SLAP_OC_ALIAS|SLAP_OC_OPERATIONAL,
 
345
                offsetof(struct slap_internal_schema, si_oc_alias) },
 
346
        { "referral", "( 2.16.840.1.113730.3.2.6 NAME 'referral' "
 
347
                        "DESC 'namedref: named subordinate referral' "
 
348
                        "SUP top STRUCTURAL MUST ref )",
 
349
                referralObjectClass, SLAP_OC_REFERRAL|SLAP_OC_OPERATIONAL,
 
350
                offsetof(struct slap_internal_schema, si_oc_referral) },
 
351
        { "LDAProotDSE", "( 1.3.6.1.4.1.4203.1.4.1 "
 
352
                        "NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' ) "
 
353
                        "DESC 'OpenLDAP Root DSE object' "
 
354
                        "SUP top STRUCTURAL MAY cn )",
 
355
                rootDseObjectClass, SLAP_OC_OPERATIONAL,
 
356
                offsetof(struct slap_internal_schema, si_oc_rootdse) },
 
357
        { "subentry", "( 2.5.17.0 NAME 'subentry' "
 
358
                        "DESC 'RFC3672: subentry' "
 
359
                        "SUP top STRUCTURAL "
 
360
                        "MUST ( cn $ subtreeSpecification ) )",
 
361
                subentryObjectClass, SLAP_OC_SUBENTRY|SLAP_OC_OPERATIONAL,
 
362
                offsetof(struct slap_internal_schema, si_oc_subentry) },
 
363
        { "subschema", "( 2.5.20.1 NAME 'subschema' "
 
364
                "DESC 'RFC4512: controlling subschema (sub)entry' "
 
365
                "AUXILIARY "
 
366
                "MAY ( dITStructureRules $ nameForms $ dITContentRules $ "
 
367
                        "objectClasses $ attributeTypes $ matchingRules $ "
 
368
                        "matchingRuleUse ) )",
 
369
                subentryObjectClass, SLAP_OC_OPERATIONAL,
 
370
                offsetof(struct slap_internal_schema, si_oc_subschema) },
 
371
#ifdef LDAP_COLLECTIVE_ATTRIBUTES
 
372
        { "collectiveAttributeSubentry", "( 2.5.17.2 "
 
373
                        "NAME 'collectiveAttributeSubentry' "
 
374
                        "DESC 'RFC3671: collective attribute subentry' "
 
375
                        "AUXILIARY )",
 
376
                subentryObjectClass,
 
377
                SLAP_OC_COLLECTIVEATTRIBUTESUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 
378
                offsetof( struct slap_internal_schema,
 
379
                        si_oc_collectiveAttributeSubentry) },
 
380
#endif
 
381
#ifdef LDAP_DYNAMIC_OBJECTS
 
382
        { "dynamicObject", "( 1.3.6.1.4.1.1466.101.119.2 "
 
383
                        "NAME 'dynamicObject' "
 
384
                        "DESC 'RFC2589: Dynamic Object' "
 
385
                        "SUP top AUXILIARY )",
 
386
                dynamicObjectClass, SLAP_OC_DYNAMICOBJECT,
 
387
                offsetof(struct slap_internal_schema, si_oc_dynamicObject) },
 
388
#endif
 
389
        { "glue", "( 1.3.6.1.4.1.4203.666.3.4 "
 
390
                        "NAME 'glue' "
 
391
                        "DESC 'Glue Entry' "
 
392
                        "SUP top STRUCTURAL )",
 
393
                0, SLAP_OC_GLUE|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 
394
                offsetof(struct slap_internal_schema, si_oc_glue) },
 
395
        { "syncConsumerSubentry", "( 1.3.6.1.4.1.4203.666.3.5 "
 
396
                        "NAME 'syncConsumerSubentry' "
 
397
                        "DESC 'Persistent Info for SyncRepl Consumer' "
 
398
                        "AUXILIARY "
 
399
                        "MAY syncreplCookie )",
 
400
                0, SLAP_OC_SYNCCONSUMERSUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 
401
                offsetof(struct slap_internal_schema, si_oc_syncConsumerSubentry) },
 
402
        { "syncProviderSubentry", "( 1.3.6.1.4.1.4203.666.3.6 "
 
403
                        "NAME 'syncProviderSubentry' "
 
404
                        "DESC 'Persistent Info for SyncRepl Producer' "
 
405
                        "AUXILIARY "
 
406
                        "MAY contextCSN )",
 
407
                0, SLAP_OC_SYNCPROVIDERSUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 
408
                offsetof(struct slap_internal_schema, si_oc_syncProviderSubentry) },
 
409
 
 
410
        { NULL, NULL, NULL, 0, 0 }
 
411
};
 
412
 
 
413
static AttributeTypeSchemaCheckFN rootDseAttribute;
 
414
static AttributeTypeSchemaCheckFN aliasAttribute;
 
415
static AttributeTypeSchemaCheckFN referralAttribute;
 
416
static AttributeTypeSchemaCheckFN subentryAttribute;
 
417
static AttributeTypeSchemaCheckFN administrativeRoleAttribute;
 
418
#ifdef LDAP_DYNAMIC_OBJECTS
 
419
static AttributeTypeSchemaCheckFN dynamicAttribute;
 
420
#endif
 
421
 
 
422
static struct slap_schema_ad_map {
 
423
        char *ssam_name;
 
424
        char *ssam_defn;
 
425
        AttributeTypeSchemaCheckFN *ssam_check;
 
426
        slap_mask_t ssam_flags;
 
427
        slap_syntax_validate_func *ssam_syn_validate;
 
428
        slap_syntax_transform_func *ssam_syn_pretty;
 
429
        slap_mr_convert_func *ssam_mr_convert;
 
430
        slap_mr_normalize_func *ssam_mr_normalize;
 
431
        slap_mr_match_func *ssam_mr_match;
 
432
        slap_mr_indexer_func *ssam_mr_indexer;
 
433
        slap_mr_filter_func *ssam_mr_filter;
 
434
        size_t ssam_offset;
 
435
} ad_map[] = {
 
436
        { "objectClass", "( 2.5.4.0 NAME 'objectClass' "
 
437
                        "DESC 'RFC4512: object classes of the entity' "
 
438
                        "EQUALITY objectIdentifierMatch "
 
439
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
 
440
                NULL, SLAP_AT_FINAL,
 
441
                oidValidate, objectClassPretty,
 
442
                NULL, NULL, objectSubClassMatch,
 
443
                        objectSubClassIndexer, objectSubClassFilter,
 
444
                offsetof(struct slap_internal_schema, si_ad_objectClass) },
 
445
 
 
446
        /* user entry operational attributes */
 
447
        { "structuralObjectClass", "( 2.5.21.9 NAME 'structuralObjectClass' "
 
448
                        "DESC 'RFC4512: structural object class of entry' "
 
449
                        "EQUALITY objectIdentifierMatch "
 
450
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
 
451
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
 
452
                NULL, SLAP_AT_MANAGEABLE,
 
453
                oidValidate, objectClassPretty,
 
454
                NULL, NULL, objectSubClassMatch,
 
455
                        objectSubClassIndexer, objectSubClassFilter,
 
456
                offsetof(struct slap_internal_schema, si_ad_structuralObjectClass) },
 
457
        { "createTimestamp", "( 2.5.18.1 NAME 'createTimestamp' "
 
458
                        "DESC 'RFC4512: time which object was created' "
 
459
                        "EQUALITY generalizedTimeMatch "
 
460
                        "ORDERING generalizedTimeOrderingMatch "
 
461
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
 
462
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
 
463
                NULL, SLAP_AT_MANAGEABLE,
 
464
                NULL, NULL,
 
465
                NULL, NULL, NULL, NULL, NULL,
 
466
                offsetof(struct slap_internal_schema, si_ad_createTimestamp) },
 
467
        { "modifyTimestamp", "( 2.5.18.2 NAME 'modifyTimestamp' "
 
468
                        "DESC 'RFC4512: time which object was last modified' "
 
469
                        "EQUALITY generalizedTimeMatch "
 
470
                        "ORDERING generalizedTimeOrderingMatch "
 
471
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
 
472
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
 
473
                NULL, SLAP_AT_MANAGEABLE,
 
474
                NULL, NULL,
 
475
                NULL, NULL, NULL, NULL, NULL,
 
476
                offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) },
 
477
        { "creatorsName", "( 2.5.18.3 NAME 'creatorsName' "
 
478
                        "DESC 'RFC4512: name of creator' "
 
479
                        "EQUALITY distinguishedNameMatch "
 
480
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
 
481
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
 
482
                NULL, SLAP_AT_MANAGEABLE,
 
483
                NULL, NULL,
 
484
                NULL, NULL, NULL, NULL, NULL,
 
485
                offsetof(struct slap_internal_schema, si_ad_creatorsName) },
 
486
        { "modifiersName", "( 2.5.18.4 NAME 'modifiersName' "
 
487
                        "DESC 'RFC4512: name of last modifier' "
 
488
                        "EQUALITY distinguishedNameMatch "
 
489
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
 
490
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
 
491
                NULL, SLAP_AT_MANAGEABLE,
 
492
                NULL, NULL,
 
493
                NULL, NULL, NULL, NULL, NULL,
 
494
                offsetof(struct slap_internal_schema, si_ad_modifiersName) },
 
495
        { "hasSubordinates", "( 2.5.18.9 NAME 'hasSubordinates' "
 
496
                        "DESC 'X.501: entry has children' "
 
497
                        "EQUALITY booleanMatch "
 
498
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
 
499
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
 
500
                NULL, SLAP_AT_DYNAMIC,
 
501
                NULL, NULL,
 
502
                NULL, NULL, NULL, NULL, NULL,
 
503
                offsetof(struct slap_internal_schema, si_ad_hasSubordinates) },
 
504
        { "subschemaSubentry", "( 2.5.18.10 NAME 'subschemaSubentry' "
 
505
                        "DESC 'RFC4512: name of controlling subschema entry' "
 
506
                        "EQUALITY distinguishedNameMatch "
 
507
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE "
 
508
                        "NO-USER-MODIFICATION USAGE directoryOperation )",
 
509
                NULL, SLAP_AT_DYNAMIC,
 
510
                NULL, NULL,
 
511
                NULL, NULL, NULL, NULL, NULL,
 
512
                offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },
 
513
#ifdef LDAP_COLLECTIVE_ATTRIBUTES
 
514
        { "collectiveAttributeSubentries", "( 2.5.18.12 "
 
515
                        "NAME 'collectiveAttributeSubentries' "
 
516
                        "DESC 'RFC3671: collective attribute subentries' "
 
517
                        "EQUALITY distinguishedNameMatch "
 
518
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
 
519
                        "NO-USER-MODIFICATION USAGE directoryOperation )",
 
520
                NULL, SLAP_AT_HIDE,
 
521
                NULL, NULL,
 
522
                NULL, NULL, NULL, NULL, NULL,
 
523
                offsetof(struct slap_internal_schema, si_ad_collectiveSubentries) },
 
524
        { "collectiveExclusions", "( 2.5.18.7 NAME 'collectiveExclusions' "
 
525
                        "DESC 'RFC3671: collective attribute exclusions' "
 
526
                        "EQUALITY objectIdentifierMatch "
 
527
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
 
528
                        "USAGE directoryOperation )",
 
529
                NULL, SLAP_AT_HIDE,
 
530
                NULL, NULL,
 
531
                NULL, NULL, NULL, NULL, NULL,
 
532
                offsetof(struct slap_internal_schema, si_ad_collectiveExclusions) },
 
533
#endif
 
534
 
 
535
        { "entryDN", "( 1.3.6.1.1.20 NAME 'entryDN' "   
 
536
                        "DESC 'DN of the entry' "
 
537
                        "EQUALITY distinguishedNameMatch "
 
538
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
 
539
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
 
540
                NULL, SLAP_AT_DYNAMIC,
 
541
                NULL, NULL,
 
542
                NULL, NULL, NULL, NULL, NULL,
 
543
                offsetof(struct slap_internal_schema, si_ad_entryDN) },
 
544
        { "entryUUID", "( 1.3.6.1.1.16.4 NAME 'entryUUID' "   
 
545
                        "DESC 'UUID of the entry' "
 
546
                        "EQUALITY UUIDMatch "
 
547
                        "ORDERING UUIDOrderingMatch "
 
548
                        "SYNTAX 1.3.6.1.1.16.1 "
 
549
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
 
550
                NULL, SLAP_AT_MANAGEABLE,
 
551
                NULL, NULL,
 
552
                NULL, NULL, NULL, NULL, NULL,
 
553
                offsetof(struct slap_internal_schema, si_ad_entryUUID) },
 
554
        { "entryCSN", "( 1.3.6.1.4.1.4203.666.1.7 NAME 'entryCSN' "
 
555
                        "DESC 'change sequence number of the entry content' "
 
556
                        "EQUALITY CSNMatch "
 
557
                        "ORDERING CSNOrderingMatch "
 
558
                        "SYNTAX 1.3.6.1.4.1.4203.666.11.2.1{64} "
 
559
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
 
560
                NULL, SLAP_AT_HIDE,
 
561
                NULL, NULL,
 
562
                NULL, NULL, NULL, NULL, NULL,
 
563
                offsetof(struct slap_internal_schema, si_ad_entryCSN) },
 
564
        { "namingCSN", "( 1.3.6.1.4.1.4203.666.1.13 NAME 'namingCSN' "
 
565
                        "DESC 'change sequence number of the entry naming (RDN)' "
 
566
                        "EQUALITY CSNMatch "
 
567
                        "ORDERING CSNOrderingMatch "
 
568
                        "SYNTAX 1.3.6.1.4.1.4203.666.11.2.1{64} "
 
569
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
 
570
                NULL, SLAP_AT_HIDE,
 
571
                NULL, NULL,
 
572
                NULL, NULL, NULL, NULL, NULL,
 
573
                offsetof(struct slap_internal_schema, si_ad_namingCSN) },
 
574
 
 
575
#ifdef LDAP_SUPERIOR_UUID
 
576
        { "superiorUUID", "( 1.3.6.1.4.1.4203.666.1.11 NAME 'superiorUUID' "   
 
577
                        "DESC 'UUID of the superior entry' "
 
578
                        "EQUALITY UUIDMatch "
 
579
                        "ORDERING UUIDOrderingMatch "
 
580
                        "SYNTAX 1.3.6.1.1.16.1 "
 
581
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
 
582
                NULL, SLAP_AT_HIDE,
 
583
                NULL, NULL,
 
584
                NULL, NULL, NULL, NULL, NULL,
 
585
                offsetof(struct slap_internal_schema, si_ad_superiorUUID) },
 
586
#endif
 
587
 
 
588
        { "syncreplCookie", "( 1.3.6.1.4.1.4203.666.1.23 "
 
589
                        "NAME 'syncreplCookie' "
 
590
                        "DESC 'syncrepl Cookie for shadow copy' "
 
591
                        "EQUALITY octetStringMatch "
 
592
                        "ORDERING octetStringOrderingMatch "
 
593
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 "
 
594
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
 
595
                NULL, SLAP_AT_HIDE,
 
596
                NULL, NULL,
 
597
                NULL, NULL, NULL, NULL, NULL,
 
598
                offsetof(struct slap_internal_schema, si_ad_syncreplCookie) },
 
599
 
 
600
        { "contextCSN", "( 1.3.6.1.4.1.4203.666.1.25 "
 
601
                        "NAME 'contextCSN' "
 
602
                        "DESC 'the largest committed CSN of a context' "
 
603
                        "EQUALITY CSNMatch "
 
604
                        "ORDERING CSNOrderingMatch "
 
605
                        "SYNTAX 1.3.6.1.4.1.4203.666.11.2.1{64} "
 
606
                        "NO-USER-MODIFICATION USAGE dSAOperation )",
 
607
                NULL, SLAP_AT_HIDE,
 
608
                NULL, NULL,
 
609
                NULL, NULL, NULL, NULL, NULL,
 
610
                offsetof(struct slap_internal_schema, si_ad_contextCSN) },
 
611
 
 
612
#ifdef LDAP_SYNC_TIMESTAMP
 
613
        { "syncTimestamp", "( 1.3.6.1.4.1.4203.666.1.26 NAME 'syncTimestamp' "
 
614
                        "DESC 'Time which object was replicated' "
 
615
                        "EQUALITY generalizedTimeMatch "
 
616
                        "ORDERING generalizedTimeOrderingMatch "
 
617
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
 
618
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
 
619
                NULL, 0,
 
620
                NULL, NULL,
 
621
                NULL, NULL, NULL, NULL, NULL,
 
622
                offsetof(struct slap_internal_schema, si_ad_syncTimestamp) },
 
623
#endif
 
624
 
 
625
        /* root DSE attributes */
 
626
        { "altServer", "( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer' "
 
627
                        "DESC 'RFC4512: alternative servers' "
 
628
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation )",
 
629
                rootDseAttribute, 0,
 
630
                NULL, NULL,
 
631
                NULL, NULL, NULL, NULL, NULL,
 
632
                offsetof(struct slap_internal_schema, si_ad_altServer) },
 
633
        { "namingContexts", "( 1.3.6.1.4.1.1466.101.120.5 "
 
634
                        "NAME 'namingContexts' "
 
635
                        "DESC 'RFC4512: naming contexts' "
 
636
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation )",
 
637
                rootDseAttribute, 0,
 
638
                NULL, NULL,
 
639
                NULL, NULL, NULL, NULL, NULL,
 
640
                offsetof(struct slap_internal_schema, si_ad_namingContexts) },
 
641
        { "supportedControl", "( 1.3.6.1.4.1.1466.101.120.13 "
 
642
                        "NAME 'supportedControl' "
 
643
                        "DESC 'RFC4512: supported controls' "
 
644
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )",
 
645
                rootDseAttribute, 0,
 
646
                NULL, NULL,
 
647
                NULL, NULL, NULL, NULL, NULL,
 
648
                offsetof(struct slap_internal_schema, si_ad_supportedControl) },
 
649
        { "supportedExtension", "( 1.3.6.1.4.1.1466.101.120.7 "
 
650
                        "NAME 'supportedExtension' "
 
651
                        "DESC 'RFC4512: supported extended operations' "
 
652
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )",
 
653
                rootDseAttribute, 0,
 
654
                NULL, NULL,
 
655
                NULL, NULL, NULL, NULL, NULL,
 
656
                offsetof(struct slap_internal_schema, si_ad_supportedExtension) },
 
657
        { "supportedLDAPVersion", "( 1.3.6.1.4.1.1466.101.120.15 "
 
658
                        "NAME 'supportedLDAPVersion' "
 
659
                        "DESC 'RFC4512: supported LDAP versions' "
 
660
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dSAOperation )",
 
661
                rootDseAttribute, 0,
 
662
                NULL, NULL,
 
663
                NULL, NULL, NULL, NULL, NULL,
 
664
                offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) },
 
665
        { "supportedSASLMechanisms", "( 1.3.6.1.4.1.1466.101.120.14 "
 
666
                        "NAME 'supportedSASLMechanisms' "
 
667
                        "DESC 'RFC4512: supported SASL mechanisms'"
 
668
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation )",
 
669
                rootDseAttribute, 0,
 
670
                NULL, NULL,
 
671
                NULL, NULL, NULL, NULL, NULL,
 
672
                offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) },
 
673
        { "supportedFeatures", "( 1.3.6.1.4.1.4203.1.3.5 "
 
674
                        "NAME 'supportedFeatures' "
 
675
                        "DESC 'RFC4512: features supported by the server' "
 
676
                        "EQUALITY objectIdentifierMatch "
 
677
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
 
678
                        "USAGE dSAOperation )",
 
679
                rootDseAttribute, 0,
 
680
                NULL, NULL,
 
681
                NULL, NULL, NULL, NULL, NULL,
 
682
                offsetof(struct slap_internal_schema, si_ad_supportedFeatures) },
 
683
        { "monitorContext", "( 1.3.6.1.4.1.4203.666.1.10 "
 
684
                        "NAME 'monitorContext' "
 
685
                        "DESC 'monitor context' "
 
686
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
 
687
                        "SINGLE-VALUE NO-USER-MODIFICATION "
 
688
                        "USAGE dSAOperation )",
 
689
                rootDseAttribute, SLAP_AT_HIDE,
 
690
                NULL, NULL,
 
691
                NULL, NULL, NULL, NULL, NULL,
 
692
                offsetof(struct slap_internal_schema, si_ad_monitorContext) },
 
693
        { "configContext", "( 1.3.6.1.4.1.4203.666.11.1.1 "
 
694
                        "NAME 'configContext' "
 
695
                        "DESC 'config context' "
 
696
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
 
697
                        "SINGLE-VALUE NO-USER-MODIFICATION "
 
698
                        "USAGE dSAOperation )",
 
699
                rootDseAttribute, SLAP_AT_HIDE,
 
700
                NULL, NULL,
 
701
                NULL, NULL, NULL, NULL, NULL,
 
702
                offsetof(struct slap_internal_schema, si_ad_configContext) },
 
703
        { "vendorName", "( 1.3.6.1.1.4 NAME 'vendorName' "
 
704
                        "DESC 'RFC3045: name of implementation vendor' "
 
705
                        "EQUALITY caseExactMatch "
 
706
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
 
707
                        "SINGLE-VALUE NO-USER-MODIFICATION "
 
708
                        "USAGE dSAOperation )",
 
709
                rootDseAttribute, 0,
 
710
                NULL, NULL,
 
711
                NULL, NULL, NULL, NULL, NULL,
 
712
                offsetof(struct slap_internal_schema, si_ad_vendorName) },
 
713
        { "vendorVersion", "( 1.3.6.1.1.5 NAME 'vendorVersion' "
 
714
                        "DESC 'RFC3045: version of implementation' "
 
715
                        "EQUALITY caseExactMatch "
 
716
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
 
717
                        "SINGLE-VALUE NO-USER-MODIFICATION "
 
718
                        "USAGE dSAOperation )",
 
719
                rootDseAttribute, 0,
 
720
                NULL, NULL,
 
721
                NULL, NULL, NULL, NULL, NULL,
 
722
                offsetof(struct slap_internal_schema, si_ad_vendorVersion) },
 
723
 
 
724
        /* subentry attributes */
 
725
        { "administrativeRole", "( 2.5.18.5 NAME 'administrativeRole' "
 
726
                        "DESC 'RFC3672: administrative role' "
 
727
                        "EQUALITY objectIdentifierMatch "
 
728
                        "USAGE directoryOperation "
 
729
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
 
730
                administrativeRoleAttribute, SLAP_AT_HIDE,
 
731
                NULL, NULL,
 
732
                NULL, NULL, NULL, NULL, NULL,
 
733
                offsetof(struct slap_internal_schema, si_ad_administrativeRole) },
 
734
        { "subtreeSpecification", "( 2.5.18.6 NAME 'subtreeSpecification' "
 
735
                        "DESC 'RFC3672: subtree specification' "
 
736
                        "SINGLE-VALUE "
 
737
                        "USAGE directoryOperation "
 
738
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.45 )",
 
739
                subentryAttribute, SLAP_AT_HIDE,
 
740
                NULL, NULL,
 
741
                NULL, NULL, NULL, NULL, NULL,
 
742
                offsetof(struct slap_internal_schema, si_ad_subtreeSpecification) },
 
743
 
 
744
        /* subschema subentry attributes */
 
745
        { "dITStructureRules", "( 2.5.21.1 NAME 'dITStructureRules' "
 
746
                        "DESC 'RFC4512: DIT structure rules' "
 
747
                        "EQUALITY integerFirstComponentMatch "
 
748
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.17 "
 
749
                        "USAGE directoryOperation ) ",
 
750
                subentryAttribute, SLAP_AT_HIDE,
 
751
                NULL, NULL,
 
752
                NULL, NULL, NULL, NULL, NULL,
 
753
                offsetof(struct slap_internal_schema, si_ad_ditStructureRules) },
 
754
        { "dITContentRules", "( 2.5.21.2 NAME 'dITContentRules' "
 
755
                        "DESC 'RFC4512: DIT content rules' "
 
756
                        "EQUALITY objectIdentifierFirstComponentMatch "
 
757
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.16 USAGE directoryOperation )",
 
758
                subentryAttribute, SLAP_AT_HIDE,
 
759
                oidValidate, NULL,
 
760
                NULL, NULL, objectClassMatch, NULL, NULL,
 
761
                offsetof(struct slap_internal_schema, si_ad_ditContentRules) },
 
762
        { "matchingRules", "( 2.5.21.4 NAME 'matchingRules' "
 
763
                        "DESC 'RFC4512: matching rules' "
 
764
                        "EQUALITY objectIdentifierFirstComponentMatch "
 
765
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.30 USAGE directoryOperation )",
 
766
                subentryAttribute, 0,
 
767
                oidValidate, NULL,
 
768
                NULL, NULL, matchingRuleMatch, NULL, NULL,
 
769
                offsetof(struct slap_internal_schema, si_ad_matchingRules) },
 
770
        { "attributeTypes", "( 2.5.21.5 NAME 'attributeTypes' "
 
771
                        "DESC 'RFC4512: attribute types' "
 
772
                        "EQUALITY objectIdentifierFirstComponentMatch "
 
773
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )",
 
774
                subentryAttribute, 0,
 
775
                oidValidate, NULL,
 
776
                NULL, NULL, attributeTypeMatch, NULL, NULL,
 
777
                offsetof(struct slap_internal_schema, si_ad_attributeTypes) },
 
778
        { "objectClasses", "( 2.5.21.6 NAME 'objectClasses' "
 
779
                        "DESC 'RFC4512: object classes' "
 
780
                        "EQUALITY objectIdentifierFirstComponentMatch "
 
781
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )",
 
782
                subentryAttribute, 0,
 
783
                oidValidate, NULL,
 
784
                NULL, NULL, objectClassMatch, NULL, NULL,
 
785
                offsetof(struct slap_internal_schema, si_ad_objectClasses) },
 
786
        { "nameForms", "( 2.5.21.7 NAME 'nameForms' "
 
787
                        "DESC 'RFC4512: name forms ' "
 
788
                        "EQUALITY objectIdentifierFirstComponentMatch "
 
789
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.35 USAGE directoryOperation )",
 
790
                subentryAttribute, SLAP_AT_HIDE,
 
791
                NULL, NULL,
 
792
                NULL, NULL, NULL, NULL, NULL,
 
793
                offsetof(struct slap_internal_schema, si_ad_nameForms) },
 
794
        { "matchingRuleUse", "( 2.5.21.8 NAME 'matchingRuleUse' "
 
795
                        "DESC 'RFC4512: matching rule uses' "
 
796
                        "EQUALITY objectIdentifierFirstComponentMatch "
 
797
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation )",
 
798
                subentryAttribute, 0,
 
799
                oidValidate, NULL,
 
800
                NULL, NULL, matchingRuleMatch, NULL, NULL,
 
801
                offsetof(struct slap_internal_schema, si_ad_matchingRuleUse) },
 
802
 
 
803
        { "ldapSyntaxes", "( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes' "
 
804
                        "DESC 'RFC4512: LDAP syntaxes' "
 
805
                        "EQUALITY objectIdentifierFirstComponentMatch "
 
806
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.54 USAGE directoryOperation )",
 
807
                subentryAttribute, 0,
 
808
                NULL, NULL,
 
809
                NULL, NULL, NULL, NULL, NULL,
 
810
                offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) },
 
811
 
 
812
        /* knowledge information */
 
813
        { "aliasedObjectName", "( 2.5.4.1 "
 
814
                        "NAME ( 'aliasedObjectName' 'aliasedEntryName' ) "
 
815
                        "DESC 'RFC4512: name of aliased object' "
 
816
                        "EQUALITY distinguishedNameMatch "
 
817
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
 
818
                aliasAttribute, SLAP_AT_FINAL,
 
819
                NULL, NULL,
 
820
                NULL, NULL, NULL, NULL, NULL,
 
821
                offsetof(struct slap_internal_schema, si_ad_aliasedObjectName) },
 
822
        { "ref", "( 2.16.840.1.113730.3.1.34 NAME 'ref' "
 
823
                        "DESC 'RFC3296: subordinate referral URL' "
 
824
                        "EQUALITY caseExactMatch "
 
825
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
 
826
                        "USAGE distributedOperation )",
 
827
                referralAttribute, 0,
 
828
                NULL, NULL,
 
829
                NULL, NULL, NULL, NULL, NULL,
 
830
                offsetof(struct slap_internal_schema, si_ad_ref) },
 
831
 
 
832
        /* access control internals */
 
833
        { "entry", "( 1.3.6.1.4.1.4203.1.3.1 "
 
834
                        "NAME 'entry' "
 
835
                        "DESC 'OpenLDAP ACL entry pseudo-attribute' "
 
836
                        "SYNTAX 1.3.6.1.4.1.4203.1.1.1 "
 
837
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
 
838
                NULL, SLAP_AT_HIDE,
 
839
                NULL, NULL,
 
840
                NULL, NULL, NULL, NULL, NULL,
 
841
                offsetof(struct slap_internal_schema, si_ad_entry) },
 
842
        { "children", "( 1.3.6.1.4.1.4203.1.3.2 "
 
843
                        "NAME 'children' "
 
844
                        "DESC 'OpenLDAP ACL children pseudo-attribute' "
 
845
                        "SYNTAX 1.3.6.1.4.1.4203.1.1.1 "
 
846
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
 
847
                NULL, SLAP_AT_HIDE,
 
848
                NULL, NULL,
 
849
                NULL, NULL, NULL, NULL, NULL,
 
850
                offsetof(struct slap_internal_schema, si_ad_children) },
 
851
 
 
852
        /* access control externals */
 
853
        { "authzTo", "( 1.3.6.1.4.1.4203.666.1.8 "
 
854
                        "NAME ( 'authzTo' 'saslAuthzTo' ) "
 
855
                        "DESC 'proxy authorization targets' "
 
856
                        "EQUALITY authzMatch "
 
857
                        "SYNTAX 1.3.6.1.4.1.4203.666.2.7 "
 
858
                        "X-ORDERED 'VALUES' "
 
859
                        "USAGE distributedOperation )",
 
860
                NULL, SLAP_AT_HIDE,
 
861
                NULL, NULL,
 
862
                NULL, NULL, NULL, NULL, NULL,
 
863
                offsetof(struct slap_internal_schema, si_ad_saslAuthzTo) },
 
864
        { "authzFrom", "( 1.3.6.1.4.1.4203.666.1.9 "
 
865
                        "NAME ( 'authzFrom' 'saslAuthzFrom' ) "
 
866
                        "DESC 'proxy authorization sources' "
 
867
                        "EQUALITY authzMatch "
 
868
                        "SYNTAX 1.3.6.1.4.1.4203.666.2.7 "
 
869
                        "X-ORDERED 'VALUES' "
 
870
                        "USAGE distributedOperation )",
 
871
                NULL, SLAP_AT_HIDE,
 
872
                NULL, NULL,
 
873
                NULL, NULL, NULL, NULL, NULL,
 
874
                offsetof(struct slap_internal_schema, si_ad_saslAuthzFrom) },
 
875
 
 
876
#ifdef LDAP_DYNAMIC_OBJECTS
 
877
        { "entryTtl", "( 1.3.6.1.4.1.1466.101.119.3 NAME 'entryTtl' "
 
878
                        "DESC 'RFC2589: entry time-to-live' "
 
879
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE "
 
880
                        "NO-USER-MODIFICATION USAGE dSAOperation )",
 
881
                dynamicAttribute, SLAP_AT_MANAGEABLE,
 
882
                NULL, NULL,
 
883
                NULL, NULL, NULL, NULL, NULL,
 
884
                offsetof(struct slap_internal_schema, si_ad_entryTtl) },
 
885
        { "dynamicSubtrees", "( 1.3.6.1.4.1.1466.101.119.4 "
 
886
                        "NAME 'dynamicSubtrees' "
 
887
                        "DESC 'RFC2589: dynamic subtrees' "
 
888
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION "
 
889
                        "USAGE dSAOperation )",
 
890
                rootDseAttribute, 0,
 
891
                NULL, NULL,
 
892
                NULL, NULL, NULL, NULL, NULL,
 
893
                offsetof(struct slap_internal_schema, si_ad_dynamicSubtrees) },
 
894
#endif
 
895
 
 
896
        /* userApplication attributes (which system schema depends upon) */
 
897
        { "distinguishedName", "( 2.5.4.49 NAME 'distinguishedName' "
 
898
                        "DESC 'RFC4519: common supertype of DN attributes' "
 
899
                        "EQUALITY distinguishedNameMatch "
 
900
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
 
901
                NULL, SLAP_AT_ABSTRACT,
 
902
                NULL, NULL,
 
903
                NULL, NULL, NULL, NULL, NULL,
 
904
                offsetof(struct slap_internal_schema, si_ad_distinguishedName) },
 
905
        { "name", "( 2.5.4.41 NAME 'name' "
 
906
                        "DESC 'RFC4519: common supertype of name attributes' "
 
907
                        "EQUALITY caseIgnoreMatch "
 
908
                        "SUBSTR caseIgnoreSubstringsMatch "
 
909
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )",
 
910
                NULL, SLAP_AT_ABSTRACT,
 
911
                NULL, NULL,
 
912
                NULL, NULL, NULL, NULL, NULL,
 
913
                offsetof(struct slap_internal_schema, si_ad_name) },
 
914
        { "cn", "( 2.5.4.3 NAME ( 'cn' 'commonName' ) "
 
915
                        "DESC 'RFC4519: common name(s) for which the entity is known by' "
 
916
                        "SUP name )",
 
917
                NULL, 0,
 
918
                NULL, NULL,
 
919
                NULL, NULL, NULL, NULL, NULL,
 
920
                offsetof(struct slap_internal_schema, si_ad_cn) },
 
921
        { "uid", "( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' ) "
 
922
                        "DESC 'RFC4519: user identifier' "
 
923
                        "EQUALITY caseIgnoreMatch "
 
924
                        "SUBSTR caseIgnoreSubstringsMatch "
 
925
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
 
926
                NULL, 0,
 
927
                NULL, NULL,
 
928
                NULL, NULL, NULL, NULL, NULL,
 
929
                offsetof(struct slap_internal_schema, si_ad_uid) },
 
930
        { "uidNumber", /* for ldapi:// */
 
931
                "( 1.3.6.1.1.1.1.0 NAME 'uidNumber' "
 
932
                "DESC 'RFC2307: An integer uniquely identifying a user "
 
933
                                "in an administrative domain' "
 
934
                "EQUALITY integerMatch "
 
935
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
 
936
                NULL, 0,
 
937
                NULL, NULL,
 
938
                NULL, NULL, NULL, NULL, NULL,
 
939
                offsetof(struct slap_internal_schema, si_ad_uidNumber) },
 
940
        { "gidNumber", /* for ldapi:// */
 
941
                "( 1.3.6.1.1.1.1.1 NAME 'gidNumber' "
 
942
                "DESC 'RFC2307: An integer uniquely identifying a group "
 
943
                                "in an administrative domain' "
 
944
                "EQUALITY integerMatch "
 
945
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
 
946
                NULL, 0,
 
947
                NULL, NULL,
 
948
                NULL, NULL, NULL, NULL, NULL,
 
949
                offsetof(struct slap_internal_schema, si_ad_gidNumber) },
 
950
        { "userPassword", "( 2.5.4.35 NAME 'userPassword' "
 
951
                        "DESC 'RFC4519/2307: password of user' "
 
952
                        "EQUALITY octetStringMatch "
 
953
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )",
 
954
                NULL, 0,
 
955
                NULL, NULL,
 
956
                NULL, NULL, NULL, NULL, NULL,
 
957
                offsetof(struct slap_internal_schema, si_ad_userPassword) },
 
958
 
 
959
        { "labeledURI", "( 1.3.6.1.4.1.250.1.57 NAME 'labeledURI' "
 
960
                        "DESC 'RFC2079: Uniform Resource Identifier with optional label' "
 
961
                        "EQUALITY caseExactMatch "
 
962
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
 
963
                NULL, 0,
 
964
                NULL, NULL,
 
965
                NULL, NULL, NULL, NULL, NULL,
 
966
                offsetof(struct slap_internal_schema, si_ad_labeledURI) },
 
967
 
 
968
#ifdef SLAPD_AUTHPASSWD
 
969
        { "authPassword", "( 1.3.6.1.4.1.4203.1.3.4 "
 
970
                        "NAME 'authPassword' "
 
971
                        "DESC 'RFC3112: authentication password attribute' "
 
972
                        "EQUALITY 1.3.6.1.4.1.4203.1.2.2 "
 
973
                        "SYNTAX 1.3.6.1.4.1.4203.1.1.2 )",
 
974
                NULL, 0,
 
975
                NULL, NULL,
 
976
                NULL, NULL, NULL, NULL, NULL,
 
977
                offsetof(struct slap_internal_schema, si_ad_authPassword) },
 
978
        { "supportedAuthPasswordSchemes", "( 1.3.6.1.4.1.4203.1.3.3 "
 
979
                        "NAME 'supportedAuthPasswordSchemes' "
 
980
                        "DESC 'RFC3112: supported authPassword schemes' "
 
981
                        "EQUALITY caseExactIA5Match "
 
982
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} "
 
983
                        "USAGE dSAOperation )",
 
984
                subschemaAttribute, 0,
 
985
                NULL, NULL,
 
986
                NULL, NULL, NULL, NULL, NULL,
 
987
                offsetof(struct slap_internal_schema, si_ad_authPasswordSchemes) },
 
988
#endif
 
989
 
 
990
        { "description", "( 2.5.4.13 NAME 'description' "
 
991
                        "DESC 'RFC4519: descriptive information' "
 
992
                        "EQUALITY caseIgnoreMatch "
 
993
                        "SUBSTR caseIgnoreSubstringsMatch "
 
994
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )",
 
995
                NULL, 0,
 
996
                NULL, NULL,
 
997
                NULL, NULL, NULL, NULL, NULL,
 
998
                offsetof(struct slap_internal_schema, si_ad_description) },
 
999
 
 
1000
        { "seeAlso", "( 2.5.4.34 NAME 'seeAlso' "
 
1001
                        "DESC 'RFC4519: DN of related object' "
 
1002
                        "SUP distinguishedName )",
 
1003
                NULL, 0,
 
1004
                NULL, NULL,
 
1005
                NULL, NULL, NULL, NULL, NULL,
 
1006
                offsetof(struct slap_internal_schema, si_ad_seeAlso) },
 
1007
 
 
1008
        { NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 }
 
1009
};
 
1010
 
 
1011
static AttributeType slap_at_undefined = {
 
1012
        { "1.1.1", NULL, "Catchall for undefined attribute types", 1, NULL,
 
1013
                NULL, NULL, NULL, NULL,
 
1014
                0, 0, 0, 1, LDAP_SCHEMA_DSA_OPERATION, NULL }, /* LDAPAttributeType */
 
1015
        BER_BVC("UNDEFINED"), /* cname */
 
1016
        NULL, /* sup */
 
1017
        NULL, /* subtypes */
 
1018
        NULL, NULL, NULL, NULL, /* matching rules routines */
 
1019
        NULL, /* syntax (will be set later to "octetString") */
 
1020
        NULL, /* schema check function */
 
1021
        NULL, /* oidmacro */
 
1022
        SLAP_AT_ABSTRACT|SLAP_AT_FINAL, /* mask */
 
1023
        { NULL }, /* next */
 
1024
        NULL /* attribute description */
 
1025
        /* mutex (don't know how to initialize it :) */
 
1026
};
 
1027
 
 
1028
static AttributeType slap_at_proxied = {
 
1029
        { "1.1.1", NULL, "Catchall for undefined proxied attribute types", 1, NULL,
 
1030
                NULL, NULL, NULL, NULL,
 
1031
                0, 0, 0, 0, LDAP_SCHEMA_USER_APPLICATIONS, NULL }, /* LDAPAttributeType */
 
1032
        BER_BVC("PROXIED"), /* cname */
 
1033
        NULL, /* sup */
 
1034
        NULL, /* subtypes */
 
1035
        NULL, NULL, NULL, NULL, /* matching rules routines (will be set later) */
 
1036
        NULL, /* syntax (will be set later to "octetString") */
 
1037
        NULL, /* schema check function */
 
1038
        NULL, /* oidmacro */
 
1039
        SLAP_AT_ABSTRACT|SLAP_AT_FINAL, /* mask */
 
1040
        { NULL }, /* next */
 
1041
        NULL /* attribute description */
 
1042
        /* mutex (don't know how to initialize it :) */
 
1043
};
 
1044
 
 
1045
static struct slap_schema_mr_map {
 
1046
        char *ssmm_name;
 
1047
        size_t ssmm_offset;
 
1048
} mr_map[] = {
 
1049
        { "caseExactIA5Match",
 
1050
                offsetof(struct slap_internal_schema, si_mr_caseExactIA5Match) },
 
1051
        { "caseExactMatch",
 
1052
                offsetof(struct slap_internal_schema, si_mr_caseExactMatch) },
 
1053
        { "caseExactSubstringsMatch",
 
1054
                offsetof(struct slap_internal_schema, si_mr_caseExactSubstringsMatch) },
 
1055
        { "distinguishedNameMatch",
 
1056
                offsetof(struct slap_internal_schema, si_mr_distinguishedNameMatch) },
 
1057
        { "dnSubtreeMatch",
 
1058
                offsetof(struct slap_internal_schema, si_mr_dnSubtreeMatch) },
 
1059
        { "dnOneLevelMatch",
 
1060
                offsetof(struct slap_internal_schema, si_mr_dnOneLevelMatch) },
 
1061
        { "dnSubordinateMatch",
 
1062
                offsetof(struct slap_internal_schema, si_mr_dnSubordinateMatch) },
 
1063
        { "dnSuperiorMatch",
 
1064
                offsetof(struct slap_internal_schema, si_mr_dnSuperiorMatch) },
 
1065
        { "integerMatch",
 
1066
                offsetof(struct slap_internal_schema, si_mr_integerMatch) },
 
1067
        { "integerFirstComponentMatch",
 
1068
                offsetof(struct slap_internal_schema,
 
1069
                        si_mr_integerFirstComponentMatch) },
 
1070
        { "objectIdentifierFirstComponentMatch",
 
1071
                offsetof(struct slap_internal_schema,
 
1072
                        si_mr_objectIdentifierFirstComponentMatch) },
 
1073
        { NULL, 0 }
 
1074
};
 
1075
 
 
1076
static struct slap_schema_syn_map {
 
1077
        char *sssm_name;
 
1078
        size_t sssm_offset;
 
1079
} syn_map[] = {
 
1080
        { "1.3.6.1.4.1.1466.115.121.1.15",
 
1081
                offsetof(struct slap_internal_schema, si_syn_directoryString) },
 
1082
        { "1.3.6.1.4.1.1466.115.121.1.12",
 
1083
                offsetof(struct slap_internal_schema, si_syn_distinguishedName) },
 
1084
        { "1.3.6.1.4.1.1466.115.121.1.27",
 
1085
                offsetof(struct slap_internal_schema, si_syn_integer) },
 
1086
        { "1.3.6.1.4.1.1466.115.121.1.40",
 
1087
                offsetof(struct slap_internal_schema, si_syn_octetString) },
 
1088
        { "1.3.6.1.4.1.1466.115.121.1.3",
 
1089
                offsetof(struct slap_internal_schema, si_syn_attributeTypeDesc) },
 
1090
        { "1.3.6.1.4.1.1466.115.121.1.16",
 
1091
                offsetof(struct slap_internal_schema, si_syn_ditContentRuleDesc) },
 
1092
        { "1.3.6.1.4.1.1466.115.121.1.54",
 
1093
                offsetof(struct slap_internal_schema, si_syn_ldapSyntaxDesc) },
 
1094
        { "1.3.6.1.4.1.1466.115.121.1.30",
 
1095
                offsetof(struct slap_internal_schema, si_syn_matchingRuleDesc) },
 
1096
        { "1.3.6.1.4.1.1466.115.121.1.31",
 
1097
                offsetof(struct slap_internal_schema, si_syn_matchingRuleUseDesc) },
 
1098
        { "1.3.6.1.4.1.1466.115.121.1.35",
 
1099
                offsetof(struct slap_internal_schema, si_syn_nameFormDesc) },
 
1100
        { "1.3.6.1.4.1.1466.115.121.1.37",
 
1101
                offsetof(struct slap_internal_schema, si_syn_objectClassDesc) },
 
1102
        { "1.3.6.1.4.1.1466.115.121.1.17",
 
1103
                offsetof(struct slap_internal_schema, si_syn_ditStructureRuleDesc) },
 
1104
        { NULL, 0 }
 
1105
};
 
1106
 
 
1107
int
 
1108
slap_schema_load( void )
 
1109
{
 
1110
        int i;
 
1111
 
 
1112
        for( i=0; syn_map[i].sssm_name; i++ ) {
 
1113
                Syntax ** synp = (Syntax **)
 
1114
                        &(((char *) &slap_schema)[syn_map[i].sssm_offset]);
 
1115
 
 
1116
                assert( *synp == NULL );
 
1117
 
 
1118
                *synp = syn_find( syn_map[i].sssm_name );
 
1119
 
 
1120
                if( *synp == NULL ) {
 
1121
                        fprintf( stderr, "slap_schema_load: Syntax: "
 
1122
                                "No syntax \"%s\" defined in schema\n",
 
1123
                                syn_map[i].sssm_name );
 
1124
                        return LDAP_INVALID_SYNTAX;
 
1125
                }
 
1126
        }
 
1127
 
 
1128
        for( i=0; mr_map[i].ssmm_name; i++ ) {
 
1129
                MatchingRule ** mrp = (MatchingRule **)
 
1130
                        &(((char *) &slap_schema)[mr_map[i].ssmm_offset]);
 
1131
 
 
1132
                assert( *mrp == NULL );
 
1133
 
 
1134
                *mrp = mr_find( mr_map[i].ssmm_name );
 
1135
 
 
1136
                if( *mrp == NULL ) {
 
1137
                        fprintf( stderr, "slap_schema_load: MatchingRule: "
 
1138
                                "No matching rule \"%s\" defined in schema\n",
 
1139
                                mr_map[i].ssmm_name );
 
1140
                        return LDAP_INAPPROPRIATE_MATCHING;
 
1141
                }
 
1142
        }
 
1143
 
 
1144
        slap_at_undefined.sat_syntax = slap_schema.si_syn_octetString;
 
1145
        slap_schema.si_at_undefined = &slap_at_undefined;
 
1146
 
 
1147
        slap_at_proxied.sat_equality = mr_find( "octetStringMatch" );
 
1148
        slap_at_proxied.sat_approx = mr_find( "octetStringMatch" );
 
1149
        slap_at_proxied.sat_ordering = mr_find( "octetStringOrderingMatch" );
 
1150
        slap_at_proxied.sat_substr = mr_find( "octetStringSubstringsMatch" );
 
1151
        slap_at_proxied.sat_syntax = slap_schema.si_syn_octetString;
 
1152
        slap_schema.si_at_proxied = &slap_at_proxied;
 
1153
 
 
1154
        ldap_pvt_thread_mutex_init( &ad_undef_mutex );
 
1155
        ldap_pvt_thread_mutex_init( &oc_undef_mutex );
 
1156
 
 
1157
        for( i=0; ad_map[i].ssam_name; i++ ) {
 
1158
                assert( ad_map[i].ssam_defn != NULL );
 
1159
                {
 
1160
                        LDAPAttributeType *at;
 
1161
                        int             code;
 
1162
                        const char      *err;
 
1163
 
 
1164
                        at = ldap_str2attributetype( ad_map[i].ssam_defn,
 
1165
                                &code, &err, LDAP_SCHEMA_ALLOW_ALL );
 
1166
                        if ( !at ) {
 
1167
                                fprintf( stderr,
 
1168
                                        "slap_schema_load: AttributeType \"%s\": %s before %s\n",
 
1169
                                         ad_map[i].ssam_name, ldap_scherr2str(code), err );
 
1170
                                return code;
 
1171
                        }
 
1172
 
 
1173
                        if ( at->at_oid == NULL ) {
 
1174
                                fprintf( stderr, "slap_schema_load: "
 
1175
                                        "AttributeType \"%s\": no OID\n",
 
1176
                                        ad_map[i].ssam_name );
 
1177
                                ldap_attributetype_free( at );
 
1178
                                return LDAP_OTHER;
 
1179
                        }
 
1180
 
 
1181
                        code = at_add( at, 0, NULL, NULL, &err );
 
1182
                        if ( code ) {
 
1183
                                ldap_attributetype_free( at );
 
1184
                                fprintf( stderr, "slap_schema_load: AttributeType "
 
1185
                                        "\"%s\": %s: \"%s\"\n",
 
1186
                                         ad_map[i].ssam_name, scherr2str(code), err );
 
1187
                                return code;
 
1188
                        }
 
1189
                        ldap_memfree( at );
 
1190
                }
 
1191
                {
 
1192
                        int rc;
 
1193
                        const char *text;
 
1194
                        Syntax *syntax = NULL;
 
1195
 
 
1196
                        AttributeDescription ** adp = (AttributeDescription **)
 
1197
                                &(((char *) &slap_schema)[ad_map[i].ssam_offset]);
 
1198
 
 
1199
                        assert( *adp == NULL );
 
1200
 
 
1201
                        rc = slap_str2ad( ad_map[i].ssam_name, adp, &text );
 
1202
                        if( rc != LDAP_SUCCESS ) {
 
1203
                                fprintf( stderr, "slap_schema_load: AttributeType \"%s\": "
 
1204
                                        "not defined in schema\n",
 
1205
                                        ad_map[i].ssam_name );
 
1206
                                return rc;
 
1207
                        }
 
1208
 
 
1209
                        if( ad_map[i].ssam_check ) {
 
1210
                                /* install check routine */
 
1211
                                (*adp)->ad_type->sat_check = ad_map[i].ssam_check;
 
1212
                        }
 
1213
                        /* install flags */
 
1214
                        (*adp)->ad_type->sat_flags |= ad_map[i].ssam_flags;
 
1215
 
 
1216
                        /* install custom syntax routines */
 
1217
                        if( ad_map[i].ssam_syn_validate ||
 
1218
                                ad_map[i].ssam_syn_pretty )
 
1219
                        {
 
1220
                                Syntax *syn;
 
1221
 
 
1222
                                syntax = (*adp)->ad_type->sat_syntax;
 
1223
 
 
1224
                                syn = ch_malloc( sizeof( Syntax ) );
 
1225
                                *syn = *syntax;
 
1226
 
 
1227
                                if( ad_map[i].ssam_syn_validate ) {
 
1228
                                        syn->ssyn_validate = ad_map[i].ssam_syn_validate;
 
1229
                                }
 
1230
                                if( ad_map[i].ssam_syn_pretty ) {
 
1231
                                        syn->ssyn_pretty = ad_map[i].ssam_syn_pretty;
 
1232
                                }
 
1233
 
 
1234
                                (*adp)->ad_type->sat_syntax = syn;
 
1235
                        }
 
1236
 
 
1237
                        /* install custom rule routines */
 
1238
                        if( syntax != NULL ||
 
1239
                                ad_map[i].ssam_mr_convert ||
 
1240
                                ad_map[i].ssam_mr_normalize ||
 
1241
                                ad_map[i].ssam_mr_match ||
 
1242
                                ad_map[i].ssam_mr_indexer ||
 
1243
                                ad_map[i].ssam_mr_filter )
 
1244
                        {
 
1245
                                MatchingRule *mr = ch_malloc( sizeof( MatchingRule ) );
 
1246
                                *mr = *(*adp)->ad_type->sat_equality;
 
1247
 
 
1248
                                if ( syntax != NULL ) {
 
1249
                                        mr->smr_syntax = (*adp)->ad_type->sat_syntax;
 
1250
                                }
 
1251
                                if ( ad_map[i].ssam_mr_convert ) {
 
1252
                                        mr->smr_convert = ad_map[i].ssam_mr_convert;
 
1253
                                }
 
1254
                                if ( ad_map[i].ssam_mr_normalize ) {
 
1255
                                        mr->smr_normalize = ad_map[i].ssam_mr_normalize;
 
1256
                                }
 
1257
                                if ( ad_map[i].ssam_mr_match ) {
 
1258
                                        mr->smr_match = ad_map[i].ssam_mr_match;
 
1259
                                }
 
1260
                                if ( ad_map[i].ssam_mr_indexer ) {
 
1261
                                        mr->smr_indexer = ad_map[i].ssam_mr_indexer;
 
1262
                                }
 
1263
                                if ( ad_map[i].ssam_mr_filter ) {
 
1264
                                        mr->smr_filter = ad_map[i].ssam_mr_filter;
 
1265
                                }
 
1266
 
 
1267
                                /* FIXME: no-one will free this at exit */
 
1268
                                (*adp)->ad_type->sat_equality = mr;
 
1269
                        }
 
1270
                }
 
1271
        }
 
1272
 
 
1273
        for( i=0; oc_map[i].ssom_name; i++ ) {
 
1274
                assert( oc_map[i].ssom_defn != NULL );
 
1275
                {
 
1276
                        LDAPObjectClass *oc;
 
1277
                        int             code;
 
1278
                        const char      *err;
 
1279
 
 
1280
                        oc = ldap_str2objectclass( oc_map[i].ssom_defn, &code, &err,
 
1281
                                LDAP_SCHEMA_ALLOW_ALL );
 
1282
                        if ( !oc ) {
 
1283
                                fprintf( stderr, "slap_schema_load: ObjectClass "
 
1284
                                        "\"%s\": %s before %s\n",
 
1285
                                        oc_map[i].ssom_name, ldap_scherr2str(code), err );
 
1286
                                return code;
 
1287
                        }
 
1288
 
 
1289
                        if ( oc->oc_oid == NULL ) {
 
1290
                                fprintf( stderr, "slap_schema_load: ObjectClass "
 
1291
                                        "\"%s\": no OID\n",
 
1292
                                        oc_map[i].ssom_name );
 
1293
                                ldap_objectclass_free( oc );
 
1294
                                return LDAP_OTHER;
 
1295
                        }
 
1296
 
 
1297
                        code = oc_add(oc,0,NULL,NULL,&err);
 
1298
                        if ( code ) {
 
1299
                                ldap_objectclass_free( oc );
 
1300
                                fprintf( stderr, "slap_schema_load: ObjectClass "
 
1301
                                        "\"%s\": %s: \"%s\"\n",
 
1302
                                        oc_map[i].ssom_name, scherr2str(code), err);
 
1303
                                return code;
 
1304
                        }
 
1305
                        ldap_memfree(oc);
 
1306
 
 
1307
                }
 
1308
                {
 
1309
                        ObjectClass ** ocp = (ObjectClass **)
 
1310
                                &(((char *) &slap_schema)[oc_map[i].ssom_offset]);
 
1311
 
 
1312
                        assert( *ocp == NULL );
 
1313
 
 
1314
                        *ocp = oc_find( oc_map[i].ssom_name );
 
1315
                        if( *ocp == NULL ) {
 
1316
                                fprintf( stderr, "slap_schema_load: "
 
1317
                                        "ObjectClass \"%s\": not defined in schema\n",
 
1318
                                        oc_map[i].ssom_name );
 
1319
                                return LDAP_OBJECT_CLASS_VIOLATION;
 
1320
                        }
 
1321
 
 
1322
                        if( oc_map[i].ssom_check ) {
 
1323
                                /* install check routine */
 
1324
                                (*ocp)->soc_check = oc_map[i].ssom_check;
 
1325
                        }
 
1326
                        /* install flags */
 
1327
                        (*ocp)->soc_flags |= oc_map[i].ssom_flags;
 
1328
                }
 
1329
        }
 
1330
 
 
1331
        return LDAP_SUCCESS;
 
1332
}
 
1333
 
 
1334
int
 
1335
slap_schema_check( void )
 
1336
{
 
1337
        /* we should only be called once after schema_init() was called */
 
1338
        assert( schema_init_done == 1 );
 
1339
 
 
1340
        /*
 
1341
         * cycle thru attributeTypes to build matchingRuleUse
 
1342
         */
 
1343
        if ( matching_rule_use_init() ) {
 
1344
                return LDAP_OTHER;
 
1345
        }
 
1346
 
 
1347
        ++schema_init_done;
 
1348
        return LDAP_SUCCESS;
 
1349
}
 
1350
 
 
1351
static int rootDseObjectClass (
 
1352
        Backend *be,
 
1353
        Entry *e,
 
1354
        ObjectClass *oc,
 
1355
        const char** text,
 
1356
        char *textbuf, size_t textlen )
 
1357
{
 
1358
        *text = textbuf;
 
1359
 
 
1360
        if( e->e_nname.bv_len ) {
 
1361
                snprintf( textbuf, textlen,
 
1362
                        "objectClass \"%s\" only allowed in the root DSE",
 
1363
                        oc->soc_oid );
 
1364
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1365
        }
 
1366
 
 
1367
        /* we should not be called for the root DSE */
 
1368
        assert( 0 );
 
1369
        return LDAP_SUCCESS;
 
1370
}
 
1371
 
 
1372
static int aliasObjectClass (
 
1373
        Backend *be,
 
1374
        Entry *e,
 
1375
        ObjectClass *oc,
 
1376
        const char** text,
 
1377
        char *textbuf, size_t textlen )
 
1378
{
 
1379
        *text = textbuf;
 
1380
 
 
1381
        if( !SLAP_ALIASES(be) ) {
 
1382
                snprintf( textbuf, textlen,
 
1383
                        "objectClass \"%s\" not supported in context",
 
1384
                        oc->soc_oid );
 
1385
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1386
        }
 
1387
 
 
1388
        return LDAP_SUCCESS;
 
1389
}
 
1390
 
 
1391
static int referralObjectClass (
 
1392
        Backend *be,
 
1393
        Entry *e,
 
1394
        ObjectClass *oc,
 
1395
        const char** text,
 
1396
        char *textbuf, size_t textlen )
 
1397
{
 
1398
        *text = textbuf;
 
1399
 
 
1400
        if( !SLAP_REFERRALS(be) ) {
 
1401
                snprintf( textbuf, textlen,
 
1402
                        "objectClass \"%s\" not supported in context",
 
1403
                        oc->soc_oid );
 
1404
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1405
        }
 
1406
 
 
1407
        return LDAP_SUCCESS;
 
1408
}
 
1409
 
 
1410
static int subentryObjectClass (
 
1411
        Backend *be,
 
1412
        Entry *e,
 
1413
        ObjectClass *oc,
 
1414
        const char** text,
 
1415
        char *textbuf, size_t textlen )
 
1416
{
 
1417
        *text = textbuf;
 
1418
 
 
1419
        if( !SLAP_SUBENTRIES(be) ) {
 
1420
                snprintf( textbuf, textlen,
 
1421
                        "objectClass \"%s\" not supported in context",
 
1422
                        oc->soc_oid );
 
1423
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1424
        }
 
1425
 
 
1426
        if( oc != slap_schema.si_oc_subentry && !is_entry_subentry( e ) ) {
 
1427
                snprintf( textbuf, textlen,
 
1428
                        "objectClass \"%s\" only allowed in subentries",
 
1429
                        oc->soc_oid );
 
1430
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1431
        }
 
1432
 
 
1433
        return LDAP_SUCCESS;
 
1434
}
 
1435
 
 
1436
#ifdef LDAP_DYNAMIC_OBJECTS
 
1437
static int dynamicObjectClass (
 
1438
        Backend *be,
 
1439
        Entry *e,
 
1440
        ObjectClass *oc,
 
1441
        const char** text,
 
1442
        char *textbuf, size_t textlen )
 
1443
{
 
1444
        *text = textbuf;
 
1445
 
 
1446
        if( !SLAP_DYNAMIC(be) ) {
 
1447
                snprintf( textbuf, textlen,
 
1448
                        "objectClass \"%s\" not supported in context",
 
1449
                        oc->soc_oid );
 
1450
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1451
        }
 
1452
 
 
1453
        return LDAP_SUCCESS;
 
1454
}
 
1455
#endif /* LDAP_DYNAMIC_OBJECTS */
 
1456
 
 
1457
static int rootDseAttribute (
 
1458
        Backend *be,
 
1459
        Entry *e,
 
1460
        Attribute *attr,
 
1461
        const char** text,
 
1462
        char *textbuf, size_t textlen )
 
1463
{
 
1464
        *text = textbuf;
 
1465
 
 
1466
        if( e->e_nname.bv_len ) {
 
1467
                snprintf( textbuf, textlen,
 
1468
                        "attribute \"%s\" only allowed in the root DSE",
 
1469
                        attr->a_desc->ad_cname.bv_val );
 
1470
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1471
        }
 
1472
 
 
1473
        /* we should not be called for the root DSE */
 
1474
        assert( 0 );
 
1475
        return LDAP_SUCCESS;
 
1476
}
 
1477
 
 
1478
static int aliasAttribute (
 
1479
        Backend *be,
 
1480
        Entry *e,
 
1481
        Attribute *attr,
 
1482
        const char** text,
 
1483
        char *textbuf, size_t textlen )
 
1484
{
 
1485
        *text = textbuf;
 
1486
 
 
1487
        if( !SLAP_ALIASES(be) ) {
 
1488
                snprintf( textbuf, textlen,
 
1489
                        "attribute \"%s\" not supported in context",
 
1490
                        attr->a_desc->ad_cname.bv_val );
 
1491
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1492
        }
 
1493
 
 
1494
        if( !is_entry_alias( e ) ) {
 
1495
                snprintf( textbuf, textlen,
 
1496
                        "attribute \"%s\" only allowed in the alias",
 
1497
                        attr->a_desc->ad_cname.bv_val );
 
1498
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1499
        }
 
1500
 
 
1501
        return LDAP_SUCCESS;
 
1502
}
 
1503
 
 
1504
static int referralAttribute (
 
1505
        Backend *be,
 
1506
        Entry *e,
 
1507
        Attribute *attr,
 
1508
        const char** text,
 
1509
        char *textbuf, size_t textlen )
 
1510
{
 
1511
        *text = textbuf;
 
1512
 
 
1513
        if( !SLAP_REFERRALS(be) ) {
 
1514
                snprintf( textbuf, textlen,
 
1515
                        "attribute \"%s\" not supported in context",
 
1516
                        attr->a_desc->ad_cname.bv_val );
 
1517
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1518
        }
 
1519
 
 
1520
        if( !is_entry_referral( e ) ) {
 
1521
                snprintf( textbuf, textlen,
 
1522
                        "attribute \"%s\" only allowed in the referral",
 
1523
                        attr->a_desc->ad_cname.bv_val );
 
1524
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1525
        }
 
1526
 
 
1527
        return LDAP_SUCCESS;
 
1528
}
 
1529
 
 
1530
static int subentryAttribute (
 
1531
        Backend *be,
 
1532
        Entry *e,
 
1533
        Attribute *attr,
 
1534
        const char** text,
 
1535
        char *textbuf, size_t textlen )
 
1536
{
 
1537
        *text = textbuf;
 
1538
 
 
1539
        if( !SLAP_SUBENTRIES(be) ) {
 
1540
                snprintf( textbuf, textlen,
 
1541
                        "attribute \"%s\" not supported in context",
 
1542
                        attr->a_desc->ad_cname.bv_val );
 
1543
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1544
        }
 
1545
 
 
1546
        if( !is_entry_subentry( e ) ) {
 
1547
                snprintf( textbuf, textlen,
 
1548
                        "attribute \"%s\" only allowed in the subentry",
 
1549
                        attr->a_desc->ad_cname.bv_val );
 
1550
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1551
        }
 
1552
 
 
1553
        return LDAP_SUCCESS;
 
1554
}
 
1555
 
 
1556
static int administrativeRoleAttribute (
 
1557
        Backend *be,
 
1558
        Entry *e,
 
1559
        Attribute *attr,
 
1560
        const char** text,
 
1561
        char *textbuf, size_t textlen )
 
1562
{
 
1563
        *text = textbuf;
 
1564
 
 
1565
        if( !SLAP_SUBENTRIES(be) ) {
 
1566
                snprintf( textbuf, textlen,
 
1567
                        "attribute \"%s\" not supported in context",
 
1568
                        attr->a_desc->ad_cname.bv_val );
 
1569
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1570
        }
 
1571
 
 
1572
        snprintf( textbuf, textlen,
 
1573
                "attribute \"%s\" not supported!",
 
1574
                attr->a_desc->ad_cname.bv_val );
 
1575
        return LDAP_OBJECT_CLASS_VIOLATION;
 
1576
}
 
1577
 
 
1578
#ifdef LDAP_DYNAMIC_OBJECTS
 
1579
static int dynamicAttribute (
 
1580
        Backend *be,
 
1581
        Entry *e,
 
1582
        Attribute *attr,
 
1583
        const char** text,
 
1584
        char *textbuf, size_t textlen )
 
1585
{
 
1586
        *text = textbuf;
 
1587
 
 
1588
        if( !SLAP_DYNAMIC(be) ) {
 
1589
                snprintf( textbuf, textlen,
 
1590
                        "attribute \"%s\" not supported in context",
 
1591
                        attr->a_desc->ad_cname.bv_val );
 
1592
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1593
        }
 
1594
 
 
1595
        if( !is_entry_dynamicObject( e ) ) {
 
1596
                snprintf( textbuf, textlen,
 
1597
                        "attribute \"%s\" only allowed in dynamic object",
 
1598
                        attr->a_desc->ad_cname.bv_val );
 
1599
                return LDAP_OBJECT_CLASS_VIOLATION;
 
1600
        }
 
1601
 
 
1602
        return LDAP_SUCCESS;
 
1603
}
 
1604
#endif /* LDAP_DYNAMIC_OBJECTS */