1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.core.schema;
21
22
23 import org.apache.directory.server.constants.MetaSchemaConstants;
24 import org.apache.directory.server.core.DirectoryService;
25 import org.apache.directory.server.core.integ.CiRunner;
26 import static org.apache.directory.server.core.integ.IntegrationUtils.getSchemaContext;
27 import org.apache.directory.server.schema.bootstrap.Schema;
28 import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
29 import org.apache.directory.shared.ldap.exception.LdapNameNotFoundException;
30 import org.apache.directory.shared.ldap.exception.LdapOperationNotSupportedException;
31 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
32 import org.apache.directory.shared.ldap.constants.SchemaConstants;
33 import static org.junit.Assert.assertEquals;
34 import static org.junit.Assert.assertTrue;
35 import static org.junit.Assert.assertFalse;
36 import static org.junit.Assert.assertNull;
37 import static org.junit.Assert.assertNotNull;
38 import static org.junit.Assert.fail;
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42
43 import javax.naming.NamingException;
44 import javax.naming.directory.Attribute;
45 import javax.naming.directory.Attributes;
46 import javax.naming.directory.BasicAttribute;
47 import javax.naming.directory.BasicAttributes;
48 import javax.naming.directory.DirContext;
49 import javax.naming.directory.ModificationItem;
50 import javax.naming.ldap.LdapContext;
51 import java.util.Map;
52
53
54
55
56
57
58
59
60
61 @RunWith ( CiRunner.class )
62 public class MetaSchemaHandlerIT
63 {
64
65 private static final String TEST_SCHEMA = "nis";
66
67 private static final String TEST_ATTR_OID = "1.3.6.1.1.1.1.0";
68
69 private static final String DUMMY_SCHEMA = "dummy";
70
71
72 public static DirectoryService service;
73
74
75 private static AttributeTypeRegistry getAttributeTypeRegistry()
76 {
77 return service.getRegistries().getAttributeTypeRegistry();
78 }
79
80
81 private static Map<String, Schema> getLoadedSchemas()
82 {
83 return service.getRegistries().getLoadedSchemas();
84 }
85
86
87 @Before
88 public void checkSambaSchema() throws Exception
89 {
90 LdapContext schemaRoot = getSchemaContext( service );
91
92
93 Attributes attributes = schemaRoot.getAttributes( "cn=samba" );
94 assertNotNull( attributes );
95 assertTrue( attributes.get( MetaSchemaConstants.M_DISABLED_AT ).contains( "TRUE" ) );
96 attributes = schemaRoot.getAttributes( "ou=attributeTypes,cn=samba" );
97 assertNotNull( attributes );
98 assertTrue( attributes.get( SchemaConstants.OU_AT ).contains( "attributetypes" ) );
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112
113 @Test
114 public void testAddDisabledSchemaNoDeps() throws Exception
115 {
116 LdapContext schemaRoot = getSchemaContext( service );
117 Attributes dummySchema = new BasicAttributes( "objectClass", "top", true );
118 dummySchema.get( "objectClass" ).add( MetaSchemaConstants.META_SCHEMA_OC );
119 dummySchema.put( "cn", DUMMY_SCHEMA );
120 dummySchema.put( MetaSchemaConstants.M_DISABLED_AT, "TRUE" );
121 schemaRoot.createSubcontext( "cn=" + DUMMY_SCHEMA, dummySchema );
122
123 assertNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
124 assertNotNull( schemaRoot.lookup( "cn=" + DUMMY_SCHEMA ) );
125 }
126
127
128
129
130
131
132
133
134 @Test
135 public void testAddDisabledSchemaWithDeps() throws Exception
136 {
137 LdapContext schemaRoot = getSchemaContext( service );
138 Attributes dummySchema = new BasicAttributes( "objectClass", "top", true );
139 dummySchema.get( "objectClass" ).add( MetaSchemaConstants.META_SCHEMA_OC );
140 dummySchema.put( "cn", DUMMY_SCHEMA );
141 dummySchema.put( MetaSchemaConstants.M_DISABLED_AT, "TRUE" );
142 dummySchema.put( MetaSchemaConstants.M_DEPENDENCIES_AT, TEST_SCHEMA );
143 dummySchema.get( MetaSchemaConstants.M_DEPENDENCIES_AT ).add( "core" );
144 schemaRoot.createSubcontext( "cn=" + DUMMY_SCHEMA, dummySchema );
145
146 assertNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
147 assertNotNull( schemaRoot.lookup( "cn=" + DUMMY_SCHEMA ) );
148 }
149
150
151
152
153
154
155
156
157 @Test
158 public void testRejectDisabledSchemaAddWithMissingDeps() throws Exception
159 {
160 LdapContext schemaRoot = getSchemaContext( service );
161 Attributes dummySchema = new BasicAttributes( "objectClass", "top", true );
162 dummySchema.get( "objectClass" ).add( MetaSchemaConstants.META_SCHEMA_OC );
163 dummySchema.put( "cn", DUMMY_SCHEMA );
164 dummySchema.put( MetaSchemaConstants.M_DISABLED_AT, "TRUE" );
165 dummySchema.put( MetaSchemaConstants.M_DEPENDENCIES_AT, "missing" );
166 dummySchema.get( MetaSchemaConstants.M_DEPENDENCIES_AT ).add( "core" );
167
168 try
169 {
170 schemaRoot.createSubcontext( "cn=" + DUMMY_SCHEMA, dummySchema );
171 }
172 catch( LdapOperationNotSupportedException e )
173 {
174 assertTrue( e.getResultCode().equals( ResultCodeEnum.UNWILLING_TO_PERFORM ) );
175 }
176
177 assertNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
178
179
180 try
181 {
182 schemaRoot.lookup( "cn=" + DUMMY_SCHEMA );
183 fail( "schema should not be added to schema partition" );
184 }
185 catch( NamingException e )
186 {
187 }
188 }
189
190
191
192
193
194
195
196
197 @Test
198 public void testAddEnabledSchemaNoDeps() throws Exception
199 {
200 LdapContext schemaRoot = getSchemaContext( service );
201 Attributes dummySchema = new BasicAttributes( "objectClass", "top", true );
202 dummySchema.get( "objectClass" ).add( MetaSchemaConstants.META_SCHEMA_OC );
203 dummySchema.put( "cn", DUMMY_SCHEMA );
204 schemaRoot.createSubcontext( "cn=" + DUMMY_SCHEMA, dummySchema );
205
206 assertNotNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
207 assertNotNull( schemaRoot.lookup( "cn=" + DUMMY_SCHEMA ) );
208 }
209
210
211
212
213
214
215
216
217 @Test
218 public void testRejectEnabledSchemaAddWithDisabledDeps() throws Exception
219 {
220 LdapContext schemaRoot = getSchemaContext( service );
221 Attributes dummySchema = new BasicAttributes( "objectClass", "top", true );
222 dummySchema.get( "objectClass" ).add( MetaSchemaConstants.META_SCHEMA_OC );
223 dummySchema.put( "cn", DUMMY_SCHEMA );
224 dummySchema.put( MetaSchemaConstants.M_DEPENDENCIES_AT, TEST_SCHEMA );
225
226 try
227 {
228 schemaRoot.createSubcontext( "cn=" + DUMMY_SCHEMA, dummySchema );
229 fail( "should not be able to add enabled schema with deps on disabled schemas" );
230 }
231 catch( LdapOperationNotSupportedException e )
232 {
233 assertTrue( e.getResultCode().equals( ResultCodeEnum.UNWILLING_TO_PERFORM ) );
234 }
235
236 assertNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
237
238
239 try
240 {
241 schemaRoot.lookup( "cn=" + DUMMY_SCHEMA );
242 fail( "schema should not be added to schema partition" );
243 }
244 catch( NamingException e )
245 {
246 }
247 }
248
249
250
251
252
253
254
255
256
257
258
259
260 @Test
261 public void testDeleteSchemaNoDependents() throws Exception
262 {
263 LdapContext schemaRoot = getSchemaContext( service );
264
265
266 testAddEnabledSchemaNoDeps();
267 assertNotNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
268
269
270 schemaRoot.destroySubcontext( "cn=" + DUMMY_SCHEMA );
271 assertNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
272 }
273
274
275
276
277
278
279
280 @Test
281 public void testRejectSchemaDeleteWithDependents() throws Exception
282 {
283 LdapContext schemaRoot = getSchemaContext( service );
284
285
286 testAddEnabledSchemaNoDeps();
287 assertNotNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
288
289
290 ModificationItem[] mods = new ModificationItem[1];
291 mods[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE,
292 new BasicAttribute( MetaSchemaConstants.M_DEPENDENCIES_AT, DUMMY_SCHEMA ) );
293 schemaRoot.modifyAttributes( "cn=" + TEST_SCHEMA, mods );
294
295
296 try
297 {
298 schemaRoot.destroySubcontext( "cn=" + DUMMY_SCHEMA );
299 fail( "should not be able to delete a schema with dependents" );
300 }
301 catch ( LdapOperationNotSupportedException e )
302 {
303 assertTrue( e.getResultCode().equals( ResultCodeEnum.UNWILLING_TO_PERFORM ) );
304 }
305
306 assertNotNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
307 }
308
309
310
311
312
313
314
315
316 @Test
317 public void testRejectEnabledSchemaAddWithMisingDeps() throws Exception
318 {
319 LdapContext schemaRoot = getSchemaContext( service );
320
321 Attributes dummySchema = new BasicAttributes( "objectClass", "top", true );
322 dummySchema.get( "objectClass" ).add( MetaSchemaConstants.META_SCHEMA_OC );
323 dummySchema.put( "cn", DUMMY_SCHEMA );
324 dummySchema.put( MetaSchemaConstants.M_DEPENDENCIES_AT, "missing" );
325
326 try
327 {
328 schemaRoot.createSubcontext( "cn=" + DUMMY_SCHEMA, dummySchema );
329 fail( "should not be able to add enabled schema with deps on missing schemas" );
330 }
331 catch( LdapOperationNotSupportedException e )
332 {
333 assertTrue( e.getResultCode().equals( ResultCodeEnum.UNWILLING_TO_PERFORM ) );
334 }
335
336 assertNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
337
338
339 try
340 {
341 schemaRoot.lookup( "cn=" + DUMMY_SCHEMA );
342 fail( "schema should not be added to schema partition" );
343 }
344 catch( NamingException e )
345 {
346 }
347 }
348
349
350
351
352
353
354
355 private void enableSchema( String schemaName ) throws Exception
356 {
357 LdapContext schemaRoot = getSchemaContext( service );
358
359
360 ModificationItem[] mods = new ModificationItem[1];
361 Attribute attr = new BasicAttribute( "m-disabled", "FALSE" );
362 mods[0] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
363 schemaRoot.modifyAttributes( "cn=" + schemaName, mods );
364 }
365
366
367 private void disableSchema( String schemaName ) throws Exception
368 {
369 LdapContext schemaRoot = getSchemaContext( service );
370
371
372 ModificationItem[] mods = new ModificationItem[1];
373 Attribute attr = new BasicAttribute( "m-disabled", "TRUE" );
374 mods[0] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
375 schemaRoot.modifyAttributes( "cn=" + schemaName, mods );
376 }
377
378
379
380
381
382
383
384
385
386 @Test
387 public void testEnableSchema() throws Exception
388 {
389 AttributeTypeRegistry atr = getAttributeTypeRegistry();
390
391
392 assertNull( getLoadedSchemas().get( TEST_SCHEMA ) );
393
394
395
396 assertFalse( atr.hasAttributeType( TEST_ATTR_OID ) );
397
398
399 enableSchema( "nis" );
400
401
402 assertNotNull( getLoadedSchemas().get( TEST_SCHEMA ) );
403
404
405
406 assertTrue( atr.hasAttributeType( TEST_ATTR_OID ) );
407 }
408
409
410
411
412
413
414
415
416 @Test
417 public void testDisableSchema() throws Exception
418 {
419
420 testEnableSchema();
421
422 AttributeTypeRegistry atr = getAttributeTypeRegistry();
423
424
425 assertNotNull( getLoadedSchemas().get( TEST_SCHEMA ) );
426
427
428
429 assertTrue( atr.hasAttributeType( TEST_ATTR_OID ) );
430
431
432 disableSchema( "samba" );
433 disableSchema( "nis" );
434
435
436 assertNull( getLoadedSchemas().get( TEST_SCHEMA ) );
437
438
439
440 assertFalse( atr.hasAttributeType( TEST_ATTR_OID ) );
441 }
442
443
444
445
446
447
448
449
450
451 @Test
452 public void testDisableSchemaWithEnabledDependents() throws Exception
453 {
454 LdapContext schemaRoot = getSchemaContext( service );
455
456
457
458
459
460 testEnableSchema();
461
462
463 Attributes dummySchema = new BasicAttributes( "objectClass", "top", true );
464 dummySchema.get( "objectClass" ).add( MetaSchemaConstants.META_SCHEMA_OC );
465 dummySchema.put( "cn", DUMMY_SCHEMA );
466 dummySchema.put( MetaSchemaConstants.M_DEPENDENCIES_AT, TEST_SCHEMA );
467 schemaRoot.createSubcontext( "cn=" + DUMMY_SCHEMA, dummySchema );
468
469
470 assertNotNull( getLoadedSchemas().get( TEST_SCHEMA ) );
471 assertNotNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
472
473 AttributeTypeRegistry atr = getAttributeTypeRegistry();
474
475
476
477 assertTrue( atr.hasAttributeType( TEST_ATTR_OID ) );
478
479
480
481 ModificationItem[] mods = new ModificationItem[1];
482 Attribute attr = new BasicAttribute( "m-disabled", "TRUE" );
483 mods[0] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
484
485 try
486 {
487 schemaRoot.modifyAttributes( "cn=nis", mods );
488 fail( "attempt to disable schema with enabled dependents should fail" );
489 }
490 catch ( LdapOperationNotSupportedException e )
491 {
492 assertTrue( e.getResultCode().equals( ResultCodeEnum.UNWILLING_TO_PERFORM ) );
493 }
494
495
496 assertNotNull( getLoadedSchemas().get( TEST_SCHEMA ) );
497 assertNotNull( getLoadedSchemas().get( DUMMY_SCHEMA ) );
498
499
500
501 assertTrue( atr.hasAttributeType( TEST_ATTR_OID ) );
502 }
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517 @Test
518 public void testSchemaRenameDisabledSchema() throws Exception
519 {
520 LdapContext schemaRoot = getSchemaContext( service );
521 schemaRoot.rename( "cn=samba", "cn=foo" );
522 assertNotNull( schemaRoot.lookup( "cn=foo" ) );
523
524
525 Attributes attributes = schemaRoot.getAttributes( "cn=foo" );
526 assertNotNull( attributes );
527 assertTrue( attributes.get( MetaSchemaConstants.M_DISABLED_AT ).contains( "TRUE" ) );
528 attributes = schemaRoot.getAttributes( "ou=attributeTypes,cn=foo" );
529 assertNotNull( attributes );
530 assertTrue( attributes.get( SchemaConstants.OU_AT ).contains( "attributetypes" ) );
531
532
533 try
534 {
535 schemaRoot.lookup( "cn=samba" );
536 fail( "the samba schema should not be present after a rename to foo" );
537 }
538 catch( LdapNameNotFoundException e )
539 {
540 }
541 }
542
543
544
545
546
547
548
549
550
551 @Test
552 public void testRejectSchemaRenameWithDeps() throws Exception
553 {
554 LdapContext schemaRoot = getSchemaContext( service );
555 try
556 {
557 schemaRoot.rename( "cn=nis", "cn=foo" );
558 fail( "should not be able to rename nis which has samba as it's dependent" );
559 }
560 catch ( LdapOperationNotSupportedException e )
561 {
562 assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, e.getResultCode() );
563 }
564
565 assertNotNull( schemaRoot.lookup( "cn=nis" ) );
566
567
568 try
569 {
570 schemaRoot.lookup( "cn=foo" );
571 fail( "the foo schema should not be present after rejecting the rename" );
572 }
573 catch( LdapNameNotFoundException e )
574 {
575 }
576 }
577
578
579
580
581
582
583
584
585
586 @Test
587 public void testSchemaRenameEnabledSchema() throws Exception
588 {
589 LdapContext schemaRoot = getSchemaContext( service );
590
591 enableSchema( "samba" );
592 assertTrue( getAttributeTypeRegistry().hasAttributeType( "sambaNTPassword" ) );
593 assertEquals( "samba", getAttributeTypeRegistry().getSchemaName( "sambaNTPassword" ) );
594
595 schemaRoot.rename( "cn=samba", "cn=foo" );
596 assertNotNull( schemaRoot.lookup( "cn=foo" ) );
597 assertTrue( getAttributeTypeRegistry().hasAttributeType( "sambaNTPassword" ) );
598 assertEquals( "foo", getAttributeTypeRegistry().getSchemaName( "sambaNTPassword" ) );
599
600
601 try
602 {
603 schemaRoot.lookup( "cn=samba" );
604 fail( "the samba schema should not be present after a rename to foo" );
605 }
606 catch( LdapNameNotFoundException e )
607 {
608 }
609 }
610
611
612
613
614
615
616
617
618
619
620
621
622
623 @Test
624 public void testRejectAddBogusDependency() throws Exception
625 {
626 LdapContext schemaRoot = getSchemaContext( service );
627
628 ModificationItem[] mods = new ModificationItem[1];
629 Attribute attr = new BasicAttribute( "m-dependencies", "bogus" );
630 mods[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, attr );
631
632 try
633 {
634 schemaRoot.modifyAttributes( "cn=" + TEST_SCHEMA, mods );
635 fail( "Should not be able to add bogus dependency to schema" );
636 }
637 catch ( LdapOperationNotSupportedException e )
638 {
639 assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, e.getResultCode() );
640 }
641 }
642
643
644
645
646
647
648
649
650
651
652 @Test
653 public void testRejectAddOfDisabledDependencyToEnabledSchema() throws Exception
654 {
655 LdapContext schemaRoot = getSchemaContext( service );
656 enableSchema( TEST_SCHEMA );
657 ModificationItem[] mods = new ModificationItem[1];
658 Attribute attr = new BasicAttribute( "m-dependencies", "mozilla" );
659 mods[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, attr );
660
661 try
662 {
663 schemaRoot.modifyAttributes( "cn=" + TEST_SCHEMA, mods );
664 fail( "Should not be able to add disabled dependency to schema" );
665 }
666 catch ( LdapOperationNotSupportedException e )
667 {
668 assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, e.getResultCode() );
669 }
670 }
671
672
673
674
675
676
677
678
679 @Test
680 public void testAddOfDisabledDependencyToDisabledSchema() throws Exception
681 {
682 LdapContext schemaRoot = getSchemaContext( service );
683 ModificationItem[] mods = new ModificationItem[1];
684 Attribute attr = new BasicAttribute( "m-dependencies", "mozilla" );
685 mods[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, attr );
686 schemaRoot.modifyAttributes( "cn=" + TEST_SCHEMA, mods );
687 Attributes attrs = schemaRoot.getAttributes( "cn=" + TEST_SCHEMA );
688 Attribute dependencies = attrs.get( "m-dependencies" );
689 assertTrue( dependencies.contains( "mozilla" ) );
690 }
691
692
693
694
695
696
697
698
699 @Test
700 public void testAddOfEnabledDependencyToDisabledSchema() throws Exception
701 {
702 LdapContext schemaRoot = getSchemaContext( service );
703 ModificationItem[] mods = new ModificationItem[1];
704 Attribute attr = new BasicAttribute( "m-dependencies", "java" );
705 mods[0] = new ModificationItem( DirContext.ADD_ATTRIBUTE, attr );
706 schemaRoot.modifyAttributes( "cn=" + TEST_SCHEMA, mods );
707 Attributes attrs = schemaRoot.getAttributes( "cn=" + TEST_SCHEMA );
708 Attribute dependencies = attrs.get( "m-dependencies" );
709 assertTrue( dependencies.contains( "java" ) );
710 }
711 }