Retrieving a JNDI dn with its proper case - ldap

I want to retrieve a user DN as stored in the LDAP server, keeping the original characters case. For example, let's assume the DN in my server is "cn=Bob, o=MyOrg". I want to query the server using "cn=bob, o=myorg" and retrieve the original "cn=Bob, o=MyOrg", as a result.
The DirContext.getAttributes(dn) method can return a set of attributes but this does not include the DN itself. On the other hand, DirContext.search() returns a SearchResult that has this information using getNameInNamespace(). Unfortunately, search expressions do not seem to allow search on DN, which is what I have.
I understand that I might achieve this by first retrieving a unique attribute using getAttributes(), and then use this attribute value in search(). But this leads to 2 connections. Plus I need to make sure that I have a unique, not null, attribute I can search() on.

Let me reply to my question with the solution I found.
It involves the search() function, where the name parameter (search context) should be the DN, and the query filter is empty or like (objectClass=*). It then returns one row, corresponding to the DN being searched. The original DN is then available in the SearchResult.

Just do a lookup of the DN. The resulting DirContext should have its getNameInNamespace() in the correct case.
A search will also work but it's less efficient and more code.

Related

What is the correct way of adding parameter to ignore case for search text in a REST API

I have an API endpoint to retrieve all users. There are 3 query parameters for searching/filtering the results as follows.
GET /users?name=test&age=23&area=abc
Now I want to introduce an option to ignore the case when searching for the name parameter. For example, the above API call should return even if the name equals Test or tesT.
What's the correct way of implementing this option? Adding another query parameter or is there any better way of implementing it?
In this specific case, an easier option could be to define the query parameter value as a regex expression, since regex expression itself allows us to define a string to be case insensitive / sensitive.
In other scenarios, another option would be to incorporate the specification (that the value needs to be case insensitive) into the query param value itself, like
http://localhost:3000?name=case_insensitive(test)
I would realize two new parameters for name, namely: nameIgnoreCase and nameCaseSensitive. In this case the user of the endpoint can and must decide. If this is well documented, the user gets an additional hint that this ‚question’ exists at all.
You can also continue to provide name as the default behavior, which will fall back to either nameIgnoreCase or nameCaseSensitive.

LDAP query for `name` works, but returns zero results for `managedBy`

I am having trouble performing a query in the LDAP system. Because I am able to query for a manager and receive the list of direct reports, I know the connection is correct.
I would like to search from the RootDSE for any item with a partial match in the managedBy field. Using * as wildcard, I want to search for *XX9XXX9*.
I receive the correct record when I perform the following search on the name field: (&(objectCategory=*)(name=XX9XXX99X99X9))
The managedBy field contains the following attributes:
CN=Lastname\, Firstname XX9XXX9
OU=Tiered Services
OU=Premium
OU=NCG
OU=Accounts
OU=BAND
DC=corp
DC=XXXXXXXXX
DC=com
When I attempt the same query as I did with the name field, no results are returned. Any help would be much appreciated.
You'll have to try an alternate method to get what you're after: managedBy contains a distinguished name, and DNs do not support the wildcard character in queries.
Edit: possible duplicate of Active Directory C# using ManagedBy attribute
Found out the issue that was causing the problem... the application i /was/ using was not doing the search in the correct manner - it was trying to do a string search, but in reality, the OU entry was not a string, it was a number (ID to the OU).... the application was trying to think for me.
Instead of showing the ID, it was performing a lookup by itself and presenting the results of the lookup, not the real value in the field.

Is there a way to search by length in a LDAP query?

In the search window, for the sAMAccountName column, is there a way to filter by exactly 7 characters or is there a function in the search window that allows me to do that?
My coworker and I did try to do a search online but couldn't find anything.
The LDAP search operation requires at least a base object from which to start the search, the scope (or depth) of the search, and a filter which indicates by its truth, falsehood, or undefinedness whether an entry should be returned in the search result. Filters are defined in RFC4511. There is no way to specify the length of an attribute value in a filter. In order to return an attribute value that matches a length, you must store an attribute whose value is the length of the attribute value you desire. For example, if the attribute is cn, an attribute value cn-length could be stored whose value is length of the cn attribute. Modern, professional-quality directory servers will provide virtual attributes which are not stored in the directory database but generated dynamically. Such a virtual attribute hold be created to generate the length.
See Scott Lowe's blog post on using Log Parser to query AD for an example of how you could do this. You could also extract results from an AD query and then feed them into Excel or another tool that has more functions than built into LDAP.

Regarding LDAP Search Query

Let's suppose that I want to search a number say 123 and LDAP has entries like 123# or 1-2-3. What should be the LDAP Search filter which needs to be provided? I tried *123* but it doesn't work in case of 1-2-3.
LDAP does not have "entries like 123#", it has entries identified by distinguished names that contain attributes. To search for an an entry that contains a value, you must provide the following parameters to a search request:
base object (distinguished name where the search should commence)
scope - base, one level subordinate to the base, or subtree (all entries subordinate to the base object
filter - an assertion that must evaluate to true in order for the entry to be returned to the client
attributes to return - a list of attributes that the LDAP client desires
If the attribute in question is named number and has a syntax of Integer and a matching rule of IntegerMatch, then the filter (number=123) will find an attribute named number with the integer value of 123. Which filter to use depends on the syntax and matching rule in the attribute type definition because the directory server performs the task of matching attribute values against provided filters with matching rules (as must applications, by the way). Programmers must not consider LDAP attribute values to be "strings", instead they must understand attribute syntaxes and matching rules. There is a DirectoryString syntax (with a very specific definition, though for many purposes it can be considered a garden-variety string) but not all attributes are defined with DirectoryString syntax. Nor do all attributes use the same matching rules and ordering rules.
see also
LDAP: ldapsearch
LDAP: Mastering search filters
LDAP: Programming Practices

Android Notepad Uri Explanation

In the android Notes demo, it accepts the URI:
sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
Where the difference between notes and notes/# is that notes/# returns the note who's ID matches #.
However, the managedQuery() method that is used to get data from the content provider has the following parameters:
Parameters
uri The URI of the content provider to query.
projection List of columns to return.
selection SQL WHERE clause.
selectionArgs The arguments to selection, if any ?s are pesent
sortOrder SQL ORDER BY clause.
So, is there any particular cause for the design decision of providing a URI for that, rather than just using the selection parameter? Or is it just a matter of taste?
Thank you.
I thinks its so you can do more complex lookups without having to complicate your selections and arguments. For example in my project I have multiple tables but use the same selection and arguments. To filter content. By using the URI I don't have interpret the query, I can just switch on the URI. It.might be personal taste to begin with. But in more complex scenarios you appreciate the URI. You can also use * to match strings in the same.way you can with#.
I think it's mostly a matter of taste. IMHO, putting the id in the Uri is a little cleaner since you can make the id opaque rather than require the client to know that it actually represents a specific row id. For instance, you can pass a lookup key (like in the the Contacts API) rather than a specific row id.