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.unit;
21
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.Hashtable;
30 import java.util.List;
31 import java.util.Map;
32
33 import javax.naming.Context;
34 import javax.naming.NamingException;
35 import javax.naming.ldap.InitialLdapContext;
36 import javax.naming.ldap.LdapContext;
37
38 import junit.framework.AssertionFailedError;
39 import junit.framework.TestCase;
40
41 import org.apache.commons.io.FileUtils;
42 import org.apache.directory.server.constants.ServerDNConstants;
43 import org.apache.directory.server.core.CoreSession;
44 import org.apache.directory.server.core.DefaultDirectoryService;
45 import org.apache.directory.server.core.DirectoryService;
46 import org.apache.directory.server.core.entry.DefaultServerEntry;
47 import org.apache.directory.server.core.jndi.CoreContextFactory;
48 import org.apache.directory.server.ldap.LdapService;
49 import org.apache.directory.server.ldap.handlers.bind.MechanismHandler;
50 import org.apache.directory.server.ldap.handlers.bind.cramMD5.CramMd5MechanismHandler;
51 import org.apache.directory.server.ldap.handlers.bind.digestMD5.DigestMd5MechanismHandler;
52 import org.apache.directory.server.ldap.handlers.bind.gssapi.GssapiMechanismHandler;
53 import org.apache.directory.server.ldap.handlers.bind.ntlm.NtlmMechanismHandler;
54 import org.apache.directory.server.ldap.handlers.bind.plain.PlainMechanismHandler;
55 import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
56 import org.apache.directory.server.ldap.handlers.extended.StoredProcedureExtendedOperationHandler;
57 import org.apache.directory.server.protocol.shared.SocketAcceptor;
58 import org.apache.directory.shared.ldap.constants.SupportedSaslMechanisms;
59 import org.apache.directory.shared.ldap.entry.Entry;
60 import org.apache.directory.shared.ldap.entry.EntryAttribute;
61 import org.apache.directory.shared.ldap.entry.Value;
62 import org.apache.directory.shared.ldap.exception.LdapConfigurationException;
63 import org.apache.directory.shared.ldap.ldif.LdifEntry;
64 import org.apache.directory.shared.ldap.ldif.LdifReader;
65 import org.apache.mina.util.AvailablePortFinder;
66
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
69
70
71
72
73
74
75
76
77 public abstract class AbstractServerTest extends TestCase
78 {
79 private static final Logger LOG = LoggerFactory.getLogger( AbstractServerTest.class );
80 private static final List<LdifEntry> EMPTY_LIST = Collections.unmodifiableList( new ArrayList<LdifEntry>( 0 ) );
81 private static final String CTX_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
82
83
84 protected LdapContext sysRoot;
85
86
87 protected CoreSession rootDSE;
88
89
90 protected LdapContext schemaRoot;
91
92
93 protected boolean doDelete = true;
94
95
96
97 protected int port = -1;
98
99 private static int start;
100 private static long t0;
101 protected static int nbTests = 10000;
102 protected DirectoryService directoryService;
103 protected SocketAcceptor socketAcceptor;
104 protected LdapService ldapService;
105
106
107
108
109
110
111
112
113
114
115
116
117
118 protected List<LdifEntry> loadTestLdif( boolean verifyEntries ) throws Exception
119 {
120 return loadLdif( getClass().getResourceAsStream( getClass().getSimpleName() + ".ldif" ), verifyEntries );
121 }
122
123
124
125
126
127
128
129
130
131
132
133
134
135 protected List<LdifEntry> loadLdif( InputStream in, boolean verifyEntries ) throws Exception
136 {
137 if ( in == null )
138 {
139 return EMPTY_LIST;
140 }
141
142 LdifReader ldifReader = new LdifReader( in );
143 List<LdifEntry> entries = new ArrayList<LdifEntry>();
144
145 for ( LdifEntry entry:ldifReader )
146 {
147 rootDSE.add(
148 new DefaultServerEntry( directoryService.getRegistries(), entry.getEntry() ) );
149
150 if ( verifyEntries )
151 {
152 verify( entry );
153 LOG.info( "Successfully verified addition of entry {}", entry.getDn() );
154 }
155 else
156 {
157 LOG.info( "Added entry {} without verification", entry.getDn() );
158 }
159
160 entries.add( entry );
161 }
162
163 return entries;
164 }
165
166
167
168
169
170
171
172
173
174 protected void verify( LdifEntry entry ) throws Exception
175 {
176 Entry readEntry = rootDSE.lookup( entry.getDn() );
177
178 for ( EntryAttribute readAttribute:readEntry )
179 {
180 String id = readAttribute.getId();
181 EntryAttribute origAttribute = entry.getEntry().get( id );
182
183 for ( Value<?> value:origAttribute )
184 {
185 if ( ! readAttribute.contains( value ) )
186 {
187 LOG.error( "Failed to verify entry addition of {}. {} attribute in original " +
188 "entry missing from read entry.", entry.getDn(), id );
189 throw new AssertionFailedError( "Failed to verify entry addition of " + entry.getDn() );
190 }
191 }
192 }
193 }
194
195
196
197
198
199
200
201
202
203
204
205 protected LdapContext getWiredContext() throws Exception
206 {
207 return getWiredContext( ServerDNConstants.ADMIN_SYSTEM_DN, "secret" );
208 }
209
210
211
212
213
214
215
216
217
218
219
220
221
222 protected LdapContext getWiredContext( String bindPrincipalDn, String password ) throws Exception
223 {
224
225
226
227
228
229 Hashtable<String, String> env = new Hashtable<String, String>();
230 env.put( Context.INITIAL_CONTEXT_FACTORY, CTX_FACTORY );
231 env.put( Context.PROVIDER_URL, "ldap://localhost:" + port );
232 env.put( Context.SECURITY_PRINCIPAL, bindPrincipalDn );
233 env.put( Context.SECURITY_CREDENTIALS, password );
234 env.put( Context.SECURITY_AUTHENTICATION, "simple" );
235 return new InitialLdapContext( env, null );
236 }
237
238
239
240
241
242
243
244
245 protected void setUp() throws Exception
246 {
247 super.setUp();
248
249 if ( start == 0 )
250 {
251 t0 = System.currentTimeMillis();
252 }
253
254 start++;
255 directoryService = new DefaultDirectoryService();
256 directoryService.setShutdownHookEnabled( false );
257 socketAcceptor = new SocketAcceptor( null );
258 ldapService = new LdapService();
259 ldapService.setSocketAcceptor( socketAcceptor );
260 ldapService.setDirectoryService( directoryService );
261 ldapService.setIpPort( port = AvailablePortFinder.getNextAvailable( 1024 ) );
262
263 setupSaslMechanisms( ldapService );
264
265 doDelete( directoryService.getWorkingDirectory() );
266 configureDirectoryService();
267 directoryService.startup();
268
269 configureLdapServer();
270
271
272 ldapService.addExtendedOperationHandler( new StartTlsHandler() );
273 ldapService.addExtendedOperationHandler( new StoredProcedureExtendedOperationHandler() );
274
275 ldapService.start();
276 setContexts( ServerDNConstants.ADMIN_SYSTEM_DN, "secret" );
277 }
278
279
280 private void setupSaslMechanisms( LdapService server )
281 {
282 Map<String, MechanismHandler> mechanismHandlerMap = new HashMap<String,MechanismHandler>();
283
284 mechanismHandlerMap.put( SupportedSaslMechanisms.PLAIN, new PlainMechanismHandler() );
285
286 CramMd5MechanismHandler cramMd5MechanismHandler = new CramMd5MechanismHandler();
287 mechanismHandlerMap.put( SupportedSaslMechanisms.CRAM_MD5, cramMd5MechanismHandler );
288
289 DigestMd5MechanismHandler digestMd5MechanismHandler = new DigestMd5MechanismHandler();
290 mechanismHandlerMap.put( SupportedSaslMechanisms.DIGEST_MD5, digestMd5MechanismHandler );
291
292 GssapiMechanismHandler gssapiMechanismHandler = new GssapiMechanismHandler();
293 mechanismHandlerMap.put( SupportedSaslMechanisms.GSSAPI, gssapiMechanismHandler );
294
295 NtlmMechanismHandler ntlmMechanismHandler = new NtlmMechanismHandler();
296
297
298
299
300 mechanismHandlerMap.put( SupportedSaslMechanisms.NTLM, ntlmMechanismHandler );
301 mechanismHandlerMap.put( SupportedSaslMechanisms.GSS_SPNEGO, ntlmMechanismHandler );
302
303 ldapService.setSaslMechanismHandlers( mechanismHandlerMap );
304 }
305
306
307 protected void configureDirectoryService() throws Exception
308 {
309 }
310
311
312 protected void configureLdapServer()
313 {
314 }
315
316
317
318
319
320
321
322 protected void doDelete( File wkdir ) throws IOException
323 {
324 if ( doDelete )
325 {
326 if ( wkdir.exists() )
327 {
328 FileUtils.deleteDirectory( wkdir );
329 }
330
331 if ( wkdir.exists() )
332 {
333 throw new IOException( "Failed to delete: " + wkdir );
334 }
335 }
336 }
337
338
339
340
341
342
343
344
345
346
347
348 protected void setContexts( String user, String passwd ) throws Exception
349 {
350 Hashtable<String, Object> env = new Hashtable<String, Object>();
351 env.put( DirectoryService.JNDI_KEY, directoryService );
352 env.put( Context.SECURITY_PRINCIPAL, user );
353 env.put( Context.SECURITY_CREDENTIALS, passwd );
354 env.put( Context.SECURITY_AUTHENTICATION, "simple" );
355 env.put( Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName() );
356 setContexts( env );
357 }
358
359
360
361
362
363
364
365
366
367 protected void setContexts( Hashtable<String, Object> env ) throws Exception
368 {
369 Hashtable<String, Object> envFinal = new Hashtable<String, Object>( env );
370 envFinal.put( Context.PROVIDER_URL, ServerDNConstants.SYSTEM_DN );
371 sysRoot = new InitialLdapContext( envFinal, null );
372
373 envFinal.put( Context.PROVIDER_URL, "" );
374 rootDSE = directoryService.getAdminSession();
375
376 envFinal.put( Context.PROVIDER_URL, ServerDNConstants.OU_SCHEMA_DN );
377 schemaRoot = new InitialLdapContext( envFinal, null );
378 }
379
380
381
382
383
384
385
386 protected void tearDown() throws Exception
387 {
388 super.tearDown();
389 ldapService.stop();
390 try
391 {
392 directoryService.shutdown();
393 }
394 catch ( Exception e )
395 {
396 }
397
398 sysRoot = null;
399 }
400
401
402
403
404
405
406
407
408
409
410
411
412 protected void importLdif( InputStream in ) throws NamingException
413 {
414 try
415 {
416 for ( LdifEntry ldifEntry:new LdifReader( in ) )
417 {
418 rootDSE.add(
419 new DefaultServerEntry(
420 rootDSE.getDirectoryService().getRegistries(), ldifEntry.getEntry() ) );
421 }
422 }
423 catch ( Exception e )
424 {
425 String msg = "failed while trying to parse system ldif file";
426 NamingException ne = new LdapConfigurationException( msg );
427 ne.setRootCause( e );
428 throw ne;
429 }
430 }
431
432
433
434
435
436
437
438
439 protected void injectEntries( String ldif ) throws Exception
440 {
441 LdifReader reader = new LdifReader();
442 List<LdifEntry> entries = reader.parseLdif( ldif );
443
444 for ( LdifEntry entry : entries )
445 {
446 rootDSE.add(
447 new DefaultServerEntry(
448 rootDSE.getDirectoryService().getRegistries(), entry.getEntry() ) );
449 }
450 }
451 }