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.operations.search;
21
22
23 import org.apache.directory.server.core.DefaultDirectoryService;
24 import org.apache.directory.server.core.DirectoryService;
25 import org.apache.directory.server.core.entry.ServerEntry;
26 import org.apache.directory.server.core.integ.IntegrationUtils;
27 import org.apache.directory.server.core.integ.Level;
28 import org.apache.directory.server.core.integ.annotations.ApplyLdifs;
29 import org.apache.directory.server.core.integ.annotations.CleanupLevel;
30 import org.apache.directory.server.core.integ.annotations.Factory;
31 import org.apache.directory.server.xdbm.Index;
32 import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
33 import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;
34 import org.apache.directory.server.integ.LdapServerFactory;
35 import org.apache.directory.server.integ.SiRunner;
36 import static org.apache.directory.server.integ.ServerIntegrationUtils.getWiredContext;
37
38 import org.apache.directory.server.ldap.LdapService;
39 import org.apache.directory.server.ldap.handlers.bind.MechanismHandler;
40 import org.apache.directory.server.ldap.handlers.bind.SimpleMechanismHandler;
41 import org.apache.directory.server.ldap.handlers.bind.cramMD5.CramMd5MechanismHandler;
42 import org.apache.directory.server.ldap.handlers.bind.digestMD5.DigestMd5MechanismHandler;
43 import org.apache.directory.server.ldap.handlers.bind.gssapi.GssapiMechanismHandler;
44 import org.apache.directory.server.ldap.handlers.bind.ntlm.NtlmMechanismHandler;
45 import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
46 import org.apache.directory.server.ldap.handlers.extended.StoredProcedureExtendedOperationHandler;
47 import org.apache.directory.server.protocol.shared.SocketAcceptor;
48 import org.apache.directory.shared.ldap.constants.SchemaConstants;
49 import org.apache.directory.shared.ldap.constants.SupportedSaslMechanisms;
50 import org.apache.mina.util.AvailablePortFinder;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53
54 import javax.naming.NamingEnumeration;
55 import javax.naming.directory.DirContext;
56 import javax.naming.directory.SearchControls;
57 import javax.naming.directory.SearchResult;
58
59 import java.util.HashMap;
60 import java.util.HashSet;
61 import java.util.Map;
62 import java.util.Set;
63
64 import static org.junit.Assert.assertTrue;
65 import static org.junit.Assert.assertEquals;
66 import static org.junit.Assert.assertFalse;
67
68
69
70
71
72
73
74
75
76 @RunWith ( SiRunner.class )
77 @CleanupLevel ( Level.CLASS )
78 @Factory ( IndexedNegationSearchIT.Factory.class )
79 @ApplyLdifs( {
80 "dn: ou=test,ou=system\n" +
81 "objectClass: top\n" +
82 "objectClass: organizationalUnit\n" +
83 "ou: test\n\n" +
84
85 "dn: uid=test1,ou=test,ou=system\n" +
86 "objectClass: top\n" +
87 "objectClass: account\n" +
88 "uid: test1\n" +
89 "ou: test1\n\n" +
90
91 "dn: uid=test2,ou=test,ou=system\n" +
92 "objectClass: top\n" +
93 "objectClass: account\n" +
94 "uid: test2\n" +
95 "ou: test2\n\n" +
96
97 "dn: uid=testNoOU,ou=test,ou=system\n" +
98 "objectClass: top\n" +
99 "objectClass: account\n" +
100 "uid: testNoOU\n\n" +
101
102 "dn: ou=actors,ou=system\n" +
103 "objectClass: top\n" +
104 "objectClass: organizationalUnit\n" +
105 "ou: actors\n\n" +
106
107 "dn: uid=jblack,ou=actors,ou=system\n" +
108 "objectClass: top\n" +
109 "objectClass: person\n" +
110 "objectClass: organizationalPerson\n" +
111 "objectClass: uidObject\n" +
112 "uid: jblack\n" +
113 "ou: comedy\n" +
114 "ou: adventure\n" +
115 "cn: Jack Black\n" +
116 "sn: Black\n\n" +
117
118 "dn: uid=bpitt,ou=actors,ou=system\n" +
119 "objectClass: top\n" +
120 "objectClass: person\n" +
121 "objectClass: organizationalPerson\n" +
122 "objectClass: uidObject\n" +
123 "uid: bpitt\n" +
124 "ou: drama\n" +
125 "ou: adventure\n" +
126 "cn: Brad Pitt\n" +
127 "sn: Pitt\n\n" +
128
129 "dn: uid=gcloony,ou=actors,ou=system\n" +
130 "objectClass: top\n" +
131 "objectClass: person\n" +
132 "objectClass: organizationalPerson\n" +
133 "objectClass: uidObject\n" +
134 "uid: gcloony\n" +
135 "ou: drama\n" +
136 "cn: Goerge Cloony\n" +
137 "sn: Cloony\n\n" +
138
139 "dn: uid=jnewbie,ou=actors,ou=system\n" +
140 "objectClass: top\n" +
141 "objectClass: person\n" +
142 "objectClass: organizationalPerson\n" +
143 "objectClass: uidObject\n" +
144 "uid: jnewbie\n" +
145 "cn: Joe Newbie\n" +
146 "sn: Newbie\n\n"
147
148 }
149 )
150 public class IndexedNegationSearchIT
151 {
152 public static LdapService ldapService;
153
154
155 public static class Factory implements LdapServerFactory
156 {
157 public LdapService newInstance() throws Exception
158 {
159 DirectoryService service = new DefaultDirectoryService();
160 IntegrationUtils.doDelete( service.getWorkingDirectory() );
161 service.getChangeLog().setEnabled( true );
162 service.setShutdownHookEnabled( false );
163
164 JdbmPartition system = new JdbmPartition();
165 system.setId( "system" );
166
167
168 system.setCacheSize( 500 );
169
170 system.setSuffix( "ou=system" );
171
172
173 Set<Index<?,ServerEntry>> indexedAttrs = new HashSet<Index<?,ServerEntry>>();
174 indexedAttrs.add( new JdbmIndex<String,ServerEntry>( SchemaConstants.OBJECT_CLASS_AT ) );
175 indexedAttrs.add( new JdbmIndex<String,ServerEntry>( SchemaConstants.OU_AT ) );
176 system.setIndexedAttributes( indexedAttrs );
177 service.setSystemPartition( system );
178
179
180
181
182
183 LdapService ldapService = new LdapService();
184 ldapService.setDirectoryService( service );
185 ldapService.setSocketAcceptor( new SocketAcceptor( null ) );
186 ldapService.setIpPort( AvailablePortFinder.getNextAvailable( 1024 ) );
187 ldapService.addExtendedOperationHandler( new StartTlsHandler() );
188 ldapService.addExtendedOperationHandler( new StoredProcedureExtendedOperationHandler() );
189
190
191
192 Map<String, MechanismHandler> mechanismHandlerMap = new HashMap<String,MechanismHandler>();
193 mechanismHandlerMap.put( SupportedSaslMechanisms.PLAIN, new SimpleMechanismHandler() );
194
195 CramMd5MechanismHandler cramMd5MechanismHandler = new CramMd5MechanismHandler();
196 mechanismHandlerMap.put( SupportedSaslMechanisms.CRAM_MD5, cramMd5MechanismHandler );
197
198 DigestMd5MechanismHandler digestMd5MechanismHandler = new DigestMd5MechanismHandler();
199 mechanismHandlerMap.put( SupportedSaslMechanisms.DIGEST_MD5, digestMd5MechanismHandler );
200
201 GssapiMechanismHandler gssapiMechanismHandler = new GssapiMechanismHandler();
202 mechanismHandlerMap.put( SupportedSaslMechanisms.GSSAPI, gssapiMechanismHandler );
203
204 NtlmMechanismHandler ntlmMechanismHandler = new NtlmMechanismHandler();
205 mechanismHandlerMap.put( SupportedSaslMechanisms.NTLM, ntlmMechanismHandler );
206 mechanismHandlerMap.put( SupportedSaslMechanisms.GSS_SPNEGO, ntlmMechanismHandler );
207
208 ldapService.setSaslMechanismHandlers( mechanismHandlerMap );
209
210 return ldapService;
211 }
212 }
213
214
215
216
217
218
219
220 @Test
221 public void testSearchNotOUIndexed() throws Exception
222 {
223 Set<SearchResult> results = getResults( "(!(ou=test1))" );
224 assertFalse( contains( "uid=test1,ou=test,ou=system", results ) );
225 assertTrue( contains( "uid=test2,ou=test,ou=system", results ) );
226 assertTrue( contains( "uid=testNoOU,ou=test,ou=system", results ) );
227 }
228
229
230
231
232
233
234
235
236
237
238 @Test
239 public void testSearchNotDramaIndexed() throws Exception
240 {
241
242 Set<SearchResult> results = getActorResults( "(!(ou=drama))" );
243 assertTrue( contains( "uid=jblack,ou=actors,ou=system", results ) );
244 assertTrue( contains( "uid=jnewbie,ou=actors,ou=system", results ) );
245 assertEquals( 2, results.size() );
246 }
247
248
249 boolean contains( String dn, Set<SearchResult> results )
250 {
251 for ( SearchResult result : results )
252 {
253 if ( result.getNameInNamespace().equals( dn ) )
254 {
255 return true;
256 }
257 }
258
259 return false;
260 }
261
262
263
264
265
266
267
268
269
270
271 @Test
272 public void testSearchNotDramaNotNewbieIndexed() throws Exception
273 {
274
275 Set<SearchResult> results = getActorResults( "(& (!(uid=jnewbie)) (!(ou=drama)) )" );
276 assertTrue( contains( "uid=jblack,ou=actors,ou=system", results ) );
277 assertFalse( contains( "uid=jnewbie,ou=actors,ou=system", results ) );
278 assertEquals( 1, results.size() );
279 }
280
281
282 Set<SearchResult> getActorResults( String filter ) throws Exception
283 {
284 DirContext ctx = getWiredContext( ldapService );
285 Set<SearchResult> results = new HashSet<SearchResult>();
286 SearchControls controls = new SearchControls();
287 controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
288 NamingEnumeration<SearchResult> namingEnumeration = ctx.search( "ou=actors,ou=system", filter, controls );
289 while( namingEnumeration.hasMore() )
290 {
291 results.add( namingEnumeration.next() );
292 }
293
294 return results;
295 }
296
297
298 Set<SearchResult> getResults( String filter ) throws Exception
299 {
300 DirContext ctx = getWiredContext( ldapService );
301 Set<SearchResult> results = new HashSet<SearchResult>();
302 SearchControls controls = new SearchControls();
303 controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
304 NamingEnumeration<SearchResult> namingEnumeration = ctx.search( "ou=system", filter, controls );
305 while( namingEnumeration.hasMore() )
306 {
307 results.add( namingEnumeration.next() );
308 }
309
310 return results;
311 }
312 }