зеркало из https://github.com/mozilla/pjs.git
Java LDAP SDK 3.5 update
This commit is contained in:
Родитель
53c162fe20
Коммит
2d2b3e97c7
|
@ -86,10 +86,10 @@ all: classes
|
|||
basics: $(DISTDIR) $(CLASSDIR)
|
||||
cp -p manifest.mf $(CLASS_DEST)
|
||||
|
||||
classes: LDAPCLASSES BEANS
|
||||
classes: LDAPCLASSES BEANS TOOLS
|
||||
|
||||
basepackage: $(CLASSPACKAGEDIR)
|
||||
cd $(DISTDIR)/classes; rm -f ../packages/$(BASEPACKAGENAME); $(JAR) cvfm ../packages/$(BASEPACKAGENAME) manifest.mf netscape/ldap/*.class netscape/ldap/client/*.class netscape/ldap/client/opers/*.class netscape/ldap/ber/stream/*.class netscape/ldap/controls/*.class netscape/ldap/util/*.class netscape/ldap/errors/*.props com/netscape/sasl/*.class
|
||||
cd $(DISTDIR)/classes; rm -f ../packages/$(BASEPACKAGENAME); $(JAR) cvfm ../packages/$(BASEPACKAGENAME) manifest.mf netscape/ldap/*.class netscape/ldap/client/*.class netscape/ldap/client/opers/*.class netscape/ldap/ber/stream/*.class netscape/ldap/controls/*.class netscape/ldap/util/*.class netscape/ldap/errors/*.props com/netscape/sasl/*.class tools/*.class
|
||||
|
||||
MAIN: basics
|
||||
cd ldapjdk/$(SRCDIR); $(JAVAC) -d "$(CLASS_DEST)" *.java
|
||||
|
@ -122,6 +122,9 @@ BEANS: OTHERBEANS
|
|||
OTHERBEANS: basics
|
||||
cd ldapbeans/$(SRCDIR)/beans; $(JAVAC) -d "$(CLASS_DEST)" *.java
|
||||
|
||||
TOOLS: basics
|
||||
cd tools; $(JAVAC) -d "$(CLASS_DEST)" *.java
|
||||
|
||||
clean:
|
||||
rm -rf $(DISTDIR)
|
||||
|
||||
|
|
|
@ -204,6 +204,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
private Properties m_securityProperties;
|
||||
private Object m_clientCB;
|
||||
private Hashtable m_methodLookup = new Hashtable();
|
||||
private LDAPConnection m_referralConnection;
|
||||
|
||||
/**
|
||||
* Properties
|
||||
|
@ -212,7 +213,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
private final static Float ProtocolVersion = new Float(3.0f);
|
||||
private final static String SecurityVersion = new String("none,simple,sasl");
|
||||
private final static Float MajorVersion = new Float(3.0f);
|
||||
private final static Float MinorVersion = new Float(0.04f);
|
||||
private final static Float MinorVersion = new Float(0.05f);
|
||||
private final static String DELIM = "#";
|
||||
private final static String PersistSearchPackageName =
|
||||
"netscape.ldap.controls.LDAPPersistSearchControl";
|
||||
|
@ -526,7 +527,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
* @exception LDAPException The connection failed.
|
||||
*/
|
||||
public void connect(String host, int port) throws LDAPException {
|
||||
connect( host, port, null, null, false );
|
||||
connect( host, port, null, null, defaultConstraints, false );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -588,11 +589,44 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
*/
|
||||
public void connect(String host, int port, String dn, String passwd)
|
||||
throws LDAPException {
|
||||
connect(host, port, dn, passwd, true);
|
||||
connect(host, port, dn, passwd, defaultConstraints, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the specified host and port and uses the specified DN and
|
||||
* password to authenticate to the server. If this LDAPConnection object
|
||||
* represents an open connection, the connection is closed first
|
||||
* before the new connection is opened. This method allows the user to
|
||||
* specify the preferences for the bind operation.
|
||||
*
|
||||
* @param host Host name of the LDAP server that you want to connect to.
|
||||
* This value can also be a space-delimited list of hostnames or
|
||||
* hostnames and port numbers (using the syntax
|
||||
* <I>hostname:portnumber</I>). Your client application or applet
|
||||
* will attempt to contact each host in the order you specify until a
|
||||
* connection is established. For example, you can specify the following
|
||||
* values for the <CODE>host</CODE> argument:<BR>
|
||||
*<PRE>
|
||||
* myhost
|
||||
* myhost hishost:389 herhost:5000 whathost
|
||||
* myhost:686 myhost:389 hishost:5000 whathost:1024
|
||||
*</PRE>
|
||||
* @param port Port number of the LDAP server that you want to connect to.
|
||||
* This parameter is ignored for any host in the <CODE>host</CODE>
|
||||
* parameter which includes a colon and port number.
|
||||
* @param dn Distinguished name used for authentication
|
||||
* @param passwd Password used for authentication
|
||||
* @param cons Preferences for the bind operation.
|
||||
* @exception LDAPException The connection or authentication failed.
|
||||
*/
|
||||
public void connect(String host, int port, String dn, String passwd,
|
||||
LDAPSearchConstraints cons) throws LDAPException {
|
||||
connect(host, port, dn, passwd, cons, true);
|
||||
}
|
||||
|
||||
private void connect(String host, int port, String dn, String passwd,
|
||||
boolean doAuthenticate) throws LDAPException {
|
||||
LDAPSearchConstraints cons, boolean doAuthenticate)
|
||||
throws LDAPException {
|
||||
if (th != null) disconnect ();
|
||||
if ((host == null) || (host.equals("")))
|
||||
throw new LDAPException ( "no host for connection",
|
||||
|
@ -639,7 +673,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
}
|
||||
|
||||
if (doAuthenticate)
|
||||
authenticate(dn, passwd);
|
||||
authenticate(dn, passwd, cons);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -680,8 +714,51 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
public void connect(int version, String host, int port, String dn,
|
||||
String passwd) throws LDAPException {
|
||||
|
||||
connect(version, host, port, dn, passwd, defaultConstraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the specified host and port and uses the specified DN and
|
||||
* password to authenticate to the server, with the specified LDAP
|
||||
* protocol version. If the server does not support the requested
|
||||
* protocol version, an exception is thrown. This method allows the user
|
||||
* to specify preferences for the bind operation. If this LDAPConnection
|
||||
* object represents an open connection, the connection is closed first
|
||||
* before the new connection is opened. This is equivalent to
|
||||
* <CODE>connect(host, port)</CODE> followed by <CODE>authenticate(version, dn, passwd)</CODE>.<P>
|
||||
*
|
||||
* @param version LDAP protocol version requested: currently 2 or 3
|
||||
* @param host Contains a hostname or dotted string representing
|
||||
* the IP address of a host running an LDAP server to connect to.
|
||||
* Alternatively, it may contain a list of host names, space-delimited.
|
||||
* Each host name may include a trailing colon and port number. In the
|
||||
* case where more than one host name is specified, each host name in
|
||||
* turn will be contacted until a connection can be established.<P>
|
||||
*
|
||||
* <PRE>
|
||||
* Examples:
|
||||
* "directory.knowledge.com"
|
||||
* "199.254.1.2"
|
||||
* "directory.knowledge.com:1050 people.catalog.com 199.254.1.2"
|
||||
* </PRE>
|
||||
* <P>
|
||||
* @param port Contains the TCP or UDP port number to connect to or contact.
|
||||
* The default LDAP port is 389. "port" is ignored for any host name which
|
||||
* includes a colon and port number.
|
||||
* @param dn If non-null and non-empty, specifies that the connection and
|
||||
* all operations through it should be authenticated with dn as the
|
||||
* distinguished name.
|
||||
* @param passwd If non-null and non-empty, specifies that the connection and
|
||||
* all operations through it should be authenticated with dn as the
|
||||
* distinguished name and passwd as password.
|
||||
* @param cons Preferences for the bind operation.
|
||||
* @exception LDAPException The connection or authentication failed.
|
||||
*/
|
||||
public void connect(int version, String host, int port, String dn,
|
||||
String passwd, LDAPSearchConstraints cons) throws LDAPException {
|
||||
|
||||
setProtocolVersion(version);
|
||||
connect(host, port, dn, passwd);
|
||||
connect(host, port, dn, passwd, cons);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -728,6 +805,8 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
// to the new thread
|
||||
try {
|
||||
newThread = new LDAPConnThread(host, port, factory, cache);
|
||||
newThread.setMaxBacklog(
|
||||
getSearchConstraints().getMaxBacklog() );
|
||||
v = (Vector)m_threadConnTable.remove(connThread);
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
|
@ -747,6 +826,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
if (!connExist) {
|
||||
try {
|
||||
newThread = new LDAPConnThread(host, port, factory, cache);
|
||||
newThread.setMaxBacklog( getSearchConstraints().getMaxBacklog() );
|
||||
v = new Vector();
|
||||
v.addElement(this);
|
||||
} catch (Exception e) {
|
||||
|
@ -844,7 +924,25 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
* @exception LDAPException Failed to authenticate to the LDAP server.
|
||||
*/
|
||||
public void authenticate(String dn, String passwd) throws LDAPException {
|
||||
authenticate(protocolVersion, dn, passwd);
|
||||
authenticate(protocolVersion, dn, passwd, defaultConstraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticates to the LDAP server (that you are currently
|
||||
* connected to) using the specified name and password. The
|
||||
* default protocol version (version 2) is used. If the server
|
||||
* doesn't support the default version, an LDAPException is thrown
|
||||
* with the error code PROTOCOL_ERROR. This method allows the
|
||||
* user to specify the preferences for the bind operation.
|
||||
*
|
||||
* @param dn Distinguished name used for authentication.
|
||||
* @param passwd Password used for authentication.
|
||||
* @param cons Preferences for the bind operation.
|
||||
* @exception LDAPException Failed to authenticate to the LDAP server.
|
||||
*/
|
||||
public void authenticate(String dn, String passwd,
|
||||
LDAPSearchConstraints cons) throws LDAPException {
|
||||
authenticate(protocolVersion, dn, passwd, cons);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -861,7 +959,27 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
* @exception LDAPException Failed to authenticate to the LDAP server.
|
||||
*/
|
||||
public void authenticate(int version, String dn, String passwd)
|
||||
throws LDAPException {
|
||||
throws LDAPException {
|
||||
authenticate(version, dn, passwd, defaultConstraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticates to the LDAP server (that you are currently
|
||||
* connected to) using the specified name and password, and
|
||||
* requesting that the server use at least the specified
|
||||
* protocol version. If the server doesn't support that
|
||||
* level, an LDAPException is thrown with the error code
|
||||
* PROTOCOL_ERROR. This method allows the user to specify the
|
||||
* preferences for the bind operation.
|
||||
*
|
||||
* @param version Required LDAP protocol version.
|
||||
* @param dn Distinguished name used for authentication.
|
||||
* @param passwd Password used for authentication.
|
||||
* @param cons Preferences for the bind operation.
|
||||
* @exception LDAPException Failed to authenticate to the LDAP server.
|
||||
*/
|
||||
public void authenticate(int version, String dn, String passwd,
|
||||
LDAPSearchConstraints cons) throws LDAPException {
|
||||
prevBoundDN = boundDN;
|
||||
prevBoundPasswd = boundPasswd;
|
||||
boundDN = dn;
|
||||
|
@ -872,7 +990,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
else
|
||||
m_anonymousBound = false;
|
||||
|
||||
bind (version, true);
|
||||
bind (version, true, cons);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1147,7 +1265,8 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
* @param rebind True if the rebind operation is requested, otherwise, false.
|
||||
* @exception LDAPException failed to bind
|
||||
*/
|
||||
private void bind (int version, boolean rebind) throws LDAPException {
|
||||
private void bind (int version, boolean rebind,
|
||||
LDAPSearchConstraints cons) throws LDAPException {
|
||||
saslBind = false;
|
||||
|
||||
if (th == null) {
|
||||
|
@ -1202,10 +1321,16 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
LDAPResponseListener myListener = getResponseListener ();
|
||||
JDAPMessage response;
|
||||
try {
|
||||
if (m_referralConnection != null) {
|
||||
m_referralConnection.disconnect();
|
||||
m_referralConnection = null;
|
||||
}
|
||||
sendRequest(new JDAPBindRequest(protocolVersion, boundDN, boundPasswd),
|
||||
myListener, defaultConstraints);
|
||||
myListener, cons);
|
||||
response = myListener.getResponse();
|
||||
checkMsg(response);
|
||||
} catch (LDAPReferralException e) {
|
||||
m_referralConnection = createReferralConnection(e, cons);
|
||||
} finally {
|
||||
releaseResponseListener(myListener);
|
||||
}
|
||||
|
@ -1251,11 +1376,11 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
* Internal routine. Binds to the LDAP server.
|
||||
* @exception LDAPException failed to bind
|
||||
*/
|
||||
private void bind () throws LDAPException {
|
||||
private void bind (LDAPSearchConstraints cons) throws LDAPException {
|
||||
if (saslBind)
|
||||
saslBind(false);
|
||||
else
|
||||
bind (protocolVersion, false);
|
||||
bind (protocolVersion, false, cons);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1267,6 +1392,11 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
* @see netscape.ldap.LDAPConnection#connect(java.lang.String, int, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public synchronized void disconnect() throws LDAPException {
|
||||
if (m_referralConnection != null) {
|
||||
m_referralConnection.disconnect();
|
||||
m_referralConnection = null;
|
||||
}
|
||||
|
||||
if (th == null)
|
||||
throw new LDAPException ( "unable to disconnect() without connecting",
|
||||
LDAPException.OTHER );
|
||||
|
@ -1857,9 +1987,9 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
printDebug("Exception: "+e);
|
||||
}
|
||||
|
||||
bind();
|
||||
bind(cons);
|
||||
|
||||
LDAPSearchListener myListener = getSearchListener ();
|
||||
LDAPSearchListener myListener = getSearchListener ( cons );
|
||||
int deref = cons.getDereference();
|
||||
|
||||
JDAPSearchRequest request = new JDAPSearchRequest (base,
|
||||
|
@ -1891,8 +2021,20 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
JDAPMessage response = myListener.getResponse ();
|
||||
Enumeration results = myListener.getSearchResults ();
|
||||
|
||||
checkSearchMsg(returnValue, response, cons, base, scope, filter,
|
||||
attrs, attrsOnly);
|
||||
try {
|
||||
checkSearchMsg(returnValue, response, cons, base, scope,
|
||||
filter, attrs, attrsOnly);
|
||||
} catch ( LDAPException ex ) {
|
||||
/* Was the exception caused by a bad referral? */
|
||||
JDAPProtocolOp op = response.getProtocolOp();
|
||||
if ( (op instanceof JDAPSearchResultReference) ||
|
||||
(op instanceof JDAPSearchResult) ){
|
||||
System.err.println( "LDAPConnection.checkSearchMsg: " +
|
||||
"ignoring bad referral" );
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
while (results.hasMoreElements ()) {
|
||||
JDAPMessage msg = (JDAPMessage)results.nextElement();
|
||||
|
@ -1921,8 +2063,22 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
releaseSearchListener (myListener);
|
||||
}
|
||||
} else {
|
||||
checkSearchMsg(returnValue, firstResult, cons, base,
|
||||
scope, filter, attrs, attrsOnly);
|
||||
/* First result could be a bad referral, ultimately causing
|
||||
a NO_SUCH_OBJECT exception. Don't want to miss all
|
||||
following results, so skip it. */
|
||||
try {
|
||||
checkSearchMsg(returnValue, firstResult, cons, base,
|
||||
scope, filter, attrs, attrsOnly);
|
||||
} catch ( LDAPException ex ) {
|
||||
/* Was the exception caused by a bad referral? */
|
||||
if (firstResult.getProtocolOp() instanceof
|
||||
JDAPSearchResultReference) {
|
||||
System.err.println( "LDAPConnection.checkSearchMsg: " +
|
||||
"ignoring bad referral" );
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
LDAPControl[] controls = (LDAPControl[])getOption(LDAPv3.SERVERCONTROLS, cons);
|
||||
|
||||
|
@ -2015,7 +2171,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
|
||||
public boolean compare( String DN, LDAPAttribute attr,
|
||||
LDAPSearchConstraints cons) throws LDAPException {
|
||||
bind();
|
||||
bind(cons);
|
||||
|
||||
LDAPResponseListener myListener = getResponseListener ();
|
||||
Enumeration en = attr.getByteValues();
|
||||
|
@ -2043,10 +2199,9 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
checkMsg (response);
|
||||
|
||||
} catch (LDAPReferralException e) {
|
||||
//boolean res[] = new boolean[1];
|
||||
Vector res = new Vector();
|
||||
performReferrals(e, cons, JDAPProtocolOp.COMPARE_REQUEST,
|
||||
DN, 0, null, null, false, null, null, attr, res);
|
||||
DN, 0, null, null, false, null, null, attr, res);
|
||||
boolean bool = false;
|
||||
if (res.size() > 0)
|
||||
bool = ((Boolean)res.elementAt(0)).booleanValue();
|
||||
|
@ -2134,7 +2289,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
*/
|
||||
public void add( LDAPEntry entry, LDAPSearchConstraints cons )
|
||||
throws LDAPException {
|
||||
bind ();
|
||||
bind (cons);
|
||||
|
||||
LDAPResponseListener myListener = getResponseListener ();
|
||||
LDAPAttributeSet attrs = entry.getAttributeSet ();
|
||||
|
@ -2173,13 +2328,36 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
*/
|
||||
public LDAPExtendedOperation extendedOperation( LDAPExtendedOperation op )
|
||||
throws LDAPException {
|
||||
bind ();
|
||||
|
||||
return extendedOperation(op, defaultConstraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an extended operation on the directory. Extended operations
|
||||
* are part of version 3 of the LDAP protocol. This method allows the
|
||||
* user to set the preferences for the operation.<P>
|
||||
*
|
||||
* Note that in order for the extended operation to work, the server
|
||||
* that you are connecting to must support LDAP v3 and must be configured
|
||||
* to process the specified extended operation.
|
||||
*
|
||||
* @param op LDAPExtendedOperation object specifying the OID of the
|
||||
* extended operation and the data to be used in the operation.
|
||||
* @param cons Preferences for the extended operation.
|
||||
* @exception LDAPException Failed to execute the operation
|
||||
* @return LDAPExtendedOperation object representing the extended response
|
||||
* returned by the server.
|
||||
* @see netscape.ldap.LDAPExtendedOperation
|
||||
*/
|
||||
public LDAPExtendedOperation extendedOperation( LDAPExtendedOperation op,
|
||||
LDAPSearchConstraints cons) throws LDAPException {
|
||||
bind (cons);
|
||||
|
||||
LDAPResponseListener myListener = getResponseListener ();
|
||||
JDAPMessage response = null;
|
||||
byte[] results = null;
|
||||
String resultID;
|
||||
LDAPSearchConstraints cons = defaultConstraints;
|
||||
|
||||
try {
|
||||
sendRequest ( new JDAPExtendedRequest( op.getID(), op.getValue() ),
|
||||
myListener, cons );
|
||||
|
@ -2361,9 +2539,9 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
* @see netscape.ldap.LDAPModification
|
||||
* @see netscape.ldap.LDAPSearchConstraints
|
||||
*/
|
||||
public void modify (String DN, LDAPModification[] mods,
|
||||
public void modify (String DN, LDAPModification[] mods,
|
||||
LDAPSearchConstraints cons) throws LDAPException {
|
||||
bind ();
|
||||
bind (cons);
|
||||
|
||||
LDAPResponseListener myListener = getResponseListener ();
|
||||
JDAPMessage response = null;
|
||||
|
@ -2373,11 +2551,11 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
checkMsg (response);
|
||||
} catch (LDAPReferralException e) {
|
||||
performReferrals(e, cons, JDAPProtocolOp.MODIFY_REQUEST,
|
||||
DN, 0, null, null, false, mods, null, null, null);
|
||||
DN, 0, null, null, false, mods, null, null, null);
|
||||
} finally {
|
||||
releaseResponseListener (myListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the entry for the specified DN from the directory. <P>
|
||||
|
@ -2417,7 +2595,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
*/
|
||||
public void delete( String DN, LDAPSearchConstraints cons )
|
||||
throws LDAPException {
|
||||
bind ();
|
||||
bind (cons);
|
||||
|
||||
LDAPResponseListener myListener = getResponseListener ();
|
||||
JDAPMessage response;
|
||||
|
@ -2577,7 +2755,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
boolean deleteOldRDN,
|
||||
LDAPSearchConstraints cons)
|
||||
throws LDAPException {
|
||||
bind ();
|
||||
bind (cons);
|
||||
|
||||
LDAPResponseListener myListener = getResponseListener ();
|
||||
JDAPMessage response;
|
||||
|
@ -2735,6 +2913,12 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
* server on each LDAP operation. Not all servers support server
|
||||
* controls; a particular server may or may not support a given
|
||||
* server control.</TD></TR>
|
||||
* <TR VALIGN=BASELINE><TD>
|
||||
* <CODE>MAXBACKLOG</CODE></TD>
|
||||
* <TD><CODE>Integer</CODE></TD>
|
||||
* <TD>Specifies the maximum number of search results to accumulate in an
|
||||
* LDAPSearchResults before suspending the reading of input from the server.
|
||||
* <P>By default, the value of this option is 100.</TD></TR>
|
||||
* </TABLE><P>
|
||||
* @return The value for the option wrapped in an object. (You
|
||||
* need to cast the returned value as its appropriate type. For
|
||||
|
@ -2777,6 +2961,8 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
return cons.getClientControls();
|
||||
case LDAPv3.SERVERCONTROLS:
|
||||
return cons.getServerControls();
|
||||
case MAXBACKLOG:
|
||||
return new Integer (cons.getMaxBacklog());
|
||||
default:
|
||||
throw new LDAPException ( "invalid option",
|
||||
LDAPException.PARAM_ERROR );
|
||||
|
@ -2908,6 +3094,12 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
* server on each LDAP operation. Not all servers support server
|
||||
* controls; a particular server may or may not support a particular
|
||||
* control.</TD></TR>
|
||||
* <TR VALIGN=BASELINE><TD>
|
||||
* <CODE>MAXBACKLOG</CODE></TD>
|
||||
* <TD><CODE>Integer</CODE></TD>
|
||||
* <TD>Specifies the maximum number of search results to accumulate in an
|
||||
* LDAPSearchResults before suspending the reading of input from the server.
|
||||
* <P>By default, the value of this option is 100.</TD></TR>
|
||||
* </TABLE><P>
|
||||
* @param value The value to assign to the option. The value must be
|
||||
* the java.lang object wrapper for the appropriate parameter
|
||||
|
@ -2975,6 +3167,15 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
throw new LDAPException ( "invalid LDAPControl",
|
||||
LDAPException.PARAM_ERROR );
|
||||
return;
|
||||
case MAXBACKLOG:
|
||||
int val = ((Integer)value).intValue();
|
||||
if ( val < 1 ) {
|
||||
throw new LDAPException ( "MAXBACKLOG must be at least 1",
|
||||
LDAPException.PARAM_ERROR );
|
||||
} else {
|
||||
cons.setMaxBacklog(((Integer)value).intValue());
|
||||
}
|
||||
return;
|
||||
default:
|
||||
throw new LDAPException ("invalid option",
|
||||
LDAPException.PARAM_ERROR );
|
||||
|
@ -2993,18 +3194,27 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
*/
|
||||
public LDAPControl[] getResponseControls() {
|
||||
LDAPControl[] controls = null;
|
||||
LDAPControl[] con;
|
||||
|
||||
/* Get the latest controls returned for our thread */
|
||||
synchronized(m_responseControlTable) {
|
||||
con = (LDAPControl[])m_responseControlTable.get(
|
||||
Thread.currentThread() );
|
||||
}
|
||||
/* If there are any, return copies of them */
|
||||
if ( (con != null) && (con.length > 0) ) {
|
||||
controls = new LDAPControl[con.length];
|
||||
for( int i = 0; i < con.length; i++ )
|
||||
controls[i] = (LDAPControl)con[i].clone();
|
||||
Vector responses = (Vector)m_responseControlTable.get(th);
|
||||
|
||||
if (responses != null) {
|
||||
// iterate through each response control
|
||||
for (int i=0,size=responses.size(); i<size; i++) {
|
||||
ResponseControl responseObj =
|
||||
(ResponseControl)responses.elementAt(i);
|
||||
|
||||
// check if the response belongs to this connection
|
||||
if (responseObj.getConnection().equals(this)) {
|
||||
controls = responseObj.getControls();
|
||||
responses.removeElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return controls;
|
||||
}
|
||||
|
||||
|
@ -3079,10 +3289,6 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
l = (LDAPResponseListener)responseListeners.elementAt (0);
|
||||
responseListeners.removeElementAt (0);
|
||||
}
|
||||
/* The agent must record the current thread in order to be able to
|
||||
distinguish between server response controls destined for
|
||||
different threads */
|
||||
l.setThread();
|
||||
return l;
|
||||
}
|
||||
|
||||
|
@ -3092,7 +3298,8 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
* synchronous.
|
||||
* @return A search response listener object
|
||||
*/
|
||||
private synchronized LDAPSearchListener getSearchListener ()
|
||||
private synchronized LDAPSearchListener getSearchListener (
|
||||
LDAPSearchConstraints cons )
|
||||
{
|
||||
if (searchListeners == null) {
|
||||
searchListeners = new Vector (5);
|
||||
|
@ -3100,16 +3307,12 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
|
||||
LDAPSearchListener l;
|
||||
if ( searchListeners.size() < 1 ) {
|
||||
l = new LDAPSearchListener ( this );
|
||||
l = new LDAPSearchListener ( this, cons );
|
||||
}
|
||||
else {
|
||||
l = (LDAPSearchListener)searchListeners.elementAt (0);
|
||||
searchListeners.removeElementAt (0);
|
||||
}
|
||||
/* The agent must record the current thread in order to be able to
|
||||
distinguish between server response controls destined for
|
||||
different threads */
|
||||
l.setThread();
|
||||
return l;
|
||||
}
|
||||
|
||||
|
@ -3180,23 +3383,63 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stash away server response controls for a particular thread.
|
||||
* Set response controls for the current connection for a particular
|
||||
* thread. Get the oldest returned controls and remove them from the
|
||||
* queue. If the connection is executing a persistent search, there may
|
||||
* be more than one set of controls in the queue. For any other
|
||||
* operation, there will only ever be at most one set of controls
|
||||
* (controls from any earlier operation are replaced by controls
|
||||
* received on the latest operation on this connection by this thread).
|
||||
* @param current The target thread.
|
||||
* @param con The server response controls.
|
||||
*/
|
||||
void setResponseControls( Thread current, LDAPControl[] con ) {
|
||||
void setResponseControls( LDAPConnThread current, ResponseControl con ) {
|
||||
synchronized(m_responseControlTable) {
|
||||
if ( con != null )
|
||||
m_responseControlTable.put( current, con );
|
||||
else
|
||||
m_responseControlTable.remove( current );
|
||||
Vector v = (Vector)m_responseControlTable.get(current);
|
||||
|
||||
// if the current thread already contains response controls from
|
||||
// a previous operation
|
||||
if ((v != null) && (v.size() > 0)) {
|
||||
|
||||
// look at each response control
|
||||
for (int i=v.size()-1; i>=0; i--) {
|
||||
ResponseControl response =
|
||||
(ResponseControl)v.elementAt(i);
|
||||
|
||||
// if this response control belongs to this connection
|
||||
if (response.getConnection().equals(this)) {
|
||||
|
||||
// if the given control is null or
|
||||
// the given control is not null and the current
|
||||
// control does not correspond to the new JDAPMessage
|
||||
if ((con == null) ||
|
||||
(con.getMsgID() != response.getMsgID()))
|
||||
v.removeElement(response);
|
||||
|
||||
// For the same connection, if the message id from the
|
||||
// given control is the same as the one in the queue,
|
||||
// those controls in the queue will not get removed
|
||||
// since they come from the persistent search control
|
||||
// which allows more than one control response for
|
||||
// one persistent search operation.
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (con != null)
|
||||
v = new Vector();
|
||||
}
|
||||
|
||||
if (con != null) {
|
||||
v.addElement(con);
|
||||
m_responseControlTable.put(current, v);
|
||||
}
|
||||
|
||||
/* Do some garbage collection: check if any attached threads have
|
||||
exited */
|
||||
/* Now check all threads in the list */
|
||||
Enumeration e = m_attachedList.elements();
|
||||
while( e.hasMoreElements() ) {
|
||||
Thread aThread = (Thread)e.nextElement();
|
||||
LDAPConnThread aThread = (LDAPConnThread)e.nextElement();
|
||||
if ( !aThread.isAlive() ) {
|
||||
m_responseControlTable.remove( aThread );
|
||||
m_attachedList.removeElement( aThread );
|
||||
|
@ -3229,14 +3472,39 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
connection.setOption(REFERRALS_HOP_LIMIT,
|
||||
new Integer(cons.getHopLimit()-1));
|
||||
connection.connect (u.getHost(), u.getPort());
|
||||
if (cons.getRebindProc() == null) {
|
||||
connection.authenticate (null, null);
|
||||
} else {
|
||||
LDAPRebindAuth auth = cons.getRebindProc().getRebindAuthentication(
|
||||
u.getHost(),
|
||||
u.getPort());
|
||||
connection.authenticate (auth.getDN(), auth.getPassword());
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish the LDAPConnection to the referred server. This one is used
|
||||
* for bind operation only since we need to keep this new connection for
|
||||
* the subsequent operations. This new connection will be destroyed in
|
||||
* two circumstances: disconnect gets called or the client binds as
|
||||
* someone else.
|
||||
* @return The new LDAPConnection to the referred server
|
||||
*/
|
||||
LDAPConnection createReferralConnection(LDAPReferralException e,
|
||||
LDAPSearchConstraints cons) throws LDAPException {
|
||||
if (cons.getHopLimit() <= 0)
|
||||
throw new LDAPException("exceed hop limit",
|
||||
e.getLDAPResultCode(), e.getLDAPErrorMessage());
|
||||
if (!cons.getReferrals()) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
LDAPUrl u[] = e.getURLs();
|
||||
// If there are no referrals (because the server isn't set up for
|
||||
// them), give up here
|
||||
if ((u == null) || (u.length <= 0) || (u[0].equals("")))
|
||||
throw new LDAPException("No target URL in referral",
|
||||
LDAPException.NO_RESULTS_RETURNED);
|
||||
|
||||
LDAPConnection connection = null;
|
||||
connection = prepareReferral(u[0], cons);
|
||||
String DN = u[0].getDN();
|
||||
if ((DN == null) || (DN.equals("")))
|
||||
DN = boundDN;
|
||||
connection.authenticate(protocolVersion, DN, boundPasswd);
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
@ -3275,60 +3543,101 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
return;
|
||||
|
||||
for (int i = 0; i < u.length; i++) {
|
||||
LDAPConnection connection = null;
|
||||
String newDN = u[i].getDN();
|
||||
String DN = null;
|
||||
if ((newDN == null) || (newDN.equals("")))
|
||||
DN = dn;
|
||||
else
|
||||
DN = newDN;
|
||||
|
||||
LDAPSearchResults res = null;
|
||||
LDAPSearchConstraints newcons = (LDAPSearchConstraints)cons.clone();
|
||||
newcons.setHopLimit( cons.getHopLimit()-1 );
|
||||
|
||||
try {
|
||||
connection = prepareReferral( u[i], cons );
|
||||
String newDN = u[i].getDN();
|
||||
String DN = null;
|
||||
if (newDN != null)
|
||||
DN = newDN;
|
||||
else
|
||||
DN = dn;
|
||||
|
||||
LDAPSearchConstraints newcons = (LDAPSearchConstraints)cons.clone();
|
||||
newcons.setHopLimit( cons.getHopLimit()-1 );
|
||||
|
||||
switch (ops) {
|
||||
case JDAPProtocolOp.SEARCH_REQUEST:
|
||||
|
||||
res = connection.search(DN, scope, filter,
|
||||
types, attrsOnly, newcons);
|
||||
if (res != null) {
|
||||
res.closeOnCompletion(connection);
|
||||
results.addElement(res);
|
||||
} else {
|
||||
connection.disconnect();
|
||||
}
|
||||
break;
|
||||
case JDAPProtocolOp.MODIFY_REQUEST:
|
||||
connection.modify(DN, mods, newcons);
|
||||
break;
|
||||
case JDAPProtocolOp.ADD_REQUEST:
|
||||
connection.add(entry, newcons);
|
||||
break;
|
||||
case JDAPProtocolOp.DEL_REQUEST:
|
||||
connection.delete(DN, newcons);
|
||||
break;
|
||||
case JDAPProtocolOp.MODIFY_RDN_REQUEST:
|
||||
connection.rename(DN, filter /* newRDN */, attrsOnly /* deleteOld */,
|
||||
newcons);
|
||||
break;
|
||||
case JDAPProtocolOp.COMPARE_REQUEST:
|
||||
boolean bool = connection.compare(DN, attr, newcons);
|
||||
results.addElement(new Boolean(bool));
|
||||
break;
|
||||
default:
|
||||
/* impossible */
|
||||
break;
|
||||
if ((m_referralConnection != null) &&
|
||||
(u[i].getHost().equals(m_referralConnection.host)) &&
|
||||
(u[i].getPort() == m_referralConnection.port)) {
|
||||
performReferrals(m_referralConnection, newcons, ops, DN,
|
||||
scope, filter, types, attrsOnly, mods, entry, attr,
|
||||
results);
|
||||
continue;
|
||||
}
|
||||
} catch (LDAPException le) {
|
||||
if (le.getLDAPResultCode() !=
|
||||
LDAPException.INSUFFICIENT_ACCESS_RIGHTS) {
|
||||
throw le;
|
||||
}
|
||||
} catch (LDAPException ee) {
|
||||
throw ee;
|
||||
} finally {
|
||||
if ((connection != null) && ((ops != JDAPProtocolOp.SEARCH_REQUEST) ||
|
||||
(res == null)))
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
LDAPConnection connection = null;
|
||||
connection = prepareReferral( u[i], cons );
|
||||
if (cons.getRebindProc() == null) {
|
||||
connection.authenticate (null, null);
|
||||
} else {
|
||||
LDAPRebindAuth auth =
|
||||
cons.getRebindProc().getRebindAuthentication(u[i].getHost(),
|
||||
u[i].getPort());
|
||||
connection.authenticate(auth.getDN(), auth.getPassword());
|
||||
}
|
||||
performReferrals(connection, newcons, ops, DN, scope, filter,
|
||||
types, attrsOnly, mods, entry, attr, results);
|
||||
}
|
||||
}
|
||||
|
||||
void performReferrals(LDAPConnection connection,
|
||||
LDAPSearchConstraints cons, int ops, String dn, int scope,
|
||||
String filter, String types[], boolean attrsOnly,
|
||||
LDAPModification mods[], LDAPEntry entry, LDAPAttribute attr,
|
||||
Vector results) throws LDAPException {
|
||||
|
||||
LDAPSearchResults res = null;
|
||||
try {
|
||||
switch (ops) {
|
||||
case JDAPProtocolOp.SEARCH_REQUEST:
|
||||
|
||||
res = connection.search(dn, scope, filter,
|
||||
types, attrsOnly, cons);
|
||||
if (res != null) {
|
||||
res.closeOnCompletion(connection);
|
||||
results.addElement(res);
|
||||
} else {
|
||||
if ((m_referralConnection == null) ||
|
||||
(!connection.equals(m_referralConnection)))
|
||||
connection.disconnect();
|
||||
}
|
||||
break;
|
||||
case JDAPProtocolOp.MODIFY_REQUEST:
|
||||
connection.modify(dn, mods, cons);
|
||||
break;
|
||||
case JDAPProtocolOp.ADD_REQUEST:
|
||||
if ((dn != null) && (!dn.equals("")))
|
||||
entry.setDN(dn);
|
||||
connection.add(entry, cons);
|
||||
break;
|
||||
case JDAPProtocolOp.DEL_REQUEST:
|
||||
connection.delete(dn, cons);
|
||||
break;
|
||||
case JDAPProtocolOp.MODIFY_RDN_REQUEST:
|
||||
connection.rename(dn, filter /* newRDN */,
|
||||
attrsOnly /* deleteOld */, cons);
|
||||
break;
|
||||
case JDAPProtocolOp.COMPARE_REQUEST:
|
||||
boolean bool = connection.compare(dn, attr, cons);
|
||||
results.addElement(new Boolean(bool));
|
||||
break;
|
||||
default:
|
||||
/* impossible */
|
||||
break;
|
||||
}
|
||||
} catch (LDAPException ee) {
|
||||
throw ee;
|
||||
} finally {
|
||||
if ((connection != null) &&
|
||||
((ops != JDAPProtocolOp.SEARCH_REQUEST) || (res == null)) &&
|
||||
((m_referralConnection == null) ||
|
||||
(!connection.equals(m_referralConnection))))
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3386,7 +3695,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
LDAPConnection c = (LDAPConnection)super.clone();
|
||||
|
||||
if (this.th == null)
|
||||
this.bind();
|
||||
this.bind(defaultConstraints);
|
||||
|
||||
c.defaultConstraints =
|
||||
(LDAPSearchConstraints)defaultConstraints.clone();
|
||||
|
@ -3421,6 +3730,17 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when a search result has been retrieved from the incoming
|
||||
* queue. We use the notification to unblock the listener thread, if it
|
||||
* is waiting for the backlog to lighten.
|
||||
*/
|
||||
void resultRetrieved() {
|
||||
if ( th != null ) {
|
||||
th.resultRetrieved();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up basic connection privileges for Communicator.
|
||||
* @return true if in Communicator and connections okay.
|
||||
|
@ -3474,10 +3794,50 @@ public class LDAPConnection implements LDAPv3, Cloneable {
|
|||
System.out.println("LDAP Protocol Version is "+ProtocolVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Option specifying the maximum number of unread entries to be cached in any
|
||||
* LDAPSearchResults without suspending reading from the server.
|
||||
* @see netscape.ldap.LDAPConnection#getOption
|
||||
* @see netscape.ldap.LDAPConnection#setOption
|
||||
*/
|
||||
public static final int MAXBACKLOG = 30;
|
||||
|
||||
private static boolean isCommunicator = checkCommunicator();
|
||||
private static final boolean debug = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This object represents the value of the m_responseControlTable hashtable.
|
||||
* It stores the response controls and its corresponding LDAPConnection and
|
||||
* the message ID for its corresponding JDAPMessage.
|
||||
*/
|
||||
class ResponseControl {
|
||||
private LDAPConnection m_connection;
|
||||
private int m_messageID;
|
||||
private LDAPControl[] m_controls;
|
||||
|
||||
public ResponseControl(LDAPConnection conn, int msgID,
|
||||
LDAPControl[] controls) {
|
||||
|
||||
m_connection = conn;
|
||||
m_messageID = msgID;
|
||||
m_controls = new LDAPControl[controls.length];
|
||||
for (int i=0; i<controls.length; i++)
|
||||
m_controls[i] = controls[i];
|
||||
}
|
||||
|
||||
public int getMsgID() {
|
||||
return m_messageID;
|
||||
}
|
||||
|
||||
public LDAPControl[] getControls() {
|
||||
return m_controls;
|
||||
}
|
||||
|
||||
public LDAPConnection getConnection() {
|
||||
return m_connection;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiple LDAPConnection clones can share a single physical connection,
|
||||
|
@ -3521,6 +3881,7 @@ class LDAPConnThread extends Thread {
|
|||
transient private boolean m_failed = false;
|
||||
private Object m_securityLayer = null;
|
||||
private Socket m_socket = null;
|
||||
private int m_maxBacklog = 100;
|
||||
|
||||
/**
|
||||
* Constructs a connection thread that maintains connection to the
|
||||
|
@ -3695,6 +4056,64 @@ class LDAPConnThread extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set and get the maximum number of unread entries any search listener can
|
||||
* have before we stop reading from the server.
|
||||
*/
|
||||
void setMaxBacklog( int backlog ) {
|
||||
m_maxBacklog = backlog;
|
||||
}
|
||||
|
||||
int getMaxBacklog() {
|
||||
return m_maxBacklog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sleep if there is a backlog of search results
|
||||
*/
|
||||
private void checkBacklog() {
|
||||
boolean doWait;
|
||||
do {
|
||||
doWait = false;
|
||||
Enumeration listeners = m_requests.elements();
|
||||
while( listeners.hasMoreElements() ) {
|
||||
LDAPResponseListener l =
|
||||
(LDAPResponseListener)listeners.nextElement();
|
||||
// If there are any threads waiting for a regular response
|
||||
// message, we have to go read the next incoming message
|
||||
if ( !(l instanceof LDAPSearchListener) ) {
|
||||
break;
|
||||
}
|
||||
// If the backlog of any search thread is too great,
|
||||
// wait for it to diminish, but if this is a synchronous
|
||||
// search, then just keep reading
|
||||
LDAPSearchListener sl = (LDAPSearchListener)l;
|
||||
if ( (sl.getConstraints().getBatchSize() != 0) &&
|
||||
(sl.getCount() >= m_maxBacklog) ) {
|
||||
doWait = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( doWait ) {
|
||||
synchronized(this) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ( doWait );
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when a search result has been retrieved from the incoming
|
||||
* queue. We use the notification to unblock the listener thread, if it
|
||||
* is waiting for the backlog to lighten.
|
||||
*/
|
||||
synchronized void resultRetrieved() {
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads from the LDAP server input stream for incoming LDAP messages.
|
||||
*/
|
||||
|
@ -3711,6 +4130,8 @@ class LDAPConnThread extends Thread {
|
|||
yield();
|
||||
int[] nread = new int[1];
|
||||
nread[0] = 0;
|
||||
// Avoid too great a backlog of results
|
||||
checkBacklog();
|
||||
try {
|
||||
BERElement element = BERElement.getElement(decoder, m_serverInput,
|
||||
nread);
|
||||
|
@ -3746,7 +4167,6 @@ class LDAPConnThread extends Thread {
|
|||
* @param incoming New message from LDAP server
|
||||
*/
|
||||
private synchronized void processResponse (JDAPMessage incoming, int size) {
|
||||
|
||||
Integer messageID = new Integer (incoming.getId());
|
||||
LDAPResponseListener l = (LDAPResponseListener)m_requests.get (messageID);
|
||||
|
||||
|
@ -3755,7 +4175,11 @@ class LDAPConnThread extends Thread {
|
|||
|
||||
/* Were there any controls for this client? */
|
||||
LDAPControl[] con = checkControls( incoming );
|
||||
l.getConnection().setResponseControls( l.getThread(), con );
|
||||
ResponseControl responseControl = null;
|
||||
if (con != null)
|
||||
responseControl = new ResponseControl(l.getConnection(),
|
||||
incoming.getId(), con);
|
||||
l.getConnection().setResponseControls( this, responseControl );
|
||||
|
||||
JDAPProtocolOp op = incoming.getProtocolOp ();
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ public class LDAPSearchConstraints implements Cloneable {
|
|||
private int m_hop_limit;
|
||||
private LDAPControl[] m_clientControls;
|
||||
private LDAPControl[] m_serverControls;
|
||||
transient private int m_maxBacklog = 100;
|
||||
|
||||
/**
|
||||
* Constructs an <CODE>LDAPSearchConstraints</CODE> object that specifies
|
||||
|
@ -328,6 +329,18 @@ public class LDAPSearchConstraints implements Cloneable {
|
|||
m_serverControls = controls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set and get the maximum number of unread entries any search listener can
|
||||
* have before we stop reading from the server.
|
||||
*/
|
||||
void setMaxBacklog( int backlog ) {
|
||||
m_maxBacklog = backlog;
|
||||
}
|
||||
|
||||
int getMaxBacklog() {
|
||||
return m_maxBacklog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of an existing set of search constraints.
|
||||
* @returns A copy of an existing set of search constraints.
|
||||
|
|
|
@ -35,16 +35,18 @@ import netscape.ldap.client.*;
|
|||
*/
|
||||
class LDAPSearchListener extends LDAPResponseListener {
|
||||
private Vector searchResults;
|
||||
private int lastRetrieved = -1;
|
||||
|
||||
// this instance variable is only for cache purpose
|
||||
private Long m_key = null;
|
||||
private LDAPSearchConstraints m_constraints;
|
||||
|
||||
/**
|
||||
* Constructs a LDAP search listener.
|
||||
*/
|
||||
LDAPSearchListener ( LDAPConnection conn ) {
|
||||
LDAPSearchListener ( LDAPConnection conn,
|
||||
LDAPSearchConstraints cons ) {
|
||||
super ( conn );
|
||||
m_constraints = cons;
|
||||
searchResults = new Vector ();
|
||||
}
|
||||
|
||||
|
@ -78,7 +80,6 @@ class LDAPSearchListener extends LDAPResponseListener {
|
|||
*/
|
||||
void reset () {
|
||||
super.reset();
|
||||
lastRetrieved = -1;
|
||||
if ( searchResults != null )
|
||||
searchResults.removeAllElements();
|
||||
}
|
||||
|
@ -91,26 +92,36 @@ class LDAPSearchListener extends LDAPResponseListener {
|
|||
* method returns null.
|
||||
* @return jdap message
|
||||
*/
|
||||
synchronized JDAPMessage nextResult () {
|
||||
while (lastRetrieved >= (searchResults.size()-1)) {
|
||||
if (isResponseReceived()) {
|
||||
searchResults.removeAllElements();
|
||||
return null;
|
||||
JDAPMessage nextResult () {
|
||||
JDAPMessage result;
|
||||
synchronized( this ) {
|
||||
while (searchResults.size() < 1) {
|
||||
if (isResponseReceived()) {
|
||||
searchResults.removeAllElements();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e ) {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e ) {
|
||||
}
|
||||
result = (JDAPMessage)searchResults.elementAt (0);
|
||||
/* Allow garbage collection to free this result */
|
||||
searchResults.removeElementAt (0);
|
||||
}
|
||||
|
||||
lastRetrieved++;
|
||||
JDAPMessage result = (JDAPMessage)searchResults.elementAt (lastRetrieved);
|
||||
/* Allow garbage collection to free this result */
|
||||
searchResults.setElementAt (null, lastRetrieved);
|
||||
getConnection().resultRetrieved();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the search constraints used to create this object
|
||||
* @return the search constraints used to create this object
|
||||
*/
|
||||
LDAPSearchConstraints getConstraints() {
|
||||
return m_constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the key of the cache entry. The listener needs to know this value
|
||||
* when the results get processed in the queue. After the results have been
|
||||
|
|
|
@ -39,14 +39,12 @@ import java.io.*;
|
|||
*/
|
||||
public class LDAPSearchResults implements Enumeration {
|
||||
|
||||
private int current = 0;
|
||||
private Vector entries = null;
|
||||
private LDAPSearchListener resultSource;
|
||||
private boolean searchComplete = false;
|
||||
private LDAPConnection connectionToClose;
|
||||
private LDAPConnection currConn;
|
||||
private boolean persistentSearch = false;
|
||||
private Vector cacheEntries = null;
|
||||
private LDAPSearchConstraints currCons;
|
||||
private String currBase;
|
||||
private int currScope;
|
||||
|
@ -54,7 +52,6 @@ public class LDAPSearchResults implements Enumeration {
|
|||
private String[] currAttrs;
|
||||
private boolean currAttrsOnly;
|
||||
private Vector referralResults = new Vector();
|
||||
private int totalReferralEntries = 0;
|
||||
|
||||
// only used for the persistent search
|
||||
private boolean firstResult = false;
|
||||
|
@ -68,10 +65,8 @@ public class LDAPSearchResults implements Enumeration {
|
|||
*/
|
||||
public LDAPSearchResults() {
|
||||
entries = new Vector();
|
||||
current = 0;
|
||||
connectionToClose = null;
|
||||
searchComplete = true;
|
||||
cacheEntries = null;
|
||||
}
|
||||
|
||||
LDAPSearchResults(LDAPConnection conn, LDAPSearchConstraints cons,
|
||||
|
@ -94,7 +89,14 @@ public class LDAPSearchResults implements Enumeration {
|
|||
*/
|
||||
LDAPSearchResults(Vector v) {
|
||||
this();
|
||||
cacheEntries = (Vector)v.clone();
|
||||
entries = (Vector)v.clone();
|
||||
|
||||
if ((entries != null) && (entries.size() >= 1)) {
|
||||
// Each cache value is represented by a vector. The first element
|
||||
// represents the size of all the LDAPEntries. This needs to be
|
||||
// removed before we iterate through each LDAPEntry.
|
||||
entries.removeElementAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
LDAPSearchResults(Vector v, LDAPConnection conn, LDAPSearchConstraints cons,
|
||||
|
@ -137,11 +139,10 @@ public class LDAPSearchResults implements Enumeration {
|
|||
* Adds search reference to this object.
|
||||
*/
|
||||
void add( JDAPSearchResultReference sr ) {
|
||||
/* build LDAPReferenceException out of this references */
|
||||
/* convert to LDAPReferralException */
|
||||
String urls[] = sr.getUrls();
|
||||
if (urls == null)
|
||||
return;
|
||||
entries.addElement(new LDAPReferralException(null, 0, urls));
|
||||
if (urls != null)
|
||||
entries.addElement(new LDAPReferralException(null, 0, urls));
|
||||
}
|
||||
|
||||
void add(LDAPException e) {
|
||||
|
@ -263,10 +264,6 @@ public class LDAPSearchResults implements Enumeration {
|
|||
entries.addElement(obj);
|
||||
}
|
||||
|
||||
// reset it to 0 since all the referral entries are now in the entries
|
||||
// vector
|
||||
totalReferralEntries = 0;
|
||||
|
||||
int numEntries = entries.size();
|
||||
if (numEntries <= 0)
|
||||
return;
|
||||
|
@ -280,13 +277,12 @@ public class LDAPSearchResults implements Enumeration {
|
|||
entries.removeAllElements();
|
||||
for (int i = 0; i < numEntries; i++)
|
||||
entries.addElement (toSort[i]);
|
||||
|
||||
current = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next LDAP entry from the search results
|
||||
* and throws an exception if the next result is a referral.
|
||||
* and throws an exception if the next result is a referral, or
|
||||
* if a sizelimit or timelimit error occurred.
|
||||
* <P>
|
||||
*
|
||||
* You can use this method in conjunction with the
|
||||
|
@ -305,13 +301,18 @@ public class LDAPSearchResults implements Enumeration {
|
|||
* // Your code for handling referrals
|
||||
* }
|
||||
* continue;
|
||||
* }
|
||||
* } catch ( LDAPException e ) {
|
||||
* // Your code for handling errors on limits exceeded
|
||||
* continue;
|
||||
* }
|
||||
* ...
|
||||
* }
|
||||
* </PRE>
|
||||
* @return The next LDAP entry in the search results.
|
||||
* @exception LDAPReferralException A referral (thrown
|
||||
* if the next result is a referral).
|
||||
* if the next result is a referral), or LDAPException
|
||||
* if a limit on the number of entries or the time was
|
||||
* exceeded.
|
||||
* @see netscape.ldap.LDAPSearchResults#hasMoreElements()
|
||||
*/
|
||||
public LDAPEntry next() throws LDAPException {
|
||||
|
@ -337,24 +338,28 @@ public class LDAPSearchResults implements Enumeration {
|
|||
* LDAPConnection.SCOPE_BASE, MY_FILTER,
|
||||
* null, false );
|
||||
* while ( res.hasMoreElements() ) {
|
||||
* LDAPEntry findEntry = (LDAPEntry)res.nextElement();
|
||||
* ...
|
||||
* }
|
||||
* </PRE>
|
||||
* Object o = res.nextElement();
|
||||
* if ( o instanceof LDAPEntry ) {
|
||||
* LDAPEntry findEntry = (LDAPEntry)o;
|
||||
* ...
|
||||
* } else if ( o instanceof LDAPReferralException ) {
|
||||
* LDAPReferralException e = (LDAPReferralException)o;
|
||||
* LDAPUrl refUrls[] = e.getURLs();
|
||||
* ...
|
||||
* } else if ( o instanceof LDAPException ) {
|
||||
* LDAPException e = (LDAPException)o;
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* </PRE>
|
||||
* @return The next element in the search results.
|
||||
* @see netscape.ldap.LDAPSearchResults#hasMoreElements()
|
||||
*/
|
||||
public Object nextElement() {
|
||||
if ((cacheEntries == null) && (!persistentSearch) && (current >= entries.size()-1))
|
||||
fetchResult();
|
||||
|
||||
if ( current < entries.size() ) {
|
||||
current++;
|
||||
/* Invalidate our reference to the entry, so it can be
|
||||
garbage collected */
|
||||
Object next = entries.elementAt( current-1 );
|
||||
entries.setElementAt( null, current-1 );
|
||||
return next;
|
||||
if ( entries.size() > 0 ) {
|
||||
Object obj = entries.elementAt(0);
|
||||
entries.removeElementAt(0);
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (referralResults.size() > 0) {
|
||||
|
@ -367,10 +372,10 @@ public class LDAPSearchResults implements Enumeration {
|
|||
Object nextReferralElement() {
|
||||
LDAPSearchResults res =
|
||||
(LDAPSearchResults)referralResults.elementAt(0);
|
||||
if ((!res.persistentSearch && res.hasMoreElements()) || (res.persistentSearch)) {
|
||||
if ((!res.persistentSearch && res.hasMoreElements()) ||
|
||||
(res.persistentSearch)) {
|
||||
Object obj = res.nextElement();
|
||||
if (obj != null) {
|
||||
totalReferralEntries++;
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -402,20 +407,20 @@ public class LDAPSearchResults implements Enumeration {
|
|||
* @see netscape.ldap.LDAPSearchResults#next()
|
||||
*/
|
||||
public boolean hasMoreElements() {
|
||||
if (current >= entries.size()-1)
|
||||
|
||||
while ((entries.size() == 0) && (!searchComplete))
|
||||
fetchResult();
|
||||
|
||||
while (referralResults.size() > 0) {
|
||||
LDAPSearchResults res =
|
||||
(LDAPSearchResults)referralResults.elementAt(0);
|
||||
if (res.hasMoreElements()) {
|
||||
|
||||
if (res.hasMoreElements())
|
||||
return true;
|
||||
} else
|
||||
else
|
||||
referralResults.removeElementAt(0);
|
||||
}
|
||||
|
||||
return ( current < entries.size() );
|
||||
return (entries.size() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,7 +428,13 @@ public class LDAPSearchResults implements Enumeration {
|
|||
* @return Count of entries found by the search.
|
||||
*/
|
||||
public int getCount() {
|
||||
return (current + totalReferralEntries);
|
||||
int totalReferralEntries = 0;
|
||||
for (int i=0; i<referralResults.size(); i++) {
|
||||
LDAPSearchResults res =
|
||||
(LDAPSearchResults)referralResults.elementAt(i);
|
||||
totalReferralEntries = totalReferralEntries+res.getCount();
|
||||
}
|
||||
return (entries.size() + totalReferralEntries);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -449,17 +460,6 @@ public class LDAPSearchResults implements Enumeration {
|
|||
* Fetchs the next result, for asynchronous searches.
|
||||
*/
|
||||
private synchronized void fetchResult() {
|
||||
// if using the results from cache
|
||||
if ((cacheEntries != null) && (current < cacheEntries.size()-1))
|
||||
{
|
||||
// always retrieves the one at current+1 because the first element
|
||||
// in the cacheEntries always contains the size of all elements in the
|
||||
// cacheEntries vector.
|
||||
LDAPEntry entry = (LDAPEntry)cacheEntries.elementAt(current+1);
|
||||
LDAPEntry e = new LDAPEntry(entry.getDN(), entry.getAttributeSet());
|
||||
entries.addElement(e);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Asynchronous case */
|
||||
if ( resultSource != null ) {
|
||||
|
|
|
@ -270,3 +270,11 @@ Name: netscape/ldap/util/MimeEncoder.class
|
|||
|
||||
Name: netscape/ldap/util/RDN.class
|
||||
|
||||
Name: LDAPTool.class
|
||||
|
||||
Name: LDAPDelete.class
|
||||
|
||||
Name: LDAPSearch.class
|
||||
|
||||
Name: LDAPModify.class
|
||||
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.util.*;
|
||||
|
||||
/**
|
||||
* Executes the delete command to delete an LDAP entry.
|
||||
* This class is implemented based on the java LDAP classes.
|
||||
*
|
||||
* <pre>
|
||||
* usage : java LDAPDelete [options] DN
|
||||
* for example : java -D "dn" -w password -h ds.internic.net -p 389
|
||||
* "cn=Johnny James,o=Ace Industry"
|
||||
*
|
||||
* options: {np = no parameters, p = requires parameters}
|
||||
* 'D' bind DN --------------------------------------------- p
|
||||
* 'h' LDAP host ------------------------------------------- p
|
||||
* 'p' LDAP port ------------------------------------------- p
|
||||
* 'w' bind password --------------------------------------- p
|
||||
*
|
||||
* note: '-' or '/' is used to distinct the option field.
|
||||
* e.g. -a -b /c /d parameter -e parameter
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class LDAPDelete extends LDAPTool { /* LDAPDelete */
|
||||
|
||||
public static void main(String args[]) { /* main */
|
||||
|
||||
if ( args.length < 1 ) {
|
||||
doUsage();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
/* extract parameters from the arguments list */
|
||||
extractParameters(args);
|
||||
|
||||
if (!m_justShow) {
|
||||
|
||||
/* perform an LDAP client connection operation */
|
||||
try {
|
||||
m_client = new LDAPConnection();
|
||||
m_client.connect( m_ldaphost, m_ldapport );
|
||||
} catch(Exception e) {
|
||||
System.err.println("Error: client connection failed!");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
/* perform an LDAP bind operation */
|
||||
try {
|
||||
m_client.authenticate( m_version, m_binddn, m_passwd );
|
||||
} catch (Exception e) {
|
||||
System.err.println( e.toString() );
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
/* perform a delete operation */
|
||||
dodelete();
|
||||
|
||||
/* disconnect */
|
||||
try {
|
||||
m_client.disconnect();
|
||||
} catch (Exception e) {
|
||||
System.err.println( e.toString() );
|
||||
}
|
||||
} else
|
||||
dodelete(null);
|
||||
System.exit(0);
|
||||
} /* main */
|
||||
|
||||
/**
|
||||
* Prints usage.
|
||||
*/
|
||||
private static void doUsage() {
|
||||
System.err.println( "usage: LDAPDelete [options] dn" );
|
||||
System.err.println("options");
|
||||
System.err.println(" -h host LDAP server name or IP address");
|
||||
System.err.println(" -p port LDAP server TCP port number");
|
||||
System.err.println(" -V version LDAP protocol version " +
|
||||
"number (default is 3)");
|
||||
System.err.println(" -D binddn bind dn");
|
||||
System.err.println(" -w password bind passwd (for simple " +
|
||||
"authentication)");
|
||||
System.err.println(" -d level set LDAP debugging level " +
|
||||
"to \'level\'");
|
||||
System.err.println(" -f file read DNs to delete from file");
|
||||
System.err.println(" -R do not automatically follow " +
|
||||
"referrals");
|
||||
System.err.println(" -O hop limit maximum number of referral " +
|
||||
"hops to traverse");
|
||||
System.err.println(" -H display usage information");
|
||||
System.err.println(" -c continuous mode (do not "+
|
||||
"stop on errors)");
|
||||
|
||||
System.err.println(" -M manage references (treat them "+
|
||||
"as regular entries)");
|
||||
}
|
||||
|
||||
/**
|
||||
* This class-method is used to extract specified parameters from the
|
||||
* arguments list.
|
||||
*/
|
||||
protected static void extractParameters(String args[]) {
|
||||
GetOpt options = LDAPTool.extractParameters( "Hcf:", args );
|
||||
|
||||
/* -H Help */
|
||||
if (options.hasOption('H')) {
|
||||
doUsage();
|
||||
System.exit(0);
|
||||
} /* Help */
|
||||
|
||||
/* -c continuous mode */
|
||||
if (options.hasOption('c')) {
|
||||
m_cont = true;
|
||||
} /* continous mode */
|
||||
|
||||
/* -f file */
|
||||
if (options.hasOption('f')) {
|
||||
String filename = options.getOptionParam('f');
|
||||
if (filename == null) {
|
||||
doUsage();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
try {
|
||||
FileInputStream fs = new FileInputStream(filename);
|
||||
DataInputStream ds = new DataInputStream(fs);
|
||||
m_reader = new BufferedReader(new InputStreamReader(ds));
|
||||
} catch (FileNotFoundException e) {
|
||||
System.err.println("File "+filename+" not found");
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error in opening the file "+filename);
|
||||
}
|
||||
} /* input file */
|
||||
|
||||
if (m_reader == null) {
|
||||
Enumeration pa = options.getParameters().elements();
|
||||
Vector vec = new Vector();
|
||||
while (pa.hasMoreElements()) { /* while */
|
||||
vec.addElement(pa.nextElement());
|
||||
}
|
||||
|
||||
if (vec.size() <= 0) {
|
||||
doUsage();
|
||||
System.exit(0);
|
||||
}
|
||||
m_delete_dn = new String[vec.size()];
|
||||
vec.copyInto(m_delete_dn);
|
||||
}
|
||||
} /* extract parameters */
|
||||
|
||||
/**
|
||||
* This class-method is used to call the LDAP Delete Operation with the
|
||||
* specified options, and/or parameters.
|
||||
*/
|
||||
private static void dodelete() { /* dodelete */
|
||||
int msgid = 0;
|
||||
LDAPSearchConstraints cons =
|
||||
(LDAPSearchConstraints)m_client.getSearchConstraints().clone();
|
||||
if (m_ordinary) {
|
||||
LDAPControl control = new LDAPControl(
|
||||
LDAPControl.MANAGEDSAIT, true, null);
|
||||
cons.setServerControls(control);
|
||||
}
|
||||
cons.setReferrals( m_referrals );
|
||||
if ( m_referrals ) {
|
||||
setDefaultReferralCredentials( cons );
|
||||
}
|
||||
cons.setHopLimit( m_hopLimit );
|
||||
dodelete(cons);
|
||||
} /* dodelete */
|
||||
|
||||
private static void dodelete(LDAPSearchConstraints cons) {
|
||||
try {
|
||||
if (m_reader == null) {
|
||||
for (int i=0; i<m_delete_dn.length; i++)
|
||||
if (!deleteEntry(m_delete_dn[i], cons) && !m_cont)
|
||||
return;
|
||||
} else {
|
||||
String dn = null;
|
||||
while ((dn=m_reader.readLine()) != null) {
|
||||
if (!deleteEntry(dn, cons) && !m_cont)
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error in reading input");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean deleteEntry(String dn, LDAPSearchConstraints cons) {
|
||||
if (m_verbose)
|
||||
System.err.println("Deleting entry: "+dn);
|
||||
if (!m_justShow) {
|
||||
try {
|
||||
m_client.delete(dn, cons);
|
||||
} catch (LDAPException ee) {
|
||||
System.err.println("Delete " + dn + " failed ");
|
||||
System.err.println("\t"+ee.errorCodeToString());
|
||||
System.err.println("\tmatched "+ee.getMatchedDN()+"\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String[] m_delete_dn = null;
|
||||
private static boolean m_cont = false;
|
||||
private static BufferedReader m_reader = null;
|
||||
} /* LDAPDelete */
|
||||
|
|
@ -0,0 +1,445 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
/*
|
||||
* @(#) LDAPModify.java
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.util.*;
|
||||
|
||||
/**
|
||||
* Executes modify, delete, add, and modRDN.
|
||||
* This class is implemented based on the java LDAP classes.
|
||||
*
|
||||
* <pre>
|
||||
* usage : java LDAPModify [options]
|
||||
* example : java LDAPModify -w "password" -h ldap.netscape.com -p 389
|
||||
* -f modify.cfg
|
||||
*
|
||||
* options: {np = no parameters, p = requires parameters}
|
||||
* 'D' bind DN --------------------------------------------- p
|
||||
* 'f' input file ------------------------------------------ p
|
||||
* 'h' LDAP host ------------------------------------------- p
|
||||
* 'p' LDAP port ------------------------------------------- p
|
||||
* 'n' override DN to modify ------------------------------- p
|
||||
* 'w' bind password --------------------------------------- p
|
||||
* 'e' record rejected records in a text file -------------- p
|
||||
* 'c' continuous, do not stop on error
|
||||
* 'a' add, if no operation is specified
|
||||
* 'r' replace, if no operation is specified
|
||||
* 'b' binary, read values starting with / from a file
|
||||
*
|
||||
* note: '-' or '/' is used to distinct the option field.
|
||||
* e.g. -a -b /c /d parameter -e parameter
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class LDAPModify extends LDAPTool { /* LDAPModify */
|
||||
|
||||
public static void main(String args[]) { /* main */
|
||||
|
||||
/* extract parameters from the arguments list */
|
||||
extractParameters(args);
|
||||
|
||||
/* perform an LDAP client connection operation */
|
||||
try {
|
||||
if (!m_justShow) {
|
||||
m_client = new LDAPConnection();
|
||||
m_client.connect( m_ldaphost, m_ldapport );
|
||||
}
|
||||
} catch(Exception e) {
|
||||
System.err.println("Error: client connection failed!");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/* perform an LDAP bind operation */
|
||||
try {
|
||||
if (!m_justShow)
|
||||
m_client.authenticate( m_version, m_binddn, m_passwd );
|
||||
} catch (Exception e) {
|
||||
System.err.println( e.toString() );
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
try {
|
||||
if ( m_file != null )
|
||||
m_ldif = new LDIF(m_file);
|
||||
else {
|
||||
m_ldif = new LDIF();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if ( m_file == null )
|
||||
m_file = "stdin";
|
||||
System.err.println("Failed to read LDIF file " + m_file +
|
||||
", " + e.toString());
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/* performs a JDAP Modify operation */
|
||||
try {
|
||||
doModify();
|
||||
} catch (Exception e) {
|
||||
System.err.println( e.toString() );
|
||||
}
|
||||
|
||||
/* disconnect */
|
||||
try {
|
||||
if (!m_justShow)
|
||||
m_client.disconnect();
|
||||
} catch (Exception e) {
|
||||
System.err.println( e.toString() );
|
||||
}
|
||||
System.exit(0);
|
||||
} /* main */
|
||||
|
||||
/**
|
||||
* Prints usage.
|
||||
*/
|
||||
private static void doUsage() {
|
||||
System.err.println( "usage: LDAPModify [options]" );
|
||||
System.err.println("options");
|
||||
System.err.println(" -h host LDAP server name or IP address");
|
||||
System.err.println(" -p port LDAP server TCP port number");
|
||||
System.err.println(" -V version LDAP protocol version " +
|
||||
"number (default is 3)");
|
||||
System.err.println(" -D binddn bind dn");
|
||||
System.err.println(" -w password bind passwd (for simple " +
|
||||
"authentication)");
|
||||
System.err.println(" -d level set LDAP debugging level " +
|
||||
"to \'level\'");
|
||||
System.err.println(" -R do not automatically follow " +
|
||||
"referrals");
|
||||
System.err.println(" -O hop limit maximum number of referral " +
|
||||
"hops to traverse");
|
||||
System.err.println(" -H display usage information");
|
||||
System.err.println(" -c continuous mode (do not " +
|
||||
"stop on errors)");
|
||||
System.err.println(" -M manage references (treat them " +
|
||||
"as regular entries)");
|
||||
System.err.println(" -f file read modifications from " +
|
||||
"file instead of standard input");
|
||||
System.err.println(" -a add entries");
|
||||
System.err.println(" -b read values that start with " +
|
||||
"/ from files (for bin attrs)");
|
||||
System.err.println(" -n show what would be done but " +
|
||||
"don\'t actually do it");
|
||||
System.err.println(" -v run in verbose mode");
|
||||
System.err.println(" -r replace existing values by " +
|
||||
"default");
|
||||
System.err.println(" -e rejectfile save rejected entries in " +
|
||||
"\'rejfile\'");
|
||||
}
|
||||
|
||||
/**
|
||||
* This class-method is used to extract specified parameters from the
|
||||
* arguments list.
|
||||
*/
|
||||
/* extract parameters */
|
||||
protected static void extractParameters(String args[]) {
|
||||
|
||||
String privateOpts = "abcHFre:f:";
|
||||
|
||||
GetOpt options = LDAPTool.extractParameters( privateOpts, args );
|
||||
|
||||
/* -H Help */
|
||||
if (options.hasOption('H')) {
|
||||
doUsage();
|
||||
System.exit(0);
|
||||
} /* Help */
|
||||
|
||||
if (options.hasOption('F'))
|
||||
m_force = true;
|
||||
|
||||
if (options.hasOption('a'))
|
||||
m_add = true;
|
||||
|
||||
if (options.hasOption('c'))
|
||||
m_continuous = true;
|
||||
|
||||
if (options.hasOption('r'))
|
||||
m_add = false;
|
||||
|
||||
if (options.hasOption('b'))
|
||||
m_binaryFiles = true;
|
||||
|
||||
/* -f input file */
|
||||
if(options.hasOption('f')) { /* Is input file */
|
||||
m_file = (String)options.getOptionParam('f');
|
||||
} /* End Is input file */
|
||||
|
||||
/* -e rejects file */
|
||||
if(options.hasOption('e')) { /* rejects file */
|
||||
m_rejectsFile = (String)options.getOptionParam('e');
|
||||
} /* End rejects file */
|
||||
|
||||
} /* extract parameters */
|
||||
|
||||
/**
|
||||
* This class-method is used to call the JDAP Modify Operation with the
|
||||
* specified options, and/or parameters.
|
||||
*/
|
||||
private static void doModify() throws IOException { /* doModify */
|
||||
DataOutputStream reject = null;
|
||||
LDAPSearchConstraints cons = null;
|
||||
if (!m_justShow) {
|
||||
cons =
|
||||
(LDAPSearchConstraints)m_client.getSearchConstraints().clone();
|
||||
if (m_ordinary) {
|
||||
LDAPControl control = new LDAPControl(
|
||||
LDAPControl.MANAGEDSAIT, true, null);
|
||||
cons.setServerControls(control);
|
||||
}
|
||||
cons.setReferrals( m_referrals );
|
||||
if ( m_referrals ) {
|
||||
setDefaultReferralCredentials( cons );
|
||||
}
|
||||
cons.setHopLimit( m_hopLimit );
|
||||
}
|
||||
|
||||
LDIFRecord rec = m_ldif.nextRecord();
|
||||
|
||||
for (; rec != null; rec = m_ldif.nextRecord() ) {
|
||||
LDIFContent content = rec.getContent();
|
||||
LDAPModification mods[] = null;
|
||||
LDAPAttribute addAttrs[] = null;
|
||||
boolean doDelete = false;
|
||||
boolean doModDN = false;
|
||||
LDAPEntry newEntry = null;
|
||||
|
||||
/* What type of record is this? */
|
||||
if ( content instanceof LDIFModifyContent ) {
|
||||
mods = ((LDIFModifyContent)content).getModifications();
|
||||
} else if ( content instanceof LDIFAddContent ) {
|
||||
addAttrs = ((LDIFAddContent)content).getAttributes();
|
||||
} else if ( content instanceof LDIFAttributeContent ) {
|
||||
/* No change type; decide what to do based on options */
|
||||
if ( m_add )
|
||||
addAttrs =
|
||||
((LDIFAttributeContent)content).getAttributes();
|
||||
else {
|
||||
LDAPAttribute[] tmpAttrs =
|
||||
((LDIFAttributeContent)content).getAttributes();
|
||||
mods = new LDAPModification[tmpAttrs.length];
|
||||
for( int ta = 0; ta < tmpAttrs.length; ta++ ) {
|
||||
mods[ta] = new LDAPModification(
|
||||
LDAPModification.REPLACE, tmpAttrs[ta] );
|
||||
}
|
||||
}
|
||||
} else if ( content instanceof LDIFDeleteContent ) {
|
||||
doDelete = true;
|
||||
} else if (content instanceof LDIFModDNContent ) {
|
||||
doModDN = true;
|
||||
} else {
|
||||
}
|
||||
|
||||
/* Prepare for adding */
|
||||
if ( addAttrs != null ) {
|
||||
LDAPAttributeSet newAttrSet = new LDAPAttributeSet();
|
||||
for( int a = 0; a < addAttrs.length; a++ )
|
||||
newAttrSet.add( addAttrs[a] );
|
||||
newEntry = new LDAPEntry( rec.getDN(), newAttrSet );
|
||||
}
|
||||
|
||||
/* Get values from files? */
|
||||
boolean skip = false;
|
||||
if ( m_binaryFiles ) {
|
||||
/* Check each value of each attribute, to see if it
|
||||
needs replacing with the contents of a file */
|
||||
if ( mods != null ) {
|
||||
for( int m = 0; m < mods.length; m++ ) {
|
||||
LDAPModification mod = mods[m];
|
||||
LDAPAttribute attr = mods[m].getAttribute();
|
||||
|
||||
LDAPAttribute newAttr = checkFiles( attr );
|
||||
if ( newAttr == null )
|
||||
skip = true;
|
||||
else
|
||||
mods[m] = new LDAPModification(
|
||||
mod.getOp(), newAttr );
|
||||
}
|
||||
} else if ( addAttrs != null ) {
|
||||
LDAPAttributeSet newAttrSet = new LDAPAttributeSet();
|
||||
for( int a = 0; a < addAttrs.length; a++ ) {
|
||||
LDAPAttribute attr = addAttrs[a];
|
||||
|
||||
LDAPAttribute newAttr = checkFiles( attr );
|
||||
if ( newAttr == null ) {
|
||||
skip = true;
|
||||
break;
|
||||
} else {
|
||||
newAttrSet.add( newAttr );
|
||||
}
|
||||
}
|
||||
if ( !skip ) {
|
||||
newEntry = new LDAPEntry( rec.getDN(), newAttrSet );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do the directory operation */
|
||||
int errCode = 0;
|
||||
if ( !skip ) {
|
||||
try {
|
||||
if ( mods != null ) {
|
||||
LDAPModificationSet modSet =
|
||||
new LDAPModificationSet();
|
||||
System.out.println("\nmodifying entry "+rec.getDN() );
|
||||
for( int m = 0; m < mods.length; m++ ) {
|
||||
if (m_verbose)
|
||||
System.out.println("\t"+mods[m] );
|
||||
modSet.add( mods[m].getOp(),
|
||||
mods[m].getAttribute() );
|
||||
}
|
||||
|
||||
if (!m_justShow)
|
||||
m_client.modify( rec.getDN(), modSet, cons );
|
||||
} else if ( newEntry != null ) {
|
||||
System.out.println( "\nadding new entry " + newEntry.getDN() );
|
||||
if ( m_verbose ) {
|
||||
LDAPAttributeSet set = newEntry.getAttributeSet();
|
||||
for( int a = 0; a < set.size(); a++ ) {
|
||||
System.out.println("\t"+set.elementAt(a) );
|
||||
}
|
||||
}
|
||||
if (!m_justShow)
|
||||
m_client.add( newEntry, cons );
|
||||
} else if ( doDelete ) {
|
||||
System.out.println( "\ndeleting entry " + rec.getDN() );
|
||||
if (!m_justShow)
|
||||
m_client.delete( rec.getDN(), cons );
|
||||
} else if ( doModDN) {
|
||||
System.out.println( "\nmodifying RDN of entry " +
|
||||
rec.getDN()+" and/or moving it beneath a new parent");
|
||||
if ( m_verbose ) {
|
||||
System.out.println( "\t"+content.toString());
|
||||
}
|
||||
if (!m_justShow) {
|
||||
LDIFModDNContent moddnContent = (LDIFModDNContent)content;
|
||||
m_client.rename( rec.getDN(), moddnContent.getRDN(),
|
||||
moddnContent.getNewParent(),
|
||||
moddnContent.getDeleteOldRDN(), cons );
|
||||
System.out.println( "rename completed");
|
||||
}
|
||||
}
|
||||
} catch (LDAPException e) {
|
||||
System.err.println( rec.getDN() + ": " +
|
||||
e.errorCodeToString() );
|
||||
if (e.getLDAPErrorMessage() != null)
|
||||
System.err.println( "additional info: " +
|
||||
e.getLDAPErrorMessage() );
|
||||
if ( !m_continuous )
|
||||
System.exit(1);
|
||||
skip = true;
|
||||
errCode = e.getLDAPResultCode();
|
||||
}
|
||||
}
|
||||
|
||||
/* Write to rejects file? */
|
||||
if ( skip && (m_rejectsFile != null) ) {
|
||||
try {
|
||||
if ( reject == null ) {
|
||||
reject = new DataOutputStream(
|
||||
new FileOutputStream( m_rejectsFile ) );
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
}
|
||||
if ( reject != null ) {
|
||||
try {
|
||||
reject.writeUTF( "dn: "+rec.getDN()+ " # Error: " + errCode + '\n' );
|
||||
if ( mods != null ) {
|
||||
for( int m = 0; m < mods.length; m++ ) {
|
||||
reject.writeUTF( mods[m].toString() +
|
||||
'\n' );
|
||||
}
|
||||
} else if ( newEntry != null ) {
|
||||
reject.writeUTF( "Add " + newEntry.toString()
|
||||
+ '\n' );
|
||||
} else if ( doDelete ) {
|
||||
reject.writeUTF( "Delete " + rec.getDN()
|
||||
+ '\n' );
|
||||
} else if (doModDN) {
|
||||
reject.writeUTF( "ModDN "+
|
||||
((LDIFModDNContent)content).toString()+'\n');
|
||||
}
|
||||
} catch ( IOException ex ) {
|
||||
System.err.println( ex.toString() );
|
||||
System.exit( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
System.exit(0);
|
||||
} /* doModify */
|
||||
|
||||
|
||||
/**
|
||||
* Read in binary data for values specified with a leading /
|
||||
* @param attr Source attribute.
|
||||
* @return Updated attribute.
|
||||
**/
|
||||
private static LDAPAttribute checkFiles ( LDAPAttribute attr ) {
|
||||
LDAPAttribute newAttr =
|
||||
new LDAPAttribute( attr.getName() );
|
||||
|
||||
/* Check each value and see if it is a file name */
|
||||
Enumeration e = attr.getStringValues();
|
||||
if (e != null) {
|
||||
while ( e.hasMoreElements() ) {
|
||||
String val = (String)e.nextElement();
|
||||
if ( (val != null) && (val.length() > 1)) {
|
||||
try {
|
||||
File file = new File( val );
|
||||
FileInputStream fi =
|
||||
new FileInputStream( file );
|
||||
byte[] bval = new byte[(int)file.length()];
|
||||
fi.read( bval, 0, (int)file.length() );
|
||||
newAttr.addValue( bval );
|
||||
} catch (FileNotFoundException ex) {
|
||||
newAttr.addValue(val) ;
|
||||
} catch ( IOException ex ) {
|
||||
System.err.println( "Unable to read value " +
|
||||
"from file " + val );
|
||||
if ( !m_continuous )
|
||||
System.exit(1);
|
||||
newAttr = null;
|
||||
}
|
||||
} else {
|
||||
newAttr.addValue( val );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
System.err.println("Failed to do string conversion for "+attr.getName());
|
||||
return newAttr;
|
||||
}
|
||||
|
||||
private static boolean m_continuous = false;
|
||||
private static boolean m_force = false;
|
||||
private static boolean m_add = false;
|
||||
private static boolean m_binaryFiles = false;
|
||||
private static String m_rejectsFile = null;
|
||||
private static LDIF m_ldif = null;
|
||||
private static String m_file = null;
|
||||
} /* LDAPModify */
|
|
@ -0,0 +1,599 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.util.*;
|
||||
import netscape.ldap.controls.*;
|
||||
|
||||
/**
|
||||
* Execute Search operations through the LDAP client interface.
|
||||
* This class is implemented based on the LDAP class library.
|
||||
*
|
||||
* <pre>
|
||||
* usage : java LDAPSearch -b baseDN [options] filter [attributes...]
|
||||
* for example : java LDAPSearch -b "c=us" -h ds.internic.net -p 389
|
||||
* "(objectClass=*)"
|
||||
*
|
||||
* note: '-' or '/' is used to distinct the option field.
|
||||
* e.g. -a -b /c /d parameter -e parameter
|
||||
*
|
||||
* filter:
|
||||
* Any string in RFC1558 specification.
|
||||
* e.g. "(objectClass=*)"
|
||||
*
|
||||
* attributes: {0..n}
|
||||
* All the string parameters follows with the filter.
|
||||
* e.g. filter attrsA attrsB attrsC
|
||||
* </pre>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class LDAPSearch extends LDAPTool {
|
||||
/**
|
||||
* This is the main function.
|
||||
* @param args list of arguments
|
||||
*/
|
||||
public static void main(String args[]) {
|
||||
|
||||
/* extract parameters from the arguments list */
|
||||
extractParameters(args);
|
||||
|
||||
if (!m_justShow) {
|
||||
/* perform an LDAP client connection operation */
|
||||
try {
|
||||
m_client = new LDAPConnection();
|
||||
m_client.connect( m_ldaphost, m_ldapport );
|
||||
} catch(Exception e) {
|
||||
System.err.println("Error: client connection failed!");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/* perform an LDAP bind operation */
|
||||
try {
|
||||
m_client.authenticate( m_version, m_binddn, m_passwd );
|
||||
} catch (Exception e) {
|
||||
System.err.println( e.toString() );
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/* perform a search operation */
|
||||
dosearch();
|
||||
|
||||
m_pw.flush();
|
||||
m_pw.close();
|
||||
|
||||
/* disconnect */
|
||||
try {
|
||||
m_client.disconnect();
|
||||
} catch (Exception e) {
|
||||
System.err.println( e.toString() );
|
||||
}
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints usage.
|
||||
*/
|
||||
private static void doUsage() {
|
||||
System.err.println("usage: LDAPSearch -b basedn [options] " +
|
||||
"filter [attributes...]");
|
||||
System.err.println("options");
|
||||
System.err.println(" -h host LDAP server name or IP address");
|
||||
System.err.println(" -p port LDAP server TCP port number");
|
||||
System.err.println(" -V version LDAP protocol version " +
|
||||
"number (default is 3)");
|
||||
System.err.println(" -D binddn bind dn");
|
||||
System.err.println(" -w password bind passwd (for simple " +
|
||||
"authentication)");
|
||||
System.err.println(" -v run in verbose mode");
|
||||
System.err.println(" -n show what would be done but "+
|
||||
"don't actually do it");
|
||||
System.err.println(" -d level set LDAP debugging level " +
|
||||
"to \'level\'");
|
||||
System.err.println(" -R do not automatically follow " +
|
||||
"referrals");
|
||||
System.err.println(" -O hop limit maximum number of referral " +
|
||||
"hops to traverse");
|
||||
System.err.println(" -H display usage information");
|
||||
System.err.println(" -t write values to files");
|
||||
System.err.println(" -A retrieve attribute names only");
|
||||
System.err.println(" -F sep print \'sep\' instead of " +
|
||||
"\'=\' between attribute names and values");
|
||||
System.err.println(" -S attr sort the results by attribute " +
|
||||
"\'attr\'");
|
||||
System.err.println(" -s scope one of base, one, or sub " +
|
||||
"(search scope)");
|
||||
System.err.println(" -a deref one of never, always, search, " +
|
||||
"or find (alias dereferencing)");
|
||||
System.err.println(" -l timelimit time limit (in seconds) for " +
|
||||
"search");
|
||||
System.err.println(" -T do not fold (wrap) long lines "+
|
||||
"(default is to fold)");
|
||||
System.err.println(" -x perform sorting on server");
|
||||
System.err.println(" -M manage references (treat them "+
|
||||
"as regular entries)");
|
||||
System.err.println(" -z sizelimit size limit (in entries) for " +
|
||||
"search");
|
||||
System.err.println(" -G before:after:index:count | before:after:value "+
|
||||
"where 'before' and 'after' are the number of "+
|
||||
"entries surrounding 'index'. 'count' is the "+
|
||||
"content count, 'value' is the search value.");
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is to extract specified parameters from the
|
||||
* arguments list.
|
||||
* @param args list of args
|
||||
*/
|
||||
protected static void extractParameters(String args[]) {
|
||||
|
||||
String privateOpts = "HATtxvna:b:F:l:s:S:z:G:";
|
||||
|
||||
GetOpt options = LDAPTool.extractParameters( privateOpts, args );
|
||||
|
||||
/* -H Help */
|
||||
if (options.hasOption('H')) {
|
||||
doUsage();
|
||||
System.exit(0);
|
||||
} /* Help */
|
||||
|
||||
/* -A retrieve attribute name only == no values */
|
||||
if (options.hasOption('A'))
|
||||
m_attrsonly = true;
|
||||
|
||||
if (options.hasOption('x'))
|
||||
m_sortOnServer = true;
|
||||
|
||||
if (options.hasOption('t'))
|
||||
m_tempFiles = true;
|
||||
|
||||
/* -F separator */
|
||||
if (options.hasOption('F'))
|
||||
m_sep = options.getOptionParam('F');
|
||||
|
||||
/* -a set alias deref option */
|
||||
if (options.hasOption('a')) { /* has option a */
|
||||
|
||||
String param = options.getOptionParam('a');
|
||||
|
||||
if (param.equalsIgnoreCase("never"))
|
||||
m_deref = 0;
|
||||
else if (param.equalsIgnoreCase("search"))
|
||||
m_deref = 1;
|
||||
else if (param.equalsIgnoreCase("find"))
|
||||
m_deref = 2;
|
||||
else if (param.equalsIgnoreCase("always"))
|
||||
m_deref = 3;
|
||||
else
|
||||
System.err.println("Error: alias deref option " +
|
||||
"should be never, search, find, " +
|
||||
"or always.");
|
||||
} /* has option a */
|
||||
|
||||
/* -b searchbase */
|
||||
if (options.hasOption('b'))
|
||||
m_base = options.getOptionParam('b');
|
||||
|
||||
/* -S sort attribute */
|
||||
if (options.hasOption('S'))
|
||||
m_sort.addElement( options.getOptionParam('S') );
|
||||
|
||||
/* -l time limit */
|
||||
if (options.hasOption('l')) { /* if the option is -l */
|
||||
try {
|
||||
m_timelimit = Integer.parseInt(options.getOptionParam('l'));
|
||||
} catch (NumberFormatException e) {
|
||||
m_timelimit = 0;
|
||||
}
|
||||
} /* if the option is -l */
|
||||
|
||||
/* -s search scope */
|
||||
if (options.hasOption('s')) { /* has option s */
|
||||
|
||||
String param = options.getOptionParam('s');
|
||||
|
||||
if (param.equalsIgnoreCase("base"))
|
||||
m_scope = 0;
|
||||
else if (param.equalsIgnoreCase("one"))
|
||||
m_scope = 1;
|
||||
else if (param.equalsIgnoreCase("sub"))
|
||||
m_scope = 2;
|
||||
else
|
||||
System.err.println("Error: scope should be base, " +
|
||||
"one or sub.");
|
||||
} /* has option s */
|
||||
|
||||
/* -z size limit */
|
||||
if (options.hasOption('z')) { /* if the option is -z */
|
||||
try {
|
||||
m_sizelimit = Integer.parseInt(options.getOptionParam('z'));
|
||||
} catch (NumberFormatException e) {
|
||||
m_sizelimit = 0;
|
||||
}
|
||||
} /* if the option is -z */
|
||||
|
||||
/* -T fold line */
|
||||
if (options.hasOption('T')) { /* if the option is -T */
|
||||
m_foldLine = false;
|
||||
}
|
||||
|
||||
parseVlv(options);
|
||||
|
||||
/* extract the filter string and attributes */
|
||||
Enumeration pa = options.getParameters().elements();
|
||||
Vector vec = new Vector();
|
||||
|
||||
while (pa.hasMoreElements()) { /* while */
|
||||
vec.addElement(pa.nextElement());
|
||||
} /* while */
|
||||
|
||||
int counter = vec.size();
|
||||
|
||||
if (counter <= 0) { /* No filter */
|
||||
System.err.println("Error: must supply filter string!");
|
||||
doUsage();
|
||||
System.exit(0);
|
||||
} /* No filter */
|
||||
|
||||
if (counter == 1) { /* Has filter but no attributes */
|
||||
|
||||
/* gets filter string */
|
||||
m_filter = (String)vec.elementAt(0);
|
||||
if (m_verbose)
|
||||
System.err.println("filter pattern: "+m_filter);
|
||||
|
||||
/* no attributes */
|
||||
m_attrs = null;
|
||||
if (m_verbose) {
|
||||
System.err.println("returning: ALL");
|
||||
System.err.println("filter is: ("+m_filter+")");
|
||||
}
|
||||
} /* Has filter but no attributes */
|
||||
|
||||
if (counter > 1) { /* Has filter and attributes */
|
||||
|
||||
/* gets filter string */
|
||||
m_filter = (String)vec.elementAt(0);
|
||||
if (m_verbose) {
|
||||
System.err.println("filter pattern: "+m_filter);
|
||||
System.err.print("returning:");
|
||||
}
|
||||
|
||||
/* gets attributes */
|
||||
m_attrs = new String[counter];
|
||||
for (int j = 1; j < counter; j++) {
|
||||
m_attrs[j-1] = (String)vec.elementAt(j);
|
||||
if (m_verbose)
|
||||
System.err.print(" "+m_attrs[j-1]);
|
||||
}
|
||||
if (m_verbose) {
|
||||
System.err.println();
|
||||
System.err.println("filter is: ("+m_filter+")");
|
||||
}
|
||||
} /* Has filter and attributes */
|
||||
}
|
||||
|
||||
private static void parseVlv(GetOpt options) {
|
||||
|
||||
/* -G virtual list */
|
||||
if (options.hasOption('G')) { /* if the option is -G */
|
||||
String val = options.getOptionParam('G');
|
||||
StringTokenizer tokenizer = new StringTokenizer(val, ":");
|
||||
m_vlvTokens = tokenizer.countTokens();
|
||||
if (m_vlvTokens < 3) {
|
||||
doUsage();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
try {
|
||||
m_beforeCount = Integer.parseInt((String)tokenizer.nextElement());
|
||||
} catch (NumberFormatException e) {
|
||||
m_beforeCount = 0;
|
||||
}
|
||||
|
||||
try {
|
||||
m_afterCount = Integer.parseInt((String)tokenizer.nextElement());
|
||||
} catch (NumberFormatException e) {
|
||||
m_afterCount = 0;
|
||||
}
|
||||
|
||||
if (m_vlvTokens == 3) {
|
||||
m_searchVal = (String)tokenizer.nextElement();
|
||||
} else if (m_vlvTokens > 3) {
|
||||
try {
|
||||
m_index = Integer.parseInt((String)tokenizer.nextElement());
|
||||
} catch (NumberFormatException e) {
|
||||
m_index = 0;
|
||||
}
|
||||
|
||||
try {
|
||||
m_count = Integer.parseInt((String)tokenizer.nextElement());
|
||||
} catch (NumberFormatException e) {
|
||||
m_count = 0;
|
||||
}
|
||||
}
|
||||
} /* if the option is -G */
|
||||
}
|
||||
|
||||
/**
|
||||
* This class-method is used to call the LDAP Search Operation with the
|
||||
* specified options, parameters, filters and/or attributes.
|
||||
*/
|
||||
private static void dosearch() {
|
||||
|
||||
LDAPControl[] controls = null;
|
||||
try {
|
||||
Vector cons = new Vector();
|
||||
LDAPSortControl sort = null;
|
||||
if ( m_sortOnServer && (m_sort.size() > 0) ) {
|
||||
LDAPSortKey[] keys = new LDAPSortKey[m_sort.size()];
|
||||
for( int i = 0; i < keys.length; i++ ) {
|
||||
keys[i] = new LDAPSortKey( (String)m_sort.elementAt(i) );
|
||||
}
|
||||
sort = new LDAPSortControl( keys, true );
|
||||
cons.addElement(sort);
|
||||
}
|
||||
|
||||
if ((sort == null) && (m_vlvTokens >= 3)) {
|
||||
System.err.println("Server-side sorting is required for "+
|
||||
"virtual list option");
|
||||
doUsage();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
LDAPVirtualListControl vControl = null;
|
||||
if (m_vlvTokens == 3) {
|
||||
vControl = new LDAPVirtualListControl(m_searchVal,
|
||||
m_beforeCount, m_afterCount);
|
||||
} else if (m_vlvTokens > 3) {
|
||||
vControl = new LDAPVirtualListControl(m_index, m_beforeCount,
|
||||
m_afterCount, m_count);
|
||||
}
|
||||
|
||||
if (vControl != null)
|
||||
cons.addElement(vControl);
|
||||
|
||||
if (m_ordinary) {
|
||||
LDAPControl manageDSAITControl = new LDAPControl(
|
||||
LDAPControl.MANAGEDSAIT, true, null);
|
||||
cons.addElement(manageDSAITControl);
|
||||
}
|
||||
|
||||
if (cons.size() > 0) {
|
||||
controls = new LDAPControl[cons.size()];
|
||||
cons.copyInto(controls);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println( e.toString() );
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/* perform an LDAP Search Operation */
|
||||
LDAPSearchResults res = null;
|
||||
try {
|
||||
LDAPSearchConstraints cons =
|
||||
(LDAPSearchConstraints)m_client.getSearchConstraints().clone();
|
||||
cons.setServerControls(controls);
|
||||
cons.setDereference( m_deref );
|
||||
cons.setMaxResults( m_sizelimit );
|
||||
cons.setTimeLimit( m_timelimit );
|
||||
cons.setReferrals( m_referrals );
|
||||
if ( m_referrals ) {
|
||||
setDefaultReferralCredentials( cons );
|
||||
}
|
||||
cons.setHopLimit( m_hopLimit );
|
||||
res = m_client.search( m_base, m_scope,
|
||||
m_filter, m_attrs,
|
||||
m_attrsonly, cons );
|
||||
} catch (Exception e) {
|
||||
System.err.println( e.toString() );
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
/* Sort? */
|
||||
if ( (m_sort.size() > 0) && !m_sortOnServer ) {
|
||||
String[] sortAttrs = new String[m_sort.size()];
|
||||
for( int i = 0; i < sortAttrs.length; i++ )
|
||||
sortAttrs[i] = (String)m_sort.elementAt( i );
|
||||
res.sort( new LDAPCompareAttrNames( sortAttrs ) );
|
||||
}
|
||||
|
||||
/* print out the values of the entries */
|
||||
printResults( res );
|
||||
|
||||
/* Any sort control responses? */
|
||||
showControls( m_client.getResponseControls() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the result entries.
|
||||
* @param res Search results
|
||||
*/
|
||||
private static void printResults( LDAPSearchResults res ) {
|
||||
/* print out the retrieved entries */
|
||||
try {
|
||||
/* Loop on results until finished */
|
||||
while ( res.hasMoreElements() ) {
|
||||
|
||||
LDAPEntry findEntry = null;
|
||||
try {
|
||||
/* Next directory entry */
|
||||
findEntry = (LDAPEntry)res.next();
|
||||
} catch (LDAPReferralException ee) {
|
||||
LDAPUrl[] urls= ee.getURLs();
|
||||
System.err.println("Referral entries: ");
|
||||
for (int i=0; i<urls.length; i++)
|
||||
System.err.println("\t"+urls[i].getUrl().toString());
|
||||
continue;
|
||||
}
|
||||
|
||||
String dn = findEntry.getDN();
|
||||
if (dn != null)
|
||||
printString("dn" + m_sep + " " + dn);
|
||||
else
|
||||
printString("dn" + m_sep);
|
||||
|
||||
/* Get the attributes of the entry */
|
||||
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
||||
Enumeration enumAttrs = findAttrs.getAttributes();
|
||||
/* Loop on attributes */
|
||||
while ( enumAttrs.hasMoreElements() ) {
|
||||
LDAPAttribute anAttr =
|
||||
(LDAPAttribute)enumAttrs.nextElement();
|
||||
String attrName = anAttr.getName();
|
||||
if (m_attrsonly) {
|
||||
printString(attrName+":");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Loop on values for this attribute */
|
||||
Enumeration enumVals;
|
||||
enumVals = anAttr.getByteValues();
|
||||
|
||||
if (enumVals != null) {
|
||||
while ( enumVals.hasMoreElements() ) {
|
||||
if ( m_tempFiles ) {
|
||||
try {
|
||||
FileOutputStream f = getTempFile( attrName );
|
||||
f.write( (byte[])enumVals.nextElement() );
|
||||
} catch ( Exception e ) {
|
||||
System.err.println( "Error writing values " +
|
||||
"of " + attrName + ", " +
|
||||
e.toString() );
|
||||
System.exit(1);
|
||||
}
|
||||
} else {
|
||||
byte[] b = (byte[])enumVals.nextElement();
|
||||
String s = null;
|
||||
if (LDIF.isPrintable(b)) {
|
||||
s = new String(b, "UTF8");
|
||||
printString(attrName + m_sep + " " + s);
|
||||
} else {
|
||||
ByteBuf inBuf = new ByteBuf( b, 0, b.length );
|
||||
ByteBuf encodedBuf = new ByteBuf();
|
||||
// Translate to base 64
|
||||
MimeBase64Encoder encoder = new MimeBase64Encoder();
|
||||
encoder.translate( inBuf, encodedBuf );
|
||||
int nBytes = encodedBuf.length();
|
||||
if ( nBytes > 0 ) {
|
||||
s = new String(encodedBuf.toBytes(), 0, nBytes);
|
||||
printString( attrName + ":: " + s );
|
||||
} else {
|
||||
m_pw.print( attrName + ": \n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
System.err.println("Failed to do string conversion for "+attrName);
|
||||
}
|
||||
m_pw.println();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println( e.toString() );
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void printString( String value ) {
|
||||
if (m_foldLine)
|
||||
LDIF.breakString(m_pw, value, MAX_LINE);
|
||||
else {
|
||||
m_pw.print(value);
|
||||
m_pw.print( '\n' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If there was a sort control returned, and the result code was
|
||||
* not zero, show it.
|
||||
* @param controls Any server controls returned.
|
||||
**/
|
||||
private static void showControls( LDAPControl[] controls ) {
|
||||
if ( controls == null )
|
||||
return;
|
||||
int[] results = new int[1];
|
||||
String bad = LDAPSortControl.parseResponse( controls, results );
|
||||
if ( results[0] != LDAPException.SUCCESS ) {
|
||||
System.err.println( "Error code: " + results[0] );
|
||||
if ( bad != null )
|
||||
System.err.println( "Offending attribute: " + bad );
|
||||
else
|
||||
System.err.println( "No offending attribute returned" );
|
||||
} else
|
||||
m_pw.println("Server indicated results sorted OK");
|
||||
LDAPVirtualListResponse vResponse =
|
||||
LDAPVirtualListResponse.parseResponse(controls);
|
||||
if (vResponse != null) {
|
||||
int resultCode = vResponse.getResultCode();
|
||||
if (resultCode == LDAPException.SUCCESS) {
|
||||
m_pw.println("Server indicated virtual list positioning OK");
|
||||
m_pw.println("index "+vResponse.getFirstPosition()+
|
||||
" content count "+vResponse.getContentCount());
|
||||
} else
|
||||
System.err.println("Virtual List Error: "+
|
||||
LDAPException.errorCodeToString(resultCode));
|
||||
}
|
||||
}
|
||||
|
||||
private static FileOutputStream getTempFile( String name )
|
||||
throws IOException {
|
||||
int num = 0;
|
||||
File f;
|
||||
String filename;
|
||||
do {
|
||||
filename = name + '.' + num;
|
||||
f = new File( filename );
|
||||
num++;
|
||||
} while ( f.exists() );
|
||||
printString(name + m_sep + " " + filename);
|
||||
return new FileOutputStream( f );
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal variables
|
||||
*/
|
||||
private static boolean m_attrsonly = false;
|
||||
private static int m_deref = 0;
|
||||
private static int m_scope = 2; // default is sub search
|
||||
private static int m_sizelimit = 0;
|
||||
private static int m_timelimit = 0;
|
||||
private static int verbose = 0;
|
||||
private static String m_attrs[] = null;
|
||||
private static String m_base = "o=ace industry,c=us";
|
||||
private static String m_filter = null;
|
||||
private static String m_sep = ":";
|
||||
private static Vector m_sort = new Vector();
|
||||
private static boolean m_sortOnServer = false;
|
||||
private static boolean m_tempFiles = false;
|
||||
private static int m_beforeCount = 0;
|
||||
private static int m_afterCount = 0;
|
||||
private static int m_index = 0;
|
||||
private static int m_count = 0;
|
||||
private static int m_vlvTokens = 0;
|
||||
private static String m_searchVal = null;
|
||||
private static boolean m_foldLine = true;
|
||||
private static final int MAX_LINE = 77;
|
||||
private static PrintWriter m_pw = new PrintWriter(System.out);
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
import netscape.ldap.*;
|
||||
import netscape.ldap.util.*;
|
||||
|
||||
/**
|
||||
* LDAPTool
|
||||
* Base class for LDAP command-line tools
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Rob Weltman
|
||||
**/
|
||||
class LDAPTool {
|
||||
|
||||
/**
|
||||
* This function is to extract specified parameters from the
|
||||
* arguments list.
|
||||
* @param args list of args
|
||||
*/
|
||||
protected static GetOpt extractParameters(String privateOpts, String args[]) {
|
||||
|
||||
GetOpt options = new GetOpt("vnRMD:h:O:p:w:d:V:" + privateOpts, args);
|
||||
|
||||
if (options.hasOption('n'))
|
||||
m_justShow = true;
|
||||
|
||||
if (options.hasOption('v'))
|
||||
m_verbose = true;
|
||||
|
||||
if (options.hasOption('R'))
|
||||
m_referrals = false;
|
||||
|
||||
/* -D bind DN */
|
||||
if (options.hasOption('D'))
|
||||
m_binddn = options.getOptionParam('D');
|
||||
|
||||
/* -h ldap host */
|
||||
if (options.hasOption('h'))
|
||||
m_ldaphost = options.getOptionParam('h');
|
||||
|
||||
/* -p ldap port */
|
||||
if (options.hasOption('p')) { /* if the option is -p */
|
||||
try {
|
||||
m_ldapport = Integer.parseInt(options.getOptionParam('p'));
|
||||
} catch (NumberFormatException e) {
|
||||
m_ldapport = 389;
|
||||
}
|
||||
} /* if the option is -p */
|
||||
|
||||
/* -O hop limit */
|
||||
if (options.hasOption('O')) { /* if the option is -O */
|
||||
try {
|
||||
m_hopLimit = Integer.parseInt(options.getOptionParam('O'));
|
||||
} catch (NumberFormatException e) {
|
||||
m_hopLimit = 10;
|
||||
}
|
||||
} /* if the option is -O */
|
||||
|
||||
/* -d debug level */
|
||||
if (options.hasOption('d')) { /* if the option is -d */
|
||||
try {
|
||||
m_debugLevel = Integer.parseInt(options.getOptionParam('d'));
|
||||
} catch (NumberFormatException e) {
|
||||
m_debugLevel = 0;
|
||||
}
|
||||
} /* if the option is -d */
|
||||
|
||||
/* -V ldap protocol version */
|
||||
if (options.hasOption('V')) { /* if the option is -V */
|
||||
try {
|
||||
m_version = Integer.parseInt(options.getOptionParam('V'));
|
||||
} catch (NumberFormatException e) {
|
||||
m_version = 3;
|
||||
}
|
||||
} /* if the option is -V */
|
||||
|
||||
/* -w bind password */
|
||||
if (options.hasOption('w'))
|
||||
m_passwd = options.getOptionParam('w');
|
||||
|
||||
/* -M treat ref attribute as ordinary entry */
|
||||
if (options.hasOption('M'))
|
||||
m_ordinary = true;
|
||||
return options;
|
||||
}
|
||||
|
||||
protected static void setDefaultReferralCredentials(
|
||||
LDAPSearchConstraints cons ) {
|
||||
LDAPRebind rebind = new LDAPRebind() {
|
||||
public LDAPRebindAuth getRebindAuthentication(
|
||||
String host,
|
||||
int port ) {
|
||||
return new LDAPRebindAuth(
|
||||
m_client.getAuthenticationDN(),
|
||||
m_client.getAuthenticationPassword() );
|
||||
}
|
||||
};
|
||||
cons.setReferrals( true );
|
||||
cons.setRebindProc( rebind );
|
||||
}
|
||||
|
||||
protected static int m_ldapport = 389;
|
||||
protected static String m_binddn = null;
|
||||
protected static String m_ldaphost = "localhost";
|
||||
protected static String m_passwd = null;
|
||||
protected static int m_version = 3;
|
||||
protected static int m_debugLevel = 0;
|
||||
protected static int m_hopLimit = 10;
|
||||
protected static boolean m_referrals = true;
|
||||
protected static LDAPConnection m_client = null;
|
||||
protected static boolean m_justShow = false;
|
||||
protected static boolean m_verbose = false;
|
||||
protected static boolean m_ordinary = false;
|
||||
}
|
Загрузка…
Ссылка в новой задаче