1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.core.authz;
21  
22  
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.List;
26  
27  import org.apache.directory.server.core.CoreSession;
28  import org.apache.directory.server.core.DirectoryService;
29  import org.apache.directory.server.core.authn.LdapPrincipal;
30  import org.apache.directory.server.core.entry.DefaultServerEntry;
31  import org.apache.directory.server.core.integ.CiRunner;
32  import static org.apache.directory.server.core.integ.IntegrationUtils.getUserAddLdif;
33  import org.apache.directory.server.core.integ.annotations.Factory;
34  import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
35  import org.apache.directory.shared.ldap.entry.Entry;
36  import org.apache.directory.shared.ldap.entry.EntryAttribute;
37  import org.apache.directory.shared.ldap.entry.Modification;
38  import org.apache.directory.shared.ldap.entry.ModificationOperation;
39  import org.apache.directory.shared.ldap.entry.client.ClientModification;
40  import org.apache.directory.shared.ldap.entry.client.DefaultClientAttribute;
41  import org.apache.directory.shared.ldap.exception.LdapNoPermissionException;
42  import org.apache.directory.shared.ldap.filter.ExprNode;
43  import org.apache.directory.shared.ldap.filter.FilterParser;
44  import org.apache.directory.shared.ldap.filter.SearchScope;
45  import org.apache.directory.shared.ldap.ldif.LdifEntry;
46  import org.apache.directory.shared.ldap.message.AliasDerefMode;
47  import org.apache.directory.shared.ldap.name.LdapDN;
48  import org.apache.directory.shared.ldap.name.Rdn;
49  
50  import static org.junit.Assert.assertNotNull;
51  import static org.junit.Assert.fail;
52  import static org.junit.Assert.assertTrue;
53  import org.junit.Test;
54  import org.junit.runner.RunWith;
55  
56  import javax.naming.NamingException;
57  
58  
59  /**
60   * Tests the Authorization service to make sure it is enforcing policies
61   * correctly.
62   *
63   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
64   * @version $Rev: 686082 $
65   */
66  @RunWith ( CiRunner.class )
67  @Factory ( AutzIntegUtils.ServiceFactory.class )
68  public class AuthorizationServiceAsNonAdminIT 
69  {
70      public static DirectoryService service;
71  
72  
73      /**
74       * Makes sure a non-admin user cannot delete the admin account.
75       *
76       * @throws NamingException if there are problems
77       */
78      @Test
79      public void testNoDeleteOnAdminByNonAdmin() throws Exception
80      {
81          LdifEntry akarasulu = getUserAddLdif();
82  
83          service.getAdminSession().add( 
84              new DefaultServerEntry( service.getRegistries(), akarasulu.getEntry() ) ); 
85  
86          try
87          {
88              service.getAdminSession().delete( new LdapDN( "uid=admin,ou=system") ); 
89              fail( "User 'admin' should not be able to delete his account" );
90          }
91          catch ( LdapNoPermissionException e )
92          {
93              assertNotNull( e );
94          }
95      }
96  
97  
98      /**
99       * Makes sure a non-admin user cannot rename the admin account.
100      *
101      * @throws NamingException if there are problems
102      */
103     @Test
104     public void testNoRdnChangesOnAdminByNonAdmin() throws Exception
105     {
106         LdifEntry akarasulu = getUserAddLdif();
107 
108         service.getAdminSession().add( 
109             new DefaultServerEntry( service.getRegistries(), akarasulu.getEntry() ) ); 
110 
111         try
112         {
113             service.getAdminSession().rename( 
114                 new LdapDN( "uid=admin,ou=system" ), 
115                 new Rdn( "uid=alex" ),
116                 false );
117             fail( "admin should not be able to rename his account" );
118         }
119         catch ( LdapNoPermissionException e )
120         {
121             assertNotNull( e );
122         }
123     }
124 
125 
126     /**
127      * Makes sure the a non-admin user cannot rename the admin account.
128      *
129      * @throws NamingException on error
130      */
131     @Test
132     public void testModifyOnAdminByNonAdmin() throws Exception
133     {
134         LdifEntry akarasulu = getUserAddLdif();
135         
136         service.getAdminSession().add( 
137             new DefaultServerEntry( service.getRegistries(), akarasulu.getEntry() ) ); 
138         
139         // Read the entry we just created using the akarasuluSession
140         Entry readEntry = service.getAdminSession().lookup( akarasulu.getDn(), new String[]{ "userPassword"} );
141         
142         assertTrue( Arrays.equals( akarasulu.get( "userPassword" ).getBytes(), readEntry.get( "userPassword" ).getBytes() ) );
143 
144         EntryAttribute attribute = new DefaultClientAttribute( "userPassword", "replaced" );
145 
146         List<Modification> mods = new ArrayList<Modification>();
147         
148         Modification mod = new ClientModification( ModificationOperation.REPLACE_ATTRIBUTE, attribute );
149         mods.add( mod );
150       
151         LdapDN userDn = new LdapDN( "uid=akarasulu,ou=users,ou=system" );
152         userDn.normalize( service.getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
153         LdapPrincipal principal = new LdapPrincipal( userDn, AuthenticationLevel.SIMPLE );
154         CoreSession akarasuluSession = service.getSession( principal );
155 
156         try
157         {
158             akarasuluSession.modify( 
159                 new LdapDN( "uid=admin,ou=system" ), mods ); 
160             fail( "User 'uid=admin,ou=system' should not be able to modify attributes on admin" );
161         }
162         catch ( Exception e )
163         {
164         }
165     }
166 
167 
168     /**
169      * Makes sure non-admin cannot search under ou=system.
170      *
171      * @throws NamingException if there are problems
172      */
173     @Test
174     public void testNoSearchByNonAdmin() throws Exception
175     {
176         LdifEntry akarasulu = getUserAddLdif();
177         
178         service.getAdminSession().add( 
179             new DefaultServerEntry( service.getRegistries(), akarasulu.getEntry() ) ); 
180 
181         try
182         {
183             ExprNode filter = FilterParser.parse( "(objectClass=*)" );
184             service.getAdminSession().search( new LdapDN( "ou=system" ), SearchScope.SUBTREE, filter , AliasDerefMode.DEREF_ALWAYS, null );
185         }
186         catch ( LdapNoPermissionException e )
187         {
188             assertNotNull( e );
189         }
190     }
191 }