/**
* Copyright 2009 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.safehaus.penrose.apacheds;
import org.safehaus.penrose.schema.SchemaConfig;
import org.safehaus.penrose.PenroseConfig;
import org.safehaus.penrose.Penrose;
import org.safehaus.penrose.backend.PenroseBackend;
import org.safehaus.penrose.server.PenroseServer;
import org.safehaus.penrose.ldap.LDAPService;
import org.apache.directory.server.core.configuration.*;
import org.apache.directory.server.jndi.ServerContextFactory;
import org.apache.directory.server.core.jndi.CoreContextFactory;
import org.apache.directory.server.configuration.MutableServerStartupConfiguration;
import org.apache.directory.server.ldap.support.extended.GracefulShutdownHandler;
import org.apache.directory.server.ldap.support.extended.LaunchDiagnosticUiHandler;
import javax.naming.Context;
import javax.naming.directory.InitialDirContext;
import java.io.File;
import java.util.*;
import org.safehaus.penrose.ldapbackend.Backend;
import org.safehaus.penrose.ldapbackend.apacheds.LDAPBackendAuthenticator;
import org.safehaus.penrose.ldapbackend.apacheds.LDAPBackendInterceptor;
/**
* @author Endi S. Dewata
*/
public class ApacheDSService extends LDAPService {
public void init() throws Exception {
super.init();
//log.warn("Starting LDAP Service.");
if (ldapPort < 0) return;
PenroseServer penroseServer = serviceContext.getPenroseServer();
Penrose penrose = penroseServer.getPenrose();
PenroseConfig penroseConfig = penrose.getPenroseConfig();
File path = serviceContext.getPath();
Backend backend = new PenroseBackend(penroseServer);
MutableServerStartupConfiguration configuration = new MutableServerStartupConfiguration();
// Configure LDAP ports
configuration.setLdapPort(ldapPort);
configuration.setEnableLdaps(enableLdaps);
configuration.setLdapsPort(ldapsPort);
if (ldapsCertificateFile != null) configuration.setLdapsCertificateFile(new File(ldapsCertificateFile));
if (ldapsCertificatePassword != null) configuration.setLdapsCertificatePassword(ldapsCertificatePassword);
//log.debug("Allow anonymous access: "+allowAnonymousAccess);
configuration.setAllowAnonymousAccess(allowAnonymousAccess);
configuration.setMaxThreads(maxThreads);
// Configure working directory
File workingDirectory = new File(path, "var"+File.separator+"data");
configuration.setWorkingDirectory(workingDirectory);
// Configure bootstrap schemas
ClassLoader classLoader = serviceContext.getClassLoader();
Set<Object> bootstrapSchemas = new HashSet<Object>();
for (SchemaConfig schemaConfig : penroseConfig.getSchemaConfigs()) {
String name = schemaConfig.getName();
String className = "org.apache.directory.server.core.schema.bootstrap." +
name.substring(0, 1).toUpperCase() + name.substring(1) +
"Schema";
log.debug("Loading " + className);
Class clazz = classLoader.loadClass(className);
Object object = clazz.newInstance();
bootstrapSchemas.add(object);
}
configuration.setBootstrapSchemas(bootstrapSchemas);
// Configure extended operation handlers
Set<Object> extendedOperationHandlers = new HashSet<Object>();
extendedOperationHandlers.add(new GracefulShutdownHandler());
extendedOperationHandlers.add(new LaunchDiagnosticUiHandler());
configuration.setExtendedOperationHandlers(extendedOperationHandlers);
// Register Penrose authenticator
LDAPBackendAuthenticator authenticator = new LDAPBackendAuthenticator();
authenticator.setBackend(backend);
MutableAuthenticatorConfiguration authenticatorConfig = new MutableAuthenticatorConfiguration();
authenticatorConfig.setName("Penrose");
authenticatorConfig.setAuthenticator(authenticator);
Set<AuthenticatorConfiguration> authenticators = new LinkedHashSet<AuthenticatorConfiguration>();
authenticators.add(authenticatorConfig);
authenticators.addAll(configuration.getAuthenticatorConfigurations());
//Set authenticators = configuration.getAuthenticatorConfigurations();
//authenticators.add(authenticatorConfig);
configuration.setAuthenticatorConfigurations(authenticators);
log.debug("Authenticators:");
for (AuthenticatorConfiguration ac : authenticators) {
log.debug(" - " + ac.getName());
}
// Register Penrose interceptor
LDAPBackendInterceptor interceptor = new LDAPBackendInterceptor();
interceptor.setBackend(backend);
MutableInterceptorConfiguration interceptorConfig = new MutableInterceptorConfiguration();
interceptorConfig.setName("penroseService");
interceptorConfig.setInterceptor(interceptor);
List<InterceptorConfiguration> interceptors = new ArrayList<InterceptorConfiguration>();
interceptors.add(interceptorConfig);
interceptors.addAll(configuration.getInterceptorConfigurations());
configuration.setInterceptorConfigurations(interceptors);
log.debug("Interceptors:");
for (InterceptorConfiguration ic : interceptors) {
log.debug(" - " + ic.getName());
}
// Initialize ApacheDS
final Hashtable<String,Object> env = new Hashtable<String,Object>();
env.put(Context.PROVIDER_URL, "ou=system");
env.put(Context.INITIAL_CONTEXT_FACTORY, ServerContextFactory.class.getName() );
env.put(Context.SECURITY_PRINCIPAL, penroseConfig.getRootDn().toString());
env.put(Context.SECURITY_CREDENTIALS, penroseConfig.getRootPassword());
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.REFERRAL, "throw");
/*
env.setProperty("asn.1.berlib.provider", "org.apache.ldap.common.berlib.asn1.SnickersProvider");
//env.setProperty("asn.1.berlib.provider", "org.apache.asn1new.ldap.TwixProvider");
env.setProperty("java.naming.ldap.attributes.binary",
"photo personalSignature audio jpegPhoto javaSerializedData "+
"userPassword userCertificate cACertificate "+
"authorityRevocationList certificateRevocationList crossCertificatePair "+
"x500UniqueIdentifier krb5Key");
*/
String binaryAttributes = getParameter("java.naming.ldap.attributes.binary");
if (binaryAttributes != null) {
//log.debug("Setting java.naming.ldap.attributes.binary: "+binaryAttributes);
env.put("java.naming.ldap.attributes.binary", binaryAttributes);
}
env.putAll(configuration.toJndiEnvironment());
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(classLoader);
new InitialDirContext(env);
} finally {
Thread.currentThread().setContextClassLoader(currentClassLoader);
}
log.warn("Listening to port "+ldapPort+" (LDAP).");
if (enableLdaps) {
log.warn("Listening to port "+ldapsPort+" (LDAPS).");
}
// Start ApacheDS synchronization thread
/*
Thread thread = new Thread() {
public void run() {
try {
env.putAll(new SyncConfiguration().toJndiEnvironment());
while (true) {
try {
Thread.sleep(20000);
} catch ( InterruptedException e ) {
// ignore
}
new InitialDirContext(env);
}
} catch (Exception e) {
log.error(e.getMessage());
}
}
};
thread.start();
*/
}
public void destroy() throws Exception {
if (ldapPort < 0) return;
Penrose penrose = serviceContext.getPenroseServer().getPenrose();
PenroseConfig penroseConfig = penrose.getPenroseConfig();
Hashtable<String,Object> env = new ShutdownConfiguration().toJndiEnvironment();
env.put(Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName());
env.put(Context.PROVIDER_URL, "ou=system");
env.put(Context.SECURITY_PRINCIPAL, penroseConfig.getRootDn().toString());
env.put(Context.SECURITY_CREDENTIALS, penroseConfig.getRootPassword());
env.put(Context.SECURITY_AUTHENTICATION, "simple");
new InitialDirContext(env);
log.warn("LDAP Service has been shutdown.");
}
}