Loading cadcAccessControl-Server/build.xml +2 −2 Original line number Diff line number Diff line Loading @@ -141,9 +141,9 @@ <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapConfigTest" />--> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapConnectionsTest" />--> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapDAOTest" />--> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapGroupDAOTest" />--> <test name="ca.nrc.cadc.ac.server.ldap.LdapGroupDAOTest" /> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapPersistenceTest" />--> <test name="ca.nrc.cadc.ac.server.ldap.LdapUserDAOTest" /> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapUserDAOTest" />--> <!--<test name="ca.nrc.cadc.ac.server.web.groups.AddGroupMemberActionTest" />--> <!--<test name="ca.nrc.cadc.ac.server.web.groups.AddUserMemberActionTest" />--> Loading cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/TestUtil.java 0 → 100644 +84 −0 Original line number Diff line number Diff line /* ************************************************************************ ******************* CANADIAN ASTRONOMY DATA CENTRE ******************* ************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES ************** * * (c) 2014. (c) 2014. * Government of Canada Gouvernement du Canada * National Research Council Conseil national de recherches * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 * All rights reserved Tous droits réservés * * NRC disclaims any warranties, Le CNRC dénie toute garantie * expressed, implied, or énoncée, implicite ou légale, * statutory, of any kind with de quelque nature que ce * respect to the software, soit, concernant le logiciel, * including without limitation y compris sans restriction * any warranty of merchantability toute garantie de valeur * or fitness for a particular marchande ou de pertinence * purpose. NRC shall not be pour un usage particulier. * liable in any event for any Le CNRC ne pourra en aucun cas * damages, whether direct or être tenu responsable de tout * indirect, special or general, dommage, direct ou indirect, * consequential or incidental, particulier ou général, * arising from the use of the accessoire ou fortuit, résultant * software. Neither the name de l'utilisation du logiciel. Ni * of the National Research le nom du Conseil National de * Council of Canada nor the Recherches du Canada ni les noms * names of its contributors may de ses participants ne peuvent * be used to endorse or promote être utilisés pour approuver ou * products derived from this promouvoir les produits dérivés * software without specific prior de ce logiciel sans autorisation * written permission. préalable et particulière * par écrit. * * This file is part of the Ce fichier fait partie du projet * OpenCADC project. OpenCADC. * * OpenCADC is free software: OpenCADC est un logiciel libre ; * you can redistribute it and/or vous pouvez le redistribuer ou le * modify it under the terms of modifier suivant les termes de * the GNU Affero General Public la “GNU Affero General Public * License as published by the License” telle que publiée * Free Software Foundation, par la Free Software Foundation * either version 3 of the : soit la version 3 de cette * License, or (at your option) licence, soit (à votre gré) * any later version. toute version ultérieure. * * OpenCADC is distributed in the OpenCADC est distribué * hope that it will be useful, dans l’espoir qu’il vous * but WITHOUT ANY WARRANTY; sera utile, mais SANS AUCUNE * without even the implied GARANTIE : sans même la garantie * warranty of MERCHANTABILITY implicite de COMMERCIALISABILITÉ * or FITNESS FOR A PARTICULAR ni d’ADÉQUATION À UN OBJECTIF * PURPOSE. See the GNU Affero PARTICULIER. Consultez la Licence * General Public License for Générale Publique GNU Affero * more details. pour plus de détails. * * You should have received Vous devriez avoir reçu une * a copy of the GNU Affero copie de la Licence Générale * General Public License along Publique GNU Affero avec * with OpenCADC. If not, see OpenCADC ; si ce n’est * <http://www.gnu.org/licenses/>. pas le cas, consultez : * <http://www.gnu.org/licenses/>. * * $Revision: 4 $ * ************************************************************************ */ package ca.nrc.cadc.ac.server; import java.lang.reflect.Field; public class TestUtil { public static void setField(Object object, Object value, String name) throws Exception { Field field = object.getClass().getDeclaredField(name); field.setAccessible(true); field.set(object, value); } } cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java +87 −67 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ */ package ca.nrc.cadc.ac.server.ldap; import java.lang.reflect.Field; import java.security.AccessControlException; import java.util.ArrayList; import java.util.Collection; Loading @@ -76,8 +77,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.apache.log4j.Logger; import ca.nrc.cadc.ac.ActivatedGroup; Loading Loading @@ -115,19 +114,31 @@ public class LdapGroupDAO extends LdapDAO { private static final Logger logger = Logger.getLogger(LdapGroupDAO.class); // LDAP Group attributes protected static final String LDAP_CN = "cn"; protected static final String LDAP_DESCRIPTION = "description"; protected static final String LDAP_ENTRYDN = "entrydn"; protected static final String LDAP_GROUP_OF_UNIQUE_NAMES = "groupofuniquenames"; protected static final String LDAP_INET_USER = "inetuser"; protected static final String LDAP_MODIFY_TIMESTAMP = "modifytimestamp"; protected static final String LDAP_NSACCOUNTLOCK = "nsaccountlock"; protected static final String LDAP_OBJECT_CLASS = "objectClass"; protected static final String LDAP_OWNER = "owner"; protected static final String LDAP_UNIQUE_MEMBER = "uniquemember"; private static final String[] PUB_GROUP_ATTRS = new String[] { "entrydn", "cn" LDAP_ENTRYDN, LDAP_CN }; private static final String[] GROUP_ATTRS = new String[] { "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description" LDAP_ENTRYDN, LDAP_CN, LDAP_NSACCOUNTLOCK, LDAP_OWNER, LDAP_MODIFY_TIMESTAMP, LDAP_DESCRIPTION }; private static final String[] GROUP_AND_MEMBER_ATTRS = new String[] { "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description", "uniquemember" LDAP_ENTRYDN, LDAP_CN, LDAP_NSACCOUNTLOCK, LDAP_OWNER, LDAP_MODIFY_TIMESTAMP, LDAP_DESCRIPTION, LDAP_UNIQUE_MEMBER }; private final Profiler profiler = new Profiler(LdapGroupDAO.class); Loading Loading @@ -170,13 +181,6 @@ public class LdapGroupDAO extends LdapDAO "Support for groups properties not available"); } // BM: Changed so that the group owner is set to be the // user in the subject //if (!isCreatorOwner(group.getOwner())) //{ // throw new AccessControlException("Group owner must be creator"); //} try { Set<DNPrincipal> ds = group.getOwner().getIdentities(DNPrincipal.class); Loading Loading @@ -228,15 +232,15 @@ public class LdapGroupDAO extends LdapDAO // add new group List<Attribute> attributes = new ArrayList<Attribute>(); Attribute ownerAttribute = new Attribute("owner", ownerDN.toNormalizedString()); new Attribute(LDAP_OWNER, ownerDN.toNormalizedString()); attributes.add(ownerAttribute); attributes.add(new Attribute("objectClass", "groupofuniquenames")); attributes.add(new Attribute("objectClass", "inetUser")); attributes.add(new Attribute("cn", groupID)); attributes.add(new Attribute(LDAP_OBJECT_CLASS, LDAP_GROUP_OF_UNIQUE_NAMES)); attributes.add(new Attribute(LDAP_OBJECT_CLASS, LDAP_INET_USER)); attributes.add(new Attribute(LDAP_CN, groupID)); if (StringUtil.hasText(description)) { attributes.add(new Attribute("description", description)); attributes.add(new Attribute(LDAP_DESCRIPTION, description)); } List<String> members = new ArrayList<String>(); Loading @@ -257,7 +261,7 @@ public class LdapGroupDAO extends LdapDAO } if (!members.isEmpty()) { attributes.add(new Attribute("uniquemember", attributes.add(new Attribute(LDAP_UNIQUE_MEMBER, (String[]) members .toArray(new String[members .size()]))); Loading Loading @@ -291,12 +295,12 @@ public class LdapGroupDAO extends LdapDAO try { // check group name exists Filter filter = Filter.createEqualityFilter("cn", group.getID()); Filter filter = Filter.createEqualityFilter(LDAP_CN, group.getID()); DN groupDN = getGroupDN(group.getID()); SearchRequest searchRequest = new SearchRequest(groupDN.toNormalizedString(), SearchScope.BASE, filter, new String[]{"nsaccountlock"}); new String[]{LDAP_NSACCOUNTLOCK}); //searchRequest.addControl( // new ProxiedAuthorizationV2RequestControl("dn:" + Loading @@ -311,7 +315,7 @@ public class LdapGroupDAO extends LdapDAO return false; } if (searchResult.getAttributeValue("nsaccountlock") == null) if (searchResult.getAttributeValue(LDAP_NSACCOUNTLOCK) == null) { throw new GroupAlreadyExistsException("Group already exists " + group.getID()); } Loading Loading @@ -349,7 +353,7 @@ public class LdapGroupDAO extends LdapDAO try { Filter filter = Filter .createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); .createNOTFilter(Filter.createPresenceFilter(LDAP_NSACCOUNTLOCK)); filter = Filter.createANDFilter(filter, Filter.create("(cn=*)")); final List<String> groupNames = new LinkedList<String>(); Loading @@ -360,7 +364,7 @@ public class LdapGroupDAO extends LdapDAO public void searchEntryReturned(SearchResultEntry sre) { String gname = sre.getAttributeValue("cn"); String gname = sre.getAttributeValue(LDAP_CN); groupNames.add(gname); long t2 = System.currentTimeMillis(); Loading Loading @@ -458,28 +462,20 @@ public class LdapGroupDAO extends LdapDAO String loggableGroupID = xgroupID; if (loggableGroupID == null) { loggableGroupID = groupDN .toString(); // member or admin group: same name, internal tree // member or admin group: same name, internal tree loggableGroupID = groupDN.toString(); } try { Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter(LDAP_NSACCOUNTLOCK)); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString())); Filter.createEqualityFilter(LDAP_ENTRYDN, groupDN.toNormalizedString())); SearchRequest searchRequest = new SearchRequest(groupDN.toNormalizedString(), SearchScope.BASE, filter, attributes); // permissions now checked in LdapGroupPersistence //searchRequest.addControl( // new ProxiedAuthorizationV2RequestControl("dn:" + // getSubjectDN() // .toNormalizedString())); SearchResultEntry searchEntry = getReadOnlyConnection() .searchForEntry(searchRequest); Loading @@ -490,12 +486,12 @@ public class LdapGroupDAO extends LdapDAO throw new GroupNotFoundException(loggableGroupID); } Group ldapGroup = createGroupFromEntry(searchEntry, attributes); Group ldapGroup = createGroupFromSearchResult(searchEntry, attributes); if (searchEntry.getAttributeValues("uniquemember") != null) if (searchEntry.getAttributeValues(LDAP_UNIQUE_MEMBER) != null) { for (String member : searchEntry .getAttributeValues("uniq<? extends Principal>uemember")) .getAttributeValues(LDAP_UNIQUE_MEMBER)) { DN memberDN = new DN(member); if (memberDN.isDescendantOf(config.getUsersDN(), false)) Loading @@ -512,8 +508,7 @@ public class LdapGroupDAO extends LdapDAO // from groups they belong to } } else if (memberDN .isDescendantOf(config.getGroupsDN(), false)) else if (memberDN.isDescendantOf(config.getGroupsDN(), false)) { try { Loading Loading @@ -577,18 +572,18 @@ public class LdapGroupDAO extends LdapDAO List<Modification> adminMods = new ArrayList<Modification>(); if (withActivate) { mods.add(new Modification(ModificationType.DELETE, "nsaccountlock")); adminMods.add(new Modification(ModificationType.DELETE, "nsaccountlock")); mods.add(new Modification(ModificationType.DELETE, LDAP_NSACCOUNTLOCK)); adminMods.add(new Modification(ModificationType.DELETE, LDAP_NSACCOUNTLOCK)); } if (StringUtil.hasText(group.description)) { mods.add(new Modification(ModificationType.REPLACE, "description", mods.add(new Modification(ModificationType.REPLACE, LDAP_DESCRIPTION, group.description)); } else { mods.add(new Modification(ModificationType.REPLACE, "description")); mods.add(new Modification(ModificationType.REPLACE, LDAP_DESCRIPTION)); } try Loading Loading @@ -626,7 +621,7 @@ public class LdapGroupDAO extends LdapDAO } // modify the admin group adminMods.add(new Modification(ModificationType.REPLACE, "uniquemember", adminMods.add(new Modification(ModificationType.REPLACE, LDAP_UNIQUE_MEMBER, (String[]) newAdmins .toArray(new String[newAdmins .size()]))); Loading @@ -642,7 +637,7 @@ public class LdapGroupDAO extends LdapDAO getReadWriteConnection().modify(adminModify).getResultCode()); // modify the group itself mods.add(new Modification(ModificationType.REPLACE, "uniquemember", mods.add(new Modification(ModificationType.REPLACE, LDAP_UNIQUE_MEMBER, (String[]) newMembers .toArray(new String[newMembers .size()]))); Loading Loading @@ -701,7 +696,7 @@ public class LdapGroupDAO extends LdapDAO AccessControlException { ModifyRequest clearMembers = new ModifyRequest(groupDN, new Modification(ModificationType.DELETE, "uniquemember")); new Modification(ModificationType.DELETE, LDAP_UNIQUE_MEMBER)); try { logger.debug("clearMembers " + groupDN); Loading @@ -715,7 +710,7 @@ public class LdapGroupDAO extends LdapDAO } ModifyRequest deleteGroup = new ModifyRequest(groupDN, new Modification(ModificationType.ADD, "nsaccountlock", "true")); new Modification(ModificationType.ADD, LDAP_NSACCOUNTLOCK, "true")); try { Loading Loading @@ -747,16 +742,16 @@ public class LdapGroupDAO extends LdapDAO { DN userDN = new DN(owner.getName()); Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter(LDAP_NSACCOUNTLOCK)); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("owner", userDN.toNormalizedString())); Filter.createEqualityFilter(LDAP_OWNER, userDN.toNormalizedString())); if (groupID != null) { DN groupDN = getGroupDN(groupID); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString())); Filter.createEqualityFilter(LDAP_ENTRYDN, groupDN.toNormalizedString())); } SearchRequest searchRequest = new SearchRequest( Loading @@ -771,7 +766,7 @@ public class LdapGroupDAO extends LdapDAO .search(searchRequest); for (SearchResultEntry result : results.getSearchEntries()) { ret.add(createGroupFromEntry(result, GROUP_ATTRS)); ret.add(createGroupFromSearchResult(result, GROUP_ATTRS)); } } catch (LDAPException e1) Loading @@ -782,23 +777,23 @@ public class LdapGroupDAO extends LdapDAO return ret; } private Group createGroupFromEntry(SearchResultEntry result, String[] attributes) private Group createGroupFromSearchResult(SearchResultEntry result, String[] attributes) throws LDAPException, TransientException { if (result.getAttribute("nsaccountlock") != null) if (result.getAttribute(LDAP_NSACCOUNTLOCK) != null) { throw new RuntimeException("BUG: found group with nsaccountlock set: " + result .getAttributeValue("entrydn").toString()); throw new RuntimeException("BUG: found group with nsaccountlock set: " + result.getAttributeValue(LDAP_ENTRYDN)); } String entryDN = result.getAttributeValue("entrydn"); String groupName = result.getAttributeValue("cn"); String entryDN = result.getAttributeValue(LDAP_ENTRYDN); String groupName = result.getAttributeValue(LDAP_CN); if (attributes == PUB_GROUP_ATTRS) { return new Group(groupName); } DN ownerDN = result.getAttributeValueAsDN("owner"); DN ownerDN = result.getAttributeValueAsDN(LDAP_OWNER); if (ownerDN == null) { throw new AccessControlException(groupName); Loading @@ -806,21 +801,23 @@ public class LdapGroupDAO extends LdapDAO try { User owner = userDAO.getX500User(ownerDN); Group g = new Group(groupName, owner); if (result.hasAttribute("description")) Group g = new Group(groupName); setField(g, owner, LDAP_OWNER); if (result.hasAttribute(LDAP_DESCRIPTION)) { g.description = result.getAttributeValue("description"); g.description = result.getAttributeValue(LDAP_DESCRIPTION); } if (result.hasAttribute("modifytimestamp")) if (result.hasAttribute(LDAP_MODIFY_TIMESTAMP)) { g.lastModified = result .getAttributeValueAsDate("modifytimestamp"); .getAttributeValueAsDate(LDAP_MODIFY_TIMESTAMP); } return g; } catch (UserNotFoundException ex) { throw new RuntimeException("Invalid state: owner does not exist: " + ownerDN + " group: " + entryDN); throw new RuntimeException("Invalid state: owner does not exist: " + ownerDN + " group: " + entryDN); } } Loading Loading @@ -877,4 +874,27 @@ public class LdapGroupDAO extends LdapDAO } } // set private field using reflection private void setField(Object object, Object value, String name) { try { Field field = object.getClass().getDeclaredField(name); field.setAccessible(true); field.set(object, value); } catch (NoSuchFieldException e) { final String error = object.getClass().getSimpleName() + " field " + name + "not found"; throw new RuntimeException(error, e); } catch (IllegalAccessException e) { final String error = "unable to update " + name + " in " + object.getClass().getSimpleName(); throw new RuntimeException(error, e); } } } cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupPersistence.java +26 −2 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ */ package ca.nrc.cadc.ac.server.ldap; import java.lang.reflect.Field; import java.security.AccessControlException; import java.security.Principal; import java.util.ArrayList; Loading Loading @@ -174,8 +175,8 @@ public class LdapGroupPersistence extends LdapPersistence implements GroupPersis GroupNotFoundException { Subject caller = AuthenticationUtil.getCurrentSubject(); // Principal owner = getUser(caller); // group.setOwner(owner); Principal owner = getUser(caller); setField(group, owner, "owner"); LdapConnections conns = new LdapConnections(this); try Loading Loading @@ -393,4 +394,27 @@ public class LdapGroupPersistence extends LdapPersistence implements GroupPersis GroupMemberships gms = gset.iterator().next(); return gms.getUserID(); } // set private field using reflection private void setField(Object object, Object value, String name) { try { Field field = object.getClass().getDeclaredField(name); field.setAccessible(true); field.set(object, value); } catch (NoSuchFieldException e) { final String error = object.getClass().getSimpleName() + " field " + name + "not found"; throw new RuntimeException(error, e); } catch (IllegalAccessException e) { final String error = "unable to update " + name + " in " + object.getClass().getSimpleName(); throw new RuntimeException(error, e); } } } cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java +16 −10 Original line number Diff line number Diff line Loading @@ -143,7 +143,7 @@ public class LdapUserDAO extends LdapDAO // Map of identity type to LDAP attribute private final Map<Class<?>, String> userLdapAttrib = new HashMap<Class<?>, String>(); // Returned User attributes // LDAP User attributes protected static final String LDAP_OBJECT_CLASS = "objectClass"; protected static final String LDAP_INET_USER = "inetuser"; protected static final String LDAP_INET_ORG_PERSON = "inetOrgPerson"; Loading @@ -163,6 +163,7 @@ public class LdapUserDAO extends LdapDAO protected static final String LDAP_EMAIL = "email"; protected static final String LDAP_INSTITUTE = "institute"; protected static final String LDAP_UID = "uid"; protected static final String USER_ID = "id"; private String[] userAttribs = new String[] { Loading Loading @@ -539,7 +540,7 @@ public class LdapUserDAO extends LdapDAO } InternalID internalID = getInternalID(numericID); setInternalID(user, internalID); setField(user, internalID, USER_ID); user.getIdentities().add(new NumericPrincipal(internalID.getUUID())); String x500str = searchResult.getAttributeValue(userLdapAttrib.get(X500Principal.class)); Loading Loading @@ -662,7 +663,7 @@ public class LdapUserDAO extends LdapDAO // Set the User's private InternalID field InternalID internalID = getInternalID(numericID); setInternalID(user, internalID); setField(user, internalID, USER_ID); user.getIdentities().add(new NumericPrincipal(internalID.getUUID())); String x500str = searchResult.getAttributeValue(userLdapAttrib.get(X500Principal.class)); Loading Loading @@ -724,7 +725,7 @@ public class LdapUserDAO extends LdapDAO logger.debug("numericID is " + numericID); InternalID internalID = getInternalID(numericID); setInternalID(user, internalID); setField(user, internalID, USER_ID); user.getIdentities().add(new NumericPrincipal(internalID.getUUID())); String dn = searchResult.getAttributeValue(LDAP_DISTINGUISHED_NAME); Loading Loading @@ -1353,22 +1354,27 @@ public class LdapUserDAO extends LdapDAO return new InternalID(uri); } private void setInternalID(User user, InternalID internalID) // set private field using reflection private void setField(Object object, Object value, String name) { // set private uri field using reflection try { Field field = user.getClass().getDeclaredField("id"); Field field = object.getClass().getDeclaredField(name); field.setAccessible(true); field.set(user, internalID); field.set(object, value); } catch (NoSuchFieldException e) { throw new RuntimeException("User id field not found", e); final String error = object.getClass().getSimpleName() + " field " + name + "not found"; throw new RuntimeException(error, e); } catch (IllegalAccessException e) { throw new RuntimeException("unable to update User id field", e); final String error = "unable to update " + name + " in " + object.getClass().getSimpleName(); throw new RuntimeException(error, e); } } } Loading
cadcAccessControl-Server/build.xml +2 −2 Original line number Diff line number Diff line Loading @@ -141,9 +141,9 @@ <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapConfigTest" />--> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapConnectionsTest" />--> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapDAOTest" />--> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapGroupDAOTest" />--> <test name="ca.nrc.cadc.ac.server.ldap.LdapGroupDAOTest" /> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapPersistenceTest" />--> <test name="ca.nrc.cadc.ac.server.ldap.LdapUserDAOTest" /> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapUserDAOTest" />--> <!--<test name="ca.nrc.cadc.ac.server.web.groups.AddGroupMemberActionTest" />--> <!--<test name="ca.nrc.cadc.ac.server.web.groups.AddUserMemberActionTest" />--> Loading
cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/TestUtil.java 0 → 100644 +84 −0 Original line number Diff line number Diff line /* ************************************************************************ ******************* CANADIAN ASTRONOMY DATA CENTRE ******************* ************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES ************** * * (c) 2014. (c) 2014. * Government of Canada Gouvernement du Canada * National Research Council Conseil national de recherches * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 * All rights reserved Tous droits réservés * * NRC disclaims any warranties, Le CNRC dénie toute garantie * expressed, implied, or énoncée, implicite ou légale, * statutory, of any kind with de quelque nature que ce * respect to the software, soit, concernant le logiciel, * including without limitation y compris sans restriction * any warranty of merchantability toute garantie de valeur * or fitness for a particular marchande ou de pertinence * purpose. NRC shall not be pour un usage particulier. * liable in any event for any Le CNRC ne pourra en aucun cas * damages, whether direct or être tenu responsable de tout * indirect, special or general, dommage, direct ou indirect, * consequential or incidental, particulier ou général, * arising from the use of the accessoire ou fortuit, résultant * software. Neither the name de l'utilisation du logiciel. Ni * of the National Research le nom du Conseil National de * Council of Canada nor the Recherches du Canada ni les noms * names of its contributors may de ses participants ne peuvent * be used to endorse or promote être utilisés pour approuver ou * products derived from this promouvoir les produits dérivés * software without specific prior de ce logiciel sans autorisation * written permission. préalable et particulière * par écrit. * * This file is part of the Ce fichier fait partie du projet * OpenCADC project. OpenCADC. * * OpenCADC is free software: OpenCADC est un logiciel libre ; * you can redistribute it and/or vous pouvez le redistribuer ou le * modify it under the terms of modifier suivant les termes de * the GNU Affero General Public la “GNU Affero General Public * License as published by the License” telle que publiée * Free Software Foundation, par la Free Software Foundation * either version 3 of the : soit la version 3 de cette * License, or (at your option) licence, soit (à votre gré) * any later version. toute version ultérieure. * * OpenCADC is distributed in the OpenCADC est distribué * hope that it will be useful, dans l’espoir qu’il vous * but WITHOUT ANY WARRANTY; sera utile, mais SANS AUCUNE * without even the implied GARANTIE : sans même la garantie * warranty of MERCHANTABILITY implicite de COMMERCIALISABILITÉ * or FITNESS FOR A PARTICULAR ni d’ADÉQUATION À UN OBJECTIF * PURPOSE. See the GNU Affero PARTICULIER. Consultez la Licence * General Public License for Générale Publique GNU Affero * more details. pour plus de détails. * * You should have received Vous devriez avoir reçu une * a copy of the GNU Affero copie de la Licence Générale * General Public License along Publique GNU Affero avec * with OpenCADC. If not, see OpenCADC ; si ce n’est * <http://www.gnu.org/licenses/>. pas le cas, consultez : * <http://www.gnu.org/licenses/>. * * $Revision: 4 $ * ************************************************************************ */ package ca.nrc.cadc.ac.server; import java.lang.reflect.Field; public class TestUtil { public static void setField(Object object, Object value, String name) throws Exception { Field field = object.getClass().getDeclaredField(name); field.setAccessible(true); field.set(object, value); } }
cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java +87 −67 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ */ package ca.nrc.cadc.ac.server.ldap; import java.lang.reflect.Field; import java.security.AccessControlException; import java.util.ArrayList; import java.util.Collection; Loading @@ -76,8 +77,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.apache.log4j.Logger; import ca.nrc.cadc.ac.ActivatedGroup; Loading Loading @@ -115,19 +114,31 @@ public class LdapGroupDAO extends LdapDAO { private static final Logger logger = Logger.getLogger(LdapGroupDAO.class); // LDAP Group attributes protected static final String LDAP_CN = "cn"; protected static final String LDAP_DESCRIPTION = "description"; protected static final String LDAP_ENTRYDN = "entrydn"; protected static final String LDAP_GROUP_OF_UNIQUE_NAMES = "groupofuniquenames"; protected static final String LDAP_INET_USER = "inetuser"; protected static final String LDAP_MODIFY_TIMESTAMP = "modifytimestamp"; protected static final String LDAP_NSACCOUNTLOCK = "nsaccountlock"; protected static final String LDAP_OBJECT_CLASS = "objectClass"; protected static final String LDAP_OWNER = "owner"; protected static final String LDAP_UNIQUE_MEMBER = "uniquemember"; private static final String[] PUB_GROUP_ATTRS = new String[] { "entrydn", "cn" LDAP_ENTRYDN, LDAP_CN }; private static final String[] GROUP_ATTRS = new String[] { "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description" LDAP_ENTRYDN, LDAP_CN, LDAP_NSACCOUNTLOCK, LDAP_OWNER, LDAP_MODIFY_TIMESTAMP, LDAP_DESCRIPTION }; private static final String[] GROUP_AND_MEMBER_ATTRS = new String[] { "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description", "uniquemember" LDAP_ENTRYDN, LDAP_CN, LDAP_NSACCOUNTLOCK, LDAP_OWNER, LDAP_MODIFY_TIMESTAMP, LDAP_DESCRIPTION, LDAP_UNIQUE_MEMBER }; private final Profiler profiler = new Profiler(LdapGroupDAO.class); Loading Loading @@ -170,13 +181,6 @@ public class LdapGroupDAO extends LdapDAO "Support for groups properties not available"); } // BM: Changed so that the group owner is set to be the // user in the subject //if (!isCreatorOwner(group.getOwner())) //{ // throw new AccessControlException("Group owner must be creator"); //} try { Set<DNPrincipal> ds = group.getOwner().getIdentities(DNPrincipal.class); Loading Loading @@ -228,15 +232,15 @@ public class LdapGroupDAO extends LdapDAO // add new group List<Attribute> attributes = new ArrayList<Attribute>(); Attribute ownerAttribute = new Attribute("owner", ownerDN.toNormalizedString()); new Attribute(LDAP_OWNER, ownerDN.toNormalizedString()); attributes.add(ownerAttribute); attributes.add(new Attribute("objectClass", "groupofuniquenames")); attributes.add(new Attribute("objectClass", "inetUser")); attributes.add(new Attribute("cn", groupID)); attributes.add(new Attribute(LDAP_OBJECT_CLASS, LDAP_GROUP_OF_UNIQUE_NAMES)); attributes.add(new Attribute(LDAP_OBJECT_CLASS, LDAP_INET_USER)); attributes.add(new Attribute(LDAP_CN, groupID)); if (StringUtil.hasText(description)) { attributes.add(new Attribute("description", description)); attributes.add(new Attribute(LDAP_DESCRIPTION, description)); } List<String> members = new ArrayList<String>(); Loading @@ -257,7 +261,7 @@ public class LdapGroupDAO extends LdapDAO } if (!members.isEmpty()) { attributes.add(new Attribute("uniquemember", attributes.add(new Attribute(LDAP_UNIQUE_MEMBER, (String[]) members .toArray(new String[members .size()]))); Loading Loading @@ -291,12 +295,12 @@ public class LdapGroupDAO extends LdapDAO try { // check group name exists Filter filter = Filter.createEqualityFilter("cn", group.getID()); Filter filter = Filter.createEqualityFilter(LDAP_CN, group.getID()); DN groupDN = getGroupDN(group.getID()); SearchRequest searchRequest = new SearchRequest(groupDN.toNormalizedString(), SearchScope.BASE, filter, new String[]{"nsaccountlock"}); new String[]{LDAP_NSACCOUNTLOCK}); //searchRequest.addControl( // new ProxiedAuthorizationV2RequestControl("dn:" + Loading @@ -311,7 +315,7 @@ public class LdapGroupDAO extends LdapDAO return false; } if (searchResult.getAttributeValue("nsaccountlock") == null) if (searchResult.getAttributeValue(LDAP_NSACCOUNTLOCK) == null) { throw new GroupAlreadyExistsException("Group already exists " + group.getID()); } Loading Loading @@ -349,7 +353,7 @@ public class LdapGroupDAO extends LdapDAO try { Filter filter = Filter .createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); .createNOTFilter(Filter.createPresenceFilter(LDAP_NSACCOUNTLOCK)); filter = Filter.createANDFilter(filter, Filter.create("(cn=*)")); final List<String> groupNames = new LinkedList<String>(); Loading @@ -360,7 +364,7 @@ public class LdapGroupDAO extends LdapDAO public void searchEntryReturned(SearchResultEntry sre) { String gname = sre.getAttributeValue("cn"); String gname = sre.getAttributeValue(LDAP_CN); groupNames.add(gname); long t2 = System.currentTimeMillis(); Loading Loading @@ -458,28 +462,20 @@ public class LdapGroupDAO extends LdapDAO String loggableGroupID = xgroupID; if (loggableGroupID == null) { loggableGroupID = groupDN .toString(); // member or admin group: same name, internal tree // member or admin group: same name, internal tree loggableGroupID = groupDN.toString(); } try { Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter(LDAP_NSACCOUNTLOCK)); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString())); Filter.createEqualityFilter(LDAP_ENTRYDN, groupDN.toNormalizedString())); SearchRequest searchRequest = new SearchRequest(groupDN.toNormalizedString(), SearchScope.BASE, filter, attributes); // permissions now checked in LdapGroupPersistence //searchRequest.addControl( // new ProxiedAuthorizationV2RequestControl("dn:" + // getSubjectDN() // .toNormalizedString())); SearchResultEntry searchEntry = getReadOnlyConnection() .searchForEntry(searchRequest); Loading @@ -490,12 +486,12 @@ public class LdapGroupDAO extends LdapDAO throw new GroupNotFoundException(loggableGroupID); } Group ldapGroup = createGroupFromEntry(searchEntry, attributes); Group ldapGroup = createGroupFromSearchResult(searchEntry, attributes); if (searchEntry.getAttributeValues("uniquemember") != null) if (searchEntry.getAttributeValues(LDAP_UNIQUE_MEMBER) != null) { for (String member : searchEntry .getAttributeValues("uniq<? extends Principal>uemember")) .getAttributeValues(LDAP_UNIQUE_MEMBER)) { DN memberDN = new DN(member); if (memberDN.isDescendantOf(config.getUsersDN(), false)) Loading @@ -512,8 +508,7 @@ public class LdapGroupDAO extends LdapDAO // from groups they belong to } } else if (memberDN .isDescendantOf(config.getGroupsDN(), false)) else if (memberDN.isDescendantOf(config.getGroupsDN(), false)) { try { Loading Loading @@ -577,18 +572,18 @@ public class LdapGroupDAO extends LdapDAO List<Modification> adminMods = new ArrayList<Modification>(); if (withActivate) { mods.add(new Modification(ModificationType.DELETE, "nsaccountlock")); adminMods.add(new Modification(ModificationType.DELETE, "nsaccountlock")); mods.add(new Modification(ModificationType.DELETE, LDAP_NSACCOUNTLOCK)); adminMods.add(new Modification(ModificationType.DELETE, LDAP_NSACCOUNTLOCK)); } if (StringUtil.hasText(group.description)) { mods.add(new Modification(ModificationType.REPLACE, "description", mods.add(new Modification(ModificationType.REPLACE, LDAP_DESCRIPTION, group.description)); } else { mods.add(new Modification(ModificationType.REPLACE, "description")); mods.add(new Modification(ModificationType.REPLACE, LDAP_DESCRIPTION)); } try Loading Loading @@ -626,7 +621,7 @@ public class LdapGroupDAO extends LdapDAO } // modify the admin group adminMods.add(new Modification(ModificationType.REPLACE, "uniquemember", adminMods.add(new Modification(ModificationType.REPLACE, LDAP_UNIQUE_MEMBER, (String[]) newAdmins .toArray(new String[newAdmins .size()]))); Loading @@ -642,7 +637,7 @@ public class LdapGroupDAO extends LdapDAO getReadWriteConnection().modify(adminModify).getResultCode()); // modify the group itself mods.add(new Modification(ModificationType.REPLACE, "uniquemember", mods.add(new Modification(ModificationType.REPLACE, LDAP_UNIQUE_MEMBER, (String[]) newMembers .toArray(new String[newMembers .size()]))); Loading Loading @@ -701,7 +696,7 @@ public class LdapGroupDAO extends LdapDAO AccessControlException { ModifyRequest clearMembers = new ModifyRequest(groupDN, new Modification(ModificationType.DELETE, "uniquemember")); new Modification(ModificationType.DELETE, LDAP_UNIQUE_MEMBER)); try { logger.debug("clearMembers " + groupDN); Loading @@ -715,7 +710,7 @@ public class LdapGroupDAO extends LdapDAO } ModifyRequest deleteGroup = new ModifyRequest(groupDN, new Modification(ModificationType.ADD, "nsaccountlock", "true")); new Modification(ModificationType.ADD, LDAP_NSACCOUNTLOCK, "true")); try { Loading Loading @@ -747,16 +742,16 @@ public class LdapGroupDAO extends LdapDAO { DN userDN = new DN(owner.getName()); Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter(LDAP_NSACCOUNTLOCK)); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("owner", userDN.toNormalizedString())); Filter.createEqualityFilter(LDAP_OWNER, userDN.toNormalizedString())); if (groupID != null) { DN groupDN = getGroupDN(groupID); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString())); Filter.createEqualityFilter(LDAP_ENTRYDN, groupDN.toNormalizedString())); } SearchRequest searchRequest = new SearchRequest( Loading @@ -771,7 +766,7 @@ public class LdapGroupDAO extends LdapDAO .search(searchRequest); for (SearchResultEntry result : results.getSearchEntries()) { ret.add(createGroupFromEntry(result, GROUP_ATTRS)); ret.add(createGroupFromSearchResult(result, GROUP_ATTRS)); } } catch (LDAPException e1) Loading @@ -782,23 +777,23 @@ public class LdapGroupDAO extends LdapDAO return ret; } private Group createGroupFromEntry(SearchResultEntry result, String[] attributes) private Group createGroupFromSearchResult(SearchResultEntry result, String[] attributes) throws LDAPException, TransientException { if (result.getAttribute("nsaccountlock") != null) if (result.getAttribute(LDAP_NSACCOUNTLOCK) != null) { throw new RuntimeException("BUG: found group with nsaccountlock set: " + result .getAttributeValue("entrydn").toString()); throw new RuntimeException("BUG: found group with nsaccountlock set: " + result.getAttributeValue(LDAP_ENTRYDN)); } String entryDN = result.getAttributeValue("entrydn"); String groupName = result.getAttributeValue("cn"); String entryDN = result.getAttributeValue(LDAP_ENTRYDN); String groupName = result.getAttributeValue(LDAP_CN); if (attributes == PUB_GROUP_ATTRS) { return new Group(groupName); } DN ownerDN = result.getAttributeValueAsDN("owner"); DN ownerDN = result.getAttributeValueAsDN(LDAP_OWNER); if (ownerDN == null) { throw new AccessControlException(groupName); Loading @@ -806,21 +801,23 @@ public class LdapGroupDAO extends LdapDAO try { User owner = userDAO.getX500User(ownerDN); Group g = new Group(groupName, owner); if (result.hasAttribute("description")) Group g = new Group(groupName); setField(g, owner, LDAP_OWNER); if (result.hasAttribute(LDAP_DESCRIPTION)) { g.description = result.getAttributeValue("description"); g.description = result.getAttributeValue(LDAP_DESCRIPTION); } if (result.hasAttribute("modifytimestamp")) if (result.hasAttribute(LDAP_MODIFY_TIMESTAMP)) { g.lastModified = result .getAttributeValueAsDate("modifytimestamp"); .getAttributeValueAsDate(LDAP_MODIFY_TIMESTAMP); } return g; } catch (UserNotFoundException ex) { throw new RuntimeException("Invalid state: owner does not exist: " + ownerDN + " group: " + entryDN); throw new RuntimeException("Invalid state: owner does not exist: " + ownerDN + " group: " + entryDN); } } Loading Loading @@ -877,4 +874,27 @@ public class LdapGroupDAO extends LdapDAO } } // set private field using reflection private void setField(Object object, Object value, String name) { try { Field field = object.getClass().getDeclaredField(name); field.setAccessible(true); field.set(object, value); } catch (NoSuchFieldException e) { final String error = object.getClass().getSimpleName() + " field " + name + "not found"; throw new RuntimeException(error, e); } catch (IllegalAccessException e) { final String error = "unable to update " + name + " in " + object.getClass().getSimpleName(); throw new RuntimeException(error, e); } } }
cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupPersistence.java +26 −2 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ */ package ca.nrc.cadc.ac.server.ldap; import java.lang.reflect.Field; import java.security.AccessControlException; import java.security.Principal; import java.util.ArrayList; Loading Loading @@ -174,8 +175,8 @@ public class LdapGroupPersistence extends LdapPersistence implements GroupPersis GroupNotFoundException { Subject caller = AuthenticationUtil.getCurrentSubject(); // Principal owner = getUser(caller); // group.setOwner(owner); Principal owner = getUser(caller); setField(group, owner, "owner"); LdapConnections conns = new LdapConnections(this); try Loading Loading @@ -393,4 +394,27 @@ public class LdapGroupPersistence extends LdapPersistence implements GroupPersis GroupMemberships gms = gset.iterator().next(); return gms.getUserID(); } // set private field using reflection private void setField(Object object, Object value, String name) { try { Field field = object.getClass().getDeclaredField(name); field.setAccessible(true); field.set(object, value); } catch (NoSuchFieldException e) { final String error = object.getClass().getSimpleName() + " field " + name + "not found"; throw new RuntimeException(error, e); } catch (IllegalAccessException e) { final String error = "unable to update " + name + " in " + object.getClass().getSimpleName(); throw new RuntimeException(error, e); } } }
cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java +16 −10 Original line number Diff line number Diff line Loading @@ -143,7 +143,7 @@ public class LdapUserDAO extends LdapDAO // Map of identity type to LDAP attribute private final Map<Class<?>, String> userLdapAttrib = new HashMap<Class<?>, String>(); // Returned User attributes // LDAP User attributes protected static final String LDAP_OBJECT_CLASS = "objectClass"; protected static final String LDAP_INET_USER = "inetuser"; protected static final String LDAP_INET_ORG_PERSON = "inetOrgPerson"; Loading @@ -163,6 +163,7 @@ public class LdapUserDAO extends LdapDAO protected static final String LDAP_EMAIL = "email"; protected static final String LDAP_INSTITUTE = "institute"; protected static final String LDAP_UID = "uid"; protected static final String USER_ID = "id"; private String[] userAttribs = new String[] { Loading Loading @@ -539,7 +540,7 @@ public class LdapUserDAO extends LdapDAO } InternalID internalID = getInternalID(numericID); setInternalID(user, internalID); setField(user, internalID, USER_ID); user.getIdentities().add(new NumericPrincipal(internalID.getUUID())); String x500str = searchResult.getAttributeValue(userLdapAttrib.get(X500Principal.class)); Loading Loading @@ -662,7 +663,7 @@ public class LdapUserDAO extends LdapDAO // Set the User's private InternalID field InternalID internalID = getInternalID(numericID); setInternalID(user, internalID); setField(user, internalID, USER_ID); user.getIdentities().add(new NumericPrincipal(internalID.getUUID())); String x500str = searchResult.getAttributeValue(userLdapAttrib.get(X500Principal.class)); Loading Loading @@ -724,7 +725,7 @@ public class LdapUserDAO extends LdapDAO logger.debug("numericID is " + numericID); InternalID internalID = getInternalID(numericID); setInternalID(user, internalID); setField(user, internalID, USER_ID); user.getIdentities().add(new NumericPrincipal(internalID.getUUID())); String dn = searchResult.getAttributeValue(LDAP_DISTINGUISHED_NAME); Loading Loading @@ -1353,22 +1354,27 @@ public class LdapUserDAO extends LdapDAO return new InternalID(uri); } private void setInternalID(User user, InternalID internalID) // set private field using reflection private void setField(Object object, Object value, String name) { // set private uri field using reflection try { Field field = user.getClass().getDeclaredField("id"); Field field = object.getClass().getDeclaredField(name); field.setAccessible(true); field.set(user, internalID); field.set(object, value); } catch (NoSuchFieldException e) { throw new RuntimeException("User id field not found", e); final String error = object.getClass().getSimpleName() + " field " + name + "not found"; throw new RuntimeException(error, e); } catch (IllegalAccessException e) { throw new RuntimeException("unable to update User id field", e); final String error = "unable to update " + name + " in " + object.getClass().getSimpleName(); throw new RuntimeException(error, e); } } }