Merge "FreeIPA as ldap backend"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 759e5cd..031f025 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -2679,9 +2679,9 @@
An example LDAP configuration follows, and then discussion of
the parameters introduced here. Suitable defaults for most
parameters are automatically guessed based on the type of server
-detected during startup. The guessed defaults support both
-link:http://www.ietf.org/rfc/rfc2307.txt[RFC 2307] and Active
-Directory.
+detected during startup. The guessed defaults support
+link:http://www.ietf.org/rfc/rfc2307.txt[RFC 2307], Active
+Directory and link:https://www.freeipa.org[FreeIPA].
----
[ldap]
@@ -2785,7 +2785,7 @@
is `(uid=${username})` or `(cn=${username})`, but the proper
setting depends on the LDAP schema used by the directory server.
+
-Default is `(uid=${username})` for RFC 2307 servers,
+Default is `(uid=${username})` for FreeIPA and RFC 2307 servers,
and `(&(objectClass=user)(sAMAccountName=${username}))`
for Active Directory.
@@ -2803,7 +2803,7 @@
If set, users will be unable to modify their full name field, as
Gerrit will populate it only from the LDAP data.
+
-Default is `displayName` for RFC 2307 servers,
+Default is `displayName` for FreeIPA and RFC 2307 servers,
and `${givenName} ${sn}` for Active Directory.
[[ldap.accountEmailAddress]]ldap.accountEmailAddress::
@@ -2846,17 +2846,25 @@
recommended not to make changes to this setting that would cause the
value to differ, as this will prevent users from logging in.
+
-Default is `uid` for RFC 2307 servers,
+Default is `uid` for FreeIPA and RFC 2307 servers,
and `${sAMAccountName.toLowerCase}` for Active Directory.
[[ldap.accountMemberField]]ldap.accountMemberField::
+
_(Optional)_ Name of an attribute on the user account object which
contains the groups the user is part of. Typically used for Active
-Directory servers.
+Directory and FreeIPA servers.
+
Default is unset for RFC 2307 servers (disabled)
-and `memberOf` for Active Directory.
+and `memberOf` for Active Directory and FreeIPA.
+
+[[ldap.accountMemberExpandGroups]]ldap.accountMemberExpandGroups::
++
+_(Optional)_ Whether to expand nested groups recursively. This
+setting is used only if `ldap.accountMemberField` is set.
++
+Default is unset for FreeIPA and `true` for RFC 2307 servers
+and Active Directory.
[[ldap.fetchMemberOfEagerly]]ldap.fetchMemberOfEagerly::
+
@@ -2866,7 +2874,7 @@
as this will result in a much faster LDAP login.
+
Default is unset for RFC 2307 servers (disabled) and `true` for
-Active Directory.
+Active Directory and FreeIPA.
[[ldap.groupBase]]ldap.groupBase::
+
@@ -2895,7 +2903,7 @@
`${groupname}` is replaced with the search term supplied by the
group owner.
+
-Default is `(cn=${groupname})` for RFC 2307,
+Default is `(cn=${groupname})` for FreeIPA and RFC 2307 servers,
and `(&(objectClass=group)(cn=${groupname}))` for Active Directory.
[[ldap.groupMemberPattern]]ldap.groupMemberPattern::
@@ -2913,7 +2921,7 @@
Attributes such as `${dn}` or `${uidNumber}` may be useful.
+
Default is `(|(memberUid=${username})(gidNumber=${gidNumber}))` for
-RFC 2307, and unset (disabled) for Active Directory.
+RFC 2307, and unset (disabled) for Active Directory and FreeIPA.
[[ldap.groupName]]ldap.groupName::
+
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/auth/ldap/Helper.java b/gerrit-server/src/main/java/com/google/gerrit/server/auth/ldap/Helper.java
index 354dc62..1e45387 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/auth/ldap/Helper.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/auth/ldap/Helper.java
@@ -276,7 +276,8 @@
private void recursivelyExpandGroups(final Set<String> groupDNs,
final LdapSchema schema, final DirContext ctx, final String groupDN) {
- if (groupDNs.add(groupDN) && schema.accountMemberField != null) {
+ 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.
@@ -319,6 +320,7 @@
final ParameterizedString accountEmailAddress;
final ParameterizedString accountSshUserName;
final String accountMemberField;
+ final boolean accountMemberExpandGroups;
final String[] accountMemberFieldArray;
final List<LdapQuery> accountQueryList;
final List<LdapQuery> accountWithMemberOfQueryList;
@@ -390,6 +392,9 @@
} else {
accountMemberFieldArray = null;
}
+ accountMemberExpandGroups =
+ LdapRealm.optional(config, "accountMemberExpandGroups",
+ type.accountMemberExpandGroups());
final SearchScope accountScope = LdapRealm.scope(config, "accountScope");
final String accountPattern =
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/auth/ldap/LdapType.java b/gerrit-server/src/main/java/com/google/gerrit/server/auth/ldap/LdapType.java
index 3c1b0d2..4e68653 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/auth/ldap/LdapType.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/auth/ldap/LdapType.java
@@ -30,6 +30,11 @@
return new ActiveDirectory();
}
+ supported = rootAtts.get("supportedExtension");
+ if (supported != null && supported.contains("2.16.840.1.113730.3.8.10.1")) {
+ return new FreeIPA();
+ }
+
return RFC_2307;
}
@@ -47,6 +52,8 @@
abstract String accountMemberField();
+ abstract boolean accountMemberExpandGroups();
+
abstract String accountPattern();
private static class Rfc2307 extends LdapType {
@@ -89,6 +96,11 @@
String accountPattern() {
return "(uid=${username})";
}
+
+ @Override
+ boolean accountMemberExpandGroups() {
+ return true;
+ }
}
private static class ActiveDirectory extends LdapType {
@@ -131,5 +143,58 @@
String accountPattern() {
return "(&(objectClass=user)(sAMAccountName=${username}))";
}
+
+ @Override
+ boolean accountMemberExpandGroups() {
+ return true;
+ }
+ }
+
+ private static class FreeIPA extends LdapType {
+
+ @Override
+ String groupPattern() {
+ return "(cn=${groupname})";
+ }
+
+ @Override
+ String groupName() {
+ return "cn";
+ }
+
+ @Override
+ String groupMemberPattern() {
+ return null; // FreeIPA uses memberOf in the account
+ }
+
+ @Override
+ String accountFullName() {
+ return "displayName";
+ }
+
+ @Override
+ String accountEmailAddress() {
+ return "mail";
+ }
+
+ @Override
+ String accountSshUserName() {
+ return "uid";
+ }
+
+ @Override
+ String accountMemberField() {
+ return "memberOf";
+ }
+
+ @Override
+ String accountPattern() {
+ return "(uid=${username})";
+ }
+
+ @Override
+ boolean accountMemberExpandGroups() {
+ return false;
+ }
}
}