[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: Java LDAP API issues



Rob,

Here are my responses to all of the issues except two.  Those I will
address in a separate e-mail.
In the responses below, I have elimated the text except the number and
first sentence of the topic for most
of my "OK" responses.  Those where I had more than an OK comment, are
quoted more fully.

Thanks for your time.

-Steve

Rob Weltman wrote:

>   I've collected all the issues raised (hope I didn't miss any) and
> responded in short to each one. Many thanks to Miodrag for helping me
> evaluate the issues. And to Steve and Steven for raising them :-)
>
> Rob
>
>
> 1.
> > Section 4.39.13 LDAPV2.setOption ...

OK

>
> >   2) STRING_FORMAT is set only by the setOption method. ...

OK

>
> >   3) setOption operates only on the LDAPSearchConstraints object ...

See separate e-mail

>
> >   4) All functionality of SetOption can be performed by code ...

OK

>
> 2.
> > If references to LDAPv2 are not removed from the draft, ...

OK

> 3.
> >
> >  In the java-api-11 I-D, an application doing asynchronous search
> >  operations is confronted with two different data formats when
> handling
> >  referrals and search continuation references.
> >
> >  When the application gets a referral status on a search operation,
> >  referral URL information is retrieved by
> LDAPResponse.getReferrals()
> >  as an array of String objects.
> >
> >  When the application gets search continuation references as part of
>
> >  the search data, the continuation references are retrieved by
> >  LDAPSearchResultReference.getURLs() as an array of LDAPUrl objects.
>
> >
> >  To be consistent, shouldn't both return an array of LDAPUrl
> objects?
>
> Returning String[] seems more flexible. Steve has recognized that in
> one of his comments following this one. "...This is because the only
> way to get the list is via the getURLs() method of the
> LDAPSearchResultReference.Perhaps it should return the  URLs as a
> string array, and let the applicationturn them into LDAPUrl objects if
> desired.  This is backwards to what I said in an earlier e-mail,
> butnow I see the need for Strings instead of LDAPUrls".
>
> So let's return String[] in both cases.

Should the method names be unified, i.e. use getReferrals() instead of
getUrls() ??

> 4.
> > An application doing its own referral handling may need to make
> >  decisions based on the scheme of URLs returned from search
> >  continuation references or referrals.
> >
> >  Shouldn't the LDAPUrl object provide a method to retrieve
> >  the URL scheme, viz. ldap, http, & etc.
>
> This is an LDAP only URL and not a generic URL, so there is no reason
> to report a URL scheme. However, there is a need to support ldaps with
> some LDAP servers. To accomodate them, we propose a boolean method
> isSecure().

OK - Don't forget toadd this field to the constructors.

> 5.
> > I am puzzled why the draft specifies that automatic referral ...

OK

> 6.
> > Re: referrals as defined in draft-ietf-ldapext-ldap-java-api-11.txt
> >
> >  The I-D seems silent on what happens if an application has
> automatic
> >  referral handling enabled, and for some reason one or more of the
> >  referrals or search continuation references cannot be followed.

OK

> 7.
> >
> >  I would like clarification on how LDAPBind vs LDAPRebind objects
> >  are used in the Java API.
> >
> >  The I-D implies, but never quite says that the two objects don't
> >  normally exist in the LDAPConstraints object at the same time.
> >  (Implied by Appendix G - LDAPConstraints - they should
> >  not be specified on the same constructor)
> >
> >  They certainly can both be set by using the set methods, but
> >  are probably not both used at the same time.
> >
> >  I surmise from the draft that these objects are used as follows:
> >
> >  1. Neither object is used unless Referrals are enabled in the
> >      LDAPConstraint object (automatic referral following enabled).
> >
> >  2. An LDAPRebind object is used only if present and if an LDAPBind
> >      object is not present in the LDAPConstraint object.
> >
> >  3. An LDAPBind object is used if present.  If present, the
> LDAPRebind
> >      object is not needed by LDAPConnection as no implicit binding
> is done.
> >      Explicit binding is the responsibility of the LDAPBind object.
> Therefore
> >      the LDAPRebind object is not used in this case.
> >
> >  If my guesses are correct, maybe the draft should be clarified as
> to the
> >  usage of these objects.
>
> This is a correct interpretation. An improvement to the I-D would be
> be to specify a single field in LDAPConstraints - rebindHandler -
> which would accept either LDAPBind or LDAPRebind. An additional tag
> interface would need to be declared, somthing like this:
>
> public interface LDAPReferralHandler {  // the tag interface
> }
>
> public class LDAPConstraints {
>      private LDAPReferralHandler rebindProc;
>      ...
> }
>
> public interface LDAPBind extends LDAPReferralHandler {
> ...
> }
>
> public interface LDAPRebind extends LDAPReferralHandler {
> ...
> }

My only objection to this is that I had it in mind that the application
may want to use
the LDAPRebindProc to provide credentials for the LDAPBind.bind()
method.
It is reasonable to think an application might do this??  Having one
object certainly
makes it simpler for the application writer to understand the behavior.

So, OK, I agree.

> 8.
> > Re: LDAPBind as defined in draft-ietf-ldapext-ldap-java-api-11.txt

OK

> >  It seems that the LDAPRebind interface would be easier to implement
> if
> >  additional data were provided in the new LDAPConnection object.
> Such as:

( ... )

>   If it really is required (which duplicates what you can do with
> LDAPBind), how about the following instead (let the implementation
> pull whatever it needs from the original connection, as LDAPBind
> does)?
>
> LDAPConnection bind(String ldapurl, LDAPConnection origConn);

But LDAPBind doesn't - it returns a void.  If you change it to the
above,
i.e. returns LDAPConnection (the new connection) then - OK.

>
> 9.  (from Kurt)
> > You might consider renaming getSubTypes to getOptions as
> > not all options (e.g. ;binary) are subtypes.
>
>   Not worth changing, I don't think.

OK

> 10.
> > The I-D interchanges referrals and search continuation references.

OK

> 11.
> > Resend - properly indicating where comments are

OK

> 12.
> > Re: Referrals on operations as defined
> >        in draft-ietf-ldapext-ldap-java-api-11.txt

OK

> 13.

OK

> Let's remove the method from the I-D. It's just a convenience.

OK

> 14.
> >
> >  I think the draft should describe more fully the
> >  semantics of the implicit bind w/r automatic referral following:
> >
> >  I will describe what the I-D describes and where
> >  I have questions:
> >
> >  1. Authentication - uses anonomyous credentials unless
> >     LDAPRebind specified in LDAPConstraints.

OK

>
> >  2. Protocol Version ?? - Does it use the same protocol

As long as it is added to the constraints so it can be retrieved.


> >  3. AuthenticationMethod: Is it the same as the originating
> connection,
> >      or is it "simple" - I assume simple is used.

OK

> >  4. Does it use the LDAPSocketFactory if specified on the
> >      originating connection.  I am not sure what to do here.
> >      It seems better to use it if available, then an encrypted
> >      connection can be established and thus prevent
> >      clear text password transmittion on the wire.  I just
> >      talked myself into it - it should be used.
>
> If the referral ldap url specifies ldaps, the referral connection
> should use ldaps (regardless of the original connection). At least in
> our implementation :-) - since ldaps is being deprecated in favor of
> startTLS, we may not want to mention it in this I-D (I just remembered
> that I owe LDAPEXT an informational RFC draft on ldaps). For startTLS,
> I guess the referral connection should attempt to use startTLS if the
> original connection was in startTLS mode. Is there any other way to
> determine whether or not to use startTLS?

IMO the application if the connection is in startTLS mode, the new
connections should also be startTLS.  Likewise,
LDAPBind.bind() needs to be able to determine if the connection is in
startTLS mode so it can also do startTLS, thus
the app needs to be able to query if the connection is in startTLS mode.

> 15.
> >  When performing a search it is possible for the server ...

OK - Just fix the wording a little to reflect this.  4.35.4
. the last time it is called ..
seems pretty final, when it really means all referral
exceptions are the last elements of the enumeration.

> 16.
> >
> >  Since LDAPResponseListener and LDAPSearchListener
> >  objects implement exactly the same set of methods,
> >  does it seem reasonable that an interface be created
> >  named something like LDAPListener that specifies
> >  those four methods, and that LDAPSearchListener
> >  and LDAPResponseListener implement this interface.
> >  This forces those methods to stay the same in both classes.
> >
>
> > If an LDAPListener interface were created, then
> > the two methods in LDAPv2.abandon
> >
> >    public void abandon(LDAPSearchListener listener)
> >    public void abandon(LDAPResponseListener listener)
> >
> > Could be combined into one
> >
> >    public void abandon(LDAPListener listener)
>
> We have responded to this earlier, but here is a brief recap. In the
> very first asynch draft, LDAPSearchListener extended
> LDAPResponseListener. Later when we adding abandon(int) method, we
> investigated removing LDAPSearchListener and leaving only
> LDAPResponseListener because there were implementation issues
> (multiplexing, and raising exceptions as a result of a lost
> connection). Then, in order not to change the draft considerably, we
> decided to make only minor changes and just resolve the implementation
> problems. We kept LDAPSearchListener, but it does not extend
> LDAPResponseListener any more.

I get the feeling we are talking about different things.
I wasn't describing LDAPSearchListener extending LDAPResponseListener,
but both
implementing a common interface, viz. LDAPListener, with methods
getMessageIDs(), getResponse(), isResponseReceived(),
and merge().  All four of  the methods of each class have identical
signatures.  Doing this reduces abandon to one call, which
can easily do exactly what it is doing now by using the instanceof
operator.

> 17.
> >
> >  4.6.19 setConstraints

See separate e-mail, same as 1.3

> 18.
> >
> >  4.39.1 LDAPv2.abandon
> >
> >  The RFC 2251 and the C api draft allow controls to be specified
> >  on an abandon operation.  In java it is allowed only using the
> default
> >  constraints object or search constraints object.  Should methods
> >  be defined that allow constraints to be specified on abandon?
>
> Strictly speaking this is true, but if we look at the properties in
> LDAPConstraints, none of them are applicable to abandon(). This change
> is not required.

Suppose an application needed to put a control on an abandon operation.
What then?

> 19.
>
>> The JAVA LDAP API (draft-ietf-ldapext-ldap-java-api-11.txt) defines
>> the following method for
>> extended operations:
>
OK

> 20.
>
>>  Section 4.7.11 LDAPConstraints.setTimeLimit
>
OK

> 21
> LDAPSortKey.

OK

> 22.
>
>> Re: LDAP_PARTIAL_RESULTS Result Code defined in
>
OK

>> 23.
>
>> In the Bibliography, [3] refers to RFC 1960.
>
OK

> 24.
>
>
>>  4.40.1
>
OK

>>  What does it mean -
>>
>>     if the first version of the method (i.e. the one that specifies no mechanism)
>>     is called, the LDAP server will be interrogated for its
>>     supportedSaslMechanisms attribute of its root DSE.
>>
>>  What does it do after the LDAP server is interrogated?  Does it use one
>>  of them, and if so how does the application know which one is used
>>  and how does it know what kind of credentials to supply?
>>
>
> Yes, if no mechanisms are specified, the mechanisms supported by the
> server are processed until one is mutually agreed on. The callback
> handler is called to obtain credentials. Are you thinking that the
> credentials to be returned depend on the mechanism being negotiated?
> Let me think about that a little...

That is what I am thinking.  Is perhaps the ChoiceCallback used in some
way to communicate the negogiated choice, or to
influence the negotiation possibilities the app will accept?  This area
is pretty new to me.

> 25.
>
>>  4.40.1 bind specifying a mechanism
>>
>>  It would seem that if the mechanism is "simple"
>>  that the API should specify how the password
>>  is to be specified in the Hashtable object props
>>  so that it is consistent across implementations.
>>  Other mechanisms and associated Hashtable
>>  values are the subject of other I-Ds.
>>
>>
>>  My suggestions:
>>
>>        props.put("password", new String("user-password-value");)
>>
>
>   Credentials are obtained from the callback handler.

I was thinking of the same semantics as getPasswd() where the original
credentials were
contained in the HashTable.  But as you say, the credentials should be
obtained
from the callbackHandler. If the application is handling multiple
connections each with different characteristics and possibly different
users, it would need
a different callback handler for each connection.  The callback handler
needs to be
available for implicit bind and explicit bind, and needs to be set in
the new connection by
the explicit bind method.  Do we need a mechanism them to get the
callbackHandler?

What is contained in HashTable if not the credentials??

> 26.
>
>
>> Shouldn't the SASL bind mechanisms also support the ability
>> for the application to specify an LDAPConstraints
>> object so that call specific controls can be specified?
>>

OK

> 27.
>
>> When using an explicit bind for referrals where sasl mechanisms
>> were used on the original LDAPConnection, the LDAPBind.bind()
>> method will need access to the Hashtable parameter passed on the
>> bind to get the credentials used.  A method needs to be
>> supplied in LDAPConnection to get the Hashtable object with
>> semantics similar to what is now used for getAuthenticationPassword()
>>
>
>   Does it need to be a public method? Can't it be a package scope
> (implementation-defined) method?

I was thinking it does need to be a public method as the explicit Bind
method may need access to it.

>
>
> 28.
>
>> I am trying to understand the encode/decode functions
>>  in the LDAPUrl class.
>
OK

> 29.
>
>> 4.16 LDAPException
>>
>>  The LDAPException class has a method getMatchedDN() but has no way to set
>>  the matched DN in the object.  Shouldn't there be a constructor with MatchedDN
>>  as a parameter?
>>
> (...)
>   Is that realistic - that a class in some other package would create
> an exception and put in its own matchedDN?

You are right, I was not thinking straight on this one.

>
>
> 30.
>
>> 4.26 LDAPException
>>
>>  I am trying to understand where the information in the
>>  constructor serverMessage comes from.  I am not
>>  aware of any message that is returned by the server with a
>>  referral result, except for the actual referral URLs.
>>
>>  Do you intend that the class gets primed with the
>>  referral URLs using the serverMessage parameter
>>  and if so how are the referrals delimited - otherwise
>>  can you elaborate on the meaning of this parameter
>>  and explain how the referral URLs are placed into the
>>  class.
>>
>
>   That is correct. The server returns the referral URLs in the message
> field. I don't know if it is necessary to define the representation
> there (it is a contract between the upper layer of an implementation
> and the BER decoding layer - which is not defined in the I-D); clients
> query getURLs() to get the URLs.
>

A ldap_result  is made up of errmsg, referral, result, matched-dn.  Were
you thinking of the error message field for ServerMessage?

>
>
> 31.
>
>> In draft-ietf-ldapext-ldap-c-api-04.txt section 11.6 Searching, it
>> states:
>
OK

>
> 32.
>
>> Also, in the Bibliograpy, [7] should be updated. (To draft-ietf-ldapext-ldap-c-api-04.txt)
>>
>   OK.

OK