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

Re: Java LDAP API issues



A few remaining comments

Rob Weltman wrote:

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

Are you thinking to eliminate the LDAPUrl class?
IMO it is certainly very useful when one needs to break apart a URL.
Connection.search( LDAPURL toGet) needs it, which I believe to
be a very useful function. An application doing its own referral
following certainly needs to break referrals apart, and what better
way than with the LDAPUrl class.  It makes a very nice utility class.
I say keep it.

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

I think bind() just has the wrong return type.

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

OK - seems reasonable to me also.

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

I'm just trying to figure out how to solve the problem of multiple connections,
each with different connection characteristics, perhaps different users.
When doing an explicit bind, how does the application get credentials
specifiic to that connection/user.  Would the callback handler being
persistent help solve this, or ??

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

Thanks, I had missed that one.

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

--
------------------------
Steve Sonntag
Novell, Inc., the leading provider of Net services software