import java.util.ArrayList;
import java.util.Dictionary;
-import java.util.Hashtable;
import java.util.List;
+import javax.naming.AuthenticationNotSupportedException;
import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.InvalidNameException;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
-import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
-import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapName;
-import javax.transaction.TransactionManager;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.naming.LdapAttrs;
import org.osgi.framework.Filter;
import org.osgi.service.useradmin.Role;
import org.osgi.service.useradmin.User;
-/**
- * A user admin based on a LDAP server. Requires a {@link TransactionManager}
- * and an open transaction for write access.
- */
+/** A user admin based on a LDAP server. */
public class LdapUserAdmin extends AbstractUserDirectory {
- private final static Log log = LogFactory.getLog(LdapUserAdmin.class);
-
- private InitialLdapContext initialLdapContext = null;
+ private LdapConnection ldapConnection;
public LdapUserAdmin(Dictionary<String, ?> properties) {
- super(null, properties);
- try {
- Hashtable<String, Object> connEnv = new Hashtable<String, Object>();
- connEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
- connEnv.put(Context.PROVIDER_URL, getUri().toString());
- connEnv.put("java.naming.ldap.attributes.binary", LdapAttrs.userPassword.name());
-
- initialLdapContext = new InitialLdapContext(connEnv, null);
- // StartTlsResponse tls = (StartTlsResponse) ctx
- // .extendedOperation(new StartTlsRequest());
- // tls.negotiate();
- Object securityAuthentication = properties.get(Context.SECURITY_AUTHENTICATION);
- if (securityAuthentication != null)
- initialLdapContext.addToEnvironment(Context.SECURITY_AUTHENTICATION, securityAuthentication);
- else
- initialLdapContext.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
- Object principal = properties.get(Context.SECURITY_PRINCIPAL);
- if (principal != null) {
- initialLdapContext.addToEnvironment(Context.SECURITY_PRINCIPAL, principal.toString());
- Object creds = properties.get(Context.SECURITY_CREDENTIALS);
- if (creds != null) {
- initialLdapContext.addToEnvironment(Context.SECURITY_CREDENTIALS, creds.toString());
+ this(properties, false);
+ }
- }
- }
- } catch (Exception e) {
- throw new UserDirectoryException("Cannot connect to LDAP", e);
- }
+ public LdapUserAdmin(Dictionary<String, ?> properties, boolean scoped) {
+ super(null, properties, scoped);
+ ldapConnection = new LdapConnection(getUri().toString(), properties);
}
public void destroy() {
- try {
- // tls.close();
- initialLdapContext.close();
- } catch (NamingException e) {
- log.error("Cannot destroy LDAP user admin", e);
- }
+ ldapConnection.destroy();
}
@Override
} else {
properties.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
}
- return new LdapUserAdmin(properties);
+ return new LdapUserAdmin(properties, true);
}
- protected InitialLdapContext getLdapContext() {
- return initialLdapContext;
- }
+// protected InitialLdapContext getLdapContext() {
+// return initialLdapContext;
+// }
@Override
protected Boolean daoHasRole(LdapName dn) {
@Override
protected DirectoryUser daoGetRole(LdapName name) throws NameNotFoundException {
try {
- Attributes attrs = getLdapContext().getAttributes(name);
+ Attributes attrs = ldapConnection.getAttributes(name);
if (attrs.size() == 0)
return null;
int roleType = roleType(name);
} catch (NameNotFoundException e) {
throw e;
} catch (NamingException e) {
- if (log.isTraceEnabled())
- log.error("Cannot get role: " + name, e);
return null;
}
}
@Override
protected List<DirectoryUser> doGetRoles(Filter f) {
+ ArrayList<DirectoryUser> res = new ArrayList<DirectoryUser>();
try {
String searchFilter = f != null ? f.toString()
: "(|(" + objectClass + "=" + getUserObjectClass() + ")(" + objectClass + "="
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
LdapName searchBase = getBaseDn();
- NamingEnumeration<SearchResult> results = getLdapContext().search(searchBase, searchFilter, searchControls);
+ NamingEnumeration<SearchResult> results = ldapConnection.search(searchBase, searchFilter, searchControls);
- ArrayList<DirectoryUser> res = new ArrayList<DirectoryUser>();
results: while (results.hasMoreElements()) {
SearchResult searchResult = results.next();
Attributes attrs = searchResult.getAttributes();
|| objectClassAttr.contains(getUserObjectClass().toLowerCase()))
role = new LdifUser(this, dn, attrs);
else {
- log.warn("Unsupported LDAP type for " + searchResult.getName());
+// log.warn("Unsupported LDAP type for " + searchResult.getName());
continue results;
}
res.add(role);
}
return res;
+ } catch (AuthenticationNotSupportedException e) {
+ // ignore (typically an unsupported anonymous bind)
+ // TODO better logging
+ return res;
} catch (Exception e) {
+ e.printStackTrace();
throw new UserDirectoryException("Cannot get roles for filter " + f, e);
}
}
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
LdapName searchBase = getBaseDn();
- NamingEnumeration<SearchResult> results = getLdapContext().search(searchBase, searchFilter, searchControls);
+ NamingEnumeration<SearchResult> results = ldapConnection.search(searchBase, searchFilter, searchControls);
while (results.hasMoreElements()) {
SearchResult searchResult = (SearchResult) results.nextElement();
@Override
protected void prepare(UserDirectoryWorkingCopy wc) {
try {
- getLdapContext().reconnect(getLdapContext().getConnectControls());
- // delete
- for (LdapName dn : wc.getDeletedUsers().keySet()) {
- if (!entryExists(dn))
- throw new UserDirectoryException("User to delete no found " + dn);
- }
- // add
- for (LdapName dn : wc.getNewUsers().keySet()) {
- if (entryExists(dn))
- throw new UserDirectoryException("User to create found " + dn);
- }
- // modify
- for (LdapName dn : wc.getModifiedUsers().keySet()) {
- if (!wc.getNewUsers().containsKey(dn) && !entryExists(dn))
- throw new UserDirectoryException("User to modify not found " + dn);
- }
+ ldapConnection.prepareChanges(wc);
} catch (NamingException e) {
throw new UserDirectoryException("Cannot prepare LDAP", e);
}
}
- private boolean entryExists(LdapName dn) throws NamingException {
- try {
- return getLdapContext().getAttributes(dn).size() != 0;
- } catch (NameNotFoundException e) {
- return false;
- }
- }
-
@Override
protected void commit(UserDirectoryWorkingCopy wc) {
try {
- // delete
- for (LdapName dn : wc.getDeletedUsers().keySet()) {
- getLdapContext().destroySubcontext(dn);
- }
- // add
- for (LdapName dn : wc.getNewUsers().keySet()) {
- DirectoryUser user = wc.getNewUsers().get(dn);
- getLdapContext().createSubcontext(dn, user.getAttributes());
- }
- // modify
- for (LdapName dn : wc.getModifiedUsers().keySet()) {
- Attributes modifiedAttrs = wc.getModifiedUsers().get(dn);
- getLdapContext().modifyAttributes(dn, DirContext.REPLACE_ATTRIBUTE, modifiedAttrs);
- }
+ ldapConnection.commitChanges(wc);
} catch (NamingException e) {
throw new UserDirectoryException("Cannot commit LDAP", e);
}