}
// gather roles from other referentials
- List<String> allRoles = new ArrayList<>(Arrays.asList(rawAuthorization.getRoles()));
+ List<String> rawRoles = Arrays.asList(rawAuthorization.getRoles());
+ List<String> allRoles = new ArrayList<>(rawRoles);
for (LdapName otherBaseDn : businessRoles.keySet()) {
if (otherBaseDn.equals(userReferentialOfThisUser.getBaseDn()))
continue;
DirectoryUserAdmin otherUserAdmin = userAdminToUse(user, businessRoles.get(otherBaseDn));
if (otherUserAdmin == null)
continue;
- Authorization auth = otherUserAdmin.getAuthorization(retrievedUser);
- allRoles.addAll(Arrays.asList(auth.getRoles()));
+ for (String roleStr : rawRoles) {
+ User role = (User) findUserAdmin(roleStr).getRole(roleStr);
+ Authorization auth = otherUserAdmin.getAuthorization(role);
+ allRoles.addAll(Arrays.asList(auth.getRoles()));
+ }
}
/** Decide whether to scope or not */
private DirectoryUserAdmin userAdminToUse(User user, DirectoryUserAdmin userAdmin) {
+ if (userAdmin.isAuthenticated())
+ return userAdmin;
if (user instanceof DirectoryUser) {
return userAdmin;
} else if (user instanceof AuthenticatingUser) {
import static org.argeo.util.naming.LdapObjs.top;
import java.net.URI;
-import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Optional;
import java.util.StringJoiner;
+import javax.naming.Context;
import javax.naming.InvalidNameException;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
private LdapDirectoryDao directoryDao;
+ /** Whether the the directory has is authenticated via a service user. */
+ private boolean authenticated = false;
+
public AbstractLdapDirectory(URI uriArg, Dictionary<String, ?> props, boolean scoped) {
this.configProperties = new Hashtable<String, Object>();
for (Enumeration<String> keys = props.keys(); keys.hasMoreElements();) {
if (DirectoryConf.SCHEME_LDAP.equals(u.getScheme())
|| DirectoryConf.SCHEME_LDAPS.equals(u.getScheme())) {
directoryDao = new LdapDao(this);
+ authenticated = configProperties.get(Context.SECURITY_PRINCIPAL) != null;
} else if (DirectoryConf.SCHEME_FILE.equals(u.getScheme())) {
directoryDao = new LdifDao(this);
+ authenticated = true;
} else if (DirectoryConf.SCHEME_OS.equals(u.getScheme())) {
directoryDao = new OsUserDirectory(this);
+ authenticated = true;
// singleUser = true;
} else {
throw new IllegalArgumentException("Unsupported scheme " + u.getScheme());
for (int i = 0; i < segments.length; i++) {
String segment = segments[i];
// TODO make attr names configurable ?
- String attr = path.startsWith("accounts/")/* IPA */ ? LdapAttrs.cn.name() : LdapAttrs.ou.name();
+ String attr = getDirectory().getRealm().isPresent()/* IPA */ ? LdapAttrs.cn.name()
+ : LdapAttrs.ou.name();
if (parentRdn != null) {
if (getUserBaseRdn().equals(parentRdn))
attr = LdapAttrs.uid.name();
return disabled;
}
+ public boolean isAuthenticated() {
+ return authenticated;
+ }
+
public Rdn getUserBaseRdn() {
return userBaseRdn;
}
package org.argeo.util.directory.ldap;
-import javax.naming.directory.Attributes;
import javax.naming.ldap.LdapName;
+/** Base class for LDAP/LDIF directory DAOs. */
public abstract class AbstractLdapDirectoryDao implements LdapDirectoryDao {
private AbstractLdapDirectory directory;
public AbstractLdapDirectoryDao(AbstractLdapDirectory directory) {
this.directory = directory;
-
}
public AbstractLdapDirectory getDirectory() {
private final LdapName dn;
-// private Attributes publishedAttributes;
-
- // Temporarily expose the fields
private AttributeDictionary properties;
private AttributeDictionary credentials;
+// private String primaryObjectClass;
+// private List<String> objectClasses = new ArrayList<>();
+
protected DefaultLdapEntry(AbstractLdapDirectory directory, LdapName dn) {
Objects.requireNonNull(directory);
Objects.requireNonNull(dn);
this.directory = directory;
this.dn = dn;
-// this.publishedAttributes = attributes;
-// properties = new AttributeDictionary(false);
-// credentials = new AttributeDictionary(true);
+
+ // Object classes
+// Objects.requireNonNull(initialAttributes);
+// try {
+// NamingEnumeration<?> en = initialAttributes.get(LdapAttrs.objectClass.name()).getAll();
+// String first = null;
+// attrs: while (en.hasMore()) {
+// String v = en.next().toString();
+// if (v.equalsIgnoreCase(LdapObjs.top.name()))
+// continue attrs;
+// if (first == null)
+// first = v;
+// if (v.equalsIgnoreCase(getDirectory().getUserObjectClass()))
+// primaryObjectClass = getDirectory().getUserObjectClass();
+// else if (v.equalsIgnoreCase(getDirectory().getGroupObjectClass()))
+// primaryObjectClass = getDirectory().getGroupObjectClass();
+// objectClasses.add(v);
+// }
+// if (primaryObjectClass == null) {
+// if (first == null)
+// throw new IllegalStateException("Could not find primary object class");
+// primaryObjectClass = first;
+// }
+// } catch (NamingException e) {
+// throw new IllegalStateException("Cannot find object classes", e);
+// }
+
}
@Override
}
public synchronized Attributes getAttributes() {
-// // lazy loading
-// if (publishedAttributes == null)
-// publishedAttributes = getDirectory().getDirectoryDao().doGetAttributes(dn);
return isEditing() ? getModifiedAttributes() : getDirectory().getDirectoryDao().doGetAttributes(dn);
}
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
+import java.util.StringJoiner;
import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
-import javax.naming.ldap.Rdn;
import org.argeo.util.directory.DirectoryConf;
import org.argeo.util.naming.LdapAttrs;
public final static String IPA_USER_BASE = "cn=users";
public final static String IPA_GROUP_BASE = "cn=groups";
public final static String IPA_ROLE_BASE = "cn=roles";
- public final static String IPA_SERVICE_BASE = "cn=services,cn=accounts";
+ public final static String IPA_SERVICE_BASE = "cn=services";
- public final static Rdn IPA_ACCOUNTS_RDN;
- static {
- try {
- IPA_ACCOUNTS_RDN = new Rdn(LdapAttrs.cn.name(), "accounts");
- } catch (InvalidNameException e) {
- // should not happen
- throw new IllegalStateException(e);
- }
- }
+ public final static String IPA_ACCOUNTS_BASE = "cn=accounts";
private final static String KRB_PRINCIPAL_NAME = LdapAttrs.krbPrincipalName.name().toLowerCase();
public static String domainToBaseDn(String domain) {
String[] dcs = domain.split("\\.");
- StringBuilder sb = new StringBuilder();
+ StringJoiner sj = new StringJoiner(",");
for (int i = 0; i < dcs.length; i++) {
- if (i != 0)
- sb.append(',');
String dc = dcs[i];
- sb.append(LdapAttrs.dc.name()).append('=').append(dc.toLowerCase());
+ sj.add(LdapAttrs.dc.name() + '=' + dc.toLowerCase());
}
- return sb.toString();
+ return IPA_ACCOUNTS_BASE + ',' + sj.toString();
}
public static LdapName kerberosToDn(String kerberosName) {
String baseDn = domainToBaseDn(kname[1]);
String dn;
if (!username.contains("/"))
- dn = LdapAttrs.uid + "=" + username + "," + IPA_USER_BASE + "," + IPA_ACCOUNTS_RDN + "," + baseDn;
+ dn = LdapAttrs.uid + "=" + username + "," + IPA_USER_BASE + "," + baseDn;
else
dn = KRB_PRINCIPAL_NAME + "=" + kerberosName + "," + IPA_SERVICE_BASE + "," + baseDn;
try {
public Iterable<HierarchyUnit> doGetDirectHierarchyUnits(LdapName searchBase, boolean functionalOnly) {
List<HierarchyUnit> res = new ArrayList<>();
try {
+ String structuralFilter = functionalOnly ? ""
+ : "(" + getDirectory().getUserBaseRdn() + ")(" + getDirectory().getGroupBaseRdn() + ")("
+ + getDirectory().getSystemRoleBaseRdn() + ")";
String searchFilter = "(|(" + objectClass + "=" + LdapObjs.organizationalUnit.name() + ")(" + objectClass
- + "=" + LdapObjs.organization.name() + "))";
-// String searchFilter = "(|(" + objectClass + "=" + LdapObjs.organizationalUnit.name() + ")(" + objectClass
-// + "=" + LdapObjs.organization.name() + ")(cn=accounts)(cn=users)(cn=groups))";
+ + "=" + LdapObjs.organization.name() + ")" + structuralFilter + ")";
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
import org.argeo.util.directory.HierarchyUnit;
import org.argeo.util.transaction.WorkingCopyProcessor;
+/** Low-level access to an LDAP/LDIF directory. */
public interface LdapDirectoryDao extends WorkingCopyProcessor<LdapEntryWorkingCopy> {
boolean checkConnection();