| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| package org.apache.directory.server.core.authz; |
| |
| |
| import org.apache.directory.ldap.client.api.LdapConnection; |
| import org.apache.directory.server.constants.ServerDNConstants; |
| import org.apache.directory.server.core.DirectoryService; |
| import org.apache.directory.server.core.integ.IntegrationUtils; |
| import org.apache.directory.shared.ldap.constants.SchemaConstants; |
| import org.apache.directory.shared.ldap.entry.DefaultEntry; |
| import org.apache.directory.shared.ldap.entry.Entry; |
| import org.apache.directory.shared.ldap.entry.EntryAttribute; |
| import org.apache.directory.shared.ldap.message.AddResponse; |
| import org.apache.directory.shared.ldap.message.ModifyRequest; |
| import org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl; |
| import org.apache.directory.shared.ldap.message.ResultCodeEnum; |
| import org.apache.directory.shared.ldap.name.DN; |
| |
| |
| /** |
| * Some extra utility methods added to it which are required by all |
| * authorization tests. |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| */ |
| public class AutzIntegUtils |
| { |
| public static DirectoryService service; |
| |
| |
| // ----------------------------------------------------------------------- |
| // Utility methods used by subclasses |
| // ----------------------------------------------------------------------- |
| |
| /** |
| * gets a LdapConnection bound using the default admin DN uid=admin,ou=system and password "secret" |
| */ |
| public static LdapConnection getAdminConnection() throws Exception |
| { |
| return IntegrationUtils.getAdminConnection( service ); |
| } |
| |
| |
| public static LdapConnection getConnectionAs( String dn, String password ) throws Exception |
| { |
| return IntegrationUtils.getConnectionAs( service, dn, password ); |
| } |
| |
| |
| public static LdapConnection getConnectionAs( DN dn, String password ) throws Exception |
| { |
| return IntegrationUtils.getConnectionAs( service, dn.getName(), password ); |
| } |
| |
| |
| public static LdapConnection getConnectionAs( String host, int port, String dn, String password ) throws Exception |
| { |
| return IntegrationUtils.getNetworkConnectionAs( host, port, dn, password ); |
| } |
| |
| |
| /** |
| * Creates a group using the groupOfUniqueNames objectClass under the |
| * ou=groups,ou=sytem container with an initial member. |
| * |
| * @param cn the common name of the group used as the RDN attribute |
| * @param firstMemberDn the DN of the first member of this group |
| * @return the distinguished name of the group entry |
| * @throws Exception if there are problems creating the new group like |
| * it exists already |
| */ |
| public static DN createGroup( String cn, String firstMemberDn ) throws Exception |
| { |
| DN groupDN = new DN( "cn=" + cn + ",ou=groups,ou=system" ); |
| Entry entry = new DefaultEntry( groupDN ); |
| entry.add( SchemaConstants.OBJECT_CLASS_AT, "groupOfUniqueNames" ); |
| entry.add( SchemaConstants.UNIQUE_MEMBER_AT, firstMemberDn ); |
| entry.add( SchemaConstants.CN_AT, cn ); |
| |
| getAdminConnection().add( entry ); |
| return groupDN; |
| } |
| |
| |
| /** |
| * Deletes a user with a specific UID under ou=users,ou=system. |
| * |
| * @param uid the RDN value for the user to delete |
| * @throws Exception if there are problems removing the user |
| * i.e. user does not exist |
| */ |
| public static void deleteUser( String uid ) throws Exception |
| { |
| getAdminConnection().delete( "uid=" + uid + ",ou=users,ou=system" ); |
| } |
| |
| |
| /** |
| * Creates a simple user as an inetOrgPerson under the ou=users,ou=system |
| * container. The user's RDN attribute is the uid argument. This argument |
| * is also used as the value of the two MUST attributes: sn and cn. |
| * |
| * @param uid the value of the RDN attriubte (uid), the sn and cn attributes |
| * @param password the password to use to create the user |
| * @return the dn of the newly created user entry |
| * @throws Exception if there are problems creating the user entry |
| */ |
| public static DN createUser( String uid, String password ) throws Exception |
| { |
| LdapConnection connection = getAdminConnection(); |
| |
| Entry entry = new DefaultEntry( new DN( "uid=" + uid + ",ou=users,ou=system" ) ); |
| entry.add( SchemaConstants.UID_AT, uid ); |
| entry.add( SchemaConstants.OBJECT_CLASS_AT, "person", "organizationalPerson", "inetOrgPerson" ); |
| entry.add( SchemaConstants.SN_AT, uid ); |
| entry.add( SchemaConstants.CN_AT, uid ); |
| entry.add( SchemaConstants.USER_PASSWORD_AT, password ); |
| |
| connection.add( entry ); |
| |
| return entry.getDn(); |
| } |
| |
| |
| /** |
| * Creates a simple groupOfUniqueNames under the ou=groups,ou=system |
| * container. The admin user is always a member of this newly created |
| * group. |
| * |
| * @param groupName the name of the cgroup to create |
| * @return the DN of the group as a Name object |
| * @throws Exception if the group cannot be created |
| */ |
| public static DN createGroup( String groupName ) throws Exception |
| { |
| DN groupDN = new DN( "cn=" + groupName + ",ou=groups,ou=system" ); |
| |
| Entry entry = new DefaultEntry( groupDN ); |
| entry.add( SchemaConstants.OBJECT_CLASS_AT, "groupOfUniqueNames" ); |
| // TODO might be ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED |
| entry.add( SchemaConstants.UNIQUE_MEMBER_AT, "uid=admin, ou=system" ); |
| entry.add( SchemaConstants.CN_AT, groupName ); |
| |
| getAdminConnection().add( entry ); |
| |
| return groupDN; |
| } |
| |
| |
| /** |
| * Adds an existing user under ou=users,ou=system to an existing group under the |
| * ou=groups,ou=system container. |
| * |
| * @param userUid the uid of the user to add to the group |
| * @param groupCn the cn of the group to add the user to |
| * @throws Exception if the group does not exist |
| */ |
| public static void addUserToGroup( String userUid, String groupCn ) throws Exception |
| { |
| LdapConnection connection = getAdminConnection(); |
| |
| ModifyRequest modReq = new ModifyRequestImpl(); |
| modReq.setName( new DN( "cn=" + groupCn + ",ou=groups,ou=system" ) ); |
| modReq.add( SchemaConstants.UNIQUE_MEMBER_AT, "uid=" + userUid + ",ou=users,ou=system" ); |
| |
| connection.modify( modReq ).getLdapResult().getResultCode(); |
| } |
| |
| |
| /** |
| * Removes a user from a group. |
| * |
| * @param userUid the RDN attribute value of the user to remove from the group |
| * @param groupCn the RDN attribute value of the group to have user removed from |
| * @throws Exception if there are problems accessing the group |
| */ |
| public static void removeUserFromGroup( String userUid, String groupCn ) throws Exception |
| { |
| ModifyRequest modReq = new ModifyRequestImpl(); |
| modReq.setName( new DN( "cn=" + groupCn + ",ou=groups,ou=system" ) ); |
| modReq.remove( SchemaConstants.UNIQUE_MEMBER_AT, "uid=" + userUid + ",ou=users,ou=system" ); |
| getAdminConnection().modify( modReq ); |
| } |
| |
| |
| public static void deleteAccessControlSubentry( String cn ) throws Exception |
| { |
| getAdminConnection().delete( "cn=" + cn + "," + ServerDNConstants.SYSTEM_DN ); |
| } |
| |
| |
| /** |
| * Creates an access control subentry under ou=system whose subtree covers |
| * the entire naming context. |
| * |
| * @param cn the common name and rdn for the subentry |
| * @param aciItem the prescriptive ACI attribute value |
| * @throws Exception if there is a problem creating the subentry |
| */ |
| public static ResultCodeEnum createAccessControlSubentry( String cn, String aciItem ) throws Exception |
| { |
| return createAccessControlSubentry( cn, "{}", aciItem ); |
| } |
| |
| |
| /** |
| * Creates an access control subentry under ou=system whose subtree covers |
| * the entire naming context. |
| * |
| * @param cn the common name and rdn for the subentry |
| * @param subtree the subtreeSpecification for the subentry |
| * @param aciItem the prescriptive ACI attribute value |
| * @throws Exception if there is a problem creating the subentry |
| */ |
| public static ResultCodeEnum createAccessControlSubentry( String cn, String subtree, String aciItem ) |
| throws Exception |
| { |
| LdapConnection connection = getAdminConnection(); |
| |
| Entry systemEntry = connection.lookup( ServerDNConstants.SYSTEM_DN, "+", "*" ); |
| |
| // modify ou=system to be an AP for an A/C AA if it is not already |
| EntryAttribute administrativeRole = systemEntry.get( "administrativeRole" ); |
| |
| if ( administrativeRole == null || !administrativeRole.contains( "accessControlSpecificArea" ) ) |
| { |
| ModifyRequest modReq = new ModifyRequestImpl(); |
| modReq.setName( systemEntry.getDn() ); |
| modReq.add( "administrativeRole", "accessControlSpecificArea" ); |
| connection.modify( modReq ); |
| } |
| |
| // now add the A/C subentry below ou=system |
| Entry subEntry = new DefaultEntry( new DN( "cn=" + cn + "," + ServerDNConstants.SYSTEM_DN ) ); |
| subEntry.add( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.SUBENTRY_OC, |
| SchemaConstants.ACCESS_CONTROL_SUBENTRY_OC ); |
| subEntry.add( SchemaConstants.SUBTREE_SPECIFICATION_AT, subtree ); |
| subEntry.add( SchemaConstants.PRESCRIPTIVE_ACI_AT, aciItem ); |
| |
| AddResponse addResp = connection.add( subEntry ); |
| |
| return addResp.getLdapResult().getResultCode(); |
| } |
| |
| |
| /** |
| * Adds and entryACI attribute to an entry specified by a relative name |
| * with respect to ou=system |
| * |
| * @param dn a name relative to ou=system |
| * @param aciItem the entryACI attribute value |
| * @throws Exception if there is a problem adding the attribute |
| */ |
| public static void addEntryACI( DN dn, String aciItem ) throws Exception |
| { |
| // modify the entry relative to ou=system to include the aciItem |
| ModifyRequest modReq = new ModifyRequestImpl(); |
| modReq.setName( dn ); |
| modReq.add( "entryACI", aciItem ); |
| |
| getAdminConnection().modify( modReq ); |
| } |
| |
| |
| /** |
| * Adds and subentryACI attribute to ou=system |
| * |
| * @param aciItem the subentryACI attribute value |
| * @throws Exception if there is a problem adding the attribute |
| */ |
| public static void addSubentryACI( String aciItem ) throws Exception |
| { |
| // modify the entry relative to ou=system to include the aciItem |
| ModifyRequest modReq = new ModifyRequestImpl(); |
| modReq.setName( new DN( "ou=system" ) ); |
| modReq.add( "subentryACI", aciItem ); |
| getAdminConnection().modify( modReq ); |
| } |
| |
| |
| /** |
| * Replaces values of an prescriptiveACI attribute of a subentry subordinate |
| * to ou=system. |
| * |
| * @param cn the common name of the aci subentry |
| * @param aciItem the new value for the ACI item |
| * @throws Exception if the modify fails |
| */ |
| public static void changePresciptiveACI( String cn, String aciItem ) throws Exception |
| { |
| ModifyRequest modReq = new ModifyRequestImpl(); |
| modReq.setName( new DN( "cn=" + cn + "," + ServerDNConstants.SYSTEM_DN ) ); |
| modReq.replace( "prescriptiveACI", aciItem ); |
| getAdminConnection().modify( modReq ); |
| } |
| |
| |
| public static void addPrescriptiveACI( String cn, String aciItem ) throws Exception |
| { |
| ModifyRequest modReq = new ModifyRequestImpl(); |
| modReq.setName( new DN( "cn=" + cn + "," + ServerDNConstants.SYSTEM_DN ) ); |
| modReq.add( "prescriptiveACI", aciItem ); |
| getAdminConnection().modify( modReq ); |
| } |
| } |