Retrieving LDAP entries from Active Directory

Discussion in 'Java' started by Malte, Mar 19, 2005.

  1. Malte

    Malte Guest

    I am using JNDI to retrieve records from Active Directory.

    For some of the users the following snippet throws a NullPointerException:

    int userAccountControl =
    Integer.parseInt((String)att.get("userAccountControl").get());

    In fact, just this code: att.get("userAccountControl").get();
    throws an exception.

    The att object is a result of

    att = sr.getAttributes()

    where sr is a SearchResult object.

    Using an ldap browser I see nothing unusual, the userAccountControl
    attribute usually has the value 512, in some instances 514 (invalid).

    I'd like to know what might throw this exception.
     
    Malte, Mar 19, 2005
    #1
    1. Advertising

  2. Malte

    iksrazal Guest

    Malte <> wrote in message news:<423bd958$0$78280$>...
    > I am using JNDI to retrieve records from Active Directory.
    >
    > For some of the users the following snippet throws a NullPointerException:
    >
    > int userAccountControl =
    > Integer.parseInt((String)att.get("userAccountControl").get());
    >
    > In fact, just this code: att.get("userAccountControl").get();
    > throws an exception.
    >
    > The att object is a result of
    >
    > att = sr.getAttributes()
    >
    > where sr is a SearchResult object.
    >
    > Using an ldap browser I see nothing unusual, the userAccountControl
    > attribute usually has the value 512, in some instances 514 (invalid).
    >
    > I'd like to know what might throw this exception.


    Hard to say just from this code snippet and your schema description.
    Plus I only really use OpenLDAP. Even still, I'd try to log all the
    attributes when the exception is thrown, using something like...

    for (NamingEnumeration ne = attrs.getAll(); ne.hasMoreElements();)
    {
    Attribute attr = (Attribute)ne.next();
    String attrID = attr.getID();
    System.out.println (attrID+":");
    for (Enumeration vals = attr.getAll();vals.hasMoreElements();)
    {
    System.out.println ("\t"+vals.nextElement());
    }
    }

    Since you only get the error sometimes, one of your fields must be
    unexpectedly null, ie, my guess is that your data is not always
    organized as expected.

    For what its worth, I do something like:

    /**
    Gets a java object from LDAP associated by a distiguished name.
    <p>
    This method is inteneded to be used for schemas like inetOrgPerson
    for attributes
    such as userCertificate;binary
    <p>
    @param type Which attribute to search for and return
    @param results Complete list of all available entries for the
    requested DN
    @return Object or null if there are problems
    */
    private Object doLookup (NamingEnumeration results, String type)
    throws WSSecurityException
    {
    try
    {
    Fwlog.debug(this, Fwlog.DB, "doLookup...");
    if (results.hasMore())
    {
    SearchResult sr = (SearchResult) results.next();
    javax.naming.directory.Attributes xanswer =
    sr.getAttributes();
    javax.naming.directory.Attribute attribute =
    xanswer.get(type);
    // check if attribute missing
    if (null==attribute)
    {
    throw new IllegalStateException("\nERROR: Attribute type not
    found: " + type);
    }

    // retrieve attribute as object and return
    Object o = attribute.get();
    if (null == o)
    {
    throw new IllegalStateException("Recieved null object for
    attribute type: " + type);
    }

    return o;
    }
    else
    {
    throw new IllegalStateException("Empty Subject recieved");
    }
    }//end try
    catch ( Exception e )
    {
    Fwlog.error(this, Fwlog.DB, "doLookup() failed for for type: " +
    type);
    Fwlog.error(this, Fwlog.DB, e);
    }
    }

    HTH,
    iksrazal
    http://www.braziloutsource.com/
     
    iksrazal, Mar 19, 2005
    #2
    1. Advertising

  3. Malte

    Nigel Wade Guest

    Malte wrote:

    > I am using JNDI to retrieve records from Active Directory.
    >
    > For some of the users the following snippet throws a NullPointerException:
    >
    > int userAccountControl =
    > Integer.parseInt((String)att.get("userAccountControl").get());
    >
    > In fact, just this code: att.get("userAccountControl").get();
    > throws an exception.
    >
    > The att object is a result of
    >
    > att = sr.getAttributes()
    >
    > where sr is a SearchResult object.
    >
    > Using an ldap browser I see nothing unusual, the userAccountControl
    > attribute usually has the value 512, in some instances 514 (invalid).
    >
    > I'd like to know what might throw this exception.


    From the limited code and description it's impossible to give a definitive
    answer.

    But the error means that either att is null, or that att.get() returned
    null. Since you haven't told us what either of them we can only speculate
    as to why they are null.

    NOTE: if att is of type Attributes then Attributes.get() can return null, as
    can Attribute.get().

    --
    Nigel Wade, System Administrator, Space Plasma Physics Group,
    University of Leicester, Leicester, LE1 7RH, UK
    E-mail :
    Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
     
    Nigel Wade, Mar 21, 2005
    #3
  4. Malte

    Malte Guest

    Nigel Wade wrote:
    >
    >
    > From the limited code and description it's impossible to give a definitive
    > answer.
    >
    > But the error means that either att is null, or that att.get() returned
    > null. Since you haven't told us what either of them we can only speculate
    > as to why they are null.
    >
    > NOTE: if att is of type Attributes then Attributes.get() can return null, as
    > can Attribute.get().
    >



    att is not null. att.get() returns null. All other fields in the att
    variable can be queried. Only the userAccountControl cannot. The
    userAccountControl field has the value 512 (verified using ldab browser).

    Actually, att.get() throws an exception, just trying to query the darned
    thing, that is what worries me.
     
    Malte, Mar 21, 2005
    #4
  5. Malte

    Nigel Wade Guest

    Malte wrote:

    > Nigel Wade wrote:
    >>
    >>
    >> From the limited code and description it's impossible to give a

    definitive
    >> answer.
    >>
    >> But the error means that either att is null, or that att.get() returned
    >> null. Since you haven't told us what either of them we can only speculate
    >> as to why they are null.
    >>
    >> NOTE: if att is of type Attributes then Attributes.get() can return null,

    as
    >> can Attribute.get().
    >>

    >
    >
    > att is not null. att.get() returns null. All other fields in the att
    > variable can be queried. Only the userAccountControl cannot. The
    > userAccountControl field has the value 512 (verified using ldab browser).


    Did you request it in the list of return attributes?
    Does the user you bind to the LDAP server have permission to read or search
    that attribute?

    >
    > Actually, att.get() throws an exception, just trying to query the darned
    > thing, that is what worries me.


    What exception?

    --
    Nigel Wade, System Administrator, Space Plasma Physics Group,
    University of Leicester, Leicester, LE1 7RH, UK
    E-mail :
    Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
     
    Nigel Wade, Mar 22, 2005
    #5
  6. Malte

    Malte Guest

    Nigel Wade wrote:
    >
    > Did you request it in the list of return attributes?
    > Does the user you bind to the LDAP server have permission to read or search
    > that attribute?


    No, I did not use the return attributes way of querying ldap. The user I
    use to bind has permission to read all attributes and retrieve up to
    8000 entries (the server has less than 6000).

    Not using a list of return attributes should give me all? Or is this
    where the mistake is?

    >
    >
    >>Actually, att.get() throws an exception, just trying to query the darned
    >>thing, that is what worries me.

    >
    >
    > What exception?
    >


    NullPointerException.
     
    Malte, Mar 22, 2005
    #6
  7. Malte

    Malte Guest

    Malte wrote:
    > Nigel Wade wrote:
    >
    >>
    >> Did you request it in the list of return attributes?
    >> Does the user you bind to the LDAP server have permission to read or
    >> search
    >> that attribute?

    >
    >
    > No, I did not use the return attributes way of querying ldap. The user I
    > use to bind has permission to read all attributes and retrieve up to
    > 8000 entries (the server has less than 6000).
    >
    > Not using a list of return attributes should give me all? Or is this
    > where the mistake is?
    >
    >>
    >>
    >>> Actually, att.get() throws an exception, just trying to query the
    >>> darned thing, that is what worries me.

    >>
    >>
    >>
    >> What exception?
    >>

    >
    > NullPointerException.

    I should add that my program has run without a hitch for approx. 13
    months. I never changed this part of the program, and the JDK used is
    the same. The customer swears they did not change anything in Active
    Directory. Obviouslly, at least one of these statements has to be false ;-)
     
    Malte, Mar 22, 2005
    #7
  8. Malte

    Nigel Wade Guest

    Malte wrote:

    > Nigel Wade wrote:
    >>
    >> Did you request it in the list of return attributes?
    >> Does the user you bind to the LDAP server have permission to read or

    search
    >> that attribute?

    >
    > No, I did not use the return attributes way of querying ldap. The user I
    > use to bind has permission to read all attributes and retrieve up to
    > 8000 entries (the server has less than 6000).
    >
    > Not using a list of return attributes should give me all? Or is this
    > where the mistake is?


    It should return all the readable attributes.
    How are you querying the ActiveDirectory, and how are you enumerating the
    returned results?

    >
    >>
    >>
    >>>Actually, att.get() throws an exception, just trying to query the darned
    >>>thing, that is what worries me.

    >>
    >>
    >> What exception?
    >>

    >
    > NullPointerException.


    I presume that att it of class BasicAttributes? att.get(String) method
    should not result in a NullPointerException unless att itself is null, or,
    perhaps if the argument string is null (the docs say that the argument must
    be non-null).


    --
    Nigel Wade, System Administrator, Space Plasma Physics Group,
    University of Leicester, Leicester, LE1 7RH, UK
    E-mail :
    Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
     
    Nigel Wade, Mar 31, 2005
    #8
  9. Malte

    Malte Guest

    Nigel Wade wrote:
    > Malte wrote:
    >
    >


    The basic process is this:

    1. Get a DirContext (OK)

    2. Call this function:

    private NamingEnumeration getAlladUsers(DirContext ctx) throws Exception {
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    // next two statements get data from a Properties file
    String filter = basicProperties.getProperty("sourceSearchFilter");
    String searchLevel =
    basicProperties.getProperty("sourceSearchFromLevel");
    answer = ctx.search(searchLevel, filter, ctls);

    return answer;
    }

    3. Process the NamingEnumeration

    // some code removed because it is redundant (to this snippet)

    while (adList.hasMore()) { // for each record // adList is the
    "answer" NamingEnumeration returned form the getAlladUser method.

    sr = (SearchResult)adList.next(); // get the SearchResult object
    att = sr.getAttributes(); // get the Attributes object

    if (att == null) {
    continue;
    }

    tmp = (String)att.get("cn").get(); // save the "cn" value
    if (tmp == null) {
    continue;
    }

    String sAMA = (String)att.get("sAMAccountName").get();

    if (sAMA == null) {
    continue;
    }

    int validUser = 512;
    int inactiveUser = 2;
    int userAccountControl =
    //!!!!!!!!!!! This is where it bombs out. Even
    att.get("userAccountControl").get() returns null, so it is not related
    to the Integer.parseInt() call
    Integer.parseInt((String)att.get("userAccountControl").get());
    if (
    (validUser == (userAccountControl & validUser)) &&
    (inactiveUser != (userAccountControl & inactiveUser))
    ) {

    // rest of the code is more of the same
     
    Malte, Mar 31, 2005
    #9
  10. Malte

    Nigel Wade Guest

    Malte wrote:

    > Nigel Wade wrote:
    >> Malte wrote:
    >>
    >>

    >
    > The basic process is this:
    >
    > 1. Get a DirContext (OK)
    >
    > 2. Call this function:
    >
    > private NamingEnumeration getAlladUsers(DirContext ctx) throws Exception {
    > SearchControls ctls = new SearchControls();
    > ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    > // next two statements get data from a Properties file
    > String filter = basicProperties.getProperty("sourceSearchFilter");
    > String searchLevel =
    > basicProperties.getProperty("sourceSearchFromLevel");
    > answer = ctx.search(searchLevel, filter, ctls);
    >
    > return answer;
    > }
    >
    > 3. Process the NamingEnumeration
    >
    > // some code removed because it is redundant (to this snippet)
    >
    > while (adList.hasMore()) { // for each record // adList is the
    > "answer" NamingEnumeration returned form the getAlladUser method.
    >
    > sr = (SearchResult)adList.next(); // get the SearchResult object
    > att = sr.getAttributes(); // get the Attributes object
    >
    > if (att == null) {
    > continue;
    > }
    >
    > tmp = (String)att.get("cn").get(); // save the "cn" value
    > if (tmp == null) {
    > continue;
    > }
    >
    > String sAMA = (String)att.get("sAMAccountName").get();
    >
    > if (sAMA == null) {
    > continue;
    > }
    >
    > int validUser = 512;
    > int inactiveUser = 2;
    > int userAccountControl =
    > //!!!!!!!!!!! This is where it bombs out. Even
    > att.get("userAccountControl").get() returns null, so it is not related
    > to the Integer.parseInt() call
    > Integer.parseInt((String)att.get("userAccountControl").get());
    > if (
    > (validUser == (userAccountControl & validUser)) &&
    > (inactiveUser != (userAccountControl & inactiveUser))
    > ) {
    >
    > // rest of the code is more of the same


    That all looks perfectly fine.

    In your comment above you say that att.get("userAccountControl").get()
    returns null. Do you really mean that, or is it that
    att.get("userAccountControl") returns null, and
    att.get("userAccountControl").get() throws NullPointerException? I could
    understand that. If "userAccountControl" isn't found in the list of
    attributes for the entry then att.get("userAccountControl") will return
    null, so attempting to invoke <null>.get() will throw the Exception.

    Can you verify the case of "userAccountControl" in the entry? It might be a
    simple failure to match on case. I use the BasicAttributes(true) method of
    searching which performs case insensitive search. I can't spot a similar
    method of specifying case insensitive search using SearchControls though.
    Of course, this might be a red herring...

    --
    Nigel Wade, System Administrator, Space Plasma Physics Group,
    University of Leicester, Leicester, LE1 7RH, UK
    E-mail :
    Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
     
    Nigel Wade, Apr 1, 2005
    #10
  11. Malte

    Malte Guest

    Nigel Wade wrote:

    >
    > That all looks perfectly fine.
    >
    > In your comment above you say that att.get("userAccountControl").get()
    > returns null. Do you really mean that, or is it that
    > att.get("userAccountControl") returns null, and
    > att.get("userAccountControl").get() throws NullPointerException? I could
    > understand that. If "userAccountControl" isn't found in the list of
    > attributes for the entry then att.get("userAccountControl") will return
    > null, so attempting to invoke <null>.get() will throw the Exception.
    >
    > Can you verify the case of "userAccountControl" in the entry? It might be a
    > simple failure to match on case. I use the BasicAttributes(true) method of
    > searching which performs case insensitive search. I can't spot a similar
    > method of specifying case insensitive search using SearchControls though.
    > Of course, this might be a red herring...
    >


    Thank you for your reply. The userAccountControl attribute is the same,
    including case, for all 5000 entries in Active Directory. I have
    verified, using ldapbrowser that the value is '512'. My program bombs
    out for approx. 80% of the 5000 entries. Always when querying the
    userAccountControl attribute, which ALWAYS has a value, sometimes 512,
    sometimes 514 (inactive user), and sometimes other values.

    Just this call att.get("userAccountControl").get() throws the
    nullpointer exception, which baffles me, because the result should be
    just null, it should not throw an exception.

    I have been wondering if I should set my queries up specifying exactly
    which attributes I want, but as it is I get them all and query only
    approx. 12 of them (title, l, streetAddress, department,
    physicalDeliveryAddress, etc.).
     
    Malte, Apr 1, 2005
    #11
  12. Malte

    Nigel Wade Guest

    Malte wrote:

    > Nigel Wade wrote:
    >
    >>
    >> That all looks perfectly fine.
    >>
    >> In your comment above you say that att.get("userAccountControl").get()
    >> returns null. Do you really mean that, or is it that
    >> att.get("userAccountControl") returns null, and
    >> att.get("userAccountControl").get() throws NullPointerException? I could
    >> understand that. If "userAccountControl" isn't found in the list of
    >> attributes for the entry then att.get("userAccountControl") will return
    >> null, so attempting to invoke <null>.get() will throw the Exception.
    >>
    >> Can you verify the case of "userAccountControl" in the entry? It might be

    a
    >> simple failure to match on case. I use the BasicAttributes(true) method

    of
    >> searching which performs case insensitive search. I can't spot a similar
    >> method of specifying case insensitive search using SearchControls though.
    >> Of course, this might be a red herring...
    >>

    >
    > Thank you for your reply. The userAccountControl attribute is the same,
    > including case, for all 5000 entries in Active Directory. I have
    > verified, using ldapbrowser that the value is '512'. My program bombs
    > out for approx. 80% of the 5000 entries. Always when querying the
    > userAccountControl attribute, which ALWAYS has a value, sometimes 512,
    > sometimes 514 (inactive user), and sometimes other values.
    >
    > Just this call att.get("userAccountControl").get() throws the
    > nullpointer exception, which baffles me, because the result should be
    > just null, it should not throw an exception.


    As I've said before, this will throw NullPointerException if
    userAccountControl is not one of the attributes returned by the search. You
    must test the return value of Attributes.get(String) invocation for null,
    before you attempt to get the actual value with the second invocation of
    Attribute.get().

    >
    > I have been wondering if I should set my queries up specifying exactly
    > which attributes I want, but as it is I get them all and query only
    > approx. 12 of them (title, l, streetAddress, department,
    > physicalDeliveryAddress, etc.).


    Is it always the same entries which cause the problem? What happens if you
    restrict the search so that only a few entries are returned, but include
    those which cause the problem?

    I would use a network protocol analyser and look at what is actually being
    returned by the LDAP server, provided it's not encrypted.


    --
    Nigel Wade, System Administrator, Space Plasma Physics Group,
    University of Leicester, Leicester, LE1 7RH, UK
    E-mail :
    Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
     
    Nigel Wade, Apr 5, 2005
    #12
  13. Malte

    Malte Guest

    Nigel Wade wrote:
    > Malte wrote:
    >
    >
    >>Nigel Wade wrote:
    >>
    >>
    >>>That all looks perfectly fine.
    >>>
    >>>In your comment above you say that att.get("userAccountControl").get()
    >>>returns null. Do you really mean that, or is it that
    >>>att.get("userAccountControl") returns null, and
    >>>att.get("userAccountControl").get() throws NullPointerException? I could
    >>>understand that. If "userAccountControl" isn't found in the list of
    >>>attributes for the entry then att.get("userAccountControl") will return
    >>>null, so attempting to invoke <null>.get() will throw the Exception.
    >>>
    >>>Can you verify the case of "userAccountControl" in the entry? It might be

    >
    > a
    >
    >>>simple failure to match on case. I use the BasicAttributes(true) method

    >
    > of
    >
    >>>searching which performs case insensitive search. I can't spot a similar
    >>>method of specifying case insensitive search using SearchControls though.
    >>>Of course, this might be a red herring...
    >>>

    >>
    >>Thank you for your reply. The userAccountControl attribute is the same,
    >>including case, for all 5000 entries in Active Directory. I have
    >>verified, using ldapbrowser that the value is '512'. My program bombs
    >>out for approx. 80% of the 5000 entries. Always when querying the
    >>userAccountControl attribute, which ALWAYS has a value, sometimes 512,
    >>sometimes 514 (inactive user), and sometimes other values.
    >>
    >>Just this call att.get("userAccountControl").get() throws the
    >>nullpointer exception, which baffles me, because the result should be
    >>just null, it should not throw an exception.

    >
    >
    > As I've said before, this will throw NullPointerException if
    > userAccountControl is not one of the attributes returned by the search. You
    > must test the return value of Attributes.get(String) invocation for null,
    > before you attempt to get the actual value with the second invocation of
    > Attribute.get().
    >
    >
    >>I have been wondering if I should set my queries up specifying exactly
    >>which attributes I want, but as it is I get them all and query only
    >>approx. 12 of them (title, l, streetAddress, department,
    >>physicalDeliveryAddress, etc.).

    >
    >
    > Is it always the same entries which cause the problem? What happens if you
    > restrict the search so that only a few entries are returned, but include
    > those which cause the problem?
    >
    > I would use a network protocol analyser and look at what is actually being
    > returned by the LDAP server, provided it's not encrypted.
    >
    >

    You have given a couple of pointer, that I will follow up on. Thanks a
    lot for helping.
     
    Malte, Apr 5, 2005
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Marty Underwood

    Active Directory using LDAP query

    Marty Underwood, Nov 27, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    634
    Marty Underwood
    Nov 27, 2003
  2. Andrew
    Replies:
    1
    Views:
    614
    Kevin Spencer
    Jun 24, 2004
  3. tangus via DotNetMonster.com

    Problem retrieving Active Directory users

    tangus via DotNetMonster.com, Sep 30, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    2,825
    S. Justin Gengo
    Oct 1, 2005
  4. Don Bruder
    Replies:
    3
    Views:
    1,022
    spikeysnack
    Aug 3, 2010
  5. L Magarian
    Replies:
    3
    Views:
    240
    Joe Kaplan \(MVP - ADSI\)
    Sep 28, 2004
Loading...

Share This Page