1 package org
.argeo
.osgi
.useradmin
;
3 import java
.io
.IOException
;
4 import java
.net
.InetAddress
;
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
;
12 import javax
.naming
.InvalidNameException
;
13 import javax
.naming
.NamingException
;
14 import javax
.naming
.ldap
.LdapName
;
16 import org
.argeo
.util
.naming
.DnsBrowser
;
17 import org
.argeo
.util
.naming
.LdapAttrs
;
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_SERVICE_BASE
= "cn=services,cn=accounts";
25 private final static String KRB_PRINCIPAL_NAME
= LdapAttrs
.krbPrincipalName
.name().toLowerCase();
27 public final static String IPA_USER_DIRECTORY_CONFIG
= UserAdminConf
.userBase
+ "=" + IPA_USER_BASE
+ "&"
28 + UserAdminConf
.groupBase
+ "=" + IPA_GROUP_BASE
+ "&" + UserAdminConf
.readOnly
+ "=true";
31 static String
domainToUserDirectoryConfigPath(String realm
) {
32 return domainToBaseDn(realm
) + "?" + IPA_USER_DIRECTORY_CONFIG
+ "&" + UserAdminConf
.realm
.name() + "=" + realm
;
35 public static void addIpaConfig(String realm
, Dictionary
<String
, Object
> properties
) {
36 properties
.put(UserAdminConf
.baseDn
.name(), domainToBaseDn(realm
));
37 properties
.put(UserAdminConf
.realm
.name(), realm
);
38 properties
.put(UserAdminConf
.userBase
.name(), IPA_USER_BASE
);
39 properties
.put(UserAdminConf
.groupBase
.name(), IPA_GROUP_BASE
);
40 properties
.put(UserAdminConf
.readOnly
.name(), Boolean
.TRUE
.toString());
43 public static String
domainToBaseDn(String domain
) {
44 String
[] dcs
= domain
.split("\\.");
45 StringBuilder sb
= new StringBuilder();
46 for (int i
= 0; i
< dcs
.length
; i
++) {
50 sb
.append(LdapAttrs
.dc
.name()).append('=').append(dc
.toLowerCase());
55 public static LdapName
kerberosToDn(String kerberosName
) {
56 String
[] kname
= kerberosName
.split("@");
57 String username
= kname
[0];
58 String baseDn
= domainToBaseDn(kname
[1]);
60 if (!username
.contains("/"))
61 dn
= LdapAttrs
.uid
+ "=" + username
+ "," + IPA_USER_BASE
+ "," + baseDn
;
63 dn
= KRB_PRINCIPAL_NAME
+ "=" + kerberosName
+ "," + IPA_SERVICE_BASE
+ "," + baseDn
;
65 return new LdapName(dn
);
66 } catch (InvalidNameException e
) {
67 throw new IllegalArgumentException("Badly formatted name for " + kerberosName
+ ": " + dn
);
75 public static String
kerberosDomainFromDns() {
76 String kerberosDomain
;
77 try (DnsBrowser dnsBrowser
= new DnsBrowser()) {
78 InetAddress localhost
= InetAddress
.getLocalHost();
79 String hostname
= localhost
.getHostName();
80 String dnsZone
= hostname
.substring(hostname
.indexOf('.') + 1);
81 kerberosDomain
= dnsBrowser
.getRecord("_kerberos." + dnsZone
, "TXT");
82 return kerberosDomain
;
83 } catch (Exception e
) {
84 throw new UserDirectoryException("Cannot determine Kerberos domain from DNS", e
);
89 public static Dictionary
<String
, Object
> convertIpaUri(URI uri
) {
90 String path
= uri
.getPath();
92 if (path
== null || path
.length() <= 1) {
93 kerberosRealm
= kerberosDomainFromDns();
95 kerberosRealm
= path
.substring(1);
98 if (kerberosRealm
== null)
99 throw new UserDirectoryException("No Kerberos domain available for " + uri
);
100 // TODO intergrate CA certificate in truststore
101 // String schemeToUse = SCHEME_LDAPS;
102 String schemeToUse
= UserAdminConf
.SCHEME_LDAP
;
103 List
<String
> ldapHosts
;
104 String ldapHostsStr
= uri
.getHost();
105 if (ldapHostsStr
== null || ldapHostsStr
.trim().equals("")) {
106 try (DnsBrowser dnsBrowser
= new DnsBrowser()) {
107 ldapHosts
= dnsBrowser
.getSrvRecordsAsHosts("_ldap._tcp." + kerberosRealm
.toLowerCase(),
108 schemeToUse
.equals(UserAdminConf
.SCHEME_LDAP
) ?
true : false);
109 if (ldapHosts
== null || ldapHosts
.size() == 0) {
110 throw new UserDirectoryException("Cannot configure LDAP for IPA " + uri
);
112 ldapHostsStr
= ldapHosts
.get(0);
114 } catch (NamingException
| IOException e
) {
115 throw new UserDirectoryException("cannot convert IPA uri " + uri
, e
);
118 ldapHosts
= new ArrayList
<>();
119 ldapHosts
.add(ldapHostsStr
);
122 StringBuilder uriStr
= new StringBuilder();
124 for (String host
: ldapHosts
) {
125 URI convertedUri
= new URI(schemeToUse
+ "://" + host
+ "/");
126 uriStr
.append(convertedUri
).append(' ');
128 } catch (URISyntaxException e
) {
129 throw new UserDirectoryException("cannot convert IPA uri " + uri
, e
);
132 Hashtable
<String
, Object
> res
= new Hashtable
<>();
133 res
.put(UserAdminConf
.uri
.name(), uriStr
.toString());
134 addIpaConfig(kerberosRealm
, res
);