use of javax.naming.PartialResultException in project tomcat by apache.
the class JNDIRealm method getRoles.
/**
* Return a List of roles associated with the given User. Any
* roles present in the user's directory entry are supplemented by
* a directory search. If no roles are associated with this user,
* a zero-length List is returned.
*
* @param context The directory context we are searching
* @param user The User to be checked
* @return the list of role names
* @exception NamingException if a directory server error occurs
*/
protected List<String> getRoles(DirContext context, User user) throws NamingException {
if (user == null)
return null;
String dn = user.getDN();
String username = user.getUserName();
String userRoleId = user.getUserRoleId();
if (dn == null || username == null)
return null;
if (containerLog.isTraceEnabled())
containerLog.trace(" getRoles(" + dn + ")");
// Start with roles retrieved from the user entry
List<String> list = new ArrayList<>();
List<String> userRoles = user.getRoles();
if (userRoles != null) {
list.addAll(userRoles);
}
if (commonRole != null)
list.add(commonRole);
if (containerLog.isTraceEnabled()) {
containerLog.trace(" Found " + list.size() + " user internal roles");
containerLog.trace(" Found user internal roles " + list.toString());
}
// Are we configured to do role searches?
if ((roleFormat == null) || (roleName == null))
return list;
// Set up parameters for an appropriate search
String filter = roleFormat.format(new String[] { doRFC2254Encoding(dn), username, userRoleId });
SearchControls controls = new SearchControls();
if (roleSubtree)
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
else
controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
controls.setReturningAttributes(new String[] { roleName });
String base = null;
if (roleBaseFormat != null) {
NameParser np = context.getNameParser("");
Name name = np.parse(dn);
String[] nameParts = new String[name.size()];
for (int i = 0; i < name.size(); i++) {
nameParts[i] = name.get(i);
}
base = roleBaseFormat.format(nameParts);
} else {
base = "";
}
// Perform the configured search and process the results
NamingEnumeration<SearchResult> results = searchAsUser(context, user, base, filter, controls, isRoleSearchAsUser());
if (results == null)
// Should never happen, but just in case ...
return list;
HashMap<String, String> groupMap = new HashMap<>();
try {
while (results.hasMore()) {
SearchResult result = results.next();
Attributes attrs = result.getAttributes();
if (attrs == null)
continue;
String dname = getDistinguishedName(context, roleBase, result);
String name = getAttributeValue(roleName, attrs);
if (name != null && dname != null) {
groupMap.put(dname, name);
}
}
} catch (PartialResultException ex) {
if (!adCompat)
throw ex;
} finally {
results.close();
}
if (containerLog.isTraceEnabled()) {
Set<Entry<String, String>> entries = groupMap.entrySet();
containerLog.trace(" Found " + entries.size() + " direct roles");
for (Entry<String, String> entry : entries) {
containerLog.trace(" Found direct role " + entry.getKey() + " -> " + entry.getValue());
}
}
// if nested group search is enabled, perform searches for nested groups until no new group is found
if (getRoleNested()) {
// The following efficient algorithm is known as memberOf Algorithm, as described in "Practices in
// Directory Groups". It avoids group slurping and handles cyclic group memberships as well.
// See http://middleware.internet2.edu/dir/ for details
Map<String, String> newGroups = new HashMap<>(groupMap);
while (!newGroups.isEmpty()) {
// Stores the groups we find in this iteration
Map<String, String> newThisRound = new HashMap<>();
for (Entry<String, String> group : newGroups.entrySet()) {
filter = roleFormat.format(new String[] { group.getKey(), group.getValue(), group.getValue() });
if (containerLog.isTraceEnabled()) {
containerLog.trace("Perform a nested group search with base " + roleBase + " and filter " + filter);
}
results = searchAsUser(context, user, roleBase, filter, controls, isRoleSearchAsUser());
try {
while (results.hasMore()) {
SearchResult result = results.next();
Attributes attrs = result.getAttributes();
if (attrs == null)
continue;
String dname = getDistinguishedName(context, roleBase, result);
String name = getAttributeValue(roleName, attrs);
if (name != null && dname != null && !groupMap.keySet().contains(dname)) {
groupMap.put(dname, name);
newThisRound.put(dname, name);
if (containerLog.isTraceEnabled()) {
containerLog.trace(" Found nested role " + dname + " -> " + name);
}
}
}
} catch (PartialResultException ex) {
if (!adCompat)
throw ex;
} finally {
results.close();
}
}
newGroups = newThisRound;
}
}
list.addAll(groupMap.values());
return list;
}
use of javax.naming.PartialResultException in project zeppelin by apache.
the class LdapRealm method rolesFor.
private Set<String> rolesFor(PrincipalCollection principals, String userNameIn, final LdapContext ldapCtx, final LdapContextFactory ldapContextFactory) throws NamingException {
final Set<String> roleNames = new HashSet<>();
final Set<String> groupNames = new HashSet<>();
final String userName;
if (getUserLowerCase()) {
log.debug("userLowerCase true");
userName = userNameIn.toLowerCase();
} else {
userName = userNameIn;
}
String userDn;
if (userSearchAttributeName == null || userSearchAttributeName.isEmpty()) {
// memberAttributeValuePrefix and memberAttributeValueSuffix
// were computed from memberAttributeValueTemplate
userDn = memberAttributeValuePrefix + userName + memberAttributeValueSuffix;
} else {
userDn = getUserDn(userName);
}
// Activate paged results
int pageSize = getPagingSize();
if (log.isDebugEnabled()) {
log.debug("Ldap PagingSize: " + pageSize);
}
int numResults = 0;
byte[] cookie = null;
try {
ldapCtx.addToEnvironment(Context.REFERRAL, "ignore");
ldapCtx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, Control.NONCRITICAL) });
do {
// ldapsearch -h localhost -p 33389 -D
// uid=guest,ou=people,dc=hadoop,dc=apache,dc=org -w guest-password
// -b dc=hadoop,dc=apache,dc=org -s sub '(objectclass=*)'
NamingEnumeration<SearchResult> searchResultEnum = null;
SearchControls searchControls = getGroupSearchControls();
try {
if (groupSearchEnableMatchingRuleInChain) {
searchResultEnum = ldapCtx.search(getGroupSearchBase(), String.format(MATCHING_RULE_IN_CHAIN_FORMAT, groupObjectClass, memberAttribute, userDn), searchControls);
while (searchResultEnum != null && searchResultEnum.hasMore()) {
// searchResults contains all the groups in search scope
numResults++;
final SearchResult group = searchResultEnum.next();
Attribute attribute = group.getAttributes().get(getGroupIdAttribute());
String groupName = attribute.get().toString();
String roleName = roleNameFor(groupName);
if (roleName != null) {
roleNames.add(roleName);
} else {
roleNames.add(groupName);
}
}
} else {
searchResultEnum = ldapCtx.search(getGroupSearchBase(), "objectClass=" + groupObjectClass, searchControls);
while (searchResultEnum != null && searchResultEnum.hasMore()) {
// searchResults contains all the groups in search scope
numResults++;
final SearchResult group = searchResultEnum.next();
addRoleIfMember(userDn, group, roleNames, groupNames, ldapContextFactory);
}
}
} catch (PartialResultException e) {
log.debug("Ignoring PartitalResultException");
} finally {
if (searchResultEnum != null) {
searchResultEnum.close();
}
}
// Re-activate paged results
ldapCtx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, cookie, Control.CRITICAL) });
} while (cookie != null);
} catch (SizeLimitExceededException e) {
log.info("Only retrieved first " + numResults + " groups due to SizeLimitExceededException.");
} catch (IOException e) {
log.error("Unabled to setup paged results");
}
// save role names and group names in session so that they can be
// easily looked up outside of this object
SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_ROLES, roleNames);
SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_GROUPS, groupNames);
if (!groupNames.isEmpty() && (principals instanceof MutablePrincipalCollection)) {
((MutablePrincipalCollection) principals).addAll(groupNames, getName());
}
if (log.isDebugEnabled()) {
log.debug("User RoleNames: " + userName + "::" + roleNames);
}
return roleNames;
}
use of javax.naming.PartialResultException in project gerrit by GerritCodeReview.
the class Helper method queryForGroups.
Set<AccountGroup.UUID> queryForGroups(final DirContext ctx, final String username, LdapQuery.Result account) throws NamingException {
final LdapSchema schema = getSchema(ctx);
final Set<String> groupDNs = new HashSet<>();
if (!schema.groupMemberQueryList.isEmpty()) {
final HashMap<String, String> params = new HashMap<>();
if (account == null) {
try {
account = findAccount(schema, ctx, username, false);
} catch (AccountException e) {
return Collections.emptySet();
}
}
for (String name : schema.groupMemberQueryList.get(0).getParameters()) {
params.put(name, account.get(name));
}
params.put(LdapRealm.USERNAME, username);
for (LdapQuery groupMemberQuery : schema.groupMemberQueryList) {
for (LdapQuery.Result r : groupMemberQuery.query(ctx, params)) {
recursivelyExpandGroups(groupDNs, schema, ctx, r.getDN());
}
}
}
if (schema.accountMemberField != null) {
if (account == null || account.getAll(schema.accountMemberField) == null) {
try {
account = findAccount(schema, ctx, username, true);
} catch (AccountException e) {
return Collections.emptySet();
}
}
final Attribute groupAtt = account.getAll(schema.accountMemberField);
if (groupAtt != null) {
final NamingEnumeration<?> groups = groupAtt.getAll();
try {
while (groups.hasMore()) {
final String nextDN = (String) groups.next();
recursivelyExpandGroups(groupDNs, schema, ctx, nextDN);
}
} catch (PartialResultException e) {
// Ignored
}
}
}
final Set<AccountGroup.UUID> actual = new HashSet<>();
for (String dn : groupDNs) {
actual.add(new AccountGroup.UUID(LDAP_UUID + dn));
}
if (actual.isEmpty()) {
return Collections.emptySet();
}
return ImmutableSet.copyOf(actual);
}
use of javax.naming.PartialResultException in project gerrit by GerritCodeReview.
the class Helper method recursivelyExpandGroups.
private void recursivelyExpandGroups(final Set<String> groupDNs, final LdapSchema schema, final DirContext ctx, final String groupDN) {
if (groupDNs.add(groupDN) && schema.accountMemberField != null && schema.accountMemberExpandGroups) {
ImmutableSet<String> cachedParentsDNs = parentGroups.getIfPresent(groupDN);
if (cachedParentsDNs == null) {
// Recursively identify the groups it is a member of.
ImmutableSet.Builder<String> dns = ImmutableSet.builder();
try {
final Name compositeGroupName = new CompositeName().add(groupDN);
final Attribute in = ctx.getAttributes(compositeGroupName, schema.accountMemberFieldArray).get(schema.accountMemberField);
if (in != null) {
final NamingEnumeration<?> groups = in.getAll();
try {
while (groups.hasMore()) {
dns.add((String) groups.next());
}
} catch (PartialResultException e) {
// Ignored
}
}
} catch (NamingException e) {
LdapRealm.log.warn("Could not find group " + groupDN, e);
}
cachedParentsDNs = dns.build();
parentGroups.put(groupDN, cachedParentsDNs);
}
for (String dn : cachedParentsDNs) {
recursivelyExpandGroups(groupDNs, schema, ctx, dn);
}
}
}
use of javax.naming.PartialResultException in project gerrit by GerritCodeReview.
the class LdapQuery method query.
List<Result> query(final DirContext ctx, final Map<String, String> params) throws NamingException {
final SearchControls sc = new SearchControls();
final NamingEnumeration<SearchResult> res;
sc.setSearchScope(searchScope.scope());
sc.setReturningAttributes(returnAttributes);
res = ctx.search(base, pattern.getRawPattern(), pattern.bind(params), sc);
try {
final List<Result> r = new ArrayList<>();
try {
while (res.hasMore()) {
r.add(new Result(res.next()));
}
} catch (PartialResultException e) {
// Ignored
}
return r;
} finally {
res.close();
}
}
Aggregations