Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.naming/share/classes/com/sun/jndi/ldap/LdapSchemaParser.java
41161 views
1
/*
2
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package com.sun.jndi.ldap;
27
28
import javax.naming.*;
29
import javax.naming.directory.*;
30
import java.util.Vector;
31
32
/**
33
* Netscape's 3.1 servers have some schema bugs:
34
* - It puts quotes around OIDs (such as those for SUP, SYNTAX).
35
* - When you try to write out the MUST/MAY list (such as "MUST cn"),
36
* it wants ("MUST (cn)") instead
37
*/
38
39
final class LdapSchemaParser {
40
41
// do debugging
42
private static final boolean debug = false;
43
44
45
// names of attribute IDs in the LDAP schema entry
46
static final String OBJECTCLASSDESC_ATTR_ID = "objectClasses";
47
static final String ATTRIBUTEDESC_ATTR_ID = "attributeTypes";
48
static final String SYNTAXDESC_ATTR_ID = "ldapSyntaxes";
49
static final String MATCHRULEDESC_ATTR_ID = "matchingRules";
50
51
// information for creating internal nodes in JNDI schema tree
52
static final String OBJECTCLASS_DEFINITION_NAME =
53
"ClassDefinition";
54
private static final String[] CLASS_DEF_ATTRS = {
55
"objectclass", "ClassDefinition"};
56
static final String ATTRIBUTE_DEFINITION_NAME =
57
"AttributeDefinition";
58
private static final String[] ATTR_DEF_ATTRS = {
59
"objectclass", "AttributeDefinition" };
60
static final String SYNTAX_DEFINITION_NAME =
61
"SyntaxDefinition";
62
private static final String[] SYNTAX_DEF_ATTRS = {
63
"objectclass", "SyntaxDefinition" };
64
static final String MATCHRULE_DEFINITION_NAME =
65
"MatchingRule";
66
private static final String[] MATCHRULE_DEF_ATTRS = {
67
"objectclass", "MatchingRule" };
68
69
// special tokens used in LDAP schema descriptions
70
private static final char SINGLE_QUOTE = '\'';
71
private static final char WHSP = ' ';
72
private static final char OID_LIST_BEGIN = '(';
73
private static final char OID_LIST_END = ')';
74
private static final char OID_SEPARATOR = '$';
75
76
// common IDs
77
private static final String NUMERICOID_ID = "NUMERICOID";
78
private static final String NAME_ID = "NAME";
79
private static final String DESC_ID = "DESC";
80
private static final String OBSOLETE_ID = "OBSOLETE";
81
private static final String SUP_ID = "SUP";
82
private static final String PRIVATE_ID = "X-";
83
84
// Object Class specific IDs
85
private static final String ABSTRACT_ID = "ABSTRACT";
86
private static final String STRUCTURAL_ID = "STRUCTURAL";
87
private static final String AUXILIARY_ID = "AUXILIARY";
88
private static final String MUST_ID = "MUST";
89
private static final String MAY_ID = "MAY";
90
91
// Attribute Type specific IDs
92
private static final String EQUALITY_ID = "EQUALITY";
93
private static final String ORDERING_ID = "ORDERING";
94
private static final String SUBSTR_ID = "SUBSTR";
95
private static final String SYNTAX_ID = "SYNTAX";
96
private static final String SINGLE_VAL_ID = "SINGLE-VALUE";
97
private static final String COLLECTIVE_ID = "COLLECTIVE";
98
private static final String NO_USER_MOD_ID = "NO-USER-MODIFICATION";
99
private static final String USAGE_ID = "USAGE";
100
101
// The string value we give to boolean variables
102
private static final String SCHEMA_TRUE_VALUE = "true";
103
104
// To get around writing schemas that crash Netscape server
105
private boolean netscapeBug;
106
107
LdapSchemaParser(boolean netscapeBug) {
108
this.netscapeBug = netscapeBug;
109
}
110
111
static final void LDAP2JNDISchema(Attributes schemaAttrs,
112
LdapSchemaCtx schemaRoot) throws NamingException {
113
Attribute objectClassesAttr = null;
114
Attribute attributeDefAttr = null;
115
Attribute syntaxDefAttr = null;
116
Attribute matchRuleDefAttr = null;
117
118
objectClassesAttr = schemaAttrs.get(OBJECTCLASSDESC_ATTR_ID);
119
if(objectClassesAttr != null) {
120
objectDescs2ClassDefs(objectClassesAttr,schemaRoot);
121
}
122
123
attributeDefAttr = schemaAttrs.get(ATTRIBUTEDESC_ATTR_ID);
124
if(attributeDefAttr != null) {
125
attrDescs2AttrDefs(attributeDefAttr, schemaRoot);
126
}
127
128
syntaxDefAttr = schemaAttrs.get(SYNTAXDESC_ATTR_ID);
129
if(syntaxDefAttr != null) {
130
syntaxDescs2SyntaxDefs(syntaxDefAttr, schemaRoot);
131
}
132
133
matchRuleDefAttr = schemaAttrs.get(MATCHRULEDESC_ATTR_ID);
134
if(matchRuleDefAttr != null) {
135
matchRuleDescs2MatchRuleDefs(matchRuleDefAttr, schemaRoot);
136
}
137
}
138
139
private static final DirContext objectDescs2ClassDefs(Attribute objDescsAttr,
140
LdapSchemaCtx schemaRoot)
141
throws NamingException {
142
143
NamingEnumeration<?> objDescs;
144
Attributes objDef;
145
LdapSchemaCtx classDefTree;
146
147
// create the class def subtree
148
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
149
attrs.put(CLASS_DEF_ATTRS[0], CLASS_DEF_ATTRS[1]);
150
classDefTree = schemaRoot.setup(LdapSchemaCtx.OBJECTCLASS_ROOT,
151
OBJECTCLASS_DEFINITION_NAME, attrs);
152
153
objDescs = objDescsAttr.getAll();
154
String currentName;
155
while(objDescs.hasMore()) {
156
String objDesc = (String)objDescs.next();
157
try {
158
Object[] def = desc2Def(objDesc);
159
currentName = (String) def[0];
160
objDef = (Attributes) def[1];
161
classDefTree.setup(LdapSchemaCtx.OBJECTCLASS,
162
currentName, objDef);
163
} catch (NamingException ne) {
164
// error occurred while parsing, ignore current entry
165
}
166
}
167
168
return classDefTree;
169
}
170
171
private static final DirContext attrDescs2AttrDefs(Attribute attributeDescAttr,
172
LdapSchemaCtx schemaRoot)
173
throws NamingException {
174
175
NamingEnumeration<?> attrDescs;
176
Attributes attrDef;
177
LdapSchemaCtx attrDefTree;
178
179
// create the AttributeDef subtree
180
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
181
attrs.put(ATTR_DEF_ATTRS[0], ATTR_DEF_ATTRS[1]);
182
attrDefTree = schemaRoot.setup(LdapSchemaCtx.ATTRIBUTE_ROOT,
183
ATTRIBUTE_DEFINITION_NAME, attrs);
184
185
attrDescs = attributeDescAttr.getAll();
186
String currentName;
187
while(attrDescs.hasMore()) {
188
String attrDesc = (String)attrDescs.next();
189
try {
190
Object[] def = desc2Def(attrDesc);
191
currentName = (String) def[0];
192
attrDef = (Attributes) def[1];
193
attrDefTree.setup(LdapSchemaCtx.ATTRIBUTE,
194
currentName, attrDef);
195
} catch (NamingException ne) {
196
// error occurred while parsing, ignore current entry
197
}
198
}
199
200
return attrDefTree;
201
}
202
203
private static final DirContext syntaxDescs2SyntaxDefs(
204
Attribute syntaxDescAttr,
205
LdapSchemaCtx schemaRoot)
206
throws NamingException {
207
208
NamingEnumeration<?> syntaxDescs;
209
Attributes syntaxDef;
210
LdapSchemaCtx syntaxDefTree;
211
212
// create the SyntaxDef subtree
213
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
214
attrs.put(SYNTAX_DEF_ATTRS[0], SYNTAX_DEF_ATTRS[1]);
215
syntaxDefTree = schemaRoot.setup(LdapSchemaCtx.SYNTAX_ROOT,
216
SYNTAX_DEFINITION_NAME, attrs);
217
218
syntaxDescs = syntaxDescAttr.getAll();
219
String currentName;
220
while(syntaxDescs.hasMore()) {
221
String syntaxDesc = (String)syntaxDescs.next();
222
try {
223
Object[] def = desc2Def(syntaxDesc);
224
currentName = (String) def[0];
225
syntaxDef = (Attributes) def[1];
226
syntaxDefTree.setup(LdapSchemaCtx.SYNTAX,
227
currentName, syntaxDef);
228
} catch (NamingException ne) {
229
// error occurred while parsing, ignore current entry
230
}
231
}
232
233
return syntaxDefTree;
234
}
235
236
private static final DirContext matchRuleDescs2MatchRuleDefs(
237
Attribute matchRuleDescAttr,
238
LdapSchemaCtx schemaRoot)
239
throws NamingException {
240
241
NamingEnumeration<?> matchRuleDescs;
242
Attributes matchRuleDef;
243
LdapSchemaCtx matchRuleDefTree;
244
245
// create the MatchRuleDef subtree
246
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
247
attrs.put(MATCHRULE_DEF_ATTRS[0], MATCHRULE_DEF_ATTRS[1]);
248
matchRuleDefTree = schemaRoot.setup(LdapSchemaCtx.MATCHRULE_ROOT,
249
MATCHRULE_DEFINITION_NAME, attrs);
250
251
matchRuleDescs = matchRuleDescAttr.getAll();
252
String currentName;
253
while(matchRuleDescs.hasMore()) {
254
String matchRuleDesc = (String)matchRuleDescs.next();
255
try {
256
Object[] def = desc2Def(matchRuleDesc);
257
currentName = (String) def[0];
258
matchRuleDef = (Attributes) def[1];
259
matchRuleDefTree.setup(LdapSchemaCtx.MATCHRULE,
260
currentName, matchRuleDef);
261
} catch (NamingException ne) {
262
// error occurred while parsing, ignore current entry
263
}
264
}
265
266
return matchRuleDefTree;
267
}
268
269
private static final Object[] desc2Def(String desc)
270
throws NamingException {
271
//System.err.println(desc);
272
273
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
274
Attribute attr = null;
275
int[] pos = new int[]{1}; // tolerate missing leading space
276
boolean moreTags = true;
277
278
// Always begins with <whsp numericoid whsp>
279
attr = readNumericOID(desc, pos);
280
String currentName = (String) attr.get(0); // name is OID by default
281
attrs.put(attr);
282
283
skipWhitespace(desc, pos);
284
285
while (moreTags) {
286
attr = readNextTag(desc, pos);
287
attrs.put(attr);
288
289
if (attr.getID().equals(NAME_ID)) {
290
currentName = (String) attr.get(0); // use NAME attribute as name
291
}
292
293
skipWhitespace(desc, pos);
294
295
if( pos[0] >= desc.length() -1 ) {
296
moreTags = false;
297
}
298
}
299
300
return new Object[] {currentName, attrs};
301
}
302
303
// returns the index of the first whitespace char of a linear whitespace
304
// sequence ending at the given position.
305
private static final int findTrailingWhitespace(String string, int pos) {
306
for(int i = pos; i > 0; i--) {
307
if(string.charAt(i) != WHSP) {
308
return i + 1;
309
}
310
}
311
return 0;
312
}
313
314
private static final void skipWhitespace(String string, int[] pos) {
315
for(int i=pos[0]; i < string.length(); i++) {
316
if(string.charAt(i) != WHSP) {
317
pos[0] = i;
318
if (debug) {
319
System.err.println("skipWhitespace: skipping to "+i);
320
}
321
return;
322
}
323
}
324
}
325
326
private static final Attribute readNumericOID(String string, int[] pos)
327
throws NamingException {
328
329
if (debug) {
330
System.err.println("readNumericoid: pos="+pos[0]);
331
}
332
333
int begin, end;
334
String value = null;
335
336
skipWhitespace(string, pos);
337
338
begin = pos[0];
339
end = string.indexOf(WHSP, begin);
340
341
if (end == -1 || end - begin < 1) {
342
throw new InvalidAttributeValueException("no numericoid found: "
343
+ string);
344
}
345
346
value = string.substring(begin, end);
347
348
pos[0] += value.length();
349
350
return new BasicAttribute(NUMERICOID_ID, value);
351
}
352
353
private static final Attribute readNextTag(String string, int[] pos)
354
throws NamingException {
355
356
Attribute attr = null;
357
String tagName = null;
358
String[] values = null;
359
360
skipWhitespace(string, pos);
361
362
if (debug) {
363
System.err.println("readNextTag: pos="+pos[0]);
364
}
365
366
// get the name and values of the attribute to return
367
int trailingSpace = string.indexOf( WHSP, pos[0] );
368
369
// tolerate a schema that omits the trailing space
370
if (trailingSpace < 0) {
371
tagName = string.substring( pos[0], string.length() - 1);
372
} else {
373
tagName = string.substring( pos[0], trailingSpace );
374
}
375
376
values = readTag(tagName, string, pos);
377
378
// make sure at least one value was returned
379
if (values.length == 0) {
380
throw new InvalidAttributeValueException("no values for " +
381
"attribute \"" +
382
tagName + "\"");
383
}
384
385
// create the attribute, using the first value
386
attr = new BasicAttribute(tagName, values[0]);
387
388
// add other values if there are any
389
for(int i = 1; i < values.length; i++) {
390
attr.add(values[i]);
391
}
392
393
return attr;
394
}
395
396
private static final String[] readTag(String tag, String string, int[] pos)
397
throws NamingException {
398
399
if (debug) {
400
System.err.println("ReadTag: " + tag + " pos="+pos[0]);
401
}
402
403
// move parser past tag name
404
pos[0] += tag.length();
405
skipWhitespace(string, pos);
406
407
if (tag.equals(NAME_ID)) {
408
return readQDescrs(string, pos); // names[0] is NAME
409
}
410
411
if(tag.equals(DESC_ID)) {
412
return readQDString(string, pos);
413
}
414
415
if (
416
tag.equals(EQUALITY_ID) ||
417
tag.equals(ORDERING_ID) ||
418
tag.equals(SUBSTR_ID) ||
419
tag.equals(SYNTAX_ID)) {
420
return readWOID(string, pos);
421
}
422
423
if (tag.equals(OBSOLETE_ID) ||
424
tag.equals(ABSTRACT_ID) ||
425
tag.equals(STRUCTURAL_ID) ||
426
tag.equals(AUXILIARY_ID) ||
427
tag.equals(SINGLE_VAL_ID) ||
428
tag.equals(COLLECTIVE_ID) ||
429
tag.equals(NO_USER_MOD_ID)) {
430
return new String[] {SCHEMA_TRUE_VALUE};
431
}
432
433
if (tag.equals(SUP_ID) || // oid list for object class; WOID for attribute
434
tag.equals(MUST_ID) ||
435
tag.equals(MAY_ID) ||
436
tag.equals(USAGE_ID)) {
437
return readOIDs(string, pos);
438
}
439
440
// otherwise it's a schema element with a quoted string value
441
return readQDStrings(string, pos);
442
}
443
444
private static final String[] readQDString(String string, int[] pos)
445
throws NamingException {
446
447
int begin, end;
448
449
begin = string.indexOf(SINGLE_QUOTE, pos[0]) + 1;
450
end = string.indexOf(SINGLE_QUOTE, begin);
451
452
if (debug) {
453
System.err.println("ReadQDString: pos=" + pos[0] +
454
" begin=" + begin + " end=" + end);
455
}
456
457
if(begin == -1 || end == -1 || begin == end) {
458
throw new InvalidAttributeIdentifierException("malformed " +
459
"QDString: " +
460
string);
461
}
462
463
// make sure the qdstring end symbol is there
464
if (string.charAt(begin - 1) != SINGLE_QUOTE) {
465
throw new InvalidAttributeIdentifierException("qdstring has " +
466
"no end mark: " +
467
string);
468
}
469
470
pos[0] = end+1;
471
return new String[] {string.substring(begin, end)};
472
}
473
474
/**
475
* dstring = 1*utf8
476
* qdstring = whsp "'" dstring "'" whsp
477
* qdstringlist = [ qdstring *( qdstring ) ]
478
* qdstrings = qdstring / ( whsp "(" qdstringlist ")" whsp )
479
*/
480
private static final String[] readQDStrings(String string, int[] pos)
481
throws NamingException {
482
483
return readQDescrs(string, pos);
484
}
485
486
/**
487
* ; object descriptors used as schema element names
488
* qdescrs = qdescr / ( whsp "(" qdescrlist ")" whsp )
489
* qdescrlist = [ qdescr *( qdescr ) ]
490
* qdescr = whsp "'" descr "'" whsp
491
* descr = keystring
492
*/
493
private static final String[] readQDescrs(String string, int[] pos)
494
throws NamingException {
495
496
if (debug) {
497
System.err.println("readQDescrs: pos="+pos[0]);
498
}
499
500
skipWhitespace(string, pos);
501
502
switch( string.charAt(pos[0]) ) {
503
case OID_LIST_BEGIN:
504
return readQDescrList(string, pos);
505
case SINGLE_QUOTE:
506
return readQDString(string, pos);
507
default:
508
throw new InvalidAttributeValueException("unexpected oids " +
509
"string: " + string);
510
}
511
}
512
513
/**
514
* qdescrlist = [ qdescr *( qdescr ) ]
515
* qdescr = whsp "'" descr "'" whsp
516
* descr = keystring
517
*/
518
private static final String[] readQDescrList(String string, int[] pos)
519
throws NamingException {
520
521
int begin, end;
522
Vector<String> values = new Vector<>(5);
523
524
if (debug) {
525
System.err.println("ReadQDescrList: pos="+pos[0]);
526
}
527
528
pos[0]++; // skip '('
529
skipWhitespace(string, pos);
530
begin = pos[0];
531
end = string.indexOf(OID_LIST_END, begin);
532
533
if(end == -1) {
534
throw new InvalidAttributeValueException ("oidlist has no end "+
535
"mark: " + string);
536
}
537
538
while(begin < end) {
539
String[] one = readQDString(string, pos);
540
541
if (debug) {
542
System.err.println("ReadQDescrList: found '" + one[0] +
543
"' at begin=" + begin + " end =" + end);
544
}
545
546
values.addElement(one[0]);
547
skipWhitespace(string, pos);
548
begin = pos[0];
549
}
550
551
pos[0] = end+1; // skip ')'
552
553
String[] answer = new String[values.size()];
554
for (int i = 0; i < answer.length; i++) {
555
answer[i] = values.elementAt(i);
556
}
557
return answer;
558
}
559
560
private static final String[] readWOID(String string, int[] pos)
561
throws NamingException {
562
563
if (debug) {
564
System.err.println("readWOIDs: pos="+pos[0]);
565
}
566
567
skipWhitespace(string, pos);
568
569
if (string.charAt(pos[0]) == SINGLE_QUOTE) {
570
// %%% workaround for Netscape schema bug
571
return readQDString(string, pos);
572
}
573
574
int begin, end;
575
576
begin = pos[0];
577
end = string.indexOf(WHSP, begin);
578
579
if (debug) {
580
System.err.println("ReadWOID: pos=" + pos[0] +
581
" begin=" + begin + " end=" + end);
582
}
583
584
if(end == -1 || begin == end) {
585
throw new InvalidAttributeIdentifierException("malformed " +
586
"OID: " +
587
string);
588
}
589
pos[0] = end+1;
590
591
return new String[] {string.substring(begin, end)};
592
}
593
594
/*
595
* oids = woid / ( "(" oidlist ")" )
596
* oidlist = woid *( "$" woid )
597
*/
598
private static final String[] readOIDs(String string, int[] pos)
599
throws NamingException {
600
601
if (debug) {
602
System.err.println("readOIDs: pos="+pos[0]);
603
}
604
605
skipWhitespace(string, pos);
606
607
// Single OID
608
if (string.charAt(pos[0]) != OID_LIST_BEGIN) {
609
return readWOID(string, pos);
610
}
611
612
// Multiple OIDs
613
614
int begin, cur, end;
615
String oidName = null;
616
Vector<String> values = new Vector<>(5);
617
618
if (debug) {
619
System.err.println("ReadOIDList: pos="+pos[0]);
620
}
621
622
pos[0]++;
623
skipWhitespace(string, pos);
624
begin = pos[0];
625
end = string.indexOf(OID_LIST_END, begin);
626
cur = string.indexOf(OID_SEPARATOR, begin);
627
628
if(end == -1) {
629
throw new InvalidAttributeValueException ("oidlist has no end "+
630
"mark: " + string);
631
}
632
633
if(cur == -1 || end < cur) {
634
cur = end;
635
}
636
637
while(cur < end && cur > 0) {
638
int wsBegin = findTrailingWhitespace(string, cur - 1);
639
oidName = string.substring(begin, wsBegin);
640
if (debug) {
641
System.err.println("ReadOIDList: found '" + oidName +
642
"' at begin=" + begin + " end =" + end);
643
}
644
values.addElement(oidName);
645
pos[0] = cur + 1;
646
skipWhitespace(string, pos);
647
begin = pos[0];
648
cur = string.indexOf(OID_SEPARATOR, begin);
649
if(debug) {System.err.println("ReadOIDList: begin = " + begin);}
650
}
651
652
if (debug) {
653
System.err.println("ReadOIDList: found '" + oidName +
654
"' at begin=" + begin + " end =" + end);
655
}
656
657
int wsBegin = findTrailingWhitespace(string, end - 1);
658
oidName = string.substring(begin, wsBegin);
659
values.addElement(oidName);
660
661
pos[0] = end+1;
662
663
String[] answer = new String[values.size()];
664
for (int i = 0; i < answer.length; i++) {
665
answer[i] = values.elementAt(i);
666
}
667
return answer;
668
}
669
670
// ----------------- "unparser" methods
671
// Methods that are used for translating a node in the schema tree
672
// into RFC2252 format for storage back into the LDAP directory
673
/*
674
static Attributes JNDI2LDAPSchema(DirContext schemaRoot)
675
throws NamingException {
676
677
Attribute objDescAttr = new BasicAttribute(OBJECTCLASSDESC_ATTR_ID);
678
Attribute attrDescAttr = new BasicAttribute(ATTRIBUTEDESC_ATTR_ID);
679
Attribute syntaxDescAttr = new BasicAttribute(SYNTAXDESC_ATTR_ID);
680
Attributes attrs = new BasicAttributes(LdapClient.caseIgnore);
681
DirContext classDefs, attributeDefs, syntaxDefs;
682
Attributes classDefsAttrs, attributeDefsAttrs, syntaxDefsAttrs;
683
NamingEnumeration defs;
684
Object obj;
685
int i = 0;
686
687
try {
688
obj = schemaRoot.lookup(OBJECTCLASS_DEFINITION_NAME);
689
if(obj != null && obj instanceof DirContext) {
690
classDefs = (DirContext)obj;
691
defs = classDefs.listBindings("");
692
while(defs.hasMoreElements()) {
693
i++;
694
DirContext classDef = (DirContext)
695
((Binding)(defs.next())).getObject();
696
classDefAttrs = classDef.getAttributes("");
697
objDescAttr.add(classDef2ObjectDesc(classDefAttrs));
698
}
699
if (debug)
700
System.err.println(i + " total object classes");
701
attrs.put(objDescAttr);
702
} else {
703
throw new NamingException(
704
"Problem with Schema tree: the object named " +
705
OBJECTCLASS_DEFINITION_NAME + " is not a " +
706
"DirContext");
707
}
708
} catch (NameNotFoundException e) {} // ignore
709
710
i=0;
711
try {
712
obj = schemaRoot.lookup(ATTRIBUTE_DEFINITION_NAME);
713
if(obj instanceof DirContext) {
714
attributeDefs = (DirContext)obj;
715
defs = attributeDefs.listBindings("");
716
while(defs.hasMoreElements()) {
717
i++;
718
DirContext attrDef = (DirContext)
719
((Binding)defs.next()).getObject();
720
attrDefAttrs = attrDef.getAttributes("");
721
attrDescAttr.add(attrDef2AttrDesc(attrDefAttrs));
722
}
723
if (debug)
724
System.err.println(i + " attribute definitions");
725
attrs.put(attrDescAttr);
726
} else {
727
throw new NamingException(
728
"Problem with schema tree: the object named " +
729
ATTRIBUTE_DEFINITION_NAME + " is not a " +
730
"DirContext");
731
}
732
} catch (NameNotFoundException e) {} // ignore
733
734
i=0;
735
try {
736
obj = schemaRoot.lookup(SYNTAX_DEFINITION_NAME);
737
if(obj instanceof DirContext) {
738
syntaxDefs = (DirContext)obj;
739
defs =syntaxDefs.listBindings("");
740
while(defs.hasMoreElements()) {
741
i++;
742
DirContext syntaxDef = (DirContext)
743
((Binding)defs.next()).getObject();
744
syntaxDefAttrs = syntaxDef.getAttributes("");
745
syntaxDescAttr.add(syntaxDef2SyntaxDesc(syntaxDefAttrs));
746
}
747
if (debug)
748
System.err.println(i + " total syntax definitions");
749
attrs.put(syntaxDescAttr);
750
} else {
751
throw new NamingException(
752
"Problem with schema tree: the object named " +
753
SYNTAX_DEFINITION_NAME + " is not a " +
754
"DirContext");
755
}
756
} catch (NameNotFoundException e) {} // ignore
757
758
return attrs;
759
}
760
761
*/
762
763
/**
764
* Translate attributes that describe an object class into the
765
* string description as defined in RFC 2252.
766
*/
767
private final String classDef2ObjectDesc(Attributes attrs)
768
throws NamingException {
769
770
StringBuilder objectDesc = new StringBuilder("( ");
771
772
Attribute attr = null;
773
int count = 0;
774
775
// extract attributes by ID to guarantee ordering
776
777
attr = attrs.get(NUMERICOID_ID);
778
if (attr != null) {
779
objectDesc.append(writeNumericOID(attr));
780
count++;
781
} else {
782
throw new ConfigurationException("Class definition doesn't" +
783
"have a numeric OID");
784
}
785
786
attr = attrs.get(NAME_ID);
787
if (attr != null) {
788
objectDesc.append(writeQDescrs(attr));
789
count++;
790
}
791
792
attr = attrs.get(DESC_ID);
793
if (attr != null) {
794
objectDesc.append(writeQDString(attr));
795
count++;
796
}
797
798
attr = attrs.get(OBSOLETE_ID);
799
if (attr != null) {
800
objectDesc.append(writeBoolean(attr));
801
count++;
802
}
803
804
attr = attrs.get(SUP_ID);
805
if (attr != null) {
806
objectDesc.append(writeOIDs(attr));
807
count++;
808
}
809
810
attr = attrs.get(ABSTRACT_ID);
811
if (attr != null) {
812
objectDesc.append(writeBoolean(attr));
813
count++;
814
}
815
816
attr = attrs.get(STRUCTURAL_ID);
817
if (attr != null) {
818
objectDesc.append(writeBoolean(attr));
819
count++;
820
}
821
822
attr = attrs.get(AUXILIARY_ID);
823
if (attr != null) {
824
objectDesc.append(writeBoolean(attr));
825
count++;
826
}
827
828
attr = attrs.get(MUST_ID);
829
if (attr != null) {
830
objectDesc.append(writeOIDs(attr));
831
count++;
832
}
833
834
attr = attrs.get(MAY_ID);
835
if (attr != null) {
836
objectDesc.append(writeOIDs(attr));
837
count++;
838
}
839
840
// process any remaining attributes
841
if (count < attrs.size()) {
842
String attrId = null;
843
844
// use enumeration because attribute ID is not known
845
for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
846
ae.hasMoreElements(); ) {
847
848
attr = ae.next();
849
attrId = attr.getID();
850
851
// skip those already processed
852
if (attrId.equals(NUMERICOID_ID) ||
853
attrId.equals(NAME_ID) ||
854
attrId.equals(SUP_ID) ||
855
attrId.equals(MAY_ID) ||
856
attrId.equals(MUST_ID) ||
857
attrId.equals(STRUCTURAL_ID) ||
858
attrId.equals(DESC_ID) ||
859
attrId.equals(AUXILIARY_ID) ||
860
attrId.equals(ABSTRACT_ID) ||
861
attrId.equals(OBSOLETE_ID)) {
862
continue;
863
864
} else {
865
objectDesc.append(writeQDStrings(attr));
866
}
867
}
868
}
869
870
objectDesc.append(")");
871
872
return objectDesc.toString();
873
}
874
875
/**
876
* Translate attributes that describe an attribute definition into the
877
* string description as defined in RFC 2252.
878
*/
879
private final String attrDef2AttrDesc(Attributes attrs)
880
throws NamingException {
881
882
StringBuilder attrDesc = new StringBuilder("( "); // opening parens
883
884
Attribute attr = null;
885
int count = 0;
886
887
// extract attributes by ID to guarantee ordering
888
889
attr = attrs.get(NUMERICOID_ID);
890
if (attr != null) {
891
attrDesc.append(writeNumericOID(attr));
892
count++;
893
} else {
894
throw new ConfigurationException("Attribute type doesn't" +
895
"have a numeric OID");
896
}
897
898
attr = attrs.get(NAME_ID);
899
if (attr != null) {
900
attrDesc.append(writeQDescrs(attr));
901
count++;
902
}
903
904
attr = attrs.get(DESC_ID);
905
if (attr != null) {
906
attrDesc.append(writeQDString(attr));
907
count++;
908
}
909
910
attr = attrs.get(OBSOLETE_ID);
911
if (attr != null) {
912
attrDesc.append(writeBoolean(attr));
913
count++;
914
}
915
916
attr = attrs.get(SUP_ID);
917
if (attr != null) {
918
attrDesc.append(writeWOID(attr));
919
count++;
920
}
921
922
attr = attrs.get(EQUALITY_ID);
923
if (attr != null) {
924
attrDesc.append(writeWOID(attr));
925
count++;
926
}
927
928
attr = attrs.get(ORDERING_ID);
929
if (attr != null) {
930
attrDesc.append(writeWOID(attr));
931
count++;
932
}
933
934
attr = attrs.get(SUBSTR_ID);
935
if (attr != null) {
936
attrDesc.append(writeWOID(attr));
937
count++;
938
}
939
940
attr = attrs.get(SYNTAX_ID);
941
if (attr != null) {
942
attrDesc.append(writeWOID(attr));
943
count++;
944
}
945
946
attr = attrs.get(SINGLE_VAL_ID);
947
if (attr != null) {
948
attrDesc.append(writeBoolean(attr));
949
count++;
950
}
951
952
attr = attrs.get(COLLECTIVE_ID);
953
if (attr != null) {
954
attrDesc.append(writeBoolean(attr));
955
count++;
956
}
957
958
attr = attrs.get(NO_USER_MOD_ID);
959
if (attr != null) {
960
attrDesc.append(writeBoolean(attr));
961
count++;
962
}
963
964
attr = attrs.get(USAGE_ID);
965
if (attr != null) {
966
attrDesc.append(writeQDString(attr));
967
count++;
968
}
969
970
// process any remaining attributes
971
if (count < attrs.size()) {
972
String attrId = null;
973
974
// use enumeration because attribute ID is not known
975
for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
976
ae.hasMoreElements(); ) {
977
978
attr = ae.next();
979
attrId = attr.getID();
980
981
// skip those already processed
982
if (attrId.equals(NUMERICOID_ID) ||
983
attrId.equals(NAME_ID) ||
984
attrId.equals(SYNTAX_ID) ||
985
attrId.equals(DESC_ID) ||
986
attrId.equals(SINGLE_VAL_ID) ||
987
attrId.equals(EQUALITY_ID) ||
988
attrId.equals(ORDERING_ID) ||
989
attrId.equals(SUBSTR_ID) ||
990
attrId.equals(NO_USER_MOD_ID) ||
991
attrId.equals(USAGE_ID) ||
992
attrId.equals(SUP_ID) ||
993
attrId.equals(COLLECTIVE_ID) ||
994
attrId.equals(OBSOLETE_ID)) {
995
continue;
996
997
} else {
998
attrDesc.append(writeQDStrings(attr));
999
}
1000
}
1001
}
1002
1003
attrDesc.append(")"); // add closing parens
1004
1005
return attrDesc.toString();
1006
}
1007
1008
/**
1009
* Translate attributes that describe an attribute syntax definition into the
1010
* string description as defined in RFC 2252.
1011
*/
1012
private final String syntaxDef2SyntaxDesc(Attributes attrs)
1013
throws NamingException {
1014
1015
StringBuilder syntaxDesc = new StringBuilder("( "); // opening parens
1016
1017
Attribute attr = null;
1018
int count = 0;
1019
1020
// extract attributes by ID to guarantee ordering
1021
1022
attr = attrs.get(NUMERICOID_ID);
1023
if (attr != null) {
1024
syntaxDesc.append(writeNumericOID(attr));
1025
count++;
1026
} else {
1027
throw new ConfigurationException("Attribute type doesn't" +
1028
"have a numeric OID");
1029
}
1030
1031
attr = attrs.get(DESC_ID);
1032
if (attr != null) {
1033
syntaxDesc.append(writeQDString(attr));
1034
count++;
1035
}
1036
1037
// process any remaining attributes
1038
if (count < attrs.size()) {
1039
String attrId = null;
1040
1041
// use enumeration because attribute ID is not known
1042
for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
1043
ae.hasMoreElements(); ) {
1044
1045
attr = ae.next();
1046
attrId = attr.getID();
1047
1048
// skip those already processed
1049
if (attrId.equals(NUMERICOID_ID) ||
1050
attrId.equals(DESC_ID)) {
1051
continue;
1052
1053
} else {
1054
syntaxDesc.append(writeQDStrings(attr));
1055
}
1056
}
1057
}
1058
1059
syntaxDesc.append(")");
1060
1061
return syntaxDesc.toString();
1062
}
1063
1064
/**
1065
* Translate attributes that describe an attribute matching rule
1066
* definition into the string description as defined in RFC 2252.
1067
*/
1068
private final String matchRuleDef2MatchRuleDesc(Attributes attrs)
1069
throws NamingException {
1070
1071
StringBuilder matchRuleDesc = new StringBuilder("( "); // opening parens
1072
1073
Attribute attr = null;
1074
int count = 0;
1075
1076
// extract attributes by ID to guarantee ordering
1077
1078
attr = attrs.get(NUMERICOID_ID);
1079
if (attr != null) {
1080
matchRuleDesc.append(writeNumericOID(attr));
1081
count++;
1082
} else {
1083
throw new ConfigurationException("Attribute type doesn't" +
1084
"have a numeric OID");
1085
}
1086
1087
attr = attrs.get(NAME_ID);
1088
if (attr != null) {
1089
matchRuleDesc.append(writeQDescrs(attr));
1090
count++;
1091
}
1092
1093
attr = attrs.get(DESC_ID);
1094
if (attr != null) {
1095
matchRuleDesc.append(writeQDString(attr));
1096
count++;
1097
}
1098
1099
attr = attrs.get(OBSOLETE_ID);
1100
if (attr != null) {
1101
matchRuleDesc.append(writeBoolean(attr));
1102
count++;
1103
}
1104
1105
attr = attrs.get(SYNTAX_ID);
1106
if (attr != null) {
1107
matchRuleDesc.append(writeWOID(attr));
1108
count++;
1109
} else {
1110
throw new ConfigurationException("Attribute type doesn't" +
1111
"have a syntax OID");
1112
}
1113
1114
// process any remaining attributes
1115
if (count < attrs.size()) {
1116
String attrId = null;
1117
1118
// use enumeration because attribute ID is not known
1119
for (NamingEnumeration<? extends Attribute> ae = attrs.getAll();
1120
ae.hasMoreElements(); ) {
1121
1122
attr = ae.next();
1123
attrId = attr.getID();
1124
1125
// skip those already processed
1126
if (attrId.equals(NUMERICOID_ID) ||
1127
attrId.equals(NAME_ID) ||
1128
attrId.equals(SYNTAX_ID) ||
1129
attrId.equals(DESC_ID) ||
1130
attrId.equals(OBSOLETE_ID)) {
1131
continue;
1132
1133
} else {
1134
matchRuleDesc.append(writeQDStrings(attr));
1135
}
1136
}
1137
}
1138
1139
matchRuleDesc.append(")");
1140
1141
return matchRuleDesc.toString();
1142
}
1143
1144
private final String writeNumericOID(Attribute nOIDAttr)
1145
throws NamingException {
1146
if(nOIDAttr.size() != 1) {
1147
throw new InvalidAttributeValueException(
1148
"A class definition must have exactly one numeric OID");
1149
}
1150
return (String)(nOIDAttr.get()) + WHSP;
1151
}
1152
1153
private final String writeWOID(Attribute attr) throws NamingException {
1154
if (netscapeBug)
1155
return writeQDString(attr);
1156
else
1157
return attr.getID() + WHSP + attr.get() + WHSP;
1158
}
1159
1160
/* qdescr = whsp "'" descr "'" whsp */
1161
private final String writeQDString(Attribute qdStringAttr)
1162
throws NamingException {
1163
if(qdStringAttr.size() != 1) {
1164
throw new InvalidAttributeValueException(
1165
qdStringAttr.getID() + " must have exactly one value");
1166
}
1167
1168
return qdStringAttr.getID() + WHSP +
1169
SINGLE_QUOTE + qdStringAttr.get() + SINGLE_QUOTE + WHSP;
1170
}
1171
1172
/**
1173
* dstring = 1*utf8
1174
* qdstring = whsp "'" dstring "'" whsp
1175
* qdstringlist = [ qdstring *( qdstring ) ]
1176
* qdstrings = qdstring / ( whsp "(" qdstringlist ")" whsp )
1177
*/
1178
private final String writeQDStrings(Attribute attr) throws NamingException {
1179
return writeQDescrs(attr);
1180
}
1181
1182
/**
1183
* qdescrs = qdescr / ( whsp "(" qdescrlist ")" whsp )
1184
* qdescrlist = [ qdescr *( qdescr ) ]
1185
* qdescr = whsp "'" descr "'" whsp
1186
* descr = keystring
1187
*/
1188
private final String writeQDescrs(Attribute attr) throws NamingException {
1189
switch(attr.size()) {
1190
case 0:
1191
throw new InvalidAttributeValueException(
1192
attr.getID() + "has no values");
1193
case 1:
1194
return writeQDString(attr);
1195
}
1196
1197
// write QDList
1198
1199
StringBuilder qdList = new StringBuilder(attr.getID());
1200
qdList.append(WHSP);
1201
qdList.append(OID_LIST_BEGIN);
1202
1203
NamingEnumeration<?> values = attr.getAll();
1204
1205
while(values.hasMore()) {
1206
qdList.append(WHSP);
1207
qdList.append(SINGLE_QUOTE);
1208
qdList.append((String)values.next());
1209
qdList.append(SINGLE_QUOTE);
1210
qdList.append(WHSP);
1211
}
1212
1213
qdList.append(OID_LIST_END);
1214
qdList.append(WHSP);
1215
1216
return qdList.toString();
1217
}
1218
1219
private final String writeOIDs(Attribute oidsAttr)
1220
throws NamingException {
1221
1222
switch(oidsAttr.size()) {
1223
case 0:
1224
throw new InvalidAttributeValueException(
1225
oidsAttr.getID() + "has no values");
1226
1227
case 1:
1228
if (netscapeBug) {
1229
break; // %%% write out as list to avoid crashing server
1230
}
1231
return writeWOID(oidsAttr);
1232
}
1233
1234
// write OID List
1235
1236
StringBuilder oidList = new StringBuilder(oidsAttr.getID());
1237
oidList.append(WHSP);
1238
oidList.append(OID_LIST_BEGIN);
1239
1240
NamingEnumeration<?> values = oidsAttr.getAll();
1241
oidList.append(WHSP);
1242
oidList.append(values.next());
1243
1244
while(values.hasMore()) {
1245
oidList.append(WHSP);
1246
oidList.append(OID_SEPARATOR);
1247
oidList.append(WHSP);
1248
oidList.append((String)values.next());
1249
}
1250
1251
oidList.append(WHSP);
1252
oidList.append(OID_LIST_END);
1253
oidList.append(WHSP);
1254
1255
return oidList.toString();
1256
}
1257
1258
private final String writeBoolean(Attribute booleanAttr)
1259
throws NamingException {
1260
return booleanAttr.getID() + WHSP;
1261
}
1262
1263
/**
1264
* Returns an attribute for updating the Object Class Definition schema
1265
* attribute
1266
*/
1267
final Attribute stringifyObjDesc(Attributes classDefAttrs)
1268
throws NamingException {
1269
Attribute objDescAttr = new BasicAttribute(OBJECTCLASSDESC_ATTR_ID);
1270
objDescAttr.add(classDef2ObjectDesc(classDefAttrs));
1271
return objDescAttr;
1272
}
1273
1274
/**
1275
* Returns an attribute for updating the Attribute Definition schema attribute
1276
*/
1277
final Attribute stringifyAttrDesc(Attributes attrDefAttrs)
1278
throws NamingException {
1279
Attribute attrDescAttr = new BasicAttribute(ATTRIBUTEDESC_ATTR_ID);
1280
attrDescAttr.add(attrDef2AttrDesc(attrDefAttrs));
1281
return attrDescAttr;
1282
}
1283
1284
/**
1285
* Returns an attribute for updating the Syntax schema attribute
1286
*/
1287
final Attribute stringifySyntaxDesc(Attributes syntaxDefAttrs)
1288
throws NamingException {
1289
Attribute syntaxDescAttr = new BasicAttribute(SYNTAXDESC_ATTR_ID);
1290
syntaxDescAttr.add(syntaxDef2SyntaxDesc(syntaxDefAttrs));
1291
return syntaxDescAttr;
1292
}
1293
1294
/**
1295
* Returns an attribute for updating the Matching Rule schema attribute
1296
*/
1297
final Attribute stringifyMatchRuleDesc(Attributes matchRuleDefAttrs)
1298
throws NamingException {
1299
Attribute matchRuleDescAttr = new BasicAttribute(MATCHRULEDESC_ATTR_ID);
1300
matchRuleDescAttr.add(matchRuleDef2MatchRuleDesc(matchRuleDefAttrs));
1301
return matchRuleDescAttr;
1302
}
1303
}
1304
1305