Hi all, 
some days ago I have posted on gis.stackexchange a question ( [ 
https://gis.stackexchange.com/questions/349065/ldap-role-service-with-hierarchical-groups-search
 | 
https://gis.stackexchange.com/questions/349065/ldap-role-service-with-hierarchical-groups-search
 ] for details) about an error given by the LDAP hierarchical groups search in 
geoserver 2.16.1 with Tomcat 7 and openjdk 1.8.0_212. 
The error occurs both in LDAP Role Service and in LDAP User/Group Service only 
when the hierarchical group search is enabled. The error given by the geoserver 
is a HTTP 500 Internal Server Error and the following stack trace is displayed: 

java.util.ConcurrentModificationException 
java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1211) 
java.util.TreeMap$KeyIterator.next(TreeMap.java:1265) 
org.geoserver.security.ldap.LDAPRoleService.getRolesForUser(LDAPRoleService.java:181)
 
org.geoserver.security.impl.RoleCalculator.calculateRoles(RoleCalculator.java:109)
 
org.geoserver.security.impl.RoleCalculator.calculateRoles(RoleCalculator.java:81)
 
org.geoserver.security.filter.GeoServerPreAuthenticatedUserNameFilter.getRolesFromRoleService(GeoServerPreAuthenticatedUserNameFilter.java:188)
 
org.geoserver.security.filter.GeoServerPreAuthenticatedUserNameFilter.getRoles(GeoServerPreAuthenticatedUserNameFilter.java:150)
 
org.geoserver.security.filter.GeoServerPreAuthenticationFilter.doAuthenticate(GeoServerPreAuthenticationFilter.java:116)
 
org.geoserver.security.filter.GeoServerPreAuthenticationFilter.doFilter(GeoServerPreAuthenticationFilter.java:56)
 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
 

By analysing the code of the LDAPRoleService class and the related error it 
came up it could be a bug in the code. 
Considering the following code of the LDAPRoleService class, I see that the 
object roles of type TreeSet is modified by the searchNestedParetRoles method 
while the getRolesForUsers method iterates on it. 

@Override 
public SortedSet<GeoServerRole> getRolesForUser(final String username) throws 
IOException { 
final SortedSet<GeoServerRole> roles = new TreeSet<GeoServerRole>(); 
... 
... 
if (useNestedGroups) { 
for (GeoServerRole erole : roles) { <-----------this line generates the error 
(line 181) 
searchNestedParentRoles(erole, roles, 1); 
} 
} 
return Collections.unmodifiableSortedSet(roles); 
} 

private void searchNestedParentRoles(GeoServerRole role, Set<GeoServerRole> 
roles, int depth) { 
if (isOutOfDepthBounds(depth)) return; 
for (GeoServerRole erole : getParentRolesbyMember(role)) { 
if (!roles.contains(erole)) { 
roles.add(erole); 
searchNestedParentRoles(erole, roles, depth + 1); 
} 
} 
} 

The Oracle's documentation about the TreeSet class states that "The iterators 
returned by this class's iterator method are fail-fast: if the set is modified 
at any time after the iterator is created, in any way except through the 
iterator's own remove method, the iterator will throw a 
ConcurrentModificationException". If I'm not totally wrong, our case is the one 
described by the documentation and indeed we get the 
ConcurrentModificationException. 

We could avoid the error by adding two line of code in the getRolesForUser 
method: 

@Override 
public SortedSet<GeoServerRole> getRolesForUser(final String username) throws 
IOException { 
final SortedSet<GeoServerRole> roles = new TreeSet<GeoServerRole>(); 
final SortedSet<GeoServerRole> parentRoles = new TreeSet<GeoServerRole>(); // 
new set containing only nested parent roles 
... 
... 
if (useNestedGroups) { 
for (GeoServerRole erole : roles) { 
searchNestedParentRoles(erole, parentRoles, 1); // parentRoles instead of roles 
passed to searchNestedParentRoles 
} 
roles.addAll(parentRoles); // merge of the roles 

} 
return Collections.unmodifiableSortedSet(roles); 
} 



Regards 
__________________________________________ 

Giovanni Spigoni 
Gestione e Sviluppo delle T ecnologie e dei Sistemi Informativi 
Comune di Reggio nell'Emilia 
Piazza Scapinelli, 2 - 42121 Reggio nell'Emilia 
tel: 0522 585185 
email: giovanni.spig...@comune.re.it 
__________________________________________ 

_______________________________________________
Geoserver-users mailing list

Please make sure you read the following two resources before posting to this 
list:
- Earning your support instead of buying it, but Ian Turton: 
http://www.ianturton.com/talks/foss4g.html#/
- The GeoServer user list posting guidelines: 
http://geoserver.org/comm/userlist-guidelines.html

If you want to request a feature or an improvement, also see this: 
https://github.com/geoserver/geoserver/wiki/Successfully-requesting-and-integrating-new-features-and-improvements-in-GeoServer


Geoserver-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-users

Reply via email to