X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.enterprise%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fuseradmin%2FUserAdminConf.java;h=19426b6c5c072a8ee22108d22429597e0e1aa8a8;hb=5d39143d7ea77173300af60264d191101e310902;hp=eef527b00167e94b4a6e4b1a4fd900076f241f5c;hpb=a2ad417ed1d0219ac29d70ae985939764c13ce38;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/UserAdminConf.java b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/UserAdminConf.java index eef527b00..19426b6c5 100644 --- a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/UserAdminConf.java +++ b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/UserAdminConf.java @@ -1,19 +1,22 @@ package org.argeo.osgi.useradmin; -import java.io.UnsupportedEncodingException; +import java.io.IOException; +import java.net.InetAddress; import java.net.URI; import java.net.URISyntaxException; -import java.net.URLDecoder; import java.util.Dictionary; import java.util.Enumeration; import java.util.Hashtable; -import java.util.LinkedHashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.naming.Context; +import javax.naming.NamingException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.naming.DnsBrowser; +import org.argeo.naming.NamingUtils; import org.osgi.framework.Constants; /** Properties used to configure user admins. */ @@ -37,9 +40,13 @@ public enum UserAdminConf { groupBase("ou=Groups"), /** Read-only source */ - readOnly(null); + readOnly(null), + + /** Authentication realm */ + realm(null); public final static String FACTORY_PID = "org.argeo.osgi.useradmin.config"; + private final static Log log = LogFactory.getLog(UserAdminConf.class); /** The default value. */ private Object def; @@ -117,7 +124,12 @@ public enum UserAdminConf { Hashtable res = new Hashtable(); URI u = new URI(uriStr); String scheme = u.getScheme(); + if (scheme != null && scheme.equals("ipa")) { + u = convertIpaConfig(u); + scheme = u.getScheme(); + } String path = u.getPath(); + // base DN String bDn = path.substring(path.lastIndexOf('/') + 1, path.length()); if (bDn.endsWith(".ldif")) bDn = bDn.substring(0, bDn.length() - ".ldif".length()); @@ -133,9 +145,10 @@ public enum UserAdminConf { credentials = userInfo.length > 1 ? userInfo[1] : null; } } else if (scheme.equals("file")) { + } else if (scheme.equals("ipa")) { } else throw new UserDirectoryException("Unsupported scheme " + scheme); - Map> query = splitQuery(u.getQuery()); + Map> query = NamingUtils.queryToMap(u); for (String key : query.keySet()) { UserAdminConf ldapProp = UserAdminConf.valueOf(key); List values = query.get(key); @@ -150,7 +163,7 @@ public enum UserAdminConf { res.put(Context.SECURITY_PRINCIPAL, principal); if (credentials != null) res.put(Context.SECURITY_CREDENTIALS, credentials); - if (scheme != null) { + if (scheme != null) {// relative URIs are dealt with externally URI bareUri = new URI(scheme, null, u.getHost(), u.getPort(), scheme.equals("file") ? u.getPath() : null, null, null); res.put(uri.name(), bareUri.toString()); @@ -161,24 +174,72 @@ public enum UserAdminConf { } } - private static Map> splitQuery(String query) throws UnsupportedEncodingException { - final Map> query_pairs = new LinkedHashMap>(); - if (query == null) - return query_pairs; - final String[] pairs = query.split("&"); - for (String pair : pairs) { - final int idx = pair.indexOf("="); - final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair; - if (!query_pairs.containsKey(key)) { - query_pairs.put(key, new LinkedList()); + private static URI convertIpaConfig(URI uri) { + String path = uri.getPath(); + String kerberosRealm; + if (path == null || path.length() <= 1) { + kerberosRealm = kerberosDomainFromDns(); + } else { + kerberosRealm = path.substring(1); + } + + if (kerberosRealm == null) + throw new UserDirectoryException("No Kerberos domain available for " + uri); + try (DnsBrowser dnsBrowser = new DnsBrowser()) { + String ldapHostsStr = uri.getHost(); + if (ldapHostsStr == null || ldapHostsStr.trim().equals("")) { + List ldapHosts = dnsBrowser.getSrvRecordsAsHosts("_ldap._tcp." + kerberosRealm.toLowerCase()); + if (ldapHosts == null || ldapHosts.size() == 0) { + throw new UserDirectoryException("Cannot configure LDAP for IPA " + uri); + } else { + ldapHostsStr = ldapHosts.get(0); + } } - final String value = idx > 0 && pair.length() > idx + 1 - ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null; - query_pairs.get(key).add(value); + URI convertedUri = new URI( + "ldap://" + ldapHostsStr + "/" + IpaUtils.domainToUserDirectoryConfigPath(kerberosRealm)); + if (log.isDebugEnabled()) + log.debug("Converted " + uri + " to " + convertedUri); + return convertedUri; + } catch (NamingException | IOException | URISyntaxException e) { + throw new UserDirectoryException("cannot convert IPA uri " + uri, e); } - return query_pairs; } + private static String kerberosDomainFromDns() { + String kerberosDomain; + try (DnsBrowser dnsBrowser = new DnsBrowser()) { + InetAddress localhost = InetAddress.getLocalHost(); + String hostname = localhost.getHostName(); + String dnsZone = hostname.substring(hostname.indexOf('.') + 1); + kerberosDomain = dnsBrowser.getRecord("_kerberos." + dnsZone, "TXT"); + return kerberosDomain; + } catch (Exception e) { + throw new UserDirectoryException("Cannot determine Kerberos domain from DNS", e); + } + + } + + // private static Map> splitQuery(String query) throws + // UnsupportedEncodingException { + // final Map> query_pairs = new LinkedHashMap>(); + // if (query == null) + // return query_pairs; + // final String[] pairs = query.split("&"); + // for (String pair : pairs) { + // final int idx = pair.indexOf("="); + // final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), + // "UTF-8") : pair; + // if (!query_pairs.containsKey(key)) { + // query_pairs.put(key, new LinkedList()); + // } + // final String value = idx > 0 && pair.length() > idx + 1 + // ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null; + // query_pairs.get(key).add(value); + // } + // return query_pairs; + // } + public static void main(String[] args) { Dictionary props = uriAsProperties("ldap://" + "uid=admin,ou=system:secret@localhost:10389" + "/dc=example,dc=com" + "?readOnly=false&userObjectClass=person");