diff --git a/mozilla/directory/java-sdk/ldapsp.mk b/mozilla/directory/java-sdk/ldapsp.mk new file mode 100644 index 00000000000..fbd03c0dbad --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp.mk @@ -0,0 +1,118 @@ +# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. +# +# Makefile for the LDAP classes +# +# An optimized compile is done by default. You can specify "DEBUG=1" on +# the make line to generate debug symbols in the bytecode. +# +ARCH := $(shell uname -s) + +MCOM_ROOT=. +ifeq ($(ARCH), WINNT) + MOZ_DIR:=$(subst \,/,$(MOZ_SRC)) + BASEDIR:=$(MOZ_DIR)/mozilla/directory/java-sdk +else + ifeq ($(ARCH), WIN95) + MOZ_DIR:=$(subst \,/,$(MOZ_SRC)) + BASEDIR:=$(MOZ_DIR)/mozilla/directory/java-sdk + else + BASEDIR := $(shell cd $(MCOM_ROOT); pwd) + endif +endif +# Destination for class files and packages +CLASS_DEST=$(BASEDIR)/dist/classes + +# Set up the CLASSPATH automatically, +ifeq ($(ARCH), WINNT) + JDK := $(subst \,/,$(JAVA_HOME)) + JAR:=$(JDK)/bin/jar + SEP=; +else + ifeq ($(ARCH), WIN95) + JDK := $(subst \,/,$(JAVA_HOME)) + JAR:=$(JDK)/bin/jar + SEP=; + else + JDK := $(JAVA_HOME) + JAR:=$(JAVA_HOME)/bin/jar + SEP=: + endif +endif +JNDILIB:=$(BASEDIR)/ldapsp/lib/jndi.jar +JAVACLASSPATH:=$(CLASS_DEST)$(SEP)$(BASEDIR)/ldapsp$(SEP)$(JDKLIB)$(SEP)$(JNDILIB)$(SEP)$(CLASSPATH) + +SRCDIR=com/netscape/jndi/ldap +DISTDIR=$(MCOM_ROOT)/dist +CLASSDIR=$(MCOM_ROOT)/dist/classes +CLASSPACKAGEDIR=$(DISTDIR)/packages +#PACKAGENAME=jndi.zip +ifeq ($(DEBUG), full) +BASEPACKAGENAME=ldapsp_debug.jar +else +BASEPACKAGENAME=ldapsp.jar +endif +CLASSPACKAGE=$(CLASSPACKAGEDIR)/$(PACKAGENAME) +MANIFEST=$(BASEDIR)/ldapsp/manifest.mf + +ifndef JAVAC + ifdef JAVA_HOME + JDKBIN=$(JDK)/bin/ + endif + ifeq ($(DEBUG), 1) + JAVAC=$(JDKBIN)javac -g -classpath "$(JAVACLASSPATH)" + else + JAVAC=$(JDKBIN)javac -O -classpath "$(JAVACLASSPATH)" + endif +endif + +all: classes + +basics: $(DISTDIR) $(CLASSDIR) + +classes: JNDICLASSES + +basepackage: $(CLASSPACKAGEDIR) + cd $(DISTDIR)/classes; rm -f ../packages/$(BASEPACKAGENAME); $(JAR) cvfm ../packages/$(BASEPACKAGENAME) $(MANIFEST) com/netscape/jndi/ldap/*.class com/netscape/jndi/ldap/common/*.class com/netscape/jndi/ldap/schema/*.class com/netscape/jndi/ldap/controls/*.class + +MAIN: basics + cd ldapsp/$(SRCDIR); $(JAVAC) -d $(CLASS_DEST) *.java + +SCHEMA: basics + cd ldapsp/$(SRCDIR)/schema; $(JAVAC) -d $(CLASS_DEST) *.java + +COMMON: basics + cd ldapsp/$(SRCDIR)/common; $(JAVAC) -d $(CLASS_DEST) *.java + +CONTROLS: basics + cd ldapsp/$(SRCDIR)/controls; $(JAVAC) -d $(CLASS_DEST) *.java + + +JNDICLASSES: COMMON CONTROLS SCHEMA MAIN + +clean: + rm -rf $(DISTDIR)/classes/com/netscape/jndi/ldap + +$(CLASSPACKAGEDIR): + mkdir -p $@ + +$(DISTDIR): + mkdir -p $@ + +$(CLASSDIR): + mkdir -p $@ + diff --git a/mozilla/directory/java-sdk/ldapsp/Readme.html b/mozilla/directory/java-sdk/ldapsp/Readme.html new file mode 100644 index 00000000000..e4bdcc6842c --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/Readme.html @@ -0,0 +1,541 @@ + + + + + + + Netscape LDAP Service Provider - Readme + + + +

+                +Netscape LDAP Service Provider for JNDI (06-04-99)

+The Netscape LDAP service provider for JNDI implements the JNDI DirContext +interface. It is implemented as a layer on top of the Netscape Directory +SDK for Java (ldapjdk.jar). While the ldapjdk uses the LDAP connection +as the primary abstraction enabling the access to the directory services, +the JNDI provider uses the concept of  a  Directory Context (the +DirContext interface) to achieve the same functionality. A DirContext as +an equivalent of a directory entry in the ldapjdk. +

The following sections are available in this document: +

Using Netscape Ldap Service Provider +
Environment Properties +
Working With Controls +
What's Not Implemented +
  +

+Using Netscape LDAP Service Provider

+The current implementation  is based on the JNDI 1.2 beta1. In addition +to the DirContext interface implementation, the Netscape LDAP provider +implements the new JNDI event service (javax.naming.event package) +and support for controls (javax.naming.ldap package) which were +introduced with the JNDI 1.2. +

To use the service provider, you'll need to: +

(1) Add the provider and the jars it depends on in the classpath. For +example, on Windows NT the classpath should be set as follows: +

set classpath=%classpath%;ldapsp.jar;ldapjdk.jar;jndi.jar; +

Assuming that all the jars are available in the current directory. The +listed jar files are: +
  + + + + + + + + + + + + + + + + + + +
ldapsp.jar Netscape LDAP Service Provider for JNDI
ldapjdk.jarNetscape Directory SDK for Java 3.1
jndi.jarJNDI 1.2 beta1
+ +

(2) Specify the Netscape LDAP provider as the provider in the context +environment created for the initial context; +
       Hashtable env = new Hashtable(); +
   env.put(Context.INITIAL_CONTEXT_FACTORY, +
          "com.netscape.jndi.ldap.LdapContextFactory"); +
    env.put(... +
    ... +
    DirContext ctx = new InitialDirContext(env); +

(3) For storing of  Java objects in a LDAP Directory, the JNDI +java object schema must be added to the directory. To enable the JNDI schema +copy the file jndi-object-schema.conf  to your <server-root>/slapd-<id>/config +directory, and include the file into your  <server-root>/slapd-<id>/config/ns-schema.conf +schema configuration file. +

For examples of using JNDI please go to the official JNDI site. +

+Environment Properties

+The environment properties can be passed directly to the initial context +as a hash table, or specified as system properties. For compatibility reasons, +for those environment properties that are relevant to LDAP protocol but +are not defined in the JNDI, the Netscape LDAP provider is using the same +property names as the SUN LDAP service provided, if a property with the +same semantics is defined by the SUN provider. +

Note: If a new property is added to the context environment, or an existing +property is changed after the initial context is created, the change will +be immediately visible unless the changed property pertains to the connection. +For changes related to connection, in order to take effect you'll need +to invoke LdapContext.reconnect(). +

The following table contains JNDI environment properties are relevant +for the Netscape LDAP service provider. Properties not found in this table +are silently ignored. +
  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Environment PropertyDescription
java.naming.factory.initial +
This environment property is used to select the LDAP provider. To select +the Netscape LDAP provider "com.netscape.jndi.ldap.LdapContextFactory" +should be specified. +

 env.put(Context.INITIAL_CONTEXT_FACTORY, "com.netscape.jndi.ldap.LdapContextFactory");

java.naming.provider.url +
Specifies LDAP server information. For example: +

env.put(Context.PROVIDER_URL, "ldap://dilly.mcom.com:389"); +

If it has not been set then the provider will attempt to access an LDAP +server at port 389 on the local host.

java.naming.ldap.version +
Specifies the protocol version for the provider. Two values are +
possible: +
    +
  • +2 - selects LDAP Version 2 (LDAPv2)
  • + +
  • +3 - selects LDAP Version 3 (LDAPv3)
  • +
+ For example,  env.put("java.naming.ldap.version", "3"); +

If this environment property has not been set then the provider will +
attempt to use LDAPv3.

java.naming.security.authentication +
Specifies the authentication mechanism for the provider to use. +
The following values are permitted for this property: +
    +
  • +   none     - use no authentication +(anonymous)
  • + +
  • +   simple   - use weak authentication (clear +text password)
  • +
+If this environment property has not been set but the     +java.naming.security.principal environment property has been +
set then the provider will use 'simple'. If neither have been set then +the provider will use anonymous bind.
java.naming.security.principal +
Specifies the DN of the principal to be authenticated. For example: +

env.put(Context.SECURITY_PRINCIPAL, "cn=Directory manager"); +

If this environment property has not been set then the provider +
will use anonymous bind.

java.naming.security.credentials +
Specifies the password of the principal to be authenticated. For example: +

env.put(Context.SECURITY_CREDENTIALS, "secret");

java.naming.security.protocol +
 Specifies the security protocol for the provider to use. One +possible value is defined:  ssl - use Secure Socket Layer +

 env.put(Context.SECURITY_PROTOCOL, "ssl"); +

When this environment property has been set and the +
 java.naming.ldap.factory.socket property has not been +set, then +
the ldapjdk default socket factory  netscape.net.SSLSocket +is used. This class is provided with Netscape Communicator 4.05 and higher. +If java.naming.ldap.factory.socket property has been set, the +
socket factory specified therein is used.

java.naming.ldap.factory.socketSpecifies the class name of a socket factory. This environment +
property is used to override the default socket factory. For example: +

env.put("java.naming.ldap.factory.socket", "crysec.SSL.SSLSocket"); +

If  the security protocol environment property has been set but +this property has not been set, then this property's value is set to netscape.net.SSLSocket. +See ldapjdk documentation for more information for connecting over SSL. +
 

java.naming.ldap.ssl.ciphersSpecifies the suite of ciphers used for SSL connections made through +sockets created by the factory specified with java.naming.ldap.factory.socket. +The value of this property is of type java.lang.Object. For example: +

try { +
    Class c = Class.forName("crysec.SSL.SSLParams"); +
    java.lang.reflect.Method m =  +
         +getMethod("getCipherSuite",new Class[0]); +
    Object cipherSuite = m.invoke(null,null); +
    if (cipherSuite != null) { +
       env.put("java.naming.ldap.ssl.ciphers", +cipherSuite); +
    } +
} +
catch (Exception e) {} +
 

java.naming.batchsizeSpecifies that search results are to be returned in batches. A setting +of zero indicates that the provider should block until all results have +been received. If this environment property has not been set then search  +results are returned in batches of one.
java.naming.ldap.maxresults +
The default  maximum number of search results to be returned for +a search request. 0 means no limit. If not specified, the ldapjdk default +is 1000. This value can be overridden per request with the parameter SearchConstraints +in the DirContex.search() method.
java.naming.ldap.timelimitThe default maximum number of milliseconds to wait for a search operation +to complete. If 0, which is the ldapjdk default, there is no maximum time +limit for a search operation. This value can be overridden per request +with the parameter SearchConstraints in the DirContex.search() +method.
java.naming.referral +
 Specifies how referrals shall be handled by the provider. Three  +possible values are defined: +
    +
  • + follow - automatically follow any referrals
  • + +
  • throw  - throw a ReferralException for each referral
  • + +
  • ignore - ignore referrals if they appear in results and treat +them like ordinary attributes if they appear in entries.
  • +
+If this environment property has not been set then the LDAP provider by +default follows referrals.
java.naming.ldap.referral.limit +
Specifies the maximum number of referrals to follow in a chain of +
referrals. A setting of zero indicates that there is no limit. The +default limit is 10.
java.naming.ldap.deleteRDN Specifies whether the old RDN is removed during rename(). +
 If the value is "true", the old RDN is removed; otherwise, +
 the RDN is not removed.  The default value is true.
java.naming.ldap.derefAliases +
 Specifies how aliases are dereferenced during search operations. +
 The possible values are: +
    +
  • +always        always dereference +aliases
  • + +
  • +never         never dereference +aliases
  • + +
  • +finding       dereference aliases +only during name resolution
  • + +
  • +searching   dereference aliases only after name resolution
  • +
+ NOTE: Netscape LDAP Server 3.x and 4.x do not support aliases
java.naming.ldap.typesOnly +
 Specifies whether only attribute types are to be returned during +
 searches and getAttributes(). Its possible values are "true" +or "false". The default is false.
java.naming.ldap.conntrol.connectAn array of Controls to be set on the LDAPConnection before +a connection attempt is made to the server. 
java.naming.ldap.attributes.binarySpecifies attributes that have binary syntax. It extends the provider's +list of known binary attributes. Its value is a space separated list of +attribute names. +

env.put("java.naming.ldap.attributes.binary", "mpegVideo"); +

In contrast to ldapjdk, JNDI does not provide for reading of attribute +values as either Strings or byte arrays. All attributes are returned as +Strings unless recognized as having binary syntax. The values of attributes +that have binary syntax are returned as byte arrays instead of Strings.  +

If this environment property has not been set then, by default, only +the following attributes are considered to have binary syntax: +

    +
  • +attribute names containing ';binary'
  • + +
  • +photo                      +(0.9.2342.19200300.100.1.7)
  • + +
  • +personalSignature  (0.9.2342.19200300.100.1.53)
  • + +
  • +audio                      +(0.9.2342.19200300.100.1.55)
  • + +
  • +jpegPhoto               +(0.9.2342.19200300.100.1.60)
  • + +
  • +javaSerializedData   (1.3.6.1.4.1.42.2.27.4.1.7)
  • + +
  • +thumbnailPhoto         (1.3.6.1.4.1.1466.101.120.35)
  • + +
  • +thumbnailLogo          (1.3.6.1.4.1.1466.101.120.36)
  • + +
  • +userPassword           +(2.5.4.35)
  • + +
  • +userCertificate          (2.5.4.36)
  • + +
  • +cACertificate            +(2.5.4.37)
  • + +
  • +authorityRevocationList    (2.5.4.38)
  • + +
  • +certificateRevocationList  (2.5.4.39)
  • + +
  • +crossCertificatePair          +(2.5.4.40)
  • + +
  • +x500UniqueIdentifier        (2.5.4.45)
  • +
+
java.naming.ldap.ref.separatorSpecifies the character to use when encoding a RefAddr object in +
the javaReferenceAddress attribute. This environment property should +be used to avoid a conflict in  the case where the default separator +character appears in the components of a RefAddr object. +

 If unspecified, the default separator is the hash character '#'.

+ +

+Working with Controls

+JNDI 1.2 adds support for Controls which are fully implemented with the +Netscape LDAP provider. However, JNDI 1.2 does not define interfaces for +any of the standard controls, like for example the sort control. Instead, +the task of defining particular controls and their interfaces is left to +service providers. Therefore, if using controls, you will also need to +import the  com.netscape.jndi.ldap.controls package in your +souce in addition to the JNDI packages. +

Being implemented on the top of ldapjdk, the Netscape LDAP provider +simply exposes all of the ldapjdk controls as JNDI controls. Thus, the +control APIs are exactly the same as in ldapjdk. The only difference is +that for the LDAP provider controls class names start with  "Ldap" +while in ldapjdk the class names start with "LDAP". For instance, the ldapjdk +control LDAPSortControl is LdapSortControl in the Netscape LDAP provider. +

Here is an example of how to use the LdapSortControl. Notice that you'll +need to obtain a LdapContext object as an initial context, because controls +are not part of the directory context (DirContext). That means that instead +of calling getInitialDirContext() you 'll need to call getInitialLdapContext(). +

import java.util.Hashtable; +
import javax.naming.*; +
import javax.naming.directory.*; +
import javax.naming.ldap.*; +
import com.netscape.jndi.ldap.controls.*; +

public class SortReverseOrder { +

public static void main(String[] args) { +

    Hashtable env = new Hashtable(5, 0.75f); +
    /* +
     * Specify the initial context implementation +to use. +
     */ +
    env.put(Context.INITIAL_CONTEXT_FACTORY, +
        "com.netscape.jndi.ldap.LdapContextFactory"); +

    /* Specify host and port to use for directory +service */ +
    //env.put(Context.PROVIDER_URL, "ldap://localhost:389"); +

    LdapContext ctx = null; +
    try { +
        /* get a handle to an +Initial DirContext */ +
        ctx = new InitialLdapContext(env, +null); +

        /* specify search constraints +to search subtree */ +
        SearchControls cons += new SearchControls(); +
        cons.setSearchScope(SearchControls.SUBTREE_SCOPE); +
        cons.setReturningAttributes(new +String[] { "sn" }); +

        // specify sort control +
        ctx.setRequestControls( +
           +new +Control[] {new LdapSortControl( +
               + +new LdapSortKey[]{ +
                  + +new LdapSortKey("sn", true,null)},Control.CRITICAL)}); +

        /* search for all entries +with surname of Jensen */ +
        NamingEnumeration results +
            += ctx.search("o=mcom.com", "(objectclass=person)", cons); +

        /* for each entry print +out name + all attrs and values */ +
        while (results != null +&& results.hasMore()) { +
            +SearchResult si = (SearchResult)results.next(); +

            +Attributes attrs = si.getAttributes(); +
            +/* print each attribute */ +
            +for (NamingEnumeration ae = attrs.getAll(); ae.hasMoreElements();) { +
                +Attribute attr = (Attribute)ae.next(); +
                +String attrId = attr.getID(); +

                    +/* print each value */ +
                +for (NamingEnumeration vals = attr.getAll(); vals.hasMore(); +
                    +System.out.println(attrId + ": " + vals.next())); +
                +} +
            +System.out.println(); +
        } +
    } +
    catch (NamingException e) { +
        System.err.println("Search +example failed."); +
        e.printStackTrace(); +
    } +
    finally { +
       // cleanup +
       if (ctx != null) { +
           try +{ ctx.close(); } catch (Exception e) {} +
       } +
    } +
} +
} +

For full documenation on available controls and their interfaces, please +check the ldapjdk documentation. +

+What's Not Implemented

+Currently, the following JNDI features are not implemented by the Netscape +JNDI provider: + + + + diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/AttributesImpl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/AttributesImpl.java new file mode 100644 index 00000000000..bf5cddbed7b --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/AttributesImpl.java @@ -0,0 +1,312 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; + +import netscape.ldap.*; + +import java.util.*; + +/** + * Wrapper for LDAPAttributes which implements JNDI Attribute interface + */ +class AttributesImpl implements Attributes { + + // TODO Create JndiAttribute class so that getAttributeDefinition and + // getAttributeSyntaxDefinition can be implemented + + LDAPAttributeSet m_attrSet; + + /** + * A list of predefined binary attribute name + */ + static String[] m_binaryAttrs = { + "photo", "userpassword", "jpegphoto", "audio", "thumbnailphoto", "thumbnaillogo", + "usercertificate", "cacertificate", "certificaterevocationlist", + "authorityrevocationlist", "crosscertificatepair", "personalsignature", + "x500uniqueidentifier", "javaserializeddata"}; + + /** + * A list of user defined binary attributes specified with the environment + * property java.naming.ldap.attributes.binary + */ + static String[] m_userBinaryAttrs = null; + + public AttributesImpl(LDAPAttributeSet attrSet, String[] userBinaryAttrs) { + m_attrSet = attrSet; + m_userBinaryAttrs = userBinaryAttrs; + } + + public Object clone() { + return new AttributesImpl((LDAPAttributeSet)m_attrSet.clone(), m_userBinaryAttrs); + } + + public Attribute get(String attrID) { + LDAPAttribute attr = m_attrSet.getAttribute(attrID); + return (attr == null) ? null : ldapAttrToJndiAttr(attr); + } + + public NamingEnumeration getAll() { + return new AttributeEnum(m_attrSet.getAttributes()); + } + + public NamingEnumeration getIDs() { + return new AttributeIDEnum(m_attrSet.getAttributes()); + } + + public boolean isCaseIgnored() { + return false; + } + + public Attribute put(String attrID, Object val) { + LDAPAttribute attr = m_attrSet.getAttribute(attrID); + if (val == null) { // no Value + m_attrSet.add(new LDAPAttribute(attrID)); + } + else if (val instanceof byte[]) { + m_attrSet.add(new LDAPAttribute(attrID, (byte[])val)); + } + else { + m_attrSet.add(new LDAPAttribute(attrID, val.toString())); + } + return (attr == null) ? null : ldapAttrToJndiAttr(attr); + } + + public Attribute put(Attribute jndiAttr) { + try { + LDAPAttribute oldAttr = m_attrSet.getAttribute(jndiAttr.getID()); + m_attrSet.add(jndiAttrToLdapAttr(jndiAttr)); + return (oldAttr == null) ? null : ldapAttrToJndiAttr(oldAttr); + } + catch (NamingException e) { + System.err.println( "Error in AttributesImpl.put(): " + e.toString() ); + e.printStackTrace(System.err); + } + return null; + } + + public Attribute remove(String attrID) { + Attribute attr = get(attrID); + m_attrSet.remove(attrID); + return attr; + } + + public int size() { + return m_attrSet.size(); + } + + + /** + * Check if an attribute is a binary one + */ + static boolean isBinaryAttribute(String attrID) { + + // attr name contains ";binary" + if (attrID.indexOf(";binary") >=0) { + return true; + } + + attrID = attrID.toLowerCase(); + + // check the predefined binary attr table + for (int i=0; i < m_binaryAttrs.length; i++) { + if (m_binaryAttrs[i].equals(attrID)) { + return true; + } + } + + // check user specified binary attrs with + for (int i=0; m_userBinaryAttrs != null && i < m_userBinaryAttrs.length; i++) { + if (m_userBinaryAttrs[i].equals(attrID)) { + return true; + } + } + + return false; + } + + /** + * Convert a JNDI Attributes object into a LDAPAttributeSet + */ + static LDAPAttributeSet jndiAttrsToLdapAttrSet(Attributes jndiAttrs) throws NamingException{ + LDAPAttributeSet attrs = new LDAPAttributeSet(); + for (Enumeration enum = jndiAttrs.getAll(); enum.hasMoreElements();) { + attrs.add(jndiAttrToLdapAttr((Attribute) enum.nextElement())); + } + return attrs; + } + + /** + * Convert a JNDI Attribute to a LDAPAttribute + */ + static LDAPAttribute jndiAttrToLdapAttr(Attribute jndiAttr) throws NamingException{ + LDAPAttribute attr = new LDAPAttribute(jndiAttr.getID()); + + for (NamingEnumeration vals = jndiAttr.getAll(); vals.hasMoreElements();) { + Object val = vals.nextElement(); + if (val == null) { + ; // no value + } + else if (val instanceof byte[]) { + attr.addValue((byte[])val); + } + else { + attr.addValue(val.toString()); + } + } + return attr; + } + + /** + * Convert a LDAPAttribute to a JNDI Attribute + */ + static Attribute ldapAttrToJndiAttr(LDAPAttribute attr) { + BasicAttribute jndiAttr = new BasicAttribute(attr.getName()); + Enumeration enumVals = null; + if (isBinaryAttribute(attr.getName())) { + enumVals = attr.getByteValues(); + } + else { + enumVals = attr.getStringValues(); + } + if (enumVals != null) { + while ( enumVals.hasMoreElements() ) { + jndiAttr.add(enumVals.nextElement()); + } + } + return jndiAttr; + } + + /** + * Convert and array of JNDI ModificationItem to a LDAPModificationSet + */ + static LDAPModificationSet jndiModsToLdapModSet(ModificationItem[] jndiMods) throws NamingException{ + LDAPModificationSet mods = new LDAPModificationSet(); + for (int i=0; i < jndiMods.length; i++) { + int modop = jndiMods[i].getModificationOp(); + LDAPAttribute attr = jndiAttrToLdapAttr(jndiMods[i].getAttribute()); + if (modop == DirContext.ADD_ATTRIBUTE) { + mods.add(LDAPModification.ADD, attr); + } + else if (modop == DirContext.REPLACE_ATTRIBUTE) { + mods.add(LDAPModification.REPLACE, attr); + } + else if (modop == DirContext.REMOVE_ATTRIBUTE) { + mods.add(LDAPModification.DELETE, attr); + } + else { + // Should never come here. ModificationItem can not + // be constructed with a wrong value + } + } + return mods; + } + + /** + * Create a LDAPModificationSet from a JNDI mod operation and JNDI Attributes + */ + static LDAPModificationSet jndiAttrsToLdapModSet(int modop, Attributes jndiAttrs) throws NamingException{ + LDAPModificationSet mods = new LDAPModificationSet(); + for (NamingEnumeration attrEnum = jndiAttrs.getAll(); attrEnum.hasMore();) { + LDAPAttribute attr = jndiAttrToLdapAttr((Attribute)attrEnum.next()); + if (modop == DirContext.ADD_ATTRIBUTE) { + mods.add(LDAPModification.ADD, attr); + } + else if (modop == DirContext.REPLACE_ATTRIBUTE) { + mods.add(LDAPModification.REPLACE, attr); + } + else if (modop == DirContext.REMOVE_ATTRIBUTE) { + mods.add(LDAPModification.DELETE, attr); + } + else { + throw new IllegalArgumentException("Illegal Attribute Modification Operation"); + } + } + return mods; + } +} + +/** + * Wrapper for enumeration of LDAPAttrubute-s. Convert each LDAPAttribute + * into a JNDI Attribute accessed through the NamingEnumeration + */ +class AttributeEnum implements NamingEnumeration { + + Enumeration _attrEnum; + + public AttributeEnum(Enumeration attrEnum) { + _attrEnum = attrEnum; + } + + public Object next() throws NamingException{ + LDAPAttribute attr = (LDAPAttribute) _attrEnum.nextElement(); + return AttributesImpl.ldapAttrToJndiAttr(attr); + } + + public Object nextElement() { + LDAPAttribute attr = (LDAPAttribute) _attrEnum.nextElement(); + return AttributesImpl.ldapAttrToJndiAttr(attr); + } + + public boolean hasMore() throws NamingException{ + return _attrEnum.hasMoreElements(); + } + + public boolean hasMoreElements() { + return _attrEnum.hasMoreElements(); + } + + public void close() { + } +} + +/** + * Wrapper for enumeration of LDAPAttrubute-s. Return the name for each + * LDAPAttribute accessed through the NamingEnumeration + */ +class AttributeIDEnum implements NamingEnumeration { + + Enumeration _attrEnum; + + public AttributeIDEnum(Enumeration attrEnum) { + _attrEnum = attrEnum; + } + + public Object next() throws NamingException{ + LDAPAttribute attr = (LDAPAttribute) _attrEnum.nextElement(); + return attr.getName(); + } + + public Object nextElement() { + LDAPAttribute attr = (LDAPAttribute) _attrEnum.nextElement(); + return attr.getName(); + } + + public boolean hasMore() throws NamingException{ + return _attrEnum.hasMoreElements(); + } + + public boolean hasMoreElements() { + return _attrEnum.hasMoreElements(); + } + + public void close() { + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/BindingEnum.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/BindingEnum.java new file mode 100644 index 00000000000..47d82efbf6e --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/BindingEnum.java @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; +import com.netscape.jndi.ldap.common.ExceptionMapper; + +import netscape.ldap.*; + +import java.util.*; + +/** + * Wrapper for the LDAPSearchResult. Convert each LDAPEntry entry into + * a JNDI Binding. Bindings are accessed through the NamingEnumeration + * interface + */ +class BindingEnum implements NamingEnumeration { + + LDAPSearchResults m_res; + LdapContextImpl m_ctx; + Name m_ctxName; + + public BindingEnum(LDAPSearchResults res, LdapContextImpl ctx) throws NamingException { + m_res = res; + m_ctx = ctx; + try { + m_ctxName = LdapNameParser.getParser().parse(m_ctx.m_ctxDN); + } + catch ( NamingException e ) { + throw ExceptionMapper.getNamingException(e); + } + } + + public Object next() throws NamingException{ + try { + LDAPEntry entry = m_res.next(); + String name = LdapNameParser.getRelativeName(m_ctxName, entry.getDN()); + Object obj = ObjectMapper.entryToObject(entry, m_ctx); + String className = obj.getClass().getName(); + return new Binding(name, className, obj, /*isRelative=*/true); + + } + catch (LDAPReferralException e) { + throw new LdapReferralException(m_ctx, e); + } + catch ( LDAPException e ) { + throw ExceptionMapper.getNamingException(e); + } + } + + public Object nextElement() { + try { + return next(); + } + catch ( Exception e ) { + System.err.println( "Error in BindingEnum.nextElement(): " + e.toString() ); + e.printStackTrace(System.err); + return null; + } + } + + public boolean hasMore() throws NamingException{ + return m_res.hasMoreElements(); + } + + public boolean hasMoreElements() { + return m_res.hasMoreElements(); + } + + public void close() throws NamingException{ + try { + m_ctx.m_ldapSvc.getConnection().abandon(m_res); + } + catch (LDAPException e) { + throw ExceptionMapper.getNamingException(e); + } + } +} \ No newline at end of file diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/ContextEnv.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/ContextEnv.java new file mode 100644 index 00000000000..cb455ea524a --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/ContextEnv.java @@ -0,0 +1,535 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; +import netscape.ldap.controls.*; + +import com.netscape.jndi.ldap.common.*; + +import java.util.*; + +/** + * Context Environment + */ +class ContextEnv extends ShareableEnv { + + public static final String DEFAULT_HOST = "localhost"; + public static final int DEFAULT_PORT = LDAPv2.DEFAULT_PORT; + public static final int DEFAULT_SSL_PORT = 636; + public static final int DEFAULT_LDAP_VERSION = 3; + + // JNDI defined environment propertiies + public static final String P_PROVIDER_URL = Context.PROVIDER_URL; + public static final String P_SECURITY_PROTOCOL = Context.SECURITY_PROTOCOL; + public static final String P_SECURITY_AUTHMODE = Context.SECURITY_AUTHENTICATION; + public static final String P_USER_DN = Context.SECURITY_PRINCIPAL; + public static final String P_USER_PASSWORD = Context.SECURITY_CREDENTIALS; + public static final String P_APPLET = Context.APPLET; + public static final String P_AUTHORITATIVE = Context.AUTHORITATIVE; + public static final String P_LANGUAGE = Context.LANGUAGE; + public static final String P_BATCHSIZE = Context.BATCHSIZE; + public static final String P_REFERRAL_MODE = Context.REFERRAL; + + // Custom properties + public static final String P_CONNECT_CTRLS = "java.naming.ldap.control.connect"; + public static final String P_BINARY_ATTRS = "java.naming.ldap.attributes.binary"; + public static final String P_ATTRS_ONLY = "java.naming.ldap.typesOnly"; + public static final String P_DELETE_OLDRDN = "java.naming.ldap.deleteRDN"; + public static final String P_SOCKET_FACTORY = "java.naming.ldap.factory.socket"; + public static final String P_CIPHER_SUITE = "java.naming.ldap.ssl.ciphers"; // new + public static final String P_TIME_LIMIT = "java.naming.ldap.timelimit"; // new + public static final String P_MAX_RESULTS = "java.naming.ldap.maxresults"; // new + public static final String P_DEREF_ALIASES = "java.naming.ldap.derefAliases"; + public static final String P_REFERRAL_HOPLIMIT = "java.naming.referral.limit"; + public static final String P_LDAP_VERSION = "java.naming.ldap.version"; + public static final String P_JNDIREF_SEPARATOR = "java.naming.ref.separator"; + + // Possible values for the Context.REFERRAL env property + private static final String V_REFERRAL_FOLLOW = "follow"; + private static final String V_REFERRAL_IGNORE = "ignore"; + private static final String V_REFERRAL_THROW_EXCEPTION = "throw"; + + // Possible values for the java.naming.ldap.derefAliases env property + private static final String V_DEREF_NEVER = "never"; + + private static final String V_DEREF_SEARCHING = "searching"; + private static final String V_DEREF_FINDING = "finding"; + private static final String V_DEREF_ALWAYS = "always"; + + // Possible values for the java.naming... env property + private static final String V_AUTH_NONE = "none"; + private static final String V_AUTH_SIMPLE = "simple"; + private static final String V_AUTH_STRONG = "strong"; + + /** + * Constructor for non root Contexts + * + * @param parent A reference to the parent context environment + * @param parentSharedEnvIdx index into parent's shared environemnt list + */ + public ContextEnv(ShareableEnv parent, int parentSharedEnvIdx) { + super(parent, parentSharedEnvIdx); + } + + /** + * Constructor for the root context + * + * @param initialEnv a hashtable with environemnt properties + */ + public ContextEnv(Hashtable initialEnv) { + super(initialEnv); + } + + /** + * Clone ContextEnv + * + * @return A "clone" of the current context environment + */ + /** + * Clone ShareableEnv + * The code is the same as in the superclass (ShareableEnv) except that + * a ContextEnv instance is returned + * + * @return A "clone" of the current context environment + */ + public Object clone() { + + // First freeze updates for this context + freezeUpdates(); + + // If the context has been modified, then it is the parent of the clone + if (m_sharedEnv != null) { + return new ContextEnv(this, m_sharedEnv.size()-1); + } + + // No changes has been done to the inherited parent context. Pass the parent + // context to the clone + else { + return new ContextEnv(m_parentEnv, m_parentSharedEnvIdx); + } + } + + /** + * Update property value. Properties that pertain to LDAPSearchConstraints + * are immediately propagated. To take effect of properties that are connection + * related, (like user name/password, ssl mode) the context mujst be reconnected + * after the change of environment + */ + Object updateProperty(String name, Object val, LDAPSearchConstraints cons) throws NamingException{ + Object oldVal = getProperty(name); + setProperty(name,val); + try { + if (name.equalsIgnoreCase(P_BATCHSIZE)) { + updateBatchSize(cons); + } + else if (name.equalsIgnoreCase(P_TIME_LIMIT)) { + updateTimeLimit(cons); + } + else if (name.equalsIgnoreCase(P_MAX_RESULTS)) { + updateMaxResults(cons); + } + else if (name.equalsIgnoreCase(P_DEREF_ALIASES)) { + updateDerefAliases(cons); + } + else if (name.equalsIgnoreCase(P_REFERRAL_MODE)) { + updateReferralMode(cons); + } + else if (name.equalsIgnoreCase(P_REFERRAL_HOPLIMIT)) { + updateReferralHopLimit(cons); + } + } + catch (IllegalArgumentException e) { + if (oldVal == null) { + removeProperty(name); + } + else { + setProperty(name, oldVal); + } + throw e; + } + return oldVal; + } + + /** + * Initialize LDAPSearchConstraints with environment properties + */ + void updateSearchCons(LDAPSearchConstraints cons) throws NamingException{ + updateBatchSize(cons); + updateTimeLimit(cons); + updateMaxResults(cons); + updateDerefAliases(cons); + updateReferralMode(cons); + updateReferralHopLimit(cons); + } + + /** + * Set the suggested number of result to return at a time during search in the + * default SearchConstraints for the connection. + * Specified with the env property java.naming.batchsize + */ + void updateBatchSize(LDAPSearchConstraints cons) { + String size = (String)getProperty(P_BATCHSIZE); + if (size != null) { + int n = -1; + try { + n = Integer.parseInt(size); + } + catch (Exception e) { + throw new IllegalArgumentException("Illegal value for " + P_BATCHSIZE); + } + cons.setBatchSize(n); + } + } + + /** + * Set the maximum number of miliseconds to wait for any operation under default + * SearchConstraints for the connection. + * Specified with the env property java.naming.ldap.timelimit + * Note: sun ldap does not have this property + */ + void updateTimeLimit(LDAPSearchConstraints cons) { + String millis = (String)getProperty(P_TIME_LIMIT); + if (millis != null) { + int n = -1; + try { + n = Integer.parseInt(millis); + } + catch (Exception e) { + throw new IllegalArgumentException("Illegal value for " + P_TIME_LIMIT); + } + cons.setTimeLimit(n); + } + } + + /** + * Set the maximum number of search results to be returned under default + * SearchConstraints for the connection. + * Specified with the env property java.naming.ldap.maxresults + * Note: sun ldap does not have this property + */ + void updateMaxResults(LDAPSearchConstraints cons) { + String max = (String)getProperty(P_MAX_RESULTS); + if (max != null) { + int n = -1; + try { + n = Integer.parseInt(max); + } + catch (Exception e) { + throw new IllegalArgumentException( + "Illegal value for " + P_MAX_RESULTS); + } + cons.setMaxResults(n); + } + } + + /** + * Set how aliases should be dereferenced under default SearchConstraints for the + * connection. + * Specified with the env property java.naming.ldap.derefAliases + */ + final void updateDerefAliases(LDAPSearchConstraints cons) throws IllegalArgumentException{ + String deref = (String)getProperty(P_DEREF_ALIASES); + if(deref != null) { + if(deref.equalsIgnoreCase(V_DEREF_NEVER)) { + cons.setDereference(LDAPv2.DEREF_NEVER); + } + else if(deref.equalsIgnoreCase(V_DEREF_SEARCHING)) { + cons.setDereference(LDAPv2.DEREF_SEARCHING); + } + else if(deref.equalsIgnoreCase(V_DEREF_FINDING)) { + cons.setDereference(LDAPv2.DEREF_FINDING); + } + else if(deref.equalsIgnoreCase(V_DEREF_ALWAYS)) { + cons.setDereference(LDAPv2.DEREF_ALWAYS); + } + else { + throw new IllegalArgumentException("Illegal value for " + P_DEREF_ALIASES); + } + } + } + + /** + * Set referral parameters for the default SearchConstraints for the connection. + * Specified with the env property java.naming.referral + */ + void updateReferralMode(LDAPSearchConstraints cons) { + String mode = (String)getProperty(P_REFERRAL_MODE); + if(mode != null) { + if(mode.equalsIgnoreCase(V_REFERRAL_FOLLOW)) { + cons.setReferrals(true); + String user = getUserDN(), passwd = getUserPassword(); + if (user != null && passwd != null) { + cons.setRebindProc(new ReferralRebindProc(user, passwd)); + } + } + else if(mode.equalsIgnoreCase(V_REFERRAL_THROW_EXCEPTION)) { + cons.setReferrals(false); + } + else if(mode.equalsIgnoreCase(V_REFERRAL_IGNORE)) { + cons.setServerControls(new LDAPControl( + LDAPControl.MANAGEDSAIT, true, null)); + } + else { + throw new IllegalArgumentException("Illegal value for " + P_REFERRAL_MODE); + } + } + } + + /** + * Implementation for LDAPRebind interface. Provide user name, password + * to autenticate with the referred to directory server. + */ + static class ReferralRebindProc implements LDAPRebind { + LDAPRebindAuth auth; + + public ReferralRebindProc(String user, String passwd) { + auth = new LDAPRebindAuth(user, passwd); + } + + public LDAPRebindAuth getRebindAuthentication(String host, int port) { + return auth; + } + } + + /** + * Set maximal number of referral hops under default SearchConstraints for the + * connection. + * Specified with the env property java.naming.referral.limit + */ + void updateReferralHopLimit(LDAPSearchConstraints cons) throws IllegalArgumentException{ + String limit = (String)getProperty(P_REFERRAL_HOPLIMIT); + if(limit != null) { + int n = -1; + try { + n = Integer.parseInt(limit); + } + catch (Exception e) { + throw new IllegalArgumentException("Illegal value for " + P_REFERRAL_HOPLIMIT); + } + cons.setHopLimit(n); + } + } + + + /** + * Check if simple auth mode is explicitly requested. If that's the case + * user DN and password must be specified as well + */ + boolean useSimpleAuth() throws NamingException { + String authMode = (String)getProperty(P_SECURITY_AUTHMODE); + if(authMode != null) { + if(authMode.equalsIgnoreCase(V_AUTH_NONE)) { + return false; + } + else if (authMode.equalsIgnoreCase(V_AUTH_SIMPLE)) { + return true; + } + else { + throw new AuthenticationNotSupportedException( + "Unsupported value for " + P_SECURITY_AUTHMODE); + } + } + return false; + } + + /** + * Check if SSL mode is enabled + */ + boolean isSSLEnabled() throws NamingException { + String secMode = (String)getProperty(P_SECURITY_PROTOCOL); + if(secMode != null) { + if(secMode.equalsIgnoreCase("ssl")) { + return true; + } + else { + throw new AuthenticationNotSupportedException( + "Unsupported value for " + P_SECURITY_PROTOCOL); + } + } + return false; + } + + /** + * Get the Directory Server URL + */ + LDAPUrl getDirectoryServerURL() throws NamingException{ + String url = (String) getProperty(Context.PROVIDER_URL); + try { + return (url == null) ? null : new LDAPUrl(url); + } + catch (java.net.MalformedURLException e) { + throw new IllegalArgumentException( + "Illegal value for " + Context.PROVIDER_URL); + } + } + + /** + * Get Ldap Version. If not specified the default is version 3 + */ + int getLdapVersion() throws NamingException{ + String version = (String) getProperty(P_LDAP_VERSION); + if (version != null) { + int v = -1; + try { + v = Integer.parseInt(version); + } + catch (Exception e) { + throw new IllegalArgumentException( + "Illegal value for java.naming.ldap.version property."); + } + /*if ( v !=2 && v !=3) { + throw new IllegalArgumentException( + "Illegal value for + java.naming.ldap.version property."); + }BLITS*/ + return v; + } + return DEFAULT_LDAP_VERSION; + } + + /** + * Get user authenticate name + */ + String getUserDN() { + return (String) getProperty(Context.SECURITY_PRINCIPAL); + } + + /** + * Get user authenticate password + */ + String getUserPassword() { + return (String) getProperty(Context.SECURITY_CREDENTIALS); + } + + /** + * Get full qualified socket factory class name + */ + String getSocketFactory() { + return (String)getProperty(P_SOCKET_FACTORY); + } + + /** + * Get cipher suite for the socket factory + */ + Object getCipherSuite() { + return getProperty(P_CIPHER_SUITE); + } + + /** + * Get controls to be used during a connection request like ProxyAuth + */ + LDAPControl[] getConnectControls() throws NamingException{ + Control[] reqCtls = (Control[])getProperty(P_CONNECT_CTRLS); + if (reqCtls != null) { + LDAPControl[] ldapCtls = new LDAPControl[reqCtls.length]; + for (int i=0; i < reqCtls.length; i++) { + try { + ldapCtls[i] = (LDAPControl) reqCtls[i]; + } + catch (ClassCastException ex) { + throw new NamingException( + "Unsupported control type " + reqCtls[i].getClass().getName()); + } + } + return ldapCtls; + } + return null; + } + + /** + * Flag whether search operation should return attribute names only + * (no values). Read environment property P_ATTRS_ONLY. If not defined + * FALSE is returned (return attribute values by default) + */ + boolean getAttrsOnlyFlag() { + String flag = (String)getProperty(P_ATTRS_ONLY); + if (flag == null) { + return false; //default + } + else if (flag.equalsIgnoreCase("true")) { + return true; + } + else if (flag.equalsIgnoreCase("false")) { + return false; + } + else { + throw new IllegalArgumentException("Illegal value for " + P_ATTRS_ONLY); + } + } + + /** + * Flag whether rename operation should delete old RDN + * Read environment property P_ATTRS_ONLY. If not defined + * TRUE is returned (delete old RDN by default) + */ + boolean getDeleteOldRDNFlag() { + String flag = (String)getProperty(P_DELETE_OLDRDN); + if (flag == null) { + return true; //default + } + else if (flag.equalsIgnoreCase("true")) { + return true; + } + else if (flag.equalsIgnoreCase("false")) { + return false; + } + else { + throw new IllegalArgumentException("Illegal value for " + P_DELETE_OLDRDN); + } + } + + /** + * A user defined value for the separator for JNDI References. + * The default value is '#'. + * Read environment property P_JNDIREF_SEPARATOR. + */ + char getRefSeparator() throws NamingException{ + String sep = (String)getProperty(P_JNDIREF_SEPARATOR ); + if(sep != null) { + if (sep.length() !=1) { + throw new IllegalArgumentException("Illegal value for " + P_JNDIREF_SEPARATOR); + } + return sep.charAt(0); + } + return '#'; + } + + /** + * A user defined list of names of binary attributes. This list augments the + * default list of well-known binary attributes. List entries are space separated + * Read environment property P_BINARY_ATTRS. + */ + String[] getUserDefBinaryAttrs() { + String binAttrList = (String)getProperty(P_BINARY_ATTRS); + if (binAttrList == null) { + return null; + } + + StringTokenizer tok = new StringTokenizer(binAttrList); + String[] binAttrs = new String[tok.countTokens()]; + for (int i=0; tok.hasMoreTokens(); i++) { + binAttrs[i] = tok.nextToken(); + } + return binAttrs; + } + +} \ No newline at end of file diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/EventService.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/EventService.java new file mode 100644 index 00000000000..8c86118da71 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/EventService.java @@ -0,0 +1,391 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.event.*; +import netscape.ldap.*; +import netscape.ldap.controls.*; +import java.util.*; +import com.netscape.jndi.ldap.common.*; + +/** + * Event Service. Use Persistant Search control to monitor changes on the + * server. Because public ldapjdk APIs do not provide for multiplexing of + * multiple requests over the same connection, a separate thread is created + * for each monitored event + * + */ +class EventService { + + LdapService m_ldapSvc; + Vector m_eventThreads = new Vector(); + + public EventService(LdapService ldapSvc) { + m_ldapSvc = ldapSvc; + } + + /** + * Create a persistent search control. + */ + private LDAPPersistSearchControl createSrchCtrl(NamingListener listener) throws NamingException{ + + int op = 0; + + if (listener instanceof ObjectChangeListener) { + op = LDAPPersistSearchControl.MODIFY; + } + if (listener instanceof NamespaceChangeListener) { + op |= LDAPPersistSearchControl.ADD | + LDAPPersistSearchControl.DELETE | + LDAPPersistSearchControl.MODDN; + } + if (op == 0) { + throw new NamingException("Non supported listener type " + listener.getClass().getName()); + } + return new LDAPPersistSearchControl( op, /*changesOnly=*/true, + /*returnControls=*/true, /*isCritical=*/true ); + } + + /** + * Remove change event listener + */ + synchronized void removeListener(NamingListener listener) throws NamingException { + boolean removed = false; + int i=0; + while(i < m_eventThreads.size()) { + EventThread et = (EventThread)m_eventThreads.elementAt(i); + if (et.removeListener(listener)) { + removed = true; + + // If no listeners left, stop the thread. + if (et.isEmpty()) { + et.abandonRequest(); + et.stop(); + if (m_eventThreads.removeElement(et)) { + continue; // do not advance counter i + } + } + } + i++; + } + + if (!removed) { + throw new NamingException("Listener not found"); + } + } + + /** + * Add change event listener + */ + synchronized void addListener (LdapContextImpl ctx, String name, String filter, SearchControls jndiCtrls, NamingListener l) throws NamingException{ + Debug.println(1, "ADD LISTENER"); + + // Create DN by appending the name to the current context + String base = ctx.getDN(); + if (name.length() > 0) { + if (base.length() > 0) { + base = name + "," + base; + } + else { + base = name; + } + } + + //Create search constraints + LDAPConnection ld = (LDAPConnection) m_ldapSvc.getConnection().clone(); + LDAPSearchConstraints cons=ld.getSearchConstraints(); + LDAPPersistSearchControl psearchCtrl = createSrchCtrl(l); + cons.setServerControls(psearchCtrl); + + // return obj flag is ignored in this implementation + boolean returnObjs = jndiCtrls.getReturningObjFlag(); + + // Because we are not returning objects in the NamingEvent's + // oldBinding and newBinding variables, there is no way for + // for the listener to read attributes from the event. Thus + // jndiCtrls.getReturningAttributes() are ignored. Request only + // javaClassName to be able to determine object type + String[] attrs = new String[] { "javaclassname" }; + + // Search scope + int scope = ProviderUtils.jndiSearchScopeToLdap(jndiCtrls.getSearchScope()); + + // Check if such change is already monitored + EventThread et = null; + for (int i=0; i < m_eventThreads.size(); i++) { + EventThread activeET = (EventThread) m_eventThreads.elementAt(i); + if (activeET.isEqualEvent(ctx, base, scope, filter, attrs, cons)) { + et = activeET; + et.addListener(l); + break; + } + } + + // Create new event if reqested change is not already monitored + if (et == null) { + et = new EventThread(ctx, ld, base, scope, filter, attrs, cons); + m_eventThreads.addElement(et); + et.addListener(l); + et.setDaemon(true); + et.start(); + } + } + + + /** + * Change Monitoring Thread + */ + static private class EventThread extends Thread { + + String base, filter, attrs[]; + int scope; + LDAPSearchConstraints cons; + LDAPConnection ld; + EventContext src; + LDAPSearchResults res = null; + LdapContextImpl ctx; + boolean doRun; + Vector listeners = new Vector(); // vector of NamingListener + + EventThread(LdapContextImpl ctx, LDAPConnection ld, String base, int scope, String filter, + String[] attrs, LDAPSearchConstraints cons) { + + this.ctx = ctx; + this.ld = ld; + this.base = base; + this.scope = scope; + this.filter = filter; + this.attrs = attrs; + this.cons = cons; + } + + /** + * Add Listsner + */ + void addListener(NamingListener l) { + synchronized(listeners) { + listeners.addElement(l); + } + } + + /** + * Remove listener + */ + boolean removeListener(NamingListener l) { + synchronized(listeners) { + return listeners.removeElement(l); + } + } + + /** + * Abandon request. Called when no listeners left. + * Unfortunatlly, ldapjdk does not allows us the interrupt a waiting + * thread and do proper cleanup. + * TODO Need improvment here!! + */ + void abandonRequest() throws NamingException { + try { + if (res != null) { + ld.abandon(res); + } + ld.disconnect(); + } + catch (Exception ex) { + throw ExceptionMapper.getNamingException(ex); + } + } + + /** + * Chech whether there are any listeners + */ + boolean isEmpty() { + return listeners.size() == 0; + } + + /** + * Check whether this event paramaters are matched + */ + boolean isEqualEvent(LdapContextImpl ctx, String base, int scope, String filter, + String[] attrs, LDAPSearchConstraints cons) { + + if (this.ctx != ctx || !this.base.equals(base) || + this.scope != scope || !this.filter.equals(filter)) { + + return false; + } + // attrs[] + if (this.attrs == null) { + if (attrs != null) { + return false; + } + } + else if (attrs == null) { + return false; + } + else if (this.attrs.length != attrs.length) { + return false; + } + else { + for (int i=0; i < this.attrs.length; i++) { + // TODO not 100% ok. Arrays may contain the same names + // but at different positions + if (!this.attrs[i].equals(attrs[i])) { + return false; + } + } + } + + // Check if persistant search is for the same change type + LDAPPersistSearchControl + psearch1 = (LDAPPersistSearchControl)this.cons.getServerControls()[0], + psearch2 = (LDAPPersistSearchControl)cons.getServerControls()[0]; + int types1 = psearch1.getChangeTypes(), + types2 = psearch2.getChangeTypes(); + return (types1 == types2); + } + + /** + * Issue persistent search request. Loop waiting for change notifications + */ + public void run() { + doRun = true; + try { + Debug.println(1, "Do persistent search for " + base); + res = ld.search( base, scope, filter, attrs, false, cons); + + /* Loop through the results until finished. */ + while ( res.hasMoreElements() && doRun) { + + /* Get the next modified directory entry. */ + LDAPEntry modEntry = res.next(); + + Debug.println(1, "Changed " + modEntry.getDN()); + + /* Get any entry change controls. */ + LDAPControl[] ctrls = ld.getResponseControls(); + + // Can not create event without change control + if (ctrls == null) { + throw new NamingException( + "Can not create NamingEvent, no change control info"); + } + + LDAPEntryChangeControl changeCtrl = + LDAPPersistSearchControl.parseResponse(ctrls); + + // Can not create event without change control + if (changeCtrl == null || changeCtrl.getChangeType() == -1) { + throw new NamingException( + "Can not create NamingEvent, no change control info"); + } + + NamingEvent event = createNamingEvent(modEntry, changeCtrl); + dispatchEvent(event); + } + } + catch(Exception ex) { + NamingException nameEx = ExceptionMapper.getNamingException(ex); + dispatchEvent(new NamingExceptionEvent(ctx, nameEx)); + } + } + + /** + * Dispatch naming event to all listeners + */ + void dispatchEvent(EventObject event) { + NamingListener[] dispatchList = null; + + // Copy listeners so that list can be modifed during dispatching + synchronized (listeners) { + dispatchList = new NamingListener[listeners.size()]; + for (int i=0; i < dispatchList.length; i++) { + dispatchList[i] = (NamingListener)listeners.elementAt(i); + } + } + + // dispatch to all listeners + for (int i=0; i < dispatchList.length; i++) { + if (event instanceof NamingEvent) { + ((NamingEvent)event).dispatch(dispatchList[i]); + } + else { + ((NamingExceptionEvent)event).dispatch(dispatchList[i]); + } + } + } + + /** + * Create naming event from the ldap entry and change control + */ + NamingEvent createNamingEvent(LDAPEntry entry, LDAPEntryChangeControl changeCtrl) throws NamingException{ + + Binding oldBd = null, newBd = null; + int eventType = -1; + Object changeInfo = null; + String oldName = null, newName = null; + + // Get the class name from the entry + String className = ObjectMapper.getClassName(entry); + + // Get information on the type of change made + int changeType = changeCtrl.getChangeType(); + switch ( changeType ) { + case LDAPPersistSearchControl.ADD: + eventType = NamingEvent.OBJECT_ADDED; + newName = LdapNameParser.getRelativeName(ctx.m_ctxDN, entry.getDN()); + break; + case LDAPPersistSearchControl.DELETE: + eventType = NamingEvent.OBJECT_REMOVED; + oldName = LdapNameParser.getRelativeName(ctx.m_ctxDN, entry.getDN()); + break; + case LDAPPersistSearchControl.MODIFY: + eventType = NamingEvent.OBJECT_CHANGED; + oldName = newName = LdapNameParser.getRelativeName(ctx.m_ctxDN, entry.getDN()); + break; + case LDAPPersistSearchControl.MODDN: + eventType = NamingEvent.OBJECT_RENAMED; + // Get the previous DN of the entry + String oldDN = changeCtrl.getPreviousDN(); + if ( oldDN != null ) { + oldName = LdapNameParser.getRelativeName(ctx.m_ctxDN, oldDN); + } + // newName might be outside the context for which the listener has registred + try { + newName = LdapNameParser.getRelativeName(ctx.m_ctxDN, entry.getDN()); + } + catch (NamingException ex) {} + break; + } + + // Pass the change log number as event's change info + // If the change log number is not present the value is -1 + changeInfo = new Integer(changeCtrl.getChangeNumber()); + + + if (oldName != null) { + oldBd = new Binding(oldName, className, /*obj=*/null, /*isRelative=*/true); + } + if (newName!= null) { + newBd = new Binding(newName, className, /*obj=*/null, /*isRelative=*/true); + } + return new NamingEvent(ctx, eventType, newBd, oldBd, changeInfo); + } + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapContextFactory.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapContextFactory.java new file mode 100644 index 00000000000..8375ede8925 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapContextFactory.java @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.event.*; +import javax.naming.spi.*; +import java.util.*; + +public class LdapContextFactory implements InitialContextFactory { + + public Context getInitialContext(Hashtable env) throws NamingException { + Hashtable ctxEnv = (Hashtable)env.clone(); + + // Read system properties as well. Add a system property to the + // env if it's name start with "java.naming." and it is not already + // present in the env (env has precedence over the System properties) + for (Enumeration e = System.getProperties().keys(); e.hasMoreElements();) { + String key = (String) e.nextElement(); + if (key.startsWith("java.naming.")) { + if (ctxEnv.get(key) == null) { + ctxEnv.put(key,System.getProperty(key)); + } + } + } + + EventDirContext ctx = new LdapContextImpl(ctxEnv); + return ctx; + } +} + diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapContextImpl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapContextImpl.java new file mode 100644 index 00000000000..53bc6d19119 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapContextImpl.java @@ -0,0 +1,604 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; +import javax.naming.event.*; + +import netscape.ldap.*; +import netscape.ldap.controls.*; + +import com.netscape.jndi.ldap.controls.NetscapeControlFactory; +import com.netscape.jndi.ldap.common.Debug; + +import java.util.*; + +/** + * Implementation for the DirContext. The context also supports controls + * through the implementation of LdapContext interface and events through + * the implementaion of EventDirContext. + * Semantically, the LdapContextImpl corresponds to a directory entry. + * Thus a context is associated with a DN (m_ctxDN). Multiple contexts share + * the same LDAPConnection which is wrapped into a LdapService object + * (m_ldapSvc). Each context also maintains a set of environment properties + * (m_ctxEnv). A context environment is shared among mutiple contexts using a + * variation of copy-on-write algorithm (see common.ShareableEnv class). + * + * Each context also maintains a set of LDAPSearchConstraints, as search + * constrainsts like e.g. server controls, or max number of returned search + * search results, are context specific. The LdapService reads the + * LDAPSearchConstraints from a context that makes a service request. + */ +public class LdapContextImpl implements EventDirContext, LdapContext { + + /** + * Context environment setting + */ + protected ContextEnv m_ctxEnv; + + /** + * DN associated with this context + * The default value is the root DSE ("") + */ + protected String m_ctxDN; + + /** + * Ldap Connection/Service + */ + protected LdapService m_ldapSvc; + + + /** + * Ldap Connection Search Constraints + */ + protected LDAPSearchConstraints m_searchCons; + + // TODO Should have a constructor that accepts attributes + + /** + * Constructor + */ + public LdapContextImpl(Hashtable env) throws NamingException{ + m_ctxEnv = new ContextEnv(env); // no need to clone (Hashtable)env.clone()); + m_ldapSvc = new LdapService(this); + m_ldapSvc.connect(); // BLITS but to be removed, hurts lazy resource usage + getDN(); + getSearchConstraints(); + } + + /** + * Copy Constructor + */ + public LdapContextImpl(String ctxDN, LdapContextImpl cloneCtx) throws NamingException{ + + m_ctxEnv = (ContextEnv)cloneCtx.m_ctxEnv.clone(); + + // An instance of ldapService is shared among multiple contexts. + // Increment the client reference count + m_ldapSvc = cloneCtx.m_ldapSvc; + cloneCtx.m_ldapSvc.incrementClientCount(); + + if (cloneCtx.getSearchConstraints().getServerControls() == null) { + m_searchCons = cloneCtx.getSearchConstraints(); + } + else { + // In LdapContext Context Controls are not inherited by derived contexts + m_searchCons = (LDAPSearchConstraints) cloneCtx.getSearchConstraints().clone(); + m_searchCons.setServerControls((LDAPControl[])null); + } + + m_ctxDN = ctxDN; + } + + + /** + * Close the context when finalized + */ + protected void finalize() { + Debug.println(1, "finalize ctx"); + try { + close(); + } + catch (Exception e) {} + } + + /** + * Disconnect the Ldap Connection if close is requested + * LDAP operations can not be performed any more ones + * the context is closed + */ + public void close() throws NamingException { + m_ldapSvc.disconnect(); + m_ldapSvc = null; + } + + /** + * Return LdapJdk search constraints for this context + */ + LDAPSearchConstraints getSearchConstraints() throws NamingException{ + if (m_searchCons == null) { + LDAPSearchConstraints cons = new LDAPSearchConstraints(); + m_ctxEnv.updateSearchCons(cons); + m_searchCons = cons; + } + return m_searchCons; + } + + /** + * Return DN for this context + */ + String getDN() throws NamingException{ + if (m_ctxDN == null) { + LDAPUrl url = m_ctxEnv.getDirectoryServerURL(); + if (url != null && url.getDN() != null) { + m_ctxDN = url.getDN(); + } + else { + m_ctxDN = ""; + } + } + return m_ctxDN; + } + + /** + * Return reference to the context environment + */ + ContextEnv getEnv() { + return m_ctxEnv; + } + + /** + * Conver object to String + */ + public String toString() { + return this.getClass().getName() + ": " + m_ctxDN; + } + + /** + * Check if LdapURL is passed as the name paremetr to a method + * If that's the case, craete environment for the ldap url + */ + String checkLdapUrlAsName(String name) throws NamingException{ + if (name.startsWith("ldap://")) { + m_ctxEnv.setProperty(ContextEnv.P_PROVIDER_URL, name); + close(); // Force reconnect + m_ldapSvc = new LdapService(this); + // Return New name relative to the context + return ""; + } + return name; + } + + /** + * Environment operatins (javax.naming.Context interface) + */ + + public Hashtable getEnvironment() throws NamingException { + return m_ctxEnv.getAllProperties(); + } + + public Object addToEnvironment(String propName, Object propValue) throws NamingException { + return m_ctxEnv.updateProperty(propName, propValue, getSearchConstraints()); + } + + public Object removeFromEnvironment(String propName) throws NamingException { + return m_ctxEnv.removeProperty(propName); + } + + /** + * Name operations (javax.naming.Context interface) + */ + + public String composeName(String name, String prefix) throws NamingException { + return name + "," + prefix; + } + + public Name composeName(Name name, Name prefix) throws NamingException { + String compoundName = composeName(name.toString(), prefix.toString()); + return LdapNameParser.getParser().parse(compoundName); + } + + public String getNameInNamespace() throws NamingException { + return new String(m_ctxDN); + } + + public NameParser getNameParser(String name) throws NamingException { + return LdapNameParser.getParser(); + } + + public NameParser getNameParser(Name name) throws NamingException { + return LdapNameParser.getParser(); + } + + /** + * Search operations (javax.naming.DirContext interface) + */ + + public NamingEnumeration search(String name, String filter, SearchControls cons) throws NamingException { + name = checkLdapUrlAsName(name); + return m_ldapSvc.search(this, name, filter, /*attrs=*/null, cons); + } + + public NamingEnumeration search(String name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException { + name = checkLdapUrlAsName(name); + String filter = ProviderUtils.expandFilterExpr(filterExpr, filterArgs); + return m_ldapSvc.search(this, name, filter, /*attrs=*/null, cons); + } + + public NamingEnumeration search(String name, Attributes matchingAttributes) throws NamingException { + name = checkLdapUrlAsName(name); + String filter = ProviderUtils.attributesToFilter(matchingAttributes); + return m_ldapSvc.search(this, name, filter, /*attrs=*/null, /*jndiCons=*/null); + } + + public NamingEnumeration search(String name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException { + name = checkLdapUrlAsName(name); + String filter = ProviderUtils.attributesToFilter(matchingAttributes); + return m_ldapSvc.search(this, name, filter, attributesToReturn, /*jndiCons=*/null); + } + + public NamingEnumeration search(Name name, String filter, SearchControls cons) throws NamingException { + return m_ldapSvc.search(this, name.toString(), filter, /*attrs=*/null, cons); + } + + public NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException { + String filter = ProviderUtils.expandFilterExpr(filterExpr, filterArgs); + return m_ldapSvc.search(this, name.toString(), filter, /*attrs=*/null, cons); + } + + public NamingEnumeration search(Name name, Attributes attrs) throws NamingException { + String filter = ProviderUtils.attributesToFilter(attrs); + return m_ldapSvc.search(this, name.toString(), filter, /*attr=*/null, /*jndiCons=*/null); + } + + public NamingEnumeration search(Name name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException { + String filter = ProviderUtils.attributesToFilter(matchingAttributes); + return m_ldapSvc.search(this, name.toString(), filter, attributesToReturn, /*jndiCons=*/null); + } + + /** + * Attribute Operations (javax.naming.DirContext interface) + */ + + public Attributes getAttributes(String name) throws NamingException { + name = checkLdapUrlAsName(name); + return m_ldapSvc.readAttrs(this, name, null); + } + + public Attributes getAttributes(String name, String[] attrIds) throws NamingException { + name = checkLdapUrlAsName(name); + return m_ldapSvc.readAttrs(this, name, attrIds); + } + + public Attributes getAttributes(Name name) throws NamingException { + return m_ldapSvc.readAttrs(this, name.toString(), null); + + } + + public Attributes getAttributes(Name name, String[] attrIds) throws NamingException { + return m_ldapSvc.readAttrs(this, name.toString(), attrIds); + + } + + public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException { + name = checkLdapUrlAsName(name); + m_ldapSvc.modifyEntry(this, name, AttributesImpl.jndiAttrsToLdapModSet(mod_op, attrs)); + } + + public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException { + name = checkLdapUrlAsName(name); + m_ldapSvc.modifyEntry(this, name, AttributesImpl.jndiModsToLdapModSet(mods)); + } + + public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException { + m_ldapSvc.modifyEntry(this, name.toString(), AttributesImpl.jndiAttrsToLdapModSet(mod_op, attrs)); + + } + + public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException { + m_ldapSvc.modifyEntry(this, name.toString(), AttributesImpl.jndiModsToLdapModSet(mods)); + } + + /** + * Ldap entry operations (javax.naming.DirContext interface) + */ + + public Context createSubcontext(String name) throws NamingException { + // Directory entry must have attributes + throw new OperationNotSupportedException(); + } + + public Context createSubcontext(Name name) throws NamingException { + // Directory entry must have attributes + throw new OperationNotSupportedException(); + } + + public DirContext createSubcontext(String name, Attributes attrs) throws NamingException { + name = checkLdapUrlAsName(name); + return m_ldapSvc.addEntry(this, name, AttributesImpl.jndiAttrsToLdapAttrSet(attrs)); + } + + public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException { + return m_ldapSvc.addEntry(this, name.toString(), AttributesImpl.jndiAttrsToLdapAttrSet(attrs)); + + } + + public void destroySubcontext(String name) throws NamingException { + name = checkLdapUrlAsName(name); + m_ldapSvc.delEntry(this, name); + } + + public void destroySubcontext(Name name) throws NamingException { + m_ldapSvc.delEntry(this, name.toString()); + + } + + /** + * Naming Bind/Rename operations + * (javax.naming.Context, javax.naming.DirContext interface) + */ + + public void bind(String name, Object obj) throws NamingException { + name = checkLdapUrlAsName(name); + m_ldapSvc.addEntry(this, name.toString(), + ObjectMapper.objectToAttrSet(obj, name, this, /*attrs=*/null)); + } + + public void bind(Name name, Object obj) throws NamingException { + bind(name.toString(), obj); + } + + public void bind(String name, Object obj, Attributes attrs) throws NamingException { + name = checkLdapUrlAsName(name); + m_ldapSvc.addEntry(this, name.toString(), + ObjectMapper.objectToAttrSet(obj, name, this, attrs)); + } + + public void bind(Name name, Object obj, Attributes attrs) throws NamingException { + bind(name.toString(), obj, attrs); + } + + public void rebind(String name, Object obj) throws NamingException { + rebind(name, obj, /*attrs=*/null); + } + + public void rebind(Name name, Object obj) throws NamingException { + rebind(name.toString(), obj, null); + } + + public void rebind(String name, Object obj, Attributes attrs) throws NamingException { + name = checkLdapUrlAsName(name); + try { + bind(name, obj, attrs); + } + catch (NameAlreadyBoundException ex) { + unbind(name); + bind(name, obj, attrs); + } + } + + public void rebind(Name name, Object obj, Attributes attrs) throws NamingException { + rebind(name.toString(), obj, attrs); + } + + public void rename(String oldName, String newName) throws NamingException { + oldName = checkLdapUrlAsName(oldName); + LdapNameParser parser = LdapNameParser.getParser(); + Name oldNameObj = parser.parse(oldName); + Name newNameObj = parser.parse(newName); + rename(oldNameObj, newNameObj); + } + + public void rename(Name oldName, Name newName) throws NamingException { + // Can rename only RDN + if (newName.size() != oldName.size()) { + throw new InvalidNameException("Invalid name " + newName); + } + Name oldPrefix = oldName.getPrefix(oldName.size() -1); + Name newPrefix = newName.getPrefix(oldName.size() -1); + if (!newPrefix.equals(oldPrefix)) { + throw new InvalidNameException("Invalid name " + newName); + } + m_ldapSvc.changeRDN(this, oldName.toString(), newName.get(newName.size()-1)); + } + + public void unbind(String name) throws NamingException { + name = checkLdapUrlAsName(name); + // In ldap every entry is naming context + destroySubcontext(name); + } + + public void unbind(Name name) throws NamingException { + // In ldap every entry is naming context + destroySubcontext(name); + } + + /** + * List Operations (javax.naming.Context interface) + */ + + public NamingEnumeration list(String name) throws NamingException { + name = checkLdapUrlAsName(name); + return m_ldapSvc.listEntries(this, name, /*returnBindings=*/false); + } + + public NamingEnumeration list(Name name) throws NamingException { + return m_ldapSvc.listEntries(this, name.toString(), /*returnBindings=*/false); + } + + public NamingEnumeration listBindings(String name) throws NamingException { + name = checkLdapUrlAsName(name); + return m_ldapSvc.listEntries(this, name, /*returnBindings=*/true); + } + + public NamingEnumeration listBindings(Name name) throws NamingException { + return m_ldapSvc.listEntries(this, name.toString(), /*returnBindings=*/true); + } + + /** + * Lookup Operations (javax.naming.Context interface) + */ + + public Object lookup(String name) throws NamingException { + name = checkLdapUrlAsName(name); + return m_ldapSvc.lookup(this, name); + } + + public Object lookup(Name name) throws NamingException { + return m_ldapSvc.lookup(this, name.toString()); + } + + public Object lookupLink(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Object lookupLink(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + + /** + * Schema Operations (javax.naming.DirContext interface) + */ + public DirContext getSchema(String name) throws NamingException { + name = checkLdapUrlAsName(name); + return m_ldapSvc.getSchema(name); + } + + public DirContext getSchema(Name name) throws NamingException { + return m_ldapSvc.getSchema(name.toString()); + } + + public DirContext getSchemaClassDefinition(String name) throws NamingException { + name = checkLdapUrlAsName(name); + throw new OperationNotSupportedException(); + } + + public DirContext getSchemaClassDefinition(Name name) throws NamingException { + return getSchemaClassDefinition(name.toString()); + } + + /** + * Naming Event methods javax.naming.event.EventDirContext interface) + */ + public void addNamingListener(String target, int scope, NamingListener l) throws NamingException { + EventService eventSvc = m_ldapSvc.getEventService(); + String filter = LdapService.DEFAULT_FILTER; + SearchControls ctls = new SearchControls(); + ctls.setSearchScope(scope); + eventSvc.addListener(this, target, filter, ctls, l); + } + + public void addNamingListener(Name target, int scope, NamingListener l) throws NamingException { + addNamingListener(target.toString(), scope, l); + } + + public void addNamingListener(String target, String filter, SearchControls ctls, NamingListener l)throws NamingException { + EventService eventSvc = m_ldapSvc.getEventService(); + eventSvc.addListener(this, target, filter, ctls, l); + + } + + public void addNamingListener(Name target, String filter, SearchControls ctls, NamingListener l)throws NamingException { + addNamingListener(target.toString(), filter, ctls, l); + } + + public void addNamingListener(String target, String filterExpr, Object[] filterArgs, SearchControls ctls, NamingListener l)throws NamingException { + EventService eventSvc = m_ldapSvc.getEventService(); + String filter = ProviderUtils.expandFilterExpr(filterExpr, filterArgs); + eventSvc.addListener(this, target, filter, ctls, l); + } + + public void addNamingListener(Name target, String filterExpr, Object[] filterArgs, SearchControls ctls, NamingListener l)throws NamingException { + addNamingListener(target.toString(), filterExpr, filterArgs, ctls, l); + } + + public void removeNamingListener(NamingListener l) throws NamingException { + EventService eventSvc = m_ldapSvc.getEventService(); + eventSvc.removeListener(l); + } + + public boolean targetMustExist() { + return true; + } + + /** + * LdapContext methods (javax.naming.ldap.LdapContext interface) + */ + public ExtendedResponse extendedOperation(ExtendedRequest req)throws NamingException { + throw new OperationNotSupportedException(); + } + + public Control[] getRequestControls() throws NamingException { + LDAPControl[] ldapCtls = m_searchCons.getServerControls(); + if (ldapCtls == null) { + return null; + } + Control[] ctls = new Control[ldapCtls.length]; + for (int i=0; i < ldapCtls.length; i++) { + ctls[i] = (Control) ldapCtls[i]; + } + return ctls; + } + + public void setRequestControls(Control[] reqCtls) throws NamingException { + LDAPControl[] ldapCtls = new LDAPControl[reqCtls.length]; + for (int i=0; i < reqCtls.length; i++) { + try { + ldapCtls[i] = (LDAPControl) reqCtls[i]; + } + catch (ClassCastException ex) { + throw new NamingException( + "Unsupported control type " + reqCtls[i].getClass().getName()); + } + } + + getSearchConstraints().setServerControls(ldapCtls); + } + + public Control[] getResponseControls() throws NamingException { + LDAPControl[] ldapCtls = m_ldapSvc.getConnection().getResponseControls(); + if (ldapCtls == null) { + return null; + } + // Parse raw controls + Control[] ctls = new Control[ldapCtls.length]; + for (int i=0; i < ldapCtls.length; i++) { + ctls[i] = NetscapeControlFactory.getControlInstance(ldapCtls[i]); + if (ctls[i] == null) { + throw new NamingException("Unsupported control " + ldapCtls[i].getID()); + } + } + return ctls; + } + + public LdapContext newInstance(Control[] reqCtls) throws NamingException { + LdapContextImpl clone = new LdapContextImpl(m_ctxDN, this); + // This controls are to be set on the the LDAPConnection + clone.m_ctxEnv.setProperty(ContextEnv.P_CONNECT_CTRLS, reqCtls); + return clone; + } + + public void reconnect() throws NamingException { + close(); + m_ldapSvc = new LdapService(this); + m_ldapSvc.connect(); + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapNameParser.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapNameParser.java new file mode 100644 index 00000000000..8dad5eb6e1a --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapNameParser.java @@ -0,0 +1,164 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import java.util.Hashtable; +import java.util.Properties; +import javax.naming.*; + +class LdapNameParser implements NameParser { + + private static LdapNameParser m_parser; + + // A table with compound name syntax properties + static Properties nameSyntax; + static { + nameSyntax = new Properties(); + nameSyntax.put("jndi.syntax.direction", "right_to_left"); + nameSyntax.put("jndi.syntax.separator", ","); + nameSyntax.put("jndi.syntax.ignorecase", "true"); + nameSyntax.put("jndi.syntax.escape", "\\"); + nameSyntax.put("jndi.syntax.beginquote", "\""); + nameSyntax.put("jndi.syntax.trimblanks", "true"); + nameSyntax.put("jndi.syntax.separator.ava", "+"); + nameSyntax.put("jndi.syntax.separator.typeval", "="); + } + + // Can not be constructed + private LdapNameParser() {} + + // Shared instance must be used + public static LdapNameParser getParser() { + if (m_parser == null) { + m_parser = new LdapNameParser(); + } + return m_parser; + } + + // implements parse + public Name parse(String name) throws NamingException { + return new CompoundName(name, nameSyntax); + } + + /** + * A convenience method for extracting RDN + * @return RDN for the DN + * @param dn Ldap Distinguished name + * @throw NamingException Name parsing failed + */ + static String getRDN(String dn) throws NamingException { + Name parsedName = getParser().parse(dn); + if (parsedName.size() > 0) { + return parsedName.get(parsedName.size()-1); + } + return ""; + } + + /** + * A convenience method for extracting attribute name from name=val + * @return attribute name or null if "=" not found + * @param nameEqVal name=value + */ + static String getAttrName(String nameEqVal) throws NamingException { + int eq = nameEqVal.indexOf("="); + return (eq >= 0) ? nameEqVal.substring(0,eq).trim() : null; + } + + /** + * A convenience method for extracting attribute value from name=val + * @return attribute value or null if "=" not found + * @param nameEqVal name=value + */ + static String getAttrValue(String nameEqVal) throws NamingException { + int eq = nameEqVal.indexOf("="); + return (eq >= 0) ? nameEqVal.substring(eq+1).trim() : null; + } + + /** + * A convenience method for extracting relative name from the ancestor context + * @return name relative to an ancestor context + * @param ctx ancestor context distinguished name + * @param entry distinguished name + */ + static String getRelativeName(String ctx, String entry) throws NamingException{ + if (entry==null) { + entry = ""; + } + Name contextName = getParser().parse(ctx); + Name entryName = getParser().parse(entry); + if (!entryName.startsWith(contextName)) { + throw new NamingException("Name not in context"); + } + return entryName.getSuffix(contextName.size()).toString(); + } + + /** + * A convenience method for extracting relative name from the ancestor context + * @return name relative to an ancestor context + * @param ctx ancestor context distinguished name + * @param entry distinguished name + */ + static String getRelativeName(Name contextName, String entry) throws NamingException{ + if (entry==null) { + entry = ""; + } + Name entryName = getParser().parse(entry); + if (!entryName.startsWith(contextName)) { + throw new NamingException("Name not in context"); + } + return entryName.getSuffix(contextName.size()).toString(); + } + + /** + * Unit test + */ + public static void main0(String[] args) { + if (args.length != 1) { + System.out.println("Usage LdapNameParser "); + System.exit(1); + } + try { + Name name = getParser().parse(args[0]); + System.out.println(name); + System.out.println("rdn: " + getParser().getRDN(args[0])); + name.add("attr=val"); + System.out.println(name); + System.out.println(name.get(0)); + System.out.println("in name=val name:<" + getAttrName("name=val ") + + "> val:<" + getAttrValue("name=val ") + ">"); + } + catch (Exception e) { + System.err.println(e); + } + } + + // Relative name test + public static void main(String[] args) { + if (args.length != 2) { + System.out.println("Usage LdapNameParser "); + System.exit(1); + } + try { + System.out.println("relativeName: " + getParser().getRelativeName(args[0], args[1])); + } + catch (Exception e) { + System.err.println(e); + } + } + +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapReferralException.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapReferralException.java new file mode 100644 index 00000000000..406641245e1 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapReferralException.java @@ -0,0 +1,80 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; + +import java.util.*; + +/** + * A wrapper for the ldapjdk LDAPReferralException + * + */ +class LdapReferralException extends javax.naming.ldap.LdapReferralException { + + LDAPReferralException m_ldapEx; + LdapContextImpl m_srcCtx; + int m_referralIdx = 0; + + public LdapReferralException(LdapContextImpl srcCtx, LDAPReferralException ldapEx) { + m_srcCtx = srcCtx; + m_ldapEx = ldapEx; + } + + public Object getReferralInfo() { + return m_ldapEx.getURLs(); + } + + public Context getReferralContext() throws NamingException{ + Hashtable env = m_srcCtx.getEnv().getAllProperties(); + env.put(ContextEnv.P_PROVIDER_URL, m_ldapEx.getURLs()[m_referralIdx]); + return new LdapContextImpl(env); + } + + public Context getReferralContext(Hashtable env) throws NamingException{ + return getReferralContext(env, null); + } + + public Context getReferralContext(Hashtable env, Control[] reqCtls) throws NamingException{ + env.put(ContextEnv.P_PROVIDER_URL, m_ldapEx.getURLs()[m_referralIdx]); + if (reqCtls != null) { + env.put(ContextEnv.P_CONNECT_CTRLS, reqCtls); + } + return new LdapContextImpl(env); + } + + + /** + * Skip the referral to be processed + */ + public boolean skipReferral() { + int maxIdx = m_ldapEx.getURLs().length - 1; + if (m_referralIdx < maxIdx) { + m_referralIdx++; + return true; + } + return false; + } + + public void retryReferral() { + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapService.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapService.java new file mode 100644 index 00000000000..659458e67f6 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/LdapService.java @@ -0,0 +1,515 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; +import netscape.ldap.*; +import java.util.*; +import com.netscape.jndi.ldap.common.*; +import com.netscape.jndi.ldap.schema.SchemaRoot; + +/** + * Ldap Service encapsulates a Ldap connection and Ldap operations over the + * connection. The connection is established in a lazy manner, first time a + * Ldap operation is initiated. A Ldap Service object is shared by multiple + * contexts. The object maintains a reference counter which is incremented + * when a context is cloned, and decremeneted when a context is closed. The + * associated Ldap Connection is relased when the reference counter reaches + * zero. + * + * LDAPsearchConstraints are always read from a context, because ldap service + * is a shared object and each context may request different search constraints. + * + */ +class LdapService { + + public static final String DEFAULT_FILTER = "(objectclass=*)"; + public static final int DEFAULT_SCOPE = LDAPv3.SCOPE_SUB; + public static final String DEFAULT_HOST = "localhost"; + public static final int DEFAULT_PORT = LDAPv2.DEFAULT_PORT; + public static final int DEFAULT_SSL_PORT = 636; + + private LdapContextImpl m_initialCtx; + private LDAPConnection m_ld; + private EventService m_eventSvc; + + /** + * The number of contexts that are currently sharing this LdapService. + * Essentially, a reference counter. Incremented in the LdapContextImpl + * copy constructor. Decremented in the LdapService.disconnect(). + * When the count reaches zero, the LDAPConnection is released. + */ + private int m_clientCount; + + + public LdapService(LdapContextImpl initialCtx) { + m_initialCtx = initialCtx; + m_ld = new LDAPConnection(); + m_clientCount = 1; + } + + LDAPConnection getConnection() { + return m_ld; + } + + /** + * Connect to the server and send bind request to authenticate the user + */ + void connect() throws NamingException{ + + if (m_ld.isConnected()) { + return; //already connected + } + + LDAPUrl url = m_initialCtx.m_ctxEnv.getDirectoryServerURL(); + String host = (url != null) ? url.getHost() : DEFAULT_HOST; + int port = (url != null) ? url.getPort() : DEFAULT_PORT; + String user = m_initialCtx.m_ctxEnv.getUserDN(); + String passwd = m_initialCtx.m_ctxEnv.getUserPassword(); + String socketFactory = m_initialCtx.m_ctxEnv.getSocketFactory(); + Object cipherSuite = m_initialCtx.m_ctxEnv.getCipherSuite(); + int ldapVersion = m_initialCtx.m_ctxEnv.getLdapVersion(); + boolean isSSLEnabled = m_initialCtx.m_ctxEnv.isSSLEnabled(); + boolean useSimpleAuth= m_initialCtx.m_ctxEnv.useSimpleAuth(); + LDAPControl[] ldCtrls= m_initialCtx.m_ctxEnv.getConnectControls(); + + // Set default ssl port if DS not specifed + if (isSSLEnabled && url == null) { + port = DEFAULT_SSL_PORT; + } + + // SSL is enabled but no Socket factory specified. Use the + // ldapjdk default one + if (isSSLEnabled && socketFactory == null) { + m_ld = new LDAPConnection(new LDAPSSLSocketFactory()); + } + + // Set the socket factory and cipher suite if cpecified + if (socketFactory != null) { + try { + LDAPSSLSocketFactory sf = null; + if (cipherSuite != null) { + Debug.println(1, "CIPHERS=" + cipherSuite); + sf = new LDAPSSLSocketFactory(socketFactory, cipherSuite); + } + else { + sf = new LDAPSSLSocketFactory(socketFactory); + } + m_ld = new LDAPConnection(sf); + Debug.println(1, "SSL CONNECTION"); + } + catch (Exception e) { + throw new IllegalArgumentException( + "Illegal value for java.naming.ldap.factory.socket: " + e); + } + } + + try { + if (ldCtrls != null) { + m_ld.setOption(LDAPv3.SERVERCONTROLS, ldCtrls); + } + m_ld.connect(ldapVersion, host, port, user, passwd); + } + catch (Exception e) { + throw ExceptionMapper.getNamingException(e); + } + } + + protected void finalize() { + try { + m_ld.disconnect(); + } + catch (Exception e) {} + } + + boolean isConnected() { + return (m_ld.isConnected()); + } + + + /** + * Physically disconect only if the client count is zero + */ + void disconnect() { + try { + if (m_clientCount > 0) { + m_clientCount--; + } + if (m_clientCount == 0 && isConnected()) { + m_ld.disconnect(); + } + } + catch (Exception e) {} + } + + /** + * Increment client count + */ + void incrementClientCount() { + m_clientCount++; + } + + /** + * LDAP search operation + */ + NamingEnumeration search (LdapContextImpl ctx, String name, String filter, String[] attrs, SearchControls jndiCtrls) throws NamingException{ + Debug.println(1, "SEARCH"); + String base = ctx.getDN(); + int scope = LDAPConnection.SCOPE_SUB; + LDAPSearchConstraints cons=ctx.getSearchConstraints(); + boolean returnObjs = false; + + connect(); // Lazy Connect + + // Create DN by appending the name to the current context + if (name.length() > 0) { + if (base.length() > 0) { + base = name + "," + base; + } + else { + base = name; + } + } + + // Map JNDI SearchControls to ldapjdk LDAPSearchConstraints + if (jndiCtrls != null) { + int maxResults = (int)jndiCtrls.getCountLimit(); + int timeLimitInMsec = jndiCtrls.getTimeLimit(); + // Convert timeLimit in msec to sec + int timeLimit = timeLimitInMsec/1000; + if (timeLimitInMsec > 0 && timeLimitInMsec < 1000) { + timeLimit = 1; //sec + } + + // Clone cons if maxResults or timeLimit is different from the default one + if (cons.getServerTimeLimit() != timeLimit || cons.getMaxResults() != maxResults) { + cons = (LDAPSearchConstraints)cons.clone(); + cons.setMaxResults(maxResults); + cons.setServerTimeLimit(timeLimit); + } + + // TODO The concept of links is not well described in JNDI docs. + // We can only specify dereferencing of Aliases, but Links and + // Aliases are not the same; IGNORE jndiCtrls.getDerefLinkFlag() + + // Attributes to return + attrs = jndiCtrls.getReturningAttributes(); + if (attrs != null && attrs.length==0) { + //return no attributes + attrs = new String[] { "1.1" }; + + // TODO check whether ldap compare operation should be performed + // That's the case if: (1) scope is OBJECT_SCOPE, (2) no attrs + // are requested to return (3) filter has the form (name==value) + // where no wildcards ()&|!=~><* are used. + + } + + // Search scope + scope = ProviderUtils.jndiSearchScopeToLdap(jndiCtrls.getSearchScope()); + + // return obj flag + returnObjs = jndiCtrls.getReturningObjFlag(); + } + + try { + // Perform Search + boolean attrsOnly = ctx.m_ctxEnv.getAttrsOnlyFlag(); + LDAPSearchResults res = m_ld.search( base, scope, filter, attrs, attrsOnly, cons ); + return new SearchResultEnum(res, returnObjs, ctx); + } + catch (LDAPReferralException e) { + throw new LdapReferralException(ctx, e); + } + catch (LDAPException e) { + throw ExceptionMapper.getNamingException(e); + } + } + + /** + * List child entries using LDAP lookup operation + */ + NamingEnumeration listEntries(LdapContextImpl ctx, String name, boolean returnBindings) throws NamingException{ + Debug.println(1, "LIST " + (returnBindings ? "BINDINGS" : "")); + String base = ctx.getDN(); + + connect(); // Lazy Connect + + // Create DN by appending the name to the current context + if (name.length() > 0) { + if (base.length() > 0) { + base = name + "," + base; + } + else { + base = name; + } + } + + try { + // Perform One Level Search + String[] attrs = null; // return all attributes if Bindings are requested + if (!returnBindings) { // for ClassNamePairs + attrs = new String[]{"javaclassname"}; //attr names must be in lowercase + } + LDAPSearchConstraints cons=ctx.getSearchConstraints(); + LDAPSearchResults res = m_ld.search( base, LDAPConnection.SCOPE_ONE, DEFAULT_FILTER, attrs, /*attrsOnly=*/false, cons); + if (returnBindings) { + return new BindingEnum(res, ctx); + } + else { + return new NameClassPairEnum(res, ctx); + } + } + catch (LDAPReferralException e) { + throw new LdapReferralException(ctx, e); + } + catch (LDAPException e) { + throw ExceptionMapper.getNamingException(e); + } + } + + /** + * Lookup an entry using LDAP search operation + */ + Object lookup(LdapContextImpl ctx, String name) throws NamingException{ + Debug.println(1, "LOOKUP"); + String base = ctx.getDN(); + + connect(); // Lazy Connect + + // Create DN by appending the name to the current context + if (name.length() > 0) { + if (base.length() > 0) { + base = name + "," + base; + } + else { + base = name; + } + } + + try { + // Perform Base Search + String[] attrs = null; // return all attrs + LDAPSearchConstraints cons=ctx.getSearchConstraints(); + LDAPSearchResults res = m_ld.search( base, LDAPConnection.SCOPE_BASE, DEFAULT_FILTER, attrs, /*attrsOnly=*/false, cons); + if (res.hasMoreElements()) { + LDAPEntry entry = res.next(); + return ObjectMapper.entryToObject(entry, ctx); + } + return null; // should never get here + + } + catch (LDAPReferralException e) { + throw new LdapReferralException(ctx, e); + } + catch (LDAPException e) { + throw ExceptionMapper.getNamingException(e); + } + } + + /** + * Read LDAP entry attributes + */ + Attributes readAttrs (LdapContextImpl ctx, String name, String[] attrs) throws NamingException{ + Debug.println(1, "READ ATTRS"); + String base = ctx.getDN(); + int scope = LDAPConnection.SCOPE_BASE; + + connect(); // Lazy Connect + + // Create DN by appending the name to the current context + if (name.length() > 0) { + if (base.length() > 0) { + base = name + "," + base; + } + else { + base = name; + } + } + + try { + // Perform Search + LDAPSearchConstraints cons=ctx.getSearchConstraints(); + LDAPSearchResults res = m_ld.search(base, scope, DEFAULT_FILTER, attrs, /*attrsOnly=*/false, cons); + while (res.hasMoreElements()) { + LDAPEntry entry = res.next(); + return new AttributesImpl(entry.getAttributeSet(), + ctx.m_ctxEnv.getUserDefBinaryAttrs()); + } + return null; + } + catch (LDAPReferralException e) { + throw new LdapReferralException(ctx, e); + } + catch (LDAPException e) { + throw ExceptionMapper.getNamingException(e); + } + } + + /** + * Modify LDAP entry attributes + */ + void modifyEntry(LdapContextImpl ctx, String name, LDAPModificationSet mods) throws NamingException{ + Debug.println(1, "MODIFY"); + String base = ctx.getDN(); + + if (mods.size() == 0) { + return; + } + connect(); // Lazy Connect + + // Create DN by appending the name to the current context + if (name.length() > 0) { + if (base.length() > 0) { + base = name + "," + base; + } + else { + base = name; + } + } + + try { + // Perform Modify + m_ld.modify(base, mods); + } + catch (LDAPReferralException e) { + throw new LdapReferralException(ctx, e); + } + catch (LDAPException e) { + throw ExceptionMapper.getNamingException(e); + } + } + + /** + * Create a new LDAP entry + */ + LdapContextImpl addEntry(LdapContextImpl ctx, String name, LDAPAttributeSet attrs) throws NamingException{ + Debug.println(1, "ADD"); + String dn = ctx.getDN(); + + connect(); // Lazy Connect + + // Create DN by appending the name to the current context + if (name.length() == 0) { + throw new IllegalArgumentException("Name can not be empty"); + } + if (dn.length() > 0) { + dn = name + "," + dn; + } + else { + dn = name; + } + + try { + // Add a new entry + m_ld.add(new LDAPEntry(dn, attrs)); + return new LdapContextImpl(dn, ctx); + } + catch (LDAPReferralException e) { + throw new LdapReferralException(ctx, e); + } + catch (LDAPException e) { + throw ExceptionMapper.getNamingException(e); + } + } + + /** + * Delete a LDAP entry + */ + void delEntry(LdapContextImpl ctx, String name) throws NamingException{ + Debug.println(1, "DELETE"); + String dn = ctx.getDN(); + + connect(); // Lazy Connect + + // Create DN by appending the name to the current context + if (name.length() == 0) { + throw new IllegalArgumentException("Name can not be empty"); + } + if (dn.length() > 0) { + dn = name + "," + dn; + } + else { + dn = name; + } + + try { + // Perform Delete + m_ld.delete(dn); + } + catch (LDAPReferralException e) { + throw new LdapReferralException(ctx, e); + } + catch (LDAPException e) { + throw ExceptionMapper.getNamingException(e); + } + } + + /** + * Chanage RDN for a LDAP entry + */ + void changeRDN(LdapContextImpl ctx, String name, String newRDN) throws NamingException{ + Debug.println(1, "RENAME"); + String dn = ctx.getDN(); + + connect(); // Lazy Connect + + // Create DN by appending the name to the current context + if (name.length() == 0 || newRDN.length() == 0) { + throw new IllegalArgumentException("Name can not be empty"); + } + if (dn.length() > 0) { + dn = name + "," + dn; + } + else { + dn = name; + } + + try { + // Rename + m_ld.rename(dn, newRDN, ctx.m_ctxEnv.getDeleteOldRDNFlag()); + } + catch (LDAPReferralException e) { + throw new LdapReferralException(ctx, e); + } + catch (LDAPException e) { + throw ExceptionMapper.getNamingException(e); + } + } + + /** + * Schema Operations + */ + DirContext getSchema(String name) throws NamingException { + connect(); // Lazy Connect + return new SchemaRoot(m_ld); + } + + /** + * Return the event service + */ + EventService getEventService() throws NamingException { + connect(); // Lazy Connect + if (m_eventSvc == null) { + m_eventSvc = new EventService(this); + } + return m_eventSvc; + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/NameClassPairEnum.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/NameClassPairEnum.java new file mode 100644 index 00000000000..cf96dd3d228 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/NameClassPairEnum.java @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; +import com.netscape.jndi.ldap.common.ExceptionMapper; + +import netscape.ldap.*; + +import java.util.*; + +/** + * Wrapper for the LDAPSearchResult. Convert each LDAPEntry entry into + * a JNDI NameClassPair. NameClassPairs are accessed through the NamingEnumeration + * interface + */ +class NameClassPairEnum implements NamingEnumeration { + + LDAPSearchResults m_res; + LdapContextImpl m_ctx; + Name m_ctxName; + + public NameClassPairEnum(LDAPSearchResults res, LdapContextImpl ctx) throws NamingException{ + m_res = res; + m_ctx = ctx; + try { + m_ctxName = LdapNameParser.getParser().parse(m_ctx.m_ctxDN); + } + catch ( NamingException e ) { + throw ExceptionMapper.getNamingException(e); + } + } + + public Object next() throws NamingException{ + try { + LDAPEntry entry = m_res.next(); + String name = LdapNameParser.getRelativeName(m_ctxName, entry.getDN()); + String className = ObjectMapper.getClassName(entry); + return new NameClassPair(name, className, /*isRelative=*/true); + + } + catch (LDAPReferralException e) { + throw new LdapReferralException(m_ctx, e); + } + catch ( LDAPException e ) { + throw ExceptionMapper.getNamingException(e); + } + } + + public Object nextElement() { + try { + return next(); + } + catch ( Exception e ) { + System.err.println( "Error in NameClassPairEnum.nextElement(): " + e.toString() ); + e.printStackTrace(System.err); + return null; + } + } + + public boolean hasMore() throws NamingException{ + return m_res.hasMoreElements(); + } + + public boolean hasMoreElements() { + return m_res.hasMoreElements(); + } + + public void close() throws NamingException{ + try { + m_ctx.m_ldapSvc.getConnection().abandon(m_res); + } + catch (LDAPException e) { + throw ExceptionMapper.getNamingException(e); + } + } +} + diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/ObjectMapper.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/ObjectMapper.java new file mode 100644 index 00000000000..50257f390c7 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/ObjectMapper.java @@ -0,0 +1,473 @@ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.spi.*; +import netscape.ldap.*; +import netscape.ldap.util.*; +import java.io.*; +import java.util.*; +import com.netscape.jndi.ldap.common.Debug; + +/** + * Class used to map Java objects to ldap entries back and forth +*/ +public class ObjectMapper { + + /** + * Schema object classes for mapping java objects to ldap entries + */ + static final String OC_JAVAOBJECT = "javaObject"; // abstract oc + static final String OC_SERIALOBJ = "javaSerializedObject";//aux oc + static final String OC_REFERENCE = "javaNamingReference"; //aux oc + static final String OC_REMOTEOBJ = "javaRemoteObject"; //aux oc + static final String OC_CONTAINER = "javaContainer"; //structural oc + + /** + * Schema attributes for mapping java objects to ldap entries + */ + static final String AT_CLASSNAME = "javaClassName"; //required + static final String AT_CODEBASE = "javaCodeBase"; //optional + static final String AT_SERIALDATA = "javaSerializedData"; //required + static final String AT_REFADDR = "javaReferenceAddress"; //optional + static final String AT_OBJFACTORY = "javaFactory"; //optional + static final String AT_REMOTELOC = "javaRemoteLocation"; //required + + //Default Object class for NameClassPair + static final String DEFAULT_OBJCLASS = "javax.naming.directory.DirContext"; + + static Object entryToObject(LDAPEntry entry, LdapContextImpl ctx) throws NamingException { + Object obj = entryToObject(entry); + if (obj == null) { + obj = new LdapContextImpl(entry.getDN(), ctx); + } + + // SP is required to contact the NamingManager first to obtain an object + try { + String relName = LdapNameParser.getRelativeName(ctx.m_ctxDN, entry.getDN()); + Name nameObj = LdapNameParser.getParser().parse(relName); + obj = NamingManager.getObjectInstance(obj, nameObj, ctx, ctx.getEnvironment()); + } + catch (Exception ex) { + if (ex instanceof NamingException) { + throw (NamingException)ex; + } + NamingException nameEx = new NamingException("NamingManager.getObjectInstance failed"); + nameEx.setRootCause(ex); + throw nameEx; + } + + return obj; + + } + + /** + * Convert a Ldap entry into a java object + */ + static Object entryToObject(LDAPEntry entry) throws NamingException { + + try { + LDAPAttributeSet attrs = entry.getAttributeSet(); + + // TODO javaCodeBase to be processed + + LDAPAttribute attr = null; + if ((attr = attrs.getAttribute(AT_SERIALDATA)) != null) { + byte[] serdata = (byte[])attr.getByteValues().nextElement(); + return deserializeObject(serdata); + } + + // Reference + else if ((attr = attrs.getAttribute(AT_REFADDR)) != null) { + return decodeRefObj(attrs); + } + + // RMI Object + else if ((attr = attrs.getAttribute(AT_REMOTELOC)) != null) { + String rmiURL = (String)attr.getByteValues().nextElement(); + return java.rmi.Naming.lookup(rmiURL); + } + + return null; + } + catch (Exception ex) { + if (ex instanceof NamingException) { + throw (NamingException)ex; + } + NamingException nameEx = new NamingException("NamingManager.getStateToStore failed"); + nameEx.setRootCause(ex); + throw nameEx; + } + } + + /** + * Get the className for NameClassPair from an entry + */ + static String getClassName(LDAPEntry entry) { + LDAPAttributeSet attrs = entry.getAttributeSet(); + LDAPAttribute attrClass = attrs.getAttribute(AT_CLASSNAME); + if (attrClass != null) { + String className = (String)attrClass.getStringValues().nextElement(); + return className; + } + return DEFAULT_OBJCLASS; + } + + + /** + * Convert a java object with an optional set of attributes into a LDAP entry + */ + static LDAPAttributeSet objectToAttrSet(Object obj, String name, LdapContextImpl ctx, Attributes attrs) throws NamingException { + + // SP is required to contact the NamingManager first to obtain a state object + try { + Name nameObj = LdapNameParser.getParser().parse(name); + obj = NamingManager.getStateToBind(obj, nameObj, ctx, ctx.getEnvironment()); + } + catch (Exception ex) { + if (ex instanceof NamingException) { + throw (NamingException)ex; + } + NamingException nameEx = new NamingException("NamingManager.getStateToStore failed"); + nameEx.setRootCause(ex); + throw nameEx; + } + + if (attrs == null) { + attrs = new BasicAttributes(/*ignoreCase=*/true); + } + + Attribute objectclass = attrs.get("objectClass"); + if (objectclass == null) { + objectclass = new BasicAttribute("objectClass", "top"); + attrs.put(objectclass); + } + + // Root object class + objectclass.add(OC_JAVAOBJECT); + + if (obj instanceof Reference) { + objectclass.add(OC_REFERENCE); + char delimChar = ctx.m_ctxEnv.getRefSeparator(); + attrs = encodeRefObj(delimChar, (Reference)obj, attrs); + } + + else if (obj instanceof Referenceable) { + objectclass.add(OC_REFERENCE); + char delimChar = ctx.m_ctxEnv.getRefSeparator(); + attrs = encodeRefObj(delimChar, ((Referenceable)obj).getReference(), attrs); + } + + else if (obj instanceof java.rmi.Remote) { + objectclass.add(OC_REMOTEOBJ); + attrs = encodeRMIObj((java.rmi.Remote)obj, attrs); + } + + else if (obj instanceof Serializable) { + objectclass.add(OC_SERIALOBJ); + attrs = encodeSerialObj((Serializable)obj , attrs); + } + + else if (obj instanceof DirContext) { + attrs = encodeDirCtxObj((DirContext)obj , attrs); + } + + else { + throw new NamingException("Can not bind object of type " + + obj.getClass().getName()); + } + + return AttributesImpl.jndiAttrsToLdapAttrSet(attrs); + } + + /** + * Deserialized object, create object from a stream of bytes + */ + private static Object deserializeObject(byte[] byteBuf) throws NamingException { + + ByteArrayInputStream bis = null; + ObjectInputStream objis = null; + + try { + bis = new ByteArrayInputStream(byteBuf); + objis = new ObjectInputStream(bis); + return objis.readObject(); + } + catch(Exception ex) { + NamingException nameEx = new NamingException("Failed to deserialize object"); + nameEx.setRootCause(ex); + throw nameEx; + } + finally { + try { + if (objis != null) { + objis.close(); + } + if (bis != null) { + bis.close(); + } + } + catch (Exception ex) {} + } + } + + + /** + * Serialize object, convert object to a stream of bytes + */ + private static byte[] serializeObject(Object obj) throws NamingException { + + ByteArrayOutputStream bos = null; + ObjectOutputStream objos = null; + + try { + bos = new ByteArrayOutputStream(); + objos = new ObjectOutputStream(bos); + objos.writeObject(obj); + objos.flush(); + return bos.toByteArray(); + } + catch(Exception ex) { + NamingException nameEx = new NamingException("Failed to serialize object"); + nameEx.setRootCause(ex); + throw nameEx; + } + finally { + try { + if (objos != null) { + objos.close(); + } + if (bos != null) { + bos.close(); + } + } + catch (Exception ex) {} + } + } + + /** + * Decode Jndi Reference Object + */ + private static Reference decodeRefObj(LDAPAttributeSet attrs) throws NamingException { + try { + + LDAPAttribute attr = null; + String className=null, factory = null, factoryLoc = null; + if ((attr = attrs.getAttribute(AT_CLASSNAME)) == null ) { + throw new NamingException("Bad Reference encoding, no attribute " + AT_CLASSNAME); + } + className = (String)attr.getStringValues().nextElement(); + + if ((attr = attrs.getAttribute(AT_OBJFACTORY)) != null ) { + factory = (String)attr.getStringValues().nextElement(); + } + if ((attr = attrs.getAttribute(AT_CODEBASE)) != null ) { + factoryLoc = (String)attr.getStringValues().nextElement(); + } + + Reference ref = new Reference(className, factory, factoryLoc); + + if ((attr = attrs.getAttribute(AT_REFADDR)) == null ) { + return ref; // no refAddr + } + + for (Enumeration e = attr.getStringValues(); e.hasMoreElements();) { + decodeRefAddr((String)e.nextElement(), ref); + } + + return ref; + } + catch (Exception ex) { + if (ex instanceof NamingException) { + throw (NamingException)ex; + } + NamingException nameEx = new NamingException("NamingManager.getStateToStore failed"); + nameEx.setRootCause(ex); + throw nameEx; + } + } + + /** + * Decode RefAddr according to the + * StringRefAddr are encoded as #posNo#refType#refValue where posNo is the + * refAddr position (index) inside a rerference. BynaryRefAddr is encoded + * as #posNo#refType##data where data is the base64 encoding of the serialized + * form of the entire BinaryRefAddr instance. + */ + private static void decodeRefAddr(String enc, Reference ref) throws NamingException{ + + if (enc.length() == 0) { + throw new NamingException("Bad Reference encoding, empty refAddr"); + } + + String delimChar = enc.substring(0,1); + + StringTokenizer tok = new StringTokenizer(enc, delimChar); + + int tokCount = tok.countTokens(); + if (tokCount != 3 && tokCount != 4) { + Debug.println(3, "enc=" + enc + " delimChar="+delimChar + " tokCount="+tokCount); + throw new NamingException("Bad Reference encoding"); + } + + String type = null; + int posn = -1; + for (int i = 0; i < tokCount; i++) { + String s = tok.nextToken(); + + if (i == 0) { // position + try { + posn = Integer.parseInt(s); + } + catch (Exception e) { + throw new NamingException("Bad Reference encoding, refAddr position not an initger"); + } + } + + else if (i == 1) { // type + if (s.length() == 0) { + throw new NamingException("Bad Reference encoding, empty refAddr type"); + } + type = s; + } + + else if (i == 2) { // value for StringRefAddr, empty for BinaryRefAddr + if (s.length() == 0 && tokCount != 4) { // should be empty for binary refs + throw new NamingException("Bad Reference encoding, empty refAddr string value"); + } + ref.add(posn, new StringRefAddr(type, s)); + } + + else { // base64 encoding of the serialized BinaryRefAddr + if (s.length() == 0) { + throw new NamingException("Bad Reference encoding, empty refAddr binary value"); + } + MimeBase64Decoder base64Dec = new MimeBase64Decoder(); + ByteBuf in = new ByteBuf(s), out = new ByteBuf(); + base64Dec.translate(in, out); + base64Dec.eof(out); + ref.add(posn, (RefAddr) deserializeObject(out.toBytes())); + } + } + } + + + /** + * Encode Jndi Reference Object + */ + private static Attributes encodeRefObj(char delimChar, Reference ref, Attributes attrs) throws NamingException { + + if (ref.getClassName() != null) { + attrs.put(new BasicAttribute(AT_CLASSNAME, ref.getClassName())); + } + if (ref.getFactoryClassName() != null) { + attrs.put(new BasicAttribute(AT_OBJFACTORY, ref.getFactoryClassName())); + } + if (ref.getFactoryClassLocation() != null) { + attrs.put(new BasicAttribute(AT_CODEBASE, ref.getFactoryClassLocation())); + } + + if(ref.size() > 0) { + BasicAttribute refAttr = new BasicAttribute(AT_REFADDR); + for(int i = 0; i < ref.size(); i++) { + refAttr.add(encodeRefAddr(delimChar, i, ref.get(i))); + } + attrs.put(refAttr); + } + return attrs; + } + + /** + * Encode RefAddr according to the + * StringRefAddr are encoded as #posNo#refType#refValue where posNo is the + * refAddr position (index) inside a rerference. BynaryRefAddr is encoded + * as #posNo#refType##data where data is the base64 encoding of the serialized + * form of the entire BinaryRefAddr instance. + + */ + private static String encodeRefAddr(char delimChar, int idx, RefAddr refAddr) throws NamingException{ + + if(refAddr instanceof StringRefAddr) { + + String content = (String) refAddr.getContent(); + if (content != null && content.length() > 0 && content.charAt(0) == delimChar) { + throw new NamingException( + "Can not encode StringRefAddr, value starts with the delimiter character " + delimChar); + } + return delimChar + idx + + delimChar + refAddr.getType() + + delimChar + content; + } + + else { // BinaryRefAdd + + byte[] serialRefAddr = serializeObject(refAddr); + MimeBase64Encoder base64 = new MimeBase64Encoder(); + ByteBuf in = new ByteBuf(), out = new ByteBuf(); + in.append(serialRefAddr); + base64.translate(in, out); + base64.eof(out); + return delimChar + idx + + delimChar + refAddr.getType() + + delimChar + delimChar + out.toString(); + } + } + + + /** + * Encode Serializable object + */ + + static Attributes encodeSerialObj(Serializable obj, Attributes attrs) throws NamingException{ + if (attrs.get(AT_CLASSNAME) == null) { + attrs.put(new BasicAttribute(AT_CLASSNAME, obj.getClass().getName())); + } + attrs.put(new BasicAttribute(AT_SERIALDATA, serializeObject(obj))); + return attrs; + } + + /** + * Encode RMI Object + */ + static Attributes encodeRMIObj(java.rmi.Remote obj, Attributes attrs) throws NamingException{ + if (attrs.get(AT_REMOTELOC) == null) { + throw new NamingException( + "Can not bind Remote object, " + AT_REMOTELOC + " not specified"); + } + if (attrs.get(AT_CLASSNAME) == null) { + attrs.put(new BasicAttribute(AT_CLASSNAME, obj.getClass().getName())); + } + return attrs; + } + + /** + * Encode DirContext object (merege attributes) + */ + static Attributes encodeDirCtxObj(DirContext obj, Attributes attrs) throws NamingException{ + Attributes ctxAttrs = obj.getAttributes(""); + for (NamingEnumeration enum = ctxAttrs.getAll(); enum.hasMore();) { + attrs.put((Attribute)enum.next()); + } + return attrs; + } + + public static void main(String[] args) { + byte[] serialRefAddr = { 'a', '0', 'A', (byte)0x10, (byte)0x7f, (byte)0xaa }; + MimeBase64Encoder base64 = new MimeBase64Encoder(); + MimeBase64Decoder base64Dec = new MimeBase64Decoder(); + ByteBuf in = new ByteBuf(), out = new ByteBuf(); + in.append(serialRefAddr); + base64.translate(in, out); + base64.eof(out); + System.err.println("in="+in); + System.err.println("out="+out); + in = new ByteBuf(out.toString()); + out = new ByteBuf(); + base64Dec.translate(in, out); + base64Dec.eof(out); + System.err.println("in="+in); + System.err.println("out="+out); + + } +} + diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/ProviderUtils.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/ProviderUtils.java new file mode 100644 index 00000000000..91f769e1c8f --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/ProviderUtils.java @@ -0,0 +1,279 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; + +import java.util.*; + +/** + * Common utility methods + * + */ +class ProviderUtils { + + public static final String DEFAULT_FILTER = "(objectclass=*)"; + + static int jndiSearchScopeToLdap(int jndiScope) throws NamingException { + int scope = -1; + if (jndiScope == SearchControls.SUBTREE_SCOPE) { + scope = LDAPConnection.SCOPE_SUB; + } + else if (jndiScope == SearchControls.ONELEVEL_SCOPE) { + scope = LDAPConnection.SCOPE_ONE; + } + else if (jndiScope == SearchControls.OBJECT_SCOPE) { + scope = LDAPConnection.SCOPE_BASE; + } + else { + throw new InvalidSearchControlsException("Illegal value for the search scope"); + } + return scope; + } + + + /** + * Convert Attribute List to a LDAP filter + * + * @return LDAP Filter + * @throw NamingException + * @param attrs An Attribute List + */ + static String attributesToFilter(Attributes attrs) throws NamingException{ + + if (attrs == null || attrs.size() == 0) { + return DEFAULT_FILTER; + } + + String filter = ""; + + for (NamingEnumeration attrEnum = attrs.getAll(); attrEnum.hasMore();) { + Attribute attrib = (Attribute) attrEnum.next(); + + //Has attributes any values + if ( attrib.size() == 0) { + // test only for presence of the attribute + filter += "(" + attrib.getID() + "=*)"; + continue; + } + + // Add attribute values to the filter, ecsaping if necessary + String attrValues = ""; + for (NamingEnumeration valEnum = attrib.getAll(); valEnum.hasMore();) { + Object val = valEnum.next(); + if (val instanceof String) { + attrValues += "(" + attrib.getID() + "=" + escapeString((String)val) +")"; + } + else if (val instanceof byte[]) { + attrValues += "(" + attrib.getID() + "=" + escapeBytes((byte[])val) +")"; + } + else if (val == null) { + //null is allowed value in Attribute.add(Object), accept it just in case + attrValues += "(" + attrib.getID() + "=*)"; + } + else { + throw new NamingException( + "Wrong Attribute value, expecting String or byte[]"); + } + } + filter += (attrib.size() > 1) ? ("(|" + attrValues + ")") : attrValues; + } + + return (attrs.size() > 1) ? ("(&" + filter + ")") : filter; + } + + + /** + * Expand filterExpr. Each occurrence of a variable "{n}", where n is a non-negative + * integer, is replaced with a variable from the filterArgs array indexed by the 'n'. + * FilterArgs can be Strings or byte[] and they are escaped according to the RFC2254 + */ + static String expandFilterExpr(String filterExpr, Object[] filterArgs) throws InvalidSearchFilterException{ + StringTokenizer tok = new StringTokenizer(filterExpr, "{}", /*returnTokens=*/true); + + if (tok.countTokens() == 1) { + return filterExpr; // No escape characters + } + + StringBuffer out= new StringBuffer(); + boolean expectVarIdx = false, expectVarOff = false; + Object arg= null; + while (tok.hasMoreTokens()) { + String s = tok.nextToken(); + + if (expectVarIdx) { + expectVarIdx = false; + try { + int idx = Integer.parseInt(s); + arg = filterArgs[idx]; + expectVarOff = true; + } + catch (IndexOutOfBoundsException e) { + throw new InvalidSearchFilterException("Filter expression variable index out of bounds"); + } + + catch (Exception e) { + throw new InvalidSearchFilterException("Invalid filter expression"); + } + } + + else if (expectVarOff) { + expectVarOff = false; + if (!s.equals("}")) { + throw new InvalidSearchFilterException("Invalid filter expression"); + } + if (arg instanceof String) { + out.append(escapeString((String)arg)); + } + else if (arg instanceof byte[]) { + out.append(escapeBytes((byte[])arg)); + } + else { + throw new InvalidSearchFilterException("Invalid filter argument type"); + } + arg = null; + } + + else if (s.equals("{")) { + expectVarIdx = true; + } + else { + out.append(s); + } + } + if (expectVarIdx || expectVarOff) { + throw new InvalidSearchFilterException("Invalid filter expression"); + } + return out.toString(); + } + + + /** + * Escape a string according to the RFC 2254 + */ + static String escapeString(String str) { + String charToEscape = "\\*()\000"; + StringTokenizer tok = new StringTokenizer(str, charToEscape, /*returnTokens=*/true); + + if (tok.countTokens() == 1) { + return str; // No escape characters + } + + StringBuffer out= new StringBuffer(); + while (tok.hasMoreTokens()) { + String s = tok.nextToken(); + + if (s.equals("*")) { + out.append("\\2a"); + } + else if (s.equals("(")) { + out.append("\\28"); + } + else if (s.equals(")")) { + out.append("\\29"); + } + else if (s.equals("\\")) { + out.append("\\5c"); + } + else if (s.equals("\000")) { + out.append("\\00"); + } + else { + out.append(s); + } + } + return out.toString(); + } + + + /** + * Escape a byte array according to the RFC 2254 + */ + static final String hexDigits="0123456789abcdef"; + + static String escapeBytes(byte[] bytes) { + StringBuffer out = new StringBuffer(""); + for (int i=0; i < bytes.length; i++) { + + int low = bytes[i] & 0x0f; + int high = (bytes[i] & 0xf0) >> 4; + out.append("\\"); + out.append(hexDigits.charAt(high)); + out.append(hexDigits.charAt(low)); + } + return out.toString(); + } + + /** + * A method used only for testing + */ + private static void testAttributesToFilter() { + try { + System.out.println(attributesToFilter(null)); + + BasicAttributes attrs = new BasicAttributes(true); + + System.out.println(attrs + " = " + attributesToFilter(attrs)); + + attrs.put (new BasicAttribute("attr1", "val1")); + attrs.put (new BasicAttribute("attr2", "(val2)\\*x")); + attrs.put (new BasicAttribute("attr3")); + BasicAttribute attr4 = new BasicAttribute("attr4", "val41"); + attr4.add("val42"); + attrs.put(attr4); + attrs.put("attr5", new byte[] { (byte)0x23, (byte)0x3, (byte)0x0, (byte)0xab, (byte)0xff}); + System.out.println(attrs + " = " +attributesToFilter(attrs)); + } + catch (Exception e) { + System.err.println(e); + } + } + + /** + * A method used only for testing + */ + private static void testFilterExpr() { + try { + String filterExpr = "(&(attr0={0})(attr1={1}))"; + Object [] args = new Object[] { "val*0", new byte[] { (byte)0xf0, (byte) 0x3a}}; + String filter = null; + filter = expandFilterExpr(filterExpr, args); + System.out.println(filterExpr + " -> " + filter); + } + catch (Exception e) { + System.err.println(e); + } + } + + /** + * Test + */ + public static void main(String[] args) { + /*testAttributesToFilter(); + String x = "012\0003"; + byte[] b = x.getBytes(); + for (int i=0; i < b.length; i++) { + System.out.println(i+"="+b[i]); + }*/ + testFilterExpr(); + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/SearchResultEnum.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/SearchResultEnum.java new file mode 100644 index 00000000000..a344d843164 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/SearchResultEnum.java @@ -0,0 +1,122 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; +import com.netscape.jndi.ldap.controls.NetscapeControlFactory; +import com.netscape.jndi.ldap.common.ExceptionMapper; +import netscape.ldap.*; +import java.util.*; + +/** + * A wrapper for the LDAPSeatchResults. Convert a LDAPSearchResults enumeration + * of LDAPEntries into a JNDI NamingEnumeration of JNDI SearchResults. + */ +class SearchResultEnum implements NamingEnumeration { + + LDAPSearchResults m_res; + boolean m_returnObjs; // ReturningObjFlag in SearchControls + LdapContextImpl m_ctx; + Name m_ctxName; + String[] m_userBinaryAttrs; + LDAPConnection m_ld; + + public SearchResultEnum(LDAPSearchResults res, boolean returnObjs, LdapContextImpl ctx) throws NamingException{ + m_res = res; + m_returnObjs = returnObjs; + m_ctx = ctx; + m_userBinaryAttrs = ctx.m_ctxEnv.getUserDefBinaryAttrs(); + + m_ld = m_ctx.m_ldapSvc.getConnection(); + try { + m_ctxName = LdapNameParser.getParser().parse(m_ctx.m_ctxDN); + } + catch ( NamingException e ) { + throw ExceptionMapper.getNamingException(e); + } + } + + public Object next() throws NamingException{ + try { + LDAPEntry entry = m_res.next(); + String name = LdapNameParser.getRelativeName(m_ctxName, entry.getDN()); + Object obj = (m_returnObjs) ? ObjectMapper.entryToObject(entry, m_ctx) : null; + Attributes attrs = new AttributesImpl(entry.getAttributeSet(), m_userBinaryAttrs); + + // check for response controls + LDAPControl[] ldapCtls = m_ld.getResponseControls(); + if (ldapCtls != null) { + // Parse raw controls + Control[] ctls = new Control[ldapCtls.length]; + for (int i=0; i < ldapCtls.length; i++) { + ctls[i] = NetscapeControlFactory.getControlInstance(ldapCtls[i]); + if (ctls[i] == null) { + throw new NamingException("Unsupported control " + ldapCtls[i].getID()); + } + } + + SearchResultWithControls searchRes = + new SearchResultWithControls(name, obj, attrs); + searchRes.setControls(ctls); + + return searchRes; + } + else { // no controls + return new SearchResult(name, obj, attrs); + } + + } + catch (LDAPReferralException e) { + throw new LdapReferralException(m_ctx, e); + } + catch ( LDAPException e ) { + throw ExceptionMapper.getNamingException(e); + } + } + + public Object nextElement() { + try { + return next(); + } + catch ( Exception e ) { + System.err.println( "Error in SearchResultEnum.nextElement(): " + e.toString() ); + e.printStackTrace(System.err); + return null; + } + } + + public boolean hasMore() throws NamingException { + return m_res.hasMoreElements(); + } + + public boolean hasMoreElements() { + return m_res.hasMoreElements(); + } + + public void close() throws NamingException{ + try { + m_ld.abandon(m_res); + } + catch (LDAPException e) { + throw ExceptionMapper.getNamingException(e); + } + } +} + diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/SearchResultWithControls.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/SearchResultWithControls.java new file mode 100644 index 00000000000..eeedcb406aa --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/SearchResultWithControls.java @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap; + +import javax.naming.ldap.*; +import javax.naming.directory.*; + +/** + * An extension of SearchResult that allows access to controls sent + * back with the results of a search + */ +class SearchResultWithControls extends SearchResult implements HasControls { + + Control[] m_ctrls; + + /** + * Enable constructors + */ + public SearchResultWithControls(String name, Object obj, Attributes attrs) { + super(name, obj, attrs); + } + + public SearchResultWithControls(String name, Object obj, Attributes attrs, boolean isRelative) { + super(name, obj, attrs, isRelative); + } + + public SearchResultWithControls(String name, String className, Object obj, Attributes attrs) { + super(name, className, obj, attrs); + } + + public SearchResultWithControls(String name, String className, Object obj, Attributes attrs, boolean isRelative) { + super(name, className, obj, attrs, isRelative); + } + + /** + * Implements HasControls interface + */ + public Control[] getControls() { + return m_ctrls; + } + + /** + * Set controls array + */ + public void setControls(Control[] ctrls) { + m_ctrls = ctrls; + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/Debug.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/Debug.java new file mode 100644 index 00000000000..a5b435bfb72 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/Debug.java @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.common; + + +/** + * Class used to selectivly enable debug statements + */ +public class Debug { + + // lower number is a higher priority message. Level 0 is the + // highest priority to be used ONLY for errors + private static int m_level = 0; + + static { + try { + String level = System.getProperty("jndi.netscape.debug"); + if (level != null) { + m_level = Integer.parseInt(level); + } + } + catch (Exception e) {} + } + + + /** + * Set the debug level. To disable debugging set the level to -1 + */ + public static void setDebugLevel(int level) { + m_level = level; + } + + /** + * Get the debug level. If -1 is returned, then debugging is disabled + */ + public static int getDebugLevel() { + return m_level; + } + + /** + * Print the message if its debug level is enabled + */ + public static void println(int level, String msg) { + if (m_level >= 0 && level <= m_level) { + System.err.println(msg); + } + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/DirContextAdapter.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/DirContextAdapter.java new file mode 100644 index 00000000000..215c2558cf8 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/DirContextAdapter.java @@ -0,0 +1,251 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.common; + +import javax.naming.*; +import javax.naming.directory.*; + +import java.util.Hashtable; + +public class DirContextAdapter implements DirContext { + +/* Context Methods */ + + public Object addToEnvironment(String propName, Object propValue) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void bind(String name, Object obj) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void bind(Name name, Object obj) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void close() throws NamingException { + throw new OperationNotSupportedException(); + } + + public String composeName(String name, String prefix) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Name composeName(Name name, Name prefix) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Context createSubcontext(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Context createSubcontext(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void destroySubcontext(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void destroySubcontext(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Hashtable getEnvironment() throws NamingException { + throw new OperationNotSupportedException(); + } + + public String getNameInNamespace() throws NamingException { + throw new OperationNotSupportedException(); + } + + public NameParser getNameParser(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NameParser getNameParser(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration list(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration list(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration listBindings(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration listBindings(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Object lookup(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Object lookup(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Object lookupLink(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Object lookupLink(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void rebind(String name, Object obj) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void rebind(Name name, Object obj) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Object removeFromEnvironment(String propName) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void rename(String oldName, String newName) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void rename(Name oldName, Name newName) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void unbind(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void unbind(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + +/* DirContext Methods */ + + public void bind(String name, Object obj, Attributes attrs) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void bind(Name name, Object obj, Attributes attrs) throws NamingException { + throw new OperationNotSupportedException(); + } + + public DirContext createSubcontext(String name, Attributes attrs) throws NamingException { + throw new OperationNotSupportedException(); + } + + public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Attributes getAttributes(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Attributes getAttributes(String name, String[] attrIds) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Attributes getAttributes(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Attributes getAttributes(Name name, String[] attrIds) throws NamingException { + throw new OperationNotSupportedException(); + } + + public DirContext getSchema(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public DirContext getSchema(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public DirContext getSchemaClassDefinition(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public DirContext getSchemaClassDefinition(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void rebind(String name, Object obj, Attributes attrs) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void rebind(Name name, Object obj, Attributes attrs) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration search(String name, String filter, SearchControls cons) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration search(String name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration search(String name, Attributes matchingAttributes) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration search(String name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration search(Name name, String filter, SearchControls cons) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration search(Name name, Attributes attrs) throws NamingException { + throw new OperationNotSupportedException(); + } + + public NamingEnumeration search(Name name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException { + throw new OperationNotSupportedException(); + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/ExceptionMapper.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/ExceptionMapper.java new file mode 100644 index 00000000000..275435c7f23 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/ExceptionMapper.java @@ -0,0 +1,220 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.common; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; + +import java.util.Hashtable; + +/** + * Class used to map ldapjdk exceptions to JNDI NamingException +*/ +public class ExceptionMapper { + + public static NamingException getNamingException(Exception origException) { + + if (origException instanceof NamingException) { + return (NamingException)origException; + } + + /** + * LdapJDK exceptions + */ + else if (origException instanceof LDAPReferralException) { + // Should never get here. The ldapjdk referral exceptions + // should be explicitly captured by the ecode and converted + // into jndi LdapReferralException instances. + return new NamingException("Provider internal error, LDAPReferralException not captured"); + } + + else if (origException instanceof LDAPException) { + LDAPException ldapException = (LDAPException) origException; + int resCode = ldapException.getLDAPResultCode(); + + if (resCode == LDAPException.OPERATION_ERROR) { + NamingException nameEx = new NamingException(ldapException.toString()); + nameEx.setRootCause(ldapException); + return nameEx; + } + else if (resCode == LDAPException.PROTOCOL_ERROR) { + return new CommunicationException(ldapException.toString()); + } + else if (resCode == LDAPException.TIME_LIMIT_EXCEEDED) { + return new TimeLimitExceededException(ldapException.toString()); + } + else if (resCode == LDAPException.SIZE_LIMIT_EXCEEDED) { + return new SizeLimitExceededException(ldapException.toString()); + } + // COMPARE_FALSE should never happen, but is included here for completeness + else if (resCode == LDAPException.COMPARE_FALSE) { + NamingException nameEx = new NamingException(ldapException.toString()); + nameEx.setRootCause(ldapException); + return nameEx; + } + // COMPARE_TRUE should never happen, but is included here for completeness + else if (resCode == LDAPException.COMPARE_TRUE) { + NamingException nameEx = new NamingException(ldapException.toString()); + nameEx.setRootCause(ldapException); + return nameEx; + } + else if (resCode == LDAPException.AUTH_METHOD_NOT_SUPPORTED) { + return new AuthenticationNotSupportedException(ldapException.toString()); + } + else if (resCode == LDAPException.STRONG_AUTH_REQUIRED) { + return new AuthenticationNotSupportedException(ldapException.toString()); + } + else if (resCode == LDAPException.LDAP_PARTIAL_RESULTS) { + return new PartialResultException(ldapException.toString()); + } + // REFERRAL code should be in LDAPReferralException + else if (resCode == LDAPException.REFERRAL) { + LDAPReferralException referralEx = (LDAPReferralException)ldapException; + // TODO create jndi LdapReferralException + } + else if (resCode == LDAPException.ADMIN_LIMIT_EXCEEDED) { + return new LimitExceededException(ldapException.toString()); + } + else if(resCode == LDAPException.UNAVAILABLE_CRITICAL_EXTENSION) { + return new OperationNotSupportedException(ldapException.toString()); + } + else if (resCode == LDAPException.CONFIDENTIALITY_REQUIRED) { + return new AuthenticationNotSupportedException( + "A secure connection is required for this operation"); + } + // This shoud never propagate to the caller + else if (resCode == LDAPException.SASL_BIND_IN_PROGRESS) { + NamingException nameEx = new NamingException(ldapException.toString()); + nameEx.setRootCause(ldapException); + return nameEx; + } + else if (resCode == LDAPException.NO_SUCH_ATTRIBUTE) { + return new NoSuchAttributeException(ldapException.toString()); + } + else if (resCode == LDAPException.UNDEFINED_ATTRIBUTE_TYPE) { + return new InvalidAttributeIdentifierException(ldapException.toString()); + } + else if (resCode == LDAPException.INAPPROPRIATE_MATCHING) { + return new InvalidSearchFilterException(ldapException.toString()); + } + else if (resCode == LDAPException.CONSTRAINT_VIOLATION) { + return new InvalidSearchControlsException(ldapException.toString()); + } + else if (resCode == LDAPException.ATTRIBUTE_OR_VALUE_EXISTS) { + return new AttributeInUseException(ldapException.toString()); + } + else if (resCode == LDAPException.INVALID_ATTRIBUTE_SYNTAX) { + return new InvalidAttributeValueException(ldapException.toString()); + } + else if (resCode == LDAPException.NO_SUCH_OBJECT) { + return new NameNotFoundException(ldapException.toString()); + } + else if (resCode == LDAPException.ALIAS_PROBLEM) { + return new NamingException(ldapException.toString()); + } + else if (resCode == LDAPException.INVALID_DN_SYNTAX) { + return new InvalidNameException(ldapException.toString()); + } + else if (resCode == LDAPException.IS_LEAF) { + NamingException nameEx = new NamingException(ldapException.toString()); + nameEx.setRootCause(ldapException); + return nameEx; + } + else if (resCode == LDAPException.ALIAS_DEREFERENCING_PROBLEM) { + NamingException nameEx = new NamingException(ldapException.toString()); + nameEx.setRootCause(ldapException); + return nameEx; + } + else if (resCode == LDAPException.INAPPROPRIATE_AUTHENTICATION) { + //return new AuthenticationNotSupportedException(ldapException.toString()); + return new AuthenticationException(ldapException.toString()); + } + else if (resCode == LDAPException.INVALID_CREDENTIALS) { + return new AuthenticationException(ldapException.toString()); + } + else if (resCode == LDAPException.INSUFFICIENT_ACCESS_RIGHTS) { + return new NoPermissionException(ldapException.toString()); + } + else if (resCode == LDAPException.BUSY) { + return new ServiceUnavailableException(ldapException.toString()); + } + else if (resCode == LDAPException.UNAVAILABLE) { + return new ServiceUnavailableException(ldapException.toString()); + } + else if (resCode == LDAPException.UNWILLING_TO_PERFORM) { + return new OperationNotSupportedException(ldapException.toString()); + } + else if (resCode == LDAPException.LOOP_DETECT) { + NamingException nameEx = new NamingException(ldapException.toString()); + nameEx.setRootCause(ldapException); + return nameEx; + } + else if (resCode == LDAPException.NAMING_VIOLATION) { + return new InvalidNameException(ldapException.toString()); + } + else if (resCode == LDAPException.OBJECT_CLASS_VIOLATION) { + return new SchemaViolationException(ldapException.toString()); + } + else if (resCode == LDAPException.NOT_ALLOWED_ON_NONLEAF) { + return new ContextNotEmptyException(ldapException.toString()); + } + else if (resCode == LDAPException.NOT_ALLOWED_ON_RDN) { + return new SchemaViolationException(ldapException.toString()); + } + else if (resCode == LDAPException.ENTRY_ALREADY_EXISTS) { + return new NameAlreadyBoundException(ldapException.toString()); + } + else if (resCode == LDAPException.OBJECT_CLASS_MODS_PROHIBITED) { + return new SchemaViolationException(ldapException.toString()); + } + else if (resCode == LDAPException.SERVER_DOWN) { + return new CommunicationException(ldapException.toString()); + } + else if (resCode == LDAPException.CONNECT_ERROR) { + return new CommunicationException(ldapException.toString()); + } + + else { + // All other result codes + // 71 AFFECTS_MULTIPLE_DSAS + // 80 OTHER + // 89 PARAM_ERROR + // 92 LDAP_NOT_SUPPORTED + // 93 CONTROL_NOT_FOUND + // 94 NO_RESULTS_RETURNED + // 95 MORE_RESULTS_TO_RETURN + // 96 CLIENT_LOOP referral + // 97 REFERRAL_LIMIT_EXCEEDED referral + + NamingException nameEx = new NamingException(ldapException.toString()); + nameEx.setRootCause(ldapException); + return nameEx; + } + } + + /** + * All other Exceptions + */ + NamingException nameEx = new NamingException(origException.toString()); + nameEx.setRootCause(origException); + return nameEx; + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/LdapContextAdapter.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/LdapContextAdapter.java new file mode 100644 index 00000000000..5828b2672a7 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/LdapContextAdapter.java @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.common; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; +import javax.naming.event.*; +import java.util.Hashtable; + +public class LdapContextAdapter extends DirContextAdapter implements EventDirContext, LdapContext { + +/* LdapContext methods */ + public ExtendedResponse extendedOperation(ExtendedRequest req)throws NamingException { + throw new OperationNotSupportedException(); + } + + public Control[] getRequestControls() throws NamingException { + throw new OperationNotSupportedException(); + } + + public Control[] getResponseControls() throws NamingException { + throw new OperationNotSupportedException(); + } + + public LdapContext newInstance(Control[] reqCtls) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void reconnect() throws NamingException { + throw new OperationNotSupportedException(); + } + + public void setRequestControls(Control[] reqCtls) throws NamingException { + throw new OperationNotSupportedException(); + } + /** + * Naming Event methods + */ + public void addNamingListener(String target, int scope, NamingListener l) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void addNamingListener(Name target, int scope, NamingListener l) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void addNamingListener(String target, String filter, SearchControls ctls, NamingListener l)throws NamingException { + throw new OperationNotSupportedException(); + } + + public void addNamingListener(Name target, String filter, SearchControls ctls, NamingListener l)throws NamingException { + throw new OperationNotSupportedException(); + } + + public void addNamingListener(String target, String filter, Object[] filtrArgs, SearchControls ctls, NamingListener l)throws NamingException { + throw new OperationNotSupportedException(); + } + + public void addNamingListener(Name target, String filter, Object[] filtrArgs, SearchControls ctls, NamingListener l)throws NamingException { + throw new OperationNotSupportedException(); + } + + public void removeNamingListener(NamingListener l) throws NamingException { + throw new OperationNotSupportedException(); + } + + public boolean targetMustExist() { + return true; + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/ShareableEnv.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/ShareableEnv.java new file mode 100644 index 00000000000..06340a9b21b --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/common/ShareableEnv.java @@ -0,0 +1,404 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.common; + +import java.util.*; + +/** + * ShareableEnv manages a set of environment properties. The class enables a memory + * efficient sharing of the environment between multiple contexts, while preserving + * the semantics that each context has its own environment. If the environment for a + * context is changed, the change is not visible to other contexts. + * + * The efficiency is achieved by implementing inheritance and override of environment + * properties ("subclass-on-write"). A read-only table of properties + * is shared among multiple contexts (_sharedEnv. If a context wants to + * modified a shared property, it will create a separate table (_privateEnv) + * to make the modifications. This table overrides the values in the shared table. + * + * Note1: The class is not thread safe, it requires external synchronization + * Note2: The class does not provide enumaration. Call getAllProperties() and then + * use the standard Hashtable enumaration techniques. + */ +public class ShareableEnv implements Cloneable{ + + /** + * A special value that denotes a removed propety. Because shared property tables + * are read-only, a shared property is deleted in the curent context by assigning + * the REMOVED_PROPERTY value in the _modEnv table. + */ + private static final Object REMOVED_PROPERTY = new Object(); + + /** + * A table of most recent environment modifications. These modifications are not + * shared until the current context is cloned, which moves _privateEnv to + * _sharedEnv + */ + protected Hashtable m_privateEnv; + + /** + * A set of environment propeties that have been changed in this Context and are + * shared with one or more child contexts. Read-only access. + */ + protected Vector m_sharedEnv; // A vector of Hashtables + + /** + * Shared environment inherited from the parent context + */ + protected ShareableEnv m_parentEnv; + + /** + * Index into parent _sharedEnv list. Designates all environment chnages + * in the parent context that are visible to this child context + */ + protected int m_parentSharedEnvIdx = -1; + + /** + * No-arg constructor is private + */ + private ShareableEnv() {} + + /** + * Constructor for non root Contexts + * + * @param parent A reference to the parent context environment + * @param parentSharedEnvIdx index into parent's shared environemnt list + */ + public ShareableEnv(ShareableEnv parent, int parentSharedEnvIdx) { + m_parentEnv = parent; + m_parentSharedEnvIdx = parentSharedEnvIdx; + } + + /** + * Constructor for the root context + * + * @param initialEnv a hashtable with environemnt properties + */ + public ShareableEnv(Hashtable initialEnv) { + m_privateEnv = initialEnv; + } + + /** + * Set the property value. + * + * @return the previous value of the specified property, + * or null if it did not exist before. + * @param prop property name + * @param val property value + */ + public Object setProperty(String prop, Object val) { + + // Need the current value to be returned + Object oldVal = getProperty(prop); + + // Lazy create _privateEnv table + if (m_privateEnv == null) { + m_privateEnv = new Hashtable(5); + } + + // Add/Modify property + m_privateEnv.put(prop, val); + + return oldVal; + } + + /** + * Get the property value. + * + * @return the object associated with the property name + * or null if property is not found + * @param prop property name + */ + public Object getProperty(String prop) { + + // First check most recent modifications + if (m_privateEnv != null) { + Object val = m_privateEnv.get(prop); + if (val != null) { + return (val == REMOVED_PROPERTY) ? null : val; + } + } + + // Then try shared properties + if (m_sharedEnv != null) { + return getSharedProperty(m_sharedEnv.size()-1, prop); + } + else { + return getSharedProperty(-1, prop); + } + } + + /** + * Get the property value for the specified _sharedEnv index + * + * @return the object associated with the property name + * @param envIdx start index in the shared environment list + * @param prop property name + */ + private Object getSharedProperty(int envIdx, String prop) { + + // Check first the frozen updtates list + if (envIdx >= 0) { + for (int i= envIdx; i >= 0; i--) { + Hashtable tab = (Hashtable) m_sharedEnv.elementAt(i); + Object val = tab.get(prop); + if (val != null) { + return (val == REMOVED_PROPERTY) ? null : val; + } + } + } + + // Check the parent env context + if (m_parentSharedEnvIdx >= 0) { + return m_parentEnv.getSharedProperty(m_parentSharedEnvIdx, prop); + } + + return null; + } + + /** + * Remove property + * + * @return the previous value of the specified property, + * or null if it did not exist before. + * @param prop property name + */ + public Object removeProperty(String prop) { + + Object val = null; + // Is this a shared property ? + if (m_sharedEnv != null) { + val = getSharedProperty(m_sharedEnv.size()-1, prop); + } + else { + val = getSharedProperty(-1, prop); + } + + if (val == null) { // Not a shared property, remove if physically + if (m_privateEnv != null) { + return m_privateEnv.remove(prop); + } + } + else { //A shared property, hide it + setProperty(prop, REMOVED_PROPERTY); + } + return val; + } + + /** + * Create a table of all properties. First read all properties from the parent env, + * then merge the local updates. Notice that the data is processed in reverse order + * than in the getProperty method. + * + * @return a hashtable containing all properties visible in this context + */ + public Hashtable getAllProperties() { + Hashtable res = null; + + // First copy shared properties + if (m_sharedEnv != null) { + res = getAllSharedProperties(m_sharedEnv.size()-1); + } + else { + res = getAllSharedProperties(-1); + } + + if (res == null) { + res = new Hashtable(51); + } + + // Then apply private env + if (m_privateEnv != null) { + Hashtable tab = m_privateEnv; + for (Enumeration e = tab.keys(); e.hasMoreElements();) { + Object key = e.nextElement(); + Object val = tab.get(key); + if (val != REMOVED_PROPERTY) { + res.put(key, val); + } + else { + res.remove(key); + } + } + } + + return res; + } + + /** + * Create a table of all shared properties for the given envIdx. First read all + * properties from the parent env, then merge the local environment. + * + * @return a hashtable containing all properties visible for the shared environment index + * @param envIdx start index in the shared environment list + */ + private Hashtable getAllSharedProperties(int envIdx) { + Hashtable res = null; + + // First copy parent env + if (m_parentEnv != null) { + res = m_parentEnv.getAllSharedProperties(m_parentSharedEnvIdx); + } + + if (res == null) { + res = new Hashtable(51); + } + + // Then copy _sharedEnv (older entries are processed before newer ones) + if (envIdx >= 0) { + for (int i= 0; i <= envIdx; i++) { + Hashtable tab = (Hashtable) m_sharedEnv.elementAt(i); + for (Enumeration e = tab.keys(); e.hasMoreElements();) { + Object key = e.nextElement(); + Object val = tab.get(key); + if (val != REMOVED_PROPERTY) { + res.put(key, val); + } + else { + res.remove(key); + } + } + } + } + return res; + } + + /** + * Freeze all environment changes changes in the current context. The "Freeze" is + * done by moving the _privateEnv table to _sharedEnv vector. + */ + protected void freezeUpdates() { + if (m_privateEnv != null) { + // Lazy create _sharedEnv vector + if (m_sharedEnv == null) { + m_sharedEnv = new Vector(); + } + m_sharedEnv.addElement(m_privateEnv); + m_privateEnv = null; + } + } + + /** + * Clone ShareableEnv + * + * @return A "clone" of the current context environment + */ + public Object clone() { + + // First freeze updates for this context + freezeUpdates(); + + // If the context has been modified, then it is the parent of the clone + if (m_sharedEnv != null) { + return new ShareableEnv(this, m_sharedEnv.size()-1); + } + + // No changes has been done to the inherited parent context. Pass the parent + // context to the clone + else { + return new ShareableEnv(m_parentEnv, m_parentSharedEnvIdx); + } + } + + /** + * Return string representation of the object + * + * @return a string representation of the object + */ + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append("ShareableEnv private="); + if (m_privateEnv != null) { + buf.append("("); + buf.append(m_privateEnv.size()); + buf.append(")"); + } + buf.append(" shared="); + if (m_sharedEnv != null) { + for (int i=0; i < m_sharedEnv.size(); i++) { + Hashtable tab = (Hashtable) m_sharedEnv.elementAt(i); + buf.append("("); + buf.append(tab.size()); + buf.append(")"); + } + } + buf.append(" parentIdx="); + buf.append(m_parentSharedEnvIdx); + + return buf.toString(); + } + + /** + * Test program + */ + public static void main(String[] args) { + + ShareableEnv c0 = new ShareableEnv(null, -1); // c=context 0=level 0=index + System.err.println("c0.getProperty(p1)=" + c0.getProperty("p1")); + System.err.println("c0.getAllProperties()=" + c0.getAllProperties()); + System.err.println("c0.setProperty(p1,vxxx)=" + c0.setProperty("p1", "vxxx")); + System.err.println("c0.setProperty(p2,v2)=" + c0.setProperty("p2", "v2")); + System.err.println("c0.setProperty(p3,v3)=" + c0.setProperty("p3", "v3")); + System.err.println("c0.setProperty(p1,v1)=" + c0.setProperty("p1", "v1")); + System.err.println("c0.getAllProperties()=" + c0.getAllProperties()); + + System.err.println("---"); + ShareableEnv c01 = (ShareableEnv)c0.clone(); + System.err.println("c01.getProperty(p1)=" + c01.getProperty("p1")); + System.err.println("c01.getAllProperties()=" + c01.getAllProperties()); + System.err.println("c01.setProperty(p1,v1a)=" + c01.setProperty("p1", "v1a")); + System.err.println("c01.getProperty(p1)=" + c01.getProperty("p1")); + System.err.println("c01.removeProperty(p2)=" + c01.removeProperty("p2")); + System.err.println("c01.getProperty(p2)=" + c01.getProperty("p2")); + System.err.println("c01.setProperty(p11,v11a)=" + c01.setProperty("p11", "v11a")); + System.err.println("c01.getAllProperties()=" + c01.getAllProperties()); + + System.err.println("---"); + ShareableEnv c02 = (ShareableEnv)c0.clone(); + System.err.println("c02.getProperty(p1)=" + c02.getProperty("p1")); + System.err.println("c02.getAllProperties()=" + c02.getAllProperties()); + + System.err.println("---"); + ShareableEnv c011 = (ShareableEnv)c01.clone(); + System.err.println("c011.getProperty(p1)=" + c011.getProperty("p1")); + System.err.println("c011.getAllProperties()=" + c011.getAllProperties()); + System.err.println("c011.setProperty(p1,v11b)=" + c011.setProperty("p1", "v11b")); + System.err.println("c011.getProperty(p1)=" + c011.getProperty("p1")); + System.err.println("c011.getAllProperties()=" + c011.getAllProperties()); + + System.err.println("---"); + System.err.println("c01.getAllProperties()=" + c01.getAllProperties()); + System.err.println("c01.removeProperty(p11)=" + c01.removeProperty("p11")); + System.err.println("c01.getAllProperties()=" + c01.getAllProperties()); + System.err.println("c011.getAllProperties()=" + c011.getAllProperties()); + + System.err.println("---"); + ShareableEnv c012 = (ShareableEnv)c01.clone(); + System.err.println("c012.getAllProperties()=" + c012.getAllProperties()); + System.err.println("c012.getProperty(p1)=" + c012.getProperty("p1")); + + System.err.println("---"); + System.err.println("c0="+c0); + System.err.println("c01="+c01); + System.err.println("c02="+c02); + System.err.println("c011="+c011); + System.err.println("c012="+c012); + + } +} + \ No newline at end of file diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapEntryChangeControl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapEntryChangeControl.java new file mode 100644 index 00000000000..b07db150125 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapEntryChangeControl.java @@ -0,0 +1,172 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.controls; + +/** + * Represents an LDAP v3 server control that specifies information + * about a change to an entry in the directory. (The OID for this + * control is 2.16.840.1.113730.3.4.7.) You need to use this control in + * conjunction with a "persistent search" control (represented + * by LdapPersistentSearchControl object. + *

+ * + * To use persistent searching for change notification, you create a + * "persistent search" control that specifies the types of changes that + * you want to track. When an entry is changed, the server sends that + * entry back to your client and may include an "entry change notification" + * control that specifies additional information about the change. + *

+ * + * Typically, you use the getResponseControls method of + * the LDAPConnection object and the parseResponse + * method of the LdapPersistSearchControl object to get + * an LdapEntryChangeControl object. + *

+ * + * Once you retrieve an LdapEntryChangeControl object from + * the server, you can get the following additional information about + * the change made to the entry: + *

+ * + *

    + *
  • The type of change made (add, modify, delete, or modify DN) + *
  • The change number identifying the record of the change in the + * change log (if the server supports change logs) + *
  • If the entry was renamed, the old DN of the entry + *
+ *

+ * + * @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl + * @see com.netscape.jndi.ldap.LDAPConnection#getResponseControls + */ + +import javax.naming.ldap.Control; +import netscape.ldap.controls.*; + +public class LdapEntryChangeControl extends LDAPEntryChangeControl implements Control { + + /** + * Constructs a new LdapEntryChangeControl object. + * This constructor is used by the NetscapeControlFactory + * + * @see com.netscape.jndi.ldap.LdapControl + * @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl + */ + LdapEntryChangeControl(boolean critical, byte[] value) { + m_critical = critical; + m_value = value; + } + + /** + * Sets the change number (which identifies the record of the change + * in the server's change log) in this "entry change notification" + * control. + * @param num Change number that you want to set. + * @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#getChangeNumber + */ + public void setChangeNumber(int num) { + super.setChangeNumber(num); + } + + /** + * Sets the change type (which identifies the type of change + * that occurred) in this "entry change notification" control. + * @param num Change type that you want to set. This can be one of + * the following values: + *

+ * + *

    + *
  • LdapPersistSearchControl.ADD (a new entry was + * added to the directory) + *
  • LdapPersistSearchControl.DELETE (an entry was + * removed from the directory) + *
  • LdapPersistSearchControl.MODIFY (an entry was + * modified) + *
  • LdapPersistSearchControl.MODDN (an entry was + * renamed) + *
+ *

+ * + * @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#getChangeType + */ + public void setChangeType(int num) { + super.setChangeType(num); + } + + /** + * Sets the previous DN of the entry (if the entry was renamed) + * in the "entry change notification control". + * @param dn The previous distinguished name of the entry. + * @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#getPreviousDN + */ + public void setPreviousDN(String dn) { + super.setPreviousDN(dn); + } + + /** + * Gets the change number, which identifies the record of the change + * in the server's change log. + * @return Change number identifying the change made. + * @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#setChangeNumber + */ + public int getChangeNumber() { + return super.getChangeNumber(); + } + + /** + * Gets the change type, which identifies the type of change + * that occurred. + * @returns Change type identifying the type of change that + * occurred. This can be one of the following values: + *

+ * + *

    + *
  • LdapPersistSearchControl.ADD (a new entry was + * added to the directory) + *
  • LdapPersistSearchControl.DELETE (an entry was + * removed from the directory) + *
  • LdapPersistSearchControl.MODIFY (an entry was + * modified) + *
  • LdapPersistSearchControl.MODDN (an entry was + * renamed) + *
+ *

+ * + * @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#setChangeType + */ + public int getChangeType() { + return super.getChangeType(); + } + + /** + * Gets the previous DN of the entry (if the entry was renamed). + * @returns The previous distinguished name of the entry. + * @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl#setPreviousDN + */ + public String getPreviousDN() { + return super.getPreviousDN(); + } + + /** + * Implements Control interface + */ + public byte[] getEncodedValue() { + return getValue(); + } +} + diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapPasswordExpiredControl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapPasswordExpiredControl.java new file mode 100644 index 00000000000..569c4113e3f --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapPasswordExpiredControl.java @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.controls; + +import javax.naming.ldap.Control; +import netscape.ldap.controls.*; + +/** + * Represents an LDAP v3 server control that may be returned if a + * password has expired, and password policy is enabled on the server. + * The OID for this control is 2.16.840.1.113730.3.4.4. + *

+ */ + +public class LdapPasswordExpiredControl extends LDAPPasswordExpiredControl implements Control{ + + private String m_message; + /** + * This constractor is used by the NetscapeControlFactory + */ + LdapPasswordExpiredControl(boolean critical, byte[] value) throws Exception{ + m_value = value; + m_critical = critical; + m_message = new String(m_value, "UTF8"); + } + + /** + * Return string message passed in the control + * TODO what is the information in this string value ? + */ + public String getMessage() { + return m_message; + } + + /** + * Implements Control interface + */ + public byte[] getEncodedValue() { + return getValue(); + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapPasswordExpiringControl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapPasswordExpiringControl.java new file mode 100644 index 00000000000..2a573a0a255 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapPasswordExpiringControl.java @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.controls; + +import javax.naming.ldap.Control; +import netscape.ldap.controls.*; + +/** + * Represents an LDAP v3 server control that may be returned if a + * password is about to expire, and password policy is enabled on the server. + * The OID for this control is 2.16.840.1.113730.3.4.5. + *

+ */ +public class LdapPasswordExpiringControl extends LDAPPasswordExpiringControl implements Control { + + //number of seconds before password expiration + int m_secondsToExpire = -1; + + /** + * This constractor is used by the NetscapeControlFactory + */ + LdapPasswordExpiringControl(boolean critical, byte[] value) throws Exception{ + m_value = value; + m_critical = critical; + String msg = new String(m_value, "UTF8"); + if (msg != null) { + m_secondsToExpire = Integer.parseInt(msg); + } + } + + /** + * Return parsed number of seconds before password expires + */ + public int getSecondsToExipre() { + return m_secondsToExpire; + } + + /** + * Implements Control interface + */ + public byte[] getEncodedValue() { + return getValue(); + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapPersistSearchControl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapPersistSearchControl.java new file mode 100644 index 00000000000..32af3fa882a --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapPersistSearchControl.java @@ -0,0 +1,194 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.controls; + +import javax.naming.ldap.Control; +import netscape.ldap.controls.*; + +/** + * Represents an LDAP v3 server control that specifies a persistent + * search (an ongoing search operation), which allows your LDAP client + * to get notification of changes to the directory. (The OID for this + * control is 2.16.840.1.113730.3.4.3.) You can use this control in + * conjunction with an "entry change notification" control (represented + * by LDAPEntryChangeControl object. + *

+ * + * To use persistent searching for change notification, you create a + * "persistent search" control that specifies the types of changes that + * you want to track. You include the control in a search request. + * If an entry in the directory is changed, the server determines if + * the entry matches the search criteria in your request and if the + * change is the type of change that you are tracking. If both of + * these are true, the server sends the entry to your client. + *

+ * + * The server can also include an "entry change notification" control + * with the entry. (The OID for this control is 2.16.840.1.113730.3.4.7.) + * This control contains additional information about the + * change made to the entry, including the type of change made, + * the change number (which corresponds to an item in the server's + * change log, if the server supports a change log), and, if the + * entry was renamed, the old DN of the entry. + *

+ * + * When constructing an LDAPPersistSearchControl object, + * you can specify the following information: + *

+ * + *

    + *
  • the type of change you want to track (added, modified, deleted, + * or renamed entries) + *
  • a preference indicating whether or not you want the server to + * return all entries that initially matched the search criteria + * (rather than only the entries that change) + *
  • a preference indicating whether or not you want entry change + * notification controls included with every entry returned by the + * server + *
+ *

+ * @see com.netscape.jndi.ldap.controls.LDAPEntryChangeControl + */ + +public class LdapPersistSearchControl extends LDAPPersistSearchControl implements Control { + + /** + * Default constructor + */ + public LdapPersistSearchControl() { + } + + /** + * Constructs an LdapPersistSearchControl object + * that specifies a persistent search. + * + * @param changeTypes The change types to be monitored. You can perform + * a bitwise OR on any of the following values and specify the result as + * the change types: + *

    + *
  • LdapPersistSearchControl.ADD (to track new entries + * added to the directory) + *
  • LdapPersistSearchControl.DELETE (to track entries + * removed from the directory) + *
  • LdapPersistSearchControl.MODIFY (to track entries + * that have been modified) + *
  • LdapPersistSearchControl.MODDN (to track entries + * that have been renamed) + *
+ * @param changesOnly true if you do not want the server + * to return all existing entries in the directory that match the + * search criteria. (You just want the changed entries to be returned.) + * @param returnControls true you want the server to return + * entry change controls with each entry in the search results. + * @param isCritical true if this control is critical to + * the search operation (for example, if the server does not support + * this control, you may not want the server to perform the search + * at all.) + * @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl + */ + public LdapPersistSearchControl(int changeTypes, boolean changesOnly, + boolean returnControls, boolean isCritical) { + super(changeTypes, changesOnly, returnControls, isCritical); + } + + /** + * Gets the change types monitored by this control. + * @return Integer representing the change types that you want monitored. + * This value can be the bitwise OR of ADD, DELETE, MODIFY, + * and/or MODDN. If the change type is unknown, + * this method returns -1. + * @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#setChangeTypes + */ + public int getChangeTypes() { + return super.getChangeTypes(); + } + + /** + * Indicates whether you want the server to send any existing + * entries that already match the search criteria or only the + * entries that have changed. + * @return If true, the server returns only the + * entries that have changed. If false, the server + * also returns any existing entries that match the search criteria + * but have not changed. + * @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#setChangesOnly + */ + public boolean getChangesOnly() { + return super.getChangesOnly(); + } + + /** + * Indicates whether or not the server includes an "entry change + * notification" control with each entry it sends back to the client + * during the persistent search. + * @return true if the server includes "entry change + * notification" controls with the entries it sends during the + * persistent search. + * @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl + * @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#setReturnControls + */ + public boolean getReturnControls() { + return super.getReturnControls(); + } + + /** + * Sets the change types that you want monitored by this control. + * @param types Integer representing the change types that you want monitored. + * This value can be the bitwise OR of ADD, DELETE, MODIFY, + * and/or MODDN. + * @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#getChangeTypes + */ + public void setChangeTypes(int types) { + super.setChangeTypes(types); + } + + /** + * Specifies whether you want the server to send any existing + * entries that already match the search criteria or only the + * entries that have changed. + * @param changesOnly If true, the server returns only the + * entries that have changed. If false, the server + * also returns any existing entries that match the search criteria + * but have not changed. + * @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#getChangesOnly + */ + public void setChangesOnly(boolean changesOnly) { + super.setChangesOnly(changesOnly); + } + + /** + * Specifies whether you want the server to include an "entry change + * notification" control with each entry it sends back to the client + * during the persistent search. + * @param returnControls If true, the server includes + * "entry change notification" controls with the entries it sends + * during the persistent search. + * @see com.netscape.jndi.ldap.controls.LdapEntryChangeControl + * @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl#setReturnControls + */ + public void setReturnControls(boolean returnControls) { + super.setReturnControls(returnControls); + } + + /** + * Implements Control interface + */ + public byte[] getEncodedValue() { + return getValue(); + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapProxiedAuthControl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapProxiedAuthControl.java new file mode 100644 index 00000000000..ff5ed80b868 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapProxiedAuthControl.java @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.controls; + +import javax.naming.ldap.Control; +import netscape.ldap.controls.*; + +/** + * Represents an LDAP v3 server control that specifies that you want + * the server to use the specified DN's identity for this operation. + * (The OID for this control is 2.16.840.1.113730.3.4.12.) + *

+ * + * You can include the control in any request by constructing + * an LDAPSearchConstraints object and calling the + * setServerControls method. You can then pass this + * LDAPSearchConstraints object to the search + * or other request method of an LDAPConnection object. + *

+ * + * For example: + *

+ * ...
+ * LDAPConnection ld = new LDAPConnection();
+ * try {
+ *     // Connect to server.
+ *     ld.connect( 3, hostname, portnumber, "", "" );
+ *
+ *     // Create a "critical" proxied auth server control using
+ *     // the DN "uid=charlie,ou=people,o=acme.com".
+ *     LDAPProxiedAuthControl ctrl =
+ *         new LDAPProxiedAuthControl( "uid=charlie,ou=people,o=acme.com",
+ *                                     true );
+ *
+ *     // Create search constraints to use that control.
+ *     LDAPSearchConstraints cons = new LDAPSearchConstraints();
+ *     cons.setServerControls( sortCtrl );
+ *
+ *     // Send the search request.
+ *     LDAPSearchResults res = ld.search( "o=Airius.com",
+ *        LDAPv3.SCOPE_SUB, "(cn=Barbara*)", null, false, cons );
+ *
+ *     ...
+ *
+ * 
+ * + *

+ * @see com.netscape.jndi.ldap.LdapSearchConstraints + * @see com.netscape.jndi.ldap.LdapSearchConstraints#setServerControls(LDAPControl) + */ +public class LdapProxiedAuthControl extends LDAPProxiedAuthControl implements Control { + + /** + * Constructs an LdapProxiedAuthControl object with a + * DN to use as identity. + * @param dn DN to use as identity for execution of a request. + * @param critical true if the LDAP operation should be + * discarded when the server does not support this control (in other + * words, this control is critical to the LDAP operation). + */ + public LdapProxiedAuthControl( String dn, + boolean critical) { + super( dn, critical); + } + + /** + * Implements Control interface + */ + public byte[] getEncodedValue() { + return getValue(); + } + +} + diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapSortControl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapSortControl.java new file mode 100644 index 00000000000..23157a5fcc4 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapSortControl.java @@ -0,0 +1,257 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.controls; + +import javax.naming.ldap.Control; +import netscape.ldap.controls.*; + +/** + * Represents an LDAP v3 server control that specifies that you want + * the server to return sorted search results. (The OID for this + * control is 1.2.840.113556.1.4.473.) + *

+ * + * When constructing an LDAPSortControl object, you can + * specify the order in which you want the results sorted. + * You can also specify whether or not this control is critical + * to the search operation. + *

+ * + * To specify the sort order, you construct an LDAPSortKey + * object and pass it to the LDAPSortControl constructor. + * The LDAPSortKey object represents a list of the attribute + * types used for sorting (a "sort key list"). + *

+ * + * You can include the control in a search request by constructing + * an LDAPSearchConstraints object and calling the + * setServerControls method. You can then pass this + * LDAPSearchConstraints object to the search + * method of an LDAPConnection object. + *

+ * + * For example: + *

+ * ...
+ * LDAPConnection ld = new LDAPConnection();
+ * try {
+ *     // Connect to server.
+ *     ld.connect( 3, hostname, portnumber, "", "" );
+ *
+ *     // Create a sort key that specifies the sort order.
+ *     LDAPSortKey sortOrder = new LDAPSortKey( attrname );
+ *
+ *     // Create a "critical" server control using that sort key.
+ *     LDAPSortControl sortCtrl = new LDAPSortControl(sortOrder,true);
+ *
+ *     // Create search constraints to use that control.
+ *     LDAPSearchConstraints cons = new LDAPSearchConstraints();
+ *     cons.setServerControls( sortCtrl );
+ *
+ *     // Send the search request.
+ *     LDAPSearchResults res = ld.search( "o=Airius.com",
+ *        LDAPv3.SCOPE_SUB, "(cn=Barbara*)", null, false, cons );
+ *
+ *     ...
+ *
+ * 
+ * + * The LDAP server sends back a sort response control to indicate + * the result of the sorting operation. (The OID for this control + * is 1.2.840.113556.1.4.474.) + *

+ * + * This control contains: + *

+ * + *

    + *
  • the result code from the sorting operation + *
  • optionally, the first attribute type in the sort key list + * that resulted in an error (for example, if the attribute does + * not exist) + *
+ *

+ * + * To parse this control, use the parseResponse method. + *

+ * + * The following table lists what kinds of results to expect from the + * LDAP server under different situations: + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Does the Server Support the Sorting Control?Is the Sorting Control Marked As Critical?Other ConditionsResults from LDAP Server
+ * No + * + * Yes + * + * None + * + *
    + *
  • The server does not send back any entries. + *
  • An LDAPException.UNAVAILABLE_CRITICAL_EXTENSION + * exception is thrown. + *
+ *
+ * No + * + * None + * + *
    + *
  • The server ignores the sorting control and + * returns the entries unsorted. + *
+ *

+ *

+ * Yes + * + * Yes + * + * The server cannot sort the results using the specified + * sort key list. + * + *
    + *
  • The server does not send back any entries. + *
  • An LDAPException.UNAVAILABLE_CRITICAL_EXTENSION + * exception is thrown. + *
  • The server sends back the sorting response control, which + * specifies the result code of the sort attempt and (optionally) + * the attribute type that caused the error. + *
+ *
+ * No + * + *
    + *
  • The server returns the entries unsorted. + *
  • The server sends back the sorting response control, which + * specifies the result code of the sort attempt and (optionally) + * the attribute type that caused the error. + *
+ *
+ * N/A (could either be marked as critical or not) + * + * The server successfully sorted the entries. + * + *
    + *
  • The server sends back the sorted entries. + *
  • The server sends back the sorting response control, which + * specifies the result code of the sort attempt + * (LDAPException.SUCCESS). + *
+ *
+ * The search itself failed (for any reason). + * + *
    + *
  • The server sends back a result code for the search + * operation. + *
  • The server does not send back the sorting response control. + *
+ *
+ *

+ * @see com.netscape.jndi.ldap.LdapSortKey + * @see com.netscape.jndi.ldap.LdapSearchConstraints + * @see com.netscape.jndi.ldap.LdapSearchConstraints#setServerControls(LDAPControl) + */ +public class LdapSortControl extends LDAPSortControl implements Control{ + /** + * Constructs an LDAPSortControl object with a single + * sorting key. + * @param key A single attribute to sort by. + * @param critical true if the LDAP operation should be + * discarded when the server does not support this control (in other + * words, this control is critical to the LDAP operation). + * @see com.netscape.jndi.ldap.LdapSortKey + */ + public LdapSortControl(LdapSortKey key, + boolean critical) { + super (key, critical); + } + + /** + * Constructs an LDAPSortControl object with an array of + * sorting keys. + * @param keys The attributes to sort by. + * @param critical true if the LDAP operation should be + * discarded when the server does not support this control (in other + * words, this control is critical to the LDAP operation). + * @see com.netscape.jndi.ldap.LdapSortKey + */ + public LdapSortControl(LdapSortKey[] keys, + boolean critical) { + super(keys, critical); + } + + + static LdapSortKey[] toSortKey(String[] keysIn) { + LdapSortKey[] keysOut = new LdapSortKey[keysIn.length]; + for (int i=0; i < keysIn.length; i++) { + keysOut[i] = new LdapSortKey(keysIn[i]); + } + return keysOut; + } + + public LdapSortControl(String[] keys, + boolean critical) { + super(toSortKey(keys), critical); + } + + + /** + * Implements Control interface + */ + public byte[] getEncodedValue() { + return getValue(); + } +} + diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapSortKey.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapSortKey.java new file mode 100644 index 00000000000..2adabe6f97e --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapSortKey.java @@ -0,0 +1,124 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.controls; + +import netscape.ldap.LDAPSortKey; + +/** + * Represents sorting instructions for a particular attribute. + * + */ +public class LdapSortKey extends LDAPSortKey{ + + /** + * Constructs a new LdapSortKey object that will + * sort based on the specified instructions. + * @param keyDescription A single attribute specification to sort by. + * If preceded by a hyphen ("-"), the attribute is sorted in reverse order. + * You can also specify the object ID (OID) of a matching rule after + * a colon (":"). For example: + *

+ *

    + *
  • "cn" (sort by the cn attribute)

    + *

  • "-cn" (sort by the cn attribute in + * reverse order)

    + *

  • "-cn:1.2.3.4" (sort by the cn + * attribute in reverse order and use the matching rule identified + * by the OID 1.2.3.4)

    + *

+ * @see com.netscape.jndi.ldap.controls.LdapPagedControl + * @see com.netscape.jndi.ldap.controls.LdapSortControl + * @see com.netscape.jndi.ldap.controls.LdapVirtualListControl + */ + public LdapSortKey( String keyDescription ) { + super(keyDescription); + } + + /** + * Constructs a new LdapSortKey object that will + * sort based on the specified attribute and sort order. + * @param key A single attribute to sort by. For example: + *

+ *

    + *
  • "cn" (sort by the cn attribute) + *
  • "givenname" (sort by the givenname + * attribute) + *
+ * @param reverse If true, the sorting is done in + * descending order. + * @see com.netscape.jndi.ldap.controls.LdapPagedControl + * @see com.netscape.jndi.ldap.controls.LdapSortControl + * @see com.netscape.jndi.ldap.controls.LdapVirtualListControl + */ + public LdapSortKey( String key, + boolean reverse) { + super(key,reverse); + } + + /** + * Constructs a new LdapSortKey object that will + * sort based on the specified attribute, sort order, and matching + * rule. + * @param key A single attribute to sort by. For example: + *

+ *

    + *
  • "cn" (sort by the cn attribute) + *
  • "givenname" (sort by the givenname + * attribute) + *
+ * @param reverse If true, the sorting is done in + * descending order. + * @param matchRule Object ID (OID) of the matching rule for + * the attribute (for example, 1.2.3.4). + * @see com.netscape.jndi.ldap.controls.LdapPagedControl + * @see com.netscape.jndi.ldap.controls.LdapSortControl + * @see com.netscape.jndi.ldap.controls.LdapVirtualListControl + */ + public LdapSortKey( String key, + boolean reverse, + String matchRule) { + super(key, reverse, matchRule); + } + + /** + * Returns the attribute to sort by. + * @return A single attribute to sort by. + */ + public String getKey() { + return super.getKey(); + } + + /** + * Returns true if sorting is to be done in descending order. + * @return true if sorting is to be done in descending order. + */ + public boolean getReverse() { + return super.getReverse(); + } + + /** + * Returns the object ID (OID) of the matching rule used for sorting. + * If no matching rule is specified, null is returned. + * @return The object ID (OID) of the matching rule, or null + * if the sorting instructions specify no matching rule. + */ + public String getMatchRule() { + return super.getMatchRule(); + } +} + diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapSortResponseControl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapSortResponseControl.java new file mode 100644 index 00000000000..5ad9d9e796e --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapSortResponseControl.java @@ -0,0 +1,223 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.controls; + +import javax.naming.NamingException; +import javax.naming.ldap.Control; +import netscape.ldap.LDAPControl; +import netscape.ldap.LDAPException; +import netscape.ldap.controls.*; +import com.netscape.jndi.ldap.common.ExceptionMapper; + +/** + * The LDAP server sends back a sort response control to indicate + * the result of the sorting operation. (The OID for this control + * is 1.2.840.113556.1.4.474.) + *

+ * + * This control contains: + *

+ * + *

    + *
  • the result code from the sorting operation + *
  • optionally, the first attribute type in the sort key list + * that resulted in an error (for example, if the attribute does + * not exist) + *
+ *

+ * + * To parse this control, use the parseResponse method. + *

+ * + * The following table lists what kinds of results to expect from the + * LDAP server under different situations: + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Does the Server Support the Sorting Control?Is the Sorting Control Marked As Critical?Other ConditionsResults from LDAP Server
+ * No + * + * Yes + * + * None + * + *
    + *
  • The server does not send back any entries. + *
  • An LDAPException.UNAVAILABLE_CRITICAL_EXTENSION + * exception is thrown. + *
+ *
+ * No + * + * None + * + *
    + *
  • The server ignores the sorting control and + * returns the entries unsorted. + *
+ *

+ *

+ * Yes + * + * Yes + * + * The server cannot sort the results using the specified + * sort key list. + * + *
    + *
  • The server does not send back any entries. + *
  • An LDAPException.UNAVAILABLE_CRITICAL_EXTENSION + * exception is thrown. + *
  • The server sends back the sorting response control, which + * specifies the result code of the sort attempt and (optionally) + * the attribute type that caused the error. + *
+ *
+ * No + * + *
    + *
  • The server returns the entries unsorted. + *
  • The server sends back the sorting response control, which + * specifies the result code of the sort attempt and (optionally) + * the attribute type that caused the error. + *
+ *
+ * N/A (could either be marked as critical or not) + * + * The server successfully sorted the entries. + * + *
    + *
  • The server sends back the sorted entries. + *
  • The server sends back the sorting response control, which + * specifies the result code of the sort attempt + * (LDAPException.SUCCESS). + *
+ *
+ * The search itself failed (for any reason). + * + *
    + *
  • The server sends back a result code for the search + * operation. + *
  • The server does not send back the sorting response control. + *
+ *
+ *

+ * @see com.netscape.jndi.ldap.LdapSortKey + * @see com.netscape.jndi.ldap.LdapSearchConstraints + * @see com.netscape.jndi.ldap.LdapSearchConstraints#setServerControls(LDAPControl) + */ +public class LdapSortResponseControl extends LDAPControl implements Control { + + String m_failedAttribute; + int m_resultCode; + /** + * Constructs a new LdapEntryChangeControl object. + * This constructor is used by the NetscapeControlFactory + * + * @see com.netscape.jndi.ldap.controls.LdapPersistSearchControl + */ + LdapSortResponseControl(boolean critical, byte[] value) { + super(LDAPSortControl.SORTRESPONSE, critical, value); + } + + /** + * Set the first attribute type from the sort key list that + * resulted in an error + * This method is used by the NetscapeControlFactory + */ + void setFailedAttribute(String attr) { + m_failedAttribute = attr; + } + + /** + * Set the sort result code + * This method is used by the NetscapeControlFactory + */ + void setResultCode(int code) { + m_resultCode = code; + } + + /** + * Get the first attribute type from the sort key list that + * resulted in an error + */ + public String getFailedAttribute() { + return m_failedAttribute; + } + + /** + * Return the sort result code + */ + public int getResultCode() { + return m_resultCode; + } + + /** + * Return corresponding NamingException for the sort error code + */ + public NamingException getSortException() { + if (m_resultCode == 0) { // success + return null; + } + return ExceptionMapper.getNamingException( + new LDAPException("Server Sort Failed", m_resultCode)); + } + /** + * Implements Control interface + */ + public byte[] getEncodedValue() { + return getValue(); + } +} + diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapStringControl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapStringControl.java new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapStringControl.java @@ -0,0 +1 @@ + diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapVirtualListControl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapVirtualListControl.java new file mode 100644 index 00000000000..17f40f6ef2a --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapVirtualListControl.java @@ -0,0 +1,147 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.controls; + +import javax.naming.ldap.Control; +import netscape.ldap.controls.*; + +/** + * Represents control data for returning paged results from a search. + * + *

+ *      VirtualListViewRequest ::= SEQUENCE {
+ *                      beforeCount    INTEGER,
+ *                      afterCount     INTEGER,
+ *                      CHOICE {
+ *                      byIndex [0] SEQUENCE {
+ *                          index           INTEGER,
+ *                          contentCount    INTEGER }
+ *                      byFilter [1] jumpTo    Substring }
+ * 
+ * + */ + +public class LdapVirtualListControl extends LDAPVirtualListControl implements Control { + + /** + * Constructs a new LDAPVirtualListControl object. Use this + * constructor on an initial search operation, specifying the first + * entry to be matched, or the initial part of it. + * @param jumpTo An LDAP search expression defining the result set. + * @param beforeCount The number of results before the top/center to + * return per page. + * @param afterCount The number of results after the top/center to + * return per page. + */ + public LdapVirtualListControl( String jumpTo, int beforeCount, + int afterCount ) { + super( jumpTo, beforeCount, afterCount); + } + + /** + * Constructs a new LDAPVirtualListControl object. Use this + * constructor on a subsquent search operation, after we know the + * size of the virtual list, to fetch a subset. + * @param startIndex The index into the virtual list of an entry to + * return. + * @param beforeCount The number of results before the top/center to + * return per page. + * @param afterCount The number of results after the top/center to + * return per page. + */ + public LdapVirtualListControl( int startIndex, int beforeCount, + int afterCount, int contentCount ) { + super( startIndex, beforeCount, afterCount, contentCount ); + } + + /** + * Sets the starting index, and the number of entries before and after + * to return. Apply this method to a control returned from a previous + * search, to specify what result range to return on the next search. + * @param startIndex The index into the virtual list of an entry to + * return. + * @param beforeCount The number of results before startIndex to + * return per page. + * @param afterCount The number of results after startIndex to + * return per page. + */ + public void setRange( int startIndex, int beforeCount, int afterCount ) { + super.setRange(startIndex, beforeCount, afterCount); + } + + /** + * Sets the search expression, and the number of entries before and after + * to return. + * @param jumpTo An LDAP search expression defining the result set. + * return. + * @param beforeCount The number of results before startIndex to + * return per page. + * @param afterCount The number of results after startIndex to + * return per page. + */ + public void setRange( String jumpTo, int beforeCount, int afterCount ) { + super.setRange(jumpTo, beforeCount, afterCount); + } + + /** + * Gets the size of the virtual result set. + * @return The size of the virtual result set, or -1 if not known. + */ + public int getIndex() { + return super.getIndex(); + } + + /** + * Gets the size of the virtual result set. + * @return The size of the virtual result set, or -1 if not known. + */ + public int getListSize() { + return super.getListSize(); + } + + /** + * Sets the size of the virtual result set. + * @param listSize The virtual result set size. + */ + public void setListSize( int listSize ) { + super.setListSize(listSize); + } + + /** + * Gets the number of results before the top/center to return per page. + * @return The number of results before the top/center to return per page. + */ + public int getBeforeCount() { + return super.getBeforeCount(); + } + + /** + * Gets the number of results after the top/center to return per page. + * @return The number of results after the top/center to return per page. + */ + public int getAfterCount() { + return super.getAfterCount(); + } + + /** + * Implements Control interface + */ + public byte[] getEncodedValue() { + return getValue(); + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapVirtualListResponseControl.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapVirtualListResponseControl.java new file mode 100644 index 00000000000..15c8d86877d --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/LdapVirtualListResponseControl.java @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.controls; + +import javax.naming.ldap.Control; +import netscape.ldap.controls.*; + + +/** + * Represents control data for returning paged results from a search. + * + * + *
+ *      VirtualListViewResponse ::= SEQUENCE {
+ *               firstPosition    INTEGER,
+ *               contentCount     INTEGER,
+ *               virtualListViewResult ENUMERATED {
+ *                 success                  (0),
+ *                 unwillingToPerform       (53),
+ *                 insufficientAccessRights (50),
+ *                 operationsError          (1),
+ *                 busy                     (51),
+ *                 timeLimitExceeded        (3),
+ *                 adminLimitExceeded       (11),
+ *                 sortControlMissing       (60),
+ *                 indexRangeError          (?),
+ *               }
+ *     }
+ *
+ */ + +public class LdapVirtualListResponseControl extends LDAPVirtualListResponse implements Control{ + + /** + * Constructs a new LDAPVirtualListResponse object. + * @param value A BER encoded byte array. + * This constructor is used by the NetscapeControlFactory + */ + LdapVirtualListResponseControl( byte[] value ) { + // The superclass constractor parses the byte[] value + // automatically. No need to call parseResponse + super(value); + } + + /** + * Gets the size of the virtual result set. + * @return The size of the virtual result set, or -1 if not known. + */ + public int getContentCount() { + return super.getContentCount(); + } + + /** + * Gets the index of the first entry returned. + * @return The index of the first entry returned. + */ + public int getFirstPosition() { + return super.getFirstPosition(); + } + + /** + * Gets the result code. + * @return The result code. + */ + public int getResultCode() { + return super.getResultCode(); + } + + /** + * Implements Control interface + */ + public byte[] getEncodedValue() { + return getValue(); + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/NetscapeControlFactory.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/NetscapeControlFactory.java new file mode 100644 index 00000000000..6bb1c82fc4b --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/controls/NetscapeControlFactory.java @@ -0,0 +1,142 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.controls; + + +/** + * Factory for creating controls. Only controls send by the direcory server + * are processed. + */ + +import javax.naming.*; +import javax.naming.ldap.*; +import netscape.ldap.LDAPControl; +import netscape.ldap.controls.*; +import com.netscape.jndi.ldap.common.ExceptionMapper; + +public class NetscapeControlFactory extends ControlFactory { + + // "1.2.840.113556.1.4.473" Sort Control (Request) + final static String REQ_SORT = LDAPSortControl.SORTREQUEST; + + // "1.2.840.113556.1.4.474" Sort Control (Response) + final static String RSP_SORT = LDAPSortControl.SORTRESPONSE; + + // "2.16.840.1.113730.3.4.2" ManageDSAIT Control + final static String REQ_MANAGEDSAIT = LDAPControl.MANAGEDSAIT; + + // "2.16.840.1.113730.3.4.3" PersistentSearch Control + final static String REQ_PERSISTENTSEARCH = LDAPPersistSearchControl.PERSISTENTSEARCH; + + // "2.16.840.1.113730.3.4.4" PasswordExpired Control + final static String RSP_PWDEXPIRED = LDAPPasswordExpiredControl.EXPIRED; + + // "2.16.840.1.113730.3.4.5" PasswordExpiring Control + final static String RSP_PWDEXPIRING = LDAPPasswordExpiringControl.EXPIRING; + + // "2.16.840.1.113730.3.4.7" EntryChanged Controle + final static String RSP_ENTRYCHANGED = LDAPEntryChangeControl.ENTRYCHANGED; + + // "2.16.840.1.113730.3.4.9" Virtual List (Request) + final static String REQ_VIRTUALLIST = LDAPVirtualListControl.VIRTUALLIST; + + // "2.16.840.1.113730.3.4.10" Virtual List (Response) + final static String RSP_VIRTUALLIST = LDAPVirtualListResponse.VIRTUALLISTRESPONSE; + + // "2.16.840.1.113730.3.4.12" Proxed Authentication + final static String REQ_PROXIEDAUTH = LDAPProxiedAuthControl.PROXIEDAUTHREQUEST; + + + /** + * Implements abstract getControlInstance() from ConrolFactory + */ + public Control getControlInstance(Control ctrl) throws NamingException { + if (ctrl == null) { + return null; + } + LDAPControl rawCtrl = new LDAPControl( + ctrl.getID(), ctrl.isCritical(), ctrl.getEncodedValue()); + return getControlInstance(rawCtrl); + } + + /** + * Create control using parseResponse() methods in ldapjdk controls + */ + public static Control getControlInstance(LDAPControl rawCtrl) throws NamingException { + if (rawCtrl == null) { + return null; + } + + try { + String ctrlID = rawCtrl.getID(); + + // Entry changed control is parsed by LDAPPersistSearchControl + if (ctrlID.equals(RSP_ENTRYCHANGED)) { + // First get ldapjdk object + LDAPEntryChangeControl ldapjdkCtrl = + LDAPPersistSearchControl.parseResponse(new LDAPControl[] {rawCtrl}); + // then map it to a jndi object + if (ldapjdkCtrl != null) { + LdapEntryChangeControl ctrl = new LdapEntryChangeControl( + rawCtrl.isCritical(), rawCtrl.getValue()); + ctrl.setChangeNumber(ldapjdkCtrl.getChangeNumber()); + ctrl.setChangeType(ldapjdkCtrl.getChangeType()); + ctrl.setPreviousDN(ldapjdkCtrl.getPreviousDN()); + return ctrl; + } + } + + // Password Expired control + else if(ctrlID.equals(RSP_PWDEXPIRED)) { + LdapPasswordExpiredControl ctrl = new LdapPasswordExpiredControl( + rawCtrl.isCritical(), rawCtrl.getValue()); + } + + // Password Expiring control + else if(ctrlID.equals(RSP_PWDEXPIRING)) { + LdapPasswordExpiringControl ctrl = new LdapPasswordExpiringControl( + rawCtrl.isCritical(), rawCtrl.getValue()); + } + + // Sort Response control + else if(ctrlID.equals(RSP_SORT)) { + // First parse the control + int[] resultCodes = new int[1]; + String failedAttr = LDAPSortControl.parseResponse( + new LDAPControl[] {rawCtrl}, resultCodes); + + LdapSortResponseControl ctrl = new LdapSortResponseControl( + rawCtrl.isCritical(), rawCtrl.getValue()); + ctrl.setResultCode(resultCodes[0]); + ctrl.setFailedAttribute(failedAttr); + return ctrl; + } + + // Virtual List Response control + else if(ctrlID.equals(RSP_VIRTUALLIST)) { + return new LdapVirtualListResponseControl(rawCtrl.getValue()); + } + + // No match try another ControlFactory + return null; + } + catch (Exception ex) { + throw ExceptionMapper.getNamingException(ex); + } + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaAttribute.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaAttribute.java new file mode 100644 index 00000000000..af8ea990e82 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaAttribute.java @@ -0,0 +1,209 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.schema; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; +import netscape.ldap.controls.*; + +import java.util.*; + +public class SchemaAttribute extends SchemaElement { + + LDAPAttributeSchema m_ldapAttribute; + + // Attribute IDs that are exposed through Netscape LdapJDK + private static String[] m_allAttrIds = {NUMERICOID, NAME, DESC, SYNTAX, SINGLEVALUE }; + + public SchemaAttribute(LDAPAttributeSchema ldapAttribute, SchemaManager schemaManager) { + super(schemaManager); + m_ldapAttribute = ldapAttribute; + m_path = ATTRDEF + "/" + m_ldapAttribute.getName(); + } + + public SchemaAttribute(Attributes attrs, SchemaManager schemaManager) throws NamingException { + super(schemaManager); + m_ldapAttribute = parseDefAttributes(attrs); + m_path = ATTRDEF + "/" + m_ldapAttribute.getName(); + } + + /** + * Parse Definition Attributes for a LDAP attribute + */ + static LDAPAttributeSchema parseDefAttributes(Attributes attrs) throws NamingException { + String name="", oid="", desc=""; + int syntax=-1; + boolean singleValued = false; + + for (Enumeration attrEnum = attrs.getAll(); attrEnum.hasMoreElements(); ) { + Attribute attr = (Attribute) attrEnum.nextElement(); + String attrName = attr.getID(); + if (attrName.equals(NAME)) { + for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) { + name = (String)valEnum.nextElement(); + break; + } + } + else if (attrName.equals(NUMERICOID)) { + for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) { + oid = (String)valEnum.nextElement(); + break; + } + } + else if (attrName.equals(SYNTAX)) { + for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) { + String syntaxString = (String)valEnum.nextElement(); + syntax = syntaxStringToInt(syntaxString); + break; + } + } + else if (attrName.equals(DESC)) { + for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) { + desc = (String)valEnum.nextElement(); + break; + } + } + else if (attrName.equals(SINGLEVALUE)) { + for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) { + String flag = (String)valEnum.nextElement(); + if (flag.equals("true")) { + singleValued = true; + } + else if (flag.equals("false")) { + singleValued = false; + } + else { + throw new InvalidAttributeValueException(attrName); + } + break; + } + } + else if (attrName.equals(OBSOLETE) || attrName.equals(SUP) || attrName.equals(USAGE) || + attrName.equals(EQUALITY) || attrName.equals(ORDERING) || + attrName.equals(COLLECTIVE) || attrName.equals(NOUSERMOD)) { + ; //ignore + } + else { + throw new NamingException("Invalid schema attribute type for attribute definition " + attrName); + } + } + + if (name.length() == 0 || oid.length() == 0 || syntax == -1) { + throw new NamingException("Incomplete schema attribute definition"); + } + + return new LDAPAttributeSchema(name, oid, desc, syntax, singleValued); + } + + + /** + * Exctract specified attributes from the ldapObjectClass + */ + Attributes extractAttributeIds(String[] attrIds) throws NamingException{ + Attributes attrs = new BasicAttributes(); + for (int i = 0; i < attrIds.length; i++) { + if (attrIds[i].equals(NUMERICOID)) { + attrs.put(new BasicAttribute(NUMERICOID, m_ldapAttribute.getOID())); + } + else if (attrIds[i].equals(NAME)) { + attrs.put(new BasicAttribute(NAME, m_ldapAttribute.getName())); + } + else if (attrIds[i].equals(DESC)) { + attrs.put(new BasicAttribute(DESC, m_ldapAttribute.getDescription())); + } + else if (attrIds[i].equals(SYNTAX)) { + attrs.put(new BasicAttribute(SYNTAX, syntaxIntToString(m_ldapAttribute.getSyntax()))); + } + else if (attrIds[i].equals(SINGLEVALUE)) { + attrs.put(new BasicAttribute(SINGLEVALUE, + (m_ldapAttribute.isSingleValued() ? "true" : "false"))); + } + else { + // ignore other attrIds as not supported by Netscape LdapJDK APIs + } + } + return attrs; + } + + + /** + * DirContext Attribute Operations + */ + + public Attributes getAttributes(String name) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + return extractAttributeIds(m_allAttrIds); + } + + public Attributes getAttributes(String name, String[] attrIds) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + return extractAttributeIds(attrIds); + } + + public Attributes getAttributes(Name name) throws NamingException { + return getAttributes(name.toString()); + } + + public Attributes getAttributes(Name name, String[] attrIds) throws NamingException { + return getAttributes(name.toString(), attrIds); + } + + public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + Attributes modAttrs = extractAttributeIds(m_allAttrIds); + modifySchemaElementAttrs(modAttrs, mod_op, attrs); + LDAPAttributeSchema modLdapAttribute = parseDefAttributes(modAttrs); + m_schemaMgr.modifyAttribute(m_ldapAttribute, modLdapAttribute); + m_ldapAttribute = modLdapAttribute; + } + + public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + Attributes modAttrs = extractAttributeIds(m_allAttrIds); + modifySchemaElementAttrs(modAttrs, mods); + LDAPAttributeSchema modLdapAttribute = parseDefAttributes(modAttrs); + m_schemaMgr.modifyAttribute(m_ldapAttribute, modLdapAttribute); + m_ldapAttribute = modLdapAttribute; + } + + public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException { + modifyAttributes(name.toString(), mod_op, attrs); + } + + public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException { + modifyAttributes(name.toString(), mods); + } + + /** + * Search operations are not implemented because of complexity. Ir will require + * to implement the full LDAP search filter sematics in the client. (The search + * filter sematics is implemented by the Directory server). + */ + +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaAttributeContainer.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaAttributeContainer.java new file mode 100644 index 00000000000..a61bf8bc681 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaAttributeContainer.java @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.schema; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; +import netscape.ldap.controls.*; + +import java.util.*; + +public class SchemaAttributeContainer extends SchemaElementContainer { + + public SchemaAttributeContainer(SchemaManager schemaMgr) throws NamingException{ + super(schemaMgr, ATTRDEF); + } + + /** + * Ldap entry operations + */ + + public DirContext createSchemaElement(String name, Attributes attrs) throws NamingException { + if (name.length() == 0) { + throw new NamingException("Empty name for schema objectclass"); + } + LDAPAttributeSchema attr = SchemaAttribute.parseDefAttributes(attrs); + m_schemaMgr.createAttribute(attr); + return new SchemaAttribute(attr, m_schemaMgr); + + } + + public void removeSchemaElement(String name) throws NamingException { + if (name.length() == 0) { + throw new NamingException("Can not delete schema object container"); + } + m_schemaMgr.removeAttribute(name); + } + + /** + * List Operations + */ + + public NamingEnumeration getNameList(String name) throws NamingException { + SchemaDirContext schemaObj = (SchemaDirContext)lookup(name); + if (schemaObj == this) { + return new SchemaElementNameEnum(m_schemaMgr.getAttributeNames()); + } + else { + throw new NotContextException(name); + } + } + + public NamingEnumeration getBindingsList(String name) throws NamingException { + SchemaDirContext schemaObj = (SchemaDirContext)lookup(name); + if (schemaObj == this) { + return new SchemaElementBindingEnum(m_schemaMgr.getAttributes(), m_schemaMgr); + } + else { + throw new NotContextException(name); + } + } + + /** + * Lookup Operations + */ + + public Object lookupSchemaElement(String name) throws NamingException { + if (name.length() == 0) { + return this; + } + + // No caching; Always create a new object + LDAPAttributeSchema attr = m_schemaMgr.getAttribute(name); + if (attr == null) { + throw new NameNotFoundException(name); + } + return new SchemaAttribute(attr, m_schemaMgr); + + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaDirContext.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaDirContext.java new file mode 100644 index 00000000000..03ad4ce6c95 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaDirContext.java @@ -0,0 +1,160 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.schema; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; +import netscape.ldap.controls.*; +import com.netscape.jndi.ldap.common.DirContextAdapter; + +import java.util.*; + +public class SchemaDirContext extends DirContextAdapter { + + public static final String CLASSDEF = "ClassDefinition"; + public static final String ATTRDEF = "AttributeDefinition"; + public static final String MRULEDEF = "MatchingRule"; + + + String m_path; + + public void close() throws NamingException { + ; //NOP + } + + /** + * Name operations + */ + + public String composeName(String name, String prefix) throws NamingException { + return name + "," + prefix; + } + + public Name composeName(Name name, Name prefix) throws NamingException { + String compoundName = composeName(name.toString(), prefix.toString()); + return SchemaNameParser.getParser().parse(compoundName); + } + + public String getNameInNamespace() throws NamingException { + return new String(m_path); + } + + public NameParser getNameParser(String name) throws NamingException { + return SchemaNameParser.getParser(); + } + + public NameParser getNameParser(Name name) throws NamingException { + return SchemaNameParser.getParser(); + } + + + /** + * Naming Bind operations + */ + + public void bind(String name, Object obj) throws NamingException { + if (obj instanceof DirContext) { + createSubcontext(name, ((DirContext)obj).getAttributes("")); + } + else { + throw new IllegalArgumentException("Can not bind this type of object"); + } + } + + public void bind(Name name, Object obj) throws NamingException { + bind(name.toString(), obj); + } + + public void rebind(String name, Object obj) throws NamingException { + try { + bind(name, obj); + } + catch (NameAlreadyBoundException ex) { + unbind(name); + bind(name, obj); + } + } + + public void rebind(Name name, Object obj) throws NamingException { + rebind(name.toString(), obj); + } + + public void rename(String oldName, String newName) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void rename(Name oldName, Name newName) throws NamingException { + rename(oldName.toString(), newName.toString()); + } + + public void unbind(String name) throws NamingException { + // In ldap every entry is naming context + destroySubcontext(name); + } + + public void unbind(Name name) throws NamingException { + // In ldap every entry is naming context + destroySubcontext(name); + } + + /** + * Empty enumeration for list operations + */ + class EmptyNamingEnumeration implements NamingEnumeration { + + public Object next() throws NamingException{ + throw new NoSuchElementException("EmptyNamingEnumeration"); + } + + public Object nextElement() { + throw new NoSuchElementException("EmptyNamingEnumeration"); + } + + public boolean hasMore() throws NamingException{ + return false; + } + + public boolean hasMoreElements() { + return false; + } + + public void close() {} + } + + static class SchemaObjectSubordinateNamePair { + SchemaDirContext schemaObj; + String subordinateName; + + public SchemaObjectSubordinateNamePair(SchemaDirContext object, String subordinateName) { + this.schemaObj = object; + this.subordinateName = subordinateName; + } + + public String toString() { + StringBuffer str = new StringBuffer("SchemaObjectSubordinateNamePair{obj:"); + str.append(((schemaObj == null) ? "null" : schemaObj.toString())); + str.append(" name:"); + str.append(subordinateName); + str.append("}"); + return str.toString(); + } + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaElement.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaElement.java new file mode 100644 index 00000000000..66c5f5c0b6a --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaElement.java @@ -0,0 +1,213 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.schema; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; +import netscape.ldap.controls.*; + +import java.util.*; + +public class SchemaElement extends SchemaDirContext { + + SchemaManager m_schemaMgr; + + // Attributes used to define schema elements + static final String NUMERICOID = "NUMERICOID"; + static final String NAME = "NAME"; + static final String DESC = "DESC"; + static final String SYNTAX = "SYNTAX"; + static final String SUP = "SUP"; + static final String MUST = "MUST"; + static final String MAY = "MAY"; + static final String SINGLEVALUE = "SINGLE-VALUE"; + + // These attribute definition properties are not supported by LdapJDK and DS + // Accept them for the appropriate schema element, but ignore them + static final String OBSOLETE = "OBSOLETE"; + static final String EQUALITY = "EQUALITY"; + static final String ORDERING = "ORDERING"; + static final String COLLECTIVE = "COLLECTIVE"; + static final String NOUSERMOD = "NO-USER-MODIFICATION"; + static final String USAGE = "USAGE"; + static final String ABSTRACT = "ABSTRACT"; + static final String STRUCTURAL = "STRUCTURAL"; + static final String AUXILIARY = "AUXILIARY"; + + + // Syntax string recognized by Netscape LdapJDK + static final String cisString = "1.3.6.1.4.1.1466.115.121.1.15"; + static final String binaryString = "1.3.6.1.4.1.1466.115.121.1.5"; + static final String telephoneString = "1.3.6.1.4.1.1466.115.121.1.50"; + static final String cesString = "1.3.6.1.4.1.1466.115.121.1.26"; + static final String intString = "1.3.6.1.4.1.1466.115.121.1.27"; + static final String dnString = "1.3.6.1.4.1.1466.115.121.1.12"; + + SchemaElement(SchemaManager schemaMgr) { + m_schemaMgr = schemaMgr; + } + + /** + * Map a syntax oid string to a constant recognized by LdapJDK + */ + static int syntaxStringToInt(String syntax) throws NamingException{ + if (syntax.equals(cisString)) { + return LDAPSchemaElement.cis; + } + else if (syntax.equals(cesString)) { + return LDAPSchemaElement.ces; + } + else if (syntax.equals(telephoneString)) { + return LDAPSchemaElement.telephone; + } + else if (syntax.equals(intString)) { + return LDAPSchemaElement.integer; + } + else if (syntax.equals(dnString)) { + return LDAPSchemaElement.dn; + } + else if (syntax.equals(binaryString)) { + return LDAPSchemaElement.binary; + } + else { + throw new InvalidAttributeValueException(syntax); + } + } + + /** + * Map a syntax identifier to a oid string + */ + static String syntaxIntToString(int syntax) throws NamingException{ + if (syntax == LDAPSchemaElement.cis) { + return cisString; + } + else if (syntax == LDAPSchemaElement.ces) { + return cesString; + } + else if (syntax == LDAPSchemaElement.telephone) { + return telephoneString; + } + else if (syntax == LDAPSchemaElement.integer) { + return intString; + } + else if (syntax == LDAPSchemaElement.dn) { + return dnString; + } + else if (syntax == LDAPSchemaElement.binary) { + return binaryString; + } + else { + throw new InvalidAttributeValueException("Interanal error, unexpected syntax value " + syntax); + } + } + + /** + * Convert string vector to an array + */ + static String[] vectorToStringAry(Vector v) { + String[] ary = new String[v.size()]; + for(int i=0; i 0) { + BasicAttribute applies = new BasicAttribute(APPLIES); + for (int a=0; a < appliesToAttrs.length; a++) { + applies.add(appliesToAttrs[a]); + } + attrs.put(applies); + } + } + else { + // ignore other attrIds as not supported by Netscape LdapJDK APIs + } + } + return attrs; + } + + + /** + * DirContext Attribute Operations + */ + + public Attributes getAttributes(String name) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + return extractAttributeIds(m_allAttrIds); + } + + public Attributes getAttributes(String name, String[] attrIds) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + return extractAttributeIds(attrIds); + } + + public Attributes getAttributes(Name name) throws NamingException { + return getAttributes(name.toString()); + } + + public Attributes getAttributes(Name name, String[] attrIds) throws NamingException { + return getAttributes(name.toString(), attrIds); + } + + public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + Attributes modAttrs = extractAttributeIds(m_allAttrIds); + modifySchemaElementAttrs(modAttrs, mod_op, attrs); + LDAPMatchingRuleSchema modLdapMatchingRule = parseDefAttributes(modAttrs); + m_schemaMgr.modifyMatchingRule(m_ldapMatchingRule, modLdapMatchingRule); + m_ldapMatchingRule = modLdapMatchingRule; + } + + public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + Attributes modAttrs = extractAttributeIds(m_allAttrIds); + modifySchemaElementAttrs(modAttrs, mods); + LDAPMatchingRuleSchema modLdapMatchingRule = parseDefAttributes(modAttrs); + m_schemaMgr.modifyMatchingRule(m_ldapMatchingRule, modLdapMatchingRule); + m_ldapMatchingRule = modLdapMatchingRule; + } + + public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException { + modifyAttributes(name.toString(), mod_op, attrs); + } + + public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException { + modifyAttributes(name.toString(), mods); + } + + /** + * Search operations are not implemented because of complexity. Ir will require + * to implement the full LDAP search filter sematics in the client. (The search + * filter sematics is implemented by the Directory server). + */ + +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaMatchingRuleContainer.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaMatchingRuleContainer.java new file mode 100644 index 00000000000..ca2f85ba892 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaMatchingRuleContainer.java @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.schema; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; +import netscape.ldap.controls.*; + +import java.util.*; + +public class SchemaMatchingRuleContainer extends SchemaElementContainer { + + public SchemaMatchingRuleContainer(SchemaManager schemaMgr) throws NamingException{ + super(schemaMgr, MRULEDEF); + } + + /** + * Ldap entry operations + */ + + public DirContext createSchemaElement(String name, Attributes attrs) throws NamingException { + if (name.length() == 0) { + throw new NamingException("Empty name for schema objectclass"); + } + LDAPMatchingRuleSchema mrule = SchemaMatchingRule.parseDefAttributes(attrs); + m_schemaMgr.createMatchingRule(mrule); + return new SchemaMatchingRule(mrule, m_schemaMgr); + + } + + public void removeSchemaElement(String name) throws NamingException { + if (name.length() == 0) { + throw new NamingException("Can not delete schema object container"); + } + m_schemaMgr.removeMatchingRule(name); + } + + /** + * List Operations + */ + + public NamingEnumeration getNameList(String name) throws NamingException { + SchemaDirContext schemaObj = (SchemaDirContext)lookup(name); + if (schemaObj == this) { + return new SchemaElementNameEnum(m_schemaMgr.getMatchingRuleNames()); + } + else { + throw new NotContextException(name); + } + } + + public NamingEnumeration getBindingsList(String name) throws NamingException { + SchemaDirContext schemaObj = (SchemaDirContext)lookup(name); + if (schemaObj == this) { + return new SchemaElementBindingEnum(m_schemaMgr.getMatchingRules(), m_schemaMgr); + } + else { + throw new NotContextException(name); + } + } + + /** + * Lookup Operations + */ + + public Object lookupSchemaElement(String name) throws NamingException { + if (name.length() == 0) { + return this; + } + + // No caching; Always create a new object + LDAPAttributeSchema mrule = m_schemaMgr.getMatchingRule(name); + if (mrule == null) { + throw new NameNotFoundException(name); + } + return new SchemaAttribute(mrule, m_schemaMgr); + + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaNameParser.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaNameParser.java new file mode 100644 index 00000000000..470c4a477fd --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaNameParser.java @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.schema; + +import java.util.Hashtable; +import java.util.Properties; +import javax.naming.*; + +class SchemaNameParser implements NameParser { + + private static SchemaNameParser m_parser; + + // A table with compound name syntax properties + static Properties nameSyntax; + static { + nameSyntax = new Properties(); + nameSyntax.put("jndi.syntax.direction", "left_to_right"); + nameSyntax.put("jndi.syntax.separator", "/"); + nameSyntax.put("jndi.syntax.ignorecase", "true"); + } + + // Can not be constructed + private SchemaNameParser() {} + + // Shared instance must be used + public static SchemaNameParser getParser() { + if (m_parser == null) { + m_parser = new SchemaNameParser(); + } + return m_parser; + } + + // implements parse + public Name parse(String name) throws NamingException { + return new CompoundName(name, nameSyntax); + } + +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaObjectClass.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaObjectClass.java new file mode 100644 index 00000000000..9e8a685c312 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaObjectClass.java @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.schema; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; +import netscape.ldap.controls.*; + +import java.util.*; + +public class SchemaObjectClass extends SchemaElement { + + LDAPObjectClassSchema m_ldapObjectClass; + + // Attribute IDs that are exposed through Netscape LdapJDK + private static String[] m_allAttrIds = {NUMERICOID, NAME, DESC, SUP, MUST, MAY }; + + public SchemaObjectClass(LDAPObjectClassSchema ldapObjectClass, SchemaManager schemaManager) { + super(schemaManager); + m_ldapObjectClass = ldapObjectClass; + m_path = CLASSDEF + "/" + m_ldapObjectClass.getName(); + } + + public SchemaObjectClass(Attributes attrs, SchemaManager schemaManager) throws NamingException { + super(schemaManager); + m_ldapObjectClass = parseDefAttributes(attrs); + m_path = CLASSDEF + "/" + m_ldapObjectClass.getName(); + } + + /** + * Parse Definition Attributes for a LDAP objectcalss + */ + static LDAPObjectClassSchema parseDefAttributes(Attributes attrs) throws NamingException { + String name="", oid="", desc="", sup=""; + Vector must=new Vector(), may=new Vector(); + + for (Enumeration attrEnum = attrs.getAll(); attrEnum.hasMoreElements(); ) { + Attribute attr = (Attribute) attrEnum.nextElement(); + String attrName = attr.getID(); + if (attrName.equals(NAME)) { + for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) { + name = (String)valEnum.nextElement(); + break; + } + } + else if (attrName.equals(NUMERICOID)) { + for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) { + oid = (String)valEnum.nextElement(); + break; + } + } + else if (attrName.equals(SUP)) { + for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) { + sup = (String)valEnum.nextElement(); + break; + } + } + else if (attrName.equals(DESC)) { + for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) { + desc = (String)valEnum.nextElement(); + break; + } + } + else if (attrName.equals(MAY)) { + for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) { + may.addElement((String)valEnum.nextElement()); + } + } + else if (attrName.equals(MUST)) { + for (Enumeration valEnum = attr.getAll(); valEnum.hasMoreElements(); ) { + must.addElement((String)valEnum.nextElement()); + } + } + else if (attrName.equals(OBSOLETE) || attrName.equals(ABSTRACT) || + attrName.equals(STRUCTURAL) || attrName.equals(AUXILIARY)) { + ; //ignore + } + else { + throw new NamingException("Invalid schema attribute type for object class definition " + attrName); + } + } + + if (name.length() == 0 || oid.length() == 0 || sup.length() == 0 || + (must.size() == 0 && may.size() == 0)) { + + throw new NamingException("Incomplete schema object class definition"); + } + + return new LDAPObjectClassSchema(name, oid, sup, desc, + vectorToStringAry(must), + vectorToStringAry(may)); + } + + /** + * Exctract specified attributes from the ldapObjectClass + */ + Attributes extractAttributeIds(String[] attrIds) { + Attributes attrs = new BasicAttributes(); + for (int i = 0; i < attrIds.length; i++) { + if (attrIds[i].equals(NUMERICOID)) { + attrs.put(new BasicAttribute(NUMERICOID, m_ldapObjectClass.getOID())); + } + else if (attrIds[i].equals(NAME)) { + attrs.put(new BasicAttribute(NAME, m_ldapObjectClass.getName())); + } + else if (attrIds[i].equals(DESC)) { + attrs.put(new BasicAttribute(DESC, m_ldapObjectClass.getDescription())); + } + else if (attrIds[i].equals(SUP)) { + attrs.put(new BasicAttribute(SUP, m_ldapObjectClass.getSuperior())); + } + else if (attrIds[i].equals(MAY)) { + BasicAttribute optional = new BasicAttribute(MAY); + for (Enumeration e = m_ldapObjectClass.getOptionalAttributes(); e.hasMoreElements();) { + optional.add(e.nextElement()); + } + attrs.put(optional); + } + else if (attrIds[i].equals(MUST)) { + BasicAttribute required = new BasicAttribute(MUST); + for (Enumeration e = m_ldapObjectClass.getRequiredAttributes(); e.hasMoreElements();) { + required.add(e.nextElement()); + } + attrs.put(required); + } + else { + // ignore other attrIds as not supported by Netscape LdapJDK APIs + } + } + return attrs; + } + + + /** + * DirContext Attribute Operations + */ + + public Attributes getAttributes(String name) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + return extractAttributeIds(m_allAttrIds); + } + + public Attributes getAttributes(String name, String[] attrIds) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + return extractAttributeIds(attrIds); + } + + public Attributes getAttributes(Name name) throws NamingException { + return getAttributes(name.toString()); + } + + public Attributes getAttributes(Name name, String[] attrIds) throws NamingException { + return getAttributes(name.toString(), attrIds); + } + + public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + Attributes modAttrs = extractAttributeIds(m_allAttrIds); + modifySchemaElementAttrs(modAttrs, mod_op, attrs); + LDAPObjectClassSchema modLdapObjectClass = parseDefAttributes(modAttrs); + m_schemaMgr.modifyObjectClass(m_ldapObjectClass, modLdapObjectClass); + m_ldapObjectClass = modLdapObjectClass; + } + + public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException { + if (name.length() != 0) { // no subcontexts + throw new NameNotFoundException(name); // no such object + } + Attributes modAttrs = extractAttributeIds(m_allAttrIds); + modifySchemaElementAttrs(modAttrs, mods); + LDAPObjectClassSchema modLdapObjectClass = parseDefAttributes(modAttrs); + m_schemaMgr.modifyObjectClass(m_ldapObjectClass, modLdapObjectClass); + m_ldapObjectClass = modLdapObjectClass; + } + + public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException { + modifyAttributes(name.toString(), mod_op, attrs); + } + + public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException { + modifyAttributes(name.toString(), mods); + } + + /** + * Search operations are not implemented because of complexity. Ir will require + * to implement the full LDAP search filter sematics in the client. (The search + * filter sematics is implemented by the Directory server). + */ + +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaObjectClassContainer.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaObjectClassContainer.java new file mode 100644 index 00000000000..2140bd440c2 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaObjectClassContainer.java @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.schema; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; +import netscape.ldap.controls.*; + +import java.util.*; + +public class SchemaObjectClassContainer extends SchemaElementContainer { + + public SchemaObjectClassContainer(SchemaManager schemaMgr) throws NamingException{ + super(schemaMgr, CLASSDEF); + } + + /** + * Ldap entry operations + */ + + public DirContext createSchemaElement(String name, Attributes attrs) throws NamingException { + if (name.length() == 0) { + throw new NamingException("Empty name for schema objectclass"); + } + LDAPObjectClassSchema objclass = SchemaObjectClass.parseDefAttributes(attrs); + m_schemaMgr.createObjectClass(objclass); + return new SchemaObjectClass(objclass, m_schemaMgr); + + } + + public void removeSchemaElement(String name) throws NamingException { + if (name.length() == 0) { + throw new NamingException("Can not delete schema object container"); + } + m_schemaMgr.removeObjectClass(name); + } + + /** + * List Operations + */ + + public NamingEnumeration getNameList(String name) throws NamingException { + SchemaDirContext schemaObj = (SchemaDirContext)lookup(name); + if (schemaObj == this) { + return new SchemaElementNameEnum(m_schemaMgr.getObjectClassNames()); + } + else { + throw new NotContextException(name); + } + } + + public NamingEnumeration getBindingsList(String name) throws NamingException { + SchemaDirContext schemaObj = (SchemaDirContext)lookup(name); + if (schemaObj == this) { + return new SchemaElementBindingEnum(m_schemaMgr.getObjectClasses(), m_schemaMgr); + } + else { + throw new NotContextException(name); + } + } + + /** + * Lookup Operations + */ + + public Object lookupSchemaElement(String name) throws NamingException { + if (name.length() == 0) { + return this; + } + + // No caching; Always create a new object + LDAPObjectClassSchema objclass = m_schemaMgr.getObjectClass(name); + if (objclass == null) { + throw new NameNotFoundException(name); + } + return new SchemaObjectClass(objclass, m_schemaMgr); + + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaRoot.java b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaRoot.java new file mode 100644 index 00000000000..f2fac29a934 --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/com/netscape/jndi/ldap/schema/SchemaRoot.java @@ -0,0 +1,360 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + */ +package com.netscape.jndi.ldap.schema; + +import javax.naming.*; +import javax.naming.directory.*; +import javax.naming.ldap.*; + +import netscape.ldap.*; +import netscape.ldap.controls.*; + +import java.util.*; + +public class SchemaRoot extends SchemaDirContext { + + static final String m_className = "javax.naming.directory.DirContext"; // for class name is bindings + + SchemaDirContext m_classContainer, m_attrContainer, m_matchRuleContainer; + + SchemaManager m_schemaMgr; + + public SchemaRoot(LDAPConnection ld) throws NamingException{ + m_path = ""; + m_schemaMgr = new SchemaManager(ld); + m_classContainer = new SchemaObjectClassContainer(m_schemaMgr); + m_attrContainer = new SchemaAttributeContainer(m_schemaMgr); + m_matchRuleContainer = new SchemaMatchingRuleContainer(m_schemaMgr); + } + + SchemaObjectSubordinateNamePair resolveSchemaObject(String name) throws NamingException{ + + SchemaDirContext obj = null; + + if (name.length() == 0) { + obj = this; + } + else if (name.startsWith(CLASSDEF) || name.startsWith(CLASSDEF.toLowerCase())) { + name = name.substring(CLASSDEF.length()); + obj = m_classContainer; + } + else if (name.startsWith(ATTRDEF) || name.startsWith(ATTRDEF.toLowerCase())) { + name = name.substring(ATTRDEF.length()); + obj = m_attrContainer; + } + else if (name.startsWith(MRULEDEF) || name.startsWith(MRULEDEF.toLowerCase())) { + name = name.substring(MRULEDEF.length()); + obj = m_matchRuleContainer; + + } + else { + throw new NameNotFoundException(name); + } + + if (name.length() > 1 && name.startsWith("/")) { + name = name.substring(1); + } + return new SchemaObjectSubordinateNamePair(obj, name); + } + + + /** + * Attribute Operations + */ + + public Attributes getAttributes(String name) throws NamingException { + SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name); + if (objNamePair.schemaObj == this) { + throw new OperationNotSupportedException(); + } + else { + return objNamePair.schemaObj.getAttributes(objNamePair.subordinateName); + } + } + + public Attributes getAttributes(String name, String[] attrIds) throws NamingException { + SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name); + if (objNamePair.schemaObj == this) { + throw new OperationNotSupportedException(); + } + else { + return objNamePair.schemaObj.getAttributes(objNamePair.subordinateName, attrIds); + } + } + + public Attributes getAttributes(Name name) throws NamingException { + return getAttributes(name.toString()); + } + + public Attributes getAttributes(Name name, String[] attrIds) throws NamingException { + return getAttributes(name.toString(), attrIds); + } + + public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException { + throw new OperationNotSupportedException(); + } + + /** + * Ldap entry operations + */ + + public Context createSubcontext(String name) throws NamingException { + // Directory entry must have attributes + throw new OperationNotSupportedException(); + } + + public Context createSubcontext(Name name) throws NamingException { + // Directory entry must have attributes + throw new OperationNotSupportedException(); + } + + public DirContext createSubcontext(String name, Attributes attrs) throws NamingException { + SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name); + if (objNamePair.schemaObj == this) { + throw new OperationNotSupportedException(); + } + else { + return objNamePair.schemaObj.createSubcontext(objNamePair.subordinateName, attrs); + } + } + + public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException { + return createSubcontext(name.toString(), attrs); + } + + public void destroySubcontext(String name) throws NamingException { + SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name); + if (objNamePair.schemaObj == this) { + throw new OperationNotSupportedException(); + } + else { + objNamePair.schemaObj.destroySubcontext(objNamePair.subordinateName); + } + } + + public void destroySubcontext(Name name) throws NamingException { + destroySubcontext(name.toString()); + } + + /** + * Naming Bind operations + */ + + public void bind(String name, Object obj) throws NamingException { + if (obj instanceof DirContext) { + createSubcontext(name, ((DirContext)obj).getAttributes("")); + } + else { + throw new IllegalArgumentException("Can not bind this type of object"); + } + } + + public void bind(Name name, Object obj) throws NamingException { + bind(name.toString(), obj); + } + + public void rebind(String name, Object obj) throws NamingException { + unbind(name); + bind(name, obj); + } + + public void rebind(Name name, Object obj) throws NamingException { + rebind(name.toString(), obj); + } + + public void rename(String oldName, String newName) throws NamingException { + throw new OperationNotSupportedException(); + } + + public void rename(Name oldName, Name newName) throws NamingException { + rename(oldName.toString(), newName.toString()); + } + + public void unbind(String name) throws NamingException { + // In ldap every entry is naming context + destroySubcontext(name); + } + + public void unbind(Name name) throws NamingException { + // In ldap every entry is naming context + destroySubcontext(name); + } + + /** + * List Operations + */ + + public NamingEnumeration list(String name) throws NamingException { + SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name); + if (objNamePair.schemaObj == this) { + return new SchemaRootNameClassPairEnum(); + } + else { + return objNamePair.schemaObj.list(objNamePair.subordinateName); + } + } + + public NamingEnumeration list(Name name) throws NamingException { + return list(name.toString()); + } + + public NamingEnumeration listBindings(String name) throws NamingException { + SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name); + if (objNamePair.schemaObj == this) { + return new SchemaRootBindingEnum(); + } + else { + return objNamePair.schemaObj.listBindings(objNamePair.subordinateName); + } + + } + + public NamingEnumeration listBindings(Name name) throws NamingException { + return listBindings(name.toString()); + } + + /** + * Lookup Operations + */ + + public Object lookup(String name) throws NamingException { + SchemaObjectSubordinateNamePair objNamePair = resolveSchemaObject(name); + if (objNamePair.schemaObj == this) { + return this; + } + else { + return objNamePair.schemaObj.lookup(objNamePair.subordinateName); + } + + } + + public Object lookup(Name name) throws NamingException { + return lookup(name.toString()); + } + + public Object lookupLink(String name) throws NamingException { + throw new OperationNotSupportedException(); + } + + public Object lookupLink(Name name) throws NamingException { + throw new OperationNotSupportedException(); + } + + /** + * Test program + */ + public static void main(String args[]) { + try { + String name = args[0]; + System.out.println((new SchemaRoot(null)).resolveSchemaObject(name)); + } + catch (Exception e) { + System.err.println(e); + } + } + + /** + * NamigEnumeration of NameClassPairs + */ + class SchemaRootNameClassPairEnum implements NamingEnumeration { + + private int m_idx = -1; + + public Object next() { + return nextElement(); + } + + public Object nextElement() { + m_idx++; + if (m_idx == 0 ) { + return new NameClassPair(CLASSDEF, m_className); + } + else if (m_idx == 1) { + return new NameClassPair(ATTRDEF, m_className); + } + else if (m_idx == 2) { + return new NameClassPair(MRULEDEF, m_className); + } + else { + throw new NoSuchElementException("SchemaRootEnumerator"); + } + + } + + public boolean hasMore() { + return hasMoreElements(); + } + + public boolean hasMoreElements() { + return m_idx < 2; + } + + public void close() {} + } + + /** + * NamingEnumeration of Bindings + */ + class SchemaRootBindingEnum implements NamingEnumeration { + + private int m_idx = -1; + + public Object next() { + return nextElement(); + } + + public Object nextElement() { + m_idx++; + if (m_idx == 0 ) { + return new Binding(CLASSDEF, m_className, m_classContainer); + } + else if (m_idx == 1) { + return new Binding(ATTRDEF, m_className, m_attrContainer); + } + else if (m_idx == 2) { + return new Binding(MRULEDEF, m_className, m_matchRuleContainer); + } + else { + throw new NoSuchElementException("SchemaRootEnumerator"); + } + + } + + public boolean hasMore() { + return hasMoreElements(); + } + + public boolean hasMoreElements() { + return m_idx < 2; + } + + public void close() {} + } +} diff --git a/mozilla/directory/java-sdk/ldapsp/jndi-object-schema.conf b/mozilla/directory/java-sdk/ldapsp/jndi-object-schema.conf new file mode 100644 index 00000000000..f901d90f3ae --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/jndi-object-schema.conf @@ -0,0 +1,47 @@ +# +# -- Attribute types -- +# +attribute javaClassName 1.3.6.1.4.1.42.2.27.4.1.6 ces single +attribute javaCodebase 1.3.6.1.4.1.42.2.27.4.1.7 ces +attribute javaSerializedData 1.3.6.1.4.1.42.2.27.4.1.8 bin single +attribute javaRemoteLocation 1.3.6.1.4.1.42.2.27.4.1.9 ces single +attribute javaFactory 1.3.6.1.4.1.42.2.27.4.1.10 ces single +attribute javaReferenceAddress 1.3.6.1.4.1.42.2.27.4.1.11 ces + +# +# -- Object classes -- +# +objectclass javaContainer + oid 1.3.6.1.4.1.42.2.27.4.2.1 + superior top + requires + cn + +objectclass javaObject + oid 1.3.6.1.4.1.42.2.27.4.2.4 + superior top + requires + javaClassName + allows + javaCodebase + +objectclass javaSerializedObject + oid 1.3.6.1.4.1.42.2.27.4.2.5 + superior javaObject + requires + javaSerializedData + + +objectclass javaRemoteObject + oid 1.3.6.1.4.1.42.2.27.4.2.6 + superior javaObject + requires + javaRemoteLocation + +objectclass javaNamingReference + oid 1.3.6.1.4.1.42.2.27.4.2.7 + superior javaObject + allows + javaReferenceAddress, + javaFactory + diff --git a/mozilla/directory/java-sdk/ldapsp/lib/jndi.jar b/mozilla/directory/java-sdk/ldapsp/lib/jndi.jar new file mode 100644 index 00000000000..54dcb652792 Binary files /dev/null and b/mozilla/directory/java-sdk/ldapsp/lib/jndi.jar differ diff --git a/mozilla/directory/java-sdk/ldapsp/manifest.mf b/mozilla/directory/java-sdk/ldapsp/manifest.mf new file mode 100644 index 00000000000..99b9c1baf2b --- /dev/null +++ b/mozilla/directory/java-sdk/ldapsp/manifest.mf @@ -0,0 +1,104 @@ +Name: com/netscape/jndi/ldap/AttributeEnum.class + +Name: com/netscape/jndi/ldap/AttributeIDEnum.class + +Name: com/netscape/jndi/ldap/AttributesImpl.class + +Name: com/netscape/jndi/ldap/BindingEnum.class + +Name: com/netscape/jndi/ldap/ContextEnv$ReferralRebindProc.class + +Name: com/netscape/jndi/ldap/ContextEnv.class + +Name: com/netscape/jndi/ldap/EventService$EventThread.class + +Name: com/netscape/jndi/ldap/EventService.class + +Name: com/netscape/jndi/ldap/LdapContextFactory.class + +Name: com/netscape/jndi/ldap/LdapContextImpl.class + +Name: com/netscape/jndi/ldap/LdapNameParser.class + +Name: com/netscape/jndi/ldap/LdapReferralException.class + +Name: com/netscape/jndi/ldap/LdapService.class + +Name: com/netscape/jndi/ldap/NameClassPairEnum.class + +Name: com/netscape/jndi/ldap/ObjectMapper.class + +Name: com/netscape/jndi/ldap/ProviderUtils.class + +Name: com/netscape/jndi/ldap/SearchResultEnum.class + +Name: com/netscape/jndi/ldap/SearchResultWithControls.class + +Name: com/netscape/jndi/ldap/common/Debug.class + +Name: com/netscape/jndi/ldap/common/DirContextAdapter.class + +Name: com/netscape/jndi/ldap/common/ExceptionMapper.class + +Name: com/netscape/jndi/ldap/common/LdapContextAdapter.class + +Name: com/netscape/jndi/ldap/common/ShareableEnv.class + +Name: com/netscape/jndi/ldap/schema/SchemaAttribute.class + +Name: com/netscape/jndi/ldap/schema/SchemaAttributeContainer.class + +Name: com/netscape/jndi/ldap/schema/SchemaDirContext$EmptyNamingEnumeration.class + +Name: com/netscape/jndi/ldap/schema/SchemaDirContext$SchemaObjectSubordinateNamePair.class + +Name: com/netscape/jndi/ldap/schema/SchemaDirContext.class + +Name: com/netscape/jndi/ldap/schema/SchemaElement.class + +Name: com/netscape/jndi/ldap/schema/SchemaElementBindingEnum.class + +Name: com/netscape/jndi/ldap/schema/SchemaElementContainer.class + +Name: com/netscape/jndi/ldap/schema/SchemaElementNameEnum.class + +Name: com/netscape/jndi/ldap/schema/SchemaManager.class + +Name: com/netscape/jndi/ldap/schema/SchemaMatchingRule.class + +Name: com/netscape/jndi/ldap/schema/SchemaMatchingRuleContainer.class + +Name: com/netscape/jndi/ldap/schema/SchemaNameParser.class + +Name: com/netscape/jndi/ldap/schema/SchemaObjectClass.class + +Name: com/netscape/jndi/ldap/schema/SchemaObjectClassContainer.class + +Name: com/netscape/jndi/ldap/schema/SchemaRoot$SchemaRootBindingEnum.class + +Name: com/netscape/jndi/ldap/schema/SchemaRoot$SchemaRootNameClassPairEnum.class + +Name: com/netscape/jndi/ldap/schema/SchemaRoot.class + +Name: com/netscape/jndi/ldap/controls/LdapEntryChangeControl.class + +Name: com/netscape/jndi/ldap/controls/LdapPasswordExpiredControl.class + +Name: com/netscape/jndi/ldap/controls/LdapPasswordExpiringControl.class + +Name: com/netscape/jndi/ldap/controls/LdapPersistSearchControl.class + +Name: com/netscape/jndi/ldap/controls/LdapProxiedAuthControl.class + +Name: com/netscape/jndi/ldap/controls/LdapSortControl.class + +Name: com/netscape/jndi/ldap/controls/LdapSortKey.class + +Name: com/netscape/jndi/ldap/controls/LdapSortResponseControl.class + +Name: com/netscape/jndi/ldap/controls/LdapVirtualListControl.class + +Name: com/netscape/jndi/ldap/controls/LdapVirtualListResponseControl.class + +Name: com/netscape/jndi/ldap/controls/NetscapeControlFactory.class +