ldapservice.java

来自「jetspeed源代码」· Java 代码 · 共 1,485 行 · 第 1/3 页

JAVA
1,485
字号
/*
 * Copyright 2000-2001,2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jetspeed.services.ldap;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.naming.AuthenticationException;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.ReferralException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.servlet.ServletConfig;

// Turbine classes
import org.apache.turbine.services.InitializationException;
import org.apache.turbine.services.TurbineBaseService;
import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.services.resources.ResourceService;

// Jetspeed classes
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;

/**
 *
 * @author <a href="mailto:ender@kilicoglu.nom.tr">Ender KILICOGLU</a>
 * @author <a href="mailto:sami.leino@netorek.fi">Sami Leino</a>
 *
 * @version $Id: LDAPService.java,v 1.6 2004/02/23 03:28:31 jford Exp $ 
 * 
 */
public class LDAPService extends TurbineBaseService
{
    /**
     * Static initialization of the logger for this class
     */    
    private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(LDAPService.class.getName());
    
    public static String SERVICE_NAME = "ldap";
    private static final String DEFAULT_ATTR[] = {
        "objectclass"
    };
    public static final int BASE = 0;
    public static final int ONE = 1;
    public static final int SUB = 2;
    public static final int DEFAULT_PORT = 389;
    public static final int DEFAULT_SSLPORT = 636;
    public static final int DEFAULT_LIMIT = 0;
    public static final int DEFAULT_TIMEOUT = 0;
    public static final int DEFAULT_VERSION = 3;
    private static String DEFAULT_CTX = "com.sun.jndi.ldap.LdapCtxFactory";

    private Hashtable connections;
    private Connector connector;
    private int limit;
    private int timeout;
    private int version;
    private String host;
    private int port;
    private int sslport;
    private String basedn;
    private String managerdn;
    private String password;
    private String managerlogin;
    private int batchsize;
    private String securityAuthentication;
    private String securityProtocol;
    private String socketFactory;
    private String saslclientpckgs;
    private String jndiprovider;
    private boolean anonymousBind;
    private String listFilter;
    private String attributesList[];
    private NameParser parser;
    private boolean showOpAttributes;
	private boolean useCachedDirContexts;
    private Properties env;

    /**
     * Main Connection Function
     *
     * Make first connection and store it in connections.
     *
     * @param url <code>LDAPURL</code> which locate server to connect.
     * @return boolean true if success else false.         
     */
    private boolean mainConnect(LDAPURL url)
    {
        setDefaultEnv();
        String base = url.getBase();
        env.put("java.naming.provider.url", base);
        try
        {
            DirContext ctx = new InitialDirContext(env);
            if (useCachedDirContexts)
            {
            	connections.put(basedn, ctx);
            }
            if(parser == null) parser = ctx.getNameParser("");
            return true;
        }
        catch(NamingException e)
        {
            logger.error ("LDAP Service: Failed to connect to " + url.getUrl(), e);
        }
        return false;
    }

    /**
     * Connection Function
     *
     * tries to connect given <code>LDAPURL</code>.
     *
     * @param url <code>LDAPURL</code> which locate server to connect.
     * @return DirContext connection context object.
     */
    public DirContext connect(LDAPURL url)
    {

        String base = url.getBase();
        DirContext ctx = (DirContext)connections.get(base);
        if(ctx != null)
        {
			// System.out.println("LDAPService: returning cached context.");
			// System.out.println("LDAPService: DN is " + url.getDN());
        	return ctx;
        }
		else
		{
			// System.out.println("LDAPService: creating new context for base " + base);
			// System.out.println("LDAPService: DN is " + url.getDN());
		}
		
        setDefaultEnv();
        env.put("java.naming.provider.url", base);
        do
        {
            try
            {
                ctx = new InitialDirContext(env);
                if (useCachedDirContexts) connections.put(base, ctx);
                return ctx;
            }
            catch(AuthenticationException e)
            {
                logger.error ("LDAP Service: Authentication error: " + base, e);
                if(connector == null)
                    return null;
                Properties pr = connector.referralConnection(env, url, anonymousBind);
                if(pr != null)
                {
                    env = pr;
                    continue;
                }
            }
            catch(CommunicationException e)
            {
                logger.error("LDAP Service: Communication error: " + base, e);
                if(connector == null)
                    return null;
                if(connector.connectionFailed(url))
                {
                    resetConnection(url);
                    continue;
                }
            }
            catch(NamingException e)
            {
                logger.error("LDAP Service:Failed to connect to " + base, e);
            }
            return ctx;
        } while(true);
    }

    /**
     * Reset Given Connection Function
     *
     * tries to connect given <code>LDAPURL</code>.
     *
     * @param url <code>LDAPURL</code> which locate server to connect.
     *
     */
    private void resetConnection(LDAPURL url)
    {
		// System.out.println("LDAPService: resetConnection() called.");
        connections.remove(url.getBase());
    }
     /**
     * Set Default Environment
     *
     * Fill properties necessary to connect.
     *
     */
    private void setDefaultEnv()
    {
        showOpAttributes = attributesList != null;
        env.put("java.naming.referral", "ignore");
        env.put("java.naming.batchsize", String.valueOf(batchsize));

        if(anonymousBind)
        {
            env.remove("java.naming.security.principal");
            env.remove("java.naming.security.credentials");
        }
        else
        {
            env.put("java.naming.security.principal", managerdn);
            env.put("java.naming.security.credentials", password);
        }

        env.put("java.naming.security.authentication", securityAuthentication);
        if(saslclientpckgs  != null)
		{
		    env.put("javax.security.sasl.client.pkgs", saslclientpckgs);
		}
		else
        {
            env.remove("javax.security.sasl.client.pkgs");
        }

        env.put("java.naming.ldap.derefAliases", "never");
        env.put("java.naming.ldap.deleteRDN", "true" );
        env.put("java.naming.ldap.version", String.valueOf(version));

        if( securityProtocol != null)
        {
            env.put("java.naming.security.protocol", securityProtocol);
            if(securityProtocol.equalsIgnoreCase("ssl"))
            {
                env.put("java.naming.ldap.factory.socket", socketFactory );
			}
        }
        else
        {
            env.remove("java.naming.security.protocol");
            env.remove("java.naming.ldap.factory.socket");
        }

		// env.put("com.sun.jndi.ldap.trace.ber", System.err);
        env.put("java.naming.factory.initial", (Object)(jndiprovider));
    }

    /**
     * Disconnection Function
     *
     * tries to disconnect all connection.
     *
     * @return boolean true if success else false.
     */

    public boolean disconnect()
    {
		// System.out.println("LDAPService: disconnect() called.");
        DirContext ctx = null;

        for(Enumeration enum = connections.elements(); enum.hasMoreElements();)
		{
		    try
            {
                ctx = (DirContext)enum.nextElement();
                ctx.close();
            }
            catch(NamingException e)
            {
                logger.error("LDAP Service: Disconnect failed", e);
            }
		}
		
        connections.clear();
        return true;
    }

    public boolean checkAndCloseContext(Context context)
    {
		try
        {
            if (!useCachedDirContexts)
            {
            	context.close();
            	// System.out.println("LDAPService: closeContext() called.");
            }
            else
            {
            	// System.out.println("LDAPService: context left in cache.");
            }
	        return true;
        }
        catch(NamingException e)
        {
            logger.error("LDAP Service: closeContext() failed", e);
	        return false;
        }
    }


    /**
     * Delete Atrribute Function
     *
     * Delete given attribute for given <code>LDAPURL</code>.
     *
     * @param url object affected.
     * @param at Atribute to delete
     * @return boolean true if success else false.
     */

    public boolean deleteAttribute(LDAPURL url, Attribute at)
    {
        try
        {
            ModificationItem mods[] = new ModificationItem[1];
            mods[0] = new ModificationItem(3, at);
            return modifyAttribute(url, mods);
        }
        catch(NamingException e)
        {
            logger.debug("LDAP Service: Failed to delete '" + at.getID() + "' attribute for " + url.getUrl(), e);
        }
        return false;
    }

    /**
     * Add Attribute Function
     *
     * add given attribute to given <code>LDAPURL</code>.
     *
     * @param url object affected.
     * @param at Atribute to add
     * @return boolean true if success else false.
     */
    public boolean addAttribute(LDAPURL url, Attribute at)
    {
        try
        {
            ModificationItem mods[] = new ModificationItem[1];
            mods[0] = new ModificationItem(1, at);
            return modifyAttribute(url, mods);
        }
        catch(NamingException e)
        {
            logger.debug("LDAP Service: Failed to add '" + at.getID() + "' attribute for " + url.getUrl(), e);
        }
        return false;
    }

    /**
     * Add entry Function
     *
     * tries to add object with given <code>LDAPURL</code> and
     * with given attributes.
     *
     * @param url object to create.
     * @param at Atributes to add
     * @return boolean true if success else false.
     */
    public boolean addEntry(LDAPURL url, Attributes at)
    {
        DirContext ctx = connect(url);

        if(ctx == null)
            return false;
        try
        {
            ctx.createSubcontext(url.getDN(), at);
            checkAndCloseContext(ctx);
        }
        catch(ReferralException e)
        {
            LDAPURL myurl = getReferralUrl(e);
            return addEntry(myurl, at);
        }
        catch(NamingException e)
        {

e.printStackTrace();

            logger.error("LDAP Service: Failed to add new entry " + url.getDN(), e);
            return false;
        }
        return true;
    }

    /**
     * Query existense of an Object Function
     *
     * tries to locate given <code>LDAPURL</code>.
     *
     * @param url object affected.
     * @return boolean true if exist else false.
     */
    public boolean exists(LDAPURL url)
    {
        DirContext ctx = connect(url);
        if(ctx == null) return false;

        try
        {
            NamingEnumeration results = search(ctx, url.getDN(), "(objectclass=*)", DEFAULT_ATTR, 0, false);
            checkAndCloseContext(ctx);
            return true;
        }
        catch(NameNotFoundException _ex)
        {
            return false;
        }
        catch(NamingException _ex)
        {
            return false;
        }
    }

    /**
     * Compare Function
     *
     * Compare given <code>LDAPURL</code>s.
     *
     * @param srcUrl object affected.
     * @param dstUrl object affected.
     * @return int 0 same host+DN, 1 same DN,2 child,3 no relation.
     */
    public int compare(LDAPURL srcUrl, LDAPURL dstUrl)
    {
        if(!srcUrl.sameHosts(dstUrl))
            return 0;
        Name src = parse(srcUrl.getDN());
        Name dst = parse(dstUrl.getDN());
        if(dst.compareTo(src) == 0)
            return 1;
        if(dst.startsWith(src))
            return 2;
        Name prefix = src.getPrefix(src.size() - 1);
        return dst.compareTo(prefix) != 0 ? 0 : 3;
    }

    /**
     * Import Function
     *
     * Import given <code>LDAPURL</code> to another dn.
     *
     * @param url object to import.
     * @param dn Dn of new object.
     * @param entry attributes.
     * @param type 0 addnew, 1 update, 2 sync.
     * @return int 1 success, 0 unknown type,-1 failure.
     */
    public int importEntry(LDAPURL url, String dn, Attributes entry, int type)
    {
        boolean rs = false;
        LDAPURL myurl = new LDAPURL(url.getHost(), url.getPort(), dn);
        if(type == 0)
            rs = addEntry(myurl, entry);
        else

        if(type == 1)
            rs = updateEntry(myurl, entry);
        else
        if(type == 2)
            rs = synchEntry(myurl, entry);
        else
            return 0;
        return !rs ? -1 : 1;
    }

    /**
     * Modify Function
     *
     * Modify given <code>LDAPURL</code> with fiven modification items.
     *

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?