Skip to content

Commit

Permalink
gplazma: ldap plugin: recreate dir context
Browse files Browse the repository at this point in the history
In some environments the connection between gPlazma and the ldap
server may be closed by an existing firewall (e.g., at DESY).
This patch changes the DirContext from being final to a newly
created one on every call.

Acked-by:
Target: 2.6
Request: 2.6-cloud
Require-book: no
Require-notes: no
  • Loading branch information
Karsten Schwank committed Oct 24, 2013
1 parent a76f036 commit 290fa3d
Showing 1 changed file with 61 additions and 31 deletions.
Expand Up @@ -8,9 +8,9 @@
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;

import java.security.Principal;
import java.util.HashSet;
Expand Down Expand Up @@ -79,6 +79,12 @@ public class Ldap implements GPlazmaIdentityPlugin, GPlazmaSessionPlugin, GPlazm
static final String LDAP_GROUP_TREE = "gplazma.ldap.tree.groups";
static final String LDAP_USER_FILTER = "gplazma.ldap.userfilter";

/**
* The ldap properties
*/
private final String server;
private final String port;

/**
* The OU (organizational unit) to add users to
*/
Expand All @@ -91,49 +97,38 @@ public class Ldap implements GPlazmaIdentityPlugin, GPlazmaSessionPlugin, GPlazm
* The search filter to use to locate a user's entry in the LDAP directory.
*/
private final String userFilter;
private final InitialDirContext _ctx;

/**
* Create a NIS identity plugin.
*
* @throws NamingException
*/
public Ldap(Properties properties) throws NamingException {
public Ldap(Properties properties) {

String server = properties.getProperty(LDAP_SERVER);
String port = properties.getProperty(LDAP_PORT);
server = properties.getProperty(LDAP_SERVER);
port = properties.getProperty(LDAP_PORT);
String organization = properties.getProperty(LDAP_ORG);
String peopleTree = properties.getProperty(LDAP_PEOPLE_TREE);
String groupTree = properties.getProperty(LDAP_GROUP_TREE);
userFilter = properties.getProperty(LDAP_USER_FILTER);


peopleOU = String.format("ou=%s,%s", peopleTree, organization);
groupOU = String.format("ou=%s,%s", groupTree, organization);

Properties env = new Properties();
env.put(DirContext.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(DirContext.PROVIDER_URL, String.format("ldap://%s:%s", server, port));

_ctx = new InitialDirContext(env);
}

@Override
public void map(Set<Principal> principals) throws AuthenticationException {
Principal principal =
find(principals, instanceOf(UserNamePrincipal.class), null);
if (principal != null) {
try {
NamingEnumeration<SearchResult> sResult = _ctx.search(peopleOU,
try (ClosableContext ctx = new ClosableContext()) {
NamingEnumeration<SearchResult> sResult = ctx.get().search(peopleOU,
String.format(userFilter, principal.getName()),
getSimplSearchControls(UID_NUMBER_ATTRIBUTE, GID_NUMBER_ATTRIBUTE));
if (sResult.hasMore()) {
Attributes userAttr = sResult.next().getAttributes();
principals.add(new UidPrincipal((String) userAttr.get(UID_NUMBER_ATTRIBUTE).get()));
principals.add(new GidPrincipal((String) userAttr.get(GID_NUMBER_ATTRIBUTE).get(), true));

NamingEnumeration<SearchResult> groupResult = _ctx.search(groupOU,
NamingEnumeration<SearchResult> groupResult = ctx.get().search(groupOU,
new BasicAttributes(MEMBER_UID_ATTRIBUTE, principal.getName()));
while (groupResult.hasMore()) {
SearchResult result = groupResult.next();
Expand All @@ -142,7 +137,7 @@ public void map(Set<Principal> principals) throws AuthenticationException {
}
}
} catch (NamingException e) {
_log.warn("Faild to get mapping: {}", e.toString());
_log.warn("Failed to get mapping: {}", e.toString());
}
}
}
Expand All @@ -151,18 +146,18 @@ public void map(Set<Principal> principals) throws AuthenticationException {
public Principal map(Principal principal) throws NoSuchPrincipalException {

String name = principal.getName();
try {
try (ClosableContext ctx = new ClosableContext()) {
NamingEnumeration<SearchResult> sResult;
if (principal instanceof UserNamePrincipal) {
sResult = _ctx.search(peopleOU,
sResult = ctx.get().search(peopleOU,
String.format("(%s=%s)", USER_ID_ATTRIBUTE, name),
getSimplSearchControls(UID_NUMBER_ATTRIBUTE));
if (sResult.hasMore()) {
SearchResult rs = sResult.next();
return new UidPrincipal((String) rs.getAttributes().get(UID_NUMBER_ATTRIBUTE).get());
}
} else if (principal instanceof GroupNamePrincipal) {
sResult = _ctx.search(groupOU,
sResult = ctx.get().search(groupOU,
String.format("(%s=%s)", COMMON_NAME_ATTRIBUTE, name),
getSimplSearchControls(GID_NUMBER_ATTRIBUTE));
if (sResult.hasMore()) {
Expand All @@ -172,20 +167,20 @@ public Principal map(Principal principal) throws NoSuchPrincipalException {
}

} catch (NamingException e) {
_log.warn("Faild to get mapping: {}", e.toString());
_log.warn("Failed to get mapping: {}", e.toString());
}
throw new NoSuchPrincipalException(principal);
}

@Override
public Set<Principal> reverseMap(Principal principal) throws NoSuchPrincipalException {
String id = principal.getName();
try {
try (ClosableContext ctx = new ClosableContext()) {

Set<Principal> principals = new HashSet<>();

if (principal instanceof GidPrincipal) {
NamingEnumeration<SearchResult> ne = _ctx.search(groupOU,
NamingEnumeration<SearchResult> ne = ctx.get().search(groupOU,
new BasicAttributes(GID_NUMBER_ATTRIBUTE, id));


Expand All @@ -195,7 +190,7 @@ public Set<Principal> reverseMap(Principal principal) throws NoSuchPrincipalExce
principals.add(new GroupNamePrincipal(name));
}
} else if (principal instanceof UidPrincipal) {
NamingEnumeration<SearchResult> ne = _ctx.search(peopleOU,
NamingEnumeration<SearchResult> ne = ctx.get().search(peopleOU,
new BasicAttributes(UID_NUMBER_ATTRIBUTE, id));


Expand All @@ -207,7 +202,7 @@ public Set<Principal> reverseMap(Principal principal) throws NoSuchPrincipalExce
}
return principals;
} catch (NamingException e) {
_log.warn("Faild to get reverse mapping: {}", e.toString());
_log.warn("Failed to get reverse mapping: {}", e.toString());
}
throw new NoSuchPrincipalException(principal);
}
Expand All @@ -217,8 +212,8 @@ public void session(Set<Principal> authorizedPrincipals, Set<Object> attrib) thr
Principal principal =
find(authorizedPrincipals, instanceOf(UserNamePrincipal.class), null);
if (principal != null) {
try {
NamingEnumeration<?> sResult = _ctx.search(peopleOU,
try (ClosableContext ctx = new ClosableContext()) {
NamingEnumeration<?> sResult = ctx.get().search(peopleOU,
String.format(userFilter, principal.getName()),
getSimplSearchControls(HOME_DIR_ATTRIBUTE));
if (sResult.hasMore()) {
Expand All @@ -237,11 +232,46 @@ public void session(Set<Principal> authorizedPrincipals, Set<Object> attrib) thr
private SearchControls getSimplSearchControls(String... attr) {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String attrList[] = attr;
constraints.setReturningAttributes(attrList);
constraints.setReturningAttributes(attr);
return constraints;
}

private class ClosableContext implements AutoCloseable {

private DirContext _ctx;

public DirContext get() {
return _ctx;
}

public ClosableContext() throws NamingException {
_ctx = newContext();
}

@Override
public void close() {
try {
if (_ctx != null) {
_ctx.close();
}
} catch (NamingException ignore) { }
}

/**
* Creates a DirContext with a new connection from the plugin's
* configuration properties.
* @throws NamingException
*/
private DirContext newContext() throws NamingException {
Properties env = new Properties();
env.put(DirContext.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(DirContext.PROVIDER_URL, String.format("ldap://%s:%s", server, port));

return new InitialLdapContext(env, null);
}
}

public static void main(String[] args) throws NamingException, AuthenticationException, NoSuchPrincipalException {
Properties properties = new Properties();
properties.setProperty(LDAP_SERVER, "seds2.desy.de");
Expand Down

0 comments on commit 290fa3d

Please sign in to comment.