[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