Loading projects/cadcAccessControl-Server/build.xml +13 −13 Original line number Diff line number Diff line Loading @@ -132,17 +132,17 @@ </copy> </target> <!--<target name="test" depends="compile,compile-test,resources">--> <!--<echo message="Running test suite..." />--> <!--<junit printsummary="yes" haltonfailure="yes" fork="yes">--> <!--<classpath>--> <!--<pathelement path="${build}/class"/>--> <!--<pathelement path="${build}/test/class"/>--> <!--<pathelement path="${testingJars}"/>--> <!--</classpath>--> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapGroupDAOTest" />--> <!--<formatter type="plain" usefile="false" />--> <!--</junit>--> <!--</target>--> <!-- <target name="group-dao-test" depends="compile,compile-test,resources"> <junit printsummary="yes" haltonfailure="yes" fork="yes"> <classpath> <pathelement path="${build}/class"/> <pathelement path="${build}/test/class"/> <pathelement path="${testingJars}"/> </classpath> <test name="ca.nrc.cadc.ac.server.ldap.LdapGroupDAOTest" /> <formatter type="plain" usefile="false" /> </junit> </target> --> </project> projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java +139 −173 Original line number Diff line number Diff line Loading @@ -106,11 +106,17 @@ import com.unboundid.ldap.sdk.SearchResult; import com.unboundid.ldap.sdk.SearchResultEntry; import com.unboundid.ldap.sdk.SearchScope; import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl; import javax.naming.ldap.Rdn; public class LdapGroupDAO<T extends Principal> extends LdapDAO { private static final Logger logger = Logger.getLogger(LdapGroupDAO.class); private static String[] GROUP_ATTRS = new String[] { "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description" }; private LdapUserDAO<T> userPersist; public LdapGroupDAO(LdapConfig config, LdapUserDAO<T> userPersist) Loading Loading @@ -235,7 +241,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO for (Group groupMember : groups) { final String groupMemberID = groupMember.getID(); if (!checkGroupExists(groupMemberID, false)) if (!checkGroupExists(groupMemberID)) { throw new GroupNotFoundException(groupMemberID); } Loading @@ -253,6 +259,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO new ProxiedAuthorizationV2RequestControl( "dn:" + getSubjectDN().toNormalizedString())); logger.debug("addGroup: " + groupDN); return getConnection().add(addRequest); } Loading Loading @@ -393,7 +400,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO return getGroup(groupID, true); } public Group getGroup(final String groupID, final boolean withMembers) private Group getGroup(final String groupID, final boolean withMembers) throws GroupNotFoundException, TransientException, AccessControlException { Loading Loading @@ -428,6 +435,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO return getGroup(groupDN, groupID, withMembers, attributes); } // withMembers is with direct members only: not members of child groups private Group getGroup(final DN groupDN, final String groupID, final boolean withMembers, final String[] attributes) throws GroupNotFoundException, TransientException, Loading @@ -435,7 +443,13 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { try { Filter filter = Filter.createEqualityFilter("cn", groupID); Filter filterLock = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filterDN = Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString()); //Filter filter = Filter.createANDFilter(filterDN, filterLock); // work-around: if we use the nsaccountlock filter then we can't tell the difference // between not-found and not-allowed (by LDAP ACI) Filter filter = filterDN; SearchRequest searchRequest = new SearchRequest(groupDN.toNormalizedString(), Loading @@ -452,7 +466,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } catch (LDAPSearchException e) { if (e.getResultCode() == ResultCode.NO_SUCH_OBJECT) logger.debug("LDAPSearchException: " + e.getEntryCount()); if (ResultCode.NO_SUCH_OBJECT.equals(e.getResultCode())) { String msg = "Group not found " + groupID; logger.debug(msg); Loading Loading @@ -531,21 +546,20 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO try { user = userPersist.getMember(memberDN); ldapGroup.getUserMembers().add(user); } catch (UserNotFoundException e) { throw new RuntimeException( "BUG: group member not found"); // ignore as we do not cleanup deleted users // from groups they belong to } ldapGroup.getUserMembers().add(user); } else if (memberDN.isDescendantOf(config.getGroupsDN(), false)) { try { ldapGroup.getGroupMembers(). add(new Group(getGroupID(memberDN))); ldapGroup.getGroupMembers().add(getGroup(memberDN)); } catch(GroupNotFoundException e) { Loading Loading @@ -631,7 +645,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } for (Group gr : group.getGroupMembers()) { if (!checkGroupExists(gr.getID(), false)) if (!checkGroupExists(gr.getID())) { throw new GroupNotFoundException(gr.getID()); } Loading Loading @@ -662,7 +676,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } for (Group gr : group.getGroupAdmins()) { if (!checkGroupExists(gr.getID(), false)) if (!checkGroupExists(gr.getID())) { throw new GroupNotFoundException(gr.getID()); } Loading Loading @@ -783,24 +797,27 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO try { getGroup(group.getID()); getGroup(getGroupDN(group.getID())); throw new RuntimeException("BUG: group not deleted " + group.getID()); } catch (GroupNotFoundException ignore) {} catch (LDAPException e) { logger.debug("deleteGroup Exception: " + e, e); throw new TransientException("Error verifying delete group", e); } } /** * Obtain a Collection of Groups that fit the given query. * Obtain a Collection of Groups that fit the given query. The returned groups * will not include members. * * @param userID The userID. * @param role Role of the user, either owner, member, or read/write. * @param groupID The Group ID. * * @return Collection of Groups * matching GROUP_READ_ACI.replace(ACTUAL_GROUP_TOKEN, * readGrDN.toNormalizedString()) the query, or empty * Collection. Never null. * @return possibly empty collection of Group that match the query * @throws TransientException If an temporary, unexpected problem occurred. * @throws UserNotFoundException * @throws GroupNotFoundException Loading @@ -822,29 +839,27 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throw new AccessControlException("Not authorized to search"); } Collection<DN> groupDNs = new HashSet<DN>(); Collection<Group> ret; if (role == Role.OWNER) { groupDNs.addAll(getOwnerGroups(user, userDN, groupID)); ret = getOwnerGroups(user, userDN, groupID); } else if (role == Role.MEMBER) { groupDNs.addAll(getMemberGroups(user, userDN, groupID, false)); } else if (role == Role.ADMIN) else { groupDNs.addAll(getMemberGroups(user, userDN, groupID, true)); } Collection<DN> groupDNs = null; if (logger.isDebugEnabled()) if (role == Role.MEMBER) { for (DN dn : groupDNs) { logger.debug("Search adding DN: " + dn); groupDNs = getMemberGroups(user, userDN, groupID, false); } else if (role == Role.ADMIN) { groupDNs = getMemberGroups(user, userDN, groupID, true); } else throw new IllegalArgumentException("null role"); Collection<Group> groups = new HashSet<Group>(); ret = new ArrayList<Group>(); try { for (DN groupDN : groupDNs) Loading @@ -855,8 +870,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } try { groups.add(getGroup(groupDN)); logger.debug("Search adding group: " + groupDN); Group g = getGroup(groupDN); logger.debug("found group: " + g.getID()); ret.add(g); } catch (GroupNotFoundException e) { Loading @@ -872,29 +888,37 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO logger.debug("getGroups Exception: " + e, e); throw new TransientException("Error getting group", e); } return groups; } protected Collection<DN> getOwnerGroups(final User<T> user, logger.debug("found: " + ret.size() + "groups matching " + userID + "," + role + "," + groupID); return ret; } protected Collection<Group> getOwnerGroups(final User<T> user, final DN userDN, final String groupID) throws TransientException, AccessControlException, GroupNotFoundException, UserNotFoundException throws TransientException, AccessControlException { Collection<DN> groupDNs = new HashSet<DN>(); Collection<Group> ret = new ArrayList<Group>(); try { Filter filter = Filter.createEqualityFilter("owner", userDN.toString()); Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("owner", userDN.toNormalizedString())); if (groupID != null) { getGroup(groupID); // getGroup(groupID); // filter = Filter.createANDFilter(filter, // Filter.createEqualityFilter("cn", groupID)); DN groupDN = getGroupDN(groupID); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("cn", groupID)); Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString())); } SearchRequest searchRequest = new SearchRequest( config.getGroupsDN(), SearchScope.SUB, filter, "entrydn", "nsaccountlock"); config.getGroupsDN(), SearchScope.SUB, filter, GROUP_ATTRS); searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + Loading @@ -903,13 +927,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO SearchResult results = getConnection().search(searchRequest); for (SearchResultEntry result : results.getSearchEntries()) { String entryDN = result.getAttributeValue("entrydn"); // make sure the group isn't deleted if (result.getAttribute("nsaccountlock") == null) { groupDNs.add(new DN(entryDN)); } ret.add(createGroup(result)); } } catch (LDAPException e1) Loading @@ -917,7 +935,31 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO logger.debug("getOwnerGroups Exception: " + e1, e1); LdapDAO.checkLdapResult(e1.getResultCode()); } return groupDNs; return ret; } private Group createGroup(SearchResultEntry result) throws LDAPException { if (result.getAttribute("nsaccountlock") != null) { throw new RuntimeException("BUG: found group with nsaccountlock set: " + result.getAttributeValue("entrydn").toString()); } String entryDN = result.getAttributeValue("entrydn"); String groupName = result.getAttributeValue("cn"); DN ownerDN = result.getAttributeValueAsDN("owner"); try { User owner = userPersist.getMember(ownerDN); Group g = new Group(groupName, owner); g.description = result.getAttributeValue("description"); g.lastModified = result.getAttributeValueAsDate("modifytimestamp"); return g; } catch(UserNotFoundException ex) { throw new RuntimeException("Invalid state: owner does not exist: " + ownerDN + " group: " + entryDN); } } protected Collection<DN> getMemberGroups(final User<T> user, Loading Loading @@ -965,93 +1007,40 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * it's deleted or caller has no access to it. */ protected Group getGroup(final DN groupDN) throws LDAPException, GroupNotFoundException, UserNotFoundException { logger.debug("groupDN=" + groupDN.toNormalizedString()); Filter filter = Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString()); SearchRequest searchRequest = new SearchRequest( config.getGroupsDN(), SearchScope.SUB, filter, "cn", "description", "owner", "nsaccountlock"); searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); SearchResultEntry searchResult = getConnection().searchForEntry(searchRequest); if (searchResult == null) { String msg = "Group not found " + groupDN; logger.debug(msg); throw new GroupNotFoundException(groupDN.toNormalizedString()); } if (searchResult.getAttribute("nsaccountlock") != null) { // deleted group String msg = "Group not found " + groupDN; logger.debug(msg); throw new GroupNotFoundException(groupDN.toNormalizedString()); } logger.debug("cn=" + searchResult.getAttributeValue("cn")); logger.debug("owner=" + searchResult.getAttributeValue("owner")); Group group = new Group(searchResult.getAttributeValue("cn"), userPersist.getMember( new DN(searchResult.getAttributeValue( "owner")))); group.description = searchResult.getAttributeValue("description"); return group; } /** * Returns a group ID corresponding to a DN. Although the groupID can be * deduced from the group DN, this method checks if the group exists and * it's active and throws an exception if any of those conditions are not * met. * * @param groupDN * @return * @throws com.unboundid.ldap.sdk.LDAPException * @throws ca.nrc.cadc.ac.GroupNotFoundException - Group not found or not * active */ protected String getGroupID(final DN groupDN) throws LDAPException, GroupNotFoundException { Filter filter = Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString()); logger.debug("getGroup: " + groupDN.toNormalizedString()); Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString())); SearchRequest searchRequest = new SearchRequest( config.getGroupsDN(), SearchScope.SUB, filter, "cn", "nsaccountlock"); config.getGroupsDN(), SearchScope.SUB, filter, GROUP_ATTRS); searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); SearchResultEntry searchResult = SearchResultEntry result = getConnection().searchForEntry(searchRequest); if (searchResult == null) if (result == null) { String msg = "Group not found " + groupDN; logger.debug(msg); throw new GroupNotFoundException(groupDN.toNormalizedString()); } if (searchResult.getAttribute("nsaccountlock") != null) if (result.getAttribute("nsaccountlock") != null) { // deleted group String msg = "Group not found " + groupDN; logger.debug(msg); throw new GroupNotFoundException(groupDN.toNormalizedString()); // TODO: logger.error() + throw GroupNotFoundException instead? throw new RuntimeException("BUG: found group with nsaccountlock set: " + groupDN.toString()); } return searchResult.getAttributeValue("cn"); Group g = createGroup(result); logger.debug("found: " + g.getID()); return g; } /** Loading Loading @@ -1118,41 +1107,18 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } } private boolean checkGroupExists(String groupID, boolean lockedGroupsExist) private boolean checkGroupExists(String groupID) throws LDAPException, TransientException { try { DN groupDN = getGroupDN(groupID); Filter filter = Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString()); SearchRequest searchRequest = new SearchRequest( config.getGroupsDN(), SearchScope.SUB, filter, "cn", "nsaccountlock"); //searchRequest.addControl( // new ProxiedAuthorizationV2RequestControl("dn:" + // getSubjectDN().toNormalizedString())); SearchResultEntry searchResult = getConnection().searchForEntry(searchRequest); if (searchResult == null) { String msg = "Group not found " + groupDN; logger.debug(msg); return false; Group g = getGroup(groupDN); return true; } if (searchResult.getAttribute("nsaccountlock") != null) catch(GroupNotFoundException ex) { // deleted group String msg = "Group marked deleted " + groupDN; logger.debug(msg); return lockedGroupsExist; } return true; return false; } finally { } } Loading projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ACSearchRunner.java +17 −0 Original line number Diff line number Diff line Loading @@ -336,6 +336,23 @@ public class ACSearchRunner implements JobRunner // } } */ catch(IllegalArgumentException ex) { logInfo.setSuccess(true); logInfo.setMessage(ex.getMessage()); log.debug("FAIL", ex); syncOut.setResponseCode(400); syncOut.setHeader("Content-Type", "text/plain"); try { syncOut.getOutputStream().write(ex.getMessage().getBytes()); } catch (IOException e) { log.warn("Could not write response to output stream", e); } } catch (AccessControlException t) { logInfo.setSuccess(true); Loading projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java +1 −9 Original line number Diff line number Diff line Loading @@ -863,18 +863,10 @@ public class LdapGroupDAOTest extends AbstractLdapDAOTest getGroupDAO().getGroups(unknownPrincipal, Role.OWNER, groupID); fail("searchGroups with unknown user should throw " + "UserNotFoundException"); "AccessControlException"); } catch (AccessControlException ignore) {} try { getGroupDAO().getGroups(daoTestPrincipal1, Role.OWNER, "foo"); fail("searchGroups with unknown user should throw " + "GroupNotFoundException"); } catch (GroupNotFoundException ignore) {} return null; } }); Loading projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClientMain.java +15 −5 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ public class GMSClientMain implements PrivilegedAction<Object> public static final String ARG_ADD_MEMBER = "add-member"; public static final String ARG_CREATE_GROUP = "create"; public static final String ARG_GET_GROUP = "get"; public static final String ARG_DELETE_GROUP = "delete"; public static final String ARG_USERID = "userid"; public static final String ARG_GROUP = "group"; Loading Loading @@ -182,6 +183,9 @@ public class GMSClientMain implements PrivilegedAction<Object> if (argMap.isSet(ARG_GET_GROUP)) return ARG_GET_GROUP; if (argMap.isSet(ARG_DELETE_GROUP)) return ARG_DELETE_GROUP; throw new IllegalArgumentException("No valid commands"); } Loading @@ -190,7 +194,7 @@ public class GMSClientMain implements PrivilegedAction<Object> System.out.println("--add-member --group=<g> --userid=<u>"); System.out.println("--create --group=<g>"); System.out.println("--get --group=<g>"); System.out.println("--delete --group=<g>"); } @Override Loading @@ -213,8 +217,7 @@ public class GMSClientMain implements PrivilegedAction<Object> client.addUserMember(group, new HttpPrincipal(userID)); } if (command.equals(ARG_CREATE_GROUP)) else if (command.equals(ARG_CREATE_GROUP)) { String group = argMap.getValue(ARG_GROUP); if (group == null) Loading @@ -229,8 +232,7 @@ public class GMSClientMain implements PrivilegedAction<Object> g.getUserMembers().add(g.getOwner()); client.createGroup(g); } if (command.equals(ARG_GET_GROUP)) else if (command.equals(ARG_GET_GROUP)) { String group = argMap.getValue(ARG_GROUP); if (group == null) Loading @@ -254,6 +256,14 @@ public class GMSClientMain implements PrivilegedAction<Object> System.out.println("member: " + gm); } else if (command.equals(ARG_DELETE_GROUP)) { String group = argMap.getValue(ARG_GROUP); if (group == null) throw new IllegalArgumentException("No group specified"); client.deleteGroup(group); } return null; } Loading Loading
projects/cadcAccessControl-Server/build.xml +13 −13 Original line number Diff line number Diff line Loading @@ -132,17 +132,17 @@ </copy> </target> <!--<target name="test" depends="compile,compile-test,resources">--> <!--<echo message="Running test suite..." />--> <!--<junit printsummary="yes" haltonfailure="yes" fork="yes">--> <!--<classpath>--> <!--<pathelement path="${build}/class"/>--> <!--<pathelement path="${build}/test/class"/>--> <!--<pathelement path="${testingJars}"/>--> <!--</classpath>--> <!--<test name="ca.nrc.cadc.ac.server.ldap.LdapGroupDAOTest" />--> <!--<formatter type="plain" usefile="false" />--> <!--</junit>--> <!--</target>--> <!-- <target name="group-dao-test" depends="compile,compile-test,resources"> <junit printsummary="yes" haltonfailure="yes" fork="yes"> <classpath> <pathelement path="${build}/class"/> <pathelement path="${build}/test/class"/> <pathelement path="${testingJars}"/> </classpath> <test name="ca.nrc.cadc.ac.server.ldap.LdapGroupDAOTest" /> <formatter type="plain" usefile="false" /> </junit> </target> --> </project>
projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java +139 −173 Original line number Diff line number Diff line Loading @@ -106,11 +106,17 @@ import com.unboundid.ldap.sdk.SearchResult; import com.unboundid.ldap.sdk.SearchResultEntry; import com.unboundid.ldap.sdk.SearchScope; import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl; import javax.naming.ldap.Rdn; public class LdapGroupDAO<T extends Principal> extends LdapDAO { private static final Logger logger = Logger.getLogger(LdapGroupDAO.class); private static String[] GROUP_ATTRS = new String[] { "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description" }; private LdapUserDAO<T> userPersist; public LdapGroupDAO(LdapConfig config, LdapUserDAO<T> userPersist) Loading Loading @@ -235,7 +241,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO for (Group groupMember : groups) { final String groupMemberID = groupMember.getID(); if (!checkGroupExists(groupMemberID, false)) if (!checkGroupExists(groupMemberID)) { throw new GroupNotFoundException(groupMemberID); } Loading @@ -253,6 +259,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO new ProxiedAuthorizationV2RequestControl( "dn:" + getSubjectDN().toNormalizedString())); logger.debug("addGroup: " + groupDN); return getConnection().add(addRequest); } Loading Loading @@ -393,7 +400,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO return getGroup(groupID, true); } public Group getGroup(final String groupID, final boolean withMembers) private Group getGroup(final String groupID, final boolean withMembers) throws GroupNotFoundException, TransientException, AccessControlException { Loading Loading @@ -428,6 +435,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO return getGroup(groupDN, groupID, withMembers, attributes); } // withMembers is with direct members only: not members of child groups private Group getGroup(final DN groupDN, final String groupID, final boolean withMembers, final String[] attributes) throws GroupNotFoundException, TransientException, Loading @@ -435,7 +443,13 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { try { Filter filter = Filter.createEqualityFilter("cn", groupID); Filter filterLock = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filterDN = Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString()); //Filter filter = Filter.createANDFilter(filterDN, filterLock); // work-around: if we use the nsaccountlock filter then we can't tell the difference // between not-found and not-allowed (by LDAP ACI) Filter filter = filterDN; SearchRequest searchRequest = new SearchRequest(groupDN.toNormalizedString(), Loading @@ -452,7 +466,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } catch (LDAPSearchException e) { if (e.getResultCode() == ResultCode.NO_SUCH_OBJECT) logger.debug("LDAPSearchException: " + e.getEntryCount()); if (ResultCode.NO_SUCH_OBJECT.equals(e.getResultCode())) { String msg = "Group not found " + groupID; logger.debug(msg); Loading Loading @@ -531,21 +546,20 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO try { user = userPersist.getMember(memberDN); ldapGroup.getUserMembers().add(user); } catch (UserNotFoundException e) { throw new RuntimeException( "BUG: group member not found"); // ignore as we do not cleanup deleted users // from groups they belong to } ldapGroup.getUserMembers().add(user); } else if (memberDN.isDescendantOf(config.getGroupsDN(), false)) { try { ldapGroup.getGroupMembers(). add(new Group(getGroupID(memberDN))); ldapGroup.getGroupMembers().add(getGroup(memberDN)); } catch(GroupNotFoundException e) { Loading Loading @@ -631,7 +645,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } for (Group gr : group.getGroupMembers()) { if (!checkGroupExists(gr.getID(), false)) if (!checkGroupExists(gr.getID())) { throw new GroupNotFoundException(gr.getID()); } Loading Loading @@ -662,7 +676,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } for (Group gr : group.getGroupAdmins()) { if (!checkGroupExists(gr.getID(), false)) if (!checkGroupExists(gr.getID())) { throw new GroupNotFoundException(gr.getID()); } Loading Loading @@ -783,24 +797,27 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO try { getGroup(group.getID()); getGroup(getGroupDN(group.getID())); throw new RuntimeException("BUG: group not deleted " + group.getID()); } catch (GroupNotFoundException ignore) {} catch (LDAPException e) { logger.debug("deleteGroup Exception: " + e, e); throw new TransientException("Error verifying delete group", e); } } /** * Obtain a Collection of Groups that fit the given query. * Obtain a Collection of Groups that fit the given query. The returned groups * will not include members. * * @param userID The userID. * @param role Role of the user, either owner, member, or read/write. * @param groupID The Group ID. * * @return Collection of Groups * matching GROUP_READ_ACI.replace(ACTUAL_GROUP_TOKEN, * readGrDN.toNormalizedString()) the query, or empty * Collection. Never null. * @return possibly empty collection of Group that match the query * @throws TransientException If an temporary, unexpected problem occurred. * @throws UserNotFoundException * @throws GroupNotFoundException Loading @@ -822,29 +839,27 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throw new AccessControlException("Not authorized to search"); } Collection<DN> groupDNs = new HashSet<DN>(); Collection<Group> ret; if (role == Role.OWNER) { groupDNs.addAll(getOwnerGroups(user, userDN, groupID)); ret = getOwnerGroups(user, userDN, groupID); } else if (role == Role.MEMBER) { groupDNs.addAll(getMemberGroups(user, userDN, groupID, false)); } else if (role == Role.ADMIN) else { groupDNs.addAll(getMemberGroups(user, userDN, groupID, true)); } Collection<DN> groupDNs = null; if (logger.isDebugEnabled()) if (role == Role.MEMBER) { for (DN dn : groupDNs) { logger.debug("Search adding DN: " + dn); groupDNs = getMemberGroups(user, userDN, groupID, false); } else if (role == Role.ADMIN) { groupDNs = getMemberGroups(user, userDN, groupID, true); } else throw new IllegalArgumentException("null role"); Collection<Group> groups = new HashSet<Group>(); ret = new ArrayList<Group>(); try { for (DN groupDN : groupDNs) Loading @@ -855,8 +870,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } try { groups.add(getGroup(groupDN)); logger.debug("Search adding group: " + groupDN); Group g = getGroup(groupDN); logger.debug("found group: " + g.getID()); ret.add(g); } catch (GroupNotFoundException e) { Loading @@ -872,29 +888,37 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO logger.debug("getGroups Exception: " + e, e); throw new TransientException("Error getting group", e); } return groups; } protected Collection<DN> getOwnerGroups(final User<T> user, logger.debug("found: " + ret.size() + "groups matching " + userID + "," + role + "," + groupID); return ret; } protected Collection<Group> getOwnerGroups(final User<T> user, final DN userDN, final String groupID) throws TransientException, AccessControlException, GroupNotFoundException, UserNotFoundException throws TransientException, AccessControlException { Collection<DN> groupDNs = new HashSet<DN>(); Collection<Group> ret = new ArrayList<Group>(); try { Filter filter = Filter.createEqualityFilter("owner", userDN.toString()); Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("owner", userDN.toNormalizedString())); if (groupID != null) { getGroup(groupID); // getGroup(groupID); // filter = Filter.createANDFilter(filter, // Filter.createEqualityFilter("cn", groupID)); DN groupDN = getGroupDN(groupID); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("cn", groupID)); Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString())); } SearchRequest searchRequest = new SearchRequest( config.getGroupsDN(), SearchScope.SUB, filter, "entrydn", "nsaccountlock"); config.getGroupsDN(), SearchScope.SUB, filter, GROUP_ATTRS); searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + Loading @@ -903,13 +927,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO SearchResult results = getConnection().search(searchRequest); for (SearchResultEntry result : results.getSearchEntries()) { String entryDN = result.getAttributeValue("entrydn"); // make sure the group isn't deleted if (result.getAttribute("nsaccountlock") == null) { groupDNs.add(new DN(entryDN)); } ret.add(createGroup(result)); } } catch (LDAPException e1) Loading @@ -917,7 +935,31 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO logger.debug("getOwnerGroups Exception: " + e1, e1); LdapDAO.checkLdapResult(e1.getResultCode()); } return groupDNs; return ret; } private Group createGroup(SearchResultEntry result) throws LDAPException { if (result.getAttribute("nsaccountlock") != null) { throw new RuntimeException("BUG: found group with nsaccountlock set: " + result.getAttributeValue("entrydn").toString()); } String entryDN = result.getAttributeValue("entrydn"); String groupName = result.getAttributeValue("cn"); DN ownerDN = result.getAttributeValueAsDN("owner"); try { User owner = userPersist.getMember(ownerDN); Group g = new Group(groupName, owner); g.description = result.getAttributeValue("description"); g.lastModified = result.getAttributeValueAsDate("modifytimestamp"); return g; } catch(UserNotFoundException ex) { throw new RuntimeException("Invalid state: owner does not exist: " + ownerDN + " group: " + entryDN); } } protected Collection<DN> getMemberGroups(final User<T> user, Loading Loading @@ -965,93 +1007,40 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * it's deleted or caller has no access to it. */ protected Group getGroup(final DN groupDN) throws LDAPException, GroupNotFoundException, UserNotFoundException { logger.debug("groupDN=" + groupDN.toNormalizedString()); Filter filter = Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString()); SearchRequest searchRequest = new SearchRequest( config.getGroupsDN(), SearchScope.SUB, filter, "cn", "description", "owner", "nsaccountlock"); searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); SearchResultEntry searchResult = getConnection().searchForEntry(searchRequest); if (searchResult == null) { String msg = "Group not found " + groupDN; logger.debug(msg); throw new GroupNotFoundException(groupDN.toNormalizedString()); } if (searchResult.getAttribute("nsaccountlock") != null) { // deleted group String msg = "Group not found " + groupDN; logger.debug(msg); throw new GroupNotFoundException(groupDN.toNormalizedString()); } logger.debug("cn=" + searchResult.getAttributeValue("cn")); logger.debug("owner=" + searchResult.getAttributeValue("owner")); Group group = new Group(searchResult.getAttributeValue("cn"), userPersist.getMember( new DN(searchResult.getAttributeValue( "owner")))); group.description = searchResult.getAttributeValue("description"); return group; } /** * Returns a group ID corresponding to a DN. Although the groupID can be * deduced from the group DN, this method checks if the group exists and * it's active and throws an exception if any of those conditions are not * met. * * @param groupDN * @return * @throws com.unboundid.ldap.sdk.LDAPException * @throws ca.nrc.cadc.ac.GroupNotFoundException - Group not found or not * active */ protected String getGroupID(final DN groupDN) throws LDAPException, GroupNotFoundException { Filter filter = Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString()); logger.debug("getGroup: " + groupDN.toNormalizedString()); Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString())); SearchRequest searchRequest = new SearchRequest( config.getGroupsDN(), SearchScope.SUB, filter, "cn", "nsaccountlock"); config.getGroupsDN(), SearchScope.SUB, filter, GROUP_ATTRS); searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); SearchResultEntry searchResult = SearchResultEntry result = getConnection().searchForEntry(searchRequest); if (searchResult == null) if (result == null) { String msg = "Group not found " + groupDN; logger.debug(msg); throw new GroupNotFoundException(groupDN.toNormalizedString()); } if (searchResult.getAttribute("nsaccountlock") != null) if (result.getAttribute("nsaccountlock") != null) { // deleted group String msg = "Group not found " + groupDN; logger.debug(msg); throw new GroupNotFoundException(groupDN.toNormalizedString()); // TODO: logger.error() + throw GroupNotFoundException instead? throw new RuntimeException("BUG: found group with nsaccountlock set: " + groupDN.toString()); } return searchResult.getAttributeValue("cn"); Group g = createGroup(result); logger.debug("found: " + g.getID()); return g; } /** Loading Loading @@ -1118,41 +1107,18 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } } private boolean checkGroupExists(String groupID, boolean lockedGroupsExist) private boolean checkGroupExists(String groupID) throws LDAPException, TransientException { try { DN groupDN = getGroupDN(groupID); Filter filter = Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString()); SearchRequest searchRequest = new SearchRequest( config.getGroupsDN(), SearchScope.SUB, filter, "cn", "nsaccountlock"); //searchRequest.addControl( // new ProxiedAuthorizationV2RequestControl("dn:" + // getSubjectDN().toNormalizedString())); SearchResultEntry searchResult = getConnection().searchForEntry(searchRequest); if (searchResult == null) { String msg = "Group not found " + groupDN; logger.debug(msg); return false; Group g = getGroup(groupDN); return true; } if (searchResult.getAttribute("nsaccountlock") != null) catch(GroupNotFoundException ex) { // deleted group String msg = "Group marked deleted " + groupDN; logger.debug(msg); return lockedGroupsExist; } return true; return false; } finally { } } Loading
projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ACSearchRunner.java +17 −0 Original line number Diff line number Diff line Loading @@ -336,6 +336,23 @@ public class ACSearchRunner implements JobRunner // } } */ catch(IllegalArgumentException ex) { logInfo.setSuccess(true); logInfo.setMessage(ex.getMessage()); log.debug("FAIL", ex); syncOut.setResponseCode(400); syncOut.setHeader("Content-Type", "text/plain"); try { syncOut.getOutputStream().write(ex.getMessage().getBytes()); } catch (IOException e) { log.warn("Could not write response to output stream", e); } } catch (AccessControlException t) { logInfo.setSuccess(true); Loading
projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java +1 −9 Original line number Diff line number Diff line Loading @@ -863,18 +863,10 @@ public class LdapGroupDAOTest extends AbstractLdapDAOTest getGroupDAO().getGroups(unknownPrincipal, Role.OWNER, groupID); fail("searchGroups with unknown user should throw " + "UserNotFoundException"); "AccessControlException"); } catch (AccessControlException ignore) {} try { getGroupDAO().getGroups(daoTestPrincipal1, Role.OWNER, "foo"); fail("searchGroups with unknown user should throw " + "GroupNotFoundException"); } catch (GroupNotFoundException ignore) {} return null; } }); Loading
projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClientMain.java +15 −5 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ public class GMSClientMain implements PrivilegedAction<Object> public static final String ARG_ADD_MEMBER = "add-member"; public static final String ARG_CREATE_GROUP = "create"; public static final String ARG_GET_GROUP = "get"; public static final String ARG_DELETE_GROUP = "delete"; public static final String ARG_USERID = "userid"; public static final String ARG_GROUP = "group"; Loading Loading @@ -182,6 +183,9 @@ public class GMSClientMain implements PrivilegedAction<Object> if (argMap.isSet(ARG_GET_GROUP)) return ARG_GET_GROUP; if (argMap.isSet(ARG_DELETE_GROUP)) return ARG_DELETE_GROUP; throw new IllegalArgumentException("No valid commands"); } Loading @@ -190,7 +194,7 @@ public class GMSClientMain implements PrivilegedAction<Object> System.out.println("--add-member --group=<g> --userid=<u>"); System.out.println("--create --group=<g>"); System.out.println("--get --group=<g>"); System.out.println("--delete --group=<g>"); } @Override Loading @@ -213,8 +217,7 @@ public class GMSClientMain implements PrivilegedAction<Object> client.addUserMember(group, new HttpPrincipal(userID)); } if (command.equals(ARG_CREATE_GROUP)) else if (command.equals(ARG_CREATE_GROUP)) { String group = argMap.getValue(ARG_GROUP); if (group == null) Loading @@ -229,8 +232,7 @@ public class GMSClientMain implements PrivilegedAction<Object> g.getUserMembers().add(g.getOwner()); client.createGroup(g); } if (command.equals(ARG_GET_GROUP)) else if (command.equals(ARG_GET_GROUP)) { String group = argMap.getValue(ARG_GROUP); if (group == null) Loading @@ -254,6 +256,14 @@ public class GMSClientMain implements PrivilegedAction<Object> System.out.println("member: " + gm); } else if (command.equals(ARG_DELETE_GROUP)) { String group = argMap.getValue(ARG_GROUP); if (group == null) throw new IllegalArgumentException("No group specified"); client.deleteGroup(group); } return null; } Loading