1   /*
2    *   Copyright 2004 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.ldap.server.authz;
18  
19  
20  import org.apache.ldap.common.exception.LdapNoPermissionException;
21  import org.apache.ldap.common.message.LockableAttributesImpl;
22  import org.apache.ldap.server.db.DbSearchResult;
23  import org.apache.ldap.server.jndi.AbstractMultiUserJndiTest;
24  
25  import javax.naming.NamingEnumeration;
26  import javax.naming.NamingException;
27  import javax.naming.directory.Attributes;
28  import javax.naming.directory.DirContext;
29  import javax.naming.directory.SearchControls;
30  import java.util.HashSet;
31  
32  
33  /***
34   * Tests the Authorization service to make sure it is enforcing policies
35   * correctly.
36   *
37   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
38   * @version $Rev: 165254 $
39   */
40  public class AuthorizationServiceTest extends AbstractMultiUserJndiTest
41  {
42      /***
43       * Makes sure the admin cannot delete the admin account.
44       *
45       * @throws NamingException if there are problems
46       */
47      public void testNoDeleteOnAdminByAdmin() throws NamingException
48      {
49          try
50          {
51              sysRoot.destroySubcontext( "uid=admin" );
52              fail( "admin should not be able to delete his account" );
53          }
54          catch ( LdapNoPermissionException e )
55          {
56              assertNotNull( e );
57          }
58      }
59  
60  
61      /***
62       * Makes sure a non-admin user cannot delete the admin account.
63       *
64       * @throws NamingException if there are problems
65       */
66      public void testNoDeleteOnAdminByNonAdmin() throws NamingException
67      {
68          try
69          {
70              sysRootAsNonAdminUser.destroySubcontext( "uid=admin" );
71              fail( sysRootAsNonAdminUser.getPrincipal().getDn()
72                      + " should not be able to delete his account" );
73          }
74          catch ( LdapNoPermissionException e )
75          {
76              assertNotNull( e );
77          }
78      }
79  
80  
81      /***
82       * Makes sure the admin cannot rename the admin account.
83       *
84       * @throws NamingException if there are problems
85       */
86      public void testNoRdnChangesOnAdminByAdmin() throws NamingException
87      {
88          try
89          {
90              sysRoot.rename( "uid=admin", "uid=alex" );
91              fail( "admin should not be able to rename his account" );
92          }
93          catch ( LdapNoPermissionException e )
94          {
95              assertNotNull( e );
96          }
97      }
98  
99  
100     /***
101      * Makes sure a non-admin user cannot rename the admin account.
102      *
103      * @throws NamingException if there are problems
104      */
105     public void testNoRdnChangesOnAdminByNonAdmin() throws NamingException
106     {
107         try
108         {
109             sysRootAsNonAdminUser.rename( "uid=admin", "uid=alex" );
110             fail( "admin should not be able to rename his account" );
111         }
112         catch ( LdapNoPermissionException e )
113         {
114             assertNotNull( e );
115         }
116     }
117 
118 
119     /***
120      * Makes sure the admin cannot rename the admin account.
121      *
122      * @throws NamingException if there are problems
123      */
124     public void testModifyOnAdminByAdmin() throws NamingException
125     {
126         Attributes attributes = new LockableAttributesImpl();
127         attributes.put( "userPassword", "replaced" );
128         sysRoot.modifyAttributes( "uid=admin", DirContext.REPLACE_ATTRIBUTE, attributes );
129         Attributes newAttrs = sysRoot.getAttributes( "uid=admin" );
130         assertEquals( "replaced", newAttrs.get( "userPassword" ).get() );
131     }
132 
133 
134     /***
135      * Makes sure the a non-admin user cannot rename the admin account.
136      */
137     public void testModifyOnAdminByNonAdmin()
138     {
139         Attributes attributes = new LockableAttributesImpl();
140         attributes.put( "userPassword", "replaced" );
141 
142         try
143         {
144             sysRootAsNonAdminUser.modifyAttributes( "uid=admin",
145                     DirContext.REPLACE_ATTRIBUTE, attributes );
146             fail( sysRootAsNonAdminUser.getPrincipal().getDn() +
147                     " should not be able to modify attributes on admin" );
148         } catch( Exception e ) { }
149     }
150 
151 
152     /***
153      * Makes sure the admin can see all entries we know of on a subtree search.
154      *
155      * @throws NamingException if there are problems
156      */
157     public void testSearchSubtreeByAdmin() throws NamingException
158     {
159         SearchControls controls = new SearchControls();
160 
161         controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
162 
163         HashSet set = new HashSet();
164 
165         NamingEnumeration list = sysRoot.search( "", "(objectClass=*)", controls );
166 
167         while ( list.hasMore() )
168         {
169             DbSearchResult result = ( DbSearchResult ) list.next();
170 
171             set.add( result.getName() );
172         }
173 
174         assertTrue( set.contains( "ou=system" ) );
175 
176         assertTrue( set.contains( "ou=groups,ou=system" ) );
177 
178         assertTrue( set.contains( "ou=users,ou=system" ) );
179 
180         assertTrue( set.contains( "uid=akarasulu,ou=users,ou=system" ) );
181 
182         assertTrue( set.contains( "uid=admin,ou=system" ) );
183     }
184 
185 
186     /***
187      * Makes sure the admin can see all entries we know of on a subtree search.
188      *
189      * @throws NamingException if there are problems
190      */
191     public void testSearchSubtreeByNonAdmin() throws NamingException
192     {
193         SearchControls controls = new SearchControls();
194         controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
195 
196         HashSet set = new HashSet();
197         NamingEnumeration list = sysRootAsNonAdminUser.search( "",
198                 "(objectClass=*)", controls );
199         while ( list.hasMore() )
200         {
201             DbSearchResult result = ( DbSearchResult ) list.next();
202             set.add( result.getName() );
203         }
204 
205         assertTrue( set.contains( "ou=system" ) );
206         assertTrue( set.contains( "ou=groups,ou=system" ) );
207         assertFalse( set.contains( "cn=administrators,ou=groups,ou=system" ) );
208         assertTrue( set.contains( "ou=users,ou=system" ) );
209         assertFalse( set.contains( "uid=akarasulu,ou=users,ou=system" ) );
210         assertFalse( set.contains( "uid=admin,ou=system" ) );
211     }
212 }