Fix LDAP account lookup when user not in group
If a user is not a member of any group and the backing LDAP server
is an Active Directory instance we won't receive a 'memberOf'
attribute in the user's account data. Instead of crashing with
NPE we should handle the case as though the list was empty.
I cleaned up the LdapQuery.Result code a little while checking the
other uses of data obtained from the directory, as we should always
handle a missing attribute gracefully.
Change-Id: Id2f030815bd597dcba5712f7def5d10818b4eb79
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/src/main/java/com/google/gerrit/server/ldap/LdapQuery.java b/src/main/java/com/google/gerrit/server/ldap/LdapQuery.java
index 33a2fad..3055fe6 100644
--- a/src/main/java/com/google/gerrit/server/ldap/LdapQuery.java
+++ b/src/main/java/com/google/gerrit/server/ldap/LdapQuery.java
@@ -80,29 +80,25 @@
class Result {
private final Map<String, Attribute> atts = new HashMap<String, Attribute>();
- private final Map<String, String> attsSingle = new HashMap<String, String>();
- Result(final SearchResult sr) throws NamingException {
+ Result(final SearchResult sr) {
if (returnAttributes != null) {
for (final String attName : returnAttributes) {
final Attribute a = sr.getAttributes().get(attName);
if (a != null && a.size() > 0) {
atts.put(attName, a);
- attsSingle.put(attName, String.valueOf(a.get(0)));
}
}
+
} else {
NamingEnumeration<? extends Attribute> e = sr.getAttributes().getAll();
while (e.hasMoreElements()) {
final Attribute a = e.nextElement();
atts.put(a.getID(), a);
- if (a.size() == 1) {
- attsSingle.put(a.getID(), String.valueOf(a.get(0)));
- }
}
}
+
atts.put("dn", new BasicAttribute("dn", sr.getNameInNamespace()));
- attsSingle.put("dn", sr.getNameInNamespace());
}
String getDN() throws NamingException {
@@ -110,15 +106,16 @@
}
String get(final String attName) throws NamingException {
- return String.valueOf(atts.get(attName).get(0));
+ final Attribute att = getAll(attName);
+ return att != null && 0 < att.size() ? String.valueOf(att.get(0)) : null;
}
Attribute getAll(final String attName) {
return atts.get(attName);
}
- Map<String, String> map() {
- return Collections.unmodifiableMap(attsSingle);
+ Set<String> attributes() {
+ return Collections.unmodifiableSet(atts.keySet());
}
@Override
diff --git a/src/main/java/com/google/gerrit/server/ldap/LdapRealm.java b/src/main/java/com/google/gerrit/server/ldap/LdapRealm.java
index f3dbd1e..47aa33d 100644
--- a/src/main/java/com/google/gerrit/server/ldap/LdapRealm.java
+++ b/src/main/java/com/google/gerrit/server/ldap/LdapRealm.java
@@ -283,11 +283,18 @@
}
}
- private static String apply(ParamertizedString p, LdapQuery.Result m) {
+ private static String apply(ParamertizedString p, LdapQuery.Result m)
+ throws NamingException {
if (p == null) {
return null;
}
- String r = p.replace(m.map());
+
+ final Map<String, String> values = new HashMap<String, String>();
+ for (final String name : m.attributes()) {
+ values.put(name, m.get(name));
+ }
+
+ String r = p.replace(values);
return r.isEmpty() ? null : r;
}
@@ -399,9 +406,12 @@
account = findAccount(ctx, username);
}
- NamingEnumeration<?> groups = account.getAll(accountMemberField).getAll();
- while (groups.hasMore()) {
- recursivelyExpandGroups(groupDNs, ctx, (String) groups.next());
+ final Attribute groupAtt = account.getAll(accountMemberField);
+ if (groupAtt != null) {
+ final NamingEnumeration<?> groups = groupAtt.getAll();
+ while (groups.hasMore()) {
+ recursivelyExpandGroups(groupDNs, ctx, (String) groups.next());
+ }
}
}