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

Re: Java LDAP API issues



Steven Sonntag wrote:

> 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.
>

  Cool. I'll add a little to the remaining ones.


> > 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() ??

  OK


>
> > 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.

  For LDAPUrl? Do we need it there if referrals are only reported as strings?


> > 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.
>

  Let me look into that a little.

> > 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.

  OK

>
>
> > >  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.

  OK

>
> > 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.

  OK


> > 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.

  Sounds reasonable, but let me think about it a little more.


> > 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?

  True. 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.

  I'm working on that area, too - as spec lead for JSR 28 in the JCP. I think it's a general SASL question, not one specific to the LDAP API. I'll need a little more time to clarify this item.

> > 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?
>

  I don't think so. It is not persistent in the connection.

>
> What is contained in HashTable if not the credentials??

  See http://www.ietf.org/internet-drafts/draft-weltman-java-sasl-03.txt, pages 7 - 8.

> > 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.

  I need to think about that some more.

> > 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?

  That's what is used in our implementation, but I don't think it matters - the client of the API should call getURLs() (or now, getReferrals()) to get the referrals. The client shouldn't need to know how they are stored internally.

Rob