]> git.argeo.org Git - lgpl/argeo-commons.git/blob - IpaUtils.java
e1c8136f515685ff21e1b9c1999f0bf130b1374a
[lgpl/argeo-commons.git] / IpaUtils.java
1 package org.argeo.osgi.useradmin;
2
3 import java.io.IOException;
4 import java.net.InetAddress;
5 import java.net.URI;
6 import java.net.URISyntaxException;
7 import java.util.ArrayList;
8 import java.util.Dictionary;
9 import java.util.Hashtable;
10 import java.util.List;
11
12 import javax.naming.InvalidNameException;
13 import javax.naming.NamingException;
14 import javax.naming.ldap.LdapName;
15
16 import org.argeo.util.naming.LdapAttrs;
17 import org.argeo.util.naming.dns.DnsBrowser;
18
19 /** Free IPA specific conventions. */
20 public class IpaUtils {
21 public final static String IPA_USER_BASE = "cn=users,cn=accounts";
22 public final static String IPA_GROUP_BASE = "cn=groups,cn=accounts";
23 public final static String IPA_ROLE_BASE = "cn=roles,cn=accounts";
24 public final static String IPA_SERVICE_BASE = "cn=services,cn=accounts";
25
26 private final static String KRB_PRINCIPAL_NAME = LdapAttrs.krbPrincipalName.name().toLowerCase();
27
28 public final static String IPA_USER_DIRECTORY_CONFIG = UserAdminConf.userBase + "=" + IPA_USER_BASE + "&"
29 + UserAdminConf.groupBase + "=" + IPA_GROUP_BASE + "&" + UserAdminConf.readOnly + "=true";
30
31 @Deprecated
32 static String domainToUserDirectoryConfigPath(String realm) {
33 return domainToBaseDn(realm) + "?" + IPA_USER_DIRECTORY_CONFIG + "&" + UserAdminConf.realm.name() + "=" + realm;
34 }
35
36 public static void addIpaConfig(String realm, Dictionary<String, Object> properties) {
37 properties.put(UserAdminConf.baseDn.name(), domainToBaseDn(realm));
38 properties.put(UserAdminConf.realm.name(), realm);
39 properties.put(UserAdminConf.userBase.name(), IPA_USER_BASE);
40 properties.put(UserAdminConf.groupBase.name(), IPA_GROUP_BASE);
41 properties.put(UserAdminConf.systemRoleBase.name(), IPA_ROLE_BASE);
42 properties.put(UserAdminConf.readOnly.name(), Boolean.TRUE.toString());
43 }
44
45 public static String domainToBaseDn(String domain) {
46 String[] dcs = domain.split("\\.");
47 StringBuilder sb = new StringBuilder();
48 for (int i = 0; i < dcs.length; i++) {
49 if (i != 0)
50 sb.append(',');
51 String dc = dcs[i];
52 sb.append(LdapAttrs.dc.name()).append('=').append(dc.toLowerCase());
53 }
54 return sb.toString();
55 }
56
57 public static LdapName kerberosToDn(String kerberosName) {
58 String[] kname = kerberosName.split("@");
59 String username = kname[0];
60 String baseDn = domainToBaseDn(kname[1]);
61 String dn;
62 if (!username.contains("/"))
63 dn = LdapAttrs.uid + "=" + username + "," + IPA_USER_BASE + "," + baseDn;
64 else
65 dn = KRB_PRINCIPAL_NAME + "=" + kerberosName + "," + IPA_SERVICE_BASE + "," + baseDn;
66 try {
67 return new LdapName(dn);
68 } catch (InvalidNameException e) {
69 throw new IllegalArgumentException("Badly formatted name for " + kerberosName + ": " + dn);
70 }
71 }
72
73 private IpaUtils() {
74
75 }
76
77 public static String kerberosDomainFromDns() {
78 String kerberosDomain;
79 try (DnsBrowser dnsBrowser = new DnsBrowser()) {
80 InetAddress localhost = InetAddress.getLocalHost();
81 String hostname = localhost.getHostName();
82 String dnsZone = hostname.substring(hostname.indexOf('.') + 1);
83 kerberosDomain = dnsBrowser.getRecord("_kerberos." + dnsZone, "TXT");
84 return kerberosDomain;
85 } catch (NamingException | IOException e) {
86 throw new IllegalStateException("Cannot determine Kerberos domain from DNS", e);
87 }
88
89 }
90
91 public static Dictionary<String, Object> convertIpaUri(URI uri) {
92 String path = uri.getPath();
93 String kerberosRealm;
94 if (path == null || path.length() <= 1) {
95 kerberosRealm = kerberosDomainFromDns();
96 } else {
97 kerberosRealm = path.substring(1);
98 }
99
100 if (kerberosRealm == null)
101 throw new IllegalStateException("No Kerberos domain available for " + uri);
102 // TODO intergrate CA certificate in truststore
103 // String schemeToUse = SCHEME_LDAPS;
104 String schemeToUse = UserAdminConf.SCHEME_LDAP;
105 List<String> ldapHosts;
106 String ldapHostsStr = uri.getHost();
107 if (ldapHostsStr == null || ldapHostsStr.trim().equals("")) {
108 try (DnsBrowser dnsBrowser = new DnsBrowser()) {
109 ldapHosts = dnsBrowser.getSrvRecordsAsHosts("_ldap._tcp." + kerberosRealm.toLowerCase(),
110 schemeToUse.equals(UserAdminConf.SCHEME_LDAP) ? true : false);
111 if (ldapHosts == null || ldapHosts.size() == 0) {
112 throw new IllegalStateException("Cannot configure LDAP for IPA " + uri);
113 } else {
114 ldapHostsStr = ldapHosts.get(0);
115 }
116 } catch (NamingException | IOException e) {
117 throw new IllegalStateException("Cannot convert IPA uri " + uri, e);
118 }
119 } else {
120 ldapHosts = new ArrayList<>();
121 ldapHosts.add(ldapHostsStr);
122 }
123
124 StringBuilder uriStr = new StringBuilder();
125 try {
126 for (String host : ldapHosts) {
127 URI convertedUri = new URI(schemeToUse + "://" + host + "/");
128 uriStr.append(convertedUri).append(' ');
129 }
130 } catch (URISyntaxException e) {
131 throw new IllegalStateException("Cannot convert IPA uri " + uri, e);
132 }
133
134 Hashtable<String, Object> res = new Hashtable<>();
135 res.put(UserAdminConf.uri.name(), uriStr.toString());
136 addIpaConfig(kerberosRealm, res);
137 return res;
138 }
139 }