This commit is contained in:
chuckb%netscape.com 1998-09-29 05:16:18 +00:00
Родитель 53c162fe20
Коммит 2d2b3e97c7
10 изменённых файлов: 2054 добавлений и 188 удалений

Просмотреть файл

@ -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);
}
/**
@ -862,6 +960,26 @@ public class LDAPConnection implements LDAPv3, Cloneable {
*/
public void authenticate(int version, String dn, String passwd)
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 {
/* 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,7 +2199,6 @@ 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);
@ -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 );
@ -2363,7 +2541,7 @@ public class LDAPConnection implements LDAPv3, Cloneable {
*/
public void modify (String DN, LDAPModification[] mods,
LDAPSearchConstraints cons) throws LDAPException {
bind ();
bind (cons);
LDAPResponseListener myListener = getResponseListener ();
JDAPMessage response = null;
@ -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() );
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;
}
/* 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();
}
}
}
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) {
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)
m_responseControlTable.put( current, con );
else
m_responseControlTable.remove( current );
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,47 +3543,87 @@ public class LDAPConnection implements LDAPv3, Cloneable {
return;
for (int i = 0; i < u.length; i++) {
LDAPConnection connection = null;
LDAPSearchResults res = null;
try {
connection = prepareReferral( u[i], cons );
String newDN = u[i].getDN();
String DN = null;
if (newDN != null)
DN = newDN;
else
if ((newDN == null) || (newDN.equals("")))
DN = dn;
else
DN = newDN;
LDAPSearchResults res = null;
LDAPSearchConstraints newcons = (LDAPSearchConstraints)cons.clone();
newcons.setHopLimit( cons.getHopLimit()-1 );
try {
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;
}
}
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, newcons);
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, newcons);
connection.modify(dn, mods, cons);
break;
case JDAPProtocolOp.ADD_REQUEST:
connection.add(entry, newcons);
if ((dn != null) && (!dn.equals("")))
entry.setDN(dn);
connection.add(entry, cons);
break;
case JDAPProtocolOp.DEL_REQUEST:
connection.delete(DN, newcons);
connection.delete(dn, cons);
break;
case JDAPProtocolOp.MODIFY_RDN_REQUEST:
connection.rename(DN, filter /* newRDN */, attrsOnly /* deleteOld */,
newcons);
connection.rename(dn, filter /* newRDN */,
attrsOnly /* deleteOld */, cons);
break;
case JDAPProtocolOp.COMPARE_REQUEST:
boolean bool = connection.compare(DN, attr, newcons);
boolean bool = connection.compare(dn, attr, cons);
results.addElement(new Boolean(bool));
break;
default:
@ -3325,12 +3633,13 @@ public class LDAPConnection implements LDAPv3, Cloneable {
} catch (LDAPException ee) {
throw ee;
} finally {
if ((connection != null) && ((ops != JDAPProtocolOp.SEARCH_REQUEST) ||
(res == null)))
if ((connection != null) &&
((ops != JDAPProtocolOp.SEARCH_REQUEST) || (res == null)) &&
((m_referralConnection == null) ||
(!connection.equals(m_referralConnection))))
connection.disconnect();
}
}
}
/**
* Performs the referral.
@ -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)) {
JDAPMessage nextResult () {
JDAPMessage result;
synchronized( this ) {
while (searchResults.size() < 1) {
if (isResponseReceived()) {
searchResults.removeAllElements();
return null;
}
try {
wait();
} catch (InterruptedException e ) {
}
}
lastRetrieved++;
JDAPMessage result = (JDAPMessage)searchResults.elementAt (lastRetrieved);
result = (JDAPMessage)searchResults.elementAt (0);
/* Allow garbage collection to free this result */
searchResults.setElementAt (null, lastRetrieved);
searchResults.removeElementAt (0);
}
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,10 +139,9 @@ 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;
if (urls != null)
entries.addElement(new LDAPReferralException(null, 0, urls));
}
@ -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();
* 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;
}